简体   繁体   English

LinkedHashMap与LinkedHashMap或ArrayList的相反顺序

[英]Reverse order of LinkedHashMap to LinkedHashMap or ArrayList

I have a LinkedHashMap<String,String> which looks something like this (don't really know how to illustrate a HashMap): 我有一个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"
}

And I want to put it like this: 我想这样说:

{
  "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"
}

I have written this solution which works because the result I want is an ArrayList, but i was thinking if there was an easier way to reverse the LinkedHashMap maintaining the same type using a tool like sort for example. 我写了这个解决方案是可行的,因为我想要的结果是一个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);
}

A LinkedHashMap orders by insertion; 一个LinkedHashMap通过插入命令; it would be more logical to sort on the associated date time: 按关联的日期时间进行排序更合乎逻辑:

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), "...");

To specify that the map is sorted, there is the interface SortedMap. 要指定地图已排序,有接口SortedMap。 Better use an interface, which is more versatile. 更好地使用接口,这是更通用的。 The implementation class for a sorted map is the TreeMap. 排序映射的实现类是TreeMap。 However you want a reversed comparison. 但是,您需要反向比较。

You could use a Local specific pattern. 您可以使用本地特定模式。 Mind that above I chose Month/Day and not the British Day/Month. 请注意,我在上面选择的是月/日,而不是英国的日/月。

If your motive is just to reverse the map ( show in descending order ) you can use Java.util.TreeMap.descendingMap() : It returns a reverse order view of the mappings contained in the map` 如果您的动机只是反转地图(以降序显示),则可以使用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());

This will do the trick. 这将达到目的。

Here Is My Own Written Logic for you. 这是为您准备的我自己的书面逻辑。 without using any built in functions to reverse: 而不使用任何内置函数来反转:

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

If you want to keep using a LinkedHashMap reversing it while keeping it somewhat efficient is not as easy. 如果要继续使用LinkedHashMap反转,同时又要保持一定的效率,则并非易事。 This is a solution that reverses a given LinkedHashMap using the iterator order (which is predictable for a LinkedHashMap and therefore probably what you are looking for). 这是一种使用迭代器顺序反转给定LinkedHashMap的解决方案(这对于LinkedHashMap是可预测的,因此可能是您所寻找的)。

Note that other solutions like using a SortedMap or a TreeMap are probably still better. 请注意,其他解决方案(例如使用SortedMapTreeMap可能仍然更好。 Yet, for the sake of sticking to your original question, here is a solution: 但是,为了坚持您的原始问题,以下是一种解决方案:

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

Note that you won't get around wrapping the entry set into an ArrayList sadly as only that provides you with an ListIterator which can be initialized to any point other than the first element. 请注意,您不会ArrayList地将条目集包装到ArrayList因为它只能为您提供一个ListIterator ,可以将其初始化为除第一个元素以外的任何点。 Having something like a reverseIterator() method would simplify life a lot - sadly there is none available. 拥有诸如reverseIterator()方法之类的东西会大大简化生活-遗憾的是没有可用的方法。

Complexity wise you iterate the list twice with this approach, first for the listIterator call from start to the last element and then once more from the back to the front when using previous . 复杂聪明人,你这种方法遍历列表两次,第一次为listIterator从后到前使用时从开始调用的最后一个元素,然后再次previous So you are looking at O(2n) here. 因此,您在这里查看O(2n)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM