java - 在 HashMap 中访问隐藏的 getEntry(Object key)

标签 java map

我有一个与讨论过的问题类似的问题 here , 但具有更强的实用性。

例如,我有一个 Map<String, Integer> ,我有一些函数,给它一个键,如果映射的整数值为负,则输入 NULL到 map :

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

public void nullifyIfNegative(String key) {
    Integer value = map.get(key);

    if (value != null && value.intValue() < 0) {
        map.put(key, null);
    }
}

在这种情况下,查找(因此,键的 hashCode 计算)进行了两次:一次用于查找,一次用于替换。最好有另一种方法(已经在 HashMap 中)并允许使其更有效:

public void nullifyIfNegative(String key) {
    Map.Entry<String, Integer> entry = map.getEntry(key);

    if (entry != null && entry.getValue().intValue() < 0) {
        entry.setValue(null);
    }
}

同样的情况,当你想操作不可变对象(immutable对象)时,它可以是映射值:

  • Map<String, String> : 我想向字符串值附加一些内容。
  • Map<String, int[]> : 我想在数组中插入一个数字。

所以这种情况很常见。可能有效但不适合我的解决方案:

  • 反射(reflection)。很好,但我不能仅仅为了这个不错的功能而牺牲性能。
  • 使用 org.apache.commons.collections.map.AbstractHashedMap (它至少有 protected getEntry() 方法),但不幸的是,commons-collections 不支持泛型。
  • 使用generic commons-collections ,但是这个库 (AFAIK) 已经过时(与 Apache 的最新库版本不同步),并且(重要的是)在中央 Maven 存储库中不可用。
  • 使用值包装器,这意味着“使值可变”(例如使用可变整数 [例如 org.apache.commons.lang.mutable.MutableInt ] 或集合而不是数组)。这种解决方案会导致内存丧失,我想避免这种情况。
  • 尝试扩展java.util.HashMap使用自定义类实现(应该在 java.util 包中)并将其放入 endorsed folder (因为 java.lang.ClassLoader 将拒绝在 Class<?> defineClass(String name, byte[] b, int off, int len) 中加载它,请参阅资源),但我不想修补 JDK,而且似乎可以认可的软件包列表不包括 java.util .

类似的问题已经在sun.com bugtracker上提出了,但我想知道,社区的意见是什么,考虑到最大内存和性能效率的出路是什么。

如果您同意,这是一个不错且有益的功能,请为这个错误投票!

最佳答案

从逻辑上讲,您是对的,因为单个 getEntry 将为您节省散列查找。作为一个实际问题,除非您有一个特定的用例,您有理由担心性能影响(这似乎不太可能,散列查找很常见,O(1),并且优化良好)您担心的是可能可以忽略不计。

你为什么不写一个测试?创建一个包含几百万个对象的哈希表,或者比您的应用程序可能创建的对象大一个数量级的任何对象,并平均 get() 的时间超过一百万次左右的迭代(提示:它将是一个非常小的数字)。

您正在做的事情的一个更大问题是同步。您应该知道,如果您在 map 上进行条件更改,您可能会遇到问题,即使您使用的是同步 map ,因为您必须锁定对覆盖 get( ) 和 set() 操作。

关于java - 在 HashMap 中访问隐藏的 getEntry(Object key),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2381000/

相关文章:

arrays - 如何在 perl 中将数组 [key1,val1] 映射到哈希 { key1 => val1}?

c++ - 有没有办法限制 STL Map 的大小?

java - 循环迭代等待 repaint() 方法完成

java - Jboss EAP 7/Wildfly 10 中的 jacorb.orb 警告

java - 连接异常 : operation timed out

java - Amazon EC2 中的 Spot 实例出价策略

map - 在 Cocos2D 中滚动平铺 map

map - Clojure 嵌套映射 - 更改值

r - 世界地图 - 将国家的一半映射为不同的颜色

java - java 中的数学随机数