使用来自不同类层次结构路由的两个字段进行map-filter lambda表达式

问题描述 投票:3回答:3

我们有一个方法,它在类层次结构的顶部接收类的对象。它使用基于层次结构中更深层的字段的条件,如果满足,则它使用构建器另一个字段,也可以在层次结构中更深的位置但在从顶级类开始的不同路径上。

public Optional<SomeType> create(final TopClassInHierarchy topClass) {
  Optional<SomeType> someObject = Optional.empty();
  if (someCondition.evaluate(getFieldOne(topClass))) {
      someObject = Optional.of(new SomeType.Builder()
              .withFieldTwo(getFieldTwo(topClass))
              .build());
  }
  return someObject;

private FieldOne getFieldOne(TopClassInHierarchy topClass) { return topClass.getSomething()...getFieldOne();
private FieldTwo getFieldTwo(TopClassInHierarchy topClass) { return topClass.getSomethingElse()...getFieldTwo();

我们希望最好将其浓缩为一个声明,如下所示

SomeType.Builder builder = new SomeType.Builder();
Optional.of(topClass)
        .map(this::getFieldOne)
        .filter(someCondition::evaluate)
        .map(this::getFieldTwo) //???
        .ifPresent(builder::withFieldTwo);

但是,一旦我们将topClass向下映射到fieldOne以进行条件评估,之后我们似乎无法“退回”到topClass以将其映射到构建器的fieldTwo。一个声明是否可行?

java lambda java-8 optional
3个回答
2
投票

如果认为这应该工作:

public Optional<SomeType> create(final TopClassInHierarchy topClass) {
  Builder builder = new Builder();

  return Optional.of(topClass)
    .filter(tc -> someCondition.evaluate(getFieldOne(tc)))
    .map(tc -> builder.withFieldTwo(getFieldTwo(tc)).build());
}

someCondition.evaluatefilter需要fieldOne作为输入,但是为了保持topClass作为Optional的当前状态,我们不mapfieldOne。而是使用方法getFieldOne。如果过滤器通过,我们可以将topClass映射到builder的结果,该fieldTwo应用于getFieldTwo方法检索的public Optional<SomeType> create(final TopClassInHierarchy topClass) { Builder builder = new Builder(); return Optional.of(topClass) .filter(tc -> someCondition.evaluate(getFieldOne(tc))) .map(this::getFieldTwo) .map(builder::withFieldTwo) .map(Builder::build); }

或者使用更多中间映射:

.map(x -> new SimpleEntry<>(this.getFieldOne(x), this.getFieldTwo(x)))
.filter(e -> evaluateTheCondition(e.getKey()))
.map(Entry::getValue)
.ifPresent(builder::withFieldTwo);

2
投票

你不应该说:

Optional.of(entity)
                .filter(p->someCondition.evaluate(p.getSomething().getFieldOne()))
                .map(this::getFieldTwo) 
                .ifPresent(builder::withFieldTwo);

2
投票

由于你不需要getFieldOne,你不应该映射到它,否则你无法回到另一个getFieldTwo的映射;我建议你首先使用没有方法引用的过滤器,如果它评估为真的映射tto getFieldTwo:

qazxswpoi
© www.soinside.com 2019 - 2024. All rights reserved.