如何控制偷看以不同的方式对待最后一个元素?

时间:2018-07-23 14:57:47

标签: java string java-8 java-stream

我有一串字符

"abcd".chars()

我正在使用peek打印出这样的流

"abcd".chars().peek(e->System.out.print(e + ":"))

唯一的问题是它打印为

a:b:c:d:

我想用换行符代替最后一个冒号,但是不知道该怎么做,有人可以帮忙吗?

5 个答案:

答案 0 :(得分:5)

使用joining收集器是另一种选择:

String result = Arrays.stream(string.split(""))
                      .collect(Collectors.joining(":"));

或:

String result = Pattern.compile("")
                       .splitAsStream(string)
                       .collect(Collectors.joining(":"));

如果您实际上想要换行,请使用joining收集器的重载

Collectors.joining(":","","\n")

答案 1 :(得分:4)

可能有一个或两个重复项,但是如果您不需要使用peek(),请执行以下操作:

String str = "abcd";
char[] arr = str.toCharArray();
for (int i = 0; i < arr.length; i++) {
    System.out.print((i == str.length() - 1) ? arr[i] + "\n" : arr[i] + ":");
}

输出:

  

a:b:c:d

答案 2 :(得分:4)

要实现所需的目标并不容易,因为您没有办法在index中获得peek()。如果您坚持要使用peek,我想使用它:

String string = "abcd";
AtomicInteger count = new AtomicInteger(0);
string.chars()
        .peek(e -> {
            System.out.print((char) e);
            if (count.incrementAndGet() != string.length()) {
                System.out.print(":");
            } else {
                System.out.println();
            }
        })...

输出

a:b:c:d

请注意,您仍然必须在peek之后使用终端操作,例如sum()


或更简单地,您可以像这样使用String.join

String string = "abcd";
string = String.join(":", string.split(""));

答案 3 :(得分:2)

简单的答案是:你不能。

流用于在可能无限数量的元素上进行可能的并行计算。因此,您无权访问index(索引是数据集中元素的位置还是并行顺序中无法保证顺序的计算调用次数?)或size(无穷大)。

对于受控遍历,您可以使用BaseStream#iterator()BaseStream#spliterator()

转换流

通过在外部跟踪位置,可以减少并行化计算的可能性,并且通过引用流的数据源,可以限制代码与非无限数据流一起使用。无论哪种方式,它都会给您一个提示,即Streams不是您尝试实现的目标的正确工具。

答案 4 :(得分:1)

您可以尝试使用.html_safe

IntStream.range

输出:

@Test
public void printChars() {
    String str = "abcd";
    IntStream.range(0, str.length())
            .mapToObj(i -> str.charAt(i) + (i < str.length()-1 ? ":" : "\n"))
            .forEach(System.out::print);
}