Find how many keys have the same value in a hashtable? - java

In a hashtable(Java), How can I find how many keys have the same value?
lets says I have:
Hashtable<String, int> table = new Hashtable<String, int>();
table.put("a", 1);
table.put("b", 2);
table.put("c", 2);
table.put("d", 2);
in this case the keys: b, c, & d would have the same value. how can I detect that?

First of all, you have to use reference types (objects) in Hashtable definition. You cannot use a primitive type like int, you have to use Integer.
As far as your problem, you could use a small function like this to count how many times a certain value is in the HashTable:
int countOccurences(Hashtable<String, Integer> table, int value) {
int count = 0;
for(String key : table.keySet()) {
if(table.get(key) == value) {
count++;
}
}
return count;
}
So if you want to know how many times the value 2 occurs in the table:
Hashtable<String, Integer> table = new Hashtable<String, Integer>();
table.put("a", 1);
table.put("b", 2);
table.put("c", 2);
table.put("d", 2);
System.out.println(countOccurences(table, 2));
This would print 3

You can't have a primitive type in a Collection (you need to use the wrapper type). I would recommend you use the diamond operator as well. I would get the keySet and iterate the keys, get each value and add it to a SortedSet (iff the Set didn't contain it already, if it did I would print it). So, I believe you are looking for something like this,
Hashtable<String, Integer> table = new Hashtable<>();
table.put("a", 1);
table.put("b", 2);
table.put("c", 2);
table.put("d", 2);
Set<String> keySet = table.keySet();
SortedSet<Integer> toCount = new TreeSet<>();
for (String key : keySet) {
Integer val = table.get(key);
if (!toCount.contains(val)) {
System.out.printf("Key %s has value %d%n", key, val);
toCount.add(val);
} else {
System.out.printf("Key %s also has value %d%n", key, val);
}
}
Which outputs
Key b has value 2
Key a has value 1
Key d also has value 2
Key c also has value 2

Map<Integer, Integer> occurenceForValue = new HashMap<Integer, Integer>();
Hashtable<String, Integer> table = new Hashtable<String, Integer>();
Iterator it = table.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pairs = (Map.Entry)it.next();
if(!occurenceForValue.containsKey(pairs.getValue())
{
occurenceForValue.put(pairs.getValue(), 1);
}
else
{
occurenceForValue.put(pairs.getValue(), occurenceForValue.get(pairs.getValue()) + 1);
}
it.remove();
}
Then occurenceForValue will contains, for each value (as key), the number of occurences.
Edit : Note in my code that I corrected your HashTable definition which used int as generic type which is not allowed.

Related

Overwriting values in a HashMap that are in an ArrayList<String>

