1.Lambda表达式
1.Lambda的作用
- 作用
- Lambda表达式的作用就是简化代码,省略了面向对象中类和方法的书写。
2.Lambda的格式
三个部分
- 一些参数
- 一个箭头
- 一段代码
标准格式
(参数)->{一段代码}
3.案例演示
线程案例演示
public class Demo_线程演示 { public static void main(String[] args) { //匿名内部类 //Thread t1 = new Thread(new Runnable() { // @Override // public void run() { // for (int i = 0; i < 10000; i++) { // System.out.println(i); // } // } //}); //t1.start(); //--------------------------------------------- //Lambda表达式 //()里面写的是run()方法的参数 Thread t2 = new Thread(()->{ for (int i = 0; i < 10000; i++) { System.out.println(i); }}); t2.start(); for (int i = 0; i < 10000; i++) { System.out.println("主线程" + i); } } }比较器案例演示
public class Demo_比较器演示 { public static void main(String[] args) { //比较器 ArrayList<Integer> list = new ArrayList<>(); //添加元素 list.add(324); list.add(123); list.add(67); list.add(987); list.add(5); System.out.println(list); //排序(默认从小到大) //Collections.sort(list); //Comparator是比较器,那能够让我们自己定义比较规则 //匿名内部类 /* 返回值是一个整数: 整数如果是一个正数,就会把元素往后放 整数如果是一个负数,就会把元素往前放 整数如果是零,就认为元素相等,不移动 参数: o1 代表的是当前要存放的元素 o2 代表的是已经排好位置的元素 */ //Collections.sort(list, new Comparator<Integer>() { // @Override // public int compare(Integer o1, Integer o2) { // return o2 - o1; // } //}); //Lambda表达式 Collections.sort(list, (Integer o1, Integer o2)->{return o2 - o1;}); //打印集合 System.out.println(list); } }
4.省略格式
省略规则
- 小括号内参数的类型可以省略
- 如果小括号内有且仅有一个参,则小括号可以省略
- 如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号、return关键字及语句分号
示例代码
//Lambda表达式(不简化写法) Collections.sort(list, (Integer o1, Integer o2)->{return o2 - o1;}); //写的越精简,阅读性就越差 //简化写法 Collections.sort(list, (o1, o2)-> o2 - o1);
5.Lambda的前提条件
- 使用Lambda必须具有接口,且要求接口中的抽象方法有且仅有一个。(别的方法没有影响)
- 使用Lambda必须具有上下文推断。
6.函数式接口
如果一个接口中只有一个抽象方法,那么这个接口叫做是函数式接口。
@FunctionalInterface这个注解 就表示这个接口是一个函数式接口
7.小结
匿名内部类:
可以用于类也可以用于接口,对类和接口中的方法的个数没有要求。
Lambda表达式:
只能用于接口,接口中抽象方法只能有一个。
Lambda表达式的要求更严格,并不是所有的匿名内部类都能改成成Lambda表达式。
2.Stream流
1.概述
Stream用来解决之前集合的弊端。
Stream流相当于是流水线的操作,可以对一个集合进行多次操作。
2.获取流的方式
- Collection单列集合
- 调用stream()方法
- Map双列集合
- 调用keySet()把键转成单列集合,再调用stream()转成流
- 调用values()把值转成单列集合,再调用stream()转成流
- 数组
- 数组使用Stream.of()静态方法(基本类型数组需要写成对应包装类)
3.常用方法
演示的代码:
- 下面的方法演示都是基于这个集合:
//创建集合
ArrayList<String> list = new ArrayList<>();
list.add("张翠山");
list.add("张无忌");
list.add("赵敏");
list.add("张三丰");
list.add("张三");
//转成Stream流
Stream<String> stream = list.stream();
终结方法:调用了终结方法,这个流对象就不能在做其他操作了。
count(): 统计个数
long count = stream.count(); System.out.println(count); //流中元素的个数 5forEach() :逐一处理
//打印流中的每个元素 stream.forEach((String s)->{ System.out.println(s); }); //把Lambda简化之后的写法: stream.forEach(s->System.out.println(s));
非终结方法:支持链式编程,可以继续调用流的其他方法。
filter() :过滤筛选
如果返回值是true就留下这个元素 , 如果返回值是false就过滤掉这个元素
//筛选留下所有姓张的人 stream.filter((String s)->{return s.startsWith("张");}). forEach(s->System.out.println(s)); //把Lambda简化之后的写法: stream.filter(s->s.startsWith("张")).forEach(s->System.out.println(s));limit(): 取用前几个
//获取流的前三个元素 stream.limit(3).forEach(s-> System.out.println(s));skip(): 跳过前几个
//跳过前三个元素获取剩余的元素 stream.skip(3).forEach(s-> System.out.println(s));map() : 映射方法(把元素进行转换)
//把流中的元素换成字符串对应的长度(这就相当于是一个字符串和整数的映射) stream.map((String s)->{return s.length();}).forEach(s-> System.out.println(s)); 流中的字符串会变成整数: 3 3 2 3 2concat() :组合(把两个流拼接成一个流)
//筛选出姓张的人(过滤掉了不姓张的人) //张翠山 张无忌 张三丰 张三 Stream<String> s1 = list.stream().filter(s -> s.startsWith("张")); //筛选出姓名是三个字的人中的前两个人 //张翠山 张无忌 Stream<String> s2 = list.stream().filter(s -> s.length() == 3).limit(2); //concat() :拼接(静态方法可以使用类名调用) Stream<String> ss = Stream.concat(s1, s2); //打印 ss.forEach(s-> System.out.println(s)); //上面代码可以用链式编程简化成下面写法,不过不推荐写太长: Stream.concat(list.stream().filter(s -> s.startsWith("张")), list.stream().filter(s -> s.length() == 3).limit(2)).forEach(s-> System.out.println(s));
4.练习
- 需求:
List<String> one = new ArrayList<>();
one.add("迪丽热巴");
one.add("宋远桥");
one.add("苏星河");
one.add("老子");
one.add("庄子");
one.add("孙子");
one.add("洪七公");
List<String> two = new ArrayList<>();
two.add("古力娜扎");
two.add("张无忌");
two.add("张三丰");
two.add("赵丽颖");
two.add("张二狗");
two.add("张天爱");
two.add("张三");
//Person类
public class Person {
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{name='" + name + "'}";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/*
1. 第一个队伍只要名字为3个字的成员姓名;
2. 第一个队伍筛选之后只要前3个人;
3. 第二个队伍只要姓张的成员姓名;
4. 第二个队伍筛选之后不要前2个人;
5. 将两个队伍合并为一个队伍;
6. 根据姓名创建 Person 对象;
7. 打印整个队伍的Person对象信息
*/
- 示例代码:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class Demo05_练习 {
public static void main(String[] args) {
List<String> one = new ArrayList<>();
one.add("迪丽热巴");
one.add("宋远桥");
one.add("苏星河");
one.add("老子");
one.add("庄子");
one.add("孙子");
one.add("洪七公");
List<String> two = new ArrayList<>();
two.add("古力娜扎");
two.add("张无忌");
two.add("张三丰");
two.add("赵丽颖");
two.add("张二狗");
two.add("张天爱");
two.add("张三");
//1. 第一个队伍只要名字为3个字的成员姓名;
//2. 第一个队伍筛选之后只要前3个人;
//one.stream().filter((String s)->{return s.length()==3;});
Stream<String> s1 = one.stream().filter(s -> s.length() == 3).limit(3);
//3. 第二个队伍只要姓张的成员姓名;
//4. 第二个队伍筛选之后不要前2个人;
Stream<String> s2 = two.stream().filter(s -> s.startsWith("张")).skip(2);
//5. 将两个队伍合并为一个队伍;
Stream<String> s3 = Stream.concat(s1, s2);
//6. 根据姓名创建 Person 对象;
//参数是原先的类型 返回值是要转成的类型
//s3.map((String s)->{return new Person(s);});
//7. 打印整个队伍的Person对象信息
s3.map(s->new Person(s)).forEach(s-> System.out.println(s));
}
}
5.收集(把流转成数组或集合)
以下代码基于这个集合:
List<String> one = new ArrayList<>();
one.add("迪丽热巴");
one.add("宋远桥");
one.add("苏星河");
one.add("老子");
one.add("庄子");
one.add("孙子");
one.add("洪七公");
//s1流里面保存的是 宋远桥 苏星河 洪七公
Stream<String> s1 = one.stream().filter(s -> s.length() == 3).limit(3);
收集成List集合
collect(Collectors.toList());
List<String> list = s1.collect(Collectors.toList()); System.out.println("list" + list);
收集成Set集合
collect(Collectors.toSet());
Set<String> set = s1.collect(Collectors.toSet()); System.out.println("set" + set);
收集成数组
toArray(); 返回值是Object[]
Object[] arr = s1.toArray(); System.out.println(Arrays.toString(arr));
收集到Map集合
collect(Collectors.toMap(键的内容,值的内容));
//姓名作为键,姓名的长度作为值 s1.collect(Collectors.toMap(s->s,s->s.length()));
版权声明:本文为weixin_44253023原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。