【Java】 Mapを値でソートする方法

Javaでソート対応のマップと言えばTreeMapだけど、TreeMapはキーのソートにしか対応してません。

マップの値でのソートはオブジェクト外の要素でソートしたい時などは値でのソートが出来ると便利ですので、今回はその方法をご紹介します。

まず、以下のような汎用メソッドを配置しましょう。


	/**
	 * 指定したマップを値でソートした結果をキーのリストで返す。
	 * 
	 * @param map
	 *            ソート対象のマップインスタンス。
	 * @param comparator
	 *            比較用インスタンス。
	 * @return 値でソートされたキーの一覧
	 */
	public static <k , V extends Comparable<V>> List</k><k> sortMapByValue(
			Map</k><k , V> map, final Comparator<v> comparator) {
		// Mapだとソートできないので、Listに変換する。
		ArrayList<map .Entry<K, V>> list = new ArrayList</map><map .Entry<K, V>>(
				map.entrySet());

		// 値の比較に使うインスタンス。
		Comparator<java .util.Map.Entry<K, V>> entryComparator = new Comparator<map .Entry<K, V>>() {

			@Override
			public int compare(java.util.Map.Entry<k , V> rhs,
					java.util.Map.Entry</k><k , V> lhs) {
				return comparator.compare(rhs.getValue(), lhs.getValue());
			};
		};

		// ソート実行。
		Collections.sort(list, entryComparator);

		// 結果をキーのリストに変換して返す。
		List</k><k> result = new ArrayList</k><k>();
		for (Map.Entry</k><k , V> entry : list) {
			result.add(entry.getKey());
		}
		return result;
	}

	/**
	 * 指定したマップを値で昇順ソートした結果をキーのリストで返す。
	 * 
	 * @param map
	 *            ソート対象のマップインスタンス。
	 * @return 値でソートされたキーの一覧
	 */
	public static </k><k , V extends Comparable<V>> List</k><k> sortMapByValue(
			Map</k><k , V> map) {
		return sortMapByValue(map,
				Collections.<v> reverseOrder(Collections.</v><v> reverseOrder()));
	}

あとはこれを使うだけ。

	public static void main(String[] args) {
		Map<string , Integer> map = new HashMap</string><string , Integer>();
		map.put("aaa", 1000);
		map.put("bbb", 51);
		map.put("ccc", 556);
		map.put("ddd", 123);
		map.put("eee", 45000);
		map.put("fff", 1232131);
		List</string><string> list = sortMapByValue(map);
		System.out.println("--昇順--");
		for (String k : list) {
			System.out.println(k + " = " + map.get(k));
		}
		System.out.println("--降順--");
		List</string><string> reversedList = sortMapByValue(map,
				Collections.<integer> reverseOrder());
		for (String k : reversedList) {
			System.out.println(k + " = " + map.get(k));
		}
}

実行結果:

--昇順--
bbb = 51
ddd = 123
ccc = 556
aaa = 1000
eee = 45000
fff = 1232131
--降順--
fff = 1232131
eee = 45000
aaa = 1000
ccc = 556
ddd = 123
bbb = 51

ジェネリック型で定義しているので何にでも利用できます。
ソースの動作保証はしませんが、ご自由にお使いください。