获取 LinkedHashMap 中最后一个键或值的最便捷方法?

发布于 2024-12-02 16:21:29 字数 228 浏览 2 评论 0原文

LinkedHashMap 描述说“它维护一个贯穿其所有条目的双向链表”,所以我想知道如何获取最后输入的条目或键?我可以自信地将 .values() 向下转换为 LinkedList 来获取双向链表并使用 .getLast() 吗?或者它是某个其他 Java 集合的实例?

如果可能的话,我想坚持使用 java.util。

LinkedHashMap description says "it maintains a doubly-linked list running through all of its entries" so I'm wondering how to get the last entry or key entered? Can I confidently downcast .values() to LinkedList to get that doubly-linked list and use .getLast() of that? Or is it an instance of some other Java collection?

I want to stick with java.util if possible.

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

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

发布评论

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

评论(4

数理化全能战士 2024-12-09 16:21:29

是的,你可以获得最后一个元素。但您必须查看其他人的建议才能获取 values() 返回的 Collection 的最后一个元素。

我检查了源代码,返回的值确实是按照预期的顺序:
LinkedListMap.values() 返回的 AbstactCollection 由一个 Iterator 支持,其值本身直接链接到键上的Iterator。显然,键上的Iterator是通过有序双向链表实现的。

Yes, you can get the last element. But you'll have to look at the suggestions from others to get the last element of the Collection<V> returned by values().

I checked in the source code that the returned values are indeed in the expected order:
The AbstactCollection<V> returned by LinkedListMap.values() is backed by an Iterator<V> over the values which is itself directly linked to the Iterator<K> over the keys. And obviously the Iterator<K> over the keys is implemented with the ordered doubly linked list.

我的影子我的梦 2024-12-09 16:21:29

不,抱歉,你不能。

“维护的双向链表”不是任何 java.util.LinkedList 类型或其他集合。它是在 LinkedHashMap 和 LinkedHashMap.Entry 类中手动实现的。

您只能从 values() 构建 LinkedList ,然后使用 letLast()

Foo last = new LinkedList<Foo>(myLinkedHashMap.values()).getLast();

No, sorry, you cannot.

The "maintained doubly-linked list" is not any java.util.LinkedList type or other collection. It's manually implemented in LinkedHashMap and LinkedHashMap.Entry classes.

You can only build LinkedList from values() and then use letLast() :

Foo last = new LinkedList<Foo>(myLinkedHashMap.values()).getLast();
孤蝉 2024-12-09 16:21:29

更新:我之前的回答是错误的。如果不修改默认行为,您就无法做到这一点!请参阅下面的原因。


..如何获取最后输入的条目或输入的键?

LinkedHashMap 的 API 描述中您可以看到:

结构修改是添加或删除一个或多个映射的任何操作,或者在访问顺序链接哈希映射的情况下影响迭代顺序的操作。在插入顺序链接哈希映射中,仅更改与映射中已包含的键关联的值并不是结构修改。在按访问顺序链接的哈希映射中,仅使用 get 查询映射就是一种结构修改

那么这一切意味着什么呢?

  • 访问顺序 - 每次执行 putget 时,元素的顺序都会发生变化
  • 插入顺序 - 插入元素时(第一次)它们最后添加

例如:

map.put(1, 1); 
map.put(2, 2); 
map.put(1, 10);
System.out.println(map);

...将打印 {1=10, 2=2} 与 插入顺序{2=2, 1=10} 带有 *access-ordered'。问题在于使用access-ordered,当然,如果您执行get操作,顺序也会改变。


如何修复

那么...如何修复。那么LinkedHashMap不能直接使用。因此,您可以包装它(不要关心老生常谈的名称)并覆盖 putputAll 方法,以便它们先从地图中删除密钥,然后再将其放回去在!

class BestLinkedHashMap<K, V> extends LinkedHashMap<K, V> {

    @Override
    public V put(K key, V value) {
        V last = super.remove(key);
        super.put(key, value);
        return last;
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> m) {
        for (K key : m.keySet())
            super.remove(key);

        super.putAll(m);
    }
}

然后要获取最后一个元素,可以执行以下操作之一:

  • 将输出包装在 LinkedList 实现中:

    V v = new LinkedList(map.values()).getLast();
    
  • toArray() 方式:

    集合值=map.values();
    V v = values.toArray(new V[0])[values.size() - 1];
    
  • 使用迭代器迭代到最后一个元素:

    迭代器 it = value.iterator();
    V最后=空;
    while (it.hasNext())
        最后 = it.next();
    

Update: My previous answer was wrong. You cannot do it without modifying the default behaviour! See below why.


..how to get the last entry or key entered?

From the API description of LinkedHashMap you can read:

A structural modification is any operation that adds or deletes one or more mappings or, in the case of access-ordered linked hash maps, affects iteration order. In insertion-ordered linked hash maps, merely changing the value associated with a key that is already contained in the map is not a structural modification. In access-ordered linked hash maps, merely querying the map with get is a structural modification.

So what does it all mean?

  • access-ordered - every time you do a put or a get the order of the elements changes
  • insertion-ordered - when inserting elements (for the first time) they are added last

For example:

map.put(1, 1); 
map.put(2, 2); 
map.put(1, 10);
System.out.println(map);

... will print {1=10, 2=2} with insertion-ordered and {2=2, 1=10} with *access-ordered'. The trouble is using access-ordered if of course if you do a get operations the order also changes.


How to fix

So... how to fix. Well the LinkedHashMap cannot be used directly used. So you can wrap it (do not care about the corny name) and override the put and the putAll methods so that they remove the key from the map first before putting it back in!

class BestLinkedHashMap<K, V> extends LinkedHashMap<K, V> {

    @Override
    public V put(K key, V value) {
        V last = super.remove(key);
        super.put(key, value);
        return last;
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> m) {
        for (K key : m.keySet())
            super.remove(key);

        super.putAll(m);
    }
}

Then to get the last element, either do:

  • wrap the output from in a LinkedList implementation:

    V v = new LinkedList<V>(map.values()).getLast();
    
  • toArray() way:

    Collection<V> values = map.values();
    V v = values.toArray(new V[0])[values.size() - 1];
    
  • iterate to the last element using the iterator:

    Iterator<V> it = values.iterator();
    V last = null;
    while (it.hasNext())
        last = it.next();
    
诗酒趁年少 2024-12-09 16:21:29

我已经“扩展”了Jdk LinkedHashMap以允许这样做,你可以看一下: LinkedHashMapEx.java

I have "extended" the Jdk LinkedHashMap to allow that, you can take a look at: LinkedHashMapEx.java

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