Get first k values from HashMap - java

I am trying to get first k values from a hashmap.
I know how to get all values from a hashmap and also how to iterate over all of them. Is there any short way to generate first k values from hashmap
for (Map.Entry<String, Integer> en : hmap.entrySet())
{
System.out.println("Key = " + en.getKey() + ", Value = " + en.getValue());
}

The notion of the first elements is undefined for Map interface. How it was mentioned in comments you can use LinkedHashMap or TreeMap where the first item make sense.
If you just want to get some limit number of map values, you could use stream api with limit:
hmap.entrySet().stream()
.limit(2)
.collect(Collectors.toList());

Related

Sorting a hashmap in reverse order using Double

I know there are a number of posts that describe how to sort a hashmap in reverse. I've tried them and I've struggled to make it work. I'm relatively new to Java.
Below, I can print the hashmap in order from lowest double to highest double, but how do I sort it so the highest double comes first?
I've followed this post unsuccessfully.
I want to sort the following in reverse order the hashMap called "lines":
public void sortResults(HashMap<Double, TextObject> lines) {
Map<Double,TextObject> sortedMap = new TreeMap<Double,TextObject>(lines);
System.out.println("**************************************");
for (Map.Entry<Double, TextObject> entry : sortedMap.entrySet()) {
System.out.println("Key : " + entry.getKey()
+ " Value : " + entry.getValue());
}
System.out.println();
}
You can create TreeMap with reverse comparator and then use putAll to add lines
Map<Double,TextObject> sortedMap = new TreeMap<Double,TextObject>(Comparator.reverseOrder());
sortedMap.putAll(lines);

How to create a collection and iterator which go through certain values until its reaches one?

