LinkedHashMap Structure for LRU Cache - java

I am a little confused about how to build a LRU cache by using LinkedHashMap (How would you implement an LRU cache in Java 6?), and I want to make sure I understand how it work internally behind the scene.
Lets say I define a class LRUMap that extends the LinkedHashMap and override the removeEldestEntry(final Map.Entry<A, B> eldest) just like the way it is.
Then I construct the data structure and insert 4 items into the map
LRUMap<String,String> map = new LRUMap<String,String>(3); //capacity 3
map.put("a", "a");
map.put("b", "b");
map.put("c", "c");
map.put("d", "d");
and interally LinkedHashMap uses an Entry object called header as a starting node to link with all the items that you add to the map. So in this case it will be
[header] -> ["a"] -> ["b"] -> ["c"] -> ["d"] -> [header]
The header Entry object is both the start and the end of the doubly linked list since header.before = header.after = header when it initially constructs.
And lets say the map reaches the maximum Entries (3 items) that I want it to be, and from
Entry<K,V> eldest = header.after;
if (removeEldestEntry(eldest)) {
removeEntryForKey(eldest.key);
}
.....
So does that mean it will remove ["a"] first ?
And when we call get(Object key) does it rearrange the list order where it puts that key (lets say "b") before the header node, so it becomes
[header] -> ["c"] -> ["d"] -> ["b"] -> [header]
Just want to clarify that.

Yes; the entry <"a", "a"> will be removed first :-)
Maybe; LinkedHashMap by default uses insertion-order, not access-order...
straight from the specification:
Hash table and linked list implementation of the Map interface, with predictable iteration 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).
That being said, LinkedHashMap also supports access-order;
A special constructor is provided to create a linked hash map whose order of iteration is the order in which its entries were last accessed, from least-recently accessed to most-recently (access-order). This kind of map is well-suited to building LRU caches. Invoking the put or get method results in an access to the corresponding entry (assuming it exists after the invocation completes).
So, if you're using insertion-order, then the order will not change from get("b"); if you're using access-order (which generally an LRU cache would ;-) then the order will change.
Any other questions? :-)

Related

I need to keep a collection of objects sorted by a "ranking" attribute even if I get more objects that are already in the collection

