cp716716
@cp716716

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

【Java】Comparatorインタフェースのcompareメソッドの動きがわかりません

初めての投稿です。
(誤字脱字、至らない点があるかもしれませんがよろしくお願いします。)

Java Silver SE 11 某問題集のコードの動きが分かりません

不明点
・Sampleクラスのsuper()はどこを指しているのか
・Mainクラスのsortメソッドの動き
・SampleComparatorクラスのcomparaメソッドの呼び出し

以下コードの答えは「CBA」と表示されると解説にあります。

Sample.java
public class Sample {
    private int id;
    private String name;
    public Sample(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public String getName() {
        return name;
    }
}
SampleComparator.java
import java.util.Comparator;

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.java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

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());
        }
    }
}

よろしくお願いします。

1

2Answer

Sampleクラスのsuper()はどこを指しているのか

JavaではすべてのクラスがObjectクラスの子クラスという関係になっており、親クラスを指定せずにクラス宣言した場合、親クラスはObjectになります。つまり、super()Objectクラスの引数なしコンストラクタを呼び出しているのと同じになります。

Mainクラスのsortメソッドの動き
SampleComparatorクラスのcomparaメソッドの呼び出し

sortはリストの中身を決められた並び順にしたがってならべかえるメソッドでSampleComparatorSampleクラスの並び方を定めたクラスになります。sortメソッドは、リストの中身のSampleインスタンスを見比べながら並べ替えていくのですが、このときSampleクラスの並び順を決定するためにSampleComparator::compareを呼び出しています。


Main.javaの以下の部分ですが、Arrays.asList(sample)ではなくArrays.asList(samples)の誤りかと思います。

List<Sample> list = new ArrayList<Sample>(Arrays.asList(sample));

Arrays.asList(sample)のままだと、実行はおろかコンパイルすらできませんね(´・ω・)

2Like

Comments

  1. @cp716716

    Questioner

    そういうことだったのですね、、
    やっと理解ができました!
    ご指摘いただいた箇所が誤っていました。
    申し訳ありません。(訂正済)
    どうもありがとうございました!

・Sampleクラスのsuper()はどこを指しているのか

javaでは、明示的に親クラスを指定しない場合に[Object]を継承します。
なので、ここでは[Object]のコンストラクタがよばれています。
とはいえ、ここの[super();]の呼び出しに意味は無いと思います。

おそらく、お使いの参考書のお約束(手癖)で書いてあるだけなのではないでしょうか?
もしくは、著者様がコード整理する際に、親クラスの継承は消したけど[super();]は消し忘れたとか。
どのみち、この[super();]はあってもなくても動作に影響はしません。

・SampleComparatorクラスのcomparaメソッドの呼び出し

@Override の記載がヒントになります。

Comparator を実装したクラスは [compare] メソッドをオーバーライドすることで、ソート処理の対象になった際の挙動を記載します。
この場合、Sample クラスのインスタンスの内容を比較し、ソート処理の際に ID の値が大きい順になるように値を返しています。

・Mainクラスのsortメソッドの動き

ご質問の回答が前後しましたが、[Comparator]を実装したリストに対して、3つのデータを渡してソートしています。
[SampleComparator]の[compare]のルールに従って、[Sample]インスタンスの要素がIDの大きい順に並微変えられます。

このサンプルは、ソートという処理の枠組みがあって、その枠組みにそった実装を紹介するものだと思います。

この辺りの流れは、C言語の[qsort]の流れや、[compare]系の返り値(0で等しい、負で小さい、正で大きい)のルールを踏襲していると思うので、とりあえず「そういものだ」とわりきってしまいましょう。

2Like

Comments

  1. おっと、回答が被ってしまいました。
    neko_the_shadow 様のお答えと同じ内容となります。
  2. @cp716716

    Questioner

    回答いただいたお二方の解説で完全に理解ができました。
    どうもありがとうございました!

Your answer might help someone💌