将Iterable <character>转换为String的最佳方法是什么?

时间:2017-03-06 13:39:23

标签: java iterable

从Iterable转换Iterable<Character>String个字符的最简单/最快捷方式是什么?

例如,如何将“A”“B”“C”的Iterable转换为String “ABC”

iter.toString()返回字符串“[A,B,C]”

4 个答案:

答案 0 :(得分:6)

5个版本:

1)通过StringBuilder.append()收集Java 8流:

public static String streamAppend(Iterable<Character> chars){
    return StreamSupport.stream(chars.spliterator(), true)
                        .collect(
                            StringBuilder::new,
                            StringBuilder::append,
                            StringBuilder::append
                         )
                        .toString();
}

通过Collectors.joining()收集的Java 8 Streams

public static String streamJoin(Iterable<Character> chars){
    return StreamSupport.stream(chars.spliterator(), true)
                        .map(Object::toString)
                        .collect(Collectors.joining(""));
}

Pre-Java8-Version使用Java 5 for循环:

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);
}

使用Iterable.forEach()的Java 8版本和方法引用:

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

line chart

正如您所看到的,最后一个版本(iterableForEach)实际上是最快的版本,Java 7和Guava版本至少在类似的范围内。对于数百个元素下的大小,Streams失败,它们显然针对大型数据集进行了优化。但是在1000个元素中,它们表现得更好,几乎与Java 7版本相当。在大约10000个元素(不在此图表上),Streams优于其他解决方案。

基准代码为available as a GitHub gist,您可以随意修改参数并检查计算机上的结果。

答案 1 :(得分:1)

鉴于xIterable<Character>,您可以使用以下代码转换String

public static String iterableToString(Iterable<Character> chars){
   return Stream.of(x).map(String::valueOf).collect(Collectors.joining());
}

答案 2 :(得分:0)

您可以使用StreamSupport类:

获得Iterable:

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 );

答案 3 :(得分:0)

使用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();