I want to write a comparator that will let me sort a TreeMap by value instead of the default natural ordering.
I tried something like this, but can't find out what went wrong:
import java.util.*;
class treeMap {
public static void main(String[] args) {
System.out.println("the main");
byValue cmp = new byValue();
Map<String, Integer> map = new TreeMap<String, Integer>(cmp);
map.put("de",10);
map.put("ab", 20);
map.put("a",5);
for (Map.Entry<String,Integer> pair: map.entrySet()) {
System.out.println(pair.getKey()+":"+pair.getValue());
}
}
}
class byValue implements Comparator<Map.Entry<String,Integer>> {
public int compare(Map.Entry<String,Integer> e1, Map.Entry<String,Integer> e2) {
if (e1.getValue() < e2.getValue()){
return 1;
} else if (e1.getValue() == e2.getValue()) {
return 0;
} else {
return -1;
}
}
}
I guess what am I asking is: Can I get a Map.Entry passed to the comparator?
You can't have the TreeMap itself sort on the values, since that defies the SortedMap specification:
A Map that further provides a total ordering on its keys.
However, using an external collection, you can always sort Map.entrySet() however you wish, either by keys, values, or even a combination(!!) of the two.
Here's a generic method that returns a SortedSet of Map.Entry, given a Map whose values are Comparable:
static <K,V extends Comparable<? super V>>
SortedSet<Map.Entry<K,V>> entriesSortedByValues(Map<K,V> map) {
SortedSet<Map.Entry<K,V>> sortedEntries = new TreeSet<Map.Entry<K,V>>(
new Comparator<Map.Entry<K,V>>() {
#Override public int compare(Map.Entry<K,V> e1, Map.Entry<K,V> e2) {
int res = e1.getValue().compareTo(e2.getValue());
return res != 0 ? res : 1;
}
}
);
sortedEntries.addAll(map.entrySet());
return sortedEntries;
}
Now you can do the following:
Map<String,Integer> map = new TreeMap<String,Integer>();
map.put("A", 3);
map.put("B", 2);
map.put("C", 1);
System.out.println(map);
// prints "{A=3, B=2, C=1}"
System.out.println(entriesSortedByValues(map));
// prints "[C=1, B=2, A=3]"
Note that funky stuff will happen if you try to modify either the SortedSet itself, or the Map.Entry within, because this is no longer a "view" of the original map like entrySet() is.
Generally speaking, the need to sort a map's entries by its values is atypical.
Note on == for Integer
Your original comparator compares Integer using ==. This is almost always wrong, since == with Integer operands is a reference equality, not value equality.
System.out.println(new Integer(0) == new Integer(0)); // prints "false"!!!
Related questions
When comparing two Integers in Java does auto-unboxing occur? (NO!!!)
Is it guaranteed that new Integer(i) == i in Java? (YES!!!)
polygenelubricants answer is almost perfect. It has one important bug though. It will not handle map entries where the values are the same.
This code:...
Map<String, Integer> nonSortedMap = new HashMap<String, Integer>();
nonSortedMap.put("ape", 1);
nonSortedMap.put("pig", 3);
nonSortedMap.put("cow", 1);
nonSortedMap.put("frog", 2);
for (Entry<String, Integer> entry : entriesSortedByValues(nonSortedMap)) {
System.out.println(entry.getKey()+":"+entry.getValue());
}
Would output:
ape:1
frog:2
pig:3
Note how our cow dissapeared as it shared the value "1" with our ape :O!
This modification of the code solves that issue:
static <K,V extends Comparable<? super V>> SortedSet<Map.Entry<K,V>> entriesSortedByValues(Map<K,V> map) {
SortedSet<Map.Entry<K,V>> sortedEntries = new TreeSet<Map.Entry<K,V>>(
new Comparator<Map.Entry<K,V>>() {
#Override public int compare(Map.Entry<K,V> e1, Map.Entry<K,V> e2) {
int res = e1.getValue().compareTo(e2.getValue());
return res != 0 ? res : 1; // Special fix to preserve items with equal values
}
}
);
sortedEntries.addAll(map.entrySet());
return sortedEntries;
}
In Java 8:
LinkedHashMap<Integer, String> sortedMap = map.entrySet().stream()
.sorted(Map.Entry.comparingByValue(/* Optional: Comparator.reverseOrder() */))
.collect(Collectors.toMap(Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1, LinkedHashMap::new));
A TreeMap is always sorted by the keys, anything else is impossible. A Comparator merely allows you to control how the keys are sorted.
If you want the sorted values, you have to extract them into a List and sort that.
This can't be done by using a Comparator, as it will always get the key of the map to compare. TreeMap can only sort by the key.
Olof's answer is good, but it needs one more thing before it's perfect. In the comments below his answer, dacwe (correctly) points out that his implementation violates the Compare/Equals contract for Sets. If you try to call contains or remove on an entry that's clearly in the set, the set won't recognize it because of the code that allows entries with equal values to be placed in the set. So, in order to fix this, we need to test for equality between the keys:
static <K,V extends Comparable<? super V>> SortedSet<Map.Entry<K,V>> entriesSortedByValues(Map<K,V> map) {
SortedSet<Map.Entry<K,V>> sortedEntries = new TreeSet<Map.Entry<K,V>>(
new Comparator<Map.Entry<K,V>>() {
#Override public int compare(Map.Entry<K,V> e1, Map.Entry<K,V> e2) {
int res = e1.getValue().compareTo(e2.getValue());
if (e1.getKey().equals(e2.getKey())) {
return res; // Code will now handle equality properly
} else {
return res != 0 ? res : 1; // While still adding all entries
}
}
}
);
sortedEntries.addAll(map.entrySet());
return sortedEntries;
}
"Note that the ordering maintained by a sorted set (whether or not an explicit comparator is provided) must be consistent with equals if the sorted set is to correctly implement the Set interface... the Set interface is defined in terms of the equals operation, but a sorted set performs all element comparisons using its compareTo (or compare) method, so two elements that are deemed equal by this method are, from the standpoint of the sorted set, equal."
(http://docs.oracle.com/javase/6/docs/api/java/util/SortedSet.html)
Since we originally overlooked equality in order to force the set to add equal valued entries, now we have to test for equality in the keys in order for the set to actually return the entry you're looking for. This is kinda messy and definitely not how sets were intended to be used - but it works.
I know this post specifically asks for sorting a TreeMap by values, but for those of us that don't really care about implementation but do want a solution that keeps the collection sorted as elements are added, I would appreciate feedback on this TreeSet-based solution. For one, elements are not easily retrieved by key, but for the use case I had at hand (finding the n keys with the lowest values), this was not a requirement.
TreeSet<Map.Entry<Integer, Double>> set = new TreeSet<>(new Comparator<Map.Entry<Integer, Double>>()
{
#Override
public int compare(Map.Entry<Integer, Double> o1, Map.Entry<Integer, Double> o2)
{
int valueComparison = o1.getValue().compareTo(o2.getValue());
return valueComparison == 0 ? o1.getKey().compareTo(o2.getKey()) : valueComparison;
}
});
int key = 5;
double value = 1.0;
set.add(new AbstractMap.SimpleEntry<>(key, value));
A lot of people hear adviced to use List and i prefer to use it as well
here are two methods you need to sort the entries of the Map according to their values.
static final Comparator<Entry<?, Double>> DOUBLE_VALUE_COMPARATOR =
new Comparator<Entry<?, Double>>() {
#Override
public int compare(Entry<?, Double> o1, Entry<?, Double> o2) {
return o1.getValue().compareTo(o2.getValue());
}
};
static final List<Entry<?, Double>> sortHashMapByDoubleValue(HashMap temp)
{
Set<Entry<?, Double>> entryOfMap = temp.entrySet();
List<Entry<?, Double>> entries = new ArrayList<Entry<?, Double>>(entryOfMap);
Collections.sort(entries, DOUBLE_VALUE_COMPARATOR);
return entries;
}
import java.util.*;
public class Main {
public static void main(String[] args) {
TreeMap<String, Integer> initTree = new TreeMap();
initTree.put("D", 0);
initTree.put("C", -3);
initTree.put("A", 43);
initTree.put("B", 32);
System.out.println("Sorted by keys:");
System.out.println(initTree);
List list = new ArrayList(initTree.entrySet());
Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
#Override
public int compare(Map.Entry<String, Integer> e1, Map.Entry<String, Integer> e2) {
return e1.getValue().compareTo(e2.getValue());
}
});
System.out.println("Sorted by values:");
System.out.println(list);
}
}
//convert HashMap into List
List<Entry<String, Integer>> list = new LinkedList<Entry<String, Integer>>(map.entrySet());
Collections.sort(list, (o1, o2) -> o1.getValue().compareTo(o2.getValue()));
If you want to use a Hash map you can add a condition in Comparator to check by values first & if values are equal perform a sort on keys
HashMap<String , Integer> polpularity = new HashMap<>();
List<String> collect = popularity.entrySet().stream().sorted((t2, t1) -> {
if (t2.getValue() > t1.getValue()) {
return -1;
} else if (t2.getValue() < t1.getValue()) {
return +1;
} else {
return t2.getKey().compareTo(t1.getKey());
}
}).map(entry -> entry.getKey()).collect(Collectors.toList());
If you don't want to take care of the latter condition then use a Treemap which will offer you sorting by itself, this can be done in an elegant single line of code:
TreeMap<String, Integer> popularity = new TreeMap<>();
List<String> collect = popularity.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).map(entry -> entry.getKey()).collect(Collectors.toList());
TreeMap is always sorted by the keys.
If you want TreeMap to be sorted by the values, so you can simply construct it also.
Example:
// the original TreeMap which is sorted by key
Map<String, Integer> map = new TreeMap<>();
map.put("de",10);
map.put("ab", 20);
map.put("a",5);
// expected output:
// {a=5, ab=20, de=10}
System.out.println(map);
// now we will constrcut a new TreeSet which is sorted by values
// [original TreeMap values will be the keys for this new TreeMap]
TreeMap<Integer, String> newTreeMapSortedByValue = new TreeMap();
treeMapmap.forEach((k,v) -> newTreeMapSortedByValue.put(v, k));
// expected output:
// {5=a, 10=de, 20=ab}
System.out.println(newTreeMapSortedByValue);
Only 1 Line Of Code Solution
Normal Order
map.entrySet().stream().sorted(Map.Entry.comparingByValue()).forEach(x->{});
Reverse Order
map.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).forEachOrdered(x -> {});
Related
I am using a treemap but created my own comparator so that the treemap is ordered by the values rather than the keys. This works fine but whenever I come to overwrite a <key, value> mapping, instead of being overwritten, a new mapping is added with the same key (which shouldn't happen because maps in Java are meant to have unique keys). I have even tried to remove the mapping first before adding another one but nothing gets deleted from the treemap. When I remove the comparator, there are no unique values and the treemap works as expected. Why does this happen?
Here is my code:
public Map<String, List<String>> mapQtToNonSampledCase(List<Entry> cases, Map<String, Integer> populationDistribution) {
Map<String. Integer> distribution = new HashMap<>(populationDistribution);
Map<String. List<String>> qtToCases = new HashMap<>();
Comparator<String> valueComparator = new Comparator<String>() {
public int compare(String k1, String k2) {
int compare = distribution.get(k1).compareTo(distribution.get(k2));
if (compare == 0)
return 1;
else
return compare;
}
};
TreeMap<String, Integer> sortedByValues = new TreeMap<>(valueComparator);
sortedByValues.putAll(distribution);
for(Entry entry: cases) {
List<Map.Entry<String, Integer>> listEntries = sortedByValues.entrySet().stream().collect(Collectors.tolist());
Map.Entry<String, Integer> qt = sortedByValues.firstEntry().getKey().equals(entry.get(UtilsClass.ID).toString()) ? (listEntries.get(1) != null ? listEntries.get(1) : null) : sortedByValues.firstEntry();
if(qt != null) {
if(!qtToCases.containsKey(qt.getKey()) {
qtToCases.put(qt.getKey(), new ArrayList<>());
);
}
qtToCases.get(qt.getKey()).add(entry.get(UtilsClass.ID).toString());
sortedByValues.put(qt.getKey(), qt.getValue() - 1);
}
}
// Printing keys
for(Map.Entry<String, Integer> entry : sortedByValues.entrySet()) {
System.out.println(entry.getKey());
}
}
And here is the console output (apologies for the quality, it's a picture from another device):
Your custom comparator is not consistent with equals: When you try to update a key with a different value, your comparator will return a value != 0, but the keys are the same.
See this comment in TreeMap API doc:
Note that the ordering maintained by a tree map, like any sorted map,
and whether or not an explicit comparator is provided, must be
consistent with equals if this sorted map is to correctly implement
the Map interface.
The term 'consistent with equals' is defined here: [Comparable API doc]:2
The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every e1 and e2 of class C.
So I am having a bit of trouble understanding how to do this. I am building a word counter in Java using Map<String, Integer> where a word is the String and the amount of times that word was said in a .txt document is Integer. This is all working great...but I am trying to develop a part where it will display at the bottom what the top 5 results are ---> what the top 5 map.values() are.
The problem I have run into is after I find the value, I can't get the String with it.
Any suggestions would be very helpful to me.
You need to use the Map.Entry<String, Integer> to get the pair of the key and value.
The values() method returns only values, whereas the keySet() method returns only the keys.
Firstly, you should sort your map, based on values, to get the top five results.
The straightforward approach uses a Comparator. See the answer here for more.
Then you simply get the first five entries of the map.getEntrySet(). It would be easier to use an Iterator for this.
UPDATE:
Set<Entry<String, Integer>> set = wordCount.entrySet();
List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(set);
Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
return o2.getValue().compareTo(o1.getValue());
}
});
int topResults = 5;
Iterator<Entry<String, Integer>> iter = list.iterator(); //refer the sorted collection
while (iter.hasNext() && topResults > 0 ) {
Map.Entry<String, Integer> entry = iter.next();
System.out.println(entry.getKey() + "->" + entry.getValue());
topResults --;
}
a) Iterate over the map, this way you have both keys and values accessible:
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Integer value = entry.getValue();
// ...
}
b) build a second map for reverse lookup, e.g. Map - note that this is likely not a good idea here as you may have duplicate keys (same number for different words)
c) consider using a bidimap - this is a map which you can query both by key and by value.
I suggest you to override Comparator and build your Map constructor based on it.
Code is showed below:
class ValueComparator implements Comparator {
Map map;
public ValueComparator(Map map) {
this.map = map;
}
public int compare(Object keyA, Object keyB) {
Comparable valueA = (Comparable) map.get(keyA);
Comparable valueB = (Comparable) map.get(keyB);
return valueB.compareTo(valueA);
}
}
public class YourClass{
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 10);
map.put("b", 30);
map.put("c", 50);
map.put("d", 40);
map.put("e", 20);
System.out.println(map);
Map sortedMap = sortByValue(map);
System.out.println(sortedMap);
}
public static Map sortByValue(Map unsortedMap) {
Map sortedMap = new TreeMap(new ValueComparator(unsortedMap));
sortedMap.putAll(unsortedMap);
return sortedMap;
}
}
What I want to do is sort a map by value. I went over many questions that are available on the stackoverflow site and found out following solution that does what I want but missing a small thing.
Link1: Sorting Map
But the issue I am running into is that by default this is sorted by ascending order by value. I want to order it by descending order:
So what I did was I created a class that implements a comparator
class MyComparator implements Comparator {
Map map;
public MyComparator(Map map) {
this.map = map;
}
public int compare(Object o1, Object o2) {
return ((Integer) map.get(o2)).compareTo((Integer) map.get(o1));
}
}
And then I pass my map to the treemap,
MyComparator comp = new MyComparator(myMap);
Map<String, Integer> newMap = new TreeMap(comp);
newMap.putAll(myMap);
This seems like bad approach because I feel this is inefficient. Is there a way to change the solution in the link to do ordering on descending order by default.
You should use new TreeMap<>(Collections.reverseOrder());.
Map<String, Integer> newMap = new TreeMap<>(Collections.reverseOrder());
newMap.putAll(myMap);
or to reverse an existing comparator like the value-comparator Collections.reverseOrder(comparator). It works like your approach swapping the two objects before invoking compare/compareTo.
TreeMap<Long,String> treeMap = new TreeMap<Long,String>();
NavigableMap <Long, String> nmap = treeMap.descendingMap();
Set<Long, String> set = nmap.entrySet();
Iterator<Long, String> iterator = set.iterator();
now u can iterate over iterator and extract the value using iterator.hasNext() and iterator.next() methods ......
This will work :
TreeMap<Integer, Integer> reverseInteger=new TreeMap<>(new Comparator<Integer>() {
#Override
public int compare(Integer o1, Integer o2) {
return o2>o1?1:o2==o1?0:-1;
}
});
You could simply invert the return value of your compare method by adding a minus sign at the beginning:
return -((Integer) map.get(o2)).compareTo((Integer) map.get(o1));
To change the solution in the link to sort by descending order, just reverse the condition:
...
// Note: this comparator imposes orderings that are inconsistent with equals.
public int compare(String a, String b) {
if (base.get(a) >= base.get(b)) {
return 1; // For ascending, return -1;
} else {
return -1; // For ascending, return 1;
} // returning 0 would merge keys
}
...
If I have a Hashtable and I want to sort it by the value, i.e: integer in a descending order. How can I do this and be able to print through all of the key - value pair?
Transfer as List and sort it:
public static void sortValue(Hashtable<?, Integer> t){
//Transfer as List and sort it
ArrayList<Map.Entry<?, Integer>> l = new ArrayList(t.entrySet());
Collections.sort(l, new Comparator<Map.Entry<?, Integer>>(){
public int compare(Map.Entry<?, Integer> o1, Map.Entry<?, Integer> o2) {
return o1.getValue().compareTo(o2.getValue());
}});
System.out.println(l);
}
SortedMap allows you to either specify a comparator, or if not use the natural ordering of elements, of which the inverse will be fine for Integers. The following prints in descending sorted order:
SortedMap<Integer, Object> map = new TreeMap<Integer, Object>(new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
});
map.put(2, "value2");
map.put(3, "value3");
map.put(1, "value1");
for (Map.Entry<Integer, Object> nextEntry : map.entrySet()) {
System.out.println(nextEntry.getKey() + " : " + nextEntry.getValue());
}
Hashtables are not sorted. So you need to make a copy of the hash table's key set, sort it, and retrieve the values from the hashtable by iterating through the keys in your sorted list.
Or use a sorted hash table substitute, such as TreeMap; that would avoid having to make the copy of the key set.
If you really mean "how do I do this", then the answer is to just add all of them to a TreeMap and then iterate through it, or add all of them to an ArrayList and then sort it.
If you mean "how do I do this efficiently", I believe the answer is that it's not possible to get any more efficient than above.
This question may have some more info.
Refer to below link
Sorting HashMap by values
or
How to sort a treemap based on its values?
Both are implementation for sorting an hashmap based on value in ascending or descending order
An inefficient way of doing it if you don't understand the above code.
public static void sortHashtable1 (Hashtable <Integer,Double> t,int count)
{
double a[]=new double[count];
int i=0;
for (int ss : t.keySet())
{
a[i]=t.get(ss);
i++;
}
Arrays.sort(a);
outer:for(int j=a.length-1;j>=0;j--)
{
for(int ss : t.keySet())
if(t.get(ss)==a[j])
{
System.out.println(ss+" "+a[j]);
a[j]=-1;
t.put(ss, -1.0);
continue outer;
}
}
}
How to move a particular HashMap entry to Last position?
For Example, I have HashMap values like this:
HashMap<String,Integer> map = new HashMap<String,Integer>();
map= {Not-Specified 1, test 2, testtest 3};
"Not-Specified" may come in any position. it may come first or in the middle of the map. But i want to move the "Not-Specified" to the last position.
How can I do that?
To answer your question in one sentence:
Per default, Maps don't have a last entry, it's not part of their contract.
And a side note: it's good practice to code against interfaces, not the implementation classes (see Effective Java by Joshua Bloch, Chapter 8, Item 52: Refer to objects by their interfaces).
So your declaration should read:
Map<String,Integer> map = new HashMap<String,Integer>();
(All maps share a common contract, so the client need not know what kind of map it is, unless he specifies a sub interface with an extended contract).
Possible Solutions
Sorted Maps:
There is a sub interface SortedMap that extends the map interface with order-based lookup methods and it has a sub interface NavigableMap that extends it even further. The standard implementation of this interface, TreeMap, allows you to sort entries either by natural ordering (if they implement the Comparable interface) or by a supplied Comparator.
You can access the last entry through the lastEntry method:
NavigableMap<String,Integer> map = new TreeMap<String, Integer>();
// add some entries
Entry<String, Integer> lastEntry = map.lastEntry();
Linked maps:
There is also the special case of LinkedHashMap, a HashMap implementation that stores the order in which keys are inserted. There is however no interface to back up this functionality, nor is there a direct way to access the last key. You can only do it through tricks such as using a List in between:
Map<String,String> map = new LinkedHashMap<String, Integer>();
// add some entries
List<Entry<String,Integer>> entryList =
new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
Entry<String, Integer> lastEntry =
entryList.get(entryList.size()-1);
Proper Solution:
Since you don't control the insertion order, you should go with the NavigableMap interface, i.e. you would write a comparator that positions the Not-Specified entry last.
Here is an example:
final NavigableMap<String,Integer> map =
new TreeMap<String, Integer>(new Comparator<String>() {
public int compare(final String o1, final String o2) {
int result;
if("Not-Specified".equals(o1)) {
result=1;
} else if("Not-Specified".equals(o2)) {
result=-1;
} else {
result =o1.compareTo(o2);
}
return result;
}
});
map.put("test", Integer.valueOf(2));
map.put("Not-Specified", Integer.valueOf(1));
map.put("testtest", Integer.valueOf(3));
final Entry<String, Integer> lastEntry = map.lastEntry();
System.out.println("Last key: "+lastEntry.getKey()
+ ", last value: "+lastEntry.getValue());
Output:
Last key: Not-Specified, last value: 1
Solution using HashMap:
If you must rely on HashMaps, there is still a solution, using a) a modified version of the above comparator, b) a List initialized with the Map's entrySet and c) the Collections.sort() helper method:
final Map<String, Integer> map = new HashMap<String, Integer>();
map.put("test", Integer.valueOf(2));
map.put("Not-Specified", Integer.valueOf(1));
map.put("testtest", Integer.valueOf(3));
final List<Entry<String, Integer>> entries =
new ArrayList<Entry<String, Integer>>(map.entrySet());
Collections.sort(entries, new Comparator<Entry<String, Integer>>(){
public int compareKeys(final String o1, final String o2){
int result;
if("Not-Specified".equals(o1)){
result = 1;
} else if("Not-Specified".equals(o2)){
result = -1;
} else{
result = o1.compareTo(o2);
}
return result;
}
#Override
public int compare(final Entry<String, Integer> o1,
final Entry<String, Integer> o2){
return this.compareKeys(o1.getKey(), o2.getKey());
}
});
final Entry<String, Integer> lastEntry =
entries.get(entries.size() - 1);
System.out.println("Last key: " + lastEntry.getKey() + ", last value: "
+ lastEntry.getValue());
}
Output:
Last key: Not-Specified, last value: 1
HashMap doesn't have "the last position", as it is not sorted.
You may use other Map which implements java.util.SortedMap, most popular one is TreeMap.
A SortedMap is the logical/best choice, however another option is to use a LinkedHashMap which maintains two order modes, most-recently-added goes last, and most-recently-accessed goes last. See the Javadocs for more details.
When using numbers as the key, I suppose you could also try this:
Map<Long, String> map = new HashMap<>();
map.put(4L, "The First");
map.put(6L, "The Second");
map.put(11L, "The Last");
long lastKey = 0;
//you entered Map<Long, String> entry
for (Map.Entry<Long, String> entry : map.entrySet()) {
lastKey = entry.getKey();
}
System.out.println(lastKey); // 11
move does not make sense for a hashmap since its a dictionary with a hashcode for bucketing based on key and then a linked list for colliding hashcodes resolved via equals.
Use a TreeMap for sorted maps and then pass in a custom comparator.
In such scenario last used key is usually known so it can be used for accessing last value (inserted with the one):
class PostIndexData {
String _office_name;
Boolean _isGov;
public PostIndexData(String name, Boolean gov) {
_office_name = name;
_isGov = gov;
}
}
//-----------------------
class KgpData {
String _postIndex;
PostIndexData _postIndexData;
public KgpData(String postIndex, PostIndexData postIndexData) {
_postIndex = postIndex;
_postIndexData = postIndexData;;
}
}
public class Office2ASMPro {
private HashMap<String,PostIndexData> _postIndexMap = new HashMap<>();
private HashMap<String,KgpData> _kgpMap = new HashMap<>();
...
private void addOffice(String kgp, String postIndex, String officeName, Boolean gov) {
if (_postIndexMap.get(postIndex) == null) {
_postIndexMap.put(postIndex, new PostIndexData(officeName, gov));
}
_kgpMap.put( kgp, new KgpData(postIndex, _postIndexMap.get(postIndex)) );
}
Find missing all elements from array
int[] array = {3,5,7,8,2,1,32,5,7,9,30,5};
TreeMap<Integer, Integer> map = new TreeMap<>();
for(int i=0;i<array.length;i++) {
map.put(array[i], 1);
}
int maxSize = map.lastKey();
for(int j=0;j<maxSize;j++) {
if(null == map.get(j))
System.out.println("Missing `enter code here`No:"+j);
}