Let's say I have a HashMap with String keys and Integer values:
map = {cat=1, kid=3, girl=3, adult=2, human=5, dog=2, boy=2}
I want to switch the keys and values by putting this information into another HashMap. I know that a HashMap cannot have duplicate keys, so I tried to put the information into a HashMap with the Integer for the keys that would map to a String ArrayList so that I could potentially have one Integer mapping to multiple Strings:
swap = {1=[cat], 2=[adult, dog, boy], 3=[kid, girl], 5=[human]}
I tried the following code:
HashMap<Integer, ArrayList<String>> swap = new HashMap<Integer, ArrayList<String>>();
for (String x : map.keySet()) {
for (int i = 0; i <= 5; i++) {
ArrayList<String> list = new ArrayList<String>();
if (i == map.get(x)) {
list.add(x);
swap.put(i, list);
}
}
}
The only difference in my code is that I didn't hard code the number 5 into my index; I have a method that finds the highest integer value in the original HashMap and used that. I know it works correctly because I get the same output even if I hard code the 5 in there, I just didn't include it to save space.
My goal here is to be able to do this 'reversal' with any set of data, otherwise I could just hard code the value. The output I get from the above code is this:
swap = {1=[cat], 2=[boy], 3=[girl], 5=[human]}
As you can see, my problem is that the value ArrayList is only keeping the last String that was put into it, instead of collecting all of them. How can I make the ArrayList store each String, rather than just the last String?
With Java 8, you can do the following:
Map<String, Integer> map = new HashMap<>();
map.put("cat", 1);
map.put("kid", 3);
map.put("girl", 3);
map.put("adult", 2);
map.put("human", 5);
map.put("dog", 2);
map.put("boy", 2);
Map<Integer, List<String>> newMap = map.keySet()
.stream()
.collect(Collectors.groupingBy(map::get));
System.out.println(newMap);
The output will be:
{1=[cat], 2=[adult, dog, boy], 3=[kid, girl], 5=[human]}
you are recreating the arrayList for every iteration and i can't figure out a way to do it with that logic, here is a good way though and without the need to check for the max integer:
for (Map.Entry<String, Integer> entry : map.entrySet()) {
String key = entry.getKey();
Integer value = entry.getValue();
List<String> get = swap.get(value);
if (get == null) {
get = new ArrayList<>();
swap.put(value, get);
}
get.add(key);
}
Best way is to iterate over the key set of the original map.
Also you have to asure that the List is present for any key in the target map:
for (Map.Entry<String,Integer> inputEntry : map.entrySet())
swap.computeIfAbsent(inputEntry.getValue(),()->new ArrayList<>()).add(inputEntry.getKey());
This is obviously not the best solution, but approaches the problem the same way you did by interchanging inner and outer loops as shown below.
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("cat", 1);
map.put("kid", 3);
map.put("girl", 3);
map.put("adult", 2);
map.put("human", 5);
map.put("dog", 2);
map.put("boy", 2);
HashMap<Integer, ArrayList<String>> swap = new HashMap<Integer, ArrayList<String>>();
for (Integer value = 0; value <= 5; value++) {
ArrayList<String> list = new ArrayList<String>();
for (String key : map.keySet()) {
if (map.get(key) == value) {
list.add(key);
}
}
if (map.containsValue(value)) {
swap.put(value, list);
}
}
Output
{1=[cat], 2=[adult, dog, boy], 3=[kid, girl], 5=[human]}
Best way I can think of is using Map.forEach method on existing map and Map.computeIfAbsent method on new map:
Map<Integer, List<String>> swap = new HashMap<>();
map.forEach((k, v) -> swap.computeIfAbsent(v, k -> new ArrayList<>()).add(k));
As a side note, you can use the diamond operator <> to create your new map (there's no need to repeat the type of the key and value when invoking the map's constructor, as the compiler will infer them).
As a second side note, it's good practice to use interface types instead of concrete types, both for generic parameter types and for actual types. This is why I've used List and Map instead of ArrayList and HashMap, respectively.
Using groupingBy like in Jacob's answer but with Map.entrySet for better performance, as suggested by Boris:
// import static java.util.stream.Collectors.*
Map<Integer, List<String>> swap = map.entrySet()
.stream()
.collect(groupingBy(Entry::getValue, mapping(Entry::getKey, toList())));
This uses two more methods of Collectors: mapping and toList.
If it wasn't for these two helper functions, the solution could look like this:
Map<Integer, List<String>> swap = map.entrySet()
.stream()
.collect(
groupingBy(
Entry::getValue,
Collector.of(
ArrayList::new,
(list, e) -> {
list.add(e.getKey());
},
(left, right) -> { // only needed for parallel streams
left.addAll(right);
return left;
}
)
)
);
Or, using toMap instead of groupingBy:
Map<Integer, List<String>> swap = map.entrySet()
.stream()
.collect(
toMap(
Entry::getValue,
(e) -> new ArrayList<>(Arrays.asList(e.getKey())),
(left, right) -> {
left.addAll(right);
return left;
}
)
);
It seams you override the values instrad of adding them to the already creared arraylist. Try this:
HashMap<Integer, ArrayList<String>> swapedMap = new HashMap<Integer, ArrayList<String>>();
for (String key : map.keySet()) {
Integer swappedKey = map.get(key);
ArrayList<String> a = swapedMap.get(swappedKey);
if (a == null) {
a = new ArrayList<String>();
swapedMap.put(swappedKey, a)
}
a.add(key);
}
I didn't have time to run it (sorry, don't have Java compiler now), but should be almost ok :)
You could use the new merge method in java-8 from Map:
Map<Integer, List<String>> newMap = new HashMap<>();
map.forEach((key, value) -> {
List<String> values = new ArrayList<>();
values.add(key);
newMap.merge(value, values, (left, right) -> {
left.addAll(right);
return left;
});
});

