将 Iterable<Character> 转换为 String 的最佳方法?
Best way to convert Iterable<Character> to String?
将 Iterable 中的字符 Iterable<Character>
转换为 String
的 easiest/fastest 方法是什么?
例如,如何转换"A"、"B"和[=20的Iterable =]"C", 到字符串 "ABC"?
iter.toString()
returns一个字符串[A,B,C].
5 个版本:
1) Java 8 个流通过 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 个流通过 Collectors.joining()
收集
public static String streamJoin(Iterable<Character> chars){
return StreamSupport.stream(chars.spliterator(), true)
.map(Object::toString)
.collect(Collectors.joining(""));
}
Pre-Java8 版本使用 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 版本使用 Joiner
:
public static String guavaJoin(Iterable<Character> chars) {
return Joiner.on("").join(chars);
}
Java 8 版本使用 Iterable.forEach()
和方法参考:
public static String iterableForEach(Iterable<Character> chars){
StringBuilder sb = new StringBuilder();
chars.forEach(sb::append);
return sb.toString();
}
关于性能的讨论之后,我 运行 一个 JMH 微基准测试供自己查看。结果很明显,但比预期的要激烈得多。
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
如您所见,最后一个版本 (iterableForEach
) 实际上是最快的,Java 7 和 Guava 版本至少处于相似的范围内。对于几百个元素以下的 Size,Streams 失败得很惨,它们显然是针对大数据集进行了优化。但在 1000 个元素时,它们的性能明显更好,几乎与 Java 7 版本相当。在大约 10000 个元素(不在此图表上)时,Streams 优于其他解决方案。
基准代码是 available as a GitHub gist,请随意修改参数并在您的机器上检查结果。
给定 x
是一个 Iterable<Character>
你可以在 String
中转换为:
public static String iterableToString(Iterable<Character> chars){
return Stream.of(x).map(String::valueOf).collect(Collectors.joining());
}
您可以使用 StreamSupport class:
获取可迭代对象:
Iterable<Character> iterableChars = Arrays.asList('1', '2', '3', '4');
附加到字符串:
String commaSeparatedChars = StreamSupport.stream(iterableChars.spliterator(), false)
.map(i -> i.toString()).collect(Collectors.joining(", "));
并打印出来:
System.out.println(commaSeparatedChars );
使用StringBuilder
的简单解决方案:
Iterable<Character> cs = ...; // wherever you get this from
StringBuilder sb = new StringBuilder();
for (Character c : cs) {
sb.append(c);
}
String result = sb.toString();
使用流的解决方案:
String result = cs.stream()
.collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
.toString();
将 Iterable 中的字符 Iterable<Character>
转换为 String
的 easiest/fastest 方法是什么?
例如,如何转换"A"、"B"和[=20的Iterable =]"C", 到字符串 "ABC"?
iter.toString()
returns一个字符串[A,B,C].
5 个版本:
1) Java 8 个流通过 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 个流通过 Collectors.joining()
public static String streamJoin(Iterable<Character> chars){
return StreamSupport.stream(chars.spliterator(), true)
.map(Object::toString)
.collect(Collectors.joining(""));
}
Pre-Java8 版本使用 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 版本使用 Joiner
:
public static String guavaJoin(Iterable<Character> chars) {
return Joiner.on("").join(chars);
}
Java 8 版本使用 Iterable.forEach()
和方法参考:
public static String iterableForEach(Iterable<Character> chars){
StringBuilder sb = new StringBuilder();
chars.forEach(sb::append);
return sb.toString();
}
关于性能的讨论之后,我 运行 一个 JMH 微基准测试供自己查看。结果很明显,但比预期的要激烈得多。
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
如您所见,最后一个版本 (iterableForEach
) 实际上是最快的,Java 7 和 Guava 版本至少处于相似的范围内。对于几百个元素以下的 Size,Streams 失败得很惨,它们显然是针对大数据集进行了优化。但在 1000 个元素时,它们的性能明显更好,几乎与 Java 7 版本相当。在大约 10000 个元素(不在此图表上)时,Streams 优于其他解决方案。
基准代码是 available as a GitHub gist,请随意修改参数并在您的机器上检查结果。
给定 x
是一个 Iterable<Character>
你可以在 String
中转换为:
public static String iterableToString(Iterable<Character> chars){
return Stream.of(x).map(String::valueOf).collect(Collectors.joining());
}
您可以使用 StreamSupport class:
获取可迭代对象:
Iterable<Character> iterableChars = Arrays.asList('1', '2', '3', '4');
附加到字符串:
String commaSeparatedChars = StreamSupport.stream(iterableChars.spliterator(), false)
.map(i -> i.toString()).collect(Collectors.joining(", "));
并打印出来:
System.out.println(commaSeparatedChars );
使用StringBuilder
的简单解决方案:
Iterable<Character> cs = ...; // wherever you get this from
StringBuilder sb = new StringBuilder();
for (Character c : cs) {
sb.append(c);
}
String result = sb.toString();
使用流的解决方案:
String result = cs.stream()
.collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
.toString();