我想知道是否有一种好方法可以重用最终针对不同输出而变化的公共(public)流操作。 下面的示例正是我试图压缩为一步操作的示例:
public static DepartmentInfo extractDepartmentInfo(BaselinePolicy resource) throws ResourceProcessorError {
Function<Exception, Exception> rpe = e -> new ResourceProcessorError(e.getMessage());
List<String> parents =
Objects.requireNonNull(
Exceptions.trying(
() -> Arrays.asList(Exceptions.dangerous(resource::getParentIds).expecting(CMException.class).throwing(rpe))
.stream()
.map(cId -> Exceptions.dangerous(cId, resource.getCMServer()::getPolicy).expecting(CMException.class).throwing(rpe))
.filter(policy -> PagePolicy.class.isAssignableFrom(policy.getClass()))
.map(PagePolicy.class::cast)
.filter(page -> Exceptions.dangerous(page,
p -> Boolean.valueOf(p.getComponentNotNull(ComponentConstants.POLOPOLY_CLIENT,
ComponentConstants.IS_HOME_DEPARTMENT,
Boolean.FALSE.toString())).booleanValue())
.expecting(CMException.class).throwing(rpe))
.map(page -> Exceptions.dangerous(page, p -> p.getExternalId().getExternalId()).expecting(CMException.class).throwing(rpe)), ResourceProcessorError.class)
.collect(Collectors.toList()));
String externalId = parents.get(parents.size()-1).toString();
List<String> list =
Objects.requireNonNull(
Exceptions.trying(
() -> Arrays.asList(Exceptions.dangerous(resource::getParentIds).expecting(CMException.class).throwing(rpe))
.stream()
.map(cId -> Exceptions.dangerous(cId, resource.getCMServer()::getPolicy).expecting(CMException.class).throwing(rpe))
.filter(policy -> PagePolicy.class.isAssignableFrom(policy.getClass()))
.map(PagePolicy.class::cast)
.map(page ->
Exceptions.dangerous(page,
p -> p.getChildPolicy(PATH_SEGMENT) != null &&
StringUtils.hasLength(SingleValued.class.cast(p.getChildPolicy(PATH_SEGMENT)).getValue())?
SingleValued.class.cast(p.getChildPolicy(PATH_SEGMENT)).getValue(): p.getName()).expecting(CMException.class).throwing(rpe))
.filter(val -> val != null && !val.isEmpty()), ResourceProcessorError.class)
.collect(Collectors.toList()));
if(list.size() > 3) {
list = list.subList(list.size() - 3, list.size()-1);
}
switch(list.size()) {
case 0: {
throw new ResourceProcessorError("br.com.oesp.XMLRender.error.noProduct");
}
case 1: {
return DepartmentInfo.withProduct(list.get(0), externalId);
}
case 2: {
return DepartmentInfo.withProduct(list.get(0), externalId).withDepartment(list.get(1));
}
default: {
return DepartmentInfo.withProduct(list.get(0), externalId).withDepartment(list.get(1)).withSubDepartment(list.get(2));
}
}
}
请注意,两者都重复第一步:
List<String> parents =
Objects.requireNonNull(
Exceptions.trying(
() -> Arrays.asList(Exceptions.dangerous(resource::getParentIds).expecting(CMException.class).throwing(rpe))
.stream()
.map(cId -> Exceptions.dangerous(cId, resource.getCMServer()::getPolicy).expecting(CMException.class).throwing(rpe))
.filter(policy -> PagePolicy.class.isAssignableFrom(policy.getClass()))
.map(PagePolicy.class::cast)
这不仅是阅读上的问题,而且特别是因为我要重做两次繁重的操作,同时以更命令的方式我会做一次。
最佳答案
您正在尝试做两件事:
- 避免创建输入数组的冗余工作
- 避免map/filter/map的冗余代码
第一个很简单:
List<Id> list = Arrays.asList(Exceptions.dangerous(resource::getParentIds)
.expecting(CMException.class)
.throwing(rpe));
现在,您可以从该源提取流两次,而无需重新实现它。
下一位只是一个从列表到流的函数:
Function<List<Id>, Stream<Something>> asStream =
list -> list.stream().map(...).filter(...).map(...);
现在,只需这样开始您的直播:
asStream.apply(list).moreStuff().moreStuff()
关于java - 重用部分流映射和过滤来组成两个不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31172888/