我最近遇到了这个问题。 这是我的代码
for(int i=1; i<=repeticiones;i++){
posiblesComunes.removeIf(p->!periodos.get(i).contains(p));
}
periodos是List(Set(String))
,posiblesComunes是Set(String)
我需要做的是只获取句点中所有Set(String)中的字符串。 我尝试使用for来做到这一点,但我收到了下一条消息:
我在封闭范围内定义的局部变量必须是最终的或有效的最终
有没有办法解决这个问题?或者另一种获取这些元素的方法? 谢谢!
编辑: 只是一个例子
periodos = {("1-1-16","6-12-16"),("1-1-16","2-8-15"),("3-7-08","1-1-16")}
我需要得到的是&#34; 1-1-16&#34;,这是共同点。
EDIT2:
periodosComunes的示例(for for循环):
periodosComunes = ("1-1-16","6-2-16")
答案 0 :(得分:3)
您无法从lambda表达式访问本地变量i
,因为它在循环期间被修改。最简单的解决方法是在另一个不可变变量中捕获i
的当前值:
for(int i=1; i<=repeticiones;i++) {
int finalI = i;
posiblesComunes.removeIf(p -> !periodos.get(finalI).contains(p));
}
请注意,for-each循环的变量没有此问题:
for(Set<String> set: periodos.subList(1, repeticiones))
posiblesComunes.removeIf(p -> !set.contains(p));
但最后,您在这里过度使用Java 8功能。自Java 2以来,可以使用原始集合API完成此操作:
for(Set<String> set: periodos.subList(1, repeticiones))
posiblesComunes.retainAll(set);
也适用于原始循环:
for(int i=1; i<=repeticiones; i++)
posiblesComunes.retainAll(periodos.get(i));
在这里,您还可以添加一个快捷方式,因为该组永远不会增长,所以如果没有共同的元素,您可以在该组变空时停止
for(int i=1; i<=repeticiones && !posiblesComunes.isEmpty(); i++)
posiblesComunes.retainAll(periodos.get(i));
答案 1 :(得分:2)
这个怎么样:
1
我使用Java 9中的集合文字为我节省了一些打字,但这与解决方案无关。
答案 2 :(得分:1)
并非所有列表都为迭代器提供了删除其项目的能力;但是,如果您选择了正确类型的列表,则会将其内置到Iterator
界面中。
Iterator i = list.iterator();
while (i.hasNext()) {
if (i.next().equals(bad)) {
i.remove();
}
}
解决方案的简单性足以让您考虑跳过基于流的方法,并且与某些类型的修改不同,Iterator
删除不会抛出ConcurrentModificationException
。
答案 3 :(得分:0)
这应该有效(如果我理解你的需要):
import java.util.stream.*;
import java.util.*;
public class P {
public static void main(String []a) {
// Init.
Set<String> periodosComunes = new HashSet<>(); periodosComunes.add("1-1-16"); periodosComunes.add("6-2-16");
Set<String> s1 = new HashSet<>(); s1.add("1-1-16"); s1.add("6-12-16");
Set<String> s2 = new HashSet<>(); s2.add("1-1-16"); s2.add("2-8-15");
Set<String> s3 = new HashSet<>(); s3.add("1-1-16"); s3.add("3-7-08");
List<Set<String>> periodos = new ArrayList<>(); periodos.add(s1); periodos.add(s2); periodos.add(s3);
// Computes the set of commons...
Set<String> r = periodosComunes.stream().filter(p->periodos.stream().allMatch(s->s.contains(p))).collect(Collectors.toSet());
System.out.println(r);
}
}
最初位于periodosCommunes
的常见句点集合位于r
。现在,您可以根据需要使用该集合删除原始集合中的适当集合:
periodosComunes.removeIf(s->!r.contains(s));