CodeMonkey
CodeMonkey

Reputation: 2285

Sorting two List (String, Integer) in java based on Integer value

I am working on a program where i am reading a file and extracting keywords and their count. Later i need to pick up word with topmost frequency and match them with a keyword.

I have stored all the keywords i have found in the file in String list. I wish to sort these on basis of frequency. So if at index 17 i have a word "stack" with value at index 17 in other integer list to be maximum, i wish to take them to position 1.

I can sort these using collections.sort but it does not take care of other list.

Here is my code :

while(m.find()) 
    {
        if(keyword.contains(m.group()))
            {
            keywordcount.set(keyword.indexOf(m.group()),keywordcount.get(keyword.indexOf(m.group()))+1);
            //System.out.println("*"+m.group()+":"+keywordcount.get(keyword.indexOf(m.group())));
            }
        else
            {
            keyword.add(m.group());
            int var=keyword.indexOf(m.group());
            //System.out.println(m.group()+":"+var);
            keywordcount.add(var, 1);
            }
        //System.out.println(keyword.size()+"#"+keywordcount.size());                       
    }
    for(int i=0;i<keyword.size();i++)
    {
        System.out.print(keyword.get(i)+ ":" +keywordcount.get(i)+" ");
    }

Upvotes: 0

Views: 2879

Answers (3)

Qkyrie
Qkyrie

Reputation: 939

This might be the ideal moment to check into multisets.

A collection that supports order-independent equality, like Set, but may have duplicate elements. A multiset is also sometimes called a bag.

Elements of a multiset that are equal to one another are referred to as occurrences of the same single element. The total number of occurrences of an element in a multiset is called the count of that element (the terms "frequency" and "multiplicity" are equivalent, but not used in this API). Since the count of an element is represented as an int, a multiset may never contain more than Integer.MAX_VALUE occurrences of any one element.

Upvotes: 1

Aurelien Ribon
Aurelien Ribon

Reputation: 7634

final List<String> words = new ArrayList<>();
final Map<String, Integer> frequencies = new HashMap<>();

while (m.find())  {
    String word = ...extract the word from m...;

    if (!words.contains(word)) words.add(word);

    if (!frequencies.contains(word)) frequencies.put(word, 1);
    else frequencies.put(word, frequencies.get(word) + 1);
}

Collections.sort(words, new Comparator<String>() {
    @Override public int compare(String s1, String s2) {
        int f1 = frequencies.get(s1);
        int f2 = frequencies.get(s2);
        if (f1 < f2) return 1;
        if (f1 > f2) return -1;
        return 0;
    }
});

Upvotes: 1

daveb
daveb

Reputation: 76171

Typically, one would put both the String and the Integer into a single class, and sort a list of instances of that class.

E.g.

class StringCount implements Comparable<StringCount> {
    private final String string;
    private final int count;

    public StringCount(String string, int count) {
        this.string = string;
        this.count = count;
    }

    @Override
    public int compareTo(StringCount right) {
        return this.count < right.count ? -1
             : this.count > right.count ? 1
             : 0;
    }

    // implement equals and hashCode too
    // if a.compareTo(b) == 0, then a.equals(b) should return true.

}

Then, you can create a List<StringCount> and call Collections.sort(stringCountList).

Note, that this will put the StringCount instances with the lowest values first, so they come out in ascending order.

Upvotes: 5

Related Questions