我有两个列表,我想要进行批量操作,例如使用方法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方法中添加基于其他字段的比较。请建议。
希望我的查询足够清楚。请让我知道澄清。
答案 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();
}
}