在许多算法中,您应该迭代一组元素,而该集合不为空。
由于您可能在迭代时更改集合,因此通常会从集合中拉出一个元素,然后执行迭代,可能会在集合中添加或删除元素。这是一个典型的Java代码。
Set<Integer> possibleFactors = Sets.newHashSet(2,3,4,5,6,7,8,100);
while (!possibleFactors.isEmpty()) {
int factor = possibleFactors.iterator().next();
for (int i=1;i<10;i++) possibleFactors.remove(i*factor);
}
编辑:正如评论中所述,我会举一个更好的例子。我正在迭代用户选择的文件,我通过检查每个项目的权限来过滤它们。但是,作为优化,如果用户没有某个目录的权限,我将从该集中删除其中的所有文件。
Set<Path> input = Sets.newHashSet(userSelectedPaths);
while (!input.isEmpty()) {
Path path = input.iterator.next();
input.remove(path);
if (!expensivePermissionCheck(path)) {
input.removeAll(path.getFiles());
} else {
processPath(path);
}
}
然而,循环中的第一行看起来很奇怪。它创建了一个多余的Iterable
对象,当我想要的只是集合中的任意元素时,我不关心它的顺序。
除了性能之外,它看起来有点奇怪,而且可读性较差。
有更好的选择吗?也许完全不同的结构?
编辑:或许更好的表述是“如何从一组中弹出任意元素?”
答案 0 :(得分:5)
答案 1 :(得分:-1)
实际上它不仅不可读,而且如果该组为空,它也会抛出异常。
在获取next()
之前,您应该始终检查hasNext()
,然后根据此行动。
答案 2 :(得分:-2)
在集合中没有特定的元素排序。您可以通过提供其值(Set.remove(Object o)或Set.contains(Object o)来删除或检查元素的存在。您可以考虑从集合中删除所有元素,或者将其保留为集合A中的元素使用
不在B组中Set.removeAll(Set B);
例如
Set<Integer> A = new HashSet();
Set<Integer> B = new HashSet();
add numbers from 1-to-10 into A
add even numbers in range [1, 10] to B
A.removeAll(B);
println(A)
will print all odd numbers, eg those that are in A but not in B.
或者,您可以调用remove()方法,该方法从集合中删除元素(如果存在):
for (int i = 2; i <= 10; i += 2) {
a.remove(i)
}
它与上面例子中的removeAll()具有相同的效果。
通常,当您处理独特事物的集合并且它们的排序无关紧要时,Set数据结构是合适的。如果要对集合执行Union,Intersection,Diff等操作,则集合很有用(并且很快)。如果您的项目可能重复一次,那么您可以考虑使用Multisets(谷歌收藏),如果您关心事物的排序,那么列表会更有帮助(但性能会更差)。