I have a TreeMap<Token, ArrayList<Token>> and I want to iterate through the map until a specific key which fulfills a requirement. I know that the following works for getting the values of a map:
Collection c = bigrams.values();
Iterator itr = c.iterator();
while (itr.hasNext()){
System.out.println(itr.next());
However, I want to be able to iterate through the map with the keys linked to the iterator, and check each value based on its pair key. Since bigrams.values() retrieves the value of each of the elements of the bigram, how may I change this to retrieve the keys instead of the values?
Your question is a bit cryptic, but if you want to get the keys, you can simply use the keySet() method:
Collection c = test.keySet();
If you want to iterate through the map based on the keys, you can do:
for (Token key: bigrams.keySet()) {
ArrayList<Token> list = bigrams.get(key);
// do with the list what you want to do with it
}
You should eilter use Map.keySet() or Map.entrySet():
Map.keySet() returns a set containing all keys of your map. You then can use Map.get() to get the value for a given key:
for (Token key: bigrams.keySet()) {
List<Token> list = bigrams.get(key);
System.out.println(key + ": " + list);
}
Map.entrySet() returns a set of all pairs in your map, so there is no need to use Map.get() with this:
for (Map.Entry<Token, List<Token>> entry : bigrams.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
Finally you also can use the Java Stream API for this. You also can use it to filter the content very easily. For example to find all tokens containing a given token in their value list:
bigrams.entrySet().stream()
.filter(e -> e.getValue().contains(tokenToFind))
.forEach(e -> System.out.println(e.getKey() + ": " + e.getValue()));

Merge duplicates in list

I have a list of some strings. I need to merge dublicates and add counter of duplicates. For example:
list1.add("Mom");
list1.add("Mom");
list1.add("Son");
list1.add("Son");
list1.add("Dad");
list1.add("Dad");
merge and add counter
and output needs to be like this:
Mom 2
Son 2
Dad 2
Also I need to sort this new list, but I think I can just use collections, to do that.
public static Map<String, Long> getValuesWithNumberOfOccurrences(
List<String> list) {
return list.stream()
.collect(
Collectors.groupingBy(i -> i, HashMap::new,
Collectors.counting()));
}
Use HashMap to keep duplicates:
HashMap<String, Integer> map = new HashMap<>();
for (int i = 0; i < list.size(); i++) {
String text = list.get(i);
if(map.get(text) == null) {
map.put(text, 1);
} else {
map.put(text, map.get(text) + 1);
}
}
for (String text : map.keySet()) {
System.out.println(text + " " + map.get(text));
}
I'm assuming that the output order needs to respect the order in which the keys were first encountered. Fortunately the clever Java bods designed an object for that: java.util.LinkedHashMap.
To set up your storage object use
java.util.Map<String, Integer> map = new java.util.LinkedHashMap<>()
Note the fancy diamond notation.
Then, with name as a string, write something like
if (map.containsKey(name)){
map.put(key, map.get(key) + 1);
} else {
map.put(key, 1);
}
This could be optimised a little: you could rely on the fact that map.get(key) will be null if key is not present. This obviates the need for the containsKey call.
Finally, to output your values use something on the lines of
for (java.util.Map.Entry<String, Integer> entry : map.entrySet()){
/*ToDo - use entry.getKey() and entry.getValue()*/
}
If you want your output to be sorted on the keys then use a java.util.TreeMap instead. If the order of output is of no consequence to you then use a java.util.HashMap.
I need to merge duplicates and add counter of duplicates.
When duplicate stuff comes to mind, think of Set to isolate. As and when you try to add an element to set and the add method returns false, print the data with 2 count.
But when the entries can occur more than twice, then you need to keep a track of each entry's count until the very end. So use a map instead with each String as key and its count as value. That basically means, while adding a string to map:
Get it from the map
- if not null, then get its value, increment 1 and set its value again.
- if null, then add it to map with value=1
At the end, you can iterate and find count.

Sorting a hash map first according to value, then key secondarily

I need to sort a hash map, first according to value then according to key.
TreeMap<String,Integer> dictionary = new TreeMap<String,Integer>();
For example, the desired output is something like:
it - 2
of - 2
the - 2
times - 2
was - 2
best - 1
worst - 1
I tried tree map, but that only sorts it according to key.
So basically, I need to sort my first according to the Integer (Highest to Lowest) and then according to the String (First A then B till Z).
I searched online and saw that I'm gonna have to use comparator but I'm not sure how to make it work?
Any guidance will be appreciated.
This is for a Java assignment.
The Map interface has no concept of "order", but you could sort the entries:
Map<String, Integer> map; // populated
List<Map.Entry<String, Integer>> entries = new ArrayList<> (map.entrySet());
Collections.sort(entries, new Comparator<Map.Entry<String, Integer>>() {
public int compareTo(Map.Entry<String, Integer> a, Map.Entry<String, Integer> b) {
return a.getValue().equals(b.getValue()) ? a.getKey().compareTo(b.getKey()) : Integer.compareTo(b.getValue(), a.getValue());
}
});
for (Map.Entry<String, Integer> entry : entries)
System.out.println(entry.getKey() + " - " + entry.getValue());
If java 8 is available, it becomes a lot neater:
Map<String, Integer> map; // populated
map.entrySet().stream()
.sorted( (a, b) -> a.getValue().equals(b.getValue()) ? a.getKey().compareTo(b.getKey()) : Integer.compareTo(b.getValue(), a.getValue()))
.map(e -> entry.getKey() + " - " + entry.getValue())
.forEach(System.out::println);
If absolutely need a map, load them into aLinkedHashMap, which "preserves order" in that it iterates over its entries in the same order they were inserted.
(I'm assuming this is something like Java). Sorted maps only deal with keys, not values. You probably want to just load the map content into a new TreeMap where each key is the original key and value combined somehow. Or, you can load into an List and sort that, or use a Set.

Count occurrences in MultiMap

I have a MultiMap that has multiple similar values:
{Entertainment=[5], Food=[2, 2, 2], Products=[11], Health & Beauty=[3]}
How do I count the total of these keys so that it counts as follows?
Entertainment = 1
Food = 3
Products = 1
Health & Beauty = 1
The number inside the array is the category id, so that Food has 3 occurrences.
Either multimap.get(key).size() or multimap.keys().count(key) should work.
Documentation
Assuming your map is declared as follows : MultiMap<String, Integer> map, you can do the following :
for (String key : map.keySet()) {
int count = map.get(key).size();
}
Using asMap(), you can get the Map<String, Collection<Integer>> representation of the Multimap, from which it's easy to get the count directly without multiple lookups:
for (Map.Entry<String, Collection<Integer>> entry : multimap.asMap().entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue().size());
}
Note: to get the Set of keys on the Multimap, you need to call keySet(), not keys() (which indeeds repeats the key as many times as it has values).

Categories

Resources