昇順に並べ替えるには、次のようにします。
myMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
どうすればそれを降順で実行できますか?
逆順に並べ替えるには、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
));
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));
_
ストリームには、コンパレータを受け入れる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)
)
);
}
}
_
Java 1.8 Java.util.Comparator.reversed() から
myMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue().reversed())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));