Java arraylist 使用流查找缺失的字段
Java arraylist find missing fields using streams
我有下面的代码。
两组arraylist。
如何使用流来迭代和比较 itemlist_a 和 itemlist_b 以检测 itemlist_b 中是否缺少 c 和 d?
当然我可以使用传统的 for 循环,但是有没有其他方法可以使用流或其他方式来实现?
import java.util.ArrayList;
import java.util.List;
class item {
String name;
public item(String name) {
this.name = name;
}
}
public class Test {
public static void main(String[] args) {
List<item> itemlist_a = new ArrayList<item>();
itemlist_a.add(new item("a"));
itemlist_a.add(new item("b"));
List<item> itemlist_b = new ArrayList<item>();
itemlist_b.add(new item("a"));
itemlist_b.add(new item("b"));
itemlist_b.add(new item("c"));
itemlist_b.add(new item("d"));
}
}
我认为这不是一个很好的流应用程序,但您可以这样做:
itemlist_a.stream().filter(e -> !itemlist_b.contains(e)).collect(Collectors.toList());
这将为您提供 itemlist_a 但不在 itemlist_b 中的所有项目的列表。
然而,流是为函数式编程而设计的,这意味着它们不应该依赖于流之外的变量。在这种情况下 itemlist_b 不在流中,但会影响函数的结果。但是它会起作用。
最简单的方法是覆盖Item中的equals
和hashCode
,然后在超集上使用removeAll
来保留差异:
//the Item class
@Override
public int hashCode() {
// TODO
return Objects.hashCode(name);
}
@Override
public boolean equals(Object obj) {
// TODO: implement
return this.name.equals(((item) obj).name);
}
然后就可以得到差值:
itemlist_b.removeAll(itemlist_a);
调用后 itemlist_b
中剩下的就是差值。如果你想让itemlist_b
不变,你可以用一个copy
做同样的事情
List<Item> diff = new ArrayList<>(itemlist_b);
diff.removeAll(itemlist_a);
而你在 diff
中有差异。
由于您使用的是列表,因此您只需要注意与重复项相关的业务逻辑。 removeAll
将删除所有匹配元素。
Java 列表 API
一个列表的副本,然后删除与另一个相同的所有元素
List<Item> differences = new ArrayList<>(itemlist_b);
differences.removeAll(itemlist_a);
流 API
List<Item> differences = itemlist_b.stream()
.filter(element -> !itemlist_a.contains(element))
.collect(Collectors.toList());
List<Item> differences = new ArrayList<>(Sets.difference(Sets.newHashSet(itemlist_a), Sets.newHashSet(itemlist_b)));
List<Item> differences = new ArrayList<>((CollectionUtils.removeAll(itemlist_b, itemlist_a)));
我有下面的代码。 两组arraylist。 如何使用流来迭代和比较 itemlist_a 和 itemlist_b 以检测 itemlist_b 中是否缺少 c 和 d? 当然我可以使用传统的 for 循环,但是有没有其他方法可以使用流或其他方式来实现?
import java.util.ArrayList;
import java.util.List;
class item {
String name;
public item(String name) {
this.name = name;
}
}
public class Test {
public static void main(String[] args) {
List<item> itemlist_a = new ArrayList<item>();
itemlist_a.add(new item("a"));
itemlist_a.add(new item("b"));
List<item> itemlist_b = new ArrayList<item>();
itemlist_b.add(new item("a"));
itemlist_b.add(new item("b"));
itemlist_b.add(new item("c"));
itemlist_b.add(new item("d"));
}
}
我认为这不是一个很好的流应用程序,但您可以这样做:
itemlist_a.stream().filter(e -> !itemlist_b.contains(e)).collect(Collectors.toList());
这将为您提供 itemlist_a 但不在 itemlist_b 中的所有项目的列表。 然而,流是为函数式编程而设计的,这意味着它们不应该依赖于流之外的变量。在这种情况下 itemlist_b 不在流中,但会影响函数的结果。但是它会起作用。
最简单的方法是覆盖Item中的equals
和hashCode
,然后在超集上使用removeAll
来保留差异:
//the Item class
@Override
public int hashCode() {
// TODO
return Objects.hashCode(name);
}
@Override
public boolean equals(Object obj) {
// TODO: implement
return this.name.equals(((item) obj).name);
}
然后就可以得到差值:
itemlist_b.removeAll(itemlist_a);
调用后 itemlist_b
中剩下的就是差值。如果你想让itemlist_b
不变,你可以用一个copy
List<Item> diff = new ArrayList<>(itemlist_b);
diff.removeAll(itemlist_a);
而你在 diff
中有差异。
由于您使用的是列表,因此您只需要注意与重复项相关的业务逻辑。 removeAll
将删除所有匹配元素。
Java 列表 API
一个列表的副本,然后删除与另一个相同的所有元素
List<Item> differences = new ArrayList<>(itemlist_b);
differences.removeAll(itemlist_a);
流 API
List<Item> differences = itemlist_b.stream()
.filter(element -> !itemlist_a.contains(element))
.collect(Collectors.toList());
List<Item> differences = new ArrayList<>(Sets.difference(Sets.newHashSet(itemlist_a), Sets.newHashSet(itemlist_b)));
List<Item> differences = new ArrayList<>((CollectionUtils.removeAll(itemlist_b, itemlist_a)));