Java唯一值映射

Java唯一值映射,java,dictionary,data-structures,Java,Dictionary,Data Structures,我需要一个带有唯一键的地图,并且只存储一次重复值。接口将是映射,但我不希望相同的值多次使用内存。例如: 在一个普通的映射实现中,比如HashMap suposing value.equals(value')和value.equals(value“”)但是value=价值和价值=价值和价值=如果我们: 然后,该值将被存储三次 我尝试了自己的实现,如下所示: class MyMap2<K, V> extends HashMap<K, V> { private Map&

我需要一个带有唯一键的地图,并且只存储一次重复值。接口将是映射,但我不希望相同的值多次使用内存。例如:

在一个普通的映射实现中,比如HashMap suposing value.equals(value')和value.equals(value“”)但是value=价值和价值=价值和价值=如果我们:

然后,该值将被存储三次

我尝试了自己的实现,如下所示:

class MyMap2<K, V> extends HashMap<K, V> {
    private Map<V, V> values;

    public MyMap2() {
        values = new HashMap<V, V>();
    }

    @Override
    public V put(final K key, final V value) {
        V v = values.get(value);
        if (v == null) {
            v = value;
            values.put(v, v);
        }
        return super.put(key, v);
    }
}
类MyMap2扩展了HashMap{ 私有地图值; 公共MyMap2(){ values=newhashmap(); } @凌驾 公共V输入(最终K键,最终V值){ V=值。获取(值); 如果(v==null){ v=值; 值。put(v,v); } 返回super.put(键,v); } } 这个实现只存储一次值(请注意,我使用的是相同的值)。但是有没有已经用get/put O(1)实现这种数据结构的Map呢


请注意,BiMap没有用处,因为如果值重复,它将导致错误。

此实现已经承诺了固定时间的获取/放置操作。最糟糕的情况是插入一个从未见过的新值。在这种情况下,您将:

  • 尝试在
    values
    map-O(1)中查找该值,因为它是
    HashMap
  • 找不到它,并将该值放入
    values
    map-O(1),因为它是
    HashMap
  • 将键值对放入
    super
    -O(1),因为它是一个
    HashMap
  • 您可以找到一种更好的方法来实现这种逻辑,但不能达到一个数量级

    编辑:
    请注意,实现可能会将放入
    super
    两次,这只是多余的。可以将其调整为稍微更干净:

    @Override
    public V put(final K key, final V value) {
        V v = values.get(value);
        if (v == null) {
            v = value
            values.put(v, v);
        } 
        return super.put(key, v);
    }
    
    这已经被问到了


    退房。

    我不确定这应该实现什么。您不是在存储对象的副本,而是在存储对它的多个引用。而且,您的实现似乎只是在最后传递给了super类。put()?为什么需要这样做?当您回答为什么您可能会意识到它不是真正需要的…如果两个唯一的键具有相同的值,该怎么办。例如,John和Bill都20岁了?当您将相同的值放入地图时,实际上不会占用太多内存。您没有复制对象。所以请随意使用HashMapI。我不相信这个问题与它标记为重复的问题问的是同一件事。但这只是我的看法。OP的例子是,将同一对象放在3个键上,会使用BiMapAs FatalError抛出一个IllegalArgumentException。他说,在这种情况下,BiMap没有用,因为当你存储相同的值时,你没有指定所需的行为。代码我也不清楚。乍一看,它似乎仍然存储重复的值
    super.put(key,value)
    super.put(key,v)
    完全相同,因为
    value==v
    。请注意,值“等于value”,但不是同一个对象,因此它将多次存储在内存中。谢谢。我同意你对super.put()的看法,但是有没有其他可能的实现不使用Map(比如“Map”来避免存储两次相同的值?在
    put(v,v)
    的情况下,你只存储对v的引用(不是两个副本)所以,虽然不优雅,但在记忆方面并不缺乏。所以我的问题是:有没有更优雅的方式来做到这一点?
    @Override
    public V put(final K key, final V value) {
        V v = values.get(value);
        if (v == null) {
            v = value
            values.put(v, v);
        } 
        return super.put(key, v);
    }