【问题标题】:Sort HashMap based on multiple conditions基于多个条件对HashMap进行排序
【发布时间】:2020-08-23 19:34:59
【问题描述】:

我有一个具有以下结构的 HashMap,

    {val1#val2=val3#val4-val5}

其中 key = val1#val2 和 value=val3#val4-val5 ,

HashMap<String, String> h = new HashMap<String, String>(); 
    h.put("aaa#bbb", "111#444-555");
    h.put("bbb#aaa", "222#ddd-222");
    h.put("111#999", "000#213-aaa");

我有三个条件,我必须将地图排序为, 1. 通过 val1。 2. 通过 val2。 3. 通过 val3。

【问题讨论】:

  • 首先,您可能想使用LinkedHashMap,因为普通的哈希映射不会保持顺序。
  • 另外,这些值是否总是包含 3 个字符?
  • 那么你想要实现什么?根据它们的键对地图进行排序?
  • 没有值将由# @Schred 分隔
  • HashMap 是无序的。您根本无法对其进行排序,更不用说“基于不同的条件”了。使用TreeMap

标签: java sorting data-structures


【解决方案1】:

HashMaps 不保证顺序,为了得到排序的地图你需要使用 LinkedHashMap。

要对键进行排序,您可以使用 java 流 api,对映射条目进行排序并将它们插入 LinkedHashMap。

    Map<String, String> h = new HashMap<>();
    h.put("aaa#bbb", "111#444-555");
    h.put("bbb#aaa", "222#ddd-222");
    h.put("111#999", "000#213-aaa");

    LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>();
    h.entrySet().stream()
        .sorted(Comparator.comparing(e -> e.getKey().split("#")[0]))// sort by val1
        .sorted(Comparator.comparing(e -> e.getKey().split("#")[1]))// sort by val2
        .sorted(Comparator.comparing(e -> e.getValue().split("#")[0]))// sort by val3
        .forEach(e -> {
            linkedHashMap.put(e.getKey(), e.getValue());
        });

【讨论】:

    【解决方案2】:

    这应该可行:

    public static void main(String[] args) {
        LinkedHashMap<String, String> map = new LinkedHashMap<>();
        map.put("aa#bb", "11111#44-5555555");
        map.put("bb#aa", "22222#ddd-222");
        map.put("11#99", "00000#213-aaa");
    
        Function<Map.Entry<String, String>, String> byVal1 = 
                 entry -> entry.getKey().substring(0, entry.getKey().indexOf('#'));
        Function<Map.Entry<String, String>, String> byVal2 =
                 entry -> entry.getKey().substring(entry.getKey().indexOf('#') + 1);
        Function<Map.Entry<String, String>, String> byVal3 =
                 entry -> entry.getValue().substring(0, entry.getValue().indexOf('#'));
    
        // Just change this value to sort by a different value
        Function<Map.Entry<String, String>, String> value = byVal3;
    
        List<Map.Entry<String, String>> asList = map.entrySet().stream().sorted(Comparator.comparing(value)).collect(Collectors.toList());
        map.clear();
        asList.forEach(entry -> map.put(entry.getKey(), entry.getValue()));
    
        map.entrySet().stream().forEach(entry -> System.out.println(entry));
    }
    

    您当然不必在方法中创建byValX 函数,而是可以使用方法引用。

    【讨论】:

      【解决方案3】:

      不知道这是否是你想要完成的(澄清需要做什么,我可以调整解决方案),但你可以使用TreeMap

      import java.util.Map;
      import java.util.Objects;
      import java.util.TreeMap;
      
      public class TestDictionary {
          public static void main(String[] args) {
              Map<Key, Object> map = new TreeMap<>(new Comparator<Key>() {
              @Override
              public int compare(Key o1, Key o2) {
                  // do whatever you want here
                  return 0;
              }
          });
      
              map.put(new Key("a", "b", "c"), new Value());
              map.put(new Key("b", "c", "a"), new Value());
              map.put(new Key("c", "b", "a"), new Value());
              System.out.println(map);
          }
      
          static class Key {
              String val1;
              String val2;
              String val3;
      
              public Key(String val1, String val2, String val3) {
                  this.val1 = val1;
                  this.val2 = val2;
                  this.val3 = val3;
              }
      
              @Override
              public boolean equals(Object o) {
                  if (this == o) return true;
                  if (o == null || getClass() != o.getClass()) return false;
                  Key key = (Key) o;
                  return val1.equals(key.val1) &&
                         val2.equals(key.val2) &&
                         val3.equals(key.val3);
              }
      
              @Override
              public int hashCode() {
                  return Objects.hash(val1, val2, val3);
              }
          }
      
          static class Value {
              int number;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-18
        • 1970-01-01
        • 2015-12-20
        • 1970-01-01
        • 2020-12-28
        • 1970-01-01
        • 2020-08-23
        • 1970-01-01
        相关资源
        最近更新 更多