22

我创建一个 WeakHashMap 作为

WeakHashMap<Employee,String> map = new WeakHashMap<Employee,String>();
map.put(emp,"hello");

其中 emp 是一个 Employee 对象。现在,如果我执行 emp = null 或说不再引用 emp 对象,那么该条目是否会从 WeakHashMap 中删除,即 Map 的大小是否为零?
如果是 HashMap,反之亦然吗?
我对 WeakHashMap 的理解正确吗?

4

6 回答 6

41

一个非常简单的例子,可以启发已经说过的内容:

import java.util.WeakHashMap;

public class WeakHashMapDemo {

    public static void main(String[] args) {
        // -- Fill a weak hash map with one entry
        WeakHashMap<Data, String> map = new WeakHashMap<Data, String>();
        Data someDataObject = new Data("foo");
        map.put(someDataObject, someDataObject.value);
        System.out.println("map contains someDataObject ? " + map.containsKey(someDataObject));

        // -- now make someDataObject elligible for garbage collection...
        someDataObject = null;

        for (int i = 0; i < 10000; i++) {
            if (map.size() != 0) {
                System.out.println("At iteration " + i + " the map still holds the reference on someDataObject");
            } else {
                System.out.println("somDataObject has finally been garbage collected at iteration " + i + ", hence the map is now empty");
                break;
            }
        }
    }

    static class Data {
        String value;
        Data(String value) {
            this.value = value;
        }
    }
}

输出 :

    map contains someDataObject ? true
    ...
    At iteration 6216 the map still holds the reference on someDataObject
    At iteration 6217 the map still holds the reference on someDataObject
    At iteration 6218 the map still holds the reference on someDataObject
    somDataObject has finally been garbage collected at iteration 6219, hence the map is now empty
于 2012-05-15T11:58:05.780 回答
14

HashMap我运行示例代码以了解和之间的区别WeakHashMap

            Map hashMap= new HashMap();
            Map weakHashMap = new WeakHashMap();

            String keyHashMap = new String("keyHashMap");
            String keyWeakHashMap = new String("keyWeakHashMap");

            hashMap.put(keyHashMap, "helloHash");
            weakHashMap.put(keyWeakHashMap, "helloWeakHash");
            System.out.println("Before: hash map value:"+hashMap.get("keyHashMap")+" and weak hash map value:"+weakHashMap.get("keyWeakHashMap"));

            keyHashMap = null;
            keyWeakHashMap = null;

            System.gc();  

            System.out.println("After: hash map value:"+hashMap.get("keyHashMap")+" and weak hash map value:"+weakHashMap.get("keyWeakHashMap"));

输出将是:

Before: hash map value:helloHash and weak hash map value:helloWeakHash
After: hash map value:helloHash and weak hash map value:null
于 2013-06-29T13:06:36.073 回答
6

*是否会从 WeakHashMap 中删除该条目,即 Map 的大小是否为零?*

如果emp包含使 Employee可强访问的最后一个引用,则可以删除映射中的条目。

Java 文档总结得很好:

具有弱键的基于哈希表的 Map 实现。WeakHashMap 中的条目在其键不再常用时将被自动删除。更准确地说,给定键的映射的存在不会阻止该键被垃圾收集器丢弃[...]。当一个键被丢弃时,它的条目被有效地从映射中删除,所以这个类的行为与其他映射实现有些不同。

 

如果是 HashMap,反之亦然吗?

从 WeakHashMap 中删除条目不会影响程序中的任何其他引用。

于 2012-05-15T11:28:26.267 回答
2

弱哈希映射示例:

Map map = new WeakHashMap();
Foo foo =  new Foo();
map.put(foo, "bar");
foo=null; // strong refrence is removed and object is available for garbage collection.  

哈希映射示例:

Map map = new HashMap();
Foo foo =  new Foo();
map.put(foo, "bar");
foo=null; // even though the reference is nullified object will not garbage collected because map is having Strong refrence.
于 2017-12-16T11:33:12.210 回答
1

在其他 Map 实现(如 HashMap)中,键是强可达的。例如,如果 HashMap 具有如下所示的 Person 类的键,并且如果 Person 对象设置为 null,即使在此之后,如果我们执行 map.get(Person),我们也会从内存中获取值,因为键是强引用的在 HashMap 中。

wm.put(person, person.getFirstName());
person = null;
System.gc();
System.out.println("Hash Map :" + wm.toString());

输出:哈希图:{test.Person@12dacd1=John}

与 HashMap 相比,WeakHashMap 是一种一旦键在内存中没有引用就会删除它的条目。例如,如果 WeakHashMap 具有如下所示的 Person 类的键,并且如果 Person 对象设置为 null,那么现在如果您执行 map.get(Person),我们将得到 null,因为该键没有引用(或者说是弱引用)可达)。

wm.put(person, person.getFirstName());
person = null;
System.gc();
System.out.println("Weak Hash Map :" + wm.toString());

输出:弱哈希映射:{}

于 2015-01-13T14:18:27.923 回答
1

java中的引用是创建的对象在内存中指向的内存地址。在 WeakHashMap 中,使用了弱引用的概念。

一旦您在 java 中创建一个对象并将其分配给某个变量,它就变得非常可访问。

弱引用对象可能有点类似于没有内存引用的对象,即它现在可以被垃圾收集。

于 2015-01-08T15:01:13.607 回答