有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

按某些键的值对Java排序映射进行排序

如何实现Comparator以按某些键值对映射列表进行排序?我的目标是对两个列表进行任意排序,以便比较不属于排序的其他字段

例如,假设我有这两个地图列表,我想按firstName和lastName排序

+-----------+--------+-------+-------+
| List 1    | Map 1  | Map 2 | Map 3 |
+-----------+--------+-------+-------+
| firstName | John   | Eric  | John  |
| lastName  | Miller | Smith | Davis |
| age       | 17     | 19    | 35    |
+-----------+--------+-------+-------+

+-----------+--------+-------+-------+
|  List 2   | Map 1  | Map 2 | Map 3 |
+-----------+--------+-------+-------+
| firstName | Eric   | John  | John  |
| lastName  | Smith  | Davis | Miller|
| age       | 53     | 38    | 26    |
+-----------+--------+-------+-------+

在我排序之后,现在我可以比较列表1的映射1和列表2的映射2,看看有什么不同

我有一个类实现了比较器,如下所示:

// Note that the values may not implement Comparable
public class PersonComparator implements Comparator<Map<String, Object>> {
    private List<String> sortKeys = Arrays.asList("firstName", "lastName");

    @Override
    public int compare(Map<String, Object> map1, Map<String, Object> map2) {
        Map<String, Object> keyValue1 = new HashMap<>();
        sortKeys.forEach(key -> keyValue1.put(key, map1.get(key)));

        Map<String, Object> keyValue2 = new HashMap<>();
        sortKeys.forEach(key -> keyValue2.put(key, map2.get(key)));

        return keyValue2.hashCode() - keyValue1.hashCode();
    }
}

在每个列表上调用sort将导致以下结果:

+-----------+--------+-------+-------+
| List 1    | Map 1  | Map 2 | Map 3 |
+-----------+--------+-------+-------+
| firstName | John   | Eric  | John  |
| lastName  | Miller | Smith | Davis |
| age       | 17     | 19    | 35    |
+-----------+--------+-------+-------+

+-----------+--------+-------+-------+
| List 2    | Map 1  | Map 2 | Map 3 |
+-----------+--------+-------+-------+
| firstName | John   | Eric  | John  |
| lastName  | Miller | Smith | Davis |
| age       | 26     | 53    | 38    |
+-----------+--------+-------+-------+

但是列表的顺序永远不会改变。。。我做错了什么


共 (1) 个答案

  1. # 1 楼答案

    最终,您的排序是基于密钥的散列码的——这种排序不一定与它们的值相关(即,“较小”的字符串可以有较大的散列码,反之亦然)

    相反,您应该根据值本身进行排序,即使这意味着显式地将Object值转换为可比值:

    Comparator<Map<String, Object>> personComparator =
        Comparator.comparing(m -> (String) m.get("firstName"))
                  .thenComparing(m -> (String) m.get("lastName"));