Java 8 找到Java8中两个集合之间的差异吗?

Java 8 找到Java8中两个集合之间的差异吗?,java-8,java-stream,Java 8,Java Stream,我试图列出一个集合中另一个集合中不存在的所有书籍的列表。我的问题是,我需要根据图书ID进行比较,所以我不能只是测试第一本书中的一本书是否包含在第二本书中,我必须确定第二本书集中的任何一本书是否与第一本书中的一本书具有相同的ID 我有以下代码来比较两个藏书集并筛选第一个藏书集: List parentBooks=listOfBooks1.stream().filter(book-> !listOfBooks2.contains(book)).collect(Collectors.toList())

我试图列出一个
集合中另一个集合中不存在的所有书籍的
列表。我的问题是,我需要根据图书ID进行比较,所以我不能只是测试第一本书中的一本书是否包含在第二本书中,我必须确定第二本书集中的任何一本书是否与第一本书中的一本书具有相同的ID

我有以下代码来比较两个藏书集并筛选第一个藏书集:

List parentBooks=listOfBooks1.stream().filter(book->
!listOfBooks2.contains(book)).collect(Collectors.toList());
代码无法正常工作,因为我正在比较对象本身。我需要根据bookId而不是整个book对象来比较对象。我应该如何更改代码,以便它可以基于bookId(book.getId())进行比较?

List books1=。。。;
列表2=。。。;
Set id=books2.stream()
.map(Book::getId)
.collect(收集器.toSet());
List parentBooks=books1.stream()
.filter(book->!ids.contains(book.getId()))
.collect(Collectors.toList());

问题很复杂,但归结起来只有一件事,那就是了解您的数据。它是不可变的、具有id的实体、重复条目等吗

下面的代码适用于仅具有值的不可变项(以及可能的重复项)

它首先尝试删除before列表中的所有条目(从复制的after列表中)

剩下的将是添加的元素。可以从后列表中删除的前列表中的那些是未更改的

其余的都是拆下的

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;
    }
}
公共类列表{
私有列表addedList=新的ArrayList();
private List unchangedList=new ArrayList();
private List removedList=new ArrayList();
公共列表不同(列表前列表、列表后列表){
addedList.addAll(afterList);//删除Before列表中的所有元素时,只包含新元素。
beforeList.forEach(e->{
布尔b=addedList.remove(e)?unchangedList.add(e):removedList.add(e);
});
}
公共列表getAddedList(){
返回添加列表;
}
公共列表getUnchangedList(){
返回未更改列表;
}
公共列表getRemovedList(){
返回删除列表;
}
}

如果有人想知道为什么要设置(ID),为什么不像我一样列出?这是因为Set的“包含”操作需要O(1)。太棒了,谢谢你的解决方案。它很有魅力。非常感谢你!books1={Book1},books2={},ids=Book1[{Book1}],parentBooks流books2为空,因此没有流。因此,parentBook为空,如果第二个参数为subset,则会满足subset的要求。不鼓励回答,因为它们不会为将来的读者提供太多信息。请对您所写的内容提供一些解释。您可以将该描述编辑到回答中吗?
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());
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;
    }
}