如何通过多个属性对HashMap条目进行排序。
假设我有一个带有键字符串和值为Object的映射。
Map<String, UserMetrics> map = new HashMap<>
map.put("user10",new UserMetrics(1,100,111));
map.put("user3",new UserMetrics(10,330,444));
map.put("user11",new UserMetrics(333,100,555));
map.put("user1",new UserMetrics(1,111,433));
public static class UsageMetrics implements Serializable {
private long param1;
private long param2;
private long param3;....
}
我想首先用“param1”对用户进行排序,然后用“param2”
进行排序预期结果:&lt;&gt;
user10, UserMetrics(1,100,111)
user1, UserMetrics(1,111,433))
user3, UserMetrics(10,330,444));
user11, UserMetrics(333,100,555))
答案 0 :(得分:5)
您可以使用以下比较器进行排序:
Comparator
.comparingLong(UserMetrics::getParam1)
.thenComparingLong(UserMetrics::getParam2);
然而,困难在于您要对值进行排序,而不是键。你似乎也需要键和值。为此,您可以对地图的条目集进行复制和排序。一些事情:
List<Map.Entry<String, UserMetrics>> sortedEntries = new ArrayList<>(map.entrySet());
Collections.sort(sortedEntries,
Map.Entry.comparingByValue(
Comparator
.comparingLong(UserMetrics::getParam1)
.thenComparingLong(UserMetrics::getParam2)));
或者您也可以使用已排序的集合(如TreeSet
)或已排序的流 - 通常您可以将自己的比较器提供给&#34;排序事物&#34;。
另请注意,我使用comparingLong
/ thenComparingLong
,与其他人使用comparing
/ thenComparing
的答案不同。 comparing
/ thenComparing
的问题在于,如果您有long
之类的基本类型,comparing
/ thenComparing
基本上会将它们包装成包含类型{{1}这完全没必要。
答案 1 :(得分:1)
您可以使用以下代码。我使用Employee
s值对象编写,因此您可以使用自己的Object
:
public class Main {
public static void main(String[] args) throws InterruptedException {
HashMap<String, Employee> map = new HashMap<>();
Map<String, Employee> sortedMap = map.entrySet()
.stream()
.sorted(Entry.comparingByValue(Main::compare))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue,
(e1, e2) -> e1, LinkedHashMap::new));
}
public static int compare(Employee e1, Employee e2) {
return e1.getAge() - e2.getAge();
}
}
<强>被修改强>:
这是您可以使用Comparator#comparing
和thenComparing
进行排序的另一种方法。
Map<String, Employee> sortedMap = map.entrySet()
.stream()
.sorted(Entry.comparingByValue(
Comparator.comparing(Employee::getAge)
.thenComparing(Employee::getSalary)))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue,
(e1, e2) -> e1, LinkedHashMap::new));
答案 2 :(得分:0)
<mutex>
不是按值排序的有效数据结构。但如果你真的需要使用它,你可以尝试这样的事情:
HashMap