如何为两个对象使用Collections方法(removeAll()和retainAll())。 (对象是父子关系) [英] How to use Collections methods(removeAll() and retainAll()) for two objects. (objects are parent-child relation)

查看:148
本文介绍了如何为两个对象使用Collections方法(removeAll()和retainAll())。 (对象是父子关系)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

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

}


推荐答案

Java集合依赖于等于 hashCode 方法(后者由使用HashMap s, HashSet s和其他)。

Java collections rely on the equals and hashCode methods (the latter is used by HashMaps, HashSets and others).

如果你想能够要使用Java集合的数据结构功能(例如 removeAll retainAll 等),你需要提供对象正确实现等于 hashCode

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

如果你不能修改 Item 类,你可以编写一个包装类,你自己的实现等于

If you can't modify the Item class, you can write a wrapper class with your own implementation of 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();
    }
}

创建一个新的 ItemWrapper 对于每个原始 Item ,将 ItemWrapper 存储在Java集合中,并使用所需的方法(的removeAll / 的retainAll )。然后迭代生成的集合并通过调用每个 ItemWrapper getItem来检索 Item s ()方法。

Create a new ItemWrapper for 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.

你的另一个选择是子类 ArrayList ,但似乎就像一个更复杂的解决方案。

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

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

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

这篇关于如何为两个对象使用Collections方法(removeAll()和retainAll())。 (对象是父子关系)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