#java #lambda #java-8 #java-stream
#java #лямбда #java-8 #java-поток
Вопрос:
У меня есть List<Entry> entries
, с приведенной ниже структурой кода,
class Entry {
public Product getProduct() {
return product;
}
}
class Product {
public List<CategoriesData> getCategories() {
return categoriesData;
}
}
class CategoriesData {
public String getName() {
return name;
}
}
Я рассматриваю сортировку по Product — CategoriesData — name (из первого элемента в List<CategoriesData>
)
// Not sure how to refer Name within CategoriesData,
// entries.stream().sorted(
// Comparator.comparing(Entry::getProduct::getCategories::getName))
// .collect(Collectors.toList())
Комментарии:
1. Хорошо, не уверен, что это будет за сравнение, но вы можете добиться этого с помощью
Comparator.comparing(a -> a.getProduct().getCategories().get(0).getName())
.2.
.get(0)
ты уверен?? Это не очень хорошая практика: p3. @Naman Я получаю ошибку «Метод getProduct () не определен для типа Object», в чем может быть причина?
4. @SyAu надеюсь, у вас есть поток записей, как в вопросе, и тогда на самом деле это не должно заканчиваться упомянутой ошибкой.
Ответ №1:
Используя решение Mureinik, вы можете сделать:
Comparator<Entry> entryComperator = Comparator
.comparing(e -> e.getProduct().getCategories().get(0).getName());
List<Entry> sorted =
entries.stream()
.sorted(entryComperator)
.collect(Collectors.toList());
Вы могли бы рассмотреть возможность доступа к имени из списка, если список пуст. вы можете скрыть всю эту логику в компараторе, как я сделал выше
Ответ №2:
Если вы пытаетесь выполнить сортировку по первой категории, вам нужно обратиться к ней в компараторе:
List<Entry> sorted =
entries.stream()
.sorted(Comparator.comparing(
e -> e.getProduct().getCategories().get(0).getName())
.collect(Collectors.toList())
Редактировать:
Чтобы ответить на вопрос в комментариях, для вторичной сортировки вам нужно будет указать тип в Comparator
:
List<Entry> sorted =
entries.stream()
.sorted(Comparator.comparing(
e -> e.getProduct().getCategories().get(0).getName())
.thenComparing(
(Entry e) -> e.getProduct().getName())
.collect(Collectors.toList())
Комментарии:
1. Спасибо. Я получаю сообщение об ошибке с сообщением о том, что «Метод getProduct() не определен для объекта типа» . В ‘Entry’ получен метод ‘getProduct’, но он выдает ошибку.
2. @SyAu Какой это тип
entries
?3. ‘entries’ — это массив, содержащий список объектов ‘Entry’
4. @SyAu Make вы собираете результат в
List<Entry>
так же, как и в ответе. Учитывая, что в вопросе это неизвестно.5. @Mureinik Я протестировал сортировку по названию категории, и это сработало. Теперь я хотел добавить еще одно поле сортировки, Comparator.comparing(e -> e.getProduct().GetCategories().stream().findFirst().get().getName()) .thenComparing(e -> e.getProduct().getName())) , это выдает ошибку.
Ответ №3:
Благодаря вводу от @Mureinik и внесению некоторых изменений, я получил приведенное ниже, и оно работает. Мое требование немного изменилось, мне нужен результат в виде карты. Название категории является ключом на карте, значением будет список ‘Entry’.
final Map<String, List<Entry>> sortedMap =
data.getEntries().stream()
.sorted(Comparator.comparing(e -> ((Entry) e).getProduct().getCategories().stream().findFirst().get().getName())
.thenComparing(Comparator.comparing(e -> ((Entry) e).getProduct().getName())) )
.collect(Collectors.groupingBy(e -> e.getProduct().getCategories().stream().findFirst().get().getName(),
LinkedHashMap::new, Collectors.toList()));