Сортування списку стрічок з цілими значеннями - Java

У мене є цей список струн

Car1

Car2

Car3

......


Carn

Я хочу сортувати цей список відповідно до числів у ньому.
наприклад, якщо у мене є Car3, Car1, Car12, Car45 , Я хочу його сортувати як Car1, Car3, Car12, Car45 .
Я використав Collections.sort() , але він повертає щось на зразок Car1, car12, car3, Car45 .
що я повинен зробити, щоб поставити його в правильному порядку?

3
Перевірте це stackoverflow.com/questions/104599/…
додано Автор Rohan, джерело
Ви бачили це питання :)
додано Автор Freak, джерело

9 Відповіді

Вам потрібен спеціальний компаратор, щось подібне

    Collections.sort(list, new Comparator() {
        public int compare(String s1, String s2) {
            int i1 = Integer.parseInt(s1.replaceAll("\\D", ""));
            int i2 = Integer.parseInt(s2.replaceAll("\\D", ""));
            return Integer.compare(i1, i2);
        }
    });
5
додано
+1, але для продуктивності я буду компілювати регулярний вираз і використовувати позитивний збіг для вилучення номерів. Компаратори зазвичай є критичними для продуктивності.
додано Автор Marko Topolnik, джерело

Використовуй це:

class ComparatorOfNumericString implements Comparator{

    public int compare(String string1, String string2) {
       //TODO Auto-generated method stub
        String a = string1.substring(3);
        String b = string2.split(3);
        return Integer.parseInt(a)-Integer.parseInt(b);
    }
}

Тепер при сортування передайте цей компаратор таким чином:

Collections.sort(stringList,new ComparatorOfNumericString ());
4
додано
Будьте обережні, коли порівнюєте ціле число з мінусом - це може переповнитися.
додано Автор Howard, джерело

You need to specify a custom Comparator to the Collections.sort() method that defines the ordering that you want for the strings.

Це працює для числа в будь-якому положенні рядка, а також обробляє рядки, які не мають чисел (повертається до звичайного порівняння рядків з природним замовленням):

final Pattern intsOnly = Pattern.compile("\\d+");

Comparator comparator = new Comparator() {
    @Override
    public int compare(final String string1, final String string2) {
        String int1 = null;
        String int2 = null;
        Matcher matcher1 = intsOnly.matcher(string1);
        if (matcher1.find()) {
            int1 = matcher1.group();
            Matcher matcher2 = intsOnly.matcher(string2);
            if (matcher2.find()) {
                int2 = matcher2.group();
            }
        }
        if (int1 == null || int2 == null) { return string1.compareTo(string2); }
        return Integer.valueOf(int1).compareTo(Integer.valueOf(int2));
    }
};
Collections.sort(strings, comparator);

Звичайно, це означає, що Truck1 з'явиться перед автомобілем Car2, але саме так ви хотіли це за вашим запитанням.

UPDATE: Вищевказане рішення не гарантує, що Car6 вийде перед Truck6. Якщо ви також хочете повернутись до натурального замовлення струни у випадку рівних чисел, скористайтеся цим:

final Pattern intsOnly = Pattern.compile("\\d+");

Comparator comparator = new Comparator() {
    @Override
    public int compare(final String string1, final String string2) {
        String int1 = null;
        String int2 = null;
        Matcher matcher1 = intsOnly.matcher(string1);
        if (matcher1.find()) {
            int1 = matcher1.group();
            Matcher matcher2 = intsOnly.matcher(string2);
            if (matcher2.find()) {
                int2 = matcher2.group();
            }
        }
        int result = 0;
        if (int1 != null && int2 != null) {
            result = Integer.valueOf(int1).compareTo(Integer.valueOf(int2));
        }
        if (result == 0) {
            return string1.compareTo(string2);
        }
        else {
            return result;
        }
    }
};
Collections.sort(strings, comparator);
3
додано

Цей сорт лексикографічний, і ви отримуєте це замовлення, оскільки 1 в алфавіті менше 3, а порівняльник ігнорує те, що далі. Що вам потрібно зробити, це або написати свій власний компаратор, який знімає «Авто», залишивши лише число в рядку, тоді вам потрібно буде проаналізувати це рядкове представлення числа у int і порівняти ints (як один з рішення)

3
додано
Дякую за вашу відповідь Я вже зробив це, але хочу бути впевненим, що це єдиний спосіб це зробити, або я просто повторюю колесо :)
додано Автор Just_another_developer, джерело
+1 для пояснення лексикографічного упорядкування рядків
додано Автор selig, джерело

Вам потрібно скористатися перевантаженням sort з компаратором. Наступний код для ваших конкретних рядків (CarXXX):

Collections.sort(carList, new Comparator() {
    public int compare(String s1, String s2) {
        int t1 = Integer.parseInt(s1.substring(3));
        int t2 = Integer.parseInt(s2.substring(3));
        return t1 - t2;
    }
});
1
додано
@Howard, якщо переповнення викликає занепокоєння, то навіть розбір значення в цілих числах може бути проблемою.
додано Автор Aleks G, джерело
Будьте обережні, коли порівнюєте ціле число з мінусом - це може переповнитися.
додано Автор Howard, джерело

Collections.sort() правильно, вам просто потрібно написати компаратор:

public class testComp implements Comparator {

@Override
public int compare(String o1, String o2) {
    int number1 = Integer.parseInt(o1.substring(3, o1.length()));
    int number2 = Integer.parseInt(o2.substring(3, o2.length()));
    if (number1 > number2) {
        return -1;
    } else {
        return 1;
    }
}
1
додано
Це працює лише для цифр у індексі 3 у рядку. Я впевнений, що "Car1", "Car2" тощо були лише прикладом. Подивіться мою відповідь на повне рішення.
додано Автор herman, джерело
Помилую моє незнання, що це з -1 і 1 ... що вони вказують?
додано Автор Just_another_developer, джерело

Вам потрібно буде створити власний компаратор, який виконує сортування, як вам це потрібно. Потім ви можете зателефонувати

Collections.sort(myList, myComparator)

Див. Collections.sort (список, компаратор) .

You can read up on comparators here: Implementing Java Comparator

1
додано

Це буде працювати для вас. Але ви не можете дублювати

    String text = "Car3, Car1, Car12, Car45";
    String[] str = text.split(", ");
    Map myMap=new HashMap<>();
    int[] numOnly=new int[str.length];
    for (int i = 0; i < str.length; i++) {
          numOnly[i] = Integer.parseInt(str[i].replaceAll("\\D", ""));
          myMap.put(numOnly[i],str[i]);
    }       
    System.out.println(myMap.values());
0
додано

Car1 є об'єктом, тому вам потрібно створити власний компаратор. і вкажіть його порядок.

Collection.Sort() is Sorts the specified list into ascending order, according to the natural ordering of its elements. just example: string will do like a-z, number is 0-9. but objects does not have any natural order.

0
додано
ІТ КПІ - Java
ІТ КПІ - Java
436 учасників