有什么方法可以将流图过滤器和映射返回Java 8中的原始对象?

时间:2019-05-08 06:10:07

标签: java java-8 java-stream

有什么方法可以播放列表->映射->过滤器->映射回列表的原始对象类型?

如果我们使用如下所示的foreach进行操作,则有解决方案:

List<Query> updatedQueries = getUpdatedQueries();

List<Query> finalQueries = new ArrayList<>();
updatedQueries.forEach(query -> {

    Period period = getPeriodRequest(query);
    boolean isValidPeriod = periodService.validatePeriodicity(period);
    if(isValidPeriod &&  isMandatory(period)){
        finalQueries.add(query);
    }

});

但是有什么方法可以使用以下方法吗?

List<Query> updatedQueries = getUpdatedQueries();

List<Query> finalQueries = updatedQueries
        .stream()
        .map(this::getPeriodRequest) //returns the object of type Period
        .filter(period->periodService.validatePeriodicity(period))
        .filter(this::isMandatory)
        //is any way we can map back to Query object (without any object translation  function)
        .collect(Collectors.toList());

5 个答案:

答案 0 :(得分:7)

尝试这个

List<Query> finalQueries = updatedQueries
    .stream().filter(query->{
        Period period = getPeriodRequest(query);
        return periodService.validatePeriodicity(period )&& isMandatory(period))
    })
    .collect(Collectors.toList());

答案 1 :(得分:5)

您可以将filter展开为:

    List<Query> finalQueries = updatedQueries
            .stream()
            .filter(query -> {
                Period period = getPeriodRequest(query);
                return periodService.validatePeriodicity(period) && isMandatory(period);
            })
            .collect(Collectors.toList());

答案 2 :(得分:1)

首先,由于该List<Period> finalQueries,您的实际结果是map(this::getPeriodRequest)类型。只需使用一些“更长的” lambda:

 updatedQueries.stream()
               .filter(q -> periodService.validatePeriodicity(q.getPeriodRequest()))
               .filter(q -> isMandatory(q.getPeriodRequest()))
               .collect(Collectors.toList())

您甚至可以将这两个filter压缩为一个,并且如果确实愿意,只能读取一次q.getPeriodRequest()

例如,您也可以映射到SimpleEntry

 updatedQueries.stream()
               .map(x -> new SimpleEntry<>(x, x.getPeriodRequest()))
               .filter(e -> periodService.validatePeriodicity(e.getValue()))
               .filter(e -> isMandatory(e.getValue()))
               .map(Entry::getKey)
               .collect(Collectors.toList());

答案 3 :(得分:0)

不。您必须以某种方式存储原始对象。

class Pair<A, B> {
    A a;
    B b;
    // constructors and getters skipped
}

然后您可以执行以下操作:

list.stream()
   .map(x -> new Pair<>(x, getOtherObject()))
   .filter(x -> checkOther(x.getB()))
   .map(Pair::getA)
   .collect(Collectors.toList());

答案 4 :(得分:0)

为什么首先使用Stream

updatedQueries.removeIf(query-> {
    Period period = getPeriodRequest(query);
    return !periodService.validatePeriodicity(period) || !isMandatory(period));
});

这将从updatedQueries中删除所有与过滤器不匹配的元素。行为相同,但未引入新的List

如果您关心性能,最好的方法可能只是使用一个简单的for循环:

for (Iterator<Query> it = updatedQueries.iterator(); it.hasNext(); ) {
    Period period = getPeriodRequest(it.next());
    if(!periodService.validatePeriodicity(period) || !isMandatory(period))) {
        it.remove();
    }
}