Подтвердить что ты не робот

Как я могу отсортировать этот ArrayList так, как я хочу?

Вот простая программа сортировки ArrayList:

ArrayList<String> list = new ArrayList<String>();

list.add("1_Update");
list.add("11_Add");
list.add("12_Delete");
list.add("2_Create");

Collections.sort(list);
for (String str : list) {
  System.out.println(str.toString());
}

Я ожидал выход этой программы как:

1_Update
2_Create
11_Add
12_Delete

Но когда я запускаю эту программу, я получаю вывод как:

11_Add
12_Delete
1_Update
2_Create

Почему это и как мне получить ArrayList для сортировки, как показано в ожидаемом выходе?

4b9b3361

Ответ 1

Вы можете написать собственный компаратор:

Collections.sort(list, new Comparator<String>() {
    public int compare(String a, String b) {
        return Integer.signum(fixString(a) - fixString(b));
    }
    private int fixString(String in) {
        return Integer.parseInt(in.substring(0, in.indexOf('_')));
    }
});

Ответ 2

Когда вы сортируете этот тип данных в виде строки, он сравнивает сами символы, включая цифры. Вся строка, начинающаяся с "1", например, закончится вместе. Итак, порядок заканчивается примерно так...

1 10 100 2 20 200

Ни в коем случае не понимает, что вы назначаете значение подмножествам строки, такие как номера переменной длины в начале строки. Когда сортировка чисел как строк, добавление влево с нулями, сколько требуется для покрытия наибольшего числа, может помочь, но на самом деле это не решает проблему, когда вы не контролируете данные, как в вашем примере. В этом случае сортировка будет...

001 002 010 020 100 200

Ответ 3

Он сортируется как текст (в алфавитном порядке), а не как числа. Чтобы обойти это, вы можете реализовать пользовательский компаратор, как это предлагается в ответе nsayer.

Ответ 4

Делает лексикографическое сравнение. Он сравнивает первый символ в каждой строке, сортируя их. Затем он сравнивает вторую строку с тем же первым символом. Когда он сравнивает символ "_" с числом, он больше по величине, чем любой одиночный символ, как 8 > 7 и a > 9. Помните, что он выполняет сравнение символов, а не числовое сравнение.

Есть способы реализовать собственную маршрутизацию сортировки, которая может быть лучше, чем переименование имен script.

Если переименование имен script является опцией, это может позволить использовать другие инструменты script. Один формат может быть

01_create_table.sql
02_create_index.sql
11_assign_privileges.sql

Сохраняя первые две цифры до двух символов, лексикографическое сравнение будет работать.

Ответ 5

В документе Collections.sort() docs говорится:

Сортирует указанный список в в порядке возрастания, согласно естественное упорядочение его элементов.

Это означает, что для строк вы получите список в алфавитном порядке. Строка 11_assign_privileges.sql встречается перед строкой 1_create_table.sql и 12_07_insert_static_data.sql до 1_create_table.sql и т.д. Таким образом, программа работает должным образом.

Ответ 6

Поскольку строки сортируются в алфавитном порядке, а символ подчеркивания - после символов для чисел. Вы должны предоставить компаратор, реализующий "Естественный порядок" для достижения желаемого результата.

Ответ 7

Алгоритм сравнения строк сравнивает каждый символ за раз. 1 сортирует до 2. Не имеет значения, что за ним следуют 1 или 2.

Итак 100 будет сортировать до 2. Если вы не хотите этого поведения, вам нужен алгоритм сравнения, который обрабатывает этот случай.

Ответ 8

Как указывали другие, элементы будут отсортированы по алфавиту по умолчанию. Решение определяет конкретный класс java.util.Comparator и передает его в качестве второго аргумента методу сортировки. Ваш компаратор должен будет проанализировать ведущие целые числа из строк и сравнить их.

Ответ 9

Чтобы сортировать sort.sort() произвольно, вы можете использовать

Collections.sort(List list, Comparator c)  

Затем просто реализуйте Компаратор, который разбивает строку и сортирует сначала в зависимости от числа, а затем от остальных или, тем не менее, вы хотите, чтобы он сортировался.

Ответ 10

Все уже отметили, что объяснение состоит в том, что ваши строки сортируются как строки, а число уже направило ваше внимание на сравнение строк Natural Order. Я просто добавлю, что это отличное упражнение для написания этого компаратора и отличная возможность практиковать развитие, основанное на тестах. Я использовал его для демонстрации TDD в Code Camp; слайды и код здесь.

Ответ 11

Как указано выше, вы ищете реализацию Comparator, которая реализует естественный вид. Джефф Этвуд написал замечательный пост по естественной сортировке некоторое время назад - это стоит прочитать.

Если вы ищете реализацию Java, я нашел, что это полезно: http://www.davekoelle.com/alphanum.html

Ответ 12

Вы можете добавить интерфейс IComparable, а затем отсортировать его по определенному свойству. Если у вас есть коллекции предметов магазина, например, вы можете отсортировать их по цене или по категориям и т.д. Если вы хотите заказать по названию, вот пример:

Обратите внимание, как ArrayList сортируется по свойству имени элементов. Если вы не добавите IComparable, то при использовании метода сортировки он выдает ошибку.

enter image description here

static void Main(string[] args)
    {
        ArrayList items = new ArrayList();
        items.Add(new Item("book", 12.32));
        items.Add(new Item("cd", 16.32));
        items.Add(new Item("bed", 124.2));
        items.Add(new Item("TV", 12.32));

        items.Sort();

        foreach (Item temp in items)
            Console.WriteLine("Name:{0} Price:{1}", temp.name, temp.price);
        Console.Read();            
    }


    class Item: IComparable
    {
        public string name;
        public double price;

        public Item(string _name, double _price)
        {
            this.name = _name;
            this.price = _price;
        }

        public int CompareTo(object obj)
        {   
            //note that I use the name property I may use a different one
            int temp = this.name.CompareTo(((Item)obj).name);
            return temp;
        }
    }