I'm programming an algorythm which is going to receive rows from a database, those rows will be defined within an object that has attributes that identify them and a "ranking" attribute. I have to use a collection (or find a way) to keep all those objects sorted by the ranking value, HOWEVER if I receive another object that is equal to other already in the collection (except for the ranking), I need to update the ranking value (adding up both objects' rankings) and keep the collection sorted.
I was thinking about a TreeSet, but there's no way I can update a value that is not on the root...
Okay let's say my collection is like:
(name='Federer', id='131', ranking='3000')
(name='Nadal', id='234', ranking='2500')
(name='Del Potro', id='180', ranking='1800')
If I receive this:
(name='Nadal', id='234', ranking='1000')
The collection should end up like this:
(name='Nadal', id='234', ranking='3500')
(name='Federer', id='131', ranking='3000')
(name='Del Potro', id='180', ranking='1800')
Thanks a lot in advance.
I've done some experimenting with TreeSet and TreeMap, but couldn't really find anything interesting for your situation. Depending on how often you add elements to the collection, it might be best to just use a HashMap and sort it when necessary.
For it to be more efficient, you could even keep track of some boolean flag that denotes that the HashMap is in a sorted state (if the Map is already sorted, then there's no need to sort it again if nothing has changed!).
var map = new HashMap<Element, Integer>();
map.put(new Element("Federer", 131), 3000);
map.put(new Element("Nadal", 234), 2500);
map.put(new Element("Del Potro", 180), 1800);
map.forEach((k, v) -> System.out.println(k + "=" + v));
System.out.println();
map.merge(new Element("Nadal", 234), 1000, Math::addExact);
map.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.forEach(System.out::println);
Output:
[Federer, 131]=3000
[Nadal, 234]=2500
[Del Potro, 180]=1800
[Nadal, 234]=3500
[Federer, 131]=3000
[Del Potro, 180]=1800
Note: I defined a class Element with a name and id field and use those fields when overriding Object#equals and Object#hashCode.
You said in the comments that your teacher recommended trees, but I don't see how you could use TreeSet or TreeMap classes for that (at least as they are).
TreeMap keeps the ordering by keys (which in your case are ids),
whereas you want to order the entries based on their rankings.
TreeSet, on the other hand, needs some property that would help it
compare two entries against each other, to only keep the ones that
are unique (since it is a set). If you want to compare based on
rankings, then if two rankings are equal, the treeset will think that the
two entries are equivalent (which might not be true). If you compare
based on ids, then it will be sorted according to the ids and not
rankings.
I think the easiest for you will be to store entries in a HashMap. And then when you need a sorted list, you can call values() on the hashmap, sort them and then display. You also mentioned that the number of entries won't surpass 300, so sorting should be very fast anyways.
You can keep a live map of ranking by ID, and use that as the basis for a priority queue to keep items sorted:
Map<Integer, Integer> rankingById = new HashMap<>();
Queue<Integer> idsByRanking = new PriorityQueue<>(
Comparator.comparing(rankingById::get).reversed());
void addItem(Item item) {
Integer id = item.getId();
idsByRanking.remove(id);
rankingById.merge(id, item.getRanking(), Integer::sum);
idsByRanking.add(id);
}
It's necessary to remove the item before updating the ranking so it can be reinserted at the correct position. See also: Updating Java PriorityQueue when its elements change priority

LinkedHashMap Implementation in Java

I cannot understand the use of HashFunction in LinkedHashMap.
In the HashMap implementation, the use of hashFunction is to find the index of the internal array, which can be justified, following the hashfunction contract (same key will must have same hashcode, but distinct key can have same hashcode).
My questions are:
1) What is the use of hashfunction in LinkedHashMap?
2) How does the put and get method works for LinkedHashMap?
3) Why does it maintains the doublylinkedlist internally?
Whats wrong in using the HashMap as internal implementation(just like HashSet) and maintain a separate Array/List of indexes of the Entry array in the sequence of insertion?
Appreciate useful response and references.
1) LinkedHashMap extends HashMap so the hashfunction is the same of HashMap (if you check the code the hash function is inherited from HashMap), i.e. the function computes a the hash of the object inserted and it use to store in a data structure together with the elements with the same key hash; the hasfunction is used in the get method to retrieve the object with the key specified as a param.
2)Put and Get method are behave the same way as HashMap plus the track the insertion order of the elements so when you iterate over the the keyset you get the key values in the order you inserted into the map (see here for more details)
3)the LinkedHashMap uses a double linked list instead of an Array because it's more compact; a double linked list is the the most efficient data structure for list where you insert and remove items; if you mostly insert/append elements then an array based implementation may be better. Since the map sematic is a key-value implementation and removing elements from the map could be a frequent operation a double linked list is a better fit. The internal implmentation could be made with a LinkedList but my opionion is that using a low level data stucture is more efficient and decouples LinkedHashMap from other classes.
A LinkedHashMap does use a HashMap (in fact it extends from it), so the hashCode is used to identify the right hash bucket in the array of hash buckets, just as for HashMap. put and get work just as for HashMap (except that the before and after references for iterating over the entries are updated differently for the two implementations).
The reason insertion order is not kept by keeping an Array or ArrayList is that addition or removal in the middle of an ArrayList is an O(n) operation because you have to move all subsequent items along one place. You could do this with a LinkedList because addition and removal in the middle of a LinkedList is O(1) (all you have to do is break a few links and make a few new ones). However there's no point using a separate LinkedList because you may as well make the Map.Entry objects reference the previous and next Entry objects, which is exactly how LinkedHashMap works.
LinkedHashMap is a good choice for a data structure where you want to be able to put and get entries with O(1) running time, but you also need the behavior of a LinkedList. The internal hashing function is what allows you put and get entries with constant-time.
Here is how you use LinkedHashMap:
Map<String, Double> linkedHashMap = new LinkedHashMap<String, String>();
linkedHashMap.put("today", "Wednesday");
linkedHashMap.put("tomorrow", "Thursday");
String today = linkedHashMap.get("today"); // today is 'Wednesday'
There are several arguments against using a simple HashMap and maintaining a separate List for the insertion order. First, if you go this route it means you will have to maintain 2 data structures instead of one. This is error prone, and makes maintaining your code more difficult. Second, if you have to make your data structure Thread-safe, this would be complex for 2 data structures. On the other hand, if you use a LinkedHashMap you only would have to worry about making this single data structure thread-safe.
As for implementation details, when you do a put into a LinkedHashMap, the JVM will take your key and use a cryptographic mapping function to ultimately convert that key into a memory address where your value will be stored. Doing a get with a given key will also use this mapping function to find the exact location in memory where the value be stored. The entrySet() method returns a Set consisting of all the keys and values in the LinkedHashMap. By definition, sets are not ordered. The entrySet() is not guaranteed to be Thread-safe.
Ans. 2)
when we call put(map,key) of linkedhashmap. Internally it calls createEntry
void createEntry(int hash, K key, V value, int bucketIndex) {
HashMap.Entry<K,V> old = table[bucketIndex];
Entry<K,V> e = new Entry<K,V>(hash, key, value, old);
table[bucketIndex] = e;
e.addBefore(header);
size++;
Ans 3)
To efficiently maintain a linkedHashmap, you actually need a doubly linked list.
Consider three entries in order
A ---> B ---> C
Suppose you want to remove B. Obviously A should now point to C. But unless you know the entry before B you cannot efficiently say which entry should now point to C. To fix this, you need entries to point in both the directions Like this
---> --->
A B C
<--- <---
This way, when you remove B you can look at the entries before and after B (A and C) and update so that A and C point to each other.
similar post in this link discussed earlier
why linkedhashmap maintains doubly linked list for iteration