How to calculate the sum of values of different hashmaps with the same key?

So I have this hashmap named "hm" which produces the following output(NOTE:
this is just a selection) :
{1=35, 2=52, 3=61, 4=68, 5=68, 6=70, 7=70, 8=70, 9=70, 10=72, 11=72}
{1=35, 2=52, 3=61, 4=68, 5=70, 6=70, 7=70, 8=68, 9=72, 10=72, 11=72}
{1=35, 2=52, 3=61, 4=68, 5=68, 6=70, 7=70, 8=70, 9=72, 10=72, 11=72}
This output was created with the following code(NOTE : the rest of the class code is not shown here) :
private int scores;
HashMap<Integer,Integer> hm = new HashMap<>();
for (int i = 0; i < fileLines.length(); i++) {
char character = fileLines.charAt(i);
this.scores = character;
int position = i +1;
hm.put(position,this.scores);
}
System.out.println(hm);
What I am trying to do is put all these hashmaps together into one hashmap with as value the sum of the values per key. I am familiar with Python's defaultdict, but could not find an equivalent working example. I have searched for an answer and hit those answers below but they do not solve my problem.
How to calculate a value for each key of a HashMap?
what java collection that provides multiple values for the same key
is there a Java equivalent of Python's defaultdict?
The desired output would be :
{1=105, 2=156, 3=183 , 4=204 ,5=206 ..... and so on}
Eventually the average per position(key) has to be calculated but that is a problem I think I can fix on my own when I know how to do the above.
EDIT : The real output is much much bigger ! Think about 100+ of the hashmaps with more than 100 keys.
Try with something like that
public Map<Integer, Integer> combine(List<Map<Integer, Integer>> maps) {
Map<Integer, Integer> result = new HashMap<Integer, Integer>();
for (Map<Integer, Integer> map : maps) {
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
int newValue = entry.getValue();
Integer existingValue = result.get(entry.getKey());
if (existingValue != null) {
newValue = newValue + existingValue;
}
result.put(entry.getKey(), newValue);
}
}
return result;
}
Basically:
Create a new map for the result
Iterate over each map
Take each element and if already present in the result increment the value, if not put it in the map
return the result
newHashMap.put(key1,map1.get(key1)+map2.get(key1)+map3.get(key1));

Counting occurrences of a key in a Map in Java

