0
0

More than 3 years have passed since last update.

ソート処理について

Posted at

現場でたまにソートして出すという要件があります。
その時に毎回「どうやるんだっけ」となってしまうので、簡単に記事にしようと思います。

配列の場合

これは簡単です。
Arraysクラスのsortメソッドを使用します。
昇順の場合は、

Shojun.java
int[] numArray = {3,2,5};
// Arraysクラスのsortメソッドに並び替える配列を渡す。
Arrays.sort(numArray);
// ソートした配列を出力
Arrays.stream(numArray).forEach(System.out::println);

// 出力結果 2 3 5

降順の場合は、sortメソッドの第二引数にCollections.reverseOrder()を指定します。
ただし、int型配列を並び替えるメソッドは用意されていない為Integer型にすると良いでしょう。

Kojun.java
Integer[] numArray = {3,2,5};
// Arraysクラスのsortメソッドに並び替える配列を渡す。
Arrays.sort(numArray,Collections.reverseOrder());
// ソートした配列を出力
Arrays.stream(numArray).forEach(System.out::println);

// 出力結果 5 3 2

上記と同じように、String型配列もsortメソッドを用いて並び替えができます。

List

これも簡単です。
Collectionsクラスのsortメソッドを使用します。
昇順は、

ShojunList.java
List<Integer> numList = Arrays.asList(3,2,5);
// Collectionsクラスのsortメソッドに並び替えるListを渡す。
Collections.sort(numList);
// ソートしたListを出力
numList.forEach(System.out::println);

// 出力結果 2 3 5

降順の場合は、sortメソッドの第二引数にCollections.reverseOrder()を指定します。

KojunList.java
List<Integer> numList = Arrays.asList(3, 2, 5);
// Collectionsクラスのsortメソッドに並び替えるListを渡す。
Collections.sort(numList, Collections.reverseOrder());
// ソートしたListを出力
numList.forEach(System.out::println);

// 出力結果 5 3 2

String型が入ったListも同じようにソート出来ます!!

Map

まずキーでソートしたい場合ですが、昇順はTreeMapに入れてしまいましょう。

ShojunMap.java
Map<Integer, String> map = new TreeMap<Integer, String>();
// 値を設定。勝手に昇順になります!
map.put(2, "にさん");
map.put(3, "さんさん");
map.put(1, "いちさん");
// 出力
map.forEach((k, v) -> System.out.println(k + ":" + v));

// 出力結果 1:いちさん 2:にさん 3:さんさん

降順はTreeMapのコンストラクタにComparator.reverseOrder()を渡しましょう。

kojunMap.java
Map<Integer, String> map = new TreeMap<Integer, String>(Comparator.reverseOrder());
// 値を設定。勝手に降順になります!
map.put(2, "にさん");
map.put(3, "さんさん");
map.put(1, "いちさん");
// 出力
map.forEach((k, v) -> System.out.println(k + ":" + v));

// 出力結果 3:さんさん 2:にさん 1:いちさん 

値でソートしたい場合はcomparingByValueメソッドでマップの値を比較するコンパレータを取得し、sortedメソッドに渡してあげることで実現できます。
昇順の場合は、

ShojunMap.java
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(2, "にさん");
map.put(3, "さんさん");
map.put(1, "いちさん");
// 値を昇順でソートし、linkedHashMapを作成
map = map.entrySet().stream().sorted(Map.Entry.comparingByValue()).collect(Collectors.toMap(Map.Entry::getKey,
        Map.Entry::getValue, (k1, k2) -> k1, LinkedHashMap::new));
// 出力
map.forEach((k, v) -> System.out.println(k + ":" + v));

// 出力結果 1:いちさん 3:さんさん 2:にさん 

HashMapだと投入順序が担保されませんので、LinkedHashMapに入れるのが良いです。

降順の場合は、comparingByValueメソッドの引数にComparator.reverseOrder()を指定します。

ShojunMap.java
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(2, "にさん");
map.put(3, "さんさん");
map.put(1, "いちさん");
// 値を降順でソートし、linkedHashMapを作成
map = map.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                .collect(Collectors.toMap(Map.Entry::getKey,
                        Map.Entry::getValue, (k1, k2) -> k1, LinkedHashMap::new));
// 出力
map.forEach((k, v) -> System.out.println(k + ":" + v));

// 出力結果 2:にさん 3:さんさん 1:いちさん 

オブジェクト

下記のクラスがあるとします。

Person.java
public class Person {

    private int age;
    private String name;

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

当クラスを年齢順でソートしたい場合、Comparatorインターフェースを実装し、sortメソッドの引数に指定します。

Person.java
// テスト用に、人情報を入れます。
List<Person> personList = new ArrayList<Person>();
personList.add(new Person(20, "Aさん"));
personList.add(new Person(16, "Cさん"));
personList.add(new Person(21, "Bさん"));
// 年齢順でソートします。
personList.sort((p1, p2) -> p1.getAge() - p2.getAge());

personList.forEach(p -> {
    System.out.println(p.getAge() + ":" + p.getName());
});

// 出力結果 16:Cさん 20:Aさん 21:Bさん

年齢が同じ場合は、名前でソートしたい時もあると思います。
その場合はまず年齢を比較して、同じだったら名前を比較すれば良いです。

Person.java
// テスト用に、人情報を入れます。
List<Person> personList = new ArrayList<Person>();
personList.add(new Person(20, "Bさん"));
personList.add(new Person(16, "Cさん"));
personList.add(new Person(20, "Aさん"));
// 年齢順でソートします。年齢が同じ場合は名前順でソートします。
personList.sort((p1, p2) -> {
    int temp = p1.getAge() - p2.getAge();
    return temp == 0 ? p1.getName().compareTo(p2.getName()) : temp;
});

personList.forEach(p -> {
    System.out.println(p.getAge() + ":" + p.getName());
});
// 出力結果 16:Cさん 20:Aさん 20:Bさん

名前は文字列なので、compareToで比較します。

終わりに

javaって一つの処理でも色々書き方があって難しいです。
今回取り上げたソート処理も、いくつか書き方がありもっと効率良く、わかりやすく記述する方法もあると思います。
参考程度で見ていただければ幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0