How to get key position from a HashMap in Java

How can I get the key position in the map? How can I see on which position is "Audi" and "BMW"?
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("Audi", 3);
map.put("BMW", 5);
As other answers state you need to use a structure like java.util.LinkedHashMap. LinkedHashMap maintains its keys internally using a LinkedEntrySet, this does not formally provide order, but iterates in the insertion order used.
If you pass the Map.keySet() into a List implementation you can make use of the List.indexOf(Object) method without having to write any of the extra code in the other answer.
Map<String, Integer> map = new LinkedHashMap<String, Integer>();
map.put("Audi", 3);
map.put("BMW", 5);
map.put("Vauxhall", 7);
List<String> indexes = new ArrayList<String>(map.keySet()); // <== Set to List
// BOOM !
System.out.println(indexes.indexOf("Audi")); // ==> 0
System.out.println(indexes.indexOf("BMW")); // ==> 1
System.out.println(indexes.indexOf("Vauxhall")); // ==> 2
You can't. The keys on a Map and a HashMap are not ordered. You'll need to use a structure that preserves order, such as a LinkedHashMap.
Note that LinkedHashMap does not provide a method that gets keys by position, so this is only appropriate if you are going to be using an iterator.
The alternative is to create a second Map that maps from your key to the Integer position, and add to it as you go along:
Map<String, Integer> indexMap = new HashMap<String, Integer>();
indexMap.put("Audi", 0);
indexMap.put("BMW", 1);
For a more elegant solution, you might need to give more information about what you're doing.
You can't. From the HashMap JavaDocs:
Hash table based implementation of the Map interface. This implementation provides all of the optional map operations, and permits null values and the null key. (The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls.) 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.
So, the order may vary between iterations. If you need to preserve the order you can take a look at LinkedHashMap
From the LinkedHashMap JavaDocs:
Hash table and linked list implementation of the Map interface, with predictable iteration 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).
So, to find the key position you basically need to iterate the keys and count the position of the key you are searching for.
On a side note, IMO this may not be the best use of the Map datatype. I believe that if you really need the position you should use some type of List (e.g. ArrayList) that actually preserves the order and you can use the get method to retrieve elements for a certain index.

