ranon-boop
@ranon-boop

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

ArrayList.sort(new Comparator());←なぜOK?

ArrayList.sort(new Comparator());←なぜOK?

なぜ引数をComparator.compare()のようにしなくてよいのでしょうか。

Java SE 11 Silverの勉強中です。
なんでこの書き方で動くの?という種類の質問です。

・問題集のコード
・疑問点

の順に書かせていただきました。

問題集のコード

①Sampleクラス、②SampleComparatorクラス、③Mainクラス、があります。

①Sampleクラス
int型のidと、String型のnameをフィールドに持ち、getterが定義されているだけのシンプルなクラスです。

②SampleComparatorクラス(並べ替えのために用意されている)

//importは省略

public class SampleComparator implements Comparator<Sample> {
    @Override
    public int compare(Sample s1, Sample s2) {
        if(s1.getId() < s2.getId()) {
            return 1;
        }
        if(s2.getId() < s1.getId()) {
            return -1;
        }
        return 0;
    }
}

③Mainクラス

//importは省略

public class Main {
    public static void main(String[] args) {
        Sample[] samples = {
            new Sample(2, "B"),
            new Sample(3, "C"),
            new Sample(1, "A")
        };
        List<Sample> list = new ArrayList<Sample>(Arrays.asList(Samples));
        list.sort(new SampleComparator());    //←わからないのはココです!
        for(Sample s : list) {
            System.out.println(s.getName());
        }
    }
}

疑問

この部分↓を、

list.sort(new SampleComparator());    //←わからないのはココです!

この書き方↓にしなくてよいのはなぜでしょうか?

SampleComparator sampleComparator = new SampleComparator();
list.sort(sampleComparator.compare);

というのも、SampleComparatorクラスにはcompareメソッド以外もあるかもしれないじゃん!と思ってしまうからです。

Mainクラスでsortメソッドに、「並べ替えにはSampleComparatorクラスを使ってね!」と言っているわけですが、「SampleComparatorクラスのcompareメソッドに従って並び替えてね!」とは言ってなくないですか!?

でも私の言ってることの一部または全部が間違っているはずです。
このままでは試験に受かりません泣
どなたか、ご教示いただけないでしょうか。

0

3Answer

@uasi さんの回答に補足すると、

java8以降、Lamda式がサポートされ引数がSAMインターフェースであれば、メソッドを直接渡すことはできますが、

list.sort(sampleComparator.compare);

だとコンパイルエラーとなります(この渡し方をサポートしていないため)。

そうではなく、メソッド参照を使って

list.sort(sampleComparator::compare);

とすれば、コンパイルは通りますし、ソートもされます。

以下SAMインターフェースの解説

3Like

Comments

  1. @ranon-boop

    Questioner

    メソッド参照という書き方があるんですね!!
    Lamda式、ちょうど勉強を始めたところです。ご紹介くださったSAMインターフェースの解説も読んでみます!
    ありがとうございます!!

Mainクラスでsortメソッドに、「並べ替えにはSampleComparatorクラスを使ってね!」と言っているわけですが、「SampleComparatorクラスのcompareメソッドに従って並び替えてね!」とは言ってなくないですか!?

sort メソッドは受け取った Comparator インスタンスの compare メソッドを呼び出してソートすることになっています。

https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html#sort(java.util.Comparator)
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Comparator.html

この書き方↓にしなくてよいのはなぜでしょうか?

そもそも list.sort(sampleComparator.compare); は存在しない compare インスタンス変数を参照しようとしてコンパイルエラーになります。

list.sort(sampleComparator.reversed()); のような書き方はありますが、これは reversed メソッドが逆順ソートを行うような新しい Comparator インスタンスを作って返すからです。 sort メソッドはそのインスタンスの compare メソッドを呼び出してソートを行います。

2Like

sort メソッドは受け取った Comparator インスタンスの compare メソッドを呼び出してソートすることになっています。

そうだったのですね。
ドキュメントに書いてあることをお聞きしてしまい申し訳ありません。

そもそも list.sort(sampleComparator.compare); は存在しない compare インスタンス変数を参照しようとしてコンパイルエラーになります。

確かにおっしゃる通りですね・・・確かに・・・

端的にご指摘いただきありがとうございます!
おかげでずーっと一人で悩むことなく解決しました!

0Like

Your answer might help someone💌