Month: December 2017

Sort Array of String by their counts in Java 8

Posted on

Here, we will see how to sort an array base on elements occurrences in Java 8.

Suppose we got a city list containing duplicate city as well like below.


First, we have to do aggregation on city name by applying groupBy function, count their occurrence and return a Map.

 String cities = "Delhi,Agra,Bihar,UP,Delhi,Agra,Bihar,UP,Delhi,Bihar,Delhi,Agra,Delhi";
 TreeMap<String, Long> groupByCitiesMap = Stream.of(cities.split(","))
                .collect(Collectors.groupingBy(s -> s, TreeMap::new, Collectors.counting()));

This will return a TreeMap of sorted by City (natural sorting) that containing unique city name as key and their counts as in value.

{Agra=3, Bihar=3, Delhi=5, Uttar Pradesh=2}


We can do it old fashion without using Stream.

TreeMap<String, CityReport> treeMap = new TreeMap();
for (String city : cities.split(",")) {
    CityReport cityReport = new CityReport(city);
    if (treeMap.containsKey(city)) {
        treeMap.computeIfPresent(city, (key, val) -> {val.counter+=1;return val;});
    } else {
        treeMap.put(city, cityReport);

This will return a Map that containing unique city name as key and CityReport as value containing city name and count.

{Agra=CityReport{city=’Agra’, counter=3}, Bihar=CityReport{city=’Bihar’, counter=3}, Delhi=CityReport{city=’Delhi’, counter=5}, UP=CityReport{city=’UP’, counter=2}}

and Finally, need to be sorted out by City count and City name. so here we do so…

List<CityReport> sortedCityReport = treeMap.values().stream().sorted(new ComparatorFilter(new ComparatorByNumber(),new ComparatorByName())).collect(Collectors.toList());

System.out.println("Sort By Count first then City Name "+ sortedCityReport);


Sort By Count first then City Name [CityReport{city=’UP’, counter=2}, CityReport{city=’Agra’, counter=3}, CityReport{city=’Bihar’, counter=3}, CityReport{city=’Delhi’, counter=5}]

Rest of code is below:-

ComparatorFilter.Java :- Sorting by chain of comparator ( by count and name )  over the Collection.

static class ComparatorFilter implements Comparator<CityReport> {

    private final List<Comparator<CityReport>> comparators;

    ComparatorFilter(Comparator<CityReport>... comparators) {
        this.comparators = Arrays.asList(comparators);

    public int compare(CityReport o1, CityReport o2) {
        for (Comparator c : this.comparators) {
            int val =, o2);
            if (val != 0) {
                return val;
        return 0;

ComparatorByName.Java – Sorting by City Name

static class ComparatorByName implements Comparator<CityReport> {

    public int compare(CityReport o1, CityReport o2) {

ComparatorByNumber.Java – sorting by count number.

static class ComparatorByNumber implements Comparator<CityReport> {

    public int compare(CityReport o1, CityReport o2) {
        return (int) (o1.counter - o2.counter);

CityReport Model Class –

class CityReport {
String city;
Long counter;

public CityReport(String city) { = city;
    this.counter = 1L;

public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    CityReport that = (CityReport) o;
    return Objects.equals(city,;

public int hashCode() {

    return Objects.hash(city);

public String toString() {
    return "CityReport{" +
            "city='" + city + '\'' +
            ", counter=" + counter +