Already it has been answered but there's no good explanation of the code.So I will try that here.
Let the array to be sorted be : int[] array = {4,4,2,2,2,2,3,3,1,1,6,7,5}
First of all let us count the frequency of each number:
To do so we will create a HashMap data-structure which will have the array elements as Key and their frequency as value.And to store our output we will have a output list.
HashMap<Integer,Integer> freqMap = new HashMap<>();
ArrayList<Integer> output = new ArrayList<>();
getOrDefault(key,defaultValue) : This is a convenient way to handle the scenario where we want a returned value other than null which is being returned by get method whenever the key was not found.
Coming to the code:
for(int current : array)
{
int count = freqMap.getOrDefault(current,0); // if arrayelement is encountered first time it returns 0 otherwise it returns the actual count
freqMap.put(current,count++); // we increase the count by one and put it in the map
output.add(current); // we also add the element in the list.
}
Now we have out elements mapped with their frequency in HashMap.
- 2 comes four times
- 3 comes two times
- 4 comes two times
- 5,6 and 7 comes one time.
Now we need to sort the output list according to the frequency. For that we implement the comparator interface. In this interface we have a method
public int compare(Object obj1, Object obj2) //It compares the first object with the second object.
So we create a class SortComparator to implement this interface and create an object comp of class SortComparator.
SortComparator comp = new SortComparator(freqMap);
Collections.sort(output,comp);
for(Integer i : output)
{
System.out.print(i + " ");
}
This is the implementation of the Comparator interface:
class SortComparator implements Comparator<Integer>
{
private final Map<Integer,Integer> freqMap;
SortComparator(Map<Integer,Integer>freqMap)
{
this.freqMap = freqMap;
}
public int compare(Integer k1,Integer k2)
{
//Comparing by frequency
int freqCompare = freqMap.get(k2).compareTo(freqMap.get(k1));
//Comparing by value
int valueCompare = k2.compareTo(k1);
if(freqCompare == 0)//frequency of both k1 and k2 is same then
{
return valueCompare;
}
else
{
return freqCompare;
}
}