Karl Alexander
Karl Alexander

Reputation: 371

Java 8 streams.reduce() with combiner

My question is that i would like a breakdown of the following code

I have a map and i want to replace certain strings with the map's value with the following reduce() function:

Map<String, String> environmentMap = new HashMap<>();

Function<String, String> replaceFunction = environmentMap.entrySet()
.stream()
.reduce
(Function.identity(),
(function,entrySet) -> stringToReplace -> function.apply(stringToReplace.replaceAll(entrySet.getKey(),entrySet.getValue(),
Function::andThen);

Somehow i'm confused on the replaceFunction part but let me break it down based on my understanding.

  1. The line environmentMap.entrySet().stream() will create a stream of Entry<String,String>.
  2. The reduce() method that i am using takes an identity, accumulator, and a combiner.
  3. Since i am not using a parallel stream i thought of omitting the combiner, but then the compiler throws an error. Is there any way that i could transform this accumulator into a BinaryOperator<T>?
  4. Function.identity() will always return a Function that returns the input argument. In this case of type String
  5. The second argument which intakes a BiFunction is one of the things i'm confused with. (function,entrySet) -> stringToReplace -> function.apply(stringToReplace.replaceAll(entrySet.getKey(),entrySet.getValue().
  6. What does Function::andThen do in this process?
  7. Lastly, where did the return type Function<String,String> in the BiFunction<T, U, R> came from??

Upvotes: 1

Views: 2151

Answers (1)

Alanpatchi
Alanpatchi

Reputation: 1199

Function<String, String> replaceFunction = environmentMap.entrySet()
            .stream()
            .reduce(Function.identity(),
                    (function,entrySet) -> stringToReplace -> function.apply(stringToReplace.replaceAll(entrySet.getKey(),entrySet.getValue())),
                            Function::andThen);
  1. The line environmentMap.entrySet().stream() will create a stream of Entry<String,String>.
  2. The reduce() method that i am using takes an identity, accumulator, and a combiner.item.

    Till this you are right, but the identity, accumulator, and combiner gets resolved as follows:

    • identity - Function.identity() gets resolved to Function<String, String>.
    • accumulator - (function,entrySet) -> stringToReplace -> function.apply(stringToReplace.replaceAll(entrySet.getKey(),entrySet.getValue())).

      Here the following part,

      `stringToReplace -> function.apply(stringToReplace.replaceAll(entrySet.getKey(),entrySet.getValue()))` 
      

      gets resolved into Function<String, String>.

      And so this entire accumulator gets resolved to

      `BiFunction<Function<String,String>, Entry<String,String>,Function<String,String>`
      
    • combiner - Function::andThen gets resolved to BinaryOperator<Function<String,String>, Function<String,String>>

So, to answer your question in 6 and 7, Function::andThen acts as the combiner; and 7 is the accumulator as I described above.

Upvotes: 1

Related Questions