需要在Java中对字符串进行排序(区分大小写),但大写字母应首先显示。
我尝试过的事情:
List<String> l = Arrays.asList("aaa","AAA","AAA","aaa","BBB","ccc","CCC");
l.stream().sorted(String.CASE_INSENSITIVE_ORDER);
System.out.println(l);`
输出:
[aaa, AAA, AAA, aaa, BBB, ccc, CCC]
期望的输出:
[AAA,AAA,aaa,aaa,BBB,CCC,ccc]
答案 0 :(得分:2)
在忽略大小写进行比较之后,可以添加第二个比较器来确定顺序。第二个比较器根据字符的大小写进行排序。
List<String> l = Arrays.asList("a","A","A","a","B","c","C");
l.sort(String.CASE_INSENSITIVE_ORDER
.thenComparing(Comparator.comparing(YourClass::isUpperCase)
.reversed()));
private static boolean isUpperCase(String s) {
return Character.isUpperCase(s.charAt(0));
}
Comparator.comparing
使用帮助方法来确定字符串是否为大写。此方法的返回类型为 boolean 。布尔值的自然顺序为 false ,后跟 true 。因此,您必须将其反转才能首先获得大写字符(字符串)。
注意:您应该在这里使用字符而不是字符串(如果所有字符串都只有一个字符)。这里的辅助方法只是检查此字符串中的第一个字符,听起来很奇怪!。
或者,如果您有一种检查小写字母的方法,则可以简化为
l.sort(String.CASE_INSENSITIVE_ORDER
.thenComparing(YourClass::isLowerCase));
private static boolean isLowerCase(String s) {
return Character.isLowerCase(s.charAt(0));
}
更新 :(根据问题的OP更新)。
如果字符串包含多个字符,并且您要基于大写字符串必须先于其他字符串进行排序的条件,则可以这样做。
l.sort(String.CASE_INSENSITIVE_ORDER
.thenComparing(YourClass::areAllCharactersLowerCase));
private static boolean areAllCharactersLowerCase(String s) {
return s.chars()
.mapToObj(c -> (char)c)
.allMatch(Character::isLowerCase);
}
注意:这样,像CCc
和Ccc
这样的字符串将被视为与第一个比较器相等,而第二个比较器将两者都返回false(将它们相等再次)。因此,它们的显示顺序与输入中显示的顺序相同。
编辑2:基于OP注释
如果具有诸如AAa或aAA或AaA之类的字符串怎么办?
@ user7,则应为AAa,AaA,aAA。
我想您的意图是通过逐个字符地比较来对字符串进行排序,并且具有最连续大写字符的字符串将被认为在其他字符串之前列出。
下面的代码按字符进行比较,并处理以下情况
a
的当前字符为大写字母,而字符串b
的当前字符为小写字母,则字符串a
位于b
之前。 / li>
a
的当前字符为小写字母,而字符串b
的当前字符为大写字母,则字符串b
位于a
之前对于相等的字符串,我们在结尾处返回0。
l.sort(String.CASE_INSENSITIVE_ORDER
.thenComparing((a, b) -> {
//String a and b are equal when compared ignoring case (and hence same length)
for (int i = 0; i < a.length(); i++) {
if (Character.isUpperCase(a.charAt(i)) && Character.isLowerCase(b.charAt(i))) {
return -1;
} else if (Character.isLowerCase(a.charAt(i)) && Character.isUpperCase(b.charAt(i))) {
return 1;
}
}
return 0;
}));
答案 1 :(得分:1)
这是自定义排序,不区分大小写。因为区分大小写,所以所有大写字母将排在小写字母之前。因此,结果将是
AAA > BBB > CCC > aaa > bbb > ccc
要实现自定义排序,您需要使用以下自定义比较器
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
public class SortCapitalFirst {
@Test
public void runTest(){
List<String> l = Arrays.asList("aaa","AAA","AAA","aaa","BBB","ccc","CCC");
l.sort((o1, o2) -> {
int compareIgnoreCaseResult = o1.compareToIgnoreCase(o2);
if (compareIgnoreCaseResult != 0){
return compareIgnoreCaseResult;
}
return o1.compareTo(o2);
});
System.out.println(l);
}
}
答案 2 :(得分:0)
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class SortStrings {
public static void main(String[] args) {
Comparator<String> comparator = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
if(o1 == null) {
return 1;
}
if(o2 == null) {
return -1;
}
int result = o1.compareToIgnoreCase(o2);
if(result != 0) {
return result;
}
return o1.compareTo(o2);
}
};
List<String> list = Arrays.asList("A","a","A","a", "B", "c","C");
Collections.sort(list, comparator);
System.out.println(list);
// [A, A, a, a, B, C, c]
List<String> list2 = Arrays.asList("Ab","a","AB", "A", "AbB", "a","B","c","C");
Collections.sort(list2, comparator);
System.out.println(list2);
// compare length first
// [A, a, a, AB, Ab, AbB, B, C, c]
List<String> list3 = Arrays.asList("aaa","AAA","AAA","aaa","BBB","ccc","CCC");
Collections.sort(list3, comparator);
System.out.println(list3);
// [AAA, AAA, aaa, aaa, BBB, CCC, ccc]
}
}
答案 3 :(得分:0)
以下代码帮助您在CASE_INSENSITIVE_ORDER中对字符串进行排序。在这里,您需要对列表进行两次排序。
public static void main(String[] args) {
List<String> l = Arrays.asList("a", "A", "A", "a", "B", "c", "C");
Collections.sort(l);
Collections.sort(l, String.CASE_INSENSITIVE_ORDER);
System.out.println(l);
}