哪种方法可以有效地分割嵌套对象列表的列表?java 8 flatmap vs是否适用于每个?

哪种方法可以有效地分割嵌套对象列表的列表?java 8 flatmap vs是否适用于每个?,java,foreach,java-8,java-stream,Java,Foreach,Java 8,Java Stream,我有一个终端对象: class Terminal{ List<TerminalPeriodApplicability> periods= new ArrayList<>(); //few other attributes //getters & setters } class TerminalPeriodApplicability{ String name; boolean isRequired; //g

我有一个
终端
对象:

class Terminal{

    List<TerminalPeriodApplicability> periods= new ArrayList<>();
    //few other attributes

    //getters & setters

}

class TerminalPeriodApplicability{

    String name;
    boolean isRequired;
    //getters & setters
}
我想根据
所需的
值,将
TerminalPeriodApplicability
的名称分为
可选的
必需的
集合
s

我试过两种方法。一个带有两个
forEach
,另一个带有
flatMap

List<Terminal> terminals= getTerminals();
Set<String> mandatoryPeriods = new HashSet<>();
Set<String> optionalPeriods = new HashSet<>();
方法2:

List<TerminalPeriodApplicability> applicablePeriods = terminals
                .stream()
                .flatMap(terminal -> terminal.getApplicablePeriods().stream())
                .collect(Collectors.toList());

applicablePeriods.forEach(period->{
    if(period.getIsRequired())
        mandatoryPeriods.add(period.name());
    else
        optionalPeriods.add(period.name());
});
List applicatableperiods=终端
.stream()
.flatMap(终端->终端.getApplicatablePeriods().stream())
.collect(Collectors.toList());
适用期间。forEach(期间->{
if(period.getIsRequired())
添加(period.name());
其他的
optionalPeriods.add(period.name());
});

我想知道哪种方法在时间和空间复杂性方面更有效。或者有更好的解决方案吗?

您可以在
flatMap
版本中使用不同的终端操作,而不是
toList
,并避免使用第二个
forEach

Map<Boolean,List<TerminalPeriodApplicability>> periods = terminals
            .stream()
            .flatMap(terminal -> terminal.getApplicablePeriods().stream())
            .collect(Collectors.partitioningBy(TerminalPeriodApplicability::getIsRequired);

您可以在
flatMap
版本中使用不同的终端操作-
partitioningBy
而不是
toList
-并避免使用第二个
forEach

Map<Boolean,List<TerminalPeriodApplicability>> periods = terminals
            .stream()
            .flatMap(terminal -> terminal.getApplicablePeriods().stream())
            .collect(Collectors.partitioningBy(TerminalPeriodApplicability::getIsRequired);

正确答案是这样的
Map periods=terminals.stream().flatMap(terminals->terminals.getApplicatePeriods().stream()).collect(收集器.partitionBy(TerminalPeriodApplicability::getIsRequired,CollectorOre.mapping)(TerminalPeriodApplicability::getName,收集器.toSet())
@HadiJ噢,我没有注意到OP把名称
字符串
放在集合中。谢谢。我会解决的。哇。太好了!我对按方法划分不太了解。谢谢@Eran&HadiJ正确的答案是
映射周期=terminals.stream().flatMap(terminal->terminals.getapplicatableperiods()).stream()).collect(收集器.partitionBy(TerminalPeriodApplicability::getIsRequired,Collectore.mapping(TerminalPeriodApplicability::getName,Collectors.toSet()))
@HadiJ噢,我没有注意到OP把名称
String
s放在集合中。谢谢。我会解决的。哇。太好了!我对按方法划分不太了解。谢谢@Eran&HadiJ
forEach
方法可以简化为
terminals.forEach(terminal->terminal.getapplicatableperiods()。forEach(period->(period.getIsRequired()?mandatoryPeriods:optionalPeriods).添加(period.name());
,但是,流方法看起来更干净,
forEach
方法可以简化为
terminals.forEach(terminal->terminals.getapplicatableperiods().forEach(period->(period.getIsRequired()?mandatoryPeriods:optionalPeriods).add(period.name());
,但是,流方法看起来更干净…
Map<Boolean,Set<TerminalPeriodApplicability>> periods = terminals
            .stream()
            .flatMap(terminal -> terminal.getApplicablePeriods().stream())
            .collect(Collectors.partitioningBy(TerminalPeriodApplicability::getIsRequired,
                                               Collectors.toSet());
Map<Boolean,Set<String>> periods = terminals
            .stream()
            .flatMap(terminal -> terminal.getApplicablePeriods().stream())
            .collect(Collectors.partitioningBy(TerminalPeriodApplicability::getIsRequired,
                                               Collectors.mapping(TerminalPeriodApplicability::name,
                                                                  Collectors.toSet()));