Java – Complex sorting of ArrayList using Collections.sort()?

Complex sorting of ArrayList using Collections.sort()?… here is a solution to the problem.

Complex sorting of ArrayList using Collections.sort()?

I

have an ArrayList<Word > in the driver class that I need to sort. My Word class has two properties:

public class Word {
    String word;
    int count;
}

In my Driver class, it reads and adds each word .txt file to the ArrayList.I need to sort the ArrayList by count first, then the words with the same count, and I need to sort them alphabetically. I can make a custom comparator class to sort by count:

public class SortByFreq implements Comparator<Word>{
    @Override
    public int compare(Word w1, Word w2) {
        return -(w1.count - w2.count);  Sort as descending order
    } 
}

And it works. But now I’m sticking to how to keep this sorted ArrayList as it is and sort it once: Because typically using Collections.sort() affects the entire ArrayList and overrides, not a portion of them. Any help would be appreciated!

Edit

I sort the ArrayList in my Driver class:

Collections.sort(wordList, new SortByFreq()); 

Solution

Just to improve the comparator logic in the code

public class SortByFreq implements Comparator<Word> {
    @Override
    public int compare(Word w1, Word w2) {
        return Integer.compare(w2.getCount(), w1.getCount());
    }
}

Your overall comparator should look like this:

Comparator<Word> comparator = Comparator.comparingInt(Word::getCount).reversed()
                                        .thenComparing(Word::getWord);

Use it to sort List<Word>wordlist as:

wordList.sort(comparator);

If you should only use a custom comparator, you can update the comparator to append the same counting logic as

static class SortByFreqAndAlphabetically implements Comparator<Word> {
    @Override
    public int compare(Word w1, Word w2) {
        if (w1.getCount() != w2.getCount()) {
            return Integer.compare(w2.getCount(), w1.getCount());
        } else {
            return w1.getWord().compareTo(w2.getWord());
        }
    }
}

Then use it further to sort :

wordList.sort(new SortByFreqAndAlphabetically());  similar to 'Collections.sort(wordList, new SortByFreqAndAlphabetically())' 

Related Problems and Solutions