0

we got a task for the next week with Lambdas. We should write some Lambdas without Control Flow Statements.

Example:
We got a string and this string should repeat n-times. Example: (string,3)-> stringstringstring. The common problem is, that we dont know, how to catch e.g. -9 or 0. My code looks like this:

BiFunction<Integer, String, String> nAnhaengen 
    = (n, word) -> {
    Stream.iterate(word, wordAdd-> word + wordAdd).
    limit(n).
    skip(n-1).          
    forEach(element -> System.out.println(element));
    return "";
};

Have you an idea or tipps, how we can catch negative integers?

Thanks and Greetings Daniel

Alexis C.
  • 91,686
  • 21
  • 171
  • 177
DanielFGA
  • 3
  • 4

1 Answers1

1

You can use IntStream.

int n = -1;
String word = "string";

String string = IntStream.range(0, n).mapToObj(a -> word).reduce(String::concat).orElse("");
System.out.println(string);

OR

Change your code to have limit to 0 if value specified is lesser than 0

string = Stream.iterate(word, a -> a).limit(Math.max(0, n)).reduce(String::concat).orElse("");
System.out.println(string);

Edit:
As @Tunaki suggested Using Foreach and StringBuilder, as String::concat causes a lot of unnecessary immutable strings to be created.

String string = IntStream.range(0, n).mapToObj(a -> word).collect(Collectors.joining())
System.out.println(string);
Kishore Bandi
  • 5,537
  • 2
  • 31
  • 52
  • 1
    `.reduce(String::concat)` will be quite slow, as it is concatenating strings which are immutable, so creating a lot of new instances of string. This specific example is referenced in the docs themselves https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#MutableReduction – Tunaki Jan 07 '17 at 17:03
  • 1
    @Tunaki Thanks for the suggestion :) Edited the answer to make use of StringBuilder. – Kishore Bandi Jan 07 '17 at 17:27
  • 1
    There is a proper way to do that without `forEach`, see the linked documentation in the previous comment, and the use of `collect`. It makes sure the stream can be run in parallel without any issues (like you would encounter with `forEach` here). – Tunaki Jan 07 '17 at 17:29
  • @Tunaki But collect would collect the string as a list or collections in general, so it wouldn't give the concatenated output the question requested right? i.e., `stringstringstring` for `(string,3)` as input. Is there a way to use collect the result in a single string using Streams.collect? – Kishore Bandi Jan 07 '17 at 17:39
  • 2
    Yes, if you use [`joining()`](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#joining--). – Tunaki Jan 07 '17 at 17:40
  • @Tunaki Ahh, nice :) Didn't know we could use Joining. Will update with your solution. – Kishore Bandi Jan 07 '17 at 17:42