Mapの値を指定してソートするためにはどうすればいいの?
昇順と降順でソートするためにはどうすればいいの?
複数キーがある場合はどうやってソートするの?
JavaのMapを扱う上で、データをソート(並べ替え)する処理はよく使います。今回はMapでソートする方法について解説していきます。
この記事では、Mapのソートについて
- 【基礎】HashMapのソート方法
- 【基礎】TreeMapのソート方法
- 【発展】複数のキーでソートする方法
などの基本から発展的な内容についてもわかりやすく解説していきます。
なお、Javaの記事については、こちらにまとめています。
HashMapのソート方法
ここでは、HashMapのソートについて、
- キー名でソートする方法
- 値を指定して昇順と降順でソートする方法
の方法をそれぞれ説明します。
キー名でソートする方法
Mapをキー名指定でソートする場合、Objectクラスを使用してMapの要素数を取得し、ソートするためにArrays.sortメソッドを使用します。以下にキー名でソートする方法を記述します。
なお、Arrays.sortメソッドを使用するためには、java.util.Arraysをインポートする必要があります。
import java.util.Map; import java.util.HashMap; import java.util.Arrays; public class Main { public static void main(String[] args) { // Mapの宣言 Map<Integer, String> mMap = new HashMap<Integer, String>(); // Mapにデータを格納 mMap.put( 1, "apple"); mMap.put( 2, "orange"); mMap.put( 4, "pineapple"); mMap.put( 5, "strawberry"); mMap.put( 3, "melon"); // キーでソートする Object[] mapkey = mMap.keySet().toArray(); Arrays.sort(mapkey); for (Integer nKey : mMap.keySet()) { System.out.println(mMap.get(nKey)); } } }
実行結果:
apple orange melon pineapple strawberry
このサンプルコードでは、定義したMap変数mMapにキー名が1、2、4、5、3の順に値を設定しています。Objectクラスを宣言し、変数mapkeyにMapの要素を全て取得します。次にArraysクラスのsortメソッドを使用し、Mapのキーをソートしています。
ループでMapの値を確認すると、ソートされていることがわかります。
値でソートする方法(compareToを使用)
ここでは、Mapの値を指定して、昇順と降順それぞれのソートの方法について記載します。
import java.util.Map; import java.util.Map.Entry; import java.util.HashMap; import java.util.List; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; public class Main { public static void main(String[] args) { Map<String, Integer> mMap = new HashMap<String, Integer>(); // 1. Mapにデータを格納 mMap.put( "apple", 1); mMap.put( "orange", 2); mMap.put( "pineapple", 4); mMap.put( "strawberry", 5); mMap.put( "melon", 3); // 2.Map.Entryのリストを作成する List<Entry<String, Integer>> list_entries = new ArrayList<Entry<String, Integer>>(mMap.entrySet()); // 3.比較関数Comparatorを使用してMap.Entryの値を比較する(昇順) Collections.sort(list_entries, new Comparator<Entry<String, Integer>>() { public int compare(Entry<String, Integer> obj1, Entry<String, Integer> obj2) { // 4. 昇順 return obj1.getValue().compareTo(obj2.getValue()); } }); System.out.println("昇順でのソート"); // 5. ループで要素順に値を取得する for(Entry<String, Integer> entry : list_entries) { System.out.println(entry.getKey() + " : " + entry.getValue()); } // 6. 比較関数Comparatorを使用してMap.Entryの値を比較する(降順) Collections.sort(list_entries, new Comparator<Entry<String, Integer>>() { //compareを使用して値を比較する public int compare(Entry<String, Integer> obj1, Entry<String, Integer> obj2) { //降順 return obj2.getValue().compareTo(obj1.getValue()); } }); System.out.println("降順でのソート"); // 7. ループで要素順に値を取得する for(Entry<String, Integer> entry : list_entries) { System.out.println(entry.getKey() + " : " + entry.getValue()); } } }
実行結果:
昇順でのソート apple : 1 orange : 2 melon : 3 pineapple : 4 strawberry : 5 降順でのソート strawberry : 5 pineapple : 4 melon : 3 orange : 2 apple : 1
このサンプルコードのコメントに記載している、1〜7の詳細を以下に説明します。
- 定義したMap変数mMapにキー名が1、2、4、5、3の順に値を設定
- MapのEntry(キーと値のペア)のリストを作成
- Collectionクラスのsortメソッドを使用して、比較関数Comparatorで、MapのEntryの値を比較し、compare関数を使用してMapのEntryのobj1(昇順)、obj2(降順)を定義
- compareToメソッドを使用して降順で並べ替えられた要素を返す
- ループで要素数を順に表示させていくと、昇順でソートされていく
- 降順でソートするときは、compareToメソッドを使用するときに、Entryのobj2(降順)を指定して返せばOK
- ループで要素数を順に表示させていくと、降順でソートされていく
TreeMapのソート方法
TreeMapもHashMapと同じようにMapを実装したコレクションクラスです。基本的な使用方法はHashMapと同じですが、TreeMapの特性としてputメソッドで格納した値を内部で自動的にソートして保持されます。以下にTreeMapを使用したサンプルコードを記述します。
なお、TreeMapを使用する際には、java.util.TreeMapをインポートする必要があります。
import java.util.Map; import java.util.TreeMap; public class Main { public static void main(String[] args) { // Mapの宣言 Map<Integer, String> mMap = new TreeMap<Integer, String>(); // Mapにデータを格納 mMap.put(1, "apple"); mMap.put(2, "orange"); mMap.put(5, "pineapple"); mMap.put(3, "strawberry"); mMap.put(4, "melon"); // keySetを使用してMapの要素数分ループする for (Integer nKey : mMap.keySet()) { System.out.println(mMap.get(nKey)); } } }
実行結果:
apple orange strawberry melon pineapple
このサンプルコードでは、キーを1、2、5、3、4の順に格納していますが、実行結果の値を確認すると、値のキーがソートされていることがわかります。
複数のキーでソートする方法
ここでは、MapとListが入れ子になっている場合にソートする方法を紹介します。
import java.util.Map; import java.util.Map.Entry; import java.util.HashMap; import java.util.List; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; public class Main { public static void main(String[] args) { // Map(mMap1)の宣言 Map<List, Integer> mMap1 = new HashMap<List, Integer>(); // list(lList1)の宣言 List<String> lList1 = new ArrayList<String>(); lList1.add("apple"); mMap1.put(lList1, 2); // list(lList2)の宣言 List<String> lList2 = new ArrayList<String>(); lList2.add("orange"); mMap1.put(lList2, 3); // list(lList3)の宣言 List<String> lList3 = new ArrayList<String>(); lList3.add("melon"); mMap1.put(lList3, 1); // Map.Entry のリストを作る List<Entry<List, Integer>> list_entries = new ArrayList<Entry<List, Integer>>(mMap1.entrySet()); // 比較関数Comparatorを使用してMap.Entryの値を比較する Collections.sort(list_entries, new Comparator<Entry<List, Integer>>() { // compareを使用して値を比較する public int compare(Entry<List, Integer> obj1, Entry<List, Integer> obj2) { return obj1.getValue().compareTo(obj2.getValue()); } }); // ループでリストの中身を表示する for(Entry<List, Integer> entry : list_entries) { System.out.println(entry.getKey() + " : " + entry.getValue()); } } }
実行結果:
[melon] : 1 [apple] : 2 [orange] : 3
このサンプルコードでは、Map変数mMap1に、作成したlList1、lList2、lList3をそれぞれMapの値2、3、1の順に格納しています。次にMapの値でのソート方法同様に、MapのEntryのリストを作成して、比較関数を使用してソートした結果を返しています。
Mapについてもっと詳しく知りたい方へ
Mapのさまざまな使い方については以下の記事にまとめていますので、ぜひ参考にしてくださいね!
compareToで大小を比較する方法総まとめ
compareToメソッドで大小を比較するいろいろな方法を次の記事にまとめているので、ぜひ確認してください!
まとめ
ここでは、Mapでのキー名を指定してのソート、値を指定してのソート、昇順・降順でのソートなどを一通り説明しました。MapやListなどのコレクションをソートする方法は、何パターンかありますが、慣れないうちは難しく感じるかもしれません。
もし、Mapでのソートをする方法を忘れてしまったら、この記事を思い出してくださいね!