Question: I have already look at [this questions](https://stackoverflow.com/questions/36172502/replace-string-with-hashmap-value-using-java-8-stream), but my problem is a little different.

I have a "baseString", n HashMap and an output string.
I want to fill the baseString with the hashmap, to construct a json call parameters.

I have already done it with Java 7, in this way:

```
HashMap<String,Integer> element= getAllElement();

String baseElem="{\"index\":{}}\r\n" + 
        "{\"name\":\"$name$\",\"age\":$age$}";

String result=baseElem;

for (Map.Entry<String, Integer> entry : element.entrySet()) {

    result=result.replace("$name$", entry.getKey());
    result=result.replace("$age$", entry.getValue().toString());
    result=result+baseElem;
}
result= result.replace(baseElem, "");

```

Now I want to the same with Java 8,
I have tried in this way:

```
element.forEach((k,v)->{
            result=result.replaceAll("$name$", k);
            result=result.replaceAll("$age$", v.toString());
            result=result+baseElem;
        });

```

But for each result I have an error 

> 
> "Local variable result defined in an enclosing scope must be final or
>  effectively final"
> 
> 
> 

So the question is: I can do that in some kind of way with Java 8 and streams? Or there is no way, and so I can use the simple Java 7 `for`?

Answer: 
As for *"Local variable result defined in an enclosing scope must be final or effectively final"* see [this](https://stackoverflow.com/questions/34865383/variable-used-in-lambda-expression-should-be-final-or-effectively-final) answer for further explanation.

As for:

> 
> So the question is: I can do that in some kind of way with Java 8 and
>  streams? Or there is no way, and so I can use the simple Java 7 for?
> 
> 
> 

The logic you're performing with the iterative approach is known as "fold" or "reduce" in the functional world i.e. streams. 

So, what you want to do is:

```
String result = element.entrySet()
                .stream()
                .reduce(baseElem,
                        (e, a) -> e.replace("$name$", a.getKey()).replace("$age$",
                                a.getValue().toString()),
                        (x, y) -> {
                            throw new RuntimeException();
                        });

```

the third input argument to `reduce` is known as the combiner function which should be an *associative, non-interfering, stateless function for combining two values, which must be compatible with the accumulator function*.

if you don't plan on using a parallel stream then the current logic should suffice otherwise you'll need to replace `(x, y) -> {...}` with the actual logic.
It think, you could use this one:

```
private static Map<String, Integer> getAllElement() {
    Map<String, Integer> map = new HashMap<>();
    map.put("\\$name\\$", 666);
    map.put("\\$age\\$", 777);
    return map;
}

Map<String, Integer> map = getAllElement();
String[] json = { "{\"index\":{}}\r\n{\"name\":\"$name$\",\"age\":$age$}" };

map.forEach((key, val) -> json[0] = json[0].replaceAll(key, String.valueOf(val)));
System.out.println(json[0]);

```

**Output:**

```
{"index":{}}
{"name":"666","age":777}

```