根据值对List<Map<String,Object>>进行排序

4

我有一个 List<Map<String,Object>>,我想根据 map 中的某个键的值对它进行排序。

问题是我不知道值的类型... 这个 map 可能包含字符串、整数、双精度浮点数、浮点数等等... 我想要排序:

目前为止

List<Map<String,Object>> data = getResults();
Collections.sort(data, (o1, o2) -> (String.valueOf(o2.get("Field1")))
              .compareTo((String.valueOf(o1.get("Field1")))));

这不是一个好主意,因为数字没有被正确地排序...... 我该如何处理?

2个回答

4

您可以通过比较它们的double值概括比较数字,因为这是最大的。如果两个对象不能被转换为数字,并且无法从这些对象解析出double值,那么请比较它们的字符串值

List<Map<String, Object>> data = Arrays.asList(
        Map.of("Field1", 21.2d),  // Double
        Map.of("Field1", "qqq"),  // String
        Map.of("Field1", "22.5"), // String
        Map.of("Field1", 2),      // Integer
        Map.of("Field1", 3L),     // Long
        Map.of("Field1", 23.1f)); // Float

data.sort(Comparator.comparingDouble((Map<String, Object> map) -> {
    Object object = map.get("Field1");
    if (object instanceof Number) {
        return ((Number) object).doubleValue();
    } else {
        try {
            return Double.parseDouble(String.valueOf(object));
        } catch (NumberFormatException e) {
            return Double.NaN;
        }
    }
}).thenComparing(map -> String.valueOf(map.get("Field1"))));

data.forEach(System.out::println);
// {Field1=2}
// {Field1=3}
// {Field1=21.2}
// {Field1=22.5}
// {Field1=23.1}
// {Field1=qqq}

另请参阅:按列标题将二维列表排序


0

我认为地图中的值应该都是Comparable的实例,所以这样做可能会起作用。这个解决方案可能比被接受的答案更好,因为你可以将自己的类作为值(例如实现了Comparable接口的MyClass)。

List<Map<String, Object>> data = getResults();

Collections.sort(data, (o1, o2) -> {
    Object v1 = o1.get("Field1");
    Object v2 = o2.get("Field1");
    if (v1 instanceof Comparable) {
        // may throw exception if v1 and v2 are not
        // the same type, eg Double compare String
        return ((Comparable) v1).compareTo((Comparable) v2);
    } else {
        return String.valueOf(v1).compareTo(String.valueOf(v2));
    }
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接