Sort List> based on value

后端 未结 2 665
我在风中等你
我在风中等你 2021-01-16 05:10

Basically I have a List>, and I want to sort it by the values of certain key in the map.

The problem is that I do not know

相关标签:
2条回答
  • 2021-01-16 05:12

    You can generalize comparing numbers by comparing their double values, because they are the largest. If two objects cannot be cast to numbers and the double value cannot be parsed from these objects, then compare their string values:

    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}
    

    See also: Sort 2D List by Column Header

    0 讨论(0)
  • 2021-01-16 05:24

    First you will have to define the desired order, especially the place of the string values, or are they all numbers in text form?

    Then implement a more complex comparator method, working through your comparison criteria from highest to lowest priority.

    Untested:

     List<Map<String, Object>> list = new ArrayList<>();
        Collections.sort(list, (map1, map2) -> {
          Object v1 = map1.get("Field1");
          Object v2 = map2.get("Field1");
    
          // --------------------------------------------
          // handle null
          // --------------------------------------------
          if(v1 == null && v2 == null) {
            return 0;
          }
    
          if(v1 == null && v2 != null) {
            return -1 /* null value before non-null value */;
          }
    
          if(v1 != null && v2 == null) {
            return 1 /* non-null value after null value */;
          }
    
          // --------------------------------------------
          // handle String
          // --------------------------------------------
          boolean v1IsString = v1 instanceof String;
          boolean v2IsString = v2 instanceof String;
          if(v1IsString && v2IsString) {
            return ((String) v1).compareToIgnoreCase((String) v2);
          }
    
          if(v1IsString && !v2IsString) {
            return -1 /* string value before non-string values */;
          }
    
          if(!v1IsString && v2IsString) {
            return 1 /* non-string value after string value */;
          }
    
          // --------------------------------------------
          // handle LocalDate
          // --------------------------------------------
          // ....
    
          // --------------------------------------------
          // handle Instant
          // --------------------------------------------
          // ....
    
          // --------------------------------------------
          // handle BigDecimal and BigInteger
          // --------------------------------------------
          // ....
    
          // --------------------------------------------
          // handle Number
          // --------------------------------------------
          boolean v1IsNumber = v1 instanceof Number;
          boolean v2IsNumber = v2 instanceof Number;
          if(v1IsNumber && v2IsNumber) {
            double d1 = ((Number) v1).doubleValue();
            double d2 = ((Number) v2).doubleValue();
            return (int) Math.signum(d1 - d2);
          }
    
          if(v1IsNumber && !v2IsNumber) {
            return -1 /* number value before non-number values */;
          }
    
          if(!v1IsNumber && v2IsNumber) {
            return 1 /* non-number value after number value */;
          }
    
          // etc.
    
          // --------------------------------------------
          // finally, treat all unhandled value types as equal
          // --------------------------------------------
          return 0;
        });
    
    0 讨论(0)
提交回复
热议问题