gpt4 book ai didi

Java:根据特定属性创建包含来自两个给定列表的所有不相交元素的列表的正确方法?

转载 作者:搜寻专家 更新时间:2023-10-31 08:18:42 26 4
gpt4 key购买 nike

给定两个对象列表,我可以根据其中一个属性判断哪些项目不在它们的交集内。让我们看下面的例子:

我有一个类Foo具有两个属性:booplaceholder

class Foo {
private int boo;
private int placeholder = 1;

public Foo(int boo) {
this.boo = boo;
}

public int getBoo() {
return boo;
}
}

现在我正在从中创建两个列表(假设这是我的输入)

    List<Foo> list1 = new ArrayList<Foo>();
list1.add(new Foo(1));
list1.add(new Foo(2));
list1.add(new Foo(3));

List<Foo> list2 = new ArrayList<Foo>();
list2.add(new Foo(0));
list2.add(new Foo(1));
list2.add(new Foo(2));

现在我想说一下 list1 中有哪些项目而不是 list2或在 list2而不是 list1基于它们的属性 boo .所以在上面的例子中我想要一个 List<Foo> notInIntersectList其中包含一个 Foo(0)和一个Foo(3) .

    List<Foo> notInIntersectList = new ArrayList<Foo>();
list1.forEach(li1foo -> {
boolean inBothLists = false;
list2.forEach(li2foo -> {
if (li1foo.getBoo() == li2foo.getBoo()) {
inBothLists = true;
}
});
if (!inBothLists) {
notInIntersectList.add(li1foo);
}
});
//now I covered all items in list1 but not in list2. Now do this again with lists swapped, so I can also cover those.
//...

可悲的是我得到了Local variable inBothLists defined in an enclosing scope must be final or effectively final作为一个错误。这个问题如何妥善解决,因为这似乎不是“正确”的解决方案?

最佳答案

您不能在 lambda 表达式中改变变量(参见:Variable used in lambda expression should be final or effectively final)

这是修复代码的方法(使用 Streams 很有趣)

List<Foo> notInIntersectList = list1.stream()
.filter(fooElementFromList1 -> list2
.stream()
.noneMatch(fooElementFromList2 -> fooElementFromList2.getBoo() == fooElementFromList1.getBoo()))
.collect(Collectors.toCollection(ArrayList::new));

list2.stream()
.filter(fooElementFromList2 -> list1
.stream()
.noneMatch(fooElementFromList1 -> fooElementFromList1.getBoo() == fooElementFromList2.getBoo()))
.forEach(notInIntersectList::add);

这个的复杂度是O(n*m)(其中nm分别是list1和list2的元素个数).

要在 O(n+m) 中执行此操作,您可以使用 Set。为此,您需要在 Foo 类上使用 equalshashcode 方法。这仅根据实例变量 boo 的值将两个 Foo 实例视为相等。

class Foo {
....

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Foo other = (Foo) obj;
return boo == other.boo;
}

@Override
public int hashCode() {
return boo;
}
}

并为此使用Set作为

Set<Foo> fooSet1 = new HashSet<>(list1);
Set<Foo> fooSet2 = new HashSet<>(list2);

fooSet1.removeAll(list2);
fooSet2.removeAll(list1);

List<Foo> notInIntersectList = Stream.concat(fooSet1.stream(), fooSet2.stream())
.collect(Collectors.toList());

关于Java:根据特定属性创建包含来自两个给定列表的所有不相交元素的列表的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53996101/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com