lambda及stream学习
Posted Vicious丶Sea
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lambda及stream学习相关的知识,希望对你有一定的参考价值。
今日板砖,见lambda,不知其然遂不以为意。后又数现之,于是乎查之,究之,学之。半晌,豁然开朗!
lambda
lambda可以理解为一个匿名函数,可以将函数作为参数传入方法中,语法:() -> {}
():用来描述参数列表
{}:用来描述方法体
对比
//1.原始创建线程方法
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("原始创建线程方法");
}
});
thread.start();
// new Thread()括号中存储的是实现了Runnable接口的一个匿名内部类;
//2. lambda创建线程方式
Thread thread1 = new Thread(()-> System.out.println("lambda线程方式"));
thread1.start();
//可以理解为,lambda创建了一个实现了Runnable接口的匿名内部类,()代表没有传递参数; System.out.println("lambda线程方式")是run()方法具体的逻辑;
lambda是针对函数式接口的一种快捷实例化方式,函数式接口为有且只有一个抽象方法的接口。使用lambda表达式,无需用对象实现接口,再继承重写抽象方法,直接通过()->{},传递参数,自定义逻辑,即可创建匿名内部类;
代码说明
-
无参无返回
/**
* 测试无返回值无参数
*/ -
有参数有返回值
/**
* 测试有返回值多个参数
*/
代码精简
由于在接口的抽象方法中,已经定义了参数数量和类型,所以在lambda中,参数类型可以省略
如果只有一个参数,小括号可以省略
如果方法体中只有一条语句,大括号可以省略
//参数类型精简
LambdaNoRMulP lam1 = (a,b)->{System.out.println(a);};
lam1.testNoRMulP(1,2);
//小括号精简
LambdaNoRSingleP lam2 = a -> {System.out.println(a);};
//大括号精简
LambdaNoRSingleP lam3 = a -> System.out.println(a);
方法引用
可以将lambda方法的实现,指向一个完整的方法,可以理解为解耦;
语法: 方法归属者::方法名
方法归属者:如果是静态方法,归属者就是类,如果是非静态方法,归属者就是对象。
要求:参数数量和类型一级返回值要和接口中定义的方法一致
public class Test{
private static int change(int a){
return a*2;
}
}
LambdaRSingleP lam2 = a-> a*2;
//等同于
LambdaRSingleP lam1 = a-> change(a);//lambda的实现a*2和change()返回值一致,可以直接引用change(a)方法
//等同于
LambdaRSingleP lam3 =Test::change;//lambda表达式是传入一个int值,返回两倍的值,和Test类中的change方法逻辑一致,可以直接引用;
stream学习
stream是java8中用来操作集合的,可以理解为另类的iterator,可以对其中元素进行操作。
举例说明
//筛选集合中满足要求的数据
List<User> userList = new ArrayList<>();
User user1 = new User("cz1",18);
User user2 = new User("cz2",19);
User user3 = new User("cz3",20);
userList.add(user1);
userList.add(user2);
Stream<User> stream = userList.stream();//将list转为stream流
Stream<User> userStream = stream.filter(o -> o.getAge() > 19);//过滤流中满足要求的数据,生成新的流
List<User> collect = userStream.collect(Collectors.toList()); // 将过滤的流转为集合
分析filter()方法源码
//filter方法传入的是一个Predicate<T>接口的实现类
Stream<T> filter(Predicate<? super T> predicate);
常用操作
数据操作
-
map 集合对象中的某个元素再转为集合
public static void testMap(List<User> userList){
List<String> collect = userList.stream().map(o -> o.getName()).collect(Collectors.toList());//获取姓名集合
List<String> collect2 = userList.stream().map(User::getName).collect(Collectors.toList());//获取姓名集合
collect.forEach(o->System.out.println(o));//打印对象
} -
flatMap 流元素合并
public static void testFlatMap(List<User> userList1 , List<User> userList2){
List<List<User>> lists = new ArrayList<>();
lists.add(userList1);
lists.add(userList2);
//将集合里的元素(集合)转为流,再将流组合为一个大的集合
List<User> collect = lists.stream().flatMap(item -> item.stream()).collect(Collectors.toList());
//合并集合
collect.forEach(System.out::println);
} -
distinct 去重
//测试distinct 去重
public static void testDistinct(){
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(1);
List<Integer> collect = list.stream().distinct().collect(Collectors.toList());
collect.forEach(o-> System.out.println(o));
} -
sorted 排序
//测试sorted 排序
public static void testSort(){
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(1);
List<Integer> collect = list.stream().sorted((o1, o2) -> o1 - o2).collect(Collectors.toList());//升序排序
List<Integer> collect2 = list.stream().sorted((o1, o2) -> o2 - o1).collect(Collectors.toList());//降序排序
} -
limit 限流,只取几个元素
//测试limit限读
public static void testLimit(){
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(1);
List<Integer> collect = list.stream().limit(1).collect(Collectors.toList());
System.out.println(collect.size());
}
-
skip 跳过读取
//测试skip 跳过读取操作
public static void testSkip(){
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(1);
List<Integer> collect = list.stream().skip(2).collect(Collectors.toList());
collect.forEach(o-> System.out.println(o));
}
Collectors收集器
-
toMap 对象元素转map集合
//测试collect收集器 toMap
public static void testCollectToMap(List<User> userList){
//以元素的name作为k,age作为v转为map集合
Map<String, Integer> collect = userList.stream().collect(Collectors.toMap(User::getName, User::getAge));
collect.forEach((o1,o2)-> System.out.println("K:"+o1+":V:"+o2));
}
-
toSet 转为不可重复集合
//测试collect收集器 toSet //不可重复
public static void testCollectToSet(List<Integer>list){
Set<Integer> collect = list.stream().collect(Collectors.toSet());
collect.forEach(System.out::println);
} -
groupingBy 集合对象分组
//测试groupingBy 分组
public static void testCollectGroupingBy(List<User> list){
Map<String, List<User>> collect = list.stream().collect(Collectors.groupingBy(User::getName));
collect.forEach((o1,o2)-> System.out.println("K:"+o1+"--V:"+o2));
} -
maxBy 取集合最大元素
//测试maxBy 获取最大元素
public static void testMaxBy(List<User> list){
//获取user对象中年龄最大的
Optional<User> collect = list.stream().collect(Collectors.maxBy((o1, o2) -> o1.getAge() - o2.getAge()));
System.out.println(collect.get());//拿到user对象
} -
minBy 取集合最小元素
//测试minBy 获取最小元素
public static void testMinBy(List<User> list){
Optional<User> collect = list.stream().collect(Collectors.minBy((o1, o2) -> o1.getAge() - o2.getAge()));
System.out.println(collect.get());
} -
mapping 获取元素的某个属性的集合
//测试mapping隐射取值
public static void testMapping(List<User> list){
List<String> collect = list.stream().collect(Collectors.mapping(User::getName,Collectors.toList()));
//等同于
List<String> collect1 = list.stream().map(o -> o.getName()).collect(Collectors.toList());
collect1.forEach(o-> System.out.println(o));
} -
match 判断集合是否匹配
//测试match
//allMatch--集合内所有元素都满足返回true
//anyMatch--任意一个元素满足就返回true
//noneMatch--没有元素满足就返回true
public static void testMatch(List<User> list){
public static void testMatch(List<User> list){
boolean b = list.stream().allMatch(o -> o.getAge() > 19);//判断集合中的所有用户年龄是否都大于19
System.out.println(b);
}
} -
以上是关于lambda及stream学习的主要内容,如果未能解决你的问题,请参考以下文章
JAVA8之lambda表达式详解,及stream中的lambda使用