Reputation: 14621
How can you convert a range in Java (either using java.util.stream.LongStream
or java.util.stream.IntStream
) to a delimited string in Java?
I have tried:
String str = LongStream.range(16, 30)
.boxed()
.map(String::valueOf)
.collect(Collectors.joining(","));
System.out.println(str);
This prints:
16,17,18,19,20,21,22,23,24,25,26,27,28,29
The same can be used with IntStream
. Is there a more convenient conversion of a range to a delimited string?
Upvotes: 10
Views: 2946
Reputation: 120978
Seriously, just for the fun of it. Using guava:
String result = ContiguousSet.create(
Range.closedOpen(16, 31), DiscreteDomain.integers())
.asList()
.toString();
Or
String result = String.join(",",
IntStream.rangeClosed(16, 30).mapToObj(String::valueOf).toArray(String[]::new));
Or:
String result = String.join(",",
() -> IntStream.rangeClosed(16, 31).mapToObj(x -> (CharSequence) String.valueOf(x)).iterator());
Or (seems like I got carried away a bit with this):
String result = IntStream.rangeClosed(16, 31)
.boxed()
.collect(
Collector.of(
() -> new Object() {
StringBuilder sb = new StringBuilder();
},
(obj, i) -> obj.sb.append(i).append(",")
,
(left, right) -> {
left.sb.append(right.sb.toString());
return left;
},
x -> {
x.sb.setLength(x.sb.length() - 1);
return x.sb.toString();
})
);
And after Holger's good points, here is even a simpler version:
StringBuilder sb = IntStream.range(16, 30)
.collect(
StringBuilder::new,
(builder, i) -> builder.append(i).append(", "),
StringBuilder::append);
if (sb.length() != 0) {
sb.setLength(sb.length() - 2);
}
String result = sb.toString();
Upvotes: 8
Reputation: 16266
With IntStream.mapToObj
:
String s = IntStream.range(16, 30)
.mapToObj(String::valueOf)
.collect(Collectors.joining(","));
Upvotes: 7
Reputation: 374
If your sense of convenience implies less code, there is no need to explicitly map the Long
to String
. They can be simply mapped while collecting process. Here's the code to do so:
List<String> str = LongStream.range(16, 30)
.boxed()
.collect(Collectors.mapping(l -> String.valueOf(l), Collectors.toList()));
System.out.println(str.toString());
The result is:
[16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
In response to the comment to whether boxing
should be avoided, it has to happen anyway. The range()
in this case returns an object of LongStream
which has to be converted to a stream
of Long
.
According to @Jubobs The mapToObject()
effectively returns stream
of Long
from the LongStream
object.
Upvotes: 0