2013-02-13 2 views
4

У меня есть два списка, на которых я хочу выполнять массовые операции, например, используя метод removeAll, containsAll. Проблема состоит в том, что оба списка имеют разные типы объектов, имеющих одно поле, которое одинаково. Его, какremoveВсе метод с разными типами объектов

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

class ObjectType2{ 
Long field1; 
String field4; 
Long field5 

}

Так песни1 содержит элементы ObjectType1 и песни2 содержит ObjectType2. Я хочу выполнять массовые операции на основе поля1, который является общим для обоих типов объектов.

Я думал об использовании метода equals в обоих объектах, основанных на общем поле. Но потом подумал, что ошибочно сделать равным только одно поле, так как в будущем может потребоваться добавить сравнение, основанное на других полях в методе equals. Пожалуйста, предложите.

Надеюсь, что я сделал свой запрос достаточно ясным. Пожалуйста, дайте мне знать для разъяснений.

+0

Я думаю, вы должны переопределить метод равно. –

ответ

0

Try ниже код будет давать список общих значений

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 в обоих классах песни3 будет содержать только два элемента Тип 1.

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, который находится в суперклассе

0

Я написали код с использованием интерфейса

public interface IMatchable { 

    Object getMatchingField(); 
} 

Тогда мой ObjectType1 и ObjectType2 реализуют этот интерфейс наряду с переопределением равно, как метод

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 с этими методами.

1

Посмотрите на библиотеку Гуавы Google. Для этого вы можете использовать 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. 
0

Как пишет @Dilum, вы можете использовать библиотеку Guava Google.
Кроме того, если у вас есть только списки, вместо этого вы должны использовать 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(); 
    } 
} 
Смежные вопросы