问题
What's the easiest/fastest way to convert an Iterable<Character>
to a String
of the characters from the Iterable?
For example, how to convert an Iterable of "A", "B", and "C", to a String "ABC"?
The iter.toString()
returns a String "[A, B, C]".
回答1:
5 Versions:
1) Java 8 streams collecting via StringBuilder.append()
:
public static String streamAppend(Iterable<Character> chars){
return StreamSupport.stream(chars.spliterator(), true)
.collect(
StringBuilder::new,
StringBuilder::append,
StringBuilder::append
)
.toString();
}
Java 8 Streams collecting via Collectors.joining()
public static String streamJoin(Iterable<Character> chars){
return StreamSupport.stream(chars.spliterator(), true)
.map(Object::toString)
.collect(Collectors.joining(""));
}
Pre-Java8-Version using Java 5 for loops:
public static String java7(Iterable<Character> chars) {
StringBuilder sb = new StringBuilder();
for (Character c: chars) {
sb.append(c);
}
return sb.toString();
}
Guava version using a Joiner
:
public static String guavaJoin(Iterable<Character> chars) {
return Joiner.on("").join(chars);
}
Java 8 version using Iterable.forEach()
and method references:
public static String iterableForEach(Iterable<Character> chars){
StringBuilder sb = new StringBuilder();
chars.forEach(sb::append);
return sb.toString();
}
After the discussions regarding performance, I ran a JMH micro-benchmark to see for myself. The results are obvious, but much more drastic than expected.
Benchmark (mode) (size) Score Units
CharsToString.stringJoin STREAM_APPEND 1 5071451.223 ± ops/s
CharsToString.stringJoin STREAM_APPEND 2 481656.870 ± ops/s
CharsToString.stringJoin STREAM_APPEND 5 162359.508 ± ops/s
CharsToString.stringJoin STREAM_APPEND 10 76910.668 ± ops/s
CharsToString.stringJoin STREAM_APPEND 20 49590.249 ± ops/s
CharsToString.stringJoin STREAM_APPEND 50 44608.948 ± ops/s
CharsToString.stringJoin STREAM_APPEND 100 20940.993 ± ops/s
CharsToString.stringJoin STREAM_APPEND 200 29634.118 ± ops/s
CharsToString.stringJoin STREAM_APPEND 500 19387.956 ± ops/s
CharsToString.stringJoin STREAM_APPEND 1000 17629.508 ± ops/s
CharsToString.stringJoin STREAM_JOIN 1 3342341.147 ± ops/s
CharsToString.stringJoin STREAM_JOIN 2 279516.584 ± ops/s
CharsToString.stringJoin STREAM_JOIN 5 102312.667 ± ops/s
CharsToString.stringJoin STREAM_JOIN 10 61759.122 ± ops/s
CharsToString.stringJoin STREAM_JOIN 20 34802.386 ± ops/s
CharsToString.stringJoin STREAM_JOIN 50 37629.593 ± ops/s
CharsToString.stringJoin STREAM_JOIN 100 33493.715 ± ops/s
CharsToString.stringJoin STREAM_JOIN 200 26186.986 ± ops/s
CharsToString.stringJoin STREAM_JOIN 500 19264.628 ± ops/s
CharsToString.stringJoin STREAM_JOIN 1000 14446.396 ± ops/s
CharsToString.stringJoin GUAVA_JOIN 1 6570784.907 ± ops/s
CharsToString.stringJoin GUAVA_JOIN 2 3821031.465 ± ops/s
CharsToString.stringJoin GUAVA_JOIN 5 1574828.190 ± ops/s
CharsToString.stringJoin GUAVA_JOIN 10 806057.685 ± ops/s
CharsToString.stringJoin GUAVA_JOIN 20 356533.358 ± ops/s
CharsToString.stringJoin GUAVA_JOIN 50 156129.534 ± ops/s
CharsToString.stringJoin GUAVA_JOIN 100 100195.171 ± ops/s
CharsToString.stringJoin GUAVA_JOIN 200 54820.347 ± ops/s
CharsToString.stringJoin GUAVA_JOIN 500 20577.137 ± ops/s
CharsToString.stringJoin GUAVA_JOIN 1000 11465.704 ± ops/s
CharsToString.stringJoin ITERABLE_FOREACH 1 11921819.833 ± ops/s
CharsToString.stringJoin ITERABLE_FOREACH 2 7007911.144 ± ops/s
CharsToString.stringJoin ITERABLE_FOREACH 5 4415785.561 ± ops/s
CharsToString.stringJoin ITERABLE_FOREACH 10 2107685.852 ± ops/s
CharsToString.stringJoin ITERABLE_FOREACH 20 1158806.591 ± ops/s
CharsToString.stringJoin ITERABLE_FOREACH 50 482412.510 ± ops/s
CharsToString.stringJoin ITERABLE_FOREACH 100 265362.511 ± ops/s
CharsToString.stringJoin ITERABLE_FOREACH 200 123663.470 ± ops/s
CharsToString.stringJoin ITERABLE_FOREACH 500 49238.673 ± ops/s
CharsToString.stringJoin ITERABLE_FOREACH 1000 24328.723 ± ops/s
CharsToString.stringJoin JAVA7 1 9746936.478 ± ops/s
CharsToString.stringJoin JAVA7 2 6431473.785 ± ops/s
CharsToString.stringJoin JAVA7 5 2736936.112 ± ops/s
CharsToString.stringJoin JAVA7 10 1764353.273 ± ops/s
CharsToString.stringJoin JAVA7 20 833322.493 ± ops/s
CharsToString.stringJoin JAVA7 50 278354.933 ± ops/s
CharsToString.stringJoin JAVA7 100 180763.740 ± ops/s
CharsToString.stringJoin JAVA7 200 86729.675 ± ops/s
CharsToString.stringJoin JAVA7 500 38560.347 ± ops/s
CharsToString.stringJoin JAVA7 1000 17798.159 ± ops/s
As you can see, the last version (iterableForEach
) is actually the fastest one, with the Java 7 and Guava versions at least in a similar ballpark. For Sizes under several hundred elements, Streams fail miserably, they are obviously optimized for large data sets. But at 1000 elements, they perform significantly better and almost on par with the Java 7 version. At about 10000 elements (not on this chart), Streams outperform the other solutions.
The benchmark code is available as a GitHub gist, feel free to tinker with the parameters and check the results on your machine.
回答2:
Given x
is a Iterable<Character>
you can convert in a String
with:
public static String iterableToString(Iterable<Character> chars){
return Stream.of(x).map(String::valueOf).collect(Collectors.joining());
}
回答3:
You can use StreamSupport class:
get the Iterable:
Iterable<Character> iterableChars = Arrays.asList('1', '2', '3', '4');
append to string:
String commaSeparatedChars = StreamSupport.stream(iterableChars.spliterator(), false)
.map(i -> i.toString()).collect(Collectors.joining(", "));
and print it:
System.out.println(commaSeparatedChars );
回答4:
Simple solution using StringBuilder
:
Iterable<Character> cs = ...; // wherever you get this from
StringBuilder sb = new StringBuilder();
for (Character c : cs) {
sb.append(c);
}
String result = sb.toString();
Solution using streams:
String result = cs.stream()
.collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
.toString();
来源:https://stackoverflow.com/questions/42627108/best-way-to-convert-iterablecharacter-to-string