I have the following class:
public class Person {
private String name;
private String gender;
}
Then I have two lists of persons
List A:
index 0: name: "Mike", gender: "male"
index 1: name: "Jane", gender: "female"
index 2: name: "Ellen", gender: "female"
index 3: name: "Ben", gender: "male"
index 4: name: "Jimmy", gender: "male"
index 5: name: "Maria", gender: "female"
List B:
index 0: name: "Ben", gender: "male"
index 1: name: "Maria", gender: "female"
index 2: name: "Jane", gender: "female"
index 3: name: "Brian", gender: "male"
index 4: name: "Sofia", gender: "female"
index 5: name: "John", gender: "male"
index 6: name: "Jimmy", gender: "male"
I want to create a new list of names of all the males that is NOT in both lists.
So from the example the list would look like this:
index 0: name: "Mike", gender: "male"
index 1: name: "John", gender: "male"
index 2: name: "Brian", gender: "male"
The tricky things here is that the filtering goes both ways. I want the final list to contain both males that are in list A but not in list B, and males that are in list B but not in list A. I've not been able to find out how to do this, but I've tried to accomplish it using streams..
CodePudding user response:
not super efecient but works
List<Person> r =
Stream.concat(
a.stream().filter(e -> e.isMale() && !b.contains(e)),
b.stream().filter(e -> e.isMale() && !a.contains(e))
)
.collect(Collectors.toList());
more readable versions with storing parial results
List<Person> aNotB = a.stream().filter(e -> e.isMale() && !b.contains(e)).collect(Collectors.toList());
List<Person> bNotA = b.stream().filter(e -> e.isMale() && !a.contains(e)).collect(Collectors.toList());
List<Person> r = new ArrayList<>(aNotB);
r.addAll(bNotA);
CodePudding user response:
List<String> malesNotInBothLists = listA.stream()
.filter(p -> p.getGender().equals("male"))
.filter(p -> !listB.stream().anyMatch(b -> b.getName().equals(p.getName())))
.map(Person::getName)
.collect(Collectors.toList());
malesNotInBothLists.addAll(listB.stream()
.filter(p -> p.getGender().equals("male"))
.filter(p -> !listA.stream().anyMatch(a -> a.getName().equals(p.getName())))
.map(Person::getName)
.collect(Collectors.toList()));`enter code here`