创建Stream流
创建一个stream流
最便捷的创建stream流是从Collection
接口的stream()
方法。
使用Stream
接口的工厂模式方法创建stream流
Stream.of()
,Arrays.stream()
Stream.generate()
Stream.iterate()
,StreamSupport.stream()
Stream.builder()
Stream.empty()
IntStream.range()
,IntStream.rangeClosed()
,LongStream.range()
,LongStream.rangeClosed()
通过特殊的jdk对象创建stream流
String.chars()
BufferedReader.lines()
,LineNumberReader.lines()
,Files.lines()
Pattern.compile().splitAsStream()
Random.ints()
,Random.longs()
,Random.doubles()
HttpClient.send(request, HttpResponse.BodyHandlers.ofLines())
从Collection
和Iterator
创建stream流
Collection
接口的stream()
方法。
Iterator
接口
Iterator<String> iterator = ...;
long estimateSize = 10L;
int characteristics = 0;
Spliterator<String> spliterator = Spliterators.spliterator(iterator, estimateSize, characteristics);
boolean parallel = false;
Stream<String> stream = StreamSupport.stream(spliterator, parallel);
创建空的stream流
Stream<String> empty = Stream.empty();
List<String> strings = empty.collect(Collectors.toList());
System.out.println("strings = " + strings);
结果
strings = []
从变参或数组创建stream流
变参
Stream<Integer> intStream = Stream.of(1, 2, 3);
List<Integer> ints = intStream.collect(Collectors.toList());
System.out.println("ints = " + ints);
结果
ints = [1, 2, 3]
数组
String[] stringArray = {"one", "two", "three"};
Stream<String> stringStream = Arrays.stream(stringArray);
List<String> strings = stringStream.collect(Collectors.toList());
System.out.println("strings = " + strings);
结果
strings = [one, two, three]
从Supplier
创建stream流
Stream<String> generated = Stream.generate(() -> "+");
List<String> strings = generated.collect(Collectors.toList());
请注意,这会产生无穷的stream流,最终会抛出OutOfMemoryError
错误,你应该使用limit()
改进
Stream<String> generated = Stream.generate(() -> "+");
List<String> strings =
generated
.limit(10L)
.collect(Collectors.toList());
System.out.println("strings = " + strings);
结果
strings = [+, +, +, +, +, +, +, +, +, +]
从UnaryOperator
和seed(种子)生成stream流
Stream<String> iterated = Stream.iterate("+", s -> s + "+");
iterated.limit(5L).forEach(System.out::println);
结果
+
++
+++
++++
+++++
这同样是无穷stream流需要添加limit()
jdk9新增了iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)
当predicate返回false时,停止生成元素。
Stream<String> iterated = Stream.iterate("+", s -> s.length() <= 5, s -> s + "+");
iterated.forEach(System.out::println);
创建范围数stream流
range()
是[)
, rangeClosed()
是[]
String[] letters = {"A", "B", "C", "D"};
List<String> listLetters =
IntStream.range(0, 10)
.mapToObj(index -> letters[index % letters.length])
.collect(Collectors.toList());
System.out.println("listLetters = " + listLetters);
结果
listLetters = [A, B, C, D, A, B, C, D, A, B]
创建随机数stream流
Random random = new Random(314L);
List<Integer> randomInts =
random.ints(10, 1, 5)
.boxed()
.collect(Collectors.toList());
System.out.println("randomInts = " + randomInts);
结果
randomInts = [4, 4, 3, 1, 1, 1, 2, 2, 4, 2]
从字符串的字符创建stream流
jdk9新增String.chars()
String sentence = "Hello Duke";
List<String> letters =
sentence.chars()
.mapToObj(codePoint -> (char)codePoint)
.map(Object::toString)
.collect(Collectors.toList());
System.out.println("letters = " + letters);
jdk11新增Character.toString()
String sentence = "Hello Duke";
List<String> letters =
sentence.chars()
.mapToObj(Character::toString)
.collect(Collectors.toList());
System.out.println("letters = " + letters);
结果
letters = [H, e, l, l, o, , D, u, k, e]
从文本文件的行创建stream流
文件I/O资源使用后需要释放资源,Stream
接口实现了AutoCloseable
接口,可以使用try-with-resources模式优雅的关闭资源
Path log = Path.of("/tmp/debug.log"); // adjust to fit your installation
try (Stream<String> lines = Files.lines(log)) {
long warnings =
lines.filter(line -> line.contains("WARNING"))
.count();
System.out.println("Number of warnings = " + warnings);
} catch (IOException e) {
// do something with the exception
}
从正则表达式创建stream流
使用String.split()
String sentence = "For there is good news yet to hear and fine things to be seen";
String[] elements = sentence.split(" ");
Stream<String> stream = Arrays.stream(elements);
使用Pattern.compile().splitAsStream()
String sentence = "For there is good news yet to hear and fine things to be seen";
Pattern pattern = Pattern.compile(" ");
Stream<String> stream = pattern.splitAsStream(sentence);
List<String> words = stream.collect(Collectors.toList());
System.out.println("words = " + words);
Pattern.compile().splitAsStream()
没有创建数组,所以开销更小。
使用构建模式创建stream流
一旦构建器用于创建stream流,就不能向其中添加更多元素,也不能再次使用它来构建另一个stream流
Stream.Builder<String> builder = Stream.<String>builder();
builder.add("one")
.add("two")
.add("three")
.add("four");
Stream<String> stream = builder.build();
List<String> list = stream.collect(Collectors.toList());
System.out.println("list = " + list);
结果
list = [one, two, three, four]
在HTTP源上创建stream流
// The URI of the file
URI uri = URI.create("https://www.gutenberg.org/files/98/98-0.txt");
// The code to open create an HTTP request
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder(uri).build();
// The sending of the request
HttpResponse<Stream<String>> response = client.send(request, HttpResponse.BodyHandlers.ofLines());
List<String> lines;
try (Stream<String> stream = response.body()) {
lines = stream
.dropWhile(line -> !line.equals("A TALE OF TWO CITIES"))
.takeWhile(line -> !line.equals("*** END OF THE PROJECT GUTENBERG EBOOK A TALE OF TWO CITIES ***"))
.collect(Collectors.toList());
}
System.out.println("# lines = " + lines.size());
结果
# lines = 15904