(java gold) Comparatorインターフェース

## Comparator
APIドキュメントより
>オブジェクトのコレクションで全体順序付けを行う比較関数です。コンパレータ(Comparator)をソート・メソッド(Collections.sortやArrays.sortなど)に渡すと、ソート順を正確に制御できます。また、コンパレータを使用すると、sorted sets (ソート・セット)やsorted maps (ソート・マップ)などの特定のデータ構造の順序を制御したり、natural ordering (自然順序付け)を持たないオブジェクトのコレクションに順序付けを提供したりすることもできます。

Javaのクラスがオブジェクトの比較方法をカスタマイズするために実装するインタフェースである。主な目的は、自然な順序付けが定義されていないクラスのオブジェクトを比較するために使用される。
### Compararのメソッド

* compare(T o1, T o2)
順序付けのために2つの引数を比較します。

  * 負の整数：
o1 は o2 よりも小さいと判断される。
  * 0：
o1 と o2 は等しいと判断される。
  * 正の整数：
o1 は o2 よりも大きいと判断される。

例
<Shoseクラス>
```java
import java.time.LocalDate;

public class Shose {

    private int price;
    private String name;
    private LocalDate dateOfIssue;

    Shose(int price, String name, LocalDate dateOfIssue){
        this.price = price;
        this.name = name;
        this.dateOfIssue = dateOfIssue;
    }

    public int getPrice() {
        return price;
    }

    public String getName() {
        return name;
    }

    public LocalDate getDateOfIssue() {
        return dateOfIssue;
    }
}
```
<名前でソートするクラス>
```java
import java.util.Comparator;

public class ShoseNameComparator implements Comparator<Shose> {

    @Override
    public int compare(Shose shose1, Shose shose2){
        return shose1.getName().compareTo(shose2.getName());
    }
}
```
<値段でソートするクラス>
```java
import java.util.Comparator;

public class ShosePriceComparator implements Comparator<Shose> {

    @Override
    public int compare(Shose shose1, Shose shose2){
        return Integer.valueOf(shose1.getPrice()).compareTo(shose2.getPrice());
    }

}
```
<日付でソートするクラス>
```java
import java.util.Comparator;

public class ShoseDateOfIssueComparator implements Comparator<Shose> {

    @Override
    public int compare(Shose shose1, Shose shose2){
        return shose1.getDateOfIssue().compareTo(shose2.getDateOfIssue());
    }
}
```
 < Mainクラス >
 
```java
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;


public class Main {
    public static void main(String[] args) throws Exception {

        // ソート対象の作成
        List<Shose> shoseList = new ArrayList<>();
        shoseList.add(new Shose(8710, "jordan",LocalDate.of(1985,9,15)));   
        shoseList.add(new Shose(10000, "Super Star",LocalDate.of(1969,4,1)));
        shoseList.add(new Shose(7700, "ALL STAR", LocalDate.of(1917,4,2)));

        // ソート実行
        Collections.sort(shoseList, new ShoseDateOfIssueComparator()); 
        // ソート対象を表示する
        System.out.println("--------日付ソート--------");
        shoseList.forEach( s -> System.out.println(s.getDateOfIssue() + ":" + s.getName() + ":" + s.getPrice()));
        System.out.println("--------------------------");

        Collections.sort(shoseList, new ShoseNameComparator()); 
        // ソート対象を表示する
        System.out.println("--------名前ソート--------");
        shoseList.forEach( s -> System.out.println(s.getName() + ":" + s.getPrice() + ":" + s.getDateOfIssue()));
        System.out.println("--------------------------");
        
        Collections.sort(shoseList, new ShosePriceComparator()); 
        // ソート対象を表示する
        System.out.println("--------値段ソート--------");
        shoseList.forEach( s -> System.out.println(s.getPrice() + ":" + s.getName() + ":" + s.getDateOfIssue()));
        System.out.println("--------------------------");
    }
}
```

<実行結果>
```java
// --------日付ソート--------
// 1917-04-02:ALL STAR:7700
// 1969-04-01:Super Star:10000
// 1985-09-15:jordan:8710
// --------------------------
// --------名前ソート--------
// ALL STAR:7700:1917-04-02
// Super Star:10000:1969-04-01
// jordan:8710:1985-09-15
// --------------------------
// --------値段ソート--------
// 7700:ALL STAR:1917-04-02
// 8710:jordan:1985-09-15
// 10000:Super Star:1969-04-01
// --------------------------
```


# ComparableとCompartorの違い

## 実装箇所と実装メソッド
`Comparable`：自身のクラス内にcompareTo()メソッドを実装する。
`Comparator`：独立したクラスや無名クラス、ラムダ式として定義され、compare()メソッドを実装する。

## 使用場所
`Comparable`：オブジェクトのクラス内で使用される。
`Comparator`：外部のクラスで使用される。

## 使用方法
Comparable：自然な順序付けに使用される。
Comparator：カスタムの比較方法に使用される。

:::note info
どちらを使用するかは、具体的な要件などに依存する。
既存のクラスを使用している場合は、Comparatorを使用してオブジェクトの比較方法をカスタマイズできる。
一方、自身のクラスに自然な順序付けを提供したい場合は、Comparableを実装することが適切である
:::