gpt4 book ai didi

java - 优雅地组合两个列表的元素,使它们在某个属性值上是唯一的?

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:52:55 25 4
gpt4 key购买 nike

假设我有这个 Java 8 代码:

public class Foo {
private long id;
public getId() {
return id;
}

//--snip--
}


//Somewhere else...

List<Foo> listA = getListA();
List<Foo> listB = getListB();

List<Foo> uniqueFoos = ???;

List<Foo> uniqueFoos我想添加 listA 的所有元素和 listB所以所有Foo s 具有唯一的 ID。 IE。如果已经有 FoouniqueFoos具有特定 ID 的不要添加另一个 Foo使用相同的 ID 但跳过它。

当然有普通的旧迭代,但我认为应该有更优雅的东西(可能涉及流,但不是强制性的),但我不太明白...

我能想到涉及覆盖 equals() 的好解决方案基本上return id == other.id;的方法并使用 Setdistinct() .不幸的是我无法覆盖 equals()因为对象相等性不能改变。

实现这一目标的清晰有效方法是什么?

最佳答案

您可以使用 Collectors.toMap 来完成:

Collection<Foo> uniqueFoos = Stream.concat(listA.stream(), listB.stream())
.collect(Collectors.toMap(
Foo::getId,
f -> f,
(oldFoo, newFoo) -> oldFoo))
.values();

如果您需要一个 List 而不是 Collection,只需执行以下操作:

List<Foo> listUniqueFoos = new ArrayList<>(uniqueFoos);

如果您还需要保留元素的相遇顺序,您可以使用 Collectors.toMap 的重载版本接受返回 map 的 Supplier:

Collection<Foo> uniqueFoos = Stream.concat(listA.stream(), listB.stream())
.collect(Collectors.toMap(
Foo::getId,
f -> f,
(oldFoo, newFoo) -> oldFoo,
LinkedHashMap::new))
.values();

我认为值得添加一个非流变体:

Map<Long, Foo> map = new LinkedHashMap<>();
listA.forEach(f -> map.merge(g.getId(), f, (oldFoo, newFoo) -> oldFoo));
listB.forEach(f -> map.merge(g.getId(), f, (oldFoo, newFoo) -> oldFoo));

Collection<Foo> uniqueFoos = map.values();

这可以重构为一个通用方法来不重复代码:

static <T, K> Collection<T> uniqueBy(Function<T, K> groupBy, List<T>... lists) {
Map<K, T> map = new LinkedHashMap<>();
for (List<T> l : lists) {
l.forEach(e -> map.merge(groupBy.apply(e), e, (o, n) -> o));
}
return map.values();
}

您可以按如下方式使用:

Collection<Foo> uniqueFoos = uniqueBy(Foo::getId, listA, listB);

此方法使用 Map.merge方法。

关于java - 优雅地组合两个列表的元素,使它们在某个属性值上是唯一的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49944648/

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