在列表中对不同类型字符串进行排序

3
我有一个字符串列表,包含AA0 AA5 BB2 BB9 AA1 BB13 AA7 AA2,但不按顺序排列。我需要将它们分成两个单独的分类,并按如下顺序排列:AA0 AA1 AA2 AA5 AA7 BB2 BB9 BB13。我该怎么做呢?
我尝试过使用以下类似的代码:myList.stream().sorted(mySorter).foreach(...);其中mySorter如下所示:
  private final Comparator<String> mySorter= ( o1, o2 ) -> {
  try
  {
     final int first = Integer.parseInt( o1.substring( 2, o1.length() ) );
     final int second = Integer.parseInt( o2.substring( 2, o2.length() ) );
     System.out.println( o1 + " -> " + first + " " + o2 + " -> " + second );
     if ( o1.contains( "AA" ) && o2.contains( "BB" ) )
     {
        return -1;
     }
     else if ( o1.contains( "AA" ) && o2.contains( "AA" ) )
     {
        return first - second;

     }
     else if ( o1.contains( "BB" ) && o2.contains( "BB" ) )
     {
        return first - second;
     }
     return first - second;

  }
  catch ( final Exception e )
  {
     e.printStackTrace();
     return 0;
  }
  };

我知道这段代码包含了一些不必要的if/else块,但同时我也遇到了java.lang.IllegalArgumentException: Comparison method violates its general contract!异常,而我不知道为什么会出现这个异常。我一直在尝试解决这个异常,并使算法能够实现我想要的功能。希望能得到任何帮助,谢谢。


你们的字符总是只有两个,然后再加一个数字吗? - dave
@dave 是的,我会有两个字符和一个数字。 - Picture
我可能会以不同的方式进行拆分,首先按字符比较,然后再按整数比较,这样你就可以避免使用if else语句了。 - dave
2
可能是在可能包含数字的字符串上排序的重复问题。 - prophet1906
@dave,我已经在这里比较字符了,你觉得呢? - Picture
2个回答

8
任何比较器都必须遵循以下规则:
  1. 如果 A<B(即 a.compareTo(b) 返回负数),那么 B>A 必须为真(即,如果调用 b.compareTo(a),它必须返回正数)。
  2. A=A (a.compareTo(a) 必须返回0)。
  3. 如果 A<B 并且 B<C,则必须满足:A<C

那个错误意味着你没有遵循这些规则。

看起来你是在说明所有的 AA 类别都在所有的 BB 类别之前(通过这行代码 ( o1.contains( "AA" ) && o2.contains( "BB" ) )),但你没有添加反向的情况,即所有的 BB 在所有的 AA 之后。你必须成对写入,否则它将无法工作。修复它。也许还有更多的违规行为,但一步一步来。


谢谢,我会尝试一下。 - Picture
不错的答案;也许值得将第3点中的“must”改为“MUST”,因为及物性与1/2同样重要。 - Marc Gravell
或者使用工厂方法,它们内在地确保对称性,即 Comparator.comparing((String s) -> s.substring(0, 2)) .thenComparingInt(s -> Integer.parseInt(s.substring(2))) 将完成任务。 - Holger

0

这是一个样例示例,用于解决按照给定的列表进行排序的问题,在该列表中string的格式为前两个字符表示字符串,其余的组成整数。

public static void main (String[] args)
{
  List<String>list = Arrays.asList("AA0", "AA5", "BB9", "BB2", "AA1", "BB13", "AA7", "AA2");

  Collections.sort(list,new Comparator<String>(){
     @Override
     public int compare(String o1,String o2) {
         String substr1 = o1.substring(0,2);
         String substr2 = o2.substring(0,2);
         Integer num1 = Integer.parseInt(o1.substring(2));
         Integer num2 = Integer.parseInt(o2.substring(2));

         int strCompare = substr1.compareTo(substr2); 
         int intCompare = num1.compareTo(num2);

         if (strCompare == 0)  return (intCompare == 0 ? strCompare : intCompare); 
         else return strCompare; 
       }
   });

   for (int i = 0; i < list.size(); ++i) {
        System.out.println(list.get(i));
   }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接