Как отсортировать лексикографически ArrayList? - PullRequest
6 голосов
/ 08 июня 2010

Я пытаюсь отсортировать ArrayList строк, которые представляют значения карт. Так, некоторые карты содержат буквы («король»), а некоторые содержат строки, содержащие только число («7»). Я знаю использовать Collections.sort, но он сортирует только строки, содержащие буквы. Как получить ArrayList для сортировки по номеру, а также по алфавиту?

Редактировать: Извините, я не обращал особого внимания, когда смотрел на сортировку. Сортировка работает правильно, меня просто скинул тот факт, что 10 будет перед 2. Спасибо

Ответы [ 5 ]

9 голосов
/ 08 июня 2010

Нет, Collections.sort отсортирует все, используя порядковое лексикографическое сравнение Unicode, так как это поведение String.compareTo. «7» предшествует «королю», а «10» предшествует «2».

4 голосов
/ 08 июня 2010

Как я понимаю, у вас есть массив, подобный ["7", "Queen", "9", "6"], и вы хотите, чтобы он выглядел как ["Queen", "9", "7", "6"] (или в обратном порядке) после завершения сортировки.

Я бы рекомендовал сделать его немного более объектно-ориентированным, т.е. создать класс Card с полями name и value:

class Card {
   private final String name;
   private final int value;
   ...
   //constructor and getters
}

и после этого создайте экземпляры следующим образом:

Card six = new Card("6", 6);
Card ten = new Card("10", 10);
Card queen = new Card("Queen", 12);

После этого будет намного проще выполнять все операции с карточками (и особенно с сортировкой), используя поле value вместо названий карточек.

1 голос
/ 08 июня 2010

Как сказал @Jon Skeet, встроенная сортировка будет сравниваться на основе значений Unicode. Вы должны написать свой собственный метод сортировки.

Пока вы пишете свой собственный код, могу ли я предложить перечисление? Колода карт является одним из канонических примеров использования перечислений. Короткая версия заключается в том, что вы можете объявить свой собственный порядок сортировки для группы вещей; Вы могли бы даже заставить короля пиков опередить короля алмазов, если хотите. Посмотрите учебник Sun здесь .

0 голосов
/ 08 июня 2010

Сортировка отсортирует все по вашей кодировке.Другими словами, все цифры будут идти перед буквами в лексикографическом порядке.Например, десятичные числа начинаются с '.'и не в порядке лексикографически.

Если вы хотите изменить это, создайте объект Comparator.Затем вы можете расположить элементы в любом порядке.

Например, это позволит отсортировать числа в порядке номеров, а также слова в лексическом порядке:

class CardComparator extends Object implements Comparator{
 public int compare(Object a, Object b){
  try{
   double d1=Double.valueOf(a.toString());
   try{
     double d2=Double.valueOf(b.toString());
     return (d2>d1)?1:-1;            // both numeric
   }catch(NumberFormatException e){ // a is numeric but b isn't
     return 1;
   }
  }catch(NumberFormatException e){  
    try{
     double d2=Double.valueOf(b.toString()); 
     return -1;                       // a is nonnumeric but b is
    }catch(NumberFormatException e){  // both nonnumeric
      return a.toString().compareTo(b.toString);
    }
  }
 }
}
Comparator comparator=new CardComparator();
Collections.sort(cards, comparator);

PS не проверено!1008 *

0 голосов
/ 08 июня 2010

Я знаю, как использовать Collections.sort, но он сортирует только строки, содержащие буквы. Как получить ArrayList для сортировки по номеру, а также по алфавиту?

Если строка является числом, она уже сортируется (хотя в виде строки):

import java.util.*;
class Sort {
    public static void main( String [] args  ) {
        List list = Arrays.asList("Kings","7", "Abcd", "3.1416");
        Collections.sort( list );
        System.out.println( list );
    }
}

Отпечатки

$ java Sort
[3.1416, 7, Abcd, Kings]

Это то, что вам нужно?

редактировать

Предполагая (угадывая), что вам нужно отсортировать колоду карт, в которой есть как цифры, так и буквы (J, Q, K, A), вы можете попробовать использовать собственный компаратор.

Вот тот, который учитывает числа «как числа», а остальные как строки, поэтому «10» следует после «2», но перед «королями»

import java.util.*;
class Sort {
    public static void main( String [] args  ) {

        List<String> list = Arrays.asList("Kings","7", "Queen", "3", "10", "A", "2", "8", "Joker");
        Collections.sort( list , new Comparator<String>(){
            public int compare( String a, String b ){
                // if both are numbers
                if( a.matches("\\d+") && b.matches("\\d+")) {
                    return new Integer( a ) - new Integer( b );
                }
                // else, compare normally. 
                return a.compareTo( b );
            }
        });
        System.out.println( list );
    }
}

$ java Sort
[2, 3, 7, 8, 10, A, Joker, Kings, Queen]

Если это то, что вам нужно, я думаю, это поможет вам выяснить все остальное. Вероятно, следующая вещь будет состоять в том, как сортировать пики против червей.

После ответа Roman вы можете создать класс и реализовать интерфейс Comparable :

  class Card implements Comparable<Card> {
       public int compareTo( Card other ) {  
           // add custom logic to compare one card with other 
       }
   }
...