【问题标题】:Java 8 - Stream - refer composite objectsJava 8 - Stream - 引用复合对象
【发布时间】:2019-04-03 04:42:05
【问题描述】:

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

我正在查看按产品排序 - 类别数据 - 名称(从 List&lt;CategoriesData&gt; 中的第一个元素开始)

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

【问题讨论】:

  • 好吧,不知道会是怎样的比较,但是你可以使用Comparator.comparing(a -&gt; a.getProduct().getCategories().get(0).getName())来实现。
  • .get(0) ,你确定??这不是一个好习惯:p
  • @Naman 我收到“对象类型的方法 getProduct() 未定义”错误,可能是什么原因?
  • @SyAu 希望您有问题中的条目流,然后它不应该真的以提到的错误结束。

标签: java lambda java-8 java-stream


【解决方案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())
    

    编辑:
    要回答 cmets 中的问题,对于二次排序,您必须在 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())
    

    【讨论】:

    • 谢谢。我收到错误 'The method getProduct() is undefined for the type Object' 。 'Entry' 有 'getProduct' 方法,但它抛出错误。
    • @SyAu entries 是什么类型?
    • 'entries' 是一个 'Entry' 对象的数组列表
    • @SyAu 让您在List&lt;Entry&gt; 以及答案中收集结果。鉴于,这是问题中的未知数。
    • @Mureinik 我测试了按类别名称排序并且它有效。现在我想再添加一个排序字段 Comparator.comparing(e -> e.getProduct().getCategories().stream().findFirst().get().getName()) .thenComparing(e -> e .getProduct().getName())) ,这是抛出错误。
    【解决方案3】:

    通过@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())); 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-26
      相关资源
      最近更新 更多