web-dev-qa-db-ja.com

JavaストリームでLinkedHashMapを値の降順で並べ替える方法は?

昇順に並べ替えるには、次のようにします。

myMap.entrySet().stream()
    .sorted(Map.Entry.comparingByValue())
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue));

どうすればそれを降順で実行できますか?

15
Oxydron

逆順に並べ替えるには、Comparator.reverseOrder()をパラメーターとしてcomparingByValueに渡します。

LinkedHashMapを取得するには、4つの引数toMap()で具体的に要求する必要があります。必要なマップの種類を指定しない場合は、デフォルトであるHashMapが取得されます。 HashMapは要素の順序を保持しないため、間違いなく機能しません。

myMap.entrySet().stream()
        .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
        .collect(Collectors.toMap(
                Map.Entry::getKey, 
                Map.Entry::getValue, 
                (x,y)-> {throw new AssertionError();},
                LinkedHashMap::new
        ));

静的インポートを使用すると、少し快適になります。

myMap.entrySet().stream()
        .sorted(comparingByValue(reverseOrder()))
        .collect(toMap(
                Map.Entry::getKey, 
                Map.Entry::getValue, 
                (x,y)-> {throw new AssertionError();},
                LinkedHashMap::new
        ));
36
Misha

comparingByValueには、任意のコンパレータを渡すことができます。

たとえば、(私はそれをテストすることができないので、私は構文が正しいことを願っています):

_myMap.entrySet().stream()
    .sorted(Map.Entry.comparingByValue((v1,v2)->v2.compareTo(v1)))
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
_

自然順序付け(Comparable 's compareTo)を使用して、2つのエントリの値を反対の順序で比較することにより、comparingByValue()(これはcomparingByValue((v1,v2)->v1.compareTo(v2)))と同じです。

ところで、_Collectors.toMap_がLinkedHashMapインスタンスを返すかどうかはよくわかりません。たとえ現在もそうであるとしても、Javadocはそれを言及していないため、将来変更される可能性があります。それを信頼してください。

結果のMapがLinkedHashMapであることを確認するには、toMapの別のバリアントを使用する必要があります。

_myMap.entrySet().stream()
    .sorted(Map.Entry.comparingByValue((v1,v2)->v2.compareTo(v1)))
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (v1,v2)->v1, LinkedHashMap::new));
_
5
Eran

ストリームには、コンパレータを受け入れるsortedメソッドがあるため、降順の並べ替えには、コンパレータを_(x,y)->y.getKey().compareTo(x.getKey())_として直接使用できます。マップを昇順に並べ替えるには、_(x,y)->x.getKey().compareTo(y.getKey())_のように順序を逆にできます

結果をLinkedHashMapに統合するには、Collectors toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier)を使用できます。これは、提供されたマッピング関数を入力要素に適用した結果のキーと値を持つマップに要素を蓄積するCollectorを返します。

作業コード

_import Java.io.*;
import Java.util.*;
import Java.util.function.*;
import Java.util.stream.Collectors;
import Java.util.stream.*;
public class HelloWorld{

     public static void main(String []args){
        LinkedHashMap<Integer,Integer> hashMap = new LinkedHashMap<Integer,Integer>(); 
            hashMap.put(1,5);
            hashMap.put(7,9);
            hashMap.put(3,8);
            hashMap.put(10,5);

            Function<Map.Entry<Integer,Integer>,Integer> keyMapper = x->x.getKey();
            Function<Map.Entry<Integer,Integer>,Integer> valueMapper = x->x.getValue();
            BinaryOperator< Integer> mergeFunction = (x,y)->x;// we do not want any merging here 
            Supplier<LinkedHashMap<Integer,Integer>> mapRequired =()-> {return new LinkedHashMap<Integer,Integer>();};// to maintain order we must use LinkedHashMap
            Comparator<Map.Entry<Integer,Integer>> descendingComparator = (x,y)->y.getKey().compareTo(x.getKey());
            // we can write it as  

        System.out.println(
                  hashMap.entrySet().stream()
                             .sorted (descendingComparator) 
                             .collect(Collectors.toMap(
                                                      keyMapper,
                                                       valueMapper,
                                                       mergeFunction,
                                                       mapRequired)
                                           )
                );           

// or even by writing below will also work

        System.out.println(
                  hashMap.entrySet().stream()
                             .sorted ((x,y)->y.getKey().compareTo(x.getKey())) 
                             .collect(Collectors.toMap(
                                                       x->x.getKey(),
                                                       x->x.getValue(),
                                                       (x,y)->x,
                                                       LinkedHashMap::new)
                                           )
                );           
     }


}
_
3

Java 1.8 Java.util.Comparator.reversed() から

myMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue().reversed())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
1
Ril Dank