是否有可能/需要在同一条目上加速HashMap操作?

时间:2013-01-24 20:48:55

标签: java map hashmap

假设我希望检查HashMap条目,然后将其替换为:

if( check( hashMap.get(key) ) ) {
    hashMap.put(key, newValue);
}

这将导致HashMap内的搜索程序运行两次:一次get,另一次put。这看起来无效。是否可以修改已找到的Map条目的值?

更新

我知道我可以制作一个包装器,我知道我有一些问题可以改变输入。但问题是为什么?可能会HashMap记得最后一次搜索以改进重复搜索吗?为什么没有方法可以做这样的操作?

4 个答案:

答案 0 :(得分:3)

编辑:我刚刚发现你可以修改条目,通过Map.Entry.setValue(并且HashMap实现是可变的)。虽然获得特定密钥的入口是一种痛苦,但我记不起有人这样做了。您可以获得条目的 set ,但据我所知,您无法获得单个密钥的条目。

有一种 evil 方式 - 在HashMap包中声明自己的java.util子类,并创建一个 public 方法只需委托package-private现有方法:

package java.util;

// Please don't actually do this...
public class BadMap<K, V> extends HashMap<K, V> {
    public Map.Entry<K, V> getEntryPublic(K key) {
        return getEntry(key);
    }
}

但这非常讨厌。

您通常不会修改条目 - 当然,如果这是一个可变类型,您可以更改值中的数据。

我非常怀疑这实际上是一个性能瓶颈,除非你这么做很多。在开始尝试微调可能不是问题的事情之前,您应该对您的应用程序进行概要分析,以证明这是一个真正的问题。

如果确实成为问题,您可以将Map<Integer, String>更改为Map<Integer, AtomicReference<String>>并使用AtomicReference<T>作为简单可变包装类型。

答案 1 :(得分:2)

对您的问题发表评论的信息过多。查看Hashmap的文档。

  

此实现为基本提供了恒定时间性能   操作(获取和放置),假设散列函数分散了   桶中的元素恰到好处。迭代集合视图   要求时间与容量成比例&#34; HashMap实例的   (桶数)加上其大小(键值的数量   映射)。因此,不设置初始容量非常重要   如果迭代性能是太高(或负载因子太低)   重要的。

恒定时间意味着它总是需要相同的时间来进行获取和放置操作[O(1)]。根据您需要循环[O(n)]的次数,所需的时间量将是线性的。

答案 2 :(得分:1)

如果条目可变,您可以更改条目。您可以执行此操作的一个示例是

private final Map<String, List<String>> map = new LinkedHashMap<>();

public void put(String key, String value) {
    List<String> list = map.get(key);
    if (list == null)
        map.put(key, list = new ArrayList<>());
    list.add(value);
}

这允许您更新值,但在一次操作中无法找到并替换值。

答案 3 :(得分:1)

看看特洛伊(http://trove4j.sourceforge.net/),他们的地图确实有几种方法可能是你想要的:

  • adjustOrPut
  • 的putIfAbsent

我不知道这是如何在内部实现的,但我猜想,因为特洛伊是高性能的,所以只有一次查找。