Java中的两种方式集合

发布于 2024-09-09 05:15:14 字数 258 浏览 2 评论 0原文

我有一个对象列表。这些对象被赋予一个 ID 并存储在哈希表中。如果我需要一个具有特定 ID 的对象,我只是说:

ht.get(ID);

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

ht.get(Object);

我的第一个想法是使用两个不同的哈希表;一个用于 ID ->对象映射和其他对象-> ID 映射。

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

I have a list of objects. The objects are given an ID and stored in a Hashtable. If I need an object with particular ID, I simply say:

ht.get(ID);

However, sometimes I need to get the ID for a given object:

ht.get(Object);

My first idea is to use two different HashTables; one for ID -> Object mapping and the other for Object -> ID mapping.

Does this sound like a good enough solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

忆离笙 2024-09-16 05:15:14

如果您无法使用外部集合(因为您似乎不想使用给定的一条评论),您可以编写一个简单的类来执行您想要的操作(是的,这本质上是您的第一个想法),沿着(我没有编译这个,这只是第一个想法,所以可能是一个坏主意,等等...):

编辑:现在有两个版本,一个允许重复值,一个不允许。如果值被覆盖,则不这样做的将删除该键。

此版本不允许重复值:

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<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"));
    }
}

隐藏类中的两个映射是一个好主意,因为稍后您会找到更好的方法您需要做的就是替换类的内部结构,其余代码保持不变。

If you cannot use external collections (as you seem to not want to use given one of your comments) you could write a simple class to do what you want (which, yes, is essentially your first thought), along the lines of (I didn't compile this, and it is just a first thought so could be a bad idea, etc ...):

EDIT: now there are two versions, one that allows for duplicate values and one that does not. The ones that does not will remove the key if the value is overwritten.

This version does not allow duplicate values:

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"));
    }
}

This version allows duplicated values and gives you back a list of all of the keys that have a given value:

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"));
    }
}

Hiding the two maps in a class is a good idea, because of you find a better way later all you need to do is replace the innards of the class and the rest of your code is left untouched.

小鸟爱天空丶 2024-09-16 05:15:14

如果使用外部库没问题,你应该检查 google 集合上的 BiMap:
http://google-collections。 googlecode.com/svn/trunk/javadoc/com/google/common/collect/BiMap.html

If using an external library is OK, you should check BiMap on google collections:
http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/BiMap.html

呆头 2024-09-16 05:15:14

您正在寻找的是双向地图。您可以在实现 commons 集合 的类中找到它/commons.apache.org/collections/apidocs/org/apache/commons/collections/BidiMap.html" rel="nofollow noreferrer">BidiMap 界面或 Google Guava

What you are looking for is a bidirectional map. You can find it in the commons collections in the classes implementing the BidiMap interface or the Google Guava.

走走停停 2024-09-16 05:15:14

您正在寻找的是双向地图。
尝试 Apache Collections BidiMap。

http://commons.apache.org/集合/api-3.1/org/apache/commons/collections/BidiMap.html

What you are looking for is a Bi-directional Map.
Try Apache Collections BidiMap.

http://commons.apache.org/collections/api-3.1/org/apache/commons/collections/BidiMap.html

飘落散花 2024-09-16 05:15:14

并不是说我立即知道,但你可以构建一个......拥有一个对象集合和多个查找结构(哈希图或树)怎么样,这些结构不存储对象本身(出于节省内存的原因),而是存储索引你的单品收藏?通过这种方式,您可以使用所需的适当查找结构(Id -> object 或反之亦然)返回一个整数值,您可以将其索引到原始集合中。这样,您可以执行的不仅仅是双向查找,以防将来需要这样做。

Not that I know of immediatley but you can build one ... How about having a single collection of your objects and several lookup structures (hashmaps or trees) that don't store the objects themselves (for memory saving reasons) but the index into your single collection? This way you use the appropriate lookup structure you need (Id -> object or vice versa) get back an integer value that you can index into your original collection. This way you can do more than a bidirectional lookup in case you need to do so in the future.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文