Java HashMap and underlying values() collection

I was wondering if the Collection view of the values contained in a HashMap is kept ordered when the HashMap changes.
For example if I have a HashMap whose values() method returns L={a, b, c}
What happened to L if I add a new element "d" to the map?
Is it added at the end, i.e. if I iterate through the elements, it's the order kept?
In particular, if the addition of the new element "d" causes a rehash, will the order be kept in L?
Many thanks!
I was wondering if the Collection view of the values contained in a HashMap is kept ordered when the HashMap changes.
No, there is no such guarantee.
If this was the case, then the following program would output and ordered sequence from 1-100
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i = 0; i < 100; i++)
map.put(i, i);
System.out.println(map.values());
(and it doesn't).
There is a class that does precisely what you're asking for, and that is LinkedHashMap:
Hash table and linked list implementation of the Map interface, with predictable iteration 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).
If it doesn't say it in the JavaDoc then there are no guarantees about it. Different versions of Java could do different things. Don't depend on undocumented behaviour.
You might want to look at LinkedHashMap.
HashMap in Java aren't ordered, so I think it will be safe to say that values() won't return an ordered Collection.
LinkedHashMap is an ordered version of HashMap (insertion order), but I don't know it values() will return an ordered Collection. I think the best is to try.
Generally they is no guarantee of order when you are using HashMap. It might be in the order in which you add elements for a few elements but it would get reshuffled when there is a possibility of collision and it has to go with a collision resolution strategy.

Difference between HashMap, LinkedHashMap and TreeMap

