gpt4 book ai didi

Java Guava 过滤两个不同类型的集合

转载 作者:行者123 更新时间:2023-11-30 06:55:37 25 4
gpt4 key购买 nike

我有两个集合:

ArrayList<B> currentB = new ArrayList<B>();
{
currentB.add(new B(new A("1")));
currentB.add(new B(new A("2")));
currentB.add(new B(new A("7")));
currentB.add(new B(new A("3")));
currentB.add(new B(new A("4")));
}
ArrayList<A> newA = new ArrayList<A>();
{
newA.add(new A("1"));
newA.add(new A("5"));
newA.add(new A("2"));
newA.add(new A("6"));
newA.add(new A("7"));
newA.add(new A("8"));

}

集合有以下类型:

class A {
private String id;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

A nodeRef = (A) o;

return !(id != null ? !id.equals(nodeRef.id) : nodeRef.id != null);

}

public A() {
}

public A(String id) {
this.id = id;
}

@Override
public String toString() {
return "NodeRef{" +
"id='" + id + '\'' +
'}';
}
}

class B {
private A a;

public A a() {
return a;
}

public A getA() {
return a;
}

public void setA(A a) {
this.a = a;
}

@Override
public String toString() {
return "B{" +
"a=" + a +
'}';
}

public B(A a) {
this.a = a;
}

public B() {
}
}

我想创建(最好的结果是修改 newA 和 currentB)两个列表:

  • 第一个应该有对象,在另一个中没有表示
    一个(例如 - a(3), a(4));
  • 第二个逻辑相同但反之亦然:(a(5), a(6),(8)).

我可以用 Guava 来做,但它需要创建 3 个集合:

Function<B, A> BtoA = new Function<B, A>() {
public A apply(final B b) {
return b.getA();
}
};
Collection<A> currentA = Collections2.transform(currentB, BtoA);

java.util.Collection<A> idToDelete = Collections2.filter(currentA, Predicates.not(Predicates.in(newA)));
java.util.Collection<A> idToAdd = Collections2.filter(newA, Predicates.not(Predicates.in(currentA)));

System.out.println("Old B" + idToDelete);
System.out.println("New A" + idToAdd);

有没有办法摆脱 Collection.transform 或者最好的方法?

最佳答案

使用 Java 8 流 API 看起来会很不错:

java.util.Collection<String> idToDelete =
currentB.stream() //get the stream
.filter(b -> !newA.contains(b.getA())) // filter those b, whose A is in newA
.map(b -> b.getA().id) // map transform to get just an Id (you can use just getA() here)
.collect(Collectors.toList()); // finally transform back to list

java.util.Collection<String> idToAdd =
newA.stream() // again get stream
.filter(
// this is a little bit fancy...
// only leave those A, for which currentB doesn't contain element, that has getA() equals to that A
a -> currentB.stream().noneMatch(
b -> b.getA().equals(a)
)
)
.map(a -> a.id) // again get id
.collect(Collectors.toList()); // transform to list

[编辑:]

如果您查看 guava 的源代码,您会发现 transform 只是用一个转换函数包装了您现有的代码。所以 Guava 基本上就像 java 8 流一样工作。所以你实际上可以像以前一样使用 transform 。如果绝对不想这样做,这是 Guava 的完整示例:

Function<B, A> BtoA = new Function<B, A>() {
public A apply(final B b) {
return b.getA();
}
};
Function<A, String> aToId = new Function<A, String>() {
public String apply(final A a) {
return a.getId();
}
};

java.util.Collection<B> bToDelete = Collections2.filter(currentB, Predicates.compose(Predicates.not(Predicates.in(newA)), BtoA));

//without transform, looks ugly
java.util.Collection<A> aToAdd = Collections2.filter(newA, new Predicate<A>() {
@Override
public boolean apply(final A a) {
return !Iterables.any(currentB, new Predicate<B>() {
@Override
public boolean apply(B b) {
return b.getA().equals(a);
}
});
}
});
// this is essentially the same, you can safely use transform
//java.util.Collection<A> aToAdd = Collections2.filter(newA, Predicates.not(Predicates.in(Collections2.transform(currentB, BtoA))));

java.util.Collection<String> idToDelete = Collections2.transform(bToDelete, Functions.compose(aToId, BtoA));
java.util.Collection<String> idToAdd = Collections2.transform(aToAdd, aToId);

System.out.println("Old B: " + idToDelete);
System.out.println("New A: " + idToAdd);

关于Java Guava 过滤两个不同类型的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35118069/

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