Как отсортировать список <Объект> в алфавитном порядке с помощью поля "Имя объекта"
У меня есть список объектов типа List<Object> p
. Я хочу отсортировать этот список в алфавитном порядке с помощью поля "Имя объекта". Объект содержит 10 полей, а поле имени - одно из них.
if (list.size() > 0) {
Collections.sort(list, new Comparator<Campaign>() {
@Override
public int compare(final Object object1, final Object object2) {
return String.compare(object1.getName(), object2.getName());
}
} );
}
Но нет ничего подобного String.compare..?
Ответы
Ответ 1
Из вашего кода, похоже, что ваш Comparator
уже параметризован с помощью Campaign
. Это будет работать только с List<Campaign>
. Кроме того, метод, который вы ищете, - compareTo
.
if (list.size() > 0) {
Collections.sort(list, new Comparator<Campaign>() {
@Override
public int compare(final Campaign object1, final Campaign object2) {
return object1.getName().compareTo(object2.getName());
}
});
}
Или, если вы используете Java 1.8
list
.stream()
.sorted((object1, object2) -> object1.getName().compareTo(object2.getName()));
Один заключительный комментарий - нет смысла проверять размер списка. Сортировка будет работать в пустом списке.
Ответ 2
Самый правильный способ сортировки алфавитных строк - использовать Collator
из-за интернационализации. Некоторые языки имеют другой порядок из-за нескольких дополнительных символов и т.д.
Collator collator = Collator.getInstance(Locale.US);
if (!list.isEmpty()) {
Collections.sort(list, new Comparator<Campaign>() {
@Override
public int compare(Campaign c1, Campaign c2) {
//You should ensure that list doesn't contain null values!
return collator.compare(c1.getName(), c2.getName());
}
});
}
Если вам не нужна интернационализация, используйте string.compare(otherString)
.
if (!list.isEmpty()) {
Collections.sort(list, new Comparator<Campaign>() {
@Override
public int compare(Campaign c1, Campaign c2) {
//You should ensure that list doesn't contain null values!
return c1.getName().compare(c2.getName());
}
});
}
Ответ 3
Посмотрите на интерфейс Collections.sort()
и Comparator
.
Сравнение строк может выполняться с помощью object1.getName().compareTo(object2.getName())
или object2.getName().compareTo(object1.getName())
(в зависимости от желаемого направления сортировки).
Если вы хотите, чтобы сортировка была агностической, сделайте object1.getName().toUpperCase().compareTo(object2.getName().toUpperCase())
.
Ответ 4
public class ObjectComparator implements Comparator<Object> {
public int compare(Object obj1, Object obj2) {
return obj1.getName().compareTo(obj2.getName());
}
}
Пожалуйста, замените Object своим классом , который содержит поле имени
Использование:
ObjectComparator comparator = new ObjectComparator();
Collections.sort(list, comparator);
Ответ 5
что-то вроде
List<FancyObject> theList = … ;
Collections.sort (theList,
new Comparator<FancyObject> ()
{ int compare (final FancyObject a, final FancyObject d)
{ return (a.getName().compareTo(d.getName())); }});
Ответ 6
Вот версия ответа Роберта Б., которая работает для List<T>
и сортировки по указанному свойству String объекта с использованием Reflection и сторонних библиотек
/**
* Sorts a List by the specified String property name of the object.
*
* @param list
* @param propertyName
*/
public static <T> void sortList(List<T> list, final String propertyName) {
if (list.size() > 0) {
Collections.sort(list, new Comparator<T>() {
@Override
public int compare(final T object1, final T object2) {
String property1 = (String)ReflectionUtils.getSpecifiedFieldValue (propertyName, object1);
String property2 = (String)ReflectionUtils.getSpecifiedFieldValue (propertyName, object2);
return property1.compareToIgnoreCase (property2);
}
});
}
}
public static Object getSpecifiedFieldValue (String property, Object obj) {
Object result = null;
try {
Class<?> objectClass = obj.getClass();
Field objectField = getDeclaredField(property, objectClass);
if (objectField!=null) {
objectField.setAccessible(true);
result = objectField.get(obj);
}
} catch (Exception e) {
}
return result;
}
public static Field getDeclaredField(String fieldName, Class<?> type) {
Field result = null;
try {
result = type.getDeclaredField(fieldName);
} catch (Exception e) {
}
if (result == null) {
Class<?> superclass = type.getSuperclass();
if (superclass != null && !superclass.getName().equals("java.lang.Object")) {
return getDeclaredField(fieldName, type.getSuperclass());
}
}
return result;
}
Ответ 7
Вы можете использовать sortThisBy()
из Eclipse Collections:
MutableList<Campaign> list = Lists.mutable.empty();
list.sortThisBy(Campaign::getName);
Если вы не можете изменить тип списка из List
:
List<Campaign> list = new ArrayList<>();
ListAdapter.adapt(list).sortThisBy(Campaign::getName);
Примечание. Я участвую в коллекциях Eclipse.
Ответ 8
Если у ваших объектов есть некоторый общий предок [пусть это будет T
], вы должны использовать List<T>
вместо List<Object>
и реализовать Comparator для этого T, используя поле имени.
Если у вас нет общего предка, вы можете реализовать Comperator и использовать reflection, чтобы извлечь имя, Обратите внимание, что он небезопасен, не предлагается и страдает от плохой производительности, чтобы использовать отражение, но он позволяет вам получить доступ к имени поля, не зная ничего о фактическом типе объекта [кроме того, что у него есть поле с соответствующим именем]
В обоих случаях вы должны использовать Collections.sort() для сортировки.
Ответ 9
Это предполагает список YourClass
вместо Object
, как объясняется amit.
Вы можете использовать этот бит из библиотеки Google Guava:
Collections.sort(list, Ordering.natural()
.onResultOf(new Function<String,YourClass>() {
public String call(YourClass o) {
return o.getName();
}))
.nullsLast();
Другие ответы, которые упоминают Comparator
, неверны, поскольку Ordering
реализует Comparator
. Это решение, на мой взгляд, немного проще, хотя может быть сложнее, если вы новичок и не привыкли использовать библиотеки и/или "функциональное программирование".
Скопировано бесстыдно из этого ответа по моему собственному вопросу.
Ответ 10
Использование выбора Сортировка
for(int i = list.size() - 1; i > 0; i--){
int max = i
for(int j = 0; j < i; j++){
if(list.get(j).getName().compareTo(list.get(j).getName()) > 0){
max= j;
}
}
//make the swap
Object temp = list.get(i);
list.get(i) = list.get(max);
list.get(max) = temp;
}
Ответ 11
Если вы используете List<Object>
для хранения объектов подтипа, у которого есть поле имени (вызывается подтип NamedObject
), вам нужно будет сбрасывать элементы списка, чтобы получить доступ к имени. У вас есть 3 варианта, лучший из которых первый:
- Не используйте
List<Object>
в первую очередь, если вы можете помочь - сохраните ваши именованные объекты в List<NamedObject>
- Скопируйте элементы
List<Object>
в List<NamedObject>
, понижающие темпы процесса, выполните сортировку, затем скопируйте их
- Сделайте downcasting в компараторе
Вариант 3 будет выглядеть следующим образом:
Collections.sort(p, new Comparator<Object> () {
int compare (final Object a, final Object b) {
return ((NamedObject) a).getName().compareTo((NamedObject b).getName());
}
}
Ответ 12
if(listAxu.size() > 0){
Collections.sort(listAxu, new Comparator<Situacao>(){
@Override
public int compare(Situacao lhs, Situacao rhs) {
return lhs.getDescricao().compareTo(rhs.getDescricao());
}
});
}