Sorting strings of letters, numbers, and special characters

Viewed 1114

I have a list of strings that I would like to sort in a particular order.

The list is ["Bea", "hel", "Hel", "--'", "813", "!@#", "813", "813", "Alb"]

and I would like to have it sorted like:

[813, 813, 813, --', !@#, Alb, Bea, Hel, hel]

I have some code that gets pretty close but there is still one bug that I cannot figure out. Currently the program is producing this.

[813, 813, 813, Alb, --', !@#, Bea, Hel, hel]

Below is the code that I currently have

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


class Main {
  public static void main(String[] args) {
    List<String> list = Arrays.asList("Bea", "hel", "Hel", "--'", "813", "!@#", "813", "813", "Alb");

    Collections.sort(list, STANDARD_ALPHABETICAL_ORDER);
    System.out.println(list);

  }


  public final static Comparator<String> STANDARD_ALPHABETICAL_ORDER =
    (a,b) -> {
        String newA = a.replaceAll("[^a-zA-Z0-9]", "");
        String newB = b.replaceAll("[^a-zA-Z0-9]", "");
        int na = newA.length();
        int nb = newB.length();
        int r;
        int n;
        if (na < nb) {
            r = -1;
            n = na;
        } else if (na > nb) {
            r = -1;
            n = nb;
        } else {
            r = 0;
            n = na;
        }
        for (int i = 0; i < n; ++i) {
            char ca = newA.charAt(i);
            char cb = newB.charAt(i);
            if (ca != cb) {
                if (Character.isDigit(ca) && !Character.isDigit(cb)) {
                  return -1;
                } else if (!Character.isDigit(ca) && Character.isDigit(cb)) {
                  return 1;
                } else if (ca > cb ) {
                  return 1;
                } else {
                  return -1;
                }
            }
        }
        return r;
    };
}
1 Answers

This part is buggy:

} else if (na > nb) {
    r = -1;
    n = nb;

Should be

} else if (na > nb) {
    r = 1;
    n = nb;

This would make appear --' and !@# before all other values, because they will be the empty string when the replacement has been done for the Variables newA or newB. You have to change this, if it is not the intended result.

Related