For homework, I have to implement a variety of hash functions in C++ or Java. I'm comfortable working with Java, but haven't used its hash functionality.
I want a hash structure that links colliding keys. Like this:
Is LinkedHashMap the correct choice here? Is it HashMap? Either? Why?
Well, just a regular HashMap links entries that end up in the same bucket (each bucket is really an element in an array of linked lists). A LinkedHashMap also maintains links between entries to preserve the insertion order, but that's not what's happening in your diagram.
HashMap does this.
What LinkedHashMap does is linking the keys in insertion order.
I think the standard HashMap already works this way: it has a number of bins, and elements with colliding hash codes end up in the same bin. You can lookup the source code of HashMap yourself: in your JDK installation directory there is a file src.zip that contains the source code.
LinkedHashMap is just a HashMap combined with a List to keep track of the insertion order of elements in the map. The word "linked" in its name doesn't have anything in particular to do with how elements in one bin are stored.
You may use HashMap
Map<String,ArrayList<Object>> map = new HashMap<String,ArrayList<Object>>();
Instead of object specify the type you need.
The HashMap grants fast random access.
Also there are :
TreeMap - data sorted by key.
LinkedHashMap - data stored in order it is entered to the container.
LinkedHashMap is for creating a iteratable map that with predictable order of the keys. Internally, a HashHap is free to use whatever means it deems fit to handle key collision which may or may not be a linked list. I don't think there is any standard guarantee that the underlaying mechanism for collision buckets to use a linked list in Java but in practice they may.
Related
Lately,I've been going through implementations of Map interface in java. I understood HashMap and everything made sense.
But when it comes to LinkedHashMap, as per my knowledge so far, the Entry has key, value, before and after. where before and after keeps track of order of insertion.
However, using hashcode and bucket concept doesn't make sense to me in LinkedHashMaps.
I went through this article for understanding implementation of linkedHashMaps
Could someone please explain it? I mean why does it matter in which bucket we put the entry node. In fact why bucket concept in the first place.? why not plain doubly llinked lists?
LinkedHashMap is still a type of a HashMap. It uses the same logic as HashMap in order to find the bucket where a key belongs (used in methods such as get(),put(),containsKey(),etc...). The hashCode() is used to locate that bucket. This logic is essential for the expected O(1) performance of these operations.
The added functionality of LinkedHashMap (which uses the before and after references) is only used to iterate the entries according to insertion order, so it affects the iterators of the Collections returned by the keySet(),entrySet() & values() methods. It doesn't affect where the entries are stored.
Without hashcodes and buckets, LinkedHashMap won't be able to lookup keys in the Map in O(1) expected time.
I need to sort a hash map according to the key.The key is a string(so I need to sort it alphabetically) and the value is an integer.
I was trying to search online and found that tree set automatically sorts it once you put it. Could somebody guide me in the right direction as to how I could convert it into a tree set or maybe even if i could just sort it using a hash map.
Thanks in advance
Since hashmaps are unsorted maps by definition you'd need to use another container for that. Depending on your needs there are several options, some being:
Use a TreeMap instead of a HashMap either temporarily or as a replacement. This would be the best option unless you have to keep the hashmap.
Use a TreeSet to sort the keys, then iterate over the keys and extract the values from the HashMap.
Do the same as in option 2 but fill a new LinkedHashMap during iteration. This will result in a map that returns the values in insert order which happens to be sort order due to use of a sorted set. Note that adding elements to the LinkedHashMap will append any new elements to the end - LinkedHashMap is still ordered by insertion order.
Is there some sort of data structure in Java that resembles a HashMap that can be sorted by key or value? In PHP you can have associative arrays that are sortable. Is there such a thing in Java?
HashMaps are unsorted almost by definition; a good hash function will produce a seemingly random distribution of the keys.
If you want to use a Map in Java that stores its elements in sorted order, consider looking into TreeMap, which is backed by a sorted binary search tree.
If you want something that can be sorted either by key or by value, you may be looking for a bidirectional map or "bimap." Java doesn't have on in its standard libraries, and the closest implementation I know of is Google's BiMap. However, as Pangea pointed out, it does not support elements in sorted order. You could easily make your own implementation by just using two TreeMaps, though, one from keys to values and one from values to keys.
Hope this helps!
SortedMap sorted only by keys
I was wondering how Java orders items in the Map (HashMap or Hashtable) when they are added. Are the keys ordered by the hashcode, memory reference or by allocation precedence...?
It's because I've noticed same pairs in the Map are not always in the same order
java.util.HashMap is unordered; you can't and shouldn't assume anything beyond that.
This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.
java.util.LinkedHashMap uses insertion-order.
This implementation differs from HashMap in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order).
java.util.TreeMap, a SortedMap, uses either natural or custom ordering of the keys.
The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.
First of all: HashMap specifically doesn't provide a stable and/or defined ordering. So anything you observe is simply an implementation detail and you must not depend on it in any way.
Since it is sometimes useful to know the reason for the seemingly random ordering, here's the basic idea:
A HashMap has number of buckets (implemented as an array) in which to store entries.
When an item is added to the map, it is assigned to a buckets based on a value derived of its hashCode and the bucket size of the HashMap. (Note that it's possible that the bucket is already occupied, which is called a collision. That's handled gracefully and correctly, but I'll ignore that handling for the description because it doesn't change the concept).
The perceived ordering of the entires (such as returned by iterating over the Map) depends on the order of the entries in those buckets.
Whenever the size is rehashed (because the map exceeded its fullness threshold), then the number of buckets changes, which means that the position of each element might change, since the bucket position is derived from the number of buckets as well.
HashMap does not sort at all. For a map that sorts by key values you should use TreeMap instead.
From the JavaDocs for TreeMap:
Red-Black tree based implementation of
the SortedMap interface. This class
guarantees that the map will be in
ascending key order, sorted according
to the natural order for the key's
class (see Comparable), or by the
comparator provided at creation time,
depending on which constructor is
used.
From the documentation of HashMap:
This class makes no guarantees as to
the order of the map; in particular,
it does not guarantee that the order
will remain constant over time.
A Map is not an ordered data structure - you should not rely on entries in a HashMap being in a certain order. Some Map implementations such as LinkedHashMap and TreeMap do guarantee a certain order, but HashMap does not.
If you really want to know what happens internally, lookup the source code of HashMap - you can find it in src.zip which should be in your JDK installation directory.
A HashMap has a number of "buckets" in which it stores its entries. Which bucket an entry is stored in is determined by the hash code of the key of the entry. The order in which you see the entries in the HashMap depends on the hash codes of the keys. But don't write programs that rely on entries being in a certain order in a HashMap - the implementation might change in a future version of Java and your program then would not work anymore.
hashmap has a not defined order of the elements
There is no defined ordering in a hash table. Keys are placed into a slot, based on the hash code, but even that isn't a trivial order-by-hash-code.
HashMap stores the values using the unique hash-value generated using a part of the key. This hash-value maps to the address where it is going to be stored. This is how it ensures an access O(1).
LinkedHashmap on the other hand preserves the order in which you added to the map.
I need a collection that behaves something like C++ multimap, but I also need to be able to get elements by a range of keys.
You can look into Google Collections. It has multiple implementations for MultiMap.
There is no built-in multimap collection in Java. To solve this you can map to every key a list of values: Map<String, List<String>>, for example. Otherwise there are third-party libraries with implemented multimaps - here is one of them.
There is a simple hack around creating multimap sortable collections in java...Use the dataset TreeMap and for keys enter key*10^4+counter. This way you are storing duplicate key values in the map (by adding counter they are actually not duplicates, so you can store the in treeMap, but you know not to use the last four digits of the integer key values), however your dataset is being sorted using your original key values. Note that depending how large is your dataset you might want to adjust 10^n to make sure that it is larger then the number of entries in your data.