Find the difference between two collections in Java 8?

。_饼干妹妹 提交于 2019-12-03 08:52:09

问题


I am trying to make a List of all of the books in one Collection that are not present in another. My problem is that I need to compare based on book ID, so I can't just test to see whether a book in the first is contained in the second, I have to determine whether any book in the second collection has the same ID as a book in the first.

I have the below code to compare two collections of books and filter the first collection:

List<Book> parentBooks = listOfBooks1.stream().filter(book->
  !listOfBooks2.contains(book)).collect(Collectors.toList());

The code doesn't work correctly because I am comparing the objects themselves. I need to compare the objects based on the bookId instead of the whole book object. How should I change the code so it can do the comparison based on the bookId (book.getId())?


回答1:


List<Book> books1 = ...;
List<Book> books2 = ...;
Set<Integer> ids = books2.stream()
        .map(Book::getId)
        .collect(Collectors.toSet());
List<Book> parentBooks = books1.stream()
        .filter(book -> !ids.contains(book.getId()))
        .collect(Collectors.toList());



回答2:


The problem is complex, but it boils down to one thing, know your data. Is it imutables, entities with an id, duplicate entries etc? The code below works for immutables with only values (and with possible duplicates). It first tries to remove all entries in the before list (from the copied after-list). What is left will be the added elements. The ones from the before-list that can be removed from the after-list are the unchanged ones. The rest are the removed ones

package scrap;

import java.util.ArrayList;
import java.util.List;

public class ListDiffer<T> {

    private List<T> addedList = new ArrayList<>();
    private List<T> unchangedList = new ArrayList<>();
    private List<T> removedList = new ArrayList<>();

    public ListDiffer(List<T> beforeList, List<T> afterList) {
        addedList.addAll(afterList); // Will contain only new elements when all elements in the Before-list are removed.
        beforeList.forEach(e -> {
            boolean b = addedList.remove(e) ? unchangedList.add(e) : removedList.add(e);
        });
    }

    public List<T> getAddedList() {
        return addedList;
    }

    public List<T> getUnchangedList() {
        return unchangedList;
    }

    public List<T> getRemovedList() {
        return removedList;
    }
}



回答3:


Set<Integer> books1ids = listOfBooks1.stream().map(Book::getId).collect(Collectors.toSet());
Set<Integer> books2ids = listOfBooks2.stream().map(Book::getId).collect(Collectors.toSet());
return books1ids.equals(books2ids);


来源:https://stackoverflow.com/questions/38226340/find-the-difference-between-two-collections-in-java-8

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!