文字列をComparatorによる並び替えを行う際、任意の順番で行いたい時

文字列をComparatorによる並び替えを行う際、任意の順番で行いたい時

文字列をComparatorによる並び替えを行う際、任意の順番で行いたい時

Comparatorで並び替えを行う時の昇順・降順についての検証についての記事で、
文字列の並び替えを行う場合、「.compareTo」を使うことで自然順序による並び替えを行うことができるということは確認しました。
今回は任意の並び替え順にソートしたい時の条件式についての説明です。

事前準備

物理、英語、数学、国語、歴史という単語を任意の順番でソートを行います。

ソート対象クラス

public class ComparaTarget {
    
    /**
     * keywordKanji
     * 以下の項目しか値に入ってこない
     * 1.物理
     * 2.英語
     * 3.数学
     * 4.国語
     * 5.歴史
     */
    private String keywordKanji;

    public String getKeywordKanji() {
        return keywordKanji;
    }

    public void setKeywordKanji(String keywordKanji) {
        this.keywordKanji = keywordKanji;
    }
}

実行その1(compareToによる昇順ソート)

Comparator

/**
 * 自然順序(昇順)による並び替え
 * @author ito-u-oti
 *
 */
public class sort1 implements Comparator<ComparaTarget> {

    @Override
    public int compare(ComparaTarget o1, ComparaTarget o2) {
        return o1.getKeywordKanji().compareTo(o2.getKeywordKanji());
    }
}

実行後

    System.out.println("★sort1・・・compareToメソッドによる並び替え★");
    List<ComparaTarget> list1 = setUpList();
    System.out.println("★sort1並び替え前★");
    list1.forEach(data -> System.out.println(data.getKeywordKanji()));
    System.out.println("★sort1並び替え後★");
    Collections.sort(list1, parent.new sort1());
    list1.forEach(data -> System.out.println(data.getKeywordKanji()));

結果

★sort1・・・compareToメソッドによる並び替え★
★sort1並び替え前★
英語
物理
国語
英語
歴史
物理
数学
国語
歴史
英語
★sort1並び替え後★
国語
国語
数学
歴史
歴史
物理
物理
英語
英語
英語

実行その2(任意の順でソート)

1、歴史
2、物理
3、英語
4、数学
5、国語
という順番でソートをかけようと思います。

Comparator

/**
 * 任意の順序による並び替え
 * @author ito-u-oti
 *
 */
public class sort3 implements Comparator<ComparaTarget> {
    @Override
    public int compare(ComparaTarget o1, ComparaTarget o2) {

        int calc = changeKey(o1.getKeywordKanji()) - changeKey(o2.getKeywordKanji());
        return calc;
    }

    private int changeKey(String str) {

    switch (str) {
        case "物理":
            return 2;
        case "英語":
            return 3;
        case "数学":
            return 4;
        case "国語":
            return 5;
        case "歴史":
            return 1;
        default:
            return 6;
        }
    }
}

実行後

    System.out.println("");
    System.out.println("★sort3・・・switch制御による任意の順で並び替え・その2★");
    List<ComparaTarget> list3 = setUpList();
    System.out.println("★sort3並び替え前★");
    list3.forEach(data -> System.out.println(data.getKeywordKanji()));
    System.out.println("★sort3並び替え後★");
    Collections.sort(list3, parent.new sort3());
    list3.forEach(data -> System.out.println(data.getKeywordKanji()));

結果

★sort3・・・switch制御による任意の順で並び替え・その2★
★sort3並び替え前★
英語
物理
国語
英語
歴史
物理
数学
国語
歴史
英語
★sort3並び替え後★
歴史
歴史
物理
物理
英語
英語
英語
数学
国語
国語

うまくソートできました。

解説

Comparatorのcompareメソッドの戻り値は「-1」「0」「1」だけではない。
基本的なことかもしれませんが、「正の値」「0」「負の値」によって制御を行います。
よって、「正の値」「負の値」の中でも順番を決めてあげれば任意のソートができるということです。
じゃあそれをどのように二つの比較対象の値で制御するのかというと、下の表になります。

表外の番号がソートにおける優先順位です。
(歴史はリストの先頭に来てほしいので1。その次に物理なので2)
表内の数字は「o1 – o2」を計算した時の値です。
o1の歴史と国語の列を見ると分かりやすいのですが、
o1から見たo2の順位の位置が、上に行くほど正の値が強まり、下に行くほど負の値が強まっています。
この相関関係からcompareしているということです。

ソースはgithubに公開しています。
sorted_compareTo

プログラミングカテゴリの最新記事