如何将字符串拆分为字符串流? [英] How to split a String into a Stream of Strings?
问题描述
将字符串拆分为流的最佳方法是什么?
What is the best method of splitting a String into a Stream?
我看到了这些变化:
-
Arrays.stream("b,l,a".split(","))
-
Stream.of("b,l,a".split(","))
-
Pattern.compile(",").splitAsStream("b,l,a")
Arrays.stream("b,l,a".split(","))
Stream.of("b,l,a".split(","))
Pattern.compile(",").splitAsStream("b,l,a")
我的优先事项是:
- 健壮
- 可读性
- 性能
完整,可编译的示例:
import java.util.Arrays;
import java.util.regex.Pattern;
import java.util.stream.Stream;
public class HelloWorld {
public static void main(String[] args) {
stream1().forEach(System.out::println);
stream2().forEach(System.out::println);
stream3().forEach(System.out::println);
}
private static Stream<String> stream1() {
return Arrays.stream("b,l,a".split(","));
}
private static Stream<String> stream2() {
return Stream.of("b,l,a".split(","));
}
private static Stream<String> stream3() {
return Pattern.compile(",").splitAsStream("b,l,a");
}
}
推荐答案
Arrays.stream
/String.split
Arrays.stream
/String.split
Since String.split
returns an array String[]
, I always recommend Arrays.stream
as the canonical idiom for streaming over an array.
String input = "dog,cat,bird";
Stream<String> stream = Arrays.stream(input.split( "," ));
stream.forEach(System.out::println);
Stream.of
/String.split
Stream.of
/String.split
Stream.of
is a varargs method which just happens to accept an array, due to the fact that varargs methods are implemented via arrays and there were compatibility concerns when varargs were introduced to Java and existing methods retrofitted to accept variable arguments.
Stream<String> stream = Stream.of(input.split(",")); // works, but is non-idiomatic
Stream<String> stream = Stream.of("dog", "cat", "bird"); // intended use case
Pattern.splitAsStream
具有直接流式传输而不是创建中间数组的优势.因此,对于大量的子字符串,这可以带来性能上的好处.另一方面,如果定界符很简单,即单个文字字符,则String.split
实现将通过快速路径而不是使用正则表达式引擎.因此,在这种情况下,答案并不简单.
Pattern.splitAsStream
Pattern.compile(",").splitAsStream(string)
has the advantage of streaming directly rather than creating an intermediate array. So for a large number of sub-strings, this can have a performance benefit. On the other hand, if the delimiter is trivial, i.e. a single literal character, the String.split
implementation will go through a fast path instead of using the regex engine. So in this case, the answer is not trivial.
Stream<String> stream = Pattern.compile(",").splitAsStream(input);
如果流发生在另一个流中,例如.flatMap(Pattern.compile(pattern) ::splitAsStream)
的优点是模式只需分析一次,而不是对外部流的每个字符串进行分析.
If the streaming happens inside another stream, e.g. .flatMap(Pattern.compile(pattern) ::splitAsStream)
there is the advantage that the pattern has to be analyzed only once, rather than for every string of the outer stream.
Stream<String> stream = Stream.of("a,b", "c,d,e", "f", "g,h,i,j")
.flatMap(Pattern.compile(",")::splitAsStream);
这是形式为expression::name
的方法引用的属性,如System.out::println 和 java.lang的等效lambda表达式是什么.使用方法引用而不是lambda表达式引发NullPointerException
This is a property of method references of the form expression::name
, which will evaluate the expression and capture the result when creating the instance of the functional interface, as explained in What is the equivalent lambda expression for System.out::println and java.lang.NullPointerException is thrown using a method-reference but not a lambda expression
这篇关于如何将字符串拆分为字符串流?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!