MultiMap vs MultiValue Map - java

At one place i have to use a map with many values mapped to a single key, so i was wondering whether there is any significant performance distinction between using HashMap of key, list and MultiMap of key , values in java.

You can try it but I doubt there is much difference as it does much the same thing.
IMHO The advantage is simpler/clearer code which is usually more important than performance.

I'd recommend to use google collections if you want to use a more convenient implementation of a Multimap. In case you don't want to introduce a new dependency, HashMap<Key, Collection<Value>> should do the trick which is pretty much what apache.collections HashMultiMap does.

If it is a Map Key-> Values, use a Map implementation.
As you will have some Values with the same Keys, use the http://guava-libraries.googlecode.com/svn/tags/release09/javadoc/com/google/common/collect/HashMultiset.html from the Google Collection (now guava library, http://code.google.com/p/guava-libraries/ ) for your task.

Hash provides O(1) which is fast and does nothing with the size of elements.
Regarding to Multimap, you could put values in dependent collection (List, Set). Different collection implementations provides different performance.
EDIT: As I commented on Sebastian's answer. You could use Guava which provides different value collection implemantions: HashMultiMap (HashMap<KEY, HashSet<VALUE>>), ArrayListMultiMap (HashMap<KEY, ArrayList<VALUE>>)...

Related

Difference between map and ImmutableMap

I work in payment gateway company and while analyzing the code I came across
ImmuatbleMap objects. I want to know all the details about. What is it?
What are its advantages over the map? Does core java has its support for ImmuatbleMap?
ImmutableMaps are introduced in Guava, they comply to Java's Map API, but with additional guarantees.
In a nutshell:
you cannot add, replace or remove entries
they are "fully immutable" if entry objects do not have mutable state
as a consequence, they are thread safe
nulls are forbidden
(slightly) more time- and space-efficient compared to usual Java's collections
iteration order is predictable
For full info see Guava's guide and javadoc for ImmutableCollection which applies to maps and other Guava's immutable collections.

Using a HashMap as a Key for another HashMap

I have a requirement where I need to map a set of configurations with a set of values, ideally denoted by a Map<Map<String, Object>, Map<String, Object>> structure.
Both the configurations & the values part of the main Map are arbitrary & hence, I am unable to use a concrete class.
Please provide some feedback on this structure. Can a Map be used as a key for another Map. Doing a bit of research, I was able to establish that the Map's equals method utilizes all underlying Keys & Values to deem two Maps as equal. Also, the HashCode of a Map is based on the Hashcodes of the Map's Keys. This IMO should suffice the minimum requirements of using a Map as a key.
I would still like someone to validate this before I go ahead with the implementation. In case there is a better solution / design that someone can suggest, please feel free to do so.
EDIT
I ended up using a simple tilde ('~') & pipe ('|') separated String as the key & deconstructed it whenever needed. Thanks to all who helped.
Yes, a HashMap can be used as a key to another map, as the class properly overrides .equals() and .hashCode().
However it's broadly speaking a bad idea to use mutable types (such as HashMap) as Map keys or Set elements, because you violate the invariants these classes expect if the objects are mutated while in the collection.
While not quite what you're looking for, Guava offers several additional data structures such as Multiset, MultiMap, BiMap, Table which may be useful. They also offer immutable collections such as ImmutableMap which (because they can't be mutated) are safer to use as a Map key. Which isn't to say you should do so, simply that it's safe (if the keys and values are also immutable).
Consider posting a question exploring the problem that lead you to conclude a Map<Map<K, V>, Map<K, V>> structure was what you needed. You may get better answers to that question.

is there any scenario where hashtable is better than concurrenthashmap?

