[英]Two way collections in Java
I have a list of objects. 我有一个对象列表。 The objects are given an ID and stored in a Hashtable.
给对象一个ID并存储在Hashtable中。 If I need an object with particular ID, I simply say:
如果我需要一个具有特定ID的对象,我只想说:
ht.get(ID);
However, sometimes I need to get the ID for a given object: 但是,有时我需要获取给定对象的ID:
ht.get(Object);
My first idea is to use two different HashTables; 我的第一个想法是使用两个不同的HashTables; one for ID -> Object mapping and the other for Object -> ID mapping.
一个用于ID - >对象映射,另一个用于对象 - > ID映射。
Does this sound like a good enough solution? 这听起来像是一个足够好的解决方案吗?
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 ...): 如果你不能使用外部集合(因为你似乎不想使用你的评论之一),你可以编写一个简单的类来做你想要的(这是,基本上是你的第一个想法),沿着(I没有编译这个,这只是第一个想法所以可能是一个坏主意等...):
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. 在一个类中隐藏这两个映射是一个好主意,因为你找到了一个更好的方法,以后你需要做的就是替换类的内部,而其余的代码保持不变。
如果使用外部库是正常的,您应该在google集合上查看BiMap: http : //google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/BiMap.html
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 .
您可以在实现BidiMap界面或Google Guava的类中的commons集合中找到它。
What you are looking for is a Bi-directional Map. 您正在寻找的是双向地图。 Try Apache Collections BidiMap.
试试Apache Collections BidiMap。
http://commons.apache.org/collections/api-3.1/org/apache/commons/collections/BidiMap.html http://commons.apache.org/collections/api-3.1/org/apache/commons/collections/BidiMap.html
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? 不是我知道immediatley但你可以构建一个...如何拥有一个对象的集合和几个不存储对象本身的查找结构(哈希映射或树)(为了节省内存的原因)但索引到你的单一收藏? 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.
这样您就可以使用所需的相应查找结构(Id - > object,反之亦然)获取一个可以索引到原始集合中的整数值。 This way you can do more than a bidirectional lookup in case you need to do so in the future.
这样,您可以做的不仅仅是双向查找,以防将来需要这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.