【问题标题】:Reverse order of LinkedHashMap to LinkedHashMap or ArrayListLinkedHashMap 倒序到 LinkedHashMap 或 ArrayList
【发布时间】:2018-07-09 11:14:05
【问题描述】:

我有一个LinkedHashMap<String,String>,看起来像这样(不知道如何说明 HashMap):

{
  "10/10/2010 10:10:10" => "SomeText1",
  "10/10/2019 10:10:19" => "SomeText2",
  "10/10/2020 10:10:20" => "SomeText3",
  "10/10/2021 10:10:21" => "SomeText4"
}

我想这样说:

{
  "10/10/2021 10:10:21" => "SomeText4",
  "10/10/2020 10:10:20" => "SomeText3",
  "10/10/2019 10:10:19" => "SomeText2",
  "10/10/2010 10:10:10" => "SomeText1"
}

我已经编写了这个可行的解决方案,因为我想要的结果是一个 ArrayList,但我在想是否有更简单的方法来反转 LinkedHashMap,使用像 sort 这样的工具来保持相同的类型例子。

private LinkedHashMap<String, String> map = new LinkedHashMap<>();
int sizeOfHashMap = map.size();
ArrayList reversedHashToArrayList = new ArrayList(map.size());
   for (Map.Entry<String,String> entry : map.entrySet()) {
   String key = entry.getKey();
   String value = entry.getValue();

   reversedHashToArrayList.add(0,entry);
}

【问题讨论】:

  • 你真的需要倒过来的LinkedHashMap吗?在需要的地方以相反的顺序迭代它不是更简单吗?
  • 任何地图都是无序结构。您不能指望地图上有任何个订单。它的唯一目的是存储键值对。集合中键的顺序可以在运行时轻松更改,您永远不要期望地图中的任何顺序
  • @VladyslavMatviienko 好吧,这正是您使用具有可预测迭代顺序的LinkedHashMap 的原因...
  • @VladyslavMatviienko 这就是我使用 LinkedHasMap 的原因,正如 Ben 解释的那样

标签: java android hashmap linkedhashmap


【解决方案1】:

LinkedHashMap 按插入排序;按关联的日期时间排序会更合乎逻辑:

private SortedMap<LocalDateTime, String> map = new TreeMap<>(Comparator.naturalOrder()
                                                                       .reversed());

LocalDateTimeFormatter formatter = LocalDateTimeFormatter.ofPattern("MM/dd/uuuu HH:mm:ss");
map.put(LocalDateTime.parse("10/10/2010 10:10:10", formatter), "...");

要指定地图是排序的,有SortedMap接口。更好地使用更通用的界面。排序地图的实现类是 TreeMap。但是你想要一个反向比较。

您可以使用本地特定模式。请注意,上面我选择了月/日,而不是英国日/月。

【讨论】:

    【解决方案2】:

    如果您的动机只是反转地图(按降序显示),您可以使用 Java.util.TreeMap.descendingMap() :它返回映射中包含的映射的倒序视图`

    LinkedHashMap<String,String> map = .... //this is your intial hashmap
    TreeMap<String,String> tmap = new TreeMap<>(map);
    map.clear();
    map.putAll(tmap.descendingMap());
    

    这样就可以了。

    【讨论】:

      【解决方案3】:

      这是我自己的书面逻辑。不使用任何内置函数来反转:

       LinkedHashMap<String, String> map = new LinkedHashMap<>();
          map.put("10/10/2010 10:10:10", "SomeText1");
          map.put("10/10/2019 10:10:19", "SomeText2");
          map.put("10/10/2020 10:10:20", "SomeText3");
          map.put("10/10/2021 10:10:21", "SomeText4");
      
          LinkedHashMap<String, String> reversed = new LinkedHashMap<>();
      
          String[] keys = map.keySet().toArray(new String[map.size()]);
      
          for (int i = keys.length - 1; i >= 0; i--) {
              reversed.put(keys[i], map.get(keys[i]));
          }
      

      【讨论】:

      • 为什么不存储在String[],这样可以避免不好的toString()
      • 在任何Linked 地图或列表上使用get(i) 通常是您要避免的事情......这可以通过多种方式得到大幅改进。您可以为初学者使用迭代器
      • 你可以简单地做System.out.println(reversed)并粘贴结果而不是图片,如果会更好
      • 我们不反对,其他人反对,请考虑我们的评论以改进您的帖子(和您的等级)
      • 这是一个非常低效的解决方案,这可能是它收到反对票的原因。
      【解决方案4】:

      如果您想继续使用LinkedHashMap,则在保持其效率的同时将其反转并不容易。这是一个使用迭代器顺序反转给定 LinkedHashMap 的解决方案(这对于 LinkedHashMap 是可预测的,因此可能是您正在寻找的)。

      请注意,使用SortedMapTreeMap 等其他解决方案可能会更好。然而,为了坚持你原来的问题,这里有一个解决方案:

      public static <K, V> LinkedHashMap<K, V> reverse(LinkedHashMap<K, V> map)
      {
          LinkedHashMap<K, V> reversedMap = new LinkedHashMap<K, V>();
      
          ListIterator<Entry<K, V>> it = new ArrayList<>(map.entrySet()).listIterator(map.entrySet().size());
      
          while (it.hasPrevious())
          {
              Entry<K, V> el = it.previous();
              reversedMap.put(el.getKey(), el.getValue());
          }
      
          return reversedMap;
      }
      

      请注意,遗憾的是,您无法绕过将条目集包装到 ArrayList 中,因为只有这样才能为您提供 ListIterator,它可以初始化为除第一个元素之外的任何点。拥有类似reverseIterator() 的方法会大大简化生活——遗憾的是没有可用的方法。

      在复杂性方面,您使用这种方法迭代列表两次,第一次是 listIterator 从开始到最后一个元素调用,然后在使用 previous 时再次从后到前调用。所以你在这里查看 O(2n)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-24
        • 2020-11-26
        • 1970-01-01
        • 2011-01-25
        • 1970-01-01
        • 1970-01-01
        • 2012-08-24
        • 1970-01-01
        相关资源
        最近更新 更多