【问题标题】:Split a Collection(using java 8 streams) into smaller components based on different parameters根据不同的参数将集合(使用 java 8 流)拆分为更小的组件
【发布时间】:2017-08-29 04:31:58
【问题描述】:

这是这个问题的延续Java 8 stream compare two objects and run a function on them

Class BigRequest{
    String bId;
    List<Parts> parts;
    //getters and setter here
    }

Class Parts{
String pId;
String partId;
//getters and setter here
}

我的问题是根据一些动态参数将集合(使用 java 8 流)拆分为更小的组件。 动态参数可以根据传递给方法 splitParts 的不同条件(在这里,我给出的示例为 getPartId() 相同)而变化,其返回类型是 List of Set of Parts

List<Set<Parts>> splitParts(BigRequest big){}

我尝试了以下方法:

 //groupingBy function but that returns a Map 
   Map<String, List<Parts>> parts = big.getParts().stream().collect(Collectors.groupingBy(Parts::getPartId));

//doesn't do it accurately
    big.getParts().stream().filter(p -> p.getPartId.equals(p.getPartId())).collect();

如何根据动态参数拆分流(可能通过在 reduce 方法上调用功能接口),然后在其上运行方法?

我的函数的签名是

List<Set<Parts>> splitParts(BigObject b){}

我认为做这样的事情可能有助于保持分裂条件的动态,但我不知道该怎么做?

 big.getParts().stream().reduce(MyFuncInterface::divide);

然后使用 forEach(),我想我可以遍历 List 并调用 abc() 方法。

我怎样才能做得更好?

非常感谢这里的任何帮助。

【问题讨论】:

  • 这个很不清楚。 BigObject 和 Parts 是什么样的,你的 splitParts 方法应该做什么。与此类方法的 javadoc 一样精确。
  • 你的 splitParts 方法应该做什么?与此类方法的 javadoc 一样精确。
  • 我同意@JBNizet 的观点,即您的问题非常不清楚。 “动态参数”、“基于输入类型的更改”、“通过 reduce 方法调用功能接口”是什么意思?这些短语都没有多大意义。如果您需要一些有效的帮助,您需要重新表述您的问题以减少歧义。
  • ListSets 的顺序是什么?如果它是无序的,那么您希望结果是 CollectionSets
  • @f.khantsis 我想要集合列表因为我想稍后索引元素。

标签: java java-8 java-stream


【解决方案1】:

如果您想要List&lt;Set&lt;Parts&gt;&gt;,请先更改您的代码以获取Map&lt;String, Set&lt;Parts&gt;&gt;

Map<String, Set<Parts>> parts = big.getParts().stream().collect(
        Collectors.groupingBy(Parts::getPartId, Collectors.toSet()));

调用parts.values() 将返回Collection&lt;Set&lt;Parts&gt;&gt;,因此将Collection 转换为List

List<Set<Parts>> list = new ArrayList<>(parts.values());

或者你可以重新流式传输它,这样你就可以在一个调用链中完成它:

List<Set<Parts>> list = big.getParts()
                           .stream()
                           .collect(Collectors.groupingBy(Parts::getPartId,
                                                          Collectors.toSet()))
                           .values()
                           .stream()
                           .collect(Collectors.toList());

【讨论】:

  • 动态以什么方式? Collectors.groupingBy() 需要 Function&lt;Parts,String&gt; 作为第一个参数。您可以声明该类型的变量并为其分配任何兼容的方法引用、lambda 表达式或匿名实现。
  • 您为什么“假设复杂性会非常高”?整个操作是O(n).
  • @user2340345:你能停止使用“动态”这个词,只描述你想要做什么吗?
  • @user2340345 你可以按照你想要的任何方式进行分区,只要你能想出一个定义分区的String 值。映射到相同String 值的所有Parts 将位于同一分区中,正如您提供给groupingByFunction&lt;Parts,String&gt; 所映射的那样。
  • 实际上,使用单链变体,甚至没有对组标准类型的依赖,所以任何Function&lt;Parts,?&gt; 都可以;不再需要生成String。在两步变体中,您必须将映射声明更改为 Map&lt;?, Set&lt;Parts&gt;&gt; parts 以独立于组标准类型。然后,它也可以接受任何Function&lt;Parts,?&gt;
猜你喜欢
  • 2022-06-12
  • 2017-12-11
  • 2011-09-16
  • 1970-01-01
  • 2016-09-23
  • 1970-01-01
  • 2021-03-28
  • 1970-01-01
  • 2019-03-26
相关资源
最近更新 更多