SelectItemのListをソートする方法

選択肢を設定するのによく使うSelectItemのList。データベースから取得した値を使ったりすると並べ替えをしたいことがある。そんな時用。

- 環境
    - CentOS Linux release 7.8.2003 (Core)
    - openjdk version "11.0.7" 2020-04-14 LTS
    - JSF 2.3.9

例えばこんなSelectItemのListがある場合のこと

|value|label|
|:-:|:-:|
|1|いぬ|
|3|さる|
|0|くま|
|2|ねこ|

```java
/** SelectItemのリスト. */
@Getter
private List<SelectItem> items;

/** SelectItemのリストを設定する. */
private void setItems() {
    this.items = new ArrayList<SelectItem>();
    this.items.add(new SelectItem(1, "いぬ"));
    this.items.add(new SelectItem(0, "くま"));
    this.items.add(new SelectItem(3, "さる"));
    this.items.add(new SelectItem(2, "ねこ"));
}
```

# valueの昇順でソートする
参考 : [Collections (Java Platform SE 8)](https://docs.oracle.com/javase/jp/8/docs/api/java/util/Collections.html#sort-java.util.List-java.util.Comparator-)

|value|label|
|:-:|:-:|
|0|くま|
|1|いぬ|
|2|ねこ|
|3|さる|

```java
Collections.sort(this.items, new Comparator<SelectItem>() {
    @Override
    public int compare(SelectItem item1, SelectItem item2) {
        if (item1 != null && item2 != null) {
            if (item1.getValue() != null && item2.getValue() != null) {
                return item1.getValue().toString().compareTo(item2.getValue().toString());
            }
        }
        return 0;
    }
});
```

## (おまけ)valueの最小値を取得する

```java
SelectItem minItem = Collections.min(this.items, new Comparator<SelectItem>() {
    // 内容はソートと同じ
});
var min = Integer.valueOf(minItem.getValue().toString());
```

# valueの降順でソートする
参考 : [Comparator (Java Platform SE 8)](https://docs.oracle.com/javase/jp/8/docs/api/java/util/Comparator.html)

|value|label|
|:-:|:-:|
|3|さる|
|2|ねこ|
|1|いぬ|
|0|くま|

```java
// 昇順のreturnにあるitem1とitem2を逆にしただけ
Collections.sort(this.items, new Comparator<SelectItem>() {
    @Override
    public int compare(SelectItem item1, SelectItem item2) {
        if (item1 != null && item2 != null) {
            if (item1.getValue() != null && item2.getValue() != null) {
                return item2.getValue().toString().compareTo(item1.getValue().toString());
            }
        }
        return 0;
    }
});
```

# labelの昇順でソートする
参考 : [ひらがなとアルファベットがまざったリストのソートをする - Qiita](https://qiita.com/tkskto/items/e98db894a3c59dfb52f9)

|value|label|
|:-:|:-:|
|1|いぬ|
|0|くま|
|3|さる|
|2|ねこ|

```java:Comparator.comparingを使う方法
this.items = this.items.stream().sorted(Comparator.comparing(SelectItem::getLabel)).collect(Collectors.toList());
```

```java:Collator.getInstanceを使う方法
Collections.sort(this.items, new Comparator<SelectItem>() {
    @Override
    public int compare(SelectItem item1, SelectItem item2) {
        if (item1 != null && item2 != null) {
            if (item1.getLabel() != null && item2.getLabel() != null) {
                return Collator.getInstance(Locale.JAPANESE).compare(item1.getLabel(), item2.getLabel());
            }
        }
        return 0;
    }
});
```

# labelの降順でソートする
|value|label|
|:-:|:-:|
|2|ねこ|
|3|さる|
|0|くま|
|1|いぬ|

```java:Comparator.comparingを使う方法
// reversed()をくっつけて降順にする
this.items = this.items.stream().sorted(Comparator.comparing(SelectItem::getLabel).reversed()).collect(Collectors.toList());
```

```java:Collator.getInstanceを使う方法
// 昇順のreturnにあるitem1とitem2を逆にしただけ
Collections.sort(this.items, new Comparator<SelectItem>() {
    @Override
    public int compare(SelectItem item1, SelectItem item2) {
        if (item1 != null && item2 != null) {
            if (item1.getLabel() != null && item2.getLabel() != null) {
                return Collator.getInstance(Locale.JAPANESE).compare(item2.getLabel(), item1.getLabel());
            }
        }
        return 0;
    }
});
```

# ソートしようとして失敗したこと
Comparatorという便利なものを知ったので早速使おうとして失敗した。
`Comparator.comparing(SelectItem::getValue)`あたりでコンパイルエラーになる。
SelectItemのvalueはObjectなのでソートのキーにできないのか・・・な？

```java
this.items = this.items.stream().sorted(Comparator.comparing(SelectItem::getValue)).collect(Collectors.toList());
```