Search code examples
javajava-streamequality

Equal Objects not being filtered by Stream.distinct()


I have a stream of Element objects that I needed to filter based on equality. This seems easy enough with .distinct() but I was getting abnormal results. Even though the objects return as equal they are not filtered by .distinct().

What am I missing? Proof below --

List<Element> elements = getStream().filter(e -> e.getName().equals("userId")).collect(Collectors.toList());

System.out.println("Elements with same name: " + elements.size());

if(elements.size() > 1) {
    System.out.println("Equals?: " + elements.get(0).equals(elements.get(1)));
}

System.out.println("Distinct Elements: " + getStream().distinct().count());
System.out.println("Full Elements: " + getStream().count());

Outputs:

Elements with same name: 2
Equals?: true
Distinct Elements: 8
Full Elements: 8

Solution

  • According to the distinct() method of the Stream API (http://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#distinct--):

    Returns a stream consisting of the distinct elements (according to Object.equals(Object)) of this stream.

    Do you override equals() and hashCode() of the Element class appropriately?

    http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object- http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--