以相反顺序迭代 LinkedHashMap

发布于 2024-12-01 06:06:35 字数 160 浏览 0 评论 0原文

我有一个 LinkedHashMap:

LinkedHashMap<String, RecordItemElement>

我需要从给定键的位置向后迭代。因此,如果给我第 10 个项目的键,我需要向后迭代哈希图 9、8、7 等。

I have a LinkedHashMap:

LinkedHashMap<String, RecordItemElement>

that I need to iterate through from a given key's position, backwards. So if I was given the 10th item's key, I'd need iterate backwards through the hashmap 9, 8, 7 etc.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

终陌 2024-12-08 06:06:35

这个问题需要一个相反顺序的 LinkedHashMap,一些答案建议使用 TreeSet,但这会根据键重新排序映射。

该解决方案允许对原始 LinkedHashMap 进行迭代,而不是像已经提议的那样对新的 ArrayList 进行迭代:

List<String> reverseOrderedKeys = new ArrayList<String>(linkedHashMap.keySet());
Collections.reverse(reverseOrderedKeys);
for (String key : reverseOrderedKeys) {
    RecordItemElement line = linkedHashMap.get(key);
}

The question requires a LinkedHashMap in reverse order, some answers suggesting using a TreeSet but this will reorder the map based upon the key.

This solution allows the iteration over the original LinkedHashMap not the new ArrayList as has also been proposed:

List<String> reverseOrderedKeys = new ArrayList<String>(linkedHashMap.keySet());
Collections.reverse(reverseOrderedKeys);
for (String key : reverseOrderedKeys) {
    RecordItemElement line = linkedHashMap.get(key);
}
迷荒 2024-12-08 06:06:35

HashMap:

HashMap<Integer, String> map = new HashMap<Integer, String>();

反向迭代值:

ListIterator<Sprite> iterator = new ArrayList<String>(map.values()).listIterator(map.size());
while (iterator.hasPrevious()) String value = iterator.previous();

反向迭代键:

ListIterator<Integer> iterator = new ArrayList(map.keySet()).listIterator(map.size());
while (iterator.hasPrevious()) Integer key = iterator.previous();

反向迭代两者:

ListIterator<Map.Entry<Integer, String>> iterator = new ArrayList<Map.Entry<Integer, String>>(map.entrySet()).listIterator(map.size());
while (iterator.hasPrevious()) Map.Entry<Integer, String> entry = iterator.previous();

The HashMap:

HashMap<Integer, String> map = new HashMap<Integer, String>();

Reverse iterating over values:

ListIterator<Sprite> iterator = new ArrayList<String>(map.values()).listIterator(map.size());
while (iterator.hasPrevious()) String value = iterator.previous();

Reverse iterating over keys:

ListIterator<Integer> iterator = new ArrayList(map.keySet()).listIterator(map.size());
while (iterator.hasPrevious()) Integer key = iterator.previous();

Reverse iterating over both:

ListIterator<Map.Entry<Integer, String>> iterator = new ArrayList<Map.Entry<Integer, String>>(map.entrySet()).listIterator(map.size());
while (iterator.hasPrevious()) Map.Entry<Integer, String> entry = iterator.previous();
守不住的情 2024-12-08 06:06:35

您不必迭代它。但拔下钥匙并将其存储在列表中会很方便。这是执行 indexOf() 类型操作的唯一方法。

List<String> keyList = new ArrayList<String>(map.keySet());
// Given 10th element's key
String key = "aKey";
int idx = keyList.indexOf(key);
for ( int i = idx ; i >= 0 ; i-- ) 
 System.out.println(map.get(keyList.get(i)));

You don't have to iterate through it. But it would be handy to pull the keys off and store it in a list. Thats the only way you can do indexOf() type operations.

List<String> keyList = new ArrayList<String>(map.keySet());
// Given 10th element's key
String key = "aKey";
int idx = keyList.indexOf(key);
for ( int i = idx ; i >= 0 ; i-- ) 
 System.out.println(map.get(keyList.get(i)));
携君以终年 2024-12-08 06:06:35
new LinkedList(linkedHashMap.keySet()).descendingIterator();
new LinkedList(linkedHashMap.keySet()).descendingIterator();
离线来电— 2024-12-08 06:06:35

从 Java 21 开始,LinkedHashMap 具有 reversed() 方法,返回地图的反转视图。这可以以标准方式迭代。

