Java 8 之 流(Stream)
程序员文章站
2022-05-15 11:34:19
...
与java.io包里的InputStream和OutputStream是完全不同的概念,它是以数据流的形式来处理数据集合。
Streams vs. Collections: What’s the difference?
两种模式
***可以相互转换!
两种操作
Stream类型
链式写法
数据源(集合、数组等).中间操作(过滤、投影等).....终止操作(forEach、reduce等)
***可以没有中间操作。
一个简单的例子
生成Stream
核心方法
过滤
投影
一对多投影
排序
获取前N个元素
跳过前N个元素
连接
无重复
自定义方法
分组
平均值
件数
最大值
最小值
合计
第一个元素
找到任何一个匹配的元素
导出到某个容器
导出到数组
是否所有的元素都匹配
是否至少一个匹配的元素
是否所有的元素都不匹配
空序列
指定范围的序列
通过函数生成
无限循环
遍历序列
http://java-latte.blogspot.jp/2014/03/stream-lambda-in-java-8.html
http://blog.informatech.cr/2013/03/24/java-streams-preview-vs-net-linq/
http://qiita.com/amay077/items/9d2941283c4a5f61f302
- 不是collection,有点儿像iterator但没有存储
- 仅代表数据流,并没有数据结构
- 只能被遍历一次(返回另外一个Stream)。采用Lazy方式,如果有多个中间操作和最终操作,在调用最终操作的时候才会同时处理所有中间操作。
- 不支持索引访问
- 避免出现Null而影响到链式操作,引入了Optional.empty代表空。
- 短路处理:只要有一个符合条件就终止遍历。善用短路处理也能提高效率,比如:stream.count() != 0 等价于 stream.findAny().isPresent()
Streams vs. Collections: What’s the difference?
两种模式
- 顺序流sequential version
- 并行流parallel version
***可以相互转换!
两种操作
- 中间操作Intermediate operation
- 终止操作Terminal operation
Stream类型
- Stream<T>
- IntStream、LongStream、DoubleStream
链式写法
数据源(集合、数组等).中间操作(过滤、投影等).....终止操作(forEach、reduce等)
***可以没有中间操作。
一个简单的例子
List<String> apples = fruits.stream() .filter(f -> f.getName().startsWith("Apple")) .filter(f -> f.getPrice() > 10) .sorted(Comparator.comparingInt(Fruit::getPrice)) .map(Fruit:getName) .collect(Collectors.toList()); // Line 1:从所有水果一览中 // Line 2:把名字以“Apple”开头 // Line 3:价格高于10元的 // Line 4:按照价格升序排序 // Line 5:并只取出名字 // Line 6:的水果一览List
生成Stream
// Values Stream<String> stream1 = Stream.of("a", "b", "c", "d", "e"); // Array Object[] array = {"string", 1, new ArrayList<Integer>()}; Stream<Object> stream2 = Arrays.stream(array); Stream<Object> stream3 = Stream.of(array); // Collection List<String> list = Arrays.asList("a", "b", "c", "d", "e"); Stream<String> stream4 = list.stream();// sequential version Stream<String> stream5 = list.parallelStream(); // parallel version // Function Stream<String> stream6 = Stream.generate(() -> "test").limit(5); Stream<Integer> stream7 = Stream.iterate(10, i -> i + 10).limit(5); // Stream.Builder Stream.Builder<String> builder = Stream.builder(); builder.accept("foo"); builder.add("bar"); Stream<String> stream8 = builder.build(); // String IntStream stream9 = "abcd".chars(); // Random Random random = new Random(); IntStream stream10 = random.ints(); // Iterable Iterable<String> iter = Arrays.asList("a", "b", "c", "d", "e"); Stream<String> stream11 = StreamSupport.stream(iter.spliterator(), false); // Stream + Stream Stream<String> a = Stream.of("a", "b", "c"); Stream<String> b = Stream.of("d", "e"); Stream<String> stream12 = Stream.concat(a, b); // Range Stream IntStream stream13 = IntStream.range(2, 10); // BufferedReader FileReader fr = new FileReader("test.txt"); BufferedReader br = new BufferedReader(fr); Stream<String> stream14 = br.lines();
核心方法
过滤
Arrays.asList(0,1,2,3,4,5,6,7,8,9).stream() .filter(x -> x % 2 == 0);
投影
Arrays.asList(0,1,2,3,4,5,6,7,8,9).stream() .map(x -> x * 10);
一对多投影
Arrays.asList(0,1,2,3,4,5,6,7,8,9).stream() .flatMap(x -> IntStream.range(x * 10, x * 10 + x).boxed());
排序
Arrays.asList(0,1,2,3,4,5,6,7,8,9).stream() .sorted((x, y) -> y - x);
获取前N个元素
Stream.iterate(1, x-> x++) .limit(5);
跳过前N个元素
Stream.iterate(1, x-> x++) .skip(3) .limit(5);
连接
Stream.concat( Arrays.asList(1,2,3).stream(), Arrays.asList(30,20,10).stream());
无重复
Arrays.asList(1,3,4,3,2,4).stream() .distinct();
自定义方法
int max = Arrays.asList(1,5,3,7,2,4).stream() .reduce(Integer.MIN_VALUE, (x, y) -> Math.max(x, y)); System.out.println(max);
分组
Arrays.asList("Sam", "Samuel", "Samu", "Ravi", "Ratna","Barsha").stream() .collect(Collectors.groupingBy(x -> x.length())) .entrySet().stream();
平均值
IntStream.range(0, 10).average().getAsDouble(); Arrays.asList(0,1,2,3,4,5,6,7,8,9).stream() .collect(Collectors.summarizingInt(x -> x)) .getAverage();
件数
Arrays.asList(0,1,2,3,4,5,6,7,8,9).stream() .count();
最大值
Arrays.asList(0,1,2,3,4,5,6,7,8,9).stream() .max();
最小值
Arrays.asList(0,1,2,3,4,5,6,7,8,9).stream() .min();
合计
IntStream.range(0, 10).sum(); Arrays.asList(0,1,2,3,4,5,6,7,8,9).stream() .collect(Collectors.summarizingInt(x -> x)) .getSum();
第一个元素
Arrays.asList(0,1,2,3,4,5,6,7,8,9).stream() .findFirst();
找到任何一个匹配的元素
Arrays.asList(0,1,2,3,4,5,6,7,8,9).stream() .findAny();
导出到某个容器
List<String> converted = Arrays.asList("foo", "foo bar").stream() .collect(Collectors.toList());
导出到数组
int[] arr = new Random().ints().limit(10).toArray();
是否所有的元素都匹配
boolean a = Arrays.asList(1, 3, 5, 7, 9).stream() .allMatch(c -> c % 3 == 0);
是否至少一个匹配的元素
boolean b = Arrays.asList(1, 3, 5, 7, 9).stream() .anyMatch(c -> c % 3 == 0);
是否所有的元素都不匹配
boolean c = Arrays.asList("foo", "foo bar").stream() .noneMatch(s -> s.startsWith("A"));
空序列
Stream.empty();
指定范围的序列
IntStream.range(0, 10);
通过函数生成
Stream.generate(() -> "test").limit(5).forEach(System.out::println); Stream.generate(new Random()::nextInt).forEach(System.out::println);
无限循环
Stream.iterate(10, i -> i + 10) .limit(5) .forEach(System.out::println);
遍历序列
Arrays.asList(0,1,2,3,4,5,6,7,8,9).stream() .forEach(System.out::println);
http://java-latte.blogspot.jp/2014/03/stream-lambda-in-java-8.html
http://blog.informatech.cr/2013/03/24/java-streams-preview-vs-net-linq/
http://qiita.com/amay077/items/9d2941283c4a5f61f302