I'm writing a project that captures Java keywords from a .java file and keeps track of the occurrences with a map. I've used a similar method in the past successfully, but I can't seem to adopt this method for my intended use here.
Map<String,Integer> map = new TreeMap<String,Integer>();
Set<String> keywordSet = new HashSet<String>(Arrays.asList(keywords));
Scanner input = new Scanner(file);
int counter = 0;
while (input.hasNext())
{
String key = input.next();
if (key.length() > 0)
{
if (keywordSet.contains(key))
{
map.put(key, 1);
counter++;
}
if(map.containsKey(key)) <--tried inner loop here, failed
{
int value = map.get(key);
value++;
map.put(key, value);
}
}
This block of code is supposed to add the keyword to the key, and increment the value each time the same key occurs. So far, it adds the keywords, but fails to properly increment the value. here is a sample output:
{assert=2, class=2, continue=2, default=2, else=2, ...}
Basically it increments every value in the map instead of the ones it's supposed to. I'm not sure if I'm over-thinking this or what. I've tried an inner loop and it gave me insane results. I really hope I'm just over-thinking this. Any help is greatly appreciated!
There's a much more concise (and easier to reason about) way to achieve what you want:
final ConcurrentMap<String, AtomicInteger> map = new ConcurrentHashMap<>();
final Scanner input = new Scanner(file);
while (input.hasNext()) {
final String key = input.next();
if (key.length() > 0) {
map.putIfAbsent(key, new AtomicInteger(0));
map.get(key).incrementAndGet();
}
}
Let's analyze why does this work.
Whenever the Scanner encounters a keyword, there are 2 possible cases: you either have encountered it before (ie, it is a known keyword), or it is an yet unseen keyword.
If it is an unseen keyword: putIfAbsent will put an AtomicInteger with value 0 in the map, and incrementAndGet() will set it to 1 right after, and, from now on, it becomes a known keyword;
If it is a known keyword: putIfAbsent will do nothing, and incrementAndGet() will increment the value that is already present in the map.
Then, if you want the key set, you do:
final Set<String> keys = map.keySet();
To print all the values, you could do something like:
for (final String k : map.keySet()) {
System.out.println(k + ": " + map.get(k).get());
}
You are not forced to use the two "different" classes I used above, ConcurrentMap and AtomicInteger. It is just easier to use them because they encapsulate much of the logic that you tried to write by yourself (and failed). The logic that they encapsulate is exactly all the other answers describe (ie, test if the value is present, if not set it to 0, then get whatever value is present, increment it and put it back into the map).
To maintain the keys of the map (our words being counted) in alphabetical order, use a ConcurrentNavigableMap such as ConcurrentSkipListMap .
For every key you scan you create a new entry in the map (overriding the existing one). Then, the next condition holds so you increment the count by 1, reaching the value 2.
The inner part should be something like:
if (keywordSet.contains(key))
{
Integer value = map.get(key);
if (value == null)
value = 0;
value++;
map.put(key, value);
}
Anyway, consider using some kind of a mutable integer to make this more efficient. You won't have to override entries in the map, and you won't be doing too much Integer boxing operations.
Even more concise using Map.merge (since Java 8):
if (keywordSet.contains(key)) {
map.merge(key, 1, (currentCount, notUsed) -> ++currentCount);
}
Here is a generic implementation of a counting map - a map with values representing the count of their keys:
public static <K> void count(K key, Map<K, Integer> map) {
map.merge(key, 1, (currentCount, notUsed) -> ++currentCount);
}
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
count("A", map);
count("B", map);
count("A", map);
count("Z", map);
count("A", map);
System.out.println(map); // {A=3, B=1, Z=1}
}
You always set the value to 1 and then update it by another one. What you need is to update the map value (and not setting it to 1 again).
Instead of:
map.put(key, 1);
use:
Integer value = map.get(key);
if (value == null){
value = 0
}
value++;
map.put(key, value);
And drop the second if.
Map<String, Integer> map = new HashMap<String, Integer>();
Set<String> keywordSet = new HashSet<String>(Arrays.asList(keywords));
Scanner input = new Scanner(file);
while (input.hasNext()){
String key = input.next();
if (key.length() > 0)
if (keywordSet.contains(key)){
Integer counter = map.get(key);
if (counter == null)
map.put(key, 1);
else
map.put(key, count + 1);
}
}
map.compute(key, (k, value) -> (value == null) ? 1 : (value + 1));

How to for each the hashmap? [duplicate]