myLinkedHashMap.reversed().forEach((key, value) -> {
  // Do something with the key and/or value
});

要根据请求专门从给定键开始,可以使用反向映射条目集上的 Stream,使用 dropWhile 跳过所有元素的方法在该键之前遇到:

String matchingKey = "someKey";
myLinkedHashMap.entrySet().stream()
        .dropWhile(e -> !matchingKey.equals(e.getKey()))
        .forEach(e -> {
            String key = e.getKey();
            RecordItemElement value = e.getValue();
            // Do something with key & value
        });

As of Java 21, LinkedHashMap has the reversed() method, which returns a reversed view of the map. This can be iterated over in the standard manner.

myLinkedHashMap.reversed().forEach((key, value) -> {
  // Do something with the key and/or value
});

To specifically start with a given key as requested, a Stream over the reversed map's entry set could be used, using the dropWhile method to skip all elements encountered prior to that key:

String matchingKey = "someKey";
myLinkedHashMap.entrySet().stream()
        .dropWhile(e -> !matchingKey.equals(e.getKey()))
        .forEach(e -> {
            String key = e.getKey();
            RecordItemElement value = e.getValue();
            // Do something with key & value
        });
等风来 2024-12-08 06:06:35

使用“user22745008”解决方案和labdas以及一些泛型,您可以得到一个非常简洁的解决方案作为方法:

  public static <T, Q> LinkedHashMap<T, Q> reverseMap(LinkedHashMap<T, Q> toReverse)
  {
      LinkedHashMap<T, Q> reversedMap = new LinkedHashMap<>();
      List<T> reverseOrderedKeys = new ArrayList<>(toReverse.keySet());
      Collections.reverse(reverseOrderedKeys);
      reverseOrderedKeys.forEach((key)->reversedMap.put(key,toReverse.get(key)));
      return reversedMap;
    }

Using "user22745008" solution and labdas with some generics you can have a very neat solution as a method:

  public static <T, Q> LinkedHashMap<T, Q> reverseMap(LinkedHashMap<T, Q> toReverse)
  {
      LinkedHashMap<T, Q> reversedMap = new LinkedHashMap<>();
      List<T> reverseOrderedKeys = new ArrayList<>(toReverse.keySet());
      Collections.reverse(reverseOrderedKeys);
      reverseOrderedKeys.forEach((key)->reversedMap.put(key,toReverse.get(key)));
      return reversedMap;
    }
古镇旧梦 2024-12-08 06:06:35

这是一个老问题,但我认为它缺乏采用更新方法的答案。以下使用 Java 9 功能:

Deque<Map.Entry<String, RecordItemElement>> top = map.entrySet().stream()
        .takeWhile(e -> !givenKey.equals(e.getKey()))
        .collect(Collectors.toCollection(ArrayDeque::new));

上面的代码流式传输映射的条目集,保留条目,直到找到与给定键相等的键。然后,条目被收集到 ArrayDeque 中。

不过,有一个细节缺失。根据您是否需要将与给定键匹配的条目也包含在结果中,您可能需要手动将其添加到双端队列中。如果您不想添加它,那么就完成了。否则,只需执行以下操作:

top.add(Map.entry(givenKey, map.get(givenKey)));

现在,要以相反的顺序迭代 Deque,只需使用其 descendingIterator()

Iterator<Map.Entry<String, RecordItemElement>> descIt = top.descendingIterator();

值得一提的是,此方法仅在流是顺序无论如何,我们在这里使用并行流不会获得任何东西。

This is an old question, but I think it's lacking an answer that takes a newer approach. The following uses Java 9 features:

Deque<Map.Entry<String, RecordItemElement>> top = map.entrySet().stream()
        .takeWhile(e -> !givenKey.equals(e.getKey()))
        .collect(Collectors.toCollection(ArrayDeque::new));

The code above streams the map's entryset, keeping entries until a key equal to the given key is found. Then, the entries are collected to an ArrayDeque.

One detail is missing, though. Depending on whether you need the entry that matches the given key to also be included in the result or not, you might need to manually add it to the deque. If you don't want it added, then you're done. Otherwise, simply do:

top.add(Map.entry(givenKey, map.get(givenKey)));

Now, to iterate the Deque in reverse order, simply use its descendingIterator():

Iterator<Map.Entry<String, RecordItemElement>> descIt = top.descendingIterator();

It's worth mentioning that this approach only works if the stream is sequential. Anyways, we wouldn't have gained anything using a parallel stream here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文