As we all know that ConcurrentHashMap is better in performance but can we have any scenario where Hashtable is better?
I'll say this before answering the question: do not ever use Hashtable anymore. Hashtable is a legacy tool from Java 1.0, before the superior collections framework introduced with Java 2 going onwards.
If you require a simple hash map, use HashMap. If you require performing thread-safety, use ConcurrentHashMap. If you require plain basic and non-performing thread-safety, wrap a HashMap into Collections.synchronizedMap(Map).
Now to actually answer the question as is, which is purely compare two specific classes without seeing the spectrum of possibilities:
Yes, such scenarios exist
From the Hashtable documentation:
If a thread-safe implementation is not needed, it is recommended to use HashMap in place of Hashtable. If a thread-safe highly-concurrent implementation is desired, then it is recommended to use ConcurrentHashMap in place of Hashtable.
So yes, Hashtable is appropriate for scenarios where you need a thread-safe implementation, but do not "desire" a highly-concurrent implementation. This, again strictly in the exclusive comparison between ConcurrentHashMap and Hashtable.
Also, if you need Enumeration[1], Hashtable has a direct support, while you have to go through Collections.enumeration(...) for other Maps.
1. Enumeration is also a Java 1.0 class. Switch to Iterator (if using Java 2 to 7) or Stream (if using Java 8+)

Sorting a Guava BiMap

I am new to the Guava library, but have found that the BiMap fits my needs nicely. My one issue is that I need to sort the values in my BiMap. Normally, I would have used a TreeMap due to its inherit sorting, but being able to invert the map to look at the keys as if they are values is a must.
So I was looking for advice from you experts about going about this. The solutions I see are:
1. Create a BiMap comparator and use my own map sorting utility.
2. Build my own 'BiTreeMap' data structure.
Is there a solution I haven't considered? Is there a 'Guava way' to do this that I missed? Thanks!
We don't currently have a sorted BiMap type because it's a little ambiguous how it would work: would the entries be sorted by the keys? By the values? Would the forward entries be sorted by the keys, and the inverse entries be sorted by the values?
Currently, the only real available alternative is ImmutableBiMap, which retains the ordering that you put the entries in -- so ImmutableBiMap.copyOf(Maps.newTreeMap(map)) would give you a BiMap sorted by the keys.
(We might more seriously consider providing a directly sorted BiMap if you filed a feature request with more details on your use case, though.)

Key that yields multiple Results

I'm pretty new to programming so I'm sorry if this is a stupid question. I was wondering if there was a type of data that returns (possibly) more than one answer per key. For example:
TestType<int,String> test = new TestType<int,String>();
So if you typed, test.getKey(1), you could get {"hello","this","is","a","test"}.
Basically, is there a type of data that can return multiple answers, sort of like a HashMap and List combined?
Not in standard Java. However, you can use the Guava MultiMap collection type. There are other libraries that also provide a multi-map collection.
If for some reason you don't want to use a third-party library, you can also roll your own data structure. However, it is definitely reinventing the wheel and it's a bit of a pain. You would define test to be a Map<Integer, Set<String>> and then write access methods to initialize the key entry with an empty set under appropriate conditions.
Note that Java does not allow primitive types (e.g., int, as you are using) to be used as generic type parameter values. You'll have to use Integer. Because of autoboxing, you can still use test.get(1) to retrieve the values stored under the key 1.
You might want to use MultiMap from apache commons collections, and its specific implementation MultiHashMap
You could also use a Map<Integer,List<String>> - as you suggested.
What you're asking for is called a multimap, there are several implementations in Guava and another one in Apache commons collections.
Java does not offer a multimap since it is not used frequently (their statement). But SUN offers a small example on how to create a multimap yourself using a Map and a List as follows:
Map<String, List<String>> m = new HashMap<String, List<String>>();
You can see an example here in Java Collections/Maps. Check the paragraph on multimaps for example code
Amit's on the right track. You can also create a class for the answer. This could help you increase encapsulation.
Map<Integer, MyAnswer>
where MyAnswer could include attributes for the data you wish to manage. Implementing your own class here gives you a world of possibilities.

Categories