2

basically I'd like to see if there is a compact lambda way of doing this:

int n = ...
String s = "";
for (int i = 0; i < n; i++) {
  s += 'a';
}

The start is easy, then I'm lost:

IntStream.range(0, n). ??
marathon
  • 7,881
  • 17
  • 74
  • 137
  • 1
    [`String s = StringUtils.repeat('a', n);`](https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html#repeat-char-int-) – Elliott Frisch Mar 14 '17 at 02:24
  • This is not a dupe of "how to repeat a string"; this asks for a lambda equivalent of this code – Bohemian Mar 15 '17 at 04:17
  • @Bohemian And [this](http://stackoverflow.com/a/27690536/438154) answer there provides that. Looks very much like yours. – Sotirios Delimanolis Mar 15 '17 at 15:18
  • @SotiriosDelimanolis hmmm, it does. I interpret the actual code here as being secondary to the main question, which is IMHO "how to do implement this loop as a stream". So, I don't think the *question* is the same, but when it's closed as a dupe the message reads "This question already has an answer here...", which is true. It's a topic for meta, but fine let's close it then – Bohemian Mar 15 '17 at 15:25

3 Answers3

5

This is better:

String s = Stream.generate(() -> "a").limit(n).collect(Collectors.joining());
Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • True, this one is much sleeker – buræquete Mar 14 '17 at 02:22
  • You can even eliminate the lambda by using `Stream.generate("a"::toString)`, making this a pure non-lambda Stream solution. Although question specifically asks for a *lambda* version of the code, I would postulate that might be a "typo", and that OP really wanted a *Stream* version. – Andreas Mar 15 '17 at 05:36
2

It is very straightforward;

int n = 20;
System.out.println(IntStream.range(0, n).boxed().map(i -> "a").collect(Collectors.joining()));

Prints out;

aaaaaaaaaaaaaaaaaaaa

You have to do boxed() to switch to a Integer stream, then just map each number to a "a" String, which will transform your stream of 1,2,3,4... to a,a,a,a,a... and finally join them.

buræquete
  • 14,226
  • 4
  • 44
  • 89
0

Why use stream/lambda for this? Less efficient.

If you want a one-liner, try this instead:

String s = new String(new char[n]).replace('\0', 'a');
Andreas
  • 154,647
  • 11
  • 152
  • 247
  • Well, we'd have to profile to be sure - for small values of `n` you are certainly right, but this approach creates 3 arrays of size `n` (of which two are very short lived - perhaps they can be eliminated by optimization?) – Hulk Mar 14 '17 at 08:34
  • Another appoach would be filling the array in place with [Arrays.fill()](https://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#fill-char:A-char-) before passing it to the String constructor - would avoid one copy. – Hulk Mar 14 '17 at 08:36
  • @Hulk True, `Arrays.fill()` is what I would usually use, since that is truly the best way, but you seemed to be looking for a one-liner. – Andreas Mar 14 '17 at 15:07
  • that's pretty clever. The reason for lambdas was just to see how it would be done using lambdas. nothing more. – marathon Mar 15 '17 at 01:52
  • This does not answer the question, which asked for a lambda – Bohemian Mar 15 '17 at 04:16