按列表对象字段的属性过滤列表

时间:2020-03-19 20:50:19

标签: java filter java-8 java-stream

鉴于TypeA中的所有List<TypeA>实例都在superTypeB字段中设置了SubTypeB的实例,我需要从列表中过滤出重复的TypeA实例,其中重复表示propertyApropertyBSubTypeB的值都匹配。使用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; }
}

2 个答案:

答案 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)

您是否可以为overrideequals类型的hashCode TypeASubTypeB方法?

如果是,这非常简单。如果没有,我将相应地编辑此答案。

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中获得每个不同对象的第一次机会是通过流发出对象的顺序。否则,您将无法控制首先遇到哪个元素。