Java 8 实战 -- 函数式数据处理 (二)
2017-06-30 15:26
519 查看
引入流
1 流简介流是Java API的新成员,它允许你以声明性方式处理数据集合,可以把它们看成遍历数据集的高级迭代器。
List<Dish> menu = Arrays.asList( new Dish("pork", false, 800, Dish.Type.MEAT), new Dish("beef", false, 700, Dish.Type.MEAT), new Dish("chicken", false, 400, Dish.Type.MEAT), new Dish("french fries", true, 530, Dish.Type.OTHER), new Dish("rice", true, 350, Dish.Type.OTHER), new Dish("season fruit", true, 120, Dish.Type.OTHER), new Dish("pizza", true, 550, Dish.Type.OTHER), new Dish("prawns", false, 300, Dish.Type.FISH), new Dish("salmon", false, 450, Dish.Type.FISH) ); //获取>400的 高热量菜单的名称 List<String> threeHighCaloricDishNames = menu.stream().filter(d -> d.getCalories() > 400).sorted().map(Dish::getName).collect(Collectors.toList());
2 流操作
java.util.stream.Stream中的Stream接口定义了许多操作。它们可以分为两大类。
中间操作 :中间操作会返回另一个流。
终端操作 :终端操作会从流的流水线生成结果。其结果是任何不 是流的值,比如List、 Integer,甚至void。
使用流
1.筛选和切片使用谓词筛选-filter(boolean):接受一个谓词(一个返回boolean的函数)作为参数
stream().filter(Dish::isVegetarian).collect(toList());
筛选各异的元素-distinct
stream().filter(i -> i % 2 == 0) .distinct().forEach(System.out::println);
截短流-limit(n):返回一个指定长度的流
stream().filter(d -> d.getCalories() > 300) .limit(3).collect(toList());
跳过元素-skip(n):跳过前n个元素
stream().filter(d -> d.getCalories() > 300) .skip(2).collect(toList());
2.映射
一个非常常见的数据处理套路就是从某些对象中选择信息。比如在SQL里,你可以从表中选择一列。 Stream API也通过map和flatMap方法提供了类似的工具。
对流中每一个元素应用函数 - map
List<String> words = Arrays.asList("Java 8", "Lambdas", "In", "Action"); List<Integer> wordLengths = words.stream() .map(String::length) .collect(toList());
流的扁平化 - flatMap
flatMap和map有什么区别呢?flatMap的作用是将所有使用流集合合并起来,扁平化为一个流。
Stream<String[]> -> flatMap -> Stream<String> Stream<Set<String>> -> flatMap -> Stream<String> Stream& 4000 lt;List<String>> -> flatMap -> Stream<String> Stream<List<Object>> -> flatMap -> Stream<Object>
List<Integer> numbers1 = Arrays.asList(1, 2, 3); List<Integer> numbers2 = Arrays.asList(3, 4); Stream<Stream<int[]>> stream3 = numbers1.stream().map(i -> numbers2.stream().map(j -> {return new int[]{i,j};}));//map Stream<int[]> stream4 = numbers1.stream().flatMap(i -> numbers2.stream().map(j -> {return new int[]{i,j};}));//flatMap的作用是将多个流合并为一个流
3.查找和匹配
anyMatch: T-> boolean
allMatch: T-> boolean
noneMatch: T-> boolean
findAny: () -> Optional<?>
findFirst: () -> Optional<?>
boolean existFlag = menu.stream() .anyMatch(Dish::isVegetarian); boolean allMatchFlag = menu.stream() .allMatch(Dish::isVegetarian); boolean noneMatchFlag = menu.stream() .noneMatch(Dish::isVegetarian); Optional<Dish> anyVegetarian = menu.stream() .filter(Dish::isVegetarian).findAny(); boolean firstVegetarianFlag = menu.stream() .filter(Dish::isVegetarian).findFirst().isPresent();
4.规约
元素求和
最大值和最小值
List<Integer> numbers1 = Arrays.asList(1, 2, 3); int sum = numbers1.stream().reduce(0, (a, b) -> a + b); sum = numbers1.stream().reduce(0, Integer::sum); int multi = numbers1.stream().reduce(1, (a, b) -> a * b); int max = numbers1.stream().reduce(0, (a, b) -> a > b ? a : b); max = numbers1.stream().reduce(0, Integer::max); //无初始值时,返回的为Optional<?> Optional<Integer> sumOpt = numbers1.stream().reduce( Integer::sum);
迄今为止,我们看到了很多流的操作,在这里做个总结:
5.数值流
Java 8引入了三个原始类型特化流接口来解决这个问题: IntStream、 DoubleStream和LongStream,分别将流中的元素特化为int、 long和double。每个接口都带来了进行常用数值归约的新方法,比如对数值流求和的sum,min,max,average等。
数值流与对象流相互转换
OptionalInt,OptionalDouble,OptionalLong
IntStream intStream = menu.stream() .mapToInt(Dish::getCalories);//转换为数值流 Stream<Integer> stream = intStream.boxed();//转换回对象流 OptionalInt maxCalories = intStream.max();
数值范围rangeClosed,range
IntStream.rangeClosed(1,3); //[1,3] IntStream.range(1,3); //[1,3)
6.构建流
由值创建流
由数组创建流
Stream<String> emptyStream = Stream.empty();//获取空流 Stream<String> stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action"); int[] numbers = {2, 3, 5, 7, 11, 13}; //数组构建流,可以将原始的数组转换为一个IntStream int sum = Arrays.stream(numbers).sum();
由函数生成流:创建无限流
Stream.iterate(0, n -> n + 2).limit(10); //迭代 Stream.generate(Math::random).limit(10); //生成
用流收集数据
参考资料
java8 in action
相关文章推荐
- Java 8实战之读书笔记三:函数式数据处理
- java8实战三:函数式数据处理--流
- Java编程的逻辑 (93) - 函数式数据处理 (下)
- 云星数据---Apache Flink实战系列(精品版)】:Flink流处理API详解与编程实战009-DataStream与MySql自定义sink和source(Java版)001
- 云星数据---Apache Flink实战系列(精品版)】:Flink流处理API详解与编程实战010-DataStream与MySql自定义sink和source(Java版)002
- Java 8——函数式数据处理(流)
- 云星数据---Apache Flink实战系列(精品版)】:Flink流处理API详解与编程实战011-DataStream与MySql自定义sink和source(Java版)003
- java处理json类型数据--阿里巴巴fastjson api常用方法实战
- Hadoop链式MapReduce、多维排序、倒排索引、自连接算法、二次排序、Join性能优化、处理员工信息Join实战、URL流量分析、TopN及其排序、求平均值和最大最小值、数据清洗ETL、分析气
- 大数据IMF传奇行动绝密课程第60课:使用Java和Scala在IDE中实战RDD和DataFrame动态转换操作
- JAVA处理千万级数据(单线程)
- 【Java】自从有了BigInteger,我再也不用担心要处理的数据有多大了
- HBase学习之四: mapreduce处理数据后存储到hbase及错误java.lang.NoClassDefFoundError的解决办法
- SpringMVC实战(四)-处理模型数据
- 大数据处理之hadoop实战(1)
- 使用Java处理XML数据
- 字符串处理是许多程序中非常重要的一部分,它们可以用于文本显示,数据表示,查找键和很多目的.在Unix下,用户可以使用正则表达式的强健功能实现这些 目的,从Java1.4起,Java核心API就引入了java.util.regex程序包,它是一种有价值的基础
- 大数据处理技术 - 基于Hadoop的实战
- 文本挖掘--数据文本处理-java
- java同步数据时候处理生僻字