Java中的双向集合

use*_*247 4 java collections

我有一个对象列表.给对象一个ID并存储在Hashtable中.如果我需要一个具有特定ID的对象,我只想说:

ht.get(ID);
Run Code Online (Sandbox Code Playgroud)

但是,有时我需要获取给定对象的ID:

ht.get(Object);
Run Code Online (Sandbox Code Playgroud)

我的第一个想法是使用两个不同的HashTables; 一个用于ID - >对象映射,另一个用于对象 - > ID映射.

这听起来像是一个足够好的解决方案吗?

Tof*_*eer 8

如果你不能使用外部集合(因为你似乎不想使用你的评论之一),你可以编写一个简单的类来做你想要的(这,是,基本上是你的第一个想法),沿着(I没有编译这个,这只是第一个想法所以可能是一个坏主意等...):

编辑:现在有两个版本,一个允许重复值,另一个不允许.如果值被覆盖,那些不会删除密钥.

此版本不允许重复值:

class Foo<K, V>
{
    private final Map<K, V> keyValue;
    private final Map<V, K> valueKey;

    {
        keyValue = new HashMap<K, V>();
        valueKey = new HashMap<V, K>();
    }

    // this makes sure that if you do not have duplicate values.
    public void put(final K key, final V value)
    {
        if(keyValue.containsValue(value))
        {
            keyValue.remove(valueKey.get(value));
        }

        keyValue.put(key, value);
        valueKey.put(value, key);
    }

    public V getValueForKey(final K key)
    {
        return (keyValue.get(key));
    }

    public K getKeyForValue(final V value)
    {
        return (valueKey.get(value));
    }

    public static void main(final String[] argv)
    {
        Foo<String, String> foo;

        foo = new Foo<String, String>();
        foo.put("a", "Hello");
        foo.put("b", "World");
        foo.put("c", "Hello");

        System.out.println(foo.getValueForKey("a"));
        System.out.println(foo.getValueForKey("b"));
        System.out.println(foo.getValueForKey("c"));

        System.out.println(foo.getKeyForValue("Hello"));
        System.out.println(foo.getKeyForValue("World"));
    }
}
Run Code Online (Sandbox Code Playgroud)

此版本允许重复的值,并返回具有给定值的所有键的列表:

class Foo<K, V>
{
    private final Map<K, V> keyValue;
    private final Map<V, List<K>> valueKeys;

    {
        keyValue = new HashMap<K, V>();
        valueKeys = new HashMap<V, List<K>>();
    }

    public void put(final K key, final V value)
    {
        List<K> values;

        keyValue.put(key, value);

        values = valueKeys.get(value);

        if(values == null)
        {
            values = new ArrayList<K>();
            valueKeys.put(value, values);
        }

        values.add(key);
    }

    public V getValueForKey(final K key)
    {
        return (keyValue.get(key));
    }

    public List<K> getKeyForValue(final V value)
    {
        return (valueKeys.get(value));
    }

    public static void main(final String[] argv)
    {
        Foo<String, String> foo;

        foo = new Foo<String, String>();
        foo.put("a", "Hello");
        foo.put("b", "World");
        foo.put("c", "Hello");

        System.out.println(foo.getValueForKey("a"));
        System.out.println(foo.getValueForKey("b"));
        System.out.println(foo.getValueForKey("c"));

        System.out.println(foo.getKeyForValue("Hello"));
        System.out.println(foo.getKeyForValue("World"));
    }
}
Run Code Online (Sandbox Code Playgroud)

在一个类中隐藏这两个映射是一个好主意,因为你找到了一个更好的方法,以后你需要做的就是替换类的内部,而其余的代码保持不变.