0

How do I convert to Java Stream the for-loop part in the following codes?

    Map<String, String> attributes = new HashMap() {{
        put("header", "Hello, world!");
        put("font", "Courier New");
        put("fontSize", "14px");
        put("color", "#0000ff");
        put("content", "hello, world" +
                "");
    }};
    Path templatePath = Paths.get("C:/workspace/spring-boot-demos/something.tpl");
List<String> lines = Files.readAllLines(templatePath).stream()
                .filter(Objects::nonNull)
                .map(line -> {
                    String parsedLine = "";
                    for (int i = 0; i < attributes.size(); i++) {
                        if (parsedLine.equals("")) parsedLine = this.parse(attributes, line);
                        else parsedLine = this.parse(attributes, parsedLine);
                    }

                    return parsedLine;
                })
                .collect(Collectors.toList());

public String parse(Map<String, String> attributes, String line) {
        return attributes.entrySet().stream()
                .filter(attributeMap -> line.indexOf("{{" + attributeMap.getKey() + "}}") != -1)
                .map(attributeMap -> {
                    String attributeKey = attributeMap.getKey();
                    String attributeValue = attributeMap.getValue();
                    String newLine = line.replace("{{" + attributeKey + "}}", attributeValue);
                    return newLine;
                })
                .findFirst().orElse(line);
    }

I find it difficult to implement it in Java 8 Stream way so that I'm forced to do it old for-loop construct. The reason behind this is that for every line of string, there might one or more placeholder (using {{}} delimiter). I have the list (attributes, HashMap) of the value to replace them. I want to make sure that before the loop of Stream leave every line, all of the placeholders must replaced with the value from the Map. Without doing this, only the first placeholder is being replaced.

Thank you.

Update: This is the content of something.tpl file:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <title>HTML Generator</title>
        <style>
            body {
                font-family: "{{font}}";
                font-size: {{fontSize}};
                color: {{color}};
            }
        </style>
    </head>
    <body>
        <header>{{header}}</header> {{content}}
        <main>{{content}}</main>
        <h1>{{header}}</h1>
    </body>
</html>
Stefan Zobel
  • 3,182
  • 7
  • 28
  • 38
Julez
  • 1,010
  • 22
  • 44

1 Answers1

2

So you want to replace every token in the given List ?

Here's how I would do it with streams :

  1. Iterate over lines
  2. parse each line only once
  3. the parsing iterates over attributes, and replaces the current attribute

The String[] pLine may be was you were missing...

package so20190412;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Snippet {

    public Snippet() {
    }

    public static void main(String[] args) {        

        Map<String, String> attributes = new HashMap<String, String> () {{
            put("john", "doe");
            put("bruce", "wayne");
        }};
        List<String> lines = Arrays.asList("My name is {{john}}, not {{bruce}}.", "Hello, {{john}}!", "How are you doing?");

        new Snippet().replaceAll(attributes, lines).forEach(System.out::println);

    }

    public List<String> replaceAll(Map<String, String> attributes, List<String> lines) {
        return lines.stream().map(l -> parse(attributes, l)).collect(Collectors.toList());
    }

    public String parse(Map<String, String> attributes, String line) {
        String[] pLine = {line};
        attributes.entrySet().stream()
                .forEach(attr -> {
                    String attributeKey = attr.getKey();
                    String attributeValue = attr.getValue();
                    String newLine = pLine[0].replace("{{" + attributeKey + "}}", attributeValue);
                    pLine[0] = newLine;
                });
        return pLine[0];
    }
}

Don't hesitate to ask if you don't understand some part.

HTH!

Highbrainer
  • 750
  • 4
  • 15