8

It can be an obvious question but I am thinking how to replace the method below with java 8 streams.

private String assembleString(int numberOfCharacters, char character) { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < numberOfCharacters; i++) { stringBuilder.append(character); } return stringBuilder.toString(); } 

I am new in Java, so java 8 it is like an unexplored world for me.

Thank you!

4
  • 3
    Why would you even want to introduce Streams to something this simple? Please don't use Streams for the sake of it. Commented Jun 27, 2018 at 12:22
  • 1
    @ThomasTimbul it is always easier to learn something with the simplest way first, he seems trying to learn something. Commented Jun 27, 2018 at 12:25
  • 1
    Please keep in your mind that streams are not faster/better by default. Do not use them just "because its fancy java 8"... Commented Jun 27, 2018 at 12:28
  • @Al-Mothafar I'd start with simple List/Map/Collection manipulation as shown in all the tutorials, not padding a String, for which the creation of Stream related objects is overkill and doesn't necessarily lead to better or more readable code. To clean up the posted code, I would use a library such as Commons StringUtils instead of Streams "just because I can". Commented Jun 27, 2018 at 12:30

6 Answers 6

6

All you need is just Collections.nCopies

private static String assembleString(int numberOfCharacters, char character) { return String.join("", Collections.nCopies(numberOfCharacters, String.valueOf(character)) ); } 
Sign up to request clarification or add additional context in comments.

Comments

2

You can use Stream.generate:

return Stream.generate(() -> String.valueOf(character)) .limit(numberOfCharacters) .collect(Collectors.joining()); 

or IntStream.rangeClosed:

return IntStream.rangeClosed(1, numberOfCharacters) .mapToObj(n -> String.valueOf(character)) .collect(Collectors.joining()); 

Comments

2

This should suffice.

IntStream.range(0, numberOfCharacters) .mapToObj(value -> character) .forEach(stringBuilder::append); 

EDIT:

Taking Holger's suggestion, this would be even more functional and cleaner.

IntStream.range(0, numberOfCharacters) .map(value -> character) .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append); 

4 Comments

+1 for the cleanest Streams based implementation on this page - it's the only one that doesn't create superfluous Strings on the way.
@ThomasTimbul even cleaner would be .map(value -> character) .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) instead of .mapToObj(value -> character) .forEach(stringBuilder::append) to an existing StringBuilder. It would also avoid boxing into Character objects.
shoudn't it be forEachOrdered ?
@AntonBalaniuc when we are just appending the same character n number of times, it doesn't matter whether it is ordered or not isn't it.
1

Use IntStream:

private String assembleString(int numberOfCharacters, char character) { return IntStream.range(0, numberOfCharacters) .mapToObj(i -> String.valueOf(character)).collect(Collectors.joining()); } 

Comments

1

With Java 11+, you could also use String::repeat:

return String.repeat(Character.toString(character), numberOfCharacters); 

Or you could "steal" their implementation:

char[] repeated = new char[numberOfCharacters]; Arrays.fill(repeated, character); return new String(repeated); 

1 Comment

Arrays.fill(…) also was the first thing that came into my mind. Of course, an implementation within String itself, like repeat avoids the defensive copying of the array.
1

Just for "completeness", without apparent loops or Streams:

private String assembleString(int numberOfCharacters, char character) { return new String(new char[numberOfCharacters]).replace('\0', character); } 

How: Creates a new char array of size 'numberOfCharacters', which will be initialised with 'null' characters. Construct a String from this array, then replace all occurrences of the null character with the desired one.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.