1

I have an Arraylist with the values:
was - 2
it - 2
the - 2
times - 2
of - 2
best - 1
worst - 1

This list has just been sorted by the count value at the end of the string(using selection sort), but now I want to sort the words that have the same count alphabetically and I have no idea how to do this.

So the expected output should be

[it - 2, of - 2, the - 2, times - 2, was - 2, best - 1, worst - 1]

3 Answers3

1

Overview

For sorting there are always two approaches:

  1. Make the class Comparable
  2. Use a Comparator

I'll assume your values are some sort of class like

public class Entry {
    private final String text;
    private final int count;

    // getters, constructor, toString, ...
}

Comparable

For the first option, simply let your class implement Comparable with a logic that first uses the count and then, if it is equal, considers the text.

public class Entry implements Comparable<? extends Entry> {
    private final String text;
    private final int count;

    // getters, constructor, toString, ...

    @Override
    public int compareTo(Entry other) {
        int countResult = -1 * Integer.compare(count, other.count);
        return countResult != 0 ? countResult : text.compareTo(other.text);
    }
}

Then simply sort your collection:

Collections.sort(entries);

The -1 * is to get the sorting-by-count descending instead of the default, ascending.


Comparator

You can do the very same using a Comparator. Fortunately, we got some nice helper methods since Java 8 that make this even simpler, here is the code:

Comparator<Entry> comparator = Comparator.comparingInt(Foo::getValue)
    .reversed()
    .thenComparing(Foo::getText);

And then you just give that to the sorter:

entries.sort(comparator);
Zabuzard
  • 25,064
  • 8
  • 58
  • 82
0

Split the strings on \s+-\s+ which means one or more whitespace characters (i.e. \s+) followed by - which in turn is followed by one or more whitespace characters.

Perform the first level of comparison for the descending order of the numeric (second) parts and then perform the second level of comparison for the ascending order of the first parts.

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class Main {
    public static void main(String args[]) {
        List<String> list = new ArrayList<>(
                List.of("was - 2", "it - 2", "the - 2", "times - 2", "of - 2", "best - 1", "worst - 1"));

        list.sort(new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                String[] s1Parts = s1.split("\\s+-\\s+");
                String[] s2Parts = s2.split("\\s+-\\s+");
                int i = Integer.compare(Integer.parseInt(s2Parts[1]), Integer.parseInt(s1Parts[1]));
                if (i != 0) {
                    return i;
                }

                return s1Parts[0].compareTo(s2Parts[0]);
            }
        });

        System.out.println(list);
    }
}

Output:

[it - 2, of - 2, the - 2, times - 2, was - 2, best - 1, worst - 1]

Note: if the two parts of each string are always separated by -, you can split as s1.split(" - ");.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • Thanks this works great, but can you please tell me what you did with the list.sort() and compare? Like what is that called? so I can research more about that. –  Dec 04 '20 at 16:22
  • You are most welcome. We write the sorting logic inside the `compare` method of [Comparator](https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html). There you write how two given objects need to be compared. You can learn more about it from [this link](https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html). You can also check [this](https://www.youtube.com/watch?v=dRX6qO46l44) and [this](https://www.youtube.com/watch?v=0xrhqxTOphI). Feel free to comment in case of any further doubt. – Arvind Kumar Avinash Dec 04 '20 at 16:33
-2
1:- With Use Comparator 

Collections.sort(creatorIdList, (Object o1,Object o2)->{
            //return 0;
        });