Java 8-流-引用复合对象

时间:2019-04-03 04:42:05

标签: java lambda java-8 java-stream

我有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;
    }
}

我正在查看按产品-CategoriesData-名称(从List<CategoriesData>的第一个元素开始)

// Not sure how to refer Name within CategoriesData, 
// entries.stream().sorted(
//   Comparator.comparing(Entry::getProduct::getCategories::getName))
//                      .collect(Collectors.toList())

3 个答案:

答案 0 :(得分:0)

如果您要按第一类进行排序,则需要在比较器中引用它:

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 :(得分:0)

您可以使用Mureinik解决方案:

Comparator<Entry> entryComperator = Comparator
                .comparing(e -> e.getProduct().getCategories().get(0).getName());
        List<Entry> sorted =
                entries.stream()
                        .sorted(entryComperator)
                        .collect(Collectors.toList());

在列表为空的情况下,您可以考虑从列表中更好地访问名称。您可以像上面一样在比较器中隐藏所有这些逻辑

答案 2 :(得分:0)

使用@Mureinik的输入并进行了一些修改,我最终在下面进行了工作。我的要求略有变化,我需要在地图中显示结果。类别名称是地图中的键,值将是“条目”的列表。

 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()));