Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的双向集合_Java_Collections - Fatal编程技术网

Java中的双向集合

Java中的双向集合,java,collections,Java,Collections,我有一个物品清单。对象被赋予一个ID并存储在哈希表中。如果我需要一个具有特定ID的对象,我只需说: ht.get(ID); 但是,有时我需要获取给定对象的ID: ht.get(Object); 我的第一个想法是使用两个不同的哈希表;一个用于ID->Object映射,另一个用于Object->ID映射 这听起来像是一个足够好的解决方案吗?如果使用外部库是可以的,您应该检查google collections上的BiMap: 您正在寻找的是双向地图。您可以在实现接口的类或中找到它。您要查找的是双

我有一个物品清单。对象被赋予一个ID并存储在哈希表中。如果我需要一个具有特定ID的对象,我只需说:

ht.get(ID);
但是,有时我需要获取给定对象的ID:

ht.get(Object);
我的第一个想法是使用两个不同的哈希表;一个用于ID->Object映射,另一个用于Object->ID映射


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

如果使用外部库是可以的,您应该检查google collections上的BiMap:

您正在寻找的是双向地图。您可以在实现接口的类或中找到它。

您要查找的是双向映射。 试试Apache集合BidiMap


我不知道伊梅特利,但你可以建造一个。。。让单个对象集合和多个查找结构(哈希映射或树)不存储对象本身(出于节省内存的原因),而是将索引存储到单个集合中,怎么样?通过这种方式,您可以使用所需的适当查找结构(Id->object,反之亦然)返回一个整数值,您可以将其索引到原始集合中。通过这种方式,您可以在将来需要进行双向查找的情况下进行更多的查找。

如果您不能使用外部集合(因为您似乎不想使用给定的注释之一),您可以编写一个简单的类来做您想做的事情(是的,这基本上是您的第一个想法),大致如下:(我没有编译这个,这只是第一个想法,所以可能是个坏主意,等等……)

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

此版本不允许重复值:

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"));
    }
}
class-Foo
{
私有最终映射键值;
私有最终映射值密钥;
{
keyValue=新的HashMap();
valueKey=newhashmap();
}
//这可以确保如果没有重复的值。
公开作废认沽权(最终K键,最终V值)
{
if(keyValue.containsValue(值))
{
keyValue.remove(valueKey.get(value));
}
keyValue.put(键,值);
value key.put(value,key);
}
public V getValueForKey(最终K键)
{
返回(keyValue.get(key));
}
公共K getKeyForValue(最终V值)
{
返回(valueKey.get(value));
}
公共静态void main(最终字符串[]argv)
{
富富,;
foo=新的foo();
foo.put(“a”,“你好”);
foo.put(“b”,“World”);
foo.put(“c”,“你好”);
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(“世界”);
}
}
此版本允许复制值,并返回具有给定值的所有键的列表:

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"));
    }
}
class-Foo
{
私有最终映射键值;
私有最终地图值密钥;
{
keyValue=新的HashMap();
valueKeys=newhashmap();
}
公开作废认沽权(最终K键,最终V值)
{
列表值;
keyValue.put(键,值);
values=valueKeys.get(值);
如果(值==null)
{
值=新的ArrayList();
valueKeys.put(值,值);
}
值。添加(键);
}
public V getValueForKey(最终K键)
{
返回(keyValue.get(key));
}
公共列表getKeyForValue(最终V值)
{
return(valueKeys.get(value));
}
公共静态void main(最终字符串[]argv)
{
富富,;
foo=新的foo();
foo.put(“a”,“你好”);
foo.put(“b”,“World”);
foo.put(“c”,“你好”);
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(“世界”);
}
}

将两个映射隐藏在一个类中是一个好主意,因为你以后会找到更好的方法,你所需要做的就是替换类的内部,剩下的代码保持不变。

这只有在哈希表是相当静态的情况下才是好主意。如果你对表有很多更新,这个方法通常需要更新两个哈希表ly(通常?)id是对象本身的一部分,因此后者成为
object.getId()
。还是不适合您的情况?它们会经常更新!两个表对我来说似乎是肮脏的解决方案…但是..嗯..不。ID不是对象的一部分。我也不使用外部收集…我注定要失败吗?哦,被2秒打败了。:-)您可以自己实现它。最常见的方法是使用2个哈希表并保持它们同步。您可以在google-collections中查看AbstractBiMap的源代码,获得一些想法。完美答案。对于刚接触Java的人来说,值得注意的是集合只不过是索引——它们不复制信息,只包含对信息的引用。这意味着此解决方案不复制包含的任何信息,它只包含两个哈希索引,这是此问题的最佳解决方案。这无法正常工作。应注意不要将相等的值插入到贴图中。考虑Myfo。放(“a”,“fo”);myFoo.put(“b”、“foo”);我确实考虑过了,但是忘记了一个事实,它会使一张地图与另一幅地图不一致。我用两种方法修复了它,一种是删除无效的密钥,另一种是使用列表来维护重复项。