Java 如何按升序和降序对带分隔符的字符串列表进行排序

Java 如何按升序和降序对带分隔符的字符串列表进行排序,java,list,sorting,data-structures,comparator,Java,List,Sorting,Data Structures,Comparator,我需要根据键中的不同分隔符对字符串列表进行排序。键是日期、标题、来源、作者的串联。我需要按日期降序排列列表,然后按标题和来源升序排列。除author外,所有值都可以为null,也可以不为null。 我添加“#”作为分隔符,用于将日期与标题、来源和作者分开 如果标题和来源为空,我会添加“|”来代替它们。 如果日期为空,我添加“*”来代替日期 Systen.out.print(listToSortKeys): [2015-03-26 00:00:00.0#CAB,2015-03-26 00:00:0

我需要根据键中的不同分隔符对字符串列表进行排序。键是日期、标题、来源、作者的串联。我需要按日期降序排列列表,然后按标题和来源升序排列。除author外,所有值都可以为null,也可以不为null。 我添加“#”作为分隔符,用于将日期与标题、来源和作者分开 如果标题和来源为空,我会添加“|”来代替它们。 如果日期为空,我添加“*”来代替日期

Systen.out.print(listToSortKeys):
[2015-03-26 00:00:00.0#CAB,2015-03-26 00:00:00.0#ABC, 2011-06-29 00:00:00.0#EFG, 2011-06-29 00:00:00.0#DFG, *#||D, *#||C, *#|C2, *#|C1]
如何使用comaparator实现这一点:

Comparator<String> cmp = new Comparator<String>() {
          public int compare(String o1, String o2) {
              String[] keySplit1 = o1.split("#",2);
              String[] keySplit2 = o2.split("#",2);
              try{
              if(!keySplit1[0].equals("*") && !keySplit2[0].equals("*")){ // if date is not null compare and sort in descending order
                      int dateCompare = sfd.parse(keySplit1[0]).compareTo(sfd.parse(keySplit2[0]));
                        if(dateCompare == -1){
                            return 1;
                        }
                      return dateCompare;

                }
              if(keySplit1[0].equals("*") && keySplit2[0].equals("*")){ // if both the date are null then do normal sort on string
                  return o1.compareTo(o2);
              }
              if((keySplit1[0].equals("*") && !keySplit2[0].equals("*")) || (!keySplit1[0].equals("*") && keySplit2[0].equals("*"))){  // if one of date is null then move it towards end of list
                  if(keySplit1[0].equals("*")){
                      return -1;  // line 18
                  }else{
                      return 1;   // line 20
                  }
              }
              }catch(Exception e){      
                  e.printStackTrace();
              }
              return keySplit1[1].compareTo(keySplit2[1]);

          }
          };
          Collections.sort(listToSortTheKeys, cmp);
如果我交换第18行和第20行中的返回值,那么我得到

输出2:

[2015-03-26 00:00:00.0#CAB, 2015-03-26 00:00:00.0#ABC, 2011-06-29 00:00:00.0#EFG, 2011-06-29 00:00:00.0#DFG, *#|C1, *#|C2, *#||C, *#||D]
预期产出:

[2015-03-26 00:00:00.0#ABC,2015-03-26 00:00:00.0#CAB,2011-06-29 00:00:00.0#DFG,2011-06-29 00:00:00.0#EFG,*#|C1,*#|C2,*#||C,*#||D]

如果两个日期都不为空,并且您比较了它们,那么您应该在两个日期相同时处理大小写,然后您应该按标题和作者升序排序。

与其自己进行任何比较,不如将每条记录转换为字符串,然后按照您描述的规则自然排序。e、 制作一个归一化方法,进行转换,然后比较器将是公共的int比较(字符串o1,字符串o2){返回归一化(o1)。比较(归一化(o2))}哦,你提到了升序和降序的混合。。我的想法可能不太管用,因为当我需要按日期按降序排序,但按剩余字符串按升序排序时,问题就出现了。我不确定的是,我们可以使用单个比较器执行降序和升序排序。
if(dateCompare=-1){return 1;}return dateCompare显然是错误的,原因有多种。首先,符号很重要,
compare
方法不需要精确返回
-1
。第二,将负数转换为正数,但让正数保持正数,无法建立正确的比较结果。第三,随后的无条件返回忽略了一个事实,即结果可能是
0
,这意味着相等,在这种情况下,应评估次要标准。您的建议有效。我尝试了两个其他的例子,它可以在更小的集合中工作,但是当我尝试使用更大的集合时,比如说1000个字符串,由于某种原因,它不能工作。然而,我把它分为两个列表,一个是日期字段,一个是空的,然后排序和合并。我也会接受你的回答。谢谢
[2015-03-26 00:00:00.0#ABC,2015-03-26 00:00:00.0#CAB,2011-06-29 00:00:00.0#DFG,2011-06-29 00:00:00.0#EFG,*#|C1,*#|C2,*#||C,*#||D]