【问题标题】:Sort the TreeMap conditionally using Comparator使用 Comparator 有条件地对 TreeMap 进行排序
【发布时间】:2021-11-01 17:41:27
【问题描述】:

我想按给定的顺序对 TreeMap 进行排序。 如果字符串中有'_',放在最后,或者保持添加的顺序。

 class Order implements Comparator<String> {
      @Override
      //This works but mess up the group order. For instance bbbb comes after 'aaaa' 
      //  instead of 'cccc'
      public int compare(String o1, String o2) {
        if(o1.contains("_")) {
          order = 1;
        }
        if(o2.contains("_")) {
          order = order == 1? 0: -1;
        }
        return order == 0 ? o1.compareTo(o2) : order;
      }
    }
    class Test {
      public static void main(String[] args) {
        Map<String, String> treeMap= new TreeMap<>(new Order());
        signalTypeMap.put("ccc_aaaa", "test");
        signalTypeMap.put("aaaa", "test");
        signalTypeMap.put("cccc", "test");
        signalTypeMap.put("bbbb", "test");
        signalTypeMap.put("ccc", "test");
        signalTypeMap.put("c_a", "test");
      }
}

最后,地图应该按照以下顺序。

{ aaaa=test, cccc=test bbbb=test, ccc=test, ccc_aaaa=test, c_a=test}

【问题讨论】:

  • Comparator.comparingBoolean(s -&gt; s.contains("_")).thenComparing(Comparator.naturalOrder())?
  • "或者保持添加的顺序" TreeMap 不保留插入顺序。它只使用比较器,比较器不应该知道插入顺序。
  • @AndyTurner 我没有看到类似比较Boolean()
  • Java 太旧,然后Comparator.comparingInt(s -&gt; s.contains("_")? 1 : 0).thenComparing(Collator.getInstance(Locale.US))。我建议在有特殊字符时使用语言环境,因此在德语中,“Österreich”(奥地利)放在“P”之前
  • @k314159 我只是再次编造 API 方法。我当然是指Comparator.comparing(s -&gt; s.contains("_"))

标签: java comparator treemap


【解决方案1】:

你想要的是保持相同的顺序,但最后有下划线。尽管这在现有地图上运行,但以下将起作用。它使用LinkedHashMap 来保留订单。

Map<String, String> map = new LinkedHashMap<>();

map.put("ccc_aaaa", "test");
map.put("aaaa", "test");
map.put("cccc", "test");
map.put("bbbb", "test");
map.put("ccc", "test");
map.put("c_a", "test");
  • 首先,迭代条目集。由于将从地图中删除元素,因此您需要遍历副本,以免得到modification exceptions
  • 如果键是下划线,请将其删除,然后重新添加。现在它将按照下划线键的原始相对顺序位于末尾。
  • 否则,忽略该条目。

for (Entry<String, String> entry : new LinkedHashMap<>(map)
        .entrySet()) {
    String key = entry.getKey();
    if (key.contains("_")) {
        map.remove(key);
        map.put(key, entry.getValue());
    }
}

map.entrySet().forEach(System.out::println);

打印

aaaa=test
cccc=test
bbbb=test
ccc=test
ccc_aaaa=test
c_a=test

【讨论】:

    【解决方案2】:

    在您的比较器中,您没有检查输入字符串中是否有_。然后您可以根据要比较的其他字符串返回 1、0、-1。

    为了在bbbb 之前添加cccc,您需要定义自己的规则。默认会按字典顺序对输入字符串进行排序。

    【讨论】:

      猜你喜欢
      • 2013-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多