如何使用Streams来处理字符串?

时间:2017-06-07 09:28:20

标签: java string java-stream

Java 8方法String.chars()String.codePoints()(实际上是从CharSequence.chars()CharSequence.codePoints()继承而来)对char的工作非常有用(如int中的IntStream s。{/ p>

但是,JDK中是否有任何收集器允许将int - ed char再次转换为String

我尝试了什么以及为什么他们不能正常

IntStream.toArray

我想我可以使用String(int[],int,int)构造函数,但令我烦恼的是我需要提供第三个参数,当我来自IntStream.toArray()时,这通常是未知的。但这迫使我使用将生成的数组存储到一个临时变量中,如果在特定的方法/收集器中使用,这是可以的,但在使用时并没有那么多"在运行中#34;就像流通常允许的那样

String str = "zyxwvutsrqponmlkjihgfedcba";
int[] codePoints = // Seems OK if I use codePoints, but chars??
    str.codePoints()
      .filter(cp -> "aeiouy".indexOf(cp) < 0) // remove vowels
      .sorted()
      .toArray();
String result = new String(codePoints, 0, codePoints.length);

这里令人困惑的部分是字符和代码点之间的区别,但主要是因为我们整天都在char上工作,然后没有人希望西班牙宗教裁判所 a {{1构造函数,特别是没有String(int[],int,int)对应的。

String(int[])

此外,IntStream.collect(Supplier,ObjIntConsumer,BiConsumer)方法与其Stream.collect(Collector)等效方法相比似乎非常低。我们甚至不能拥有IntStream.collect,这有助于创建此类方法。马上丢弃。

但是存在一个解决方案:

IntCollector

尽管如此,这是非常冗长和不直观的。能够给String str = "zyxwvutsrqponmlkjihgfedcba"; String result = str .codePoints() .filter(cp -> "aeiouy".indexOf(cp) < 0) // remove vowels .sorted() .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) .toString(); 能够击败这一千倍!此外,收集的结果是Collector,强制呼叫StringBuilder。是的,真的不直观。

使用中介.toString()

迄今为止最令人满意的解决方案。

StringBuilder

使用它并不明显,因为我需要两个中介&#34;解决方案&#34;首先,使用代码点,其次,使用String str = "zyxwvutsrqponmlkjihgfedcba"; StringBuilder sb = new StringBuilder(); str.codePoints() .filter(cp -> "aeiouy".indexOf(cp) < 0) // remove vowels .sorted() .forEach(sb::appendCodePoint); String result = sb.toString(); 结合forEach而不是StringBuilder } Collector API通常会这样做。

展平为循环

显而易见的解决方案是将所有事情弄平并做到这一点&#34;旧方式&#34;与for循环。但是这标题失败了,因为我们不会使用流来处理字符串&#34;。

不幸的是,由于缺少其他明显的流工具,这仍然是为同事提供可读代码的最佳选择。

结论

我认为我不应该使用StreamString.chars(),除非我错过了一个明显的方法,因此问题是:是否有任何简单/明显的方法来执行简单的流操作在字符串字符/ codePoints上并轻松返回String.codePoints()

备注

  • 我非常了解Guava的String来删除元音,但这不是重点:重点是如何在字符串上下文中正确使用Stream API

0 个答案:

没有答案