Чтобы отсортировать его по возрастанию, я могу использовать:
myMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
Как я могу сделать это в порядке убывания?
Чтобы отсортировать его по возрастанию, я могу использовать:
myMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
Как я могу сделать это в порядке убывания?
Так как Java 1.8 java.util.Comparator.reversed()
myMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue().reversed())
.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
compareTo
), вы получите обратный порядок по сравнению с тем, что comparingByValue()
(что эквивалентно comparingByValue((v1,v2)->v1.compareTo(v2))
) будет дайте вам.
Кстати, я не уверен, что Collectors.toMap
возвращает экземпляр LinkedHashMap
, и даже если он в настоящее время работает, он может измениться в будущем, поскольку Javadoc не упоминает об этом, поэтому вы не можете положиться на нем.
Чтобы убедиться, что результирующая Карта будет 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)
, который
Возвращает коллекционер, который накапливает элементы в карту, ключи и значения которой являются результатом применения предоставленных функций отображения к входным элементам.
Рабочий код
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)
)
);
}
}