day26 Lambda表达式 函数式接口、StreamAPI

1. Lambda
    1.1 概述    
        Lambda表达式是一种没有名字的函数,也可称为闭包,是java1.8发布的最重要的新特性。
    本质上是一段匿名内部类,也可以是一段可以传递的代码。也被叫做 箭头函数。
    1.2 优点
        是匿名内部类的简写方式,使代码更加简洁。
    1.3 和匿名内部类对比
        import java.util.Arrays;
        import java.util.Collections;
        import java.util.Comparator;
        import java.util.List;

        public class Test{
            public static void main(String[]args){
                String[] s  ={"7","1","3","5"};
                List<String> list = Arrays.asList(s);
                Collections.sort(list,new Comparator<String>(){
                    @Override
                    public int compare(String o1, String o2) {
                        Integer i1 = Integer.valueOf(o1);
                        Integer i2 = Integer.valueOf(o2);
                        return i1-i2;
                    }    
                });
                System.out.println(list);
                Collections.sort(list, (s1,s2)->{
                    Integer i1 = Integer.valueOf(s1);
                    Integer i2 = Integer.valueOf(s2);
                    return i2-i1;
                });
                System.out.println(list);
            }
        }
    1.4 语法结构
        (参数,参数,参数...) -> {方法体}
        1 无参和多参,小括号必须写
        2 只有一个参数的时候,小括号可以不写
        3 如果只有一条语句,大括号也可以不写,并且语句结尾不需要 分号
        4 如果只有一条语句,并且也是返回值语句的话,return 也要省略
        5 如果是多条语句,必须加{},就是正常编码,该写分号写分号,该写return就写return
    1.5 案例
        import java.util.Arrays;
        import java.util.Collections;
        import java.util.Comparator;
        import java.util.List;
        public class Test{
            public static void main(String[]args){
                Integer[] it = {5,2,9,8,6,7};
                List<Integer> list  = Arrays.asList(it);
                Collections.sort(list,new Comparator<Integer>(){
                    @Override
                    public int compare(Integer o1, Integer o2) {
                        return o1-o2;
                    }
                });
                System.out.println(list);
                Collections.sort(list,(o1,o2)->o2-o1);
                System.out.println(list);
            }
        }
2. 函数式接口
    2.1 概述
        英文称为Functional Interface  
        其本质是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
        核心目标是为了给Lambda表达式的使用提供更好的支持,进一步达到函数式编程的目标,可通过运用函数式编程极大地提高编程效率。  
        其可以被隐式转换为 lambda 表达式。
    2.2 特点
        函数式接口是仅制定一个抽象方法的接口,可以包含一个或多个静态或默认方法
        专用注解即@FunctionalInterface 检查它是否是一个函数式接口,也可不添加该注解
        如果有两个或以上 抽象方法,就不能当成函数式接口去使用,也不能添加@FunctionalInterface这个注解
        如果只有一个抽象方法,那么@FunctionalInterface注解 加不加 都可以当做函数式接口去使用
    2.3 自定义
        public class Test04{
        public static void main(String[]args){
            A a = new A();
            m1(a);
            m1(new MyFunction(){
                @Override
                public void print() {
                    System.out.println("内部类实现");
                }
            });
            m1(()->System.out.println("Lambda式写法"));
        }
        public static void m1(MyFunction function) {
            function.print();
        }
    }
    @FunctionalInterface
    interface MyFunction{
        public void print();
    }
    class A implements MyFunction{
        public void print(){
            System.out.println("我是类A");
        }
    }
    2.4 JDK自带的函数式接口
        Supplier : 表示供应商,有个get方法,无参,有返回值,一般用于获取数据
        Consumer : 表示消费者,accept,有参,无返回值
        Function ,函数操作, apply , 有参也有返回值
        Predicate 断言,用于做判断校验操作,test,需要传入参数并返回boolean类型
3. 方法、构造器、数组
    3.1 概述
        Lambda表达式的另外一种形式。
    3.2 方法引用
        import java.util.function.Supplier;
        public class Test {
            public static void main(String[]args){
                Integer i = 5;
                Supplier<String> s = i::toString;
                System.out.println(s.get());
                System.out.println(i.toString());
                
            }
        }
        import java.util.function.Function;
        public class Test {
            public static void main(String[]args){
                String s = "156";
                Function<String,Integer> f = Integer::parseInt;
                int value  = f.apply(s);
                System.out.println(value);
            }
        }
        import java.util.function.BiPredicate;
        public class Test {
            public static void main(String[]args){
                BiPredicate<String,String>bp = String::equals;
                System.out.println(bp.test("a",new String("b")));
            }
        }
    3.3 构造器引用
    import java.util.function.Function;
    import java.util.function.Supplier;
        public class Test {
            public static void main(String[]args){
                Supplier<Object> s = Object::new;
                System.out.println(s.get());
                Function<String,String> f = String::new;
                System.out.println(f.apply("eeq"));
            }
        }
    3.4 数组引用
    import java.util.function.Function;
    public class Test{
        public static void main(String[]args){
            Function<Integer,Integer[]> f = Integer[]::new;
            Integer[] arr = f.apply(3);
            for(Integer i : arr){
                System.out.println(i);
            }
        }
    }
