java8 函数式编程
2017-09-25 11:45
453 查看
1、简单的lamda表达式
如果一个接口中有多个方法,lamda不支持interface A { void testA(); } interface B { void testB(int x); } public class Test{ public static void main(String[] args) { //不带参数的lamda表达式 A a = ()->{ /*TODO*/ }; //只有一条语句的lamda表达式 B b = x -> System.out.println(x); //带参数的lamda表达式 B b1 = (int x) -> { /*TODO*/ }; } }
2、流
public class Test{ static ArrayList<Integer> list = new ArrayList<>(); public static void main(String[] args) { for (int i = 0; i < 30; i++) { list.add(i); } //迭代器遍历 Iterator<Integer> iterator = list.iterator(); while(iterator.hasNext()) { Integer data = iterator.next(); if(data == 10) { System.out.println("find data==>"+10); } } //使用流进行遍历 long count = list.stream().filter(data -> { if(data==10) { System.out.println("find data==>" + 10); return true; } return false; }).count(); System.out.println("count==>"+count); } }
以上都是遍历集合,查找并打印。
第一种使用迭代器操作
第二种使用流操作
filter为过滤方法,只是描述stream,但是不会做什么实质的工作。这种方法叫做懒性求值方法。
count会从stream产生值,叫做及早求值方法
2.1 一些常用的流操作
2.1.1List<String> list = Stream.of("a", "b", "c").collect(Collectors.toList());
of方法将一组初始值生成新的Stream。
collect方法将Stream中的值生成一个集合。
2.1.2
public static void main(String[] args) { List<Integer> src = new ArrayList<>(); for (int i = 0; i < 10; i++) src.add(i); List<String> dst = src.stream() .map(x -> String.valueOf(x)) .collect(Collectors.toList()); }
map中的参数其实是一个Function接口
map方法将参数从一种类型转换为另一种类型,这两种类型可以毫无关系。
2.1.3
List<Integer> dst = src.stream() .filter(x -> x<10) .collect(Collectors.toList());
filter的参数是Predicate接口,参数返回boolean。Stream值保留返回true的值。
2.1.4
import java.util.List; import java.util.stream.Stream; import static java.util.Arrays.asList; import static java.util.stream.Collectors.toList; List<Integer> list = Stream.of(asList(1, 2), asList(3, 4)) .flatMap(numbers -> numbers.stream()) .collect(toList());
flatmap将多个stream合并为一个stream
2.1.5
int min = Stream.of(1, 2, 3, 4, 5) .min(Comparator.comparing(x -> x)) .get();
min/max 获取最小/最大值,需要实现Comparator接口
2.1.6
int count = Stream.of(1, 2, 3, 4, 5) .reduce(0, (acc, element) -> acc+element);
reduce可以将一组值生成一个值,count,min, max都是reduce的一种。
需要注意的是在lamda函数其实是接口,会设计内部方法自动添加final字段
3.1 基本类型
IntSummaryStatistics res = list.stream().mapToInt(x -> x).summaryStatistics(); res.getSum(); res.getMax();
lamda封装了基本类型的操作,可以使用mapToxxx方法进行具体的转换。
调用summaryStatistics方法将返回xxxSummaryStatistics.里面封装了具体的求最大值、最小值、和、平均值等操作。
3.2 @FunctionalInterface
FunctionalInterface注解用于标识lamda接口,将代码块作为数据打包起来。该注解会强制javac检查一个接口是否符合lamda函数接口的标准。如果该注解添加在枚举、类、另一个注解或者接口不止一个抽象方法,javac会报错。重构代码时,可以很容易发现问题。
3.3 方法引用
//data为Model类型 l//amda表达式片段为 data -> data.get(); //等价于 Model::get
3.4 collect收集器
3.4.1LinkedBlockingQueue res = list.stream().collect(Collectors.toCollection(LinkedBlockingQueue::new));
Collectors.toCollection方法可以将集合转换为任意Set或Collectoion的子类
3.4.2
求值操作,如求最大值、最小值、平均值。需要注意返回类型。求值操作可以有具体的类型,如averagingInt、averagingXXX
class Model { private int data; public int getData() { return data; } public Model(int data){ this.data = data; } } public class Test{ public static void main(String[] args) { List<Model> list = new ArrayList<>(); for (int i = 0; i < 10; i++) list.add(new Model(i)); //平均值 double res = list.stream().collect(Collectors.averagingInt(Model::getData)); //求最大值 Optional<Model> d = list.stream().collect(maxBy(comparing(Model::getData))); } }
3.4.3
Map<Boolean, List<Model>> res = list.stream().collect(partitioningBy(x -> x.getData() > 5));
partitioningBy可以将一个集合按照条件分割成多个集合
3.4.4
组合收集器,可以将多个操作组合使用。
Map<Integer, Long> res = list.stream().collect(groupingBy(x -> x.getData(), counting()));
groupingBy可以将两个操作一起返回。
x -> x.getData()对应Map的Integer,counting()对应Map的Long
4、并行流处理
普通流调用parallel()或集合调用parallelStream()即可获得一个拥有并行能力的流。并行处理的性能
数据的大小:并行处理是将数据分割、处理、合并。数据量足够大才能充分体现效率。
源数据结构:
ArrayList、数组或者IntStream支持随机读取的数据结构容易分割。性能较好
HashSet、TreeSet这些不容易分割,但是可以分割。性能一般
LinkedList、Streams.iterate等需要O(N)时间复杂度来分解问题,性能较差
装箱:基本类型比装箱类型效果好
cpu核心数:核心越多,效果越好
单元处理开销:花在流中每个元素的时间越长,效果越好
4.1 并行化数组操作
Arrays.parallelPrefix //计算数组的和 Arrays.parallelSetAll //更新数组元素 Arrays.parallelSort //并行化对数组元素排序
5、调试
使用peek方法可以用于调试打印,不会影响正常的操作list.stream().peek(natie -> System.out.println("==>"+natie.getData())).count();
相关文章推荐
- paip. java的 函数式编程 大法
- Java 函数式编程和 lambda 表达式
- Java FP: Java中函数式编程的Map和Fold(Reduce)
- Java编程的逻辑 (93) - 函数式数据处理 (下)
- paip.提升效率---filter map reduce 的java 函数式编程实现
- OOP23-Java函数式编程
- Java 8(一)函数式编程
- Java经典类库-Guava中的函数式编程讲解
- Java8 新特性之流式数据函数式编程
- Java函数式编程
- Java 中的一种更轻松的函数式编程途径
- Java8:函数式编程与Lambda表达式
- 函数式编程-Java8语法分析
- java8 函数式编程
- java函数式编程之Consumer
- Java8 Lambda表达式 函数式编程
- java 8函数式编程与Lambda表达式
- 简要介绍JAVA8中的函数式编程;Brief Introduction to Functional Programming in Java 8
- Java 8 函数式编程
- java guava 函数式编程