LoginSignup
2
5

More than 5 years have passed since last update.

Stream API を使用して Map をソートする

Last updated at Posted at 2018-11-11

概要

Java にて Map に格納されている Entry を Value (降順) 、Key (昇順) の順番でソートしたいと考えました。
簡単にソートしたいので、Stream API を使用することを考えましたが、使用方法について少しはまってしまったので自分用に備忘録を残したいと思います。

ソート前

key value
21 10
11 12
2 10

ソート後

key value
11 12
2 10
21 10

実装

Sort.java

import java.util.*;
import java.util.stream.Collectors;

public class Sort {

    public static void main(String[] args) {
        // 挿入順は担保されないが上記図のイメージに合わせて挿入
        Map<Integer, Integer> map = new HashMap<>();
        map.put(21, 10);
        map.put(11, 12);
        map.put(2, 10);
        Map<Integer, Integer> result = map.entrySet().stream()
                .sorted(Map.Entry.<Integer, Integer>comparingByValue().reversed()
                        .thenComparing(Map.Entry.comparingByKey()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));

        for (Map.Entry<Integer, Integer> sorted : result.entrySet()) {
            System.out.printf("Key is %d  value is %d \n", sorted.getKey(), sorted.getValue());
        }
    }
}

結果
Key is 11  value is 12 
Key is 2  value is 10 
Key is 21  value is 10 

補足

HashMap では挿入順序が担保されないので、LinkedHashMap を使用しています。

HashMap
Mapインタフェースのハッシュ表に基づく実装です。この実装は、マップに関連するオプションのオペレーションをすべてサポートし、null値およびnullキーを使用できます。HashMapクラスはHashtableと同じとみなしてもかまいませんが、HashMapの方は同期がとられず、nullの場合もあります。このクラスはマップの順序を保証しません。特に、その順序を常に一定に保つことを保証しません。

LinkedHashMap
この実装では、HashMapおよびHashtableで提供される未指定(無秩序)の順序がクライアントで起きることはありません(TreeMapのように負荷が増えることもありません)。この実装を使用することで、元のマップの実装にかかわらず、元のマップと同じ順序のコピーを作成できます。

参考

こちらのページ から学習させていただきました。

toMap の引数は、下記となっています。

N 引数名 内容
1 keyMapper 新規Map のため Key を生成するための関数
2 valueMapper 新規Map のため value を生成するための関数
3 mergeFunction 新規キー (例では key になる)
4 mapSupplier 新規Mapインスタンスを生成する関数
Collectors.java

    * @param <T> the type of the input elements
     * @param <K> the output type of the key mapping function
     * @param <U> the output type of the value mapping function
     * @param <M> the type of the resulting {@code Map}
     * @param keyMapper a mapping function to produce keys
     * @param valueMapper a mapping function to produce values
     * @param mergeFunction a merge function, used to resolve collisions between
     *                      values associated with the same key, as supplied
     *                      to {@link Map#merge(Object, Object, BiFunction)}
     * @param mapSupplier a function which returns a new, empty {@code Map} into
     *                    which the results will be inserted
     * @return a {@code Collector} which collects elements into a {@code Map}
     * whose keys are the result of applying a key mapping function to the input
     * elements, and whose values are the result of applying a value mapping
     * function to all input elements equal to the key and combining them
     * using the merge function
     *
     * @see #toMap(Function, Function)
     * @see #toMap(Function, Function, BinaryOperator)
     * @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
     */
    public static <T, K, U, M extends Map<K, U>>
    Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
                                Function<? super T, ? extends U> valueMapper,
                                BinaryOperator<U> mergeFunction,
                                Supplier<M> mapSupplier) {

}
2
5
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
2
5