Java8可以是一个里程碑的版本,提供了很多有用的特性。
作用:简化匿名内部类的代码写法
首先回顾一下匿名内部类:
(为什么要引入匿名内部类?是因为可以方便创建子类对象,最终目的是为了简化代码编写,具体可以指路:匿名内部类)
// 首先创建一个接口
interface inter{public void eat();
}public class AnonymousDemo
{public static void main(String[] args) {// 直接使用匿名内部类,重写eat方法并调用new inter(){@Overridepublic void eat() {System.out.println("正在调用eat方法");}}.eat();}
}
但是,Lambda看到这里还是觉得不够简便,所以进一步开始简化!
Lambda语法:
( parameter-list ) -> { expression-or-statements }
注:-> 是语法形式,无实际含义
所以上面的可以简化成:
interface inter{public void eat();
}
public class AnonymousDemo {public static void main(String[] args) {// 这里的eat函数没有参数,另外实现语句只有一句,就省略{}inter myInter = () -> System.out.println("正在调用eat方法");myInter.eat(); // 调用eat方法}
}
Lambda表达式本身就是一个接口的实现,Lambda表达式只能简化函数式接口的匿名内部类的写法形式
什么是函数式接口?
首先必须是接口、其次接口中有且仅有一个抽象方法的形式
常会在接口上加上一个@FunctionalInterface
注解,标记该接口必须是满足函数式接口
最后用两张图进行Java8 和Java7的对比,参考https://www.zhihu.com/question/20125256/answer/324121308
第一张图,和上面的例子很像,原本java7必须得按照面向对象那套流程;而Java 8的Lambda可以直接将接口的实现赋值给一个变量。
第二张图,是说明上面那个“变量”可以当作参数传给其他函数(传统的Java 7必须要求定义一个实现类)
直接通过几种不同场景来熟悉Lambda
借用线程中的接口来演示一下
(1)无参数,无返回体
() -> System.out.println("零参数 lambda");
(2)一个参数,无返回值
// 实现Function接口
Function add = (x) -> x + 1;
int result = add.apply(5); // result = 6
(3)两个参数,有返回值
public static void findMaxValue(int num1,int num2){Comparator comparatorMax = (o1, o2) ->{log.info("o1:{}",o1);log.info("o2:{}",o2);return (o1
作用:用来简化数组和集合的操作
简单说就是 Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等
可以先看一个小例子:
要求是:创建一个集合,存储多个字符串元素,把集合中所有以"张"开头的元素存储到一个新的集合,把"张"开头的集合中的长度为3的元素存储到一个新的集合最后遍历
如果按照正常编程,可能得挨个遍历对元素进行判断处理,但是Stream编程就可以一步到位
public class StreamDemo {public static void main(String[] args) {//集合的批量添加ArrayList list1 = new ArrayList<>(List.of("张三丰","张无忌","张翠山","王二麻子","张良"));//Stream流list1.stream().filter(s->s.startsWith("张")).filter(s->s.length() == 3).forEach(s-> System.out.println(s));}
}
Stream流的主要构成(三类方法)
下面将对三个组成进行分别介绍
Stream操作集合或者数组的第一步是先得到Stream流,然后才能使用流的功能。
(1)Collection集合获取Stream流的方式
可以使用Collection接口中的默认方法stream()生成流
// 获取当前集合对象的Stream流
default Stream stream()
(2) Map体系集合
把Map转成Set集合,间接的生成流
(3)数组获取Stream流的方式
通过Arrays中的静态方法stream生成流
方法 | 含义 |
---|---|
public static Stream stream(T[ ] array) | 获取当前数组的Stream流 |
public static Stream of(T… values) | 获取当前数组/可变数据的stream流 |
public class StreamDemo {public static void main(String[] args) {//Collection体系的集合可以使用默认方法stream()生成流List list = new ArrayList();Stream listStream = list.stream();//Map体系的集合间接的生成流Map map = new HashMap();Stream keyStream = map.keySet().stream();Stream valueStream = map.values().stream();Stream> entryStream = map.entrySet().stream();//数组可以通过Arrays中的静态方法stream生成流String[] strArray = {"hello","world","java"};Stream strArrayStream = Arrays.stream(strArray);
}
方法 | 含义 |
---|---|
stream filter(Predicate< ? super T> predicate) | 用于对流中的数据进行过滤 |
stream limit( long maxsize) | 获取前几个元素 |
stream skip(long n) | 跳过前几个元素 |
stream distinct( ) | 去除流中重复的元素。依赖(hashCode和equals方法) |
static stream concat(Stream a,Stream b) | 合并a和b两个流为一个流 |
中间方法也称为非终结方法,调用完成后返回新的Stream流可以继续使用,支持链式编程。
在Stream流中无法直接修改集合、数组中的数据
方法 | 含义 |
---|---|
void forEach(Consumer action) | 对此流的每个元素执行遍历操作 |
long count() | 返回此流中的元素数 |
终结操作方法,调用完成后流就无法继续使用了,原因是不会返回Stream了
把Stream流操作后的结果数据转回到集合或者数组中去
方法名 | 说明 |
---|---|
R collect(Collector collector) | 把结果收集到集合中 |
具体收集方法(Collector工具类):
方法名 | 说明 |
---|---|
public static Collector toList() | 把元素收集到List集合中 |
public static Collector toSet() | 把元素收集到Set集合中 |
public static Collector toMap(Function keyMapper,Function valueMapper) | 把元素收集到Map集合中 |
上一篇:OpenCV库编译移植