This question already has answers here:
How do I efficiently iterate over each entry in a Java Map?
(46 answers)
Closed 7 years ago.
I have this field:
HashMap<String, HashMap> selects = new HashMap<String, HashMap>();
For each Hash<String, HashMap> I need to create a ComboBox, whose items are the value (which happens to be a HashMap itself) of HashMap <String, **HashMap**>.
By way of (non-functioning) demonstration:
for (int i=0; i < selects.size(); i++) {
HashMap h = selects[i].getValue();
ComboBox cb = new ComboBox();
for (int y=0; y < h.size(); i++) {
cb.items.add(h[y].getValue);
}
}
I know I'm a bit late for that one, but I'll share what I did too, in case it helps someone else :
HashMap<String, HashMap> selects = new HashMap<String, HashMap>();
for(Map.Entry<String, HashMap> entry : selects.entrySet()) {
String key = entry.getKey();
HashMap value = entry.getValue();
// do what you have to do here
// In your case, another loop.
}
Lambda Expression Java 8
In Java 1.8 (Java 8) this has become lot easier by using forEach method from Aggregate operations(Stream operations) that looks similar to iterators from Iterable Interface.
Just copy paste below statement to your code and rename the HashMap variable from hm to your HashMap variable to print out key-value pair.
HashMap<Integer,Integer> hm = new HashMap<Integer, Integer>();
/*
* Logic to put the Key,Value pair in your HashMap hm
*/
// Print the key value pair in one line.
hm.forEach((k,v) -> System.out.println("key: "+k+" value:"+v));
Here is an example where a Lambda Expression is used:
HashMap<Integer,Integer> hm = new HashMap<Integer, Integer>();
Random rand = new Random(47);
int i=0;
while(i<5){
i++;
int key = rand.nextInt(20);
int value = rand.nextInt(50);
System.out.println("Inserting key: "+key+" Value: "+value);
Integer imap =hm.put(key,value);
if( imap == null){
System.out.println("Inserted");
}
else{
System.out.println("Replaced with "+imap);
}
}
hm.forEach((k,v) -> System.out.println("key: "+k+" value:"+v));
Output:
Inserting key: 18 Value: 5
Inserted
Inserting key: 13 Value: 11
Inserted
Inserting key: 1 Value: 29
Inserted
Inserting key: 8 Value: 0
Inserted
Inserting key: 2 Value: 7
Inserted
key: 1 value:29
key: 18 value:5
key: 2 value:7
key: 8 value:0
key: 13 value:11
Also one can use Spliterator for the same.
Spliterator sit = hm.entrySet().spliterator();
UPDATE
Including documentation links to Oracle Docs.
For more on Lambda go to this link and must read Aggregate Operations and for Spliterator go to this link.
Map.values():
HashMap<String, HashMap<SomeInnerKeyType, String>> selects =
new HashMap<String, HashMap<SomeInnerKeyType, String>>();
...
for(HashMap<SomeInnerKeyType, String> h : selects.values())
{
ComboBox cb = new ComboBox();
for(String s : h.values())
{
cb.items.add(s);
}
}
Streams Java 8
Along with forEach method that accepts a lambda expression we have also got stream APIs, in Java 8.
Iterate over entries (Using forEach and Streams):
sample.forEach((k,v) -> System.out.println(k + "=" + v));
sample.entrySet().stream().forEachOrdered((entry) -> {
Object currentKey = entry.getKey();
Object currentValue = entry.getValue();
System.out.println(currentKey + "=" + currentValue);
});
sample.entrySet().parallelStream().forEach((entry) -> {
Object currentKey = entry.getKey();
Object currentValue = entry.getValue();
System.out.println(currentKey + "=" + currentValue);
});
The advantage with streams is they can be parallelized easily and can be useful when we have multiple CPUs at disposal. We simply need to use parallelStream() in place of stream() above. With parallel streams it makes more sense to use forEach as forEachOrdered would make no difference in performance. If we want to iterate over keys we can use sample.keySet() and for values sample.values().
Why forEachOrdered and not forEach with streams ?
Streams also provide forEach method but the behaviour of forEach is explicitly nondeterministic where as the forEachOrdered performs an action for each element of this stream, in the encounter order of the stream if the stream has a defined encounter order. So forEach does not guarantee that the order would be kept. Also check this for more.
You can iterate over a HashMap (and many other collections) using an iterator, e.g.:
HashMap<T,U> map = new HashMap<T,U>();
...
Iterator it = map.values().iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
I generally do the same as cx42net, but I don't explicitly create an Entry.
HashMap<String, HashMap> selects = new HashMap<String, HashMap>();
for (String key : selects.keySet())
{
HashMap<innerKey, String> boxHolder = selects.get(key);
ComboBox cb = new ComboBox();
for (InnerKey innerKey : boxHolder.keySet())
{
cb.items.add(boxHolder.get(innerKey));
}
}
This just seems the most intuitive to me, I think I'm prejudiced against iterating over the values of a map.
Use entrySet,
/**
*Output:
D: 99.22
A: 3434.34
C: 1378.0
B: 123.22
E: -19.08
B's new balance: 1123.22
*/
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MainClass {
public static void main(String args[]) {
HashMap<String, Double> hm = new HashMap<String, Double>();
hm.put("A", new Double(3434.34));
hm.put("B", new Double(123.22));
hm.put("C", new Double(1378.00));
hm.put("D", new Double(99.22));
hm.put("E", new Double(-19.08));
Set<Map.Entry<String, Double>> set = hm.entrySet();
for (Map.Entry<String, Double> me : set) {
System.out.print(me.getKey() + ": ");
System.out.println(me.getValue());
}
System.out.println();
double balance = hm.get("B");
hm.put("B", balance + 1000);
System.out.println("B's new balance: " + hm.get("B"));
}
}
see complete example here:
http://www.java2s.com/Code/JavaAPI/java.util/HashMapentrySet.htm

Accessing the last entry in a Map

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);
}

Categories