【问题标题】:Find the difference between two collections in Java 8?找出 Java 8 中两个集合之间的区别?
【发布时间】:2016-07-06 14:18:20
【问题描述】:

我正在尝试在一个 Collection 中创建一个 List 中不存在于另一个中的所有书籍。我的问题是我需要根据书的ID进行比较,所以我不能只测试第一个中的书是否包含在第二个中,我必须确定第二个集合中的任何书是否具有相同的ID首先是一本书。

我有以下代码来比较两个书籍集合并过滤第一个集合:

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

代码无法正常工作,因为我正在比较对象本身。我需要根据 bookId 而不是整个 book 对象来比较对象。我应该如何更改代码以便它可以根据 bookId (book.getId()) 进行比较?

【问题讨论】:

    标签: java-8 java-stream


    【解决方案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());
    

    【讨论】:

    • 如果有人想知道为什么是 Set (ids),为什么不像我一样 List?这是因为 Set 的“包含”操作需要 O(1)。
    • 太棒了,感谢您的解决方案。它就像一个魅力。
    • 非常感谢!
    • books1 = {Book1}, books2 = {}, ids = Book1[{Book1}], parentBooks 流 books2 是空白的,所以没有流。所以,parentBook 为空
    • 并且,如果第二个参数是子集,它将满足子集
    【解决方案2】:

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

    下面的代码适用于只有值(并且可能有重复项)的不可变对象。

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

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

    剩下的都是被删除的

    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;
        }
    }
    

    【讨论】:

    • 不鼓励仅使用代码回答,因为它们没有为未来的读者提供太多信息,请对您所写的内容提供一些解释
    • 您能否将该描述编辑为答案?
    猜你喜欢
    • 2014-11-04
    • 2012-08-06
    • 2018-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 2015-09-01
    相关资源
    最近更新 更多