鉴于TypeA
中的所有List<TypeA>
实例都在superTypeB字段中设置了SubTypeB
的实例,我需要从列表中过滤出重复的TypeA
实例,其中重复表示propertyA
中propertyB
和SubTypeB
的值都匹配。使用Java 8流API可以做到这一点吗?
public class TypeA {
private SuperTypeB superTypeB;
public SuperTypeB getSuperTypeB(){ return superTypeB; }
}
public class SuperTypeB {
private String propertyX;
}
public class SubTypeB extends SuperTypeB {
private String propertyA;
private String propertyB;
public String getPropertyA(){ return propertyA; }
public String getPropertyB(){ return propertyB; }
}
答案 0 :(得分:1)
在map
收集为相同类型之前,请确保不要filter
。使用distinctByKey
utility,您可以进一步选择将collect
更改为List
:
List<TypeA> filteredTypeAs = typeAList.stream()
.filter(distinctByKey(s -> {
SubTypeB subTypeB = (SubTypeB) s.getSuperTypeB();
return Arrays.asList(subTypeB.getPropertyA(), subTypeB.getPropertyB());
}))
.collect(Collectors.toList());
注意 :这取决于问题中所述的假设,即无需进行instanceof
检查就可以强制转换所有子类型。
答案 1 :(得分:0)
您是否可以为override
和equals
类型的hashCode
TypeA
和SubTypeB
方法?
如果是,这非常简单。如果没有,我将相应地编辑此答案。
class TypeA {
private SuperTypeB superTypeB;
public SuperTypeB getSuperTypeB(){ return superTypeB; }
@Override
public boolean equals( final Object o) {
if (this == o) return true;
if (!(o instanceof TypeA)) return false;
TypeA typeA = (TypeA) o;
return superTypeB.equals(typeA.superTypeB);
}
@Override
public int hashCode() {
return Objects.hash(superTypeB);
}
}
class SubTypeB extends SuperTypeB {
private String propertyA;
private String propertyB;
public String getPropertyA(){ return propertyA; }
public String getPropertyB(){ return propertyB; }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof SubTypeB)) return false;
SubTypeB subTypeB = (SubTypeB) o;
return propertyA.equals(subTypeB.propertyA) &&
propertyB.equals(subTypeB.propertyB);
}
@Override
public int hashCode() {
return Objects.hash(propertyA, propertyB);
}
}
在此之后,您所需要做的就是:
List<TypeA> finalList = list.stream().distinct().collect(Collectors.toList());
唯一可以确保在流API中获得每个不同对象的第一次机会是通过流发出对象的顺序。否则,您将无法控制首先遇到哪个元素。