Java - Stream.distinct()の使用方法と例

Java8で導入されたStreamの distinct()について調べてみましょう。

1. Stream の distinct() メソッド

distinctの辞書的な意味は「区別できる」です。 Streamでは、distinct()メソッドはストリームから重複する要素をすべて削除し、新しいストリームを返します。

次の例では、stream1はリストのストリームであり、stream2はstream1から重複が削除された要素のストリームになります。 distinct() は重複を削除し、新しいストリームを返します。

List<String> strings =
        Arrays.asList("google", "apple", "google", "apple", "samsung");

Stream<String> stream1 = strings.stream();
Stream<String> stream2 = stream1.distinct();
stream2.forEach(System.out::println);

Output:

google
apple
samsung

ちなみに、 distinct() メソッドで重複する要素を確認するとき、同じオブジェクトかどうかを判断する基準は Object.equals(Object) メソッドです。 上記の例では、Stringクラスは equals() が既に実装されているので問題はありませんが Custom クラスなら正しく実装が正しいか確認してみる必要はあります。

2. Custom クラスに対する distinct() の使用例

distinct() で重複を判別する基準が equals() と呼ばれました。カスタムクラスで equals() をオーバーライドしない場合は、デフォルトで継承した equals() を使用します。

もしクラスの特定の要素だけ同じなら、同じオブジェクトと判断したいときは、 equals() を自分の状況に合わせてオーバーライドしなければなりません。

注意すべき点は、 equals() をオーバーライドするときに hashCode() も一緒にオーバーライドしなければなりません。 distinct() で重複する要素を判別するとき、まず hashCode() を使ってオブジェクトが異なることを確認し、 equals() で等しいかどうかチェックするようです。どちらか一方が再定義されていないと、正しく動作しない可能性があります。

次の例では、MyStringというカスタムクラスを定義し、 hashCode()equals() をオーバーライドしました。

public class StreamExample5 {
    public static void main(String args[]) {
        List<MyString> myStrings =
                Arrays.asList(new MyString("google"),new  MyString("apple"),
                        new MyString("google"), new MyString("apple"), new MyString("samsung"));
        Stream<MyString> stream3 = myStrings.stream();
        Stream<MyString> stream4 = stream3.distinct();
        stream4.forEach(System.out::println);

    }

    public static class MyString {
        public String str;

        public MyString(String str) {
            this.str = str;
        }

        @Override
        public boolean equals(Object o) {
            if (o instanceof MyString) {
                return str.equals(((MyString) o).str);
            }
            return false;
        }

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

        @Override
        public String toString() {
            return str;
        }
    }
}

Output:

google
apple
samsung

Related Posts

codechachaCopyright ©2019 codechacha