Reputation: 21
Let's say, for example that I have the same 2 strings but the first one starts with capital letter and the second one isn't. Now, I need to order capital letters before lowercase letters using CompareTo method. How do I do that? because CompareTo method will order them the opposite way.
An Example: List = { "world","Aple","World", "aple","Hello"} the order I want to get is: "Aple","Hello","World", "aple", "world". Meaning, no matter what, uppercase letters come first.
Upvotes: 1
Views: 7292
Reputation: 8499
Try
public class StringSorter {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("apple");
list.add("Hello");
list.add("Apple");
list.add("World");
list.add("hello");
Collections.sort(list,
new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
if(o1.equalsIgnoreCase(o2)){
return o1.compareTo(o2);
}
return o1.toUpperCase().compareTo(o2.toUpperCase());
}
});
System.out.println(list);
// in a shorter way with java-8
list.sort(Comparator.comparing(String::toLowerCase));
}
}
Upvotes: 3
Reputation: 3364
I liked Syam S answer. And thought of trying in different way. I believe it is comparatively efficient too
Off course - add null check :)
Collections.sort(list,
new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int min = Math.min(o1.length(), o2.length());
for (int k = 0; k < min ; k++ ){
char c1 = o1.charAt(k);
char c2 = o2.charAt(k);
if (c1 != c2 ){
char u1 = Character.toUpperCase(c1);
char u2 = Character.toUpperCase(c2);
if (u1 == u2) {
return Character.isUpperCase(c1) ? -1 : 1;
}else{
return u1 - u2;
}
}
}
return o1.length() - o2.length();
}
});
Upvotes: 0
Reputation: 65793
Something like this should work - I am tinkering with the returns so it may change.
static class CasedStringComparator implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
if ( o1 == null ) {
return -1;
}
if ( o2 == null ) {
return 1;
}
for ( int i = 0; i < Math.min(o1.length(), o2.length()); i++ ) {
char c1 = o1.charAt(i);
char c2 = o2.charAt(i);
if ( Character.isUpperCase(c1) && !Character.isUpperCase(c2)) {
return -1;
}
if ( !Character.isUpperCase(c1) && Character.isUpperCase(c2)) {
return 1;
}
int diff = Character.compare(c1, c2);
if (diff != 0) {
return diff;
}
}
if ( o1.length() < o2.length() ) {
return -1;
}
return 0;
}
}
But as @GriffeyDog points out - this does not change the default ordering which also puts uppercase before lowercase.
Upvotes: 0
Reputation: 10468
Here's a(the) standard implementation of string comparisons:
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
You'll need to write a method like this that changes the char values, e.g. swapping uppercase and lowercase. Then as netinept says, use it in a sort algorithm as a 'compareTo' override or 'Comparable' implementation.
Upvotes: 0
Reputation: 8490
Override the compareTo
method or implement the Comparable
Interface.
The documentation says that the return value for this is
-1, 0, or 1 according to whether the value of expression is negative, zero or positive.
So, you only need to do your own string comparisons and return the appropriate value.
Upvotes: 1