Сортировка строк другого типа в списке - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть список строк, содержащих 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!, что я не знаю почему.Я пытался решить исключение, и алгоритм мог делать то, что я хочу.Любая помощь приветствуется.Спасибо.

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

Ниже приведен пример решения для сортировки заданного списка 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));
   }
}
0 голосов
/ 29 ноября 2018

Любой компаратор должен следовать этим правилам:

  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.

Эта ошибка означает, что вы этого не делаете.

Похоже, вы заявляете, что всеКатегории АА предшествуют всем категориям ББ (через строку ( o1.contains( "AA" ) && o2.contains( "BB" ) ), но вы не добавили обратное, где все ББ идут после всех АА. Вы должны написать это парами, иначе это не сработает. Исправьте это. Возможно, естьбольше нарушений, но по одному шагу за раз.

...