【问题标题】:How to sort List of string with delimiters by ascending and descending order如何按升序和降序对带有分隔符的字符串列表进行排序
【发布时间】:2016-04-25 19:34:49
【问题描述】:

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

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]

如何使用比较器实现这一点:

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);

输出1:

[*#|C1,*#|C2,*#||C,*#||D,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]

如果我在第 18 行和第 20 行交换返回值,那么我得到 ​​p>

输出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]

【问题讨论】:

  • 与其自己进行任何比较,不如将每条记录转换为一个字符串,然后自然地按照您描述的规则进行排序。例如创建一个 normalize 方法,该方法进行转换,然后比较器将是 public int compare(String o1, String o2) { return normalise(o1).compareTo(normalise(o2)) }
  • 哦,你提到了升序和降序的混合......我的想法可能不太适用
  • 当我需要按日期降序排序但剩余字符串升序排序时出现问题。我不确定的是我们是否可以使用单个比较器执行降序和升序排序。
  • if(dateCompare == -1){ return 1; } return dateCompare; 显然是错误的,原因有很多。首先,符号很重要,compare 方法不需要完全返回 -1。其次,将负数转换为正数但让正数保持正数,不能建立正确的比较结果。第三,随后的无条件返回忽略了这样一个事实,即结果可能是0,意味着相等,在这种情况下,应该评估次要标准。

标签: java list sorting data-structures comparator


【解决方案1】:

如果两个日期都不为空,你比较他们,那么你应该处理两个日期相同的情况,然后你应该按标题和作者升序排序。

【讨论】:

  • 您的建议奏效了。我尝试了其他几个示例,但它可以在较小的集合中运行,但是当尝试使用较大的集合时,例如 1000 个字符串,由于某种原因它不会。但是,我通过将它分成两个列表来工作,一个带有日期字段,一个带有 null,然后排序和合并。我也会接受你的回答。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-18
  • 2017-01-09
  • 2012-04-03
  • 2020-11-09
  • 1970-01-01
相关资源
最近更新 更多