String[] inputStringArray = { "1", "19", "2", "3pt1", "3", "5pt1", "6pt2", "7pt3", "7pt3", "10", "10x1", "15", "7", "A7", "B87", "10pt5" };

// The input is a String array. Make that an ArrayList:

java.util.List<String> inputList = new java.util.ArrayList<String>(java.util.Arrays.asList(inputStringArray));

Say we have the above input array of string values that we have converted to an ArrayList

public static java.util.List<String> sort(java.util.List<String> list) {

java.util.Collections.sort(list, new java.util.Comparator<String>() {

/**

* Custom compare to sort numbers as numbers.

* Strings as strings, with numbers ordered before strings.

*

* @param o1

* @param o2

* @return

*/

@Override

public int compare(String o1, String o2) {

boolean isFirstNumeric, isSecondNumeric;

isFirstNumeric = o1.matches("\\d+");

isSecondNumeric = o2.matches("\\d+");

if (isFirstNumeric) {

if (isSecondNumeric) {

return Integer.valueOf(o1).compareTo(Integer.valueOf(o2));

} else {

return -1; // numbers always smaller than letters

}

} else {

if (isSecondNumeric) {

return 1; // numbers always smaller than letters

} else {

isFirstNumeric = o1.split("[^0-9]")[0].matches("\\d+");

isSecondNumeric = o2.split("[^0-9]")[0].matches("\\d+");

if (isFirstNumeric) {

if (isSecondNumeric) {

int intCompare = Integer.valueOf(o1.split("[^0-9]")[0]).compareTo(Integer.valueOf(o2.split("[^0-9]")[0]));

if (intCompare == 0) {

return o1.compareToIgnoreCase(o2);

}

return intCompare;

} else {

return -1; // numbers always smaller than letters

}

} else {

if (isSecondNumeric) {

return 1; // numbers always smaller than letters

} else {

return o1.compareToIgnoreCase(o2);

}

}

}

}

}

});

return list;

}

The above does the following:

- Determines if the strings being compared are numeric values or not, using regular expression to match on \d which signifies a numeric digit.
- If both values are numeric, then we compare as integers using its already implemented compareTo function.
- If only one of the values is numeric, then it is the smallest as we want the numbers to sort first.
- If both are non-numeric, then we simply compare as strings. However, to show extended support for our third case of blended numbers and text, we go through same logic as above on the two string values: if both begin with numbers, then compare as integers with difference that equal numbers then need to sort by text; if one begins with a number, then it is smaller; if both are text, then just compare as strings.

Hopefully that is clear, but to test the results, you can use the following code:

java.util.List<String> sortedList = sort(inputList);

System.out.println("Numbers and text sorted!");

for (String s : sortedList) {

System.out.println(s);

}

Hope that helps.

Happy coding!

**References:**