【Java】Map(HashMap・TreeMap)のkey・valueでソートする方法

Mapのキーを指定してソートするためにはどうすればいいの?
Mapの値を指定してソートするためにはどうすればいいの?
昇順と降順でソートするためにはどうすればいいの?
複数キーがある場合はどうやってソートするの?

JavaのMapを扱う上で、データをソート(並べ替え)する処理はよく使います。今回はMapでソートする方法について解説していきます。

この記事では、Mapのソートについて

  • 【基礎】HashMapのソート方法
  • 【基礎】TreeMapのソート方法
  • 【発展】複数のキーでソートする方法

などの基本から発展的な内容についてもわかりやすく解説していきます。

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の詳細を以下に説明します。

  1. 定義したMap変数mMapにキー名が1、2、4、5、3の順に値を設定
  2. MapのEntry(キーと値のペア)のリストを作成
  3. Collectionクラスのsortメソッドを使用して、比較関数Comparatorで、MapのEntryの値を比較し、compare関数を使用してMapのEntryのobj1(昇順)、obj2(降順)を定義
  4. compareToメソッドを使用して降順で並べ替えられた要素を返す
  5. ループで要素数を順に表示させていくと、昇順でソートされていく
  6. 降順でソートするときは、compareToメソッドを使用するときに、Entryのobj2(降順)を指定して返せばOK
  7. ループで要素数を順に表示させていくと、降順でソートされていく

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のさまざまな使い方については以下の記事にまとめていますので、ぜひ参考にしてくださいね!

【Java入門】Mapの使い方総まとめ(HashMapで初期化、値のソート)
更新日 : 2019年5月22日

compareToで大小を比較する方法総まとめ

compareToメソッドで大小を比較するいろいろな方法を次の記事にまとめているので、ぜひ確認してください!

【Java入門】compareToで大小を比較をする方法総まとめ(文字列/日付)
更新日 : 2019年4月23日

まとめ

ここでは、Mapでのキー名を指定してのソート、値を指定してのソート、昇順・降順でのソートなどを一通り説明しました。MapやListなどのコレクションをソートする方法は、何パターンかありますが、慣れないうちは難しく感じるかもしれません。

もし、Mapでのソートをする方法を忘れてしまったら、この記事を思い出してくださいね!

LINEで送る
Pocket

無料でSEからWebエンジニアへ転職しませんか?



侍エンジニア塾では、完全未経験の方から現在SEだけどプログラミングはやっていないという経験者まで、幅広い方々の人生を好転させるプログラミング指導を行ってきました。SEの方とお話していくなかで、

  • システムエンジニアという職業だけどコードが書けない
  • 事務作業が多くスキルがないため将来が不安
  • スクールに通うと完全未経験者と同じスタートになるからレベルが合わない
という、すでに知識があるSEならではのお悩みがあることに気づきました。そんな方におすすめなのが、弊社の「転職コース 」です。

弊社では、マンツーマンでレッスンを行いますので、現在お持ちの知識レベルからカリキュラムを作成いたします。さらにこちらの転職コースは無料で受講を始められて転職成功でそのまま卒業できるというとてもお得なコースとなっています。

既に知識のあるSEといっても転職は年齢が若いほど受かりやすいため、まずは無料体験レッスンで今の現状や理想の働き方について一緒に考えていきましょう。

まずは無料体験レッスンを予約する

書いた人

ヤマシタ

エンジニア歴10年のフリーランスエンジニア。ITに関わるさまざまなコンテンツの企画・制作も行っています。
ITに関してはノウハウ系、ライフハック系、トレンド系など、200本以上の執筆経験があります。

おすすめコンテンツ

あなたにぴったりなプログラミング学習プランを無料で診断!

プログラミング学習の効率を劇的に上げる学習メソッドを解説