Вы можете сделать что-то вроде этого:
public static void main(String[] args) {
List<Foo> fooList = asList(new Foo("1", "1"), new Foo("2", "2"), new Foo("3", "3"));
List<Bar> barList = asList(new Bar("4", 4), new Bar("3", 3), new Bar("5", 5));
Set<Blah> fooSet = fooList.stream().map(Main::fooToBlah).collect(toCollection(HashSet::new));
Set<Blah> barSet = barList.stream().map(Main::barToBlah).collect(toCollection(HashSet::new));
barList.stream()
.filter(bar -> !fooSet.contains(barToBlah(bar)))
.forEach(System.out::println);
fooList.stream()
.filter(foo -> !barSet.contains(fooToBlah(foo)))
.forEach(System.out::println);
}
static Blah fooToBlah(Foo foo) {
return new Blah(foo.name, foo.age);
}
static Blah barToBlah(Bar bar) {
return new Blah(bar.barName, "" + bar.codeBar);
}
static class Blah {
String name;
String age;
public Blah(String name, String age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
...
}
@Override
public int hashCode() {
...
}
}
- Возьмите все
Foo
объекты и преобразуйте их в Blah
(конечно, назовите его соответствующим образом) - это необходимо, потому что Foo
имеет другие поля, которые нам не нужны.
- Поместите
Blah
объектов в HashSet
, чтобы у вас не было O(n*m)
сложности со временем. Вы могли бы сделать просто collect(toSet())
, но я предпочитаю быть прямо об этом здесь, так как это важно для производительности.
- Перейдите к
Bar
объектам, и если объект не входит в вышеуказанный набор, это необычный Bar
объект. Его необходимо преобразовать в Blah
, и, к сожалению, вы не можете использовать Stream.map
, так как в конце оно все равно должно быть Stream<Bar>
, а не Stream<Blah>
.
- Повторите выше три шага для другого списка, чтобы найти все необычные
Foo
объекты.
Помните, что в классе Blah
необходимы методы equals
и hashCode
. Foo
и Bar
классы не нуждаются в них.
EDIT:
Вы можете преобразовать следующий код
Set<Blah> fooSet = fooList.stream().map(Main::fooToBlah).collect(toCollection(HashSet::new));
barList.stream()
.filter(bar -> !fooSet.contains(barToBlah(bar)))
.forEach(System.out::println);
примерно так
barList.stream()
.filter(bar -> fooList.stream()
.map(Main::fooToBlah)
.noneMatch(foo -> foo.equals(barToBlah(bar)))
)
.forEach(System.out::println);
или даже полностью удалить Blah
класс
barList.stream()
.filter(bar -> fooList.stream().noneMatch(foo -> Objects.equals(foo.name, bar.barName) && Objects.equals(foo.age, "" + bar.codeBar)
.forEach(System.out::println);
но у вас будет намного хуже сложность времени, а также возникает вопрос читабельности.