1

I have this aggregate converter:

public O convert() {
    output = getOutput();

    final List<GenericConverterBase> converters = getConverters();

    for (GenericConverterBase converterBase : converters) {
        output = (O) Optional.ofNullable(converterBase.getInput()).map(converterBase::apply).orElse(output);
    }

    return output;
}

Basically, the getConverters() return a list of converters that have a concrete implementation of the apply in with they fill a common kind of object (let's say OutputDTO).

This works, however I have 2 issues:

  1. Is it possibile to transform for each loop using a java 8 functional method?

Premise: Actually the output is filled with new properties and keep the old ones, i.e. the second time the loop call the converter.apply() the output will be a result of the second and the previous one.

  1. I needed to cast to (O) within the loop, otherwise java doesn't compile because it say "required O, found Object". By applying the cast (O) I solved the issue, btw compiler warn me of the "unchecked cast". Any chance to solve in other way ?
3
  • 3
    Question: Why don't you choose the last element from converters to assign it(after mapping) to the output variable? What is the iteration even required for? It would be worth sharing the implementations relevant to the question for the classes GenericConverterBase and O (not assuming it to be a generic here). Commented Sep 3, 2019 at 8:37
  • That's probably because he wants to "not touch" the output if the input is null Commented Sep 3, 2019 at 8:46
  • 1
    @m.antkowicz that doesn’t explain anything. Searching for the last occurrence of a non-null input has the same effect, but does much less work. Commented Sep 3, 2019 at 9:32

1 Answer 1

2

You can use stream like this, to fetch inputs and filter them out before processing

output = getOutput();
emptyIfNull(getConverters())
    .stream()
    .map(GenericConverterBase::getInput)
    .filter(Objects::nonNull)
    .forEach(input -> output = input.apply(output)); // here I suppose you will need to provide casting to O
return output;

About casting - the question is what your apply method is returning - if Object you must cast, if not you can make converters generic, operating on the same type of O super class/interface and infer this type to the convert method

Sign up to request clarification or add additional context in comments.

1 Comment

There is no need for inserting a questionable emptyIfNull(…) that wasn’t in the original code. Besides that, this code only works if output is a field, i.e. not a local variable. Since this is repeatedly overwriting output, which boils down to using the last occurrence, a clean solution would be output = getConverters() .stream().map(GenericConverterBase::getInput).filter(Objects::nonNull).map(converterBase ::apply).reduce((a,b) -> b) .orElse(getOutput());

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.