1

I have the following method

public String toIndentedString() {
    StringJoiner sj = new StringJoiner("\n");
    sj.add(rootValue.toString());
    for (Tree<T> child : children) {
        String childString = child.toIndentedString();
        sj.add(childString.replaceAll("(?m)^", "  "));
    }
    return sj.toString();
}

The output it is returning is slightly off, here is an image which shows the output it requires.

Could someone please tell me what I need to change to get this to work?

weston
  • 54,145
  • 21
  • 145
  • 203
eZ_Harry
  • 816
  • 9
  • 25

3 Answers3

4

The idea of StringJoiner is that you can use the constructor to specify the paramaters

delimiter - the sequence of characters to be used between each element

added to the StringJoiner prefix - the sequence of characters to be

used at the beginning suffix - the sequence of characters to be used at the end

so you could do

StringJoiner sj = new StringJoiner("\n", "", "\n");
Community
  • 1
  • 1
Scary Wombat
  • 44,617
  • 6
  • 35
  • 64
  • 1
    Doing this still seems to produce a pretty wild result, there are various new lines throughout the output – eZ_Harry May 12 '17 at 00:46
  • hmm, I have just noticed that this is a recursive method, so you probably want to create your `StringJoiner` outside of this method – Scary Wombat May 12 '17 at 00:52
2

One solution is to wrap each value with newlines and remove the extra one in the parent:

public String toIndentedString() {
    return "\n" + rootValue + children.stream()
            .map(Tree::toIndentedString)
            .map(s -> s.substring(0, s.length() - 1)) // strip trailing newline
            .map(s -> s.replaceAll("\n", "\n  "))
            .collect(Collectors.joining())
            + "\n";
}

Ideone

Alternatively, you can separate the indentation logic from line insertion like this:

public String toIndentedString() {
    return indentChildren()
            .collect(Collectors.joining("\n", "\n", "\n"));
}

private Stream<String> indentChildren() {
    return Stream.concat(Stream.of(rootValue.toString()),
            children.stream()
                    .flatMap(Tree::indentChildren)
                    .map("  "::concat));
}
shmosel
  • 49,289
  • 6
  • 73
  • 138
-1

Here is the solution, I needed to put the StringJoiner into another method. Then call that method and append a new line "\n". The code has also been changed to use StringBuilder as it is simpler. Special thanks to 4castle for helping me with this!

public String toIndentedString() {
    return _toIndentedString() + '\n';
}

private String _toIndentedString() {
    StringBuilder sb = new StringBuilder(rootValue.toString());
    for (Tree<T> child : children) {
        sb.append('\n');
        sb.append(child._toIndentedString().replaceAll("(?m)^", "  "));
    }
    return sb.toString();
}
eZ_Harry
  • 816
  • 9
  • 25