How to remove first element from a TreeMap? - java

I need to implement a container which contains maximum 32 values where elements are sorted by key. In C++ it's kinda easy, cause every map is sorted by it's key, in Java I'm not that sure.
So I read some and came with a TreeMap.
How to efficently remove the oldest element from a TreeMap (the first one)?
Thanks!

You said
The key here is a 'sequenceNumber' which is being incremented in the same loop.
By TreeMap documentation it states
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.
So you can easily remove the first element after sorted.
Example:
TreeMap<Integer, String> map = new TreeMap<>();
map.put(1, "ac");
map.put(2, "ef");
map.put(3, "bd");
map.remove(map.firstKey());

Use LinkedHashMap, which has method removeEldestEntry.

Related

Sort hasmap by value inside of a treemap

I have the following treemap
private TreeMap<Long, HashMap<Long, Entry>> index;
Entry contains:
int tf //count
ArrayList<long> off //positions
For each entry in the treemap, I would like to sort the hashmaps by tf. In the following picture, tf of [3] has a bigger value of tf of [0] so I would like to move it to be at the beggining. How can I do that?
You cannot order a HashMap. Trying to do so breaks the way a HashMap stores and finds the elements added to it
What you are trying to do here (as I understand it) is sorting the treemap by its value, while TreeMap can only sort by its keys. more details here - TreeMap sort by value
You may try writing your own sorting method and store the result of sort in a linkedHashMap instead of Treemap. That way you can be able to access the entries in the exact order you added that to the linkedHashMap.
Note: with each change happening to the original map, you ll need to sort it and move it to a different linkedHashMap. Which is very clumsy.
You may consider using different object model for your program.
I believe the fundamental problem with your question is that HashMaps are not sortable by definition. Secondly, a variable definition that is more generic may prove useful:
private SortedMap<Long, SortedMap<Entry, Long>> index;
Noticed I switched the order of Entry and Long. This is because Maps only sort based on the key. You'd have to either make Entry implement Comparable or provide a custom Comparator when you instantiate that Map.

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.

Iterating HashMap in order

I have a HashMap.
It has 100s of millions of observations.
What's the best way to iterate over the elements of the HashMap, in numerical order of the keys?
I considered changing to TreeMap, but did not do that since it may actually increase the load in creating the Map (as TreeMap is O(n), HashMap is O(1)).
With Java 8 you could use something similar to the following:
import static java.util.Comparator.comparing;
map.entrySet().stream()
.sorted(comparing(Entry::getKey))
.forEach(e -> doSomethingWithTheEntry(e));
That will obviously involve sorting the unsorted keys, which will come at a cost. So you need to decide whether you want to pay the cost upfront with a TreeMap or when required and keep using a HashMap.
You can't iterate over a HashMap in order. You'll have to use TreeMap for that. If you use a LinkedHashMap, you can iterate in the order the keys were inserted to the Map, but it's still not what you want (unless you insert the keys in numerical order).
If your insertion order is the same order as your keys, then you could use a 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). Note that insertion order is not affected if a key is re-inserted into the map. (A key k is reinserted into a map m if m.put(k, v) is invoked when m.containsKey(k) would return true immediately prior to the invocation.)

HashMap returns value in non sequential order

I am inserting four values with different keys in a HashMap.
Code Snippet :
HashMap<Integer, String> choice = new HashMap<Integer, String>();
choice.put(1, "1917");
choice.put(2, "1791");
choice.put(3, "1902");
choice.put(4, "1997");
But when I am printing that map values,it returns a result something like :
{4=1997, 1=1917, 2=1791, 3=1902}
How can I get the map values in a sequential order the way I have put/inserted?
You can use a LinkedHashMap instead, which will keep the 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).
You can modify your code like this:
Map<Integer, String> choice = new LinkedHashMap<Integer, String>();
//rest of the code is the same
LinkedHashMap, which is a Hash table and linked list implementation of the Map interface can be used.
It maintains the same order in which the values are inserted using doubly linked list.
Reference : http://docs.oracle.com/javase/1.4.2/docs/api/java/util/LinkedHashMap.html
[Edit]What the OP asks is not entirely clear to me. The OP could be asking, "How do I retrieve items from a map in insertion order?" If that is what the OP meant, then the following information is not a solution.
If the OP is asking, "How do I retrieve items from a Hash sorted by the key?" then the following is on-point. Getting the sorted keys of a hash/associative array is a common operation.
The answer can be found in how to sort Map values by key in Java:
List sortedKeys=new ArrayList(yourMap.keySet());
Collections.sort(sortedKeys);
If you care about the order in which the keys are stored and retrieved, consider using a TreeMap instead. Unless you have a very large number of elements (millions+), the performance difference is not likely to be noticeable.

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.

Categories