1

I've got a list of Folder objects, with getFolderName method (returns a String).

I'm trying to sort the list but I'm having an issue where the order is incorrect because some of the folder names starts with numeric values like:

  • 1 Test
  • 2 Test
  • 3 Test
  • 4 Test
  • ...
  • 9 Test
  • 10 Test
  • 11 Test
  • 12 Test

Here is my code:

Collections.sort(folders, new Comparator<Folder>() {
 @Override
 public int compare(Folder folder1, Folder folder2) {
  return Integer.compare(folder1.getFolderName(), folder2.getFolderName());
 }
});

Current output:

  • 1 Test
  • 10 Test
  • 11 Test
  • 12 Test
  • 2 Test
  • 3 Test
  • 4 Test
  • ...
  • 8 Test
  • 9 Test

Expected output:

  • 1 Test
  • 2 Test
  • 3 Test
  • 4 Test
  • ...
  • 8 Test
  • 9 Test
  • 10 Test
  • 11 Test
  • 12 Test

What am I missing to sort the list correctly?

2
  • You said getFolderName returns a String, but in your code you use it as int Commented Dec 6, 2019 at 14:21
  • @Shadov I've now got public int compare(Folder folder1, Folder folder2) { Integer fn1 = Integer.parseInt(folder1.getFolderName()); Integer fn2 = Integer.parseInt(folder2.getFolderName()); return Integer.compare(fn1, fn2); } but I still get the same output. Can you help me please? Commented Dec 6, 2019 at 14:26

1 Answer 1

1

I think the logic you want here is to first compare the folder names alphabetically, and then in the case of two folders having the same name, break the tie using the leading number. We can try something along these lines:

Collections.sort(folders, new Comparator<Folder>() {
    @Override
    public int compare(Folder folder1, Folder folder2) {
        String f1 = folder1.getFolderName();
        String f2 = folder2.getFolderName();
        String f1name = f1.replaceAll("\\d+\\s+(.*)", "$1");
        String f2name = f2.replaceAll("\\d+\\s+(.*)", "$1");
        if (f1name.compareTo(f2name) != 0) {
            return f1name.compareTo(f2name);
        }
        else {
            int num1 = Integer.parseInt(f1.replaceAll("(\\d+)\\b.*", "$1"));
            int num2 = Integer.parseInt(f2.replaceAll("(\\d+)\\b.*", "$1"));
            return Integer.compare(num1, num2);
        }
    }
});

Note that I omitted things like null checks in multiple places and other sanity checks. The above code is idealistic and assumes this is not a concern.

Sign up to request clarification or add additional context in comments.

2 Comments

Thats not far off what I currently have. Let me try your snippet.
Still not sure where I went wrong though. I will inspect what you did more closely to try and understand. THANK YOU!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.