Java stream distinct does not work on custom objects?

armani :

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

I have a list of custom objects with some duplicates. When I run distinct() method on the streamed list, I still get the original list back. Why are the duplicates not getting removed even though I defined an equals method in the custom object ?

Code :

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

class CustomType {
    private String data1;

    public CustomType(String data1) { this.data1 = data1; }
    public String getData1() { return data1; }

    @Override
    public boolean equals(Object other){
        CustomType otherC = (CustomType) other;
        return this.getData1().equals(otherC.getData1());
    }

    @Override
    public String toString(){
        return "[" + data1 + "]";
    }
}

public class StreamDistinctTest {
    public static void main(String [] args){
        List<CustomType> data = Arrays.asList(
            new CustomType("a"),
            new CustomType("b"),
            new CustomType("a"),
            new CustomType("c")
        );

        List<CustomType> filtered = data.stream().distinct().collect(Collectors.toList());
        filtered.forEach(System.out::println);
    }
}

Output :

[a]
[b]
[a]
[c]

BTW, I put a breakpoint in CustomType.equals(arg) and noticed that distinct( ) does not even call equals(arg).

Hovercraft Full Of Eels :

You always should override hashCode when overriding equals, else your equals method doesn't obey the expected contract:

@Override
public int hashCode() {
    return data1.hashCode();
}

This works suggesting that distinct() first tests using hashCode and then if hashCodes are the same, uses the equals method.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=334635&siteId=1