2016-09-19 2 views
3

Я работаю над тем, что требует от меня сортировки объектов (безалкогольных напитков) по трем атрибутам - name (str), colour (str) и volume (int). Я исследовал и нашел способы упорядочить их по имени и цвету и объему отдельно, но есть ли способ упорядочить их всеми тремя?Сортировка объектов по нескольким атрибутам

я имею в виду: например, говорят, что есть четыре Softdrink объекты: Fanta Orange 500, Кокс Красный 500, Кокс Серебро 500 Fanta Orange 400.

Выход Я ищу бы:

  • 1) Кокс Красный 500
  • 2) Кокс Серебро 500
  • 3) Фанта оранжевый 400
  • 4) Фанта оранжевый 500

Сортировка по названию сначала, затем цвет, затем объем (по возрастанию).

В настоящее время я использую три компаратора: nameComparator, colourComparator и volumeComparator, но каждый из них сортирует объекты только по имени, а затем только по цвету, а затем по объему. Можно ли сортировать по нескольким атрибутам с помощью компаратора?

+0

Подсказка: было прекрасное представление о том, что этим летом: http://2016.java-forum-stuttgart.de/_data/D4_Wiedeking.pdf ... некоторый немецкий текст на некоторых из фольг, но в основном источник java примеры кода. Эта вещь берет лямбды и сравнивает материал ... на следующий уровень. – GhostCat

+0

@GhostCat Эта ссылка не работает для меня:/она просто забирает меня на домашнюю страницу. –

+0

Отвечает также на домашнюю страницу, но если у вас есть ссылка, не стесняйтесь публиковать ее. Было бы определенно интересно узнать о сравнении вещей более подробно :) –

ответ

12

попробовать что-то вроде этого:

drinks.sort(
     Comparator.comparing(Drink::getName).thenComparing(Drink::getColour).thenComparing(Drink::getVolume) 
    ); 

Помните, чтобы иметь добытчиками для ваших атрибутов (getName, getColour и т.д.). Это все, что вам нужно, нет необходимости в каких-либо специализированных компараторах или что-то еще.

+3

Последний тип - 'int', поэтому вы можете использовать' thenComparingInt', чтобы избежать бокса. –

+0

Работал отлично. Благодаря! –

1

Alex!

Отвечая на Ваш вопрос о заказе объектов по нескольким атрибутам с компаратором Вот ссылка на Java учебник по упорядочению объектов: https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html

В частности, существует пример компаратора, который первым сравнивает объекты по дате, а затем (в случае равенства) сравнивает их по номеру:

static final Comparator<Employee> SENIORITY_ORDER = 
             new Comparator<Employee>() { 
    public int compare(Employee e1, Employee e2) { 
     int dateCmp = e2.hireDate().compareTo(e1.hireDate()); 
     if (dateCmp != 0) 
      return dateCmp; 

     return (e1.number() < e2.number() ? -1 : 
       (e1.number() == e2.number() ? 0 : 1)); 
    } 
}; 

Это легко применить этот шаблон к вашему случаю:

static final Comparator<SoftDrink> DRINKS_ORDER = new Comparator<SoftDrink>() { 
    public int compare(SoftDrink d1, SoftDrink d2) { 
     int nameCmp = d1.getName().compareTo(d2.getName()); 
     if (nameCmp != 0) { 
      return nameCmp; 
     } 
     int colorCmp = d1.getColor().compareTo(d2.getColor()); 
     if (colorCmp != 0) { 
      return colorCmp; 
     } 
     return d1.getVolume() < d2.getVolume() ? -1 : (d1.getVolume() == d2.getVolume() ? 0 : 1); 
    } 
}; 

Обязательно проверьте значения для нулей (если необходимо) перед вызовом метода compareTo.

Смежные вопросы