Reputation: 73
I have two arraylists of objects, I want to know which strings are unique to arraylist 1, and which strings are unique to arraylist 2. What I have come up with is the forloop below, which I have to implement twice, reversing the positions of the arraylists. I'm hopeful someone can suggest a more elegant way to do this.
Per request, a bunch more stuff I guess I wrongfully assumed was implied in the code-snippet itself. And the output this produces is:
grape doesn't exist in second arrayList
pineapple doesn't exist in first arrayList
Works great, everything is great, but, per above, I'm hopeful someone with more knowledge of streams/java in general can provide a better solution than just running my stream twice, with the inputs reversed.
import java.util.ArrayList;
public class CompareTwoArrays {
ArrayList<MyCustomObject> firstArrayListOfObjects = new ArrayList<>();
ArrayList<MyCustomObject> secondArrayListOfObjects = new ArrayList<>();
public void superSpecificExampleMethod() {
firstArrayListOfObjects.add(new MyCustomObject(1, 1, "apple"));
firstArrayListOfObjects.add(new MyCustomObject(1, 1, "orange"));
firstArrayListOfObjects.add(new MyCustomObject(1, 1, "banana"));
firstArrayListOfObjects.add(new MyCustomObject(1, 1, "grape"));
secondArrayListOfObjects.add(new MyCustomObject(1, 1, "apple"));
secondArrayListOfObjects.add(new MyCustomObject(1, 1, "pineapple"));
secondArrayListOfObjects.add(new MyCustomObject(1, 1, "orange"));
secondArrayListOfObjects.add(new MyCustomObject(1, 1, "banana"));
for (MyCustomObject object : firstArrayListOfObjects) {
if (!secondArrayListOfObjects.stream().map(MyCustomObject::getString).filter(object.getString()::equals).findFirst().isPresent()) {
System.out.println(object.getString() + " doesn't exist in second arrayList");
}
}
for (MyCustomObject object : secondArrayListOfObjects) {
if (!firstArrayListOfObjects.stream().map(MyCustomObject::getString).filter(object.getString()::equals).findFirst().isPresent()) {
System.out.println(object.getString() + " doesn't exist in first arrayList");
}
}
}
}
class MyCustomObject {
private int randomIntOne;
private int randomIntTwo;
private String string;
public MyCustomObject(int randomIntOne, int randomIntTwo, String string) {
this.randomIntOne = randomIntOne;
this.randomIntTwo = randomIntTwo;
this.string = string;
}
public String getString() {
return string;
}
}
Upvotes: 0
Views: 828
Reputation: 19565
Assuming there are two array lists of objects MyObject
containing strings:
List<MyObject> listOne = new ArrayList<>(Arrays.asList(
new MyObject("aaa"), new MyObject("bbb"), new MyObject("ccc"), new MyObject("ddd")
));
List<MyObject> listTwo = new ArrayList<>(Arrays.asList(
new MyObject("fff"), new MyObject("bbb"), new MyObject("ggg"), new MyObject("ddd")
));
To find "unique" objects in listOne
that is those which are not available in listTwo
there are several ways:
List::removeAll
providing that the methods equals
and hashCode
are properly implemented in this classremoveAll
should be applied to a copy of listOne
List<MyObject> diffOneMinusTwo = new ArrayList<>(listOne); // copy
diffOneMinusTwo.removeAll(listTwo); // ["aaa", "ccc"]
List::removeIf
accepting a predicate and using a set of the strings contained in the objects of listTwo
:Set<String> listTwoStrings = listTwo
.stream()
.map(MyObject::getString)
.collect(Collectors.toSet);
List<MyObject> diffOneMinusTwo = new ArrayList<>(listOne); // copy
diffOneMinusTwo.removeIf(x -> listTwoStrings.contains(x.getString()));
filter
and collect
- no copy is needed here but a temporary set of strings is usedList<MyObject> diffOneMinusTwo = listOne
.stream()
.filter(x -> !listTwoStrings.contains(x.getString()))
.collect(Collectors.toList());
In Java 11 there is static Predicate::not
method so the stream version may look like this (if hashCode
and equals
are implemented properly):
List<MyObject> diffOneMinusTwo = listOne
.stream()
.filter(Predicate.not(listTwo::contains)) // using method reference
.collect(Collectors.toList());
The difference between listTwo
and listOne
can be created vice versa.
Upvotes: 1