I have a list of items consists of digits and alphabets like below:
Original List:
Apple 1
Apple 1
Apple 4
Apple 1A
Apple 1B
Apple 1D
Apple 2A
Apple 2A
Apple 1C
Apple 1B
Apple 2C
Apple 10
Apple 11
Apple 5
Apple 11
Apple 8D
Banana 1
Banana 4
Banana 9D
Banana 9E
Banana 9C
Banana 13
Banana 16
It's a search result from a API but only sorted by alphabetical order of Apples
and Bananas
. Now I'd like to sort it by the digits (digits randomly come with letters A, B, C, D, E) like below:
The digits with A, B, C, D, E letters should be sorted by both digit and alphabetical order.
Expected list:
Apple 1
Apple 1
Apple 1A
Apple 1B
Apple 1B
Apple 1C
Apple 1D
Apple 2
Apple 2A
Apple 2A
Apple 2C
Apple 4
Apple 5
Apple 8D
Apple 10
Apple 11
Banana 1
Banana 4
Banana 9C
Banana 9D
Banana 9E
Banana 13
Banana 16
I have tried this solution, but it orders all items by the item begins with 0-9 digit like below:
private List<Location> sortLocationList(List<Location> locationArrayList){
Collections.sort(locationArrayList, new Comparator<Location>(){
@Override
public int compare(Location o1, Location o2){
return o1.getValue().compareToIgnoreCase(o2.getValue());
}
});
return locationArrayList;
}
public class Location{
public enum LocationType{ADDRESS, STREET, CITY}
private JavascriptObject object;
private LocationType locationType;
private String value;
public Location(LocationType locationType, String value, JavascriptObject object){
this.locationType = locationType;
this.value = value;
this.object = object;
}
}
My solution is returning this:
Apple 1
Apple 1
Apple 10
Apple 11
Apple 1A
Apple 1B
Apple 1B
Apple 1C
Apple 1D
Apple 2
Apple 2A
Apple 2A
Apple 2C
Apple 4
Apple 5
Apple 8D
Banana 1
Banana 13
Banana 16
Banana 4
Banana 9C
Banana 9D
Banana 9E
Any better solution to sort this list?
Thanks in advance.
I assume that there will always be a pattern like:
"something something"
for all the values that the getValue()
method returns
and that the 2nd "something"
will always start with a number with or without trailing chars.
The code below splits every such value in 3 parts and compares
the 1st part alphabetically
the 2nd part numerically and
the 3d part alphabetically:
private List<Location> sortLocationList(List<Location> locationArrayList){
Collections.sort(locationArrayList, new Comparator<Location>(){
@Override
public int compare(Location o1, Location o2){
String s1 = o1.getValue();
String s2 = o2.getValue();
if (s1.equalsIgnoreCase(s2))
return 0;
String[] tokens1 = s1.split(" ");
String[] tokens2 = s2.split(" ");
if (!tokens1[0].equalsIgnoreCase(tokens2[0]))
return s1.compareToIgnoreCase(s2);
int number1 = Integer.parseInt(tokens1[1].replaceAll("\\D", ""));
int number2 = Integer.parseInt(tokens2[1].replaceAll("\\D", ""));
if (number1 != number2)
return number1 - number2;
String suffix1 = tokens1[1].replaceAll("\\d", "");
String suffix2 = tokens2[1].replaceAll("\\d", "");
return suffix1.compareToIgnoreCase(suffix2);
}
});
return locationArrayList;
}
in alphabetical sort, the letters are after than numbers and '2' after than '10' You need sort by a name, number and suffix(String nullable), use a new class instead a String' with this attributes (name, number and suffix)
// change String to a new type
private Product value;
and fix your sort
@Override
public int compare(Location o1, Location o2){
int c;
// compare name
c = o1.getValue().getName().compareTo(o12.getValue().getName());
if (c == 0) {
// if is the same name compare number
c = o1.getValue().getNum().compareTo(o2.getValue().getNum());
if (c ==0 && o1.getValue().getSufix() != null) {
// if is the same number compare suffix
c = o1.getValue().getSufix().compareTo(o2.getValue().getSufix());
}
}
return c;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With