Java排序映射比较器,在字母键之后排序数字键

Java排序映射比较器,在字母键之后排序数字键,java,comparator,digits,letter,sortedmap,Java,Comparator,Digits,Letter,Sortedmap,我需要一个SortedMap,其中Charachter键按如下方式排序:('a''Z''0''9'),所以首先是字符,然后是数字,全部按升序排列。 这是我到目前为止尝试过的,但是,输出显示它无法返回我想要的排序,因为数字键的值仍然在字母键的值之前。 我做错了什么?还有更好的方法吗? 提前谢谢 public static void main(String[] args) { SortedMap<Character, String> sortedMap = new TreeMap

我需要一个SortedMap,其中Charachter键按如下方式排序:('a''Z''0''9'),所以首先是字符,然后是数字,全部按升序排列。 这是我到目前为止尝试过的,但是,输出显示它无法返回我想要的排序,因为数字键的值仍然在字母键的值之前。 我做错了什么?还有更好的方法吗? 提前谢谢

public static void main(String[] args) {
    SortedMap<Character, String> sortedMap = new TreeMap<>(new Comparator<Character>() {
        @Override
        public int compare(Character o1, Character o2) {
            if (Character.isDigit(o1) && Character.isLetter(o2)){
                return o2.compareTo(o1);
            }
            else if(Character.isLetter(o1) && Character.isDigit(o2)){
                return o1.compareTo(o2);
            }
            else{
                return o1.compareTo(o2);
            }
        }
    });

    sortedMap.put('5', "five");
    sortedMap.put('8', "nine");
    sortedMap.put('A', "ALPHA");
    sortedMap.put('G', "GOLF");
    sortedMap.put('F', "FOXTROT");
    System.out.println(sortedMap.values());
}
publicstaticvoidmain(字符串[]args){
SortedMap SortedMap=新树映射(新比较器(){
@凌驾
公共整数比较(字符o1,字符o2){
if(字符isDigit(o1)和字符islitter(o2)){
返回o2.compareTo(o1);
}
else if(字符Isleter(o1)和字符isDigit(o2)){
返回o1。与(o2)相比;
}
否则{
返回o1。与(o2)相比;
}
}
});
分类地图放置('5','5');
分类地图放置('8','9');
分类地图放置('A','ALPHA');
分类地图放置('G','GOLF');
分类地图放置('F',“狐步”);
System.out.println(sortedMap.values());
}

如果o1是数字,o2是字母,则需要返回结果“o1>o2”,因此在本例中返回1。同样,如果o1是字母,o2是数字,则需要返回结果“o1
public int compare(Character o1, Character o2) {
   if (Character.isDigit(o1) && Character.isLetter(o2)){
      return 1;
   }
   else if(Character.isLetter(o1) && Character.isDigit(o2)){
      return -1;
   }
   else{
      return o1.compareTo(o2);
   }
}

如果
o1
是一个字母,而
o2
是一个数字,则应始终返回-1,因为您总是希望字母在前面。如果相反,你应该总是返回1


它应该返回的唯一情况是
o1。compareTo(o2)
在最后一个
else
,这意味着
o1
o2
都是字母或数字,在这种情况下,比较器应该简单地遵循自然顺序。

如果希望所有字母都位于所有数字之前,如果你得到一个数字和一个字母,你根本不应该比较它们:

public int比较(字符o1,字符o2){
if(字符isDigit(o1)和字符islitter(o2)){
//o1o2,无论o1和o2的值是多少
//所以返回任何正整数
返回100;
}
//两者都必须是字母或都必须是整数
//回到正常的比较,就像你已经做的那样
返回o1。与(o2)相比;
}

我更喜欢在Map声明之外使用
三元(?:)
构造来构建
比较器。我还添加了一些额外的值,这些值与您的值穿插在一起,以增加可变性

        Comparator<Character> comp = (a, b) -> Character.isLetter(a)
                && Character.isDigit(b) ? -1 :
                Character.isLetter(b) && Character.isDigit(a) ? 1 :
                a.compareTo(b);

        SortedMap<Character, String> sortedMap = new TreeMap<>(comp);
        sortedMap.put('Q', "Quebec");
        sortedMap.put('B', "Beta");
        sortedMap.put('5', "five");
        sortedMap.put('9', "nine");
        sortedMap.put('A', "ALPHA");
        sortedMap.put('3', "three");
        sortedMap.put('G', "GOLF");
        sortedMap.put('F', "FOXTROT");
        sortedMap.entrySet().forEach(System.out::println);

假设您使用的是Java 8+,请将地图声明为:

SortedMap<Character, String> sortedMap = 
            new TreeMap<>(Comparator.comparingInt(c -> (c + 197) % 255));
SortedMap-SortedMap=
新的树形图(比较器。比较(c->(c+197)%255));
或者,您可以将“幻数”197和255提取到常数中,或者将
comparingit(…)
的参数提取到常数中

说明:
字符0..9对应于ASCII码48..57
所有字母的ASCII码属于范围65..122
上面的代码将代码移位一位,将数字范围移动到245..254,将字母范围移动到7..64

由于比较器比较移位的代码,它将字母放在数字之前

是的,它可以工作,但这是一个坏习惯。始终返回1、-1或0。这是一个很好的解决方案+1.
SortedMap<Character, String> sortedMap = 
            new TreeMap<>(Comparator.comparingInt(c -> (c + 197) % 255));