Java 如何为两个对象使用集合方法(removeAll() 和 retainAll())。(对象是父子关系)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4462626/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 17:50:42  来源:igfitidea点击:

How to use Collections methods(removeAll() and retainAll()) for two objects. (objects are parent-child relation)

javalistcollectionsapache-commons

提问by zono

I expected to result below but actually not. I would like to know how to show the differences between two Collections. (objects are parent and child relationship) In this case, can I use standard method like removeAll() or can you recommend another approach like using apache-commons. Thanks.

我希望结果低于但实际上不是。我想知道如何显示两个集合之间的差异。(对象是父子关系)在这种情况下,我可以使用像 removeAll() 这样的标准方法,或者你可以推荐另一种方法,比如使用 apache-commons。谢谢。

CONSTRAINT
------------------------------
1.Item.class is unmodifiable(eg. I can not add equals method)
2.If id is same between two objects, they are assumed as same things.
------------------------------

EXPECTED
------------------------------
removed object are:
2
same object are:
1
3
add object are:
4
------------------------------

ACTUAL
------------------------------
removed object are:
1
2
3
same object are:
add object are:
1
3
4
------------------------------

package com.javastudy;

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

public class CollectionCompareToObjects {

    public static void main(String[] args) {

        List<Item> before = new ArrayList<Item>();
        List<ItemEx> after = new ArrayList<ItemEx>();

        before.add(new Item(1L));
        before.add(new Item(2L)); // delete
        before.add(new Item(3L));

        after.add(new ItemEx(1L));
        after.add(new ItemEx(3L));
        after.add(new ItemEx(4L)); // added

        List<Item> removed = new ArrayList<Item>(before);
        removed.removeAll(after);

        System.out.println("removed objects are:");
        for(Item item : removed){
            System.out.println(item.getId());
        }

        List<Item> same = new ArrayList<Item>(before);
        same.retainAll(after);

        System.out.println("same objects are:");
        for(Item item : same){
            System.out.println(item.getId());
        }

        List<Item> added = new ArrayList<Item>(after);
        added.removeAll(before);

        System.out.println("add objects are:");
        for(Item item : added){
            System.out.println(item.getId());
        }

    }

}


package com.javastudy;

public class Item {

    private Long id;

    public Item(Long id) {
        this.id = id;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

}

package com.javastudy;

public class ItemEx extends Item {

    private String name;

    public ItemEx(Long id) {
        super(id);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

采纳答案by Eli Acherkan

Java collections rely on the equalsand hashCodemethods (the latter is used by HashMaps, HashSets and others).

Java 集合依赖于equalshashCode方法(后者被HashMaps、HashSets 和其他人使用)。

If you want to be able to use the data structure capabilities of Java collections (such as removeAll, retainAlletc.), you need to supply objects with proper implementations of equalsand hashCode.

如果你希望能够使用Java集合的数据结构的能力(如removeAllretainAll等),你需要用正确的实现提供对象equalshashCode

If you can't modify the Itemclass, you can write a wrapper class with your own implementation of equals:

如果您无法修改Item该类,则可以使用自己的实现编写一个包装类equals

public class ItemWrapper {
    private final Item item;
    public ItemWrapper(Item item) {
        this.item = item;
    }

    public Item getItem() {
        return item;
    }

    @Override
    public boolean equals(Object obj) {
        return obj instanceof ItemWrapper && item.getId().equals(((ItemWrapper) obj).item.getId());
    }

    @Override
    public int hashCode() {
        return item.getId().hashCode();
    }
}

Create a new ItemWrapperfor each original Item, store the ItemWrappers in Java collections, and use the required methods (removeAll/retainAll). Then iterate over the resulting collection and retrieve the Items by calling each ItemWrapper's getItem()method.

ItemWrapper为每个原件创建一个新的Item,将ItemWrappers存储在 Java 集合中,并使用所需的方法 ( removeAll/ retainAll)。然后遍历结果集合并Item通过调用 eachItemWrappergetItem()方法检索s 。

Your other option is to subclass ArrayList, but it seems like a more convoluted solution.

您的另一个选择是 subclass ArrayList,但这似乎是一个更复杂的解决方案。

Yet another option is not to use Java collections for the remove/retain logic, implementing them yourself instead.

另一种选择是不将 Java 集合用于删除/保留逻辑,而是自己实现它们。