Bilateral Collections in Java

I have a list of objects. Objects are assigned an identifier and stored in a Hashtable. If I need an object with a specific identifier, I just say:

ht.get(ID); 

However, sometimes I need to get an identifier for this object:

 ht.get(Object); 

My first idea is to use two different HashTables; one for ID β†’ Display objects, and the other for matching identifiers Object β†’ ID.

Does this sound like a good enough solution?

+4
source share
5 answers

If you cannot use external collections (as you seem to not want to use this comment), you can write a simple class to do what you want (which, yes, this is, in fact, your first thought), along the lines (I did not compile this, and this is just a first thought, so there may be a bad idea, etc.):

EDIT: There are now two versions, one of which allows duplicate values, and the other does not. Those that do not delete 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 you to duplicate values ​​and returns a list of all 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 two cards in a class is a good idea because you will find a better way later, all you have to do is replace the class internals and the rest of your code will remain untouched.

+8
source

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

+2
source

What you are looking for is a bi-directional map. You can find it in collection collections in classes that implement BidiMap or Google Guava .

0
source

What you are looking for is a bi-directional map. Try Apache BidiMap Collections.

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

0
source

Not that I knew about the immediate, but you can create one ... How about having one collection of your objects and several search structures (hashmaps or trees) that do not store the objects themselves (for reasons of memory saving), but an index into your single collection? Thus, you use the desired search structure (Id β†’ object or vice versa), return an integer value that you can index into your original collection. This way you can do more than bidirectional search if you need to do this in the future.

0
source

Source: https://habr.com/ru/post/1315015/


All Articles