Сортировка arrayylist в алфавитном порядке (без учета регистра)


122

У меня есть список строк, namesкоторый содержит имена людей. Я хочу отсортировать Arraylist в алфавитном порядке.

ArrayList<String> names = new ArrayList<String>();
names.add("seetha");
names.add("sudhin");
names.add("Swetha");
names.add("Neethu");
names.add("ananya");
names.add("Athira");
names.add("bala");
names.add("Tony");
names.add("Karthika");
names.add("Nithin");
names.add("Vinod");
names.add("jeena");
Collections.sort(names);
for(int i=0; i<names.size(); i++)
    System.out.println(names.get(i));

Я попытался отсортировать список указанным выше способом. Но он отображает отсортированный массив как:

Athira
Karthika
..
..
ananya
bala
...

но я не хочу делать его чувствительным к регистру. Я хочу получить такой результат:

ananya
Athira
bala

Ответы:


332

Кастом Comparatorдолжен помочь

Collections.sort(list, new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        return s1.compareToIgnoreCase(s2);
    }
});

Или, если вы используете Java 8:

list.sort(String::compareToIgnoreCase);

1
Можете ли вы сказать мне, что такое строка s1 и s2? и как увидеть результат, если функция сравнения возвращает целочисленное значение.
andro-girl

@seethalakshmi - это строки из вашего списка. Пожалуйста, взгляните на исходники метода Collections.sort, если вы хотите получить более подробную информацию об этом
denis.solonenko

я хочу отобразить отсортированный список в logcat. как я могу это сделать?
andro-girl

Он будет отображаться как объект, если вы не разберете список с помощью цикла после сортировки. for (TYPE newvariable : ARRAYTYPE arrayname) { Log.i("YOURAPPTAG", newvariable); }
Брошенная тележка

2
@Dante, если вы посмотрите на реализацию h String.CASE_INSENSITIVE_ORDER, то вы увидите, что A1 используется, lessчем A10, только потому, что длина меньше. Из коробки нет поддержки «естественной сортировки», возможно, вы захотите взглянуть на stackoverflow.com/questions/1262239/…
denis.solonenko 07

195

Самое простое, что нужно сделать:

Collections.sort(list, String.CASE_INSENSITIVE_ORDER);

@djunod, спасибо за ответ. Я пробовал также ваше решение для ArrayList от A1 до A10, но A10 не сортировался правильно, как решение denis.solenenko. Каким-то образом A10 идет после A1. В основном он отсортирован как A1, A10, A2, A3 и т. Д. Почему это произошло и как правильно отсортировать список?
Данте

2
@dante, это обычная сортировка строк. Если вы хотите, чтобы A2
находился

1
Плюс 1. Работал и в Android. Спасибо и поздравляю.
statosdotcom

@djunod Большое спасибо :)
Кумар

stackoverflow должен предоставить мне возможность сохранять такие ответы / фрагменты ..
HB.

29

попробуйте этот код

Collections.sort(yourarraylist, new SortBasedOnName());



import java.util.Comparator;
import com.RealHelp.objects.FBFriends_Obj;
import com.RealHelp.ui.importFBContacts;

public class SortBasedOnName implements Comparator
{
public int compare(Object o1, Object o2) 
{

    FBFriends_Obj dd1 = (FBFriends_Obj)o1;// where FBFriends_Obj is your object class
    FBFriends_Obj dd2 = (FBFriends_Obj)o2;
    return dd1.uname.compareToIgnoreCase(dd2.uname);//where uname is field name
}

}

3
Отличный ответ! Я думаю, что если вы измените 'реализует Comparator' на 'реализует Comparator <FBFriends_Obj>, и вы измените типы объектов в сравнении на FBFriends_Obj, тогда вам не нужны dd1 и dd2, вы можете использовать o1 и o2 непосредственно в операторе возврата
FrinkTheBrave

11

Основываясь на вышеупомянутых ответах, мне удалось сравнить мои пользовательские объекты класса следующим образом:

ArrayList<Item> itemList = new ArrayList<>();
...
Collections.sort(itemList, new Comparator<Item>() {
            @Override
            public int compare(Item item, Item t1) {
                String s1 = item.getTitle();
                String s2 = t1.getTitle();
                return s1.compareToIgnoreCase(s2);
            }

        });

4

Вам нужно использовать собственный компаратор, который будет использовать compareToIgnoreCase, а не compareTo.


Я попробовал эту ссылку, но я не смог найти решение. Могу ли ты объяснить, пожалуйста,
andro-girl

3

Начиная с Java 8 вы можете использовать Stream:

List<String> sorted = Arrays.asList(
                          names.stream().sorted(
                              (s1, s2) -> s1.compareToIgnoreCase(s2)
                          ).toArray(String[]::new)
                      );

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

Если вы распечатаете результат, используя:

System.out.println(sorted);

вы получите следующий результат:

[ananya, Athira, bala, jeena, Karthika, Neethu, Nithin, seetha, sudhin, Swetha, Tony, Vinod]

3

К сожалению, пока что все ответы не учитывают то, что "a"нельзя считать равным, "A"когда дело доходит до сортировки.

String[] array = {"b", "A", "C", "B", "a"};

// Approach 1
Arrays.sort(array);
// array is [A, B, C, a, b]

// Approach 2
Arrays.sort(array, String.CASE_INSENSITIVE_ORDER);
// array is [A, a, b, B, C]

// Approach 3
Arrays.sort(array, java.text.Collator.getInstance());
// array is [a, A, b, B, C]

В подходе 1 любые строчные буквы считаются большими, чем любые прописные.

Подход 2 усугубляет ситуацию, поскольку CASE_INSENSITIVE_ORDER считает "a"и "A"равными (результат сравнения равен 0). Это делает сортировку недетерминированной.

Подход 3 (с использованием java.text.Collator) - это ИМХО единственный способ сделать это правильно, поскольку он учитывает "a"и "A"не равняется, а помещает их в правильном порядке в соответствии с текущим (или любым другим желаемым) Locale.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.