排序列表<Map<String,Object>> 基于值
Sort List<Map<String,Object>> based on value
基本上我有一个 List<Map<String,Object>>
,我想按映射中某个键的值对它进行排序。
问题是我不知道类型...此映射可以包含字符串、整数、双精度数、浮点数等....我想对其进行排序:
到目前为止
List<Map<String,Object>> data = getResults();
Collections.sort(data, (o1, o2) -> (String.valueOf(o2.get("Field1")))
.compareTo((String.valueOf(o1.get("Field1")))));
这不是一个好主意,因为数字没有正确排序....
我该如何处理?
您可以概括比较数字,方法是比较它们的双倍值,因为它们是最大的。如果两个对象无法转换为 numbers 且 double 值 无法从这些对象中解析,则比较它们的 string 值:
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}
另请参阅:
我认为地图中的值应该都是 Comparable 的实例,所以这样的事情可能会起作用。该解决方案可能比公认的答案更好,因为您可以将自己的 class 作为值(例如实现 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));
}
});
基本上我有一个 List<Map<String,Object>>
,我想按映射中某个键的值对它进行排序。
问题是我不知道类型...此映射可以包含字符串、整数、双精度数、浮点数等....我想对其进行排序:
到目前为止
List<Map<String,Object>> data = getResults();
Collections.sort(data, (o1, o2) -> (String.valueOf(o2.get("Field1")))
.compareTo((String.valueOf(o1.get("Field1")))));
这不是一个好主意,因为数字没有正确排序.... 我该如何处理?
您可以概括比较数字,方法是比较它们的双倍值,因为它们是最大的。如果两个对象无法转换为 numbers 且 double 值 无法从这些对象中解析,则比较它们的 string 值:
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}
另请参阅:
我认为地图中的值应该都是 Comparable 的实例,所以这样的事情可能会起作用。该解决方案可能比公认的答案更好,因为您可以将自己的 class 作为值(例如实现 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));
}
});