I have a list of strings def123, abc999, zzz000, abc123, zzz111. I want the list sorted such that first three characters are sorted in ascendng order and next three in descending. So the output should be abc999, abc123, def123, zzz111,zzz000 Is this possible?
-
5Everything is possible, but SO if you want help you need to show some attempt to solve the problem. So I'll point you in the right direction. You need to implement Comparable, http://stackoverflow.com/questions/2784514/sort-arraylist-of-custom-objects-by-property – Leon Sep 12 '16 at 05:50
-
Comparable does not fit here, since Strings are final. – Sharon Ben Asher Sep 12 '16 at 05:51
-
(`Comparable does not fit here, since Strings are final` - applies _if_ `string` from the question is `java.lang.String`. (Then, there are things like [AspectJ](http://eclipse.org/aspectj)…).) – greybeard Sep 12 '16 at 06:55
5 Answers
Other answers have suggested you implement Comparator
. That's no longer necessary with recent utility methods added to the interface in Java 8:
list.sort(Comparator
.comparing(s -> s.substring(0, 3))
.thenComparing(s -> s.subtring(3, 6), Comparator.reverseOrder()));
Also note that List
now has a sort
method.

- 11,964
- 10
- 61
- 87

- 27,148
- 6
- 47
- 78
-
This one needs and ending parenthesis. Even if I enter that, this one is giving me compiler errors. any idea?? – Supun Wijerathne Sep 28 '16 at 08:41
Yes, it is possible. You will have to write your own Comparator
. Here's a tutorial to get you started https://www.tutorialspoint.com//java/java_using_comparator.htm

- 13,849
- 5
- 33
- 47
-
1That tutorial is now very out-of-date. Java 8's enhancements to Comparator means that it is generally not necessary to override `compare`. Having said that, Oracle's tutorial on building comparators is equally out-of-date! – sprinter Sep 12 '16 at 07:15
Break the strings into two substrings and then sort using comparator
. Something like this: Demo
List<String> list = Arrays.asList("def123", "abc999", "zzz000", "abc123", "zzz111");
Comparator<String> cmp = new Comparator<String>() {
public int compare(String o1, String o2) {
int diff = (o1.substring(0,3)).compareTo(o2.substring(0,3));
return (diff == 0) ? (Integer.valueOf(o2.substring(3)).compareTo(Integer.valueOf(o1.substring(3)))): diff;
}
};
Collections.sort(list, cmp);

- 13,038
- 6
- 64
- 79
-
-
In this special case, where the source strings have equal lengths with leading zeros where necessary, you can just compare the strings without parsing them to `int`s. – Holger Sep 13 '16 at 15:42
You should create a custom class including your String
as an attribute. That class should implement the Comparable interface.
Inside your custom class you have to override method compareTo(T o)
which was inherited from Comparable
interface. You should apply your sorting logic there.
Then if you make a Collection
(ex: List<CustomClass>
) using that custom class as the object type, you can use Collections.sort(list) method to sort that List.
A complete example can be found here.

- 11,964
- 10
- 61
- 87
If you want more of an algorithmic approach, check this out: https://jsfiddle.net/5adpqgrc/1/
// start with ['def123', 'abc999', 'zzz000', 'abc123', 'zzz111']
var strings = ['def123', 'abc999', 'zzz000', 'abc123', 'zzz111']
$('body').append(strings.join(' ') + '<br>')
// reverse the digits
// get this ['def876', 'abc000', 'zzz999', 'abc876', 'zzz888']
strings = reverse_digits_only(strings)
$('body').append(strings.join(' ') + '<br>')
// sort it
// get this ['abc000', 'abc876', 'def876', 'zzz888', 'zzz999']
strings = strings.sort()
$('body').append(strings.join(' ') + '<br>')
// reverse the digits again
// get this ['abc999' 'abc123' 'def123' 'zzz111' 'zzz000']
strings = reverse_digits_only(strings)
$('body').append(strings.join(' ') + '<br>')
function reverse_digits_only (strings) {
return strings.map(function (string) {
var first_three_letters = string.substring(0, 3)
var reversed_digits = string.substring(3).split('').map(function (digit) {
return 9 - digit
})
return first_three_letters + reversed_digits.join('')
})
}
How this works is that you:
- Reverse the digits (abc999 becomes abc000)
- Then sort it naturally
- And then reverse the digits again.

- 2,721
- 13
- 27