What is the difference between HashMap, LinkedHashMap and TreeMap in Java?
I don't see any difference in the output as all the three has keySet and values. What are Hashtables?
Map m1 = new HashMap();
m1.put("map", "HashMap");
m1.put("schildt", "java2");
m1.put("mathew", "Hyden");
m1.put("schildt", "java2s");
print(m1.keySet());
print(m1.values());
SortedMap sm = new TreeMap();
sm.put("map", "TreeMap");
sm.put("schildt", "java2");
sm.put("mathew", "Hyden");
sm.put("schildt", "java2s");
print(sm.keySet());
print(sm.values());
LinkedHashMap lm = new LinkedHashMap();
lm.put("map", "LinkedHashMap");
lm.put("schildt", "java2");
lm.put("mathew", "Hyden");
lm.put("schildt", "java2s");
print(lm.keySet());
print(lm.values());
I prefer visual presentation:
Property
HashMap
TreeMap
LinkedHashMap
Iteration Order
no guaranteed order, will remain constant over time
sorted according to the natural ordering
insertion-order
Get / put / remove / containsKey
O(1)
O(log(n))
O(1)
Interfaces
Map
NavigableMap, Map, SortedMap
Map
Null values/keys
allowed
only values
allowed
Fail-fast behavior
Fail-fast behavior of an iterator cannot be guaranteed, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification
Fail-fast behavior of an iterator cannot be guaranteed, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification
Fail-fast behavior of an iterator cannot be guaranteed, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification
Implementation
buckets
Red-Black Tree
double-linked buckets
Is synchronized
implementation is not synchronized
implementation is not synchronized
implementation is not synchronized
All three classes implement the Map interface and offer mostly the same functionality. The most important difference is the order in which iteration through the entries will happen:
HashMap makes absolutely no guarantees about the iteration order. It can (and will) even change completely when new elements are added.
TreeMap will iterate according to the "natural ordering" of the keys according to their compareTo() method (or an externally supplied Comparator). Additionally, it implements the SortedMap interface, which contains methods that depend on this sort order.
LinkedHashMap will iterate in the order in which the entries were put into the map
"Hashtable" is the generic name for hash-based maps. In the context of the Java API,
Hashtable is an obsolete class from the days of Java 1.1 before the collections framework existed. It should not be used anymore, because its API is cluttered with obsolete methods that duplicate functionality, and its methods are synchronized (which can decrease performance and is generally useless). Use ConcurrentHashMap instead of Hashtable.
All three represent mapping from unique keys to values, and therefore implement the Map interface.
HashMap is a map based on hashing of the keys. It supports O(1) get/put operations. Keys must have consistent implementations of hashCode() and equals() for this to work.
LinkedHashMap is very similar to HashMap, but it adds awareness to the order at which items are added (or accessed), so the iteration order is the same as insertion order (or access order, depending on construction parameters).
TreeMap is a tree based mapping. Its put/get operations take O(log n) time. It requires items to have some comparison mechanism, either with Comparable or Comparator. The iteration order is determined by this mechanism.
See where each class is in the class hierarchy in the following diagram (bigger one). TreeMap implements SortedMap and NavigableMap while HashMap doesn't.
HashTable is obsolete and the corresponding ConcurrentHashMap class should be used.
HashMap
It has pair values(keys,values)
NO duplication key values
unordered unsorted
it allows one null key and more than one null values
HashTable
same as hash map
it does not allows null keys and null values
LinkedHashMap
It is ordered version of map implementation
Based on linked list and hashing data structures
TreeMap
Ordered and sortered version
based on hashing data structures
Just some more input from my own experience with maps, on when I would use each one:
HashMap - Most useful when looking for a best-performance (fast) implementation.
TreeMap (SortedMap interface) - Most useful when I'm concerned with being able to sort or iterate over the keys in a particular order that I define.
LinkedHashMap - Combines advantages of guaranteed ordering from TreeMap without the increased cost of maintaining the TreeMap. (It is almost as fast as the HashMap). In particular, the LinkedHashMap also provides a great starting point for creating a Cache object by overriding the removeEldestEntry() method. This lets you create a Cache object that can expire data using some criteria that you define.
All three classes HashMap, TreeMap and LinkedHashMap implements java.util.Map interface, and represents mapping from unique key to values.
HashMap
A HashMap contains values based on the key.
It contains only unique elements.
It may have one null key and multiple null values.
It maintains no order.
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
LinkedHashMap
A LinkedHashMap contains values based on the key.
It contains only unique elements.
It may have one null key and multiple null values.
It is same as HashMap instead maintains insertion order. //See class deceleration below
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>
TreeMap
A TreeMap contains values based on the key. It implements the NavigableMap interface and extends AbstractMap class.
It contains only unique elements.
It cannot have null key but can have multiple null values.
It is same as HashMap instead maintains ascending order(Sorted using the natural order of its key.).
public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, Serializable
Hashtable
A Hashtable is an array of list. Each list is known as a bucket. The position of bucket is identified by calling the hashcode() method. A Hashtable contains values based on the key.
It contains only unique elements.
It may have not have any null key or value.
It is synchronized.
It is a legacy class.
public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable
Ref: http://javarevisited.blogspot.in/2015/08/difference-between-HashMap-vs-TreeMap-vs-LinkedHashMap-Java.html
HashMap makes absolutely not guarantees about the iteration order. It
can (and will) even change completely when new elements are added.
TreeMap will iterate according to the "natural ordering" of the keys
according to their compareTo() method (or an externally supplied
Comparator). Additionally, it implements the SortedMap interface,
which contains methods that depend on this sort order. LinkedHashMap
will iterate in the order in which the entries were put into the map
Look at how performance varying..
Tree map which is an implementation of Sorted map. The complexity of the put, get and containsKey operation is O(log n) due to the Natural ordering
#Amit: SortedMap is an interface whereas TreeMap is a class which implements the SortedMap interface. That means if follows the protocol which SortedMap asks its implementers to do.
A tree unless implemented as search tree, can't give you ordered data because tree can be any kind of tree. So to make TreeMap work like Sorted order, it implements SortedMap ( e.g, Binary Search Tree - BST, balanced BST like AVL and R-B Tree , even Ternary Search Tree - mostly used for iterative searches in ordered way ).
public class TreeMap<K,V>
extends AbstractMap<K,V>
implements SortedMap<K,V>, Cloneable, Serializable
In NUT-SHELL
HashMap : gives data in O(1) , no ordering
TreeMap : gives data in O(log N), base 2. with ordered keys
LinkedHashMap : is Hash table with linked list (think of indexed-SkipList) capability to store data in the way it gets inserted in the tree. Best suited to implement LRU ( least recently used ).
Hash map doesn't preserves the insertion order.
Example. Hashmap
If you are inserting keys as
1 3
5 9
4 6
7 15
3 10
It can store it as
4 6
5 9
3 10
1 3
7 15
Linked Hashmap preserves the insertion order.
Example.
If you are inserting keys
1 3
5 9
4 6
7 15
3 10
It will store it as
1 3
5 9
4 6
7 15
3 10
same as we insert.
Tree map stores the vales in Increasing Order Of Keys.
Example.
If you are inserting keys
1 3
5 9
4 6
7 15
3 10
It will store it as
1 3
3 10
4 6
5 9
7 15
HashMap:
Order not maintains
Faster than LinkedHashMap
Used for store heap of objects
LinkedHashMap:
LinkedHashMap insertion order will be maintained
Slower than HashMap and faster than TreeMap
If you want to maintain an insertion order use this.
TreeMap:
TreeMap is a tree-based mapping
TreeMap will follow the natural ordering of key
Slower than HashMap and LinkedHashMap
Use TreeMap when you need to maintain natural(default) ordering
Following are major difference between HashMap and TreeMap
HashMap does not maintain any order. In other words , HashMap does not provide any guarantee that the element inserted first will be printed first, where as Just like TreeSet , TreeMap elements are also sorted according to the natural ordering of its elements
Internal HashMap implementation use Hashing and TreeMap internally uses Red-Black tree implementation.
HashMap can store one null key and many null values.TreeMap can not contain null keys but may contain many null values.
HashMap take constant time performance for the basic operations like get and put i.e O(1).According to Oracle docs , TreeMap provides guaranteed log(n) time cost for the get and put method.
HashMap is much faster than TreeMap, as performance time of HashMap is constant against the log time TreeMap for most operations.
HashMap uses equals() method in comparison while TreeMap uses compareTo() method for maintaining ordering.
HashMap implements Map interface while TreeMap implements NavigableMap interface.
These are different implementations of the same interface. Each implementation has some advantages and some disadvantages (fast insert, slow search) or vice versa.
For details look at the javadoc of TreeMap, HashMap, LinkedHashMap.
While there are plenty of excellent Answers here, I'd like to present my own table describing the various Map implementations bundled with Java 11.
We can see these differences listed on the table graphic:
HashMap is the general-purpose Map commonly used when you have no special needs.
LinkedHashMap extends HashMap, adding this behavior: Maintains an order, the order in which the entries were originally added. Altering the value for key-value entry does not alter its place in the order.
TreeMap too maintains an order, but uses either (a) the “natural” order, meaning the value of the compareTo method on the key objects defined on the Comparable interface, or (b) invokes a Comparator implementation you provide.
TreeMap implements both the SortedMap interface, and its successor, the NavigableMap interface.
NULLs: TreeMap does not allow a NULL as the key, while HashMap & LinkedHashMap do.
All three allow NULL as the value.
HashTable is legacy, from Java 1. Supplanted by the ConcurrentHashMap class. Quoting the Javadoc: ConcurrentHashMap obeys the same functional specification as Hashtable, and includes versions of methods corresponding to each method of Hashtable.
The most important among all the three is how they save the order of the entries.
HashMap - Does not save the order of the entries.
eg.
public static void main(String[] args){
HashMap<String,Integer> hashMap = new HashMap<>();
hashMap.put("First",1);// First ---> 1 is put first in the map
hashMap.put("Second",2);//Second ---> 2 is put second in the map
hashMap.put("Third",3); // Third--->3 is put third in the map
for(Map.Entry<String,Integer> entry : hashMap.entrySet())
{
System.out.println(entry.getKey()+"--->"+entry.getValue());
}
}
LinkedHashMap : It save the order in which entries were made. eg:
public static void main(String[] args){
LinkedHashMap<String,Integer> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("First",1);// First ---> 1 is put first in the map
linkedHashMap.put("Second",2);//Second ---> 2 is put second in the map
linkedHashMap.put("Third",3); // Third--->3 is put third in the map
for(Map.Entry<String,Integer> entry : linkedHashMap.entrySet())
{
System.out.println(entry.getKey()+"--->"+entry.getValue());
}
}
TreeMap : It saves the entries in ascending order of the keys. eg:
public static void main(String[] args) throws IOException {
TreeMap<String,Integer> treeMap = new TreeMap<>();
treeMap.put("A",1);// A---> 1 is put first in the map
treeMap.put("C",2);//C---> 2 is put second in the map
treeMap.put("B",3); //B--->3 is put third in the map
for(Map.Entry<String,Integer> entry : treeMap.entrySet())
{
System.out.println(entry.getKey()+"--->"+entry.getValue());
}
}
All offer a key->value map and a way to iterate through the keys. The most important distinction between
these classes are the time guarantees and the ordering of the keys.
HashMap offers 0(1) lookup and insertion. If you iterate through the keys, though, the ordering of the
keys is essentially arbitrary. It is implemented by an array of linked lists.
TreeMap offers O(log N) lookup and insertion. Keys are ordered, so if you need to iterate through
the keys in sorted order, you can. This means that keys must implement the Comparable interface.TreeMap is implemented by a Red-Black Tree.
LinkedHashMap offers 0(1) lookup and insertion. Keys are ordered by their insertion order. It is
implemented by doubly-linked buckets.
Imagine you passed an empty TreeMap, HashMap, and LinkedHashMap into the following function:
void insertAndPrint(AbstractMap<Integer, String> map) {
int[] array= {1, -1, 0};
for (int x : array) {
map.put(x, Integer.toString(x));
}
for (int k: map.keySet()) {
System.out.print(k + ", ");
}
}
The output for each will look like the results below.
For HashMap, the output was, in my own tests, { 0, 1, -1}, but it could be any ordering. There is no guarantee on the
ordering.
Treemap,the output was,{ -1, 0, 1}
LinkedList,the output was,{ 1, -1, 0}
HashMap
can contain one null key.
HashMap maintains no order.
TreeMap
TreeMap can not contain any null key.
TreeMap maintains ascending order.
LinkedHashMap
LinkedHashMap can be used to maintain insertion order, on which keys are inserted into Map or it can also be used to maintain an access order, on which keys are accessed.
Examples::
1) HashMap map = new HashMap();
map.put(null, "Kamran");
map.put(2, "Ali");
map.put(5, "From");
map.put(4, "Dir");`enter code here`
map.put(3, "Lower");
for (Map.Entry m : map.entrySet()) {
System.out.println(m.getKey() + " " + m.getValue());
}
2) TreeMap map = new TreeMap();
map.put(1, "Kamran");
map.put(2, "Ali");
map.put(5, "From");
map.put(4, "Dir");
map.put(3, "Lower");
for (Map.Entry m : map.entrySet()) {
System.out.println(m.getKey() + " " + m.getValue());
}
3) LinkedHashMap map = new LinkedHashMap();
map.put(1, "Kamran");
map.put(2, "Ali");
map.put(5, "From");
map.put(4, "Dir");
map.put(3, "Lower");
for (Map.Entry m : map.entrySet()) {
System.out.println(m.getKey() + " " + m.getValue());
}

Categories