Reputation: 29
Thank you for lending your time :)
I have a piece of code that sorts Arraylist using compareToIgnoreCase.
Collections.sort(als,new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
//I want to alter this part
int dif=o1.compareToIgnoreCase(o2);
return dif;
}
});
But I want to sort the arraylist in the following manner:
input: (in any order)
sherin
Sherin
SHERIN
bubBle
buBble
BUBBLE
heart
hEart
hEArt
output :
BUBBLE
buBble
bubBle
hEArt
hEart
heart
SHERIN
Sherin
sherin
Could you please help me with this? Thanks in advance :)
Upvotes: 0
Views: 96
Reputation: 61
public int compare(String s1, String s2) {
int n1 = s1.length();
int n2 = s2.length();
int min = Math.min(n1, n2);
for (int i = 0; i < min; i++) {
char c1 = s1.charAt(i);
char c2 = s2.charAt(i);
char u1 = Character.toUpperCase(c1);
char u2 = Character.toUpperCase(c2);
char l1 = Character.toLowerCase(c1);
char l2 = Character.toLowerCase(c2);
if (u1 != u2) {
return u1 - u2;
} else {
if (l1 != l2) {
return l1 - l2;
} else if (c1 != c2) {
return c1 - c2;
}
}
}
return n1 - n2;
}
Upvotes: 2
Reputation: 14572
Your first try wasn't too bad, but you need to add another comparison in case of similar case insensitive values to order them :
Stream.of("sherin", "Sherin", "SHERIN", "bubBle", "buBble", "BUBBLE", "heart", "hEart", "hEArt")
.sorted((s1, s2) -> {
int tmp = s1.compareToIgnoreCase(s2);
return tmp == 0 ?
s1.compareTo(s2) //Compare equivalent values based on the case (upper case first)
: tmp;
}).forEach(System.out::println);
The comparator provided to Stream.sorted
is the same has your implementation but using a lambda notation.
Result :
BUBBLE
buBble
bubBle
hEArt
hEart
heart
SHERIN
Sherin
sherin
EDIT: Thanks to Joop Eggen for the suggestion of using the comparator decorator :
Comparator
.comparing(Function.identity(), String::compareToIgnoreCase)
.thenComparing(Function.identity(), String::compareTo);
This is a bit cleaner to use and give the same result :
Stream.of("sherin", "Sherin", "SHERIN", "bubBle", "buBble", "BUBBLE", "heart", "hEart", "hEArt").sorted(
Comparator
.comparing(Function.identity(), String::compareToIgnoreCase)
.thenComparing(Function.identity(), String::compareTo)
).forEach(System.out::println);
And the shorter I could do with this notation is :
Comparator.comparing((String s) ->.toLowerCase()).thenComparing(Function.identity())
Upvotes: 7