Nós temos um método que recebe um objeto da classe no topo da hierarquia de classes. Ele usa uma condição baseada em um campo em algum lugar mais profundo na hierarquia, e se isso é preenchida, então ele usa para um construtor de outro campo também em algum lugar mais profundo na hierarquia, mas em uma rota diferente a partir da classe.
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();
Nós gostaríamos de condensar preferência isso em uma instrução, algo como isto
SomeType.Builder builder = new SomeType.Builder();
Optional.of(topClass)
.map(this::getFieldOne)
.filter(someCondition::evaluate)
.map(this::getFieldTwo) //???
.ifPresent(builder::withFieldTwo);
No entanto, uma vez que o mapa topclass até FieldOne para a avaliação condição, depois a gente não parecem ser capazes de "passo para trás" para topclass para mapeá-lo para baixo para fieldTwo para o construtor. É este viável com uma declaração?
Se acha que isso deve funcionar:
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.evaluate
em filter
necessidades fieldOne
como entrada, mas para manter topClass
como o estado atual do Optional
que não fazer map
para fieldOne
. Em vez disso, o método getFieldOne
é usado. Se o filtro é passado podemos mapear topClass
para o resultado do builder
aplicado em fieldTwo
recuperada pelo método getFieldTwo
.
Ou com mapeamentos mais intermediários:
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);
}