4. Stream API
    4.1 概述
        数据渠道、管道,用于操作数据源(集合、数组等)所生成的元素序列。
        集合讲的是数据,流讲的是计算
        即一组用来处理数组,集合的API。
    4.2 特点
        Stream 不是数据结构,没有内部存储,自己不会存储元素。
        Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
        Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。
        不支持索引访问。
        延迟计算    
        支持并行    
        很容易生成数据或集合        
        支持过滤,查找,转换,汇总,聚合等操作。
    4.3 应用场景
        流式计算处理,需要延迟计算、更方便的并行计算
        更灵活、简洁的集合处理方式场景
    4.4 创建流的五种方式
        import java.util.Arrays;
        import java.util.List;
        import java.util.stream.IntStream;
        import java.util.stream.Stream;
        public class Test {
            public static void main(String[] args) {
                // 1 数组 , Stream.of
                String[] strings = {"a","b","c","d"};
                Stream<String> stream1 = Stream.of(strings);
                // 2 通过集合
                List<String> strings2  = Arrays.asList(strings);
                Stream<String> stream2 = strings2.stream();
                // 3 通过Stream.generate来创建
                // 创建一个无限流,里面全是1,并且通过limit 限制条数是5条
                Stream<Integer> generate = Stream.generate(()->1);
                generate.limit(5).forEach(x -> System.out.println(x));
                // 4 通过Stream.iterate来创建
                // 创建一个无限流,里面的数据有序,从2开始步长为3
                Stream<Integer> iterate = Stream.iterate(2, x->x+3);
                iterate.limit(5).forEach(x -> System.out.println(x));
                // 5 通过已有API
                String string = "abc";
                IntStream chars = string.chars();
                chars.forEach(x->System.out.println(x));
            }
        }

    4.5 转换算子
        4.5.1 概述
            转换算子:又称为中间操作,所有的转换算子得到的都是一个新的流,所以一般用于链式调用。
        常见的转换算子:
            limit: 取集合中的前几条数据
            filter: 对元素进行过滤筛选,不符合条件的就不要了。
            distinct:去除重复
            skip: 跳过
            map: 更改数组
            sorted: 排序
        只有转换算子,是不执行的,必须执行动作才会真正执行。
        4.5.2 常用方法
        import java.util.Arrays;
        import java.util.List;
        import java.util.stream.Collectors;
        import java.util.stream.Stream;
        public class Test {
            public static void main(String[] args) {
                List<String> list = Arrays.asList("s","f","f","q","a","s");
                //只要f filter
                Stream<String> s1 = list.stream();
                List<String> value1 = s1.filter(x->x.equals("f")).collect(Collectors.toList());
                System.out.println(value1);
                //不要奇数
                List<Integer> list1 = Arrays.asList(1,5,6,8,9,32,16,13);
                Stream<Integer> s2 = list1.stream();
                List<Integer> value2 = s2.filter(x->x%2==1).collect(Collectors.toList());
                System.out.println(value2);
                // skip : 跳过元素
                s1 = list.stream();
                List<String> value3 = s1.skip(2).collect(Collectors.toList());
                System.out.println(value3);
                // distinct : 去重
                s1 = list.stream();
                List<String> value4 = s1.distinct().collect(Collectors.toList());
                System.out.println(value4);
                // map : 遍历过程中对元素进行操作,比如涨薪
                List<Double> list2 = Arrays.asList(112.5,245.5,456.4);
                Stream<Double> s3 = list2.stream();
                List<Double> value5 = s3.map(x-> x*1.2).collect(Collectors.toList());
                System.out.println(value5);
                // limit 前几条,比如查看前两名
                s3 = list2.stream();
                // sorted 进行排序 y-x 是降序 , x-y 是升序
                value5 = s3.sorted((x,y)->{
                    if(y>x){
                        return 1;
                    }else if (y == x) {
                        return 0;
                    }else{
                        return -1;
                    }
                }).limit(2).collect(Collectors.toList());
                System.out.println(value5);
            }
        }

    4.6 动作算子
        import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Stream;
    public class Test {
        public static void main(String[] args) {
            List<String> strings = Arrays.asList("a", "b", "c", "a", "b", "c", "a",
                    "b", "c");
            Stream<String> stream = strings.stream();
            // forEach
            stream.forEach(x -> System.out.println(x));
            // 计数 count
            stream = strings.stream();
            long count = stream.filter(x->x.equals("a")).count();
            System.out.println(count);
            // max 获取最大值  min 最小值
            List<Integer> integers = Arrays.asList(1,2,3,4,5);
            Stream<Integer> integerStream = integers.stream();
            Integer i1 = integerStream.max((x,y)->x-y).get();
            System.out.println(i1);
            // anyMatch 匹配数据,比如是否包含
            integerStream = integers.stream();
            boolean flag = integerStream.anyMatch(x->x==5);
            System.out.println(flag);
            // 当然这种是否包含可以使用contains解决,但是有的是contains解决不了的
            System.out.println(integers.contains(5));
            // 比如 所有的用户中 是否有19岁的
            List<User> users = new ArrayList<User>();
            users.add(new User("a", 18));
            users.add(new User("b", 19));
            users.add(new User("c", 20));
            Stream<User> userStream = users.stream();
            flag = userStream.anyMatch(u->u.age==19);
            System.out.println(flag);
        }
    }
    class User{
        String name;
        int age;
        public User(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        
    }


        
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值