Сортировать ArrayList пользовательских объектов по свойству - PullRequest
1067 голосов
/ 07 мая 2010

Я читал о сортировке списков ArrayLists с использованием Comparator, но во всех примерах люди использовали compareTo, который согласно некоторым исследованиям является методом для строк.

Я хотел отсортировать ArrayList пользовательских объектов по одному из их свойств: объекту Date (getStartDay()). Обычно я сравниваю их по item1.getStartDate().before(item2.getStartDate()), поэтому мне было интересно, смогу ли я написать что-то вроде:

public class CustomComparator {
    public boolean compare(Object object1, Object object2) {
        return object1.getStartDate().before(object2.getStartDate());
    }
}

public class RandomName {
    ...
    Collections.sort(Database.arrayList, new CustomComparator);
    ...
}

Ответы [ 25 ]

6 голосов
/ 03 января 2016

С Java 8 и далее нам не нужно использовать Collections.sort() напрямую. List интерфейс имеет метод по умолчанию sort() метод:

List<User> users = Arrays.asList(user1,user2,user3);
users.sort( (u1, u2) -> { 
return u1.getFirstName.compareTo(u2.getFirstName());}); 

См. http://visvv.blogspot.in/2016/01/sorting-objects-in-java-8.html.

5 голосов
/ 06 сентября 2016

Вы можете сортировать, используя Java 8

yourList.sort(Comparator.comparing(Classname::getName));

or

yourList.stream().forEach(a -> a.getBObjects().sort(Comparator.comparing(Classname::getValue)));
5 голосов
/ 09 сентября 2015

Java 8 Лямбда сокращает сортировку.

Collections.sort(stdList, (o1, o2) -> o1.getName().compareTo(o2.getName()));
5 голосов
/ 07 мая 2010

Вы можете использовать Bean Comparator для сортировки по любому свойству в вашем пользовательском классе.

5 голосов
/ 07 мая 2010

Да, это возможно, например, в этом ответе Я сортирую по свойству v класса IndexValue

    // Sorting by property v using a custom comparator.
    Arrays.sort( array, new Comparator<IndexValue>(){
        public int compare( IndexValue a, IndexValue b ){
            return a.v - b.v;
        }
    });

Если вы заметили здесь, я создаю анонимный внутренний класс (который является Java для замыканий) и передаю его непосредственно методу sort класса Arrays

Ваш объект также может реализовывать Comparable (это то, что делает String и большинство базовых библиотек в Java), но это определит «естественный порядок сортировки» самого класса и не позволит вам подключать новые. .

5 голосов
/ 17 марта 2013

Вы можете попробовать гуаву Заказ :

Function<Item, Date> getStartDate = new Function<Item, Date>() {
    public Date apply(Item item) {
        return item.getStartDate();
    }
};

List<Item> orderedItems = Ordering.natural().onResultOf(getStartDate).
                          sortedCopy(items);
4 голосов
/ 25 апреля 2012

Я обнаружил, что большинство, если не все эти ответы, полагаются на базовый класс (Object) для реализации сопоставимого или вспомогательного интерфейса.

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

Collections.sort(anArrayListOfSomeObjectPerhapsUsersOrSomething, new ReflectiveComparator(). new ListComparator("name"));

public class ReflectiveComparator {
    public class FieldComparator implements Comparator<Object> {
        private String fieldName;

        public FieldComparator(String fieldName){
            this.fieldName = fieldName;
        }

        @SuppressWarnings({ "unchecked", "rawtypes" })
        @Override
        public int compare(Object object1, Object object2) {
            try {
                Field field = object1.getClass().getDeclaredField(fieldName);
                field.setAccessible(true);

                Comparable object1FieldValue = (Comparable) field.get(object1);
                Comparable object2FieldValue = (Comparable) field.get(object2);

                return object1FieldValue.compareTo(object2FieldValue);
            }catch (Exception e){}

            return 0;
        }
    }

    public class ListComparator implements Comparator<Object> {
        private String fieldName;

