removeAll方法具有不同的对象类型

时间:2013-02-13 05:51:10

标签: java collections

我有两个列表,我想要进行批量操作,例如使用方法removeAll,retainAll,contains。问题是列表具有不同类型的对象,其中一个字段是相同的。就像

class ObjectType1{
  Long field1;
  String field2;
  String field3
 }

class ObjectType2{
Long field1;
String field4;
Long field5

}

因此list1包含ObjectType1的元素,而list2包含ObjectType2。我想基于field1进行批量操作,这在两种对象类型中都很常见。

我正在考虑在基于公共字段的两个对象中实现equals方法。但是后来认为在一个字段上进行平等可能是错误的,因为将来可能需要在equals方法中添加基于其他字段的比较。请建议。

希望我的查询足够清楚。请让我知道澄清。

5 个答案:

答案 0 :(得分:1)

查看Google的Guava库。您可以使用Collections2.transform来实现此目的。以下是retainAll()的处理方式,例如:

import com.google.common.base.Function;
import com.google.common.collect.Collections2;
...
List<ObjectType1> list1 = ...;
List<ObjectType2> list2 = ...;
Colection<Long> list1field1 = 
  Collections2.transform(list1, 
                         new Function<ObjectType1, Long>() {
                           public Long apply(ObjectType1 input) {
                             return (null == input) ? null : input.field1;
                           }
                         });
Collection<Long> list2field1 = 
  Collections2.transform(list2, ...);

// list1.retainAll(list2) based on field1 equivalence
list1field1.retainAll(list2field1); // this affects the underlying list, ie list1.

答案 1 :(得分:0)

尝试以下代码,它将提供常用值列表

package rais;

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

public class ArrayClient {

    public static void main(String[] args) {

        List<ObjectType1> list1 = new ArrayList<ObjectType1>();

        ObjectType1 type1Obj1 = new ObjectType1(10001l, "XXX", "YYYY");
        list1.add(type1Obj1);

        ObjectType1 type1Obj2 = new ObjectType1(10002l, "XXX", "YYYY");
        list1.add(type1Obj2);

        ObjectType1 type1Obj3 = new ObjectType1(10003l, "XXX", "YYYY");
        list1.add(type1Obj3);

        ObjectType1 type1Obj4 = new ObjectType1(10004l, "XXX", "YYYY");
        list1.add(type1Obj4);

        ObjectType1 type1Obj5 = new ObjectType1(10005l, "XXX", "YYYY");
        list1.add(type1Obj5);

        List<ObjectType2> list2 = new ArrayList<ObjectType2>();

        ObjectType2 type2Obj1 = new ObjectType2(10001l, "XXX", 2000l);
        list2.add(type2Obj1);

        ObjectType2 type2Obj2 = new ObjectType2(10002l, "XXX", 2001l);
        list2.add(type2Obj2);

        ObjectType2 type2Obj3 = new ObjectType2(50002l, "XXX", 2002l);
        list2.add(type2Obj3);

        ObjectType2 type2Obj4 = new ObjectType2(50003l, "XXX", 2003l);
        list2.add(type2Obj4);

        List<ObjectType1> list3 = retainAll(list1, list2);

        for (ObjectType1 objectType : list3) {
            System.out.println(objectType);
        }

    }

    public static List<ObjectType1> retainAll(List<ObjectType1> firstList,  List<ObjectType2> secondList) {

        List<ObjectType1> list3 = new ArrayList<ObjectType1>();

        for (ObjectType1 first : firstList) {
            for (ObjectType2 second : secondList) {
                if (first.getField1().equals(second.getField1())) {
                    list3.add(first);
                    break;
                }

            }

        }

        return list3;

    }

}

在上面的程序中有两个对象

ObjectType1 type1Obj1 = new ObjectType1(10001l, "XXX", "YYYY");
            list1.add(type1Obj1);

            ObjectType1 type1Obj2 = new ObjectType1(10002l, "XXX", "YYYY");
            list1.add(type1Obj2);

在两个类中都有共同的 field1 ,list3将只包含type1的两个元素。

答案 2 :(得分:0)

如果我理解你的问题,你需要像

这样的东西
    class SuperObject{
        Long field1;
        public SuperObject(){}
        public void setField1(Long f){
            field1 = f;
        }
        public Long getField1(){
            return field1;
        }
        public boolean equals(Object obj){
    if(obj instanceof SuperObject)
        return field1.equals(((SuperObject) obj).getField1());
    else
        return false;
}
    }
    class ObjectType1 extends SuperObject{
        String field2;
        String field3;
        ...    
}

    class ObjectType2 extends SuperObject{
        String field4;
        Long field5;
        ...
    }

列表应该是

List<SuperObject> list = new ArrayList<SuperObject>();
    ObjectType1 obj1 = new ObjectType1();
    ObjectType2 obj2 = new ObjectType2();
    list.add(obj1);
    list.add(obj2);

列表中的对象现在具有相同的方法实现,基于field1,它位于超类中

答案 3 :(得分:0)

我使用界面

编写代码
public interface IMatchable {

    Object getMatchingField();
}

然后我的ObjectType1和ObjectType2正在实现此接口以及覆盖equals方法

public class ObjectType1 implements IMatchable {

@Override
public Object getMatchingField() {
    return field1;
}
 @Override
 public boolean equals(Object obj) {
    IMatchable matchableObj = null;
    if (obj instanceof IMatchable) {
        matchableObj = (IMatchable) obj;
    } else {
        return false;
    }
    return matchableObj.getMatchingField().equals(this.getMatchingField()) ? true: false;
}
}

使用这些方法类似于ObjectType2。

答案 4 :(得分:0)

正如@Dilum所写,您可以使用Google的Guava库 此外,如果您只有列表,则应使用Lists.transform代替 此外,如果您使用Java 8,那么它将如下所示:

List<Long> list1field1 =
    Lists.transform(list1, input -> input == null ? null : input.field1);

或者你可以手动完成:

// list1.removeAll(list2);
Set<Long> set = new HashSet<Long>();
for (ObjectType2 o2 : list2) {
    set.add(o2.field1);
}
Iterator<ObjectType1> i = list1.iterator();
while (i.hasNext()) {
    if (set.contains(i.next().field1)) {
        i.remove();
    }
}