首页 > 解决方案 > Java WeakHashMap 不使用 equal 方法

问题描述

我有一个User带有一个equals()方法和一个hashCode()方法的类,WeakHashMap<User,V>现在我想向它添加两个新用户。问题是这两个新用户在我比较它们时具有相同的字段和equals()返回true,所以我不能WeakHashMap<User,V>为这两个用户中的每一个添加一个值并不奇怪。但是我需要为每个用户指定一个特定的值...我尝试了一个使用直接对象比较Wrapper覆盖该方法的类,但现在我的问题是它不再起作用了,因为根本没有对包装器对象的直接引用时间。这里以代码形式解释了同样的事情:equals==WeakHashMap<Wrapper, V>

private static class User{
    private final String username;

    private User(String username) {
        this.username = username;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(username, user.username);
    }

    @Override
    public int hashCode() {
        return username != null ? username.hashCode() : 0;
    }

    @Override
    public String toString() {
        return username;
    }
}

private static class Wrapper{
    private final Object wrapped;

    private Wrapper(Object wrapped) {
        this.wrapped = wrapped;
    }

    public boolean equals(Object o){
        return o instanceof Wrapper && ((Wrapper) o).wrapped == wrapped;
    }

    @Override
    public int hashCode() {
        return wrapped.hashCode();
    }
}

public static void main(String[] args) {
    System.out.println("---Default WeakHashMap---");
    Map<User, String> map = new WeakHashMap<>();
    User freddy = new User("freddy");
    User freddyClone = new User("freddy");
    map.put(freddy, "original");
    map.put(freddyClone, "clone");
    //first problem the clone overrides the original
    System.out.println("freddy:       "+map.get(freddy));
    System.out.println("freddy clone: "+map.get(freddyClone));
    System.out.println("---Wrapper Map---");

    Map<Wrapper,String> wrapperMap = new WeakHashMap<>();
    wrapperMap.put(new Wrapper(freddy),"original");
    wrapperMap.put(new Wrapper(freddyClone),"clone");
    //first problem solved
    System.out.println("---before GC---");
    System.out.println("freddy:       "+wrapperMap.get(new Wrapper(freddy)));
    System.out.println("freddy clone: "+wrapperMap.get(new Wrapper(freddyClone)));
    //second problem gc kills all wrapper objects because there is no reference to it
    System.gc();
    System.out.println("---after GC---");
    System.out.println("freddy:       "+wrapperMap.get(new Wrapper(freddy)));
    System.out.println("freddy clone: "+wrapperMap.get(new Wrapper(freddyClone)));
}

结果:

---Default WeakHashMap---
freddy:       clone
freddy clone: clone
---Wrapper Map---
---before GC---
freddy:       original
freddy clone: clone
---after GC---
freddy:       null
freddy clone: null

标签: javawrapperweak-referencesweakhashmap

解决方案


推荐阅读