        public ListComparator(String fieldName) {
            this.fieldName = fieldName;
        }

        @SuppressWarnings({ "unchecked", "rawtypes" })
        @Override
        public int compare(Object object1, Object object2) {
            try {
                Field field = object1.getClass().getDeclaredField(fieldName);
                field.setAccessible(true);
                Comparable o1FieldValue = (Comparable) field.get(object1);
                Comparable o2FieldValue = (Comparable) field.get(object2);

                if (o1FieldValue == null){ return -1;}
                if (o2FieldValue == null){ return 1;}
                return o1FieldValue.compareTo(o2FieldValue);
            } catch (NoSuchFieldException e) {
                throw new IllegalStateException("Field doesn't exist", e);
            } catch (IllegalAccessException e) {
                throw new IllegalStateException("Field inaccessible", e);
            }
        }
    }
}
3 голосов
/ 04 февраля 2013

Этот фрагмент кода может быть полезен. Если вы хотите отсортировать объект в моем случае я хочу отсортировать по VolumeName:

public List<Volume> getSortedVolumes() throws SystemException {
    List<Volume> volumes = VolumeLocalServiceUtil.getAllVolumes();
    Collections.sort(volumes, new Comparator<Volume>() {
        public int compare(Volume o1, Volume o2) {
            Volume p1 = (Volume) o1;
            Volume p2 = (Volume) o2;
            return p1.getVolumeName().compareToIgnoreCase(
                    p2.getVolumeName());
        }
    });
    return volumes;
}

Это работает. Я использую это в моем JSP.

3 голосов
/ 31 мая 2017

Новое, поскольку 1.8 - это метод List.sort () вместо использования Collection.sort (), поэтому вы напрямую вызываете mylistcontainer.sort ()

Вот фрагмент кода, который демонстрирует List.sort () функция:

List<Fruit> fruits = new ArrayList<Fruit>();
fruits.add(new Fruit("Kiwi","green",40));
fruits.add(new Fruit("Banana","yellow",100));
fruits.add(new Fruit("Apple","mixed green,red",120));
fruits.add(new Fruit("Cherry","red",10));

// a) using an existing compareto() method
fruits.sort((Fruit f1,Fruit f2) -> f1.getFruitName().compareTo(f2.getFruitName()));
System.out.println("Using String.compareTo(): " + fruits);
//Using String.compareTo(): [Apple is: mixed green,red, Banana is: yellow, Cherry is: red, Kiwi is: green]

// b) Using a comparable class
fruits.sort((Fruit f1,Fruit f2) -> f1.compareTo(f2));  
System.out.println("Using a Comparable Fruit class (sort by color): " + fruits);
// Using a Comparable Fruit class (sort by color): [Kiwi is green, Apple is: mixed green,red, Cherry is: red, Banana is: yellow]

Фруктовый класс:

public class Fruit implements Comparable<Fruit>
{
    private String name;
    private String color;
    private int quantity;

    public Fruit(String name,String color,int quantity)
    { this.name = name; this.color = color; this.quantity = quantity; }

    public String getFruitName() { return name; }        
    public String getColor() { return color; }  
    public int getQuantity() { return quantity; }

    @Override public final int compareTo(Fruit f) // sorting the color
    {
        return this.color.compareTo(f.color);
    }     
    @Override public String toString()
    {   
        return (name + " is: " + color);
    }
} // end of Fruit class   
3 голосов
/ 20 декабря 2016

Вы можете ознакомиться с этой презентацией на форуме Java в Штутгарте, Германия, в 2016 году.

Только несколько слайдов используют немецкий язык, 99% контента - это "исходный код Java" на английском языке; как

someCollection.sort(
  OurCustomComparator
    .comparing(Person::getName)
    .thenComparing(Person::getId)
);

где OurCustomComparator использует методы по умолчанию (и другие интересные идеи). Как показано, приведение к очень лаконичному коду для выбора метода получения для сортировки; и супер простое сцепление (или изменение) критериев сортировки.

Если вы знакомы с java8, вы найдете там много материала, с которого можно начать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...