简体   繁体   中英

How can I form a string containing numbers from 0 to n

For eg when n = 5 , I need to generate a string "012345" .

I could do it by running a for loop from 0 to n and appending numbers to a string.

for(int i = 0; i <= n; i++) {
    s += i;
}

Is there a simple way of doing it without the for loop? Perhaps using streams?

I think the best way to do this is the way you're already done it in your Question using a loop. Reading the comments, it seems to be the general consensus. Nikolas Charalambidis pointed out in a comment that the solution could do with a StringBuilder instead:

StringBuilder s = new StringBuilder();
for(int i = 0; i <= n; i++) {
  s.append(i);
}

If you must use a Stream , I believe the accepted Answer is the way to go because

  1. I think it just looks "clean" and
  2. It also uses StringBuilder instead of String . There are other approaches though.

One approach is relying on side-effects. Create a variable and update it from within the stream. The JavaDoc on Package java.util.stream warns about the use:

Side-effects in behavioral parameters to stream operations are, in general, discouraged, as they can often lead to unwitting violations of the statelessness requirement, as well as other thread-safety hazards.

String[] alternativeWayA = {""};
IntStream.rangeClosed(0,n).forEach(i -> alternativeWayA[0] = alternativeWayA[0] + i);

Luiggi Mendoza mentions in one comment

You could use collect(Collectors.joining()) and have the same output

and in another comment

Well, you could use boxed before calling collect

String alternativeWayB = IntStream.rangeClosed(0,n)
                                  .boxed()
                                  .map(i -> i.toString())
                                  .collect(Collectors.joining(""));

..if one prefers using reduce instead of Collectors.joining :

String alternativeWayC = IntStream.rangeClosed(0,n)
                                  .boxed()
                                  .map(i -> i.toString())
                                  .reduce("", String::concat);

..or as Nikolas Charalambidis suggests in this comment

you need to mapToObj as this collector is not available for IntStream

String alternativeWayD = IntStream.rangeClosed(0,n)
                                  .mapToObj(i -> String.valueOf(i))
                                  .collect(Collectors.joining(""));

Holger posted a comment with

String string = new String(IntStream.rangeClosed('1', '1'+n).toArray(), 0, n);

which I think is very elegant and works for n < 10 . For n = 15 the result becomes 0123456789:;<=>? since it's using integer values of characters. I added a + 1 to the last parameter of the String constructor:

String alternativeWayE = new String(IntStream.rangeClosed('0', '0'+n).toArray(), 0, n + 1);

Use IntStream and StringBuilder :

int n = 5;
String string = IntStream.rangeClosed(0, n)
     .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
     .toString();

However, for this particular case it's better to use a for-loop with StringBuilder .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM