Reputation: 3
I have a String ArrayList of sizes, for example
[12, 10L, 10, 10R, 10S, 10L]
The output should be
[10S, 10R, 10L, 10, 12]
So basically sizes must be first sorted by number - (1,2,3,4,5 ... etc) then by letters.
I managed to get the numbers to sort, so my current output for the input above is
10L, 10, 10R, 10S, 10L, 12
if a letter is missing, then it is the largest (see output above - 10 is after 10L - 10S < 10R < 10L < 10 < 12. )
How should i code a comparator that allows me to do this?
Consider an input array, sizes. This array contains product sizes in the format AB, where:
A is a mandatory integer B is an optional character in [S,R,L] Sizes must first be ordered from smallest to largest by A, and then by B in the order S
Upvotes: 0
Views: 449
Reputation: 845
Try this if it works for your testcases. We can always refine it if needed. (Added a helper method)
List<String> list = new ArrayList<>(Arrays.asList("12","10L","10","10R","10S","10L","14L","14","8","12S"));
List<String> orderArray = new ArrayList<>(Arrays.asList("S", "R", "L"));
List<String> sortedList = list.stream()
.sorted(Comparator.comparing(str -> Integer.parseInt(((String)str).replaceAll("[A-Z]*","")))
.thenComparing(str -> getAnInt(orderArray, (String) str)))
.distinct()
.collect(Collectors.toList());
System.out.println(sortedList);
private int getAnInt(List<String> orderArray, String str) {
int i = orderArray.indexOf(str.substring(str.length() - 1));
if (i == -1) return Integer.MAX_VALUE;
return i;
}
Output: [8, 10S, 10R, 10L, 10, 12S, 12, 14L, 14]
if you don't want to use streams:
List<String> list = new ArrayList<>(Arrays.asList("12","10L","10","10R","10S","10L","14L","14","8","12S"));
List<String> orderArray = new ArrayList<>(Arrays.asList("S", "R", "L"));
list.sort(new Comparator<String>() {
@Override
public int compare(String lhs, String rhs) {
int lInt = Integer.parseInt(lhs.replaceAll("[A-Z]*", ""));
int rInt = Integer.parseInt(rhs.replaceAll("[A-Z]*", ""));
if (lInt != rInt) {
return lInt - rInt;
} else {
return getAnInt(orderArray, lhs) - getAnInt(orderArray, rhs);
}
}
});
System.out.println(list);
Upvotes: 1
Reputation: 12391
I assume finalList
list has the sort data.
10L, 10, 10R, 10S, 10L, 12
Use regex to match the integer, merge the list of alphanumerics
and numbers
.
On your sorted list, run this
List<String> numberList= new ArrayList<String>(); // store number list
List<String> sizeList= new ArrayList<String>(); // store alphanumerics
for(String value: finalList){
if(!value.matches("[0-9]+")){ // if contains characters
sizeList.add(value);
}
else{
numberList.add(value);
}
}
sizeList.addAll(numberList);
sizeList
has what you need
Upvotes: 0