Java:如何遍历三个List <string> </string>

时间:2012-09-11 15:17:47

标签: java loops for-loop foreach

我有三个List<String>个变量:classFilesusernamesfileDirectories。我有一个String(一个字符串列表,但我将比较列表中的每个字符串和下面的循环),它包含每个列表中的一个项目。我想遍历所有三个列表并检查所有三个列表中的一个值是否在String

最好的方法是什么?

for(String classFile:classFiles) {
//if contains classfile statement
  for(String username:usernames) {
  //if contains username statement
    for(String fileDirectory:fileDirectories) {
      //if contains filedirectory statement
    }
  }
}

for(String classFile:classFiles) {
  for(String username:usernames) {
    for(String fileDirectory:fileDirectories) {
      //if statement
    }
  }
}

for(String classFile:classFiles) {
  //make list of files that contain classFile
}

for(String username:usernames) {
  //remove items from list that do not contain username
}

for(String fileDirectory:fileDirectories){
  //remove items from list that do not contain fileDirectory
}

或者有更好的方法吗?

编辑:示例

classFiles - a1, a2, a3
usernames - noc1, noc2, noc3
fileDirectories - C:/projects/a1/noc1/example.java, C:/projects/a1/ad3/example.java

和要检查的字符串

String - C:/bin/a1/noc1/example.class

我想要做的是如果fileDirectory和String都包含classFile和username,那么将它添加到列表中

因此,在此示例中,C:/bin/a1/noc1/example.class将添加到列表中,但C:/bin/a4/fd1/example.class将不会或C:/bin/a3/noc3/example.class将不会添加

4 个答案:

答案 0 :(得分:9)

执行删除操作时,每个循环都不是最佳选择。您应该使用Iterator并删除迭代器以避免并发修改异常。

相反

for(String fileDirectory:fileDirectories){
  //remove items from list that do not contain fileDirectory
}

您应该执行类似

的操作
Iterator iter = fileDirectores.iterator();
while(iter.hasNext())
{
//Get next
//Do your check 
iter.remove();
}

这导致有三个单独的迭代来完全满足您的要求。

答案 1 :(得分:1)

有时最好定义您实际尝试编写的功能:

/**
  * Checks to see if candidate has one string in each of classFiles, usernames and fileDirectories
  */ 
public boolean hasEssentialComponents(List<String> candidate) {
  //Code here
}

现在,您的第一个选项有一个非常长的最长运行时间O(n ^ 3)。如果您希望函数通常失败,那么对于三个列表中的每个项目,您将循环遍历下一个列表。其中大部分都是多余的,如果这些列表很长,您将会产生巨大的性能影响。

第二个是微妙的不同,但具有相同的总运行时间。

第三个显然更好;在这种情况下,只要您发现列表没有组件并且您从未检查过两次组件的列表,就会失败。但是,Java提供了一些可以使这更容易的sugar

public boolean hasEssentialComponents(List<String> candidates) {
  //Sanity check the data
  if (candidate.size() != 3) { return false; } //I'm assuming a 'good' candidate has only three items.

  valid = true;
  for (String candidate:candidates) {
    if (valid &&  
        ! (   check(this.classFiles, candidate)
           || check(this.usernames, candidate)
           || check(this.fileDirectories, candidate) )
          )) {
      valid = false;
    }
  }
  return valid;
}

private boolean check(List<String> masterList, String candidate) {
  return masterList.contains(candidate);
}

现在,我在这里不必要地详细说明,以确保解决问题的部分内容。请注意,您应该尽可能使用Java内置函数;他们很好地优化了。不要将您的列表添加到一起;你花了不必要的时间复制。此外,如果您需要的话,只进行一次比较:请注意,如果您知道字符串列表中的元素应该位于您的某个主列表中,那么可以做得更好。

最后,我真的建议你先写一个方法签名。它迫使你去思考你实际上要做的事情。

答案 2 :(得分:0)

所以我认为你想要获得所有三个列表之间的交集? 只需使用List上的retainAll方法。

classFiles.retainAll(usernames);
classFiles.retainAll(fileDirectories);

现在classFiles将只有三个列表之间的交集。

答案 3 :(得分:0)

您是否可以考虑使用HashSet或HashMap快速访问您的字符串值(使用.contains(string))?

它将消除循环。

如果我理解这个问题(不确定^^)

,我会这样做