lambda及stream学习

lambda及stream学习

今日板砖,见lambda,不知其然遂不以为意。后又数现之,于是乎查之,究之,学之。半晌,豁然开朗!

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表达式,无需用对象实现接口,再继承重写抽象方法,直接通过()->{},传递参数,自定义逻辑,即可创建匿名内部类;

代码说明

  1. 无参无返回

    /**
     * 测试无返回值无参数
     */
    @FunctionalInterface
    public interface LambdaNoRNoP {
        void testNoRNop();
    }
    
     //无参无返回
    LambdaNoRNoP lam1 = ()->{System.out.println("hello");};//创建一个匿名内部类,重写testNoRNop()方法
    lam1.testNoRNop(); 
    
  2. 有参数有返回值

    /**
     * 测试有返回值多个参数
     */
    @FunctionalInterface
    public interface LambdaRMulP {
        int testRMulP(int a ,int b);
    }
    
    //有返回值,多个参数
    LambdaRMulP lam6 = (int a ,int b )->{ return a+b; };
    System.out.println(lam6.testRMulP(1,2));
    

代码精简

  1. 由于在接口的抽象方法中,已经定义了参数数量和类型,所以在lambda中,参数类型可以省略
  2. 如果只有一个参数,小括号可以省略
  3. 如果方法体中只有一条语句,大括号可以省略
//参数类型精简
 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);

@FunctionalInterface  //说明是个函数时接口,抽象方法接收一个对象,返回一个boolean值
public interface Predicate<T> {

    boolean test(T t);
  }
  

常用操作

数据操作
  1. 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));//打印对象
    }
    
  2. 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);
    }
    
  3. 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));
        }
    
  4. 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());//降序排序
    }
    
  5. 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());
    }

  1. 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收集器
  1. 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));
}
  1. toSet 转为不可重复集合

        //测试collect收集器 toSet //不可重复
        public static  void testCollectToSet(List<Integer>list){
            Set<Integer> collect = list.stream().collect(Collectors.toSet());
            collect.forEach(System.out::println);
        }
    
  2. 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));
        }
    
  3. 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对象
        }
    
  4. 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());
        }
    
  5. 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));
        }
    
  6. 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);
        }
        }
    
常用操作
  1. list对对象的某个元素求和

        //测试match
        //allMatch--集合内所有元素都满足返回true
        //anyMatch--任意一个元素满足就返回true
        //noneMatch--没有元素满足就返回true
     	list.stream()
     		.map(o -> o.getAmount()) //获取对象中的数量
     		.filter(o -> Objects.nonNull(o)) //过滤掉null值,不然求和会报错
     		.reduce(BigDecimal.ZERO, BigDecimal::add);	//累加器,第一个参数是初始化值;第二个参数是累加器,可以自定义
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值