将 LinkedHashMap 与 LinkedHashMap 或 ArrayList 的顺序相反



我有一个看起来像这样的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 保持相同的类型。

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 按插入顺序排序;按关联的日期时间排序会更合乎逻辑:

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。最好使用更通用的界面。排序映射的实现类是树状图。但是,您需要反向比较。

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

如果你的动机只是反转地图(按降序显示),你可以使用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());

这将解决问题。

这是我自己为你编写的逻辑。 不使用任何内置函数来反转:

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]));
}

如果你想继续使用一个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)。

JEP 431:即将推出的 Java 版本 21 中的排序集合为LinkedHashMap添加了reversed()方法。 这将返回地图的反向视图。

LinkedHashMap<String, String> map = ...;
LinkedHashMap<String, String> reversed = map.reversed();

最新更新