如何按多个属性Java8

时间:2018-04-12 08:56:04

标签: java java-8

如何通过多个属性对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))

3 个答案:

答案 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#comparingthenComparing进行排序的另一种方法。

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