I have this HashMap containing words and the count for each word from a given text file;

{word=1, word2=1, word3=2, word4=1, word5=1, word6=4, word7=1, word8=1};

i was following your suggestion in other topics; but i have notice that if use fro example sorted Collections and i search for a specific KEY which could be 1 in this case it only return me one word while instead can return more values for same key;

the point is between all the collections:

Lists Maps ArrayLists Trees HashMaps HashTables

which is the most advisable to use?

on my Class the user will input an int and that int will correspond to the 1st or 2nd or 3rd or 4th and so on..... words used in the files base on the count and occurences;

it's challenging

so far i have managed to store in hashmap and eventually order it in a Tree by Desc Key; so first element will be the greater; but still the algorithm needs more sense;

ps. i do not expect solution or pieces of codes but a good input to start ... a very good advise or direction best to follow;

2

There are 2 answers

0
Nir Alfasi On

Maps, by nature, store (will return) only one element per key. That means that if you'll store [key:1, val:a] and then store again [key:1, val:2]. The second insertion will override the first and when you'll "get" key:1 the returned result will be b.

You can, however, to store a List per key. This list can store all the value values per the same key. So we'll declare the map that we'l use as follows:

Map<String, LinkedList<String>> map = new HashMap<>();

This is how insert should look like:

public void insert(String key, String value){
    List<String> values = map.get(key);
    if (values == null){ // this is the first time we use this key
        values = new LinkedList<String>(); // so we need to create a new values List
    }
    values.add(value);
    map.put(key, values)
}

the "get" is pretty straightforward:
you get the list of values and if it's not null - iterate the values and print/do whatever you want with them.

public List<String> get(String key){
    return map.get(key);
}
2
Boann On

If I understand you correctly, you have a Map<String,Integer> map; which maps words to their frequencies, and now you want to look up words by frequency.

Create a new map that Map<Integer,List<String>> and fill it using the first map:

Map<Integer,List<String>> reverseMap = new HashMap<>();
for (Map.Entry<String,Integer> entry : map.entrySet()) {
    List<String> list = reverseMap.get(entry.getValue());
    if (list == null) {
        reverseMap.put(entry.getValue(), list = new ArrayList<>());
    }
    list.add(entry.getKey());
}

You will get a map like:

java.util.HashMap[3] {
    1=[word2, word4, word, word5, word7, word8]
    2=[word3]
    4=[word6]
}

In this map, each key is the frequency, each value is a list of words having that frequency.

Edit: To pull out the words having the second-most used frequency ("rank 2"), generate a list of the most used frequencies:

List<Integer> frequencies = new ArrayList<>(reverseMap.keySet());
Collections.sort(frequencies, Collections.reverseOrder());

Then:

System.out.println(reverseMap.get(frequences.get(2 - 1)));

Or, to sort the entire map in descending order of frequency (4, 2, 1), declare it as a TreeMap instead of a HashMap, with a reverseOrder comparator:

Map<Integer,List<String>> reverseMap = new TreeMap<>(Collections.reverseOrder());