检索“规范值"来自集合 T其中 T 有一个自定义的 equals() [英] Retrieving the "canonical value" from a Set<T> where T has a custom equals()

查看:35
本文介绍了检索“规范值"来自集合 T其中 T 有一个自定义的 equals()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 class Foo,它正确地覆盖了 equals()hashCode().

I have a class Foo which overrides equals() and hashCode() properly.

我还想使用 HashSet 来跟踪规范值",例如我有一个类,我喜欢这样写,这样如果我有两个等效的独立对象,我可以将它们合并为对同一对象的引用:

I would like to also would like to use a HashSet<Foo> to keep track of "canonical values" e.g. I have a class that I would like to write like this, so that if I have two separate objects that are equivalent I can coalesce them into references to the same object:

class Canonicalizer<T>
{
    final private Set<T> values = new HashSet<T>(); 

    public T findCanonicalValue(T value)
    {
        T canonical = this.values.get(value);
        if (canonical == null)
        {
           // not in the set, so put it there for the future
           this.values.add(value);
           return value;
        }
        else
        {
           return canonical;
        }
    }
}

除了 Set 没有返回存储在集合中的实际值的get"方法,只有返回 true 或 false 的contains"方法.(我猜它假设如果你有一个对象等于集合中的一个单独的对象,你不需要检索集合中的那个)

except that Set doesn't have a "get" method that would return the actual value stored in the set, just the "contains" method that returns true or false. (I guess that it assumes that if you have an object that is equal to a separate object in the set, you don't need to retrieve the one in the set)

有没有方便的方法来做到这一点?我唯一能想到的就是使用地图和列表:

Is there a convenient way to do this? The only other thing I can think of is to use a map and a list:

class Canonicalizer<T>
{
    // warning: neglects concurrency issues

    final private Map<T, Integer> valueIndex = new HashMap<T, Integer>(); 
    final private List<T> values = new ArrayList<T>();

    public T findCanonicalValue(T value)
    {
        Integer i = this.valueIndex.get(value);
        if (i == null)
        {
           // not in the set, so put it there for the future
           i = this.values.size();
           this.values.add(value);
           this.valueIndex.put(value, i);
           return value;
        }
        else
        {
           // in the set
           return this.values.get(i);
        }
    }
}

推荐答案

我会像这样使用 HashMap:

I would use just a HashMap like this:

final private Map<T, T> values = new HashMap<T, T>(); 
public T findCanonicalValue(T value)
{
    T canon = this.values.get(value);
    if (canon == null)
    {
       // not in the set, so put it there for the future
       this.values.put(value, value);
       return value;
    }
    else
    {
       // in the set
       return canon;
    }
}

它仍然有点笨拙,但它应该比地图和列表更有效(少一个数据结构).

its still a little awkard but it should be slightly more efficient than the map and the list (one fewer data structure).

这篇关于检索“规范值"来自集合 T其中 T 有一个自定义的 equals()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