others - 在Java 8中有什么方法可以使用Stream Map Filter&映射回原始对象?

是否可以将list --

如果我们使用下面的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());



时间:

试试这个


List<Query> finalQueries = updatedQueries


 .stream().filter(query->{


 Period period = getPeriodRequest(query);


 return periodService.validatePeriodicity(period )&& isMandatory(period))


 })


 .collect(Collectors.toList());



你可以将filter展开为:


 List<Query> finalQueries = updatedQueries


 .stream()


 .filter(query -> {


 Period period = getPeriodRequest(query);


 return periodService.validatePeriodicity(period) && isMandatory(period);


 })


 .collect(Collectors.toList());



首先,由于map(this::getPeriodRequest)的原因,你的实际结果是List<Period> finalQueries类型。 只需使用一些"更长的"lambdas:


 updatedQueries.stream()


 .filter(q -> periodService.validatePeriodicity(q.getPeriodRequest()))


 .filter(q -> isMandatory(q.getPeriodRequest()))


 .collect(Collectors.toList())



你甚至可以将这两个filter压缩成一个,并且只读一次,如果你真的想。

或者,你可以映射到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());



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

像这样


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



为什么Stream在第一个地方使用?


updatedQueries.removeIf(query-> {


 Period period = getPeriodRequest(query);


 return !periodService.validatePeriodicity(period) || !isMandatory(period));


});



这将删除updatedQueries中与筛选器不匹配的所有元素,行为相同,但是,不引入新的List

最好的方法可能只使用一个简单的for -loop,如果你关心性能:


for (Iterator<Query> it = updatedQueries.iterator(); it.hasNext(); ) {


 Period period = getPeriodRequest(it.next());


 if(!periodService.validatePeriodicity(period) || !isMandatory(period))) {


 it.remove();


 }


}



...