zoukankan      html  css  js  c++  java
  • Java 1.8 新特性

    Lambda表达式

    1、本质上是对匿名内部类对象的一种格式的简化

    2、Lambda运算符 "->",也称箭头运算符,作用 分隔前后两部分

    3、运算符左边是Lambda的参数列表(接口中定义的抽象方法的参数)

      右边是Lambda的方法体

    4、语法格式:

      1、没有参数和返回值  () -> System.out.println(“Hello Lambda”);

      2、有一个参数,没有返回值 (x)-> System.out.println(x * x);  当只有一个参数时,参数的括号可以省略

      3、有多个参数,没有返回值,格式和语法格式2相同 (x, y) -> System.out.println(x + y);

      4、接口中需要重写的方法,方法内容有多句,需要给多句话加上大括号 

        (x, y) -> {int result = x + y; return result;}

        如果Lambda体中语句只有一句,那么大括号可以省略不写;如果大括号中只有一条语句,并且是return语句,

      那么return关键字也可以省略不写(如果要省略return关键字,就必须省略大括号)

          例如:(x, y) -> x + y

    函数式接口

    1、Lambda表达式使用的前提,就是接口必须是一个函数式接口

    2、如果在接口中,只有一个抽象方法,那么这个接口就是函数式接口

    3、使用注解来检查当前接口是否是一个函数式接口

        @FunctionalInterface     如果不是函数式接口,则编译报错

    4、本质: 

      想表达的是一个方法的内容,由于方法不在任何类中,所以称为函数

      接口其实想表达的就是一个函数的声明

      将来使用这个接口的实现类对象,来表达一个函数的实现

      Java中不支持将函数作为一个数据,也就不能将这个函数进行各种传递,也就不能作为对象的成员变量存在

      只能在方法外加一层接口的声明,将来可以传递方法所在接口的实现类对象,来间接的传递方法内容

    5、常用内置函数式接口

      1.8中提供了一些常用的函数式接口,在使用类似功能的时候,不需要额外定义接口,直接使用jdk中提供的即可。  

      Consumer<T>:消费型接口

          void accept(T t);

      Supplier<T>:供给型接口

        T get();

      Function<T, R>:函数型接口

        R apply(T t);

      Predicate<T>:断言型接口

        boolean test(T t)

    6、方法的引用

      1、写一个函数式接口时,方法的实现(lambda体),已经被某个其他的对象实现了,就不需要在Lambda体中,再次调用这个实现,而可以直接使用那个已经定义好的方法。

      2、格式:

          函数式接口 名称 = 对象名 :: 方法名称

          函数式接口 名称 = 类名 :: 静态方法名

      3、作用:

          把已经实现的方法,作为一个数据,作为一个引用,赋值给某个函数式接口的引用

          可以把这个引用当做方法的返回值,也可以作为方法的实际参数进行传递

      4、本质:

          可以把任意一个方法,作为函数式接口的一个实现类对象

    方法的引用

    7、消费型接口 Consumer<T>

      抽象方法:void accept(T t);

      某个函数可以接收一个数据,并且处理这个数据,处理完成之后,不需要返回任何数据,这个函数需要当做数据来进行传递,就使用消费型接口。

    import java.util.function.Consumer;
    
    public class Test4 {
    
        public static void main(String[] args) {
            Consumer<String> con = x->System.out.println(x);
            test(998,con,"大宝剑");
        }
        public static void test(int money,Consumer<String> con,String str) {
            //只需要处理数据,不需要返回值Consumer<T>
            System.out.println("花了"+money+"块钱");
            con.accept(str);
        }
    }
    消费型接口

    8、供给型接口 Supplier<T>

      抽象方法:T get()

      如果需要定义函数,可以生产一个需要的数据,这个函数需要当做数据来进行传递,那么就可以使用供给型接口。

      以前我们只能传递数据,现在可以传递生产数据的方式。

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    import java.util.function.Supplier;
    
    public class Test6 {
    
        public static void main(String[] args) {
            Random r = new Random();
            //在参数中定义Lambda函数体
            List<Integer> list = getNum(10,()->r.nextInt(30)+21);
            System.out.println(list);
    
        }
        public static List<Integer> getNum(int n,Supplier<Integer> sup){
            List<Integer> list = new ArrayList<Integer>();
            for(int i=1;i<=n;i++) {
                list.add(sup.get());//供给对象调用get()方法获取生成的数据
            }
            return list;    
        }
    }
    供给型接口

    9、函数型接口 Function<T, R>

      抽象方法:R apply(T t)  

      如果需要定义一个函数,接收一个数据,将数据进行处理,完成之后,还能返回一个结果,就可以使用函数型接口

      以前我们只能传递处理好之后的数据,或者将原始数据传入方法

      现在可以传入原始数据,并且还可以传入处理方式

    import java.util.function.Function;
    
    public class Test7 {
    
        public static void main(String[] args) {
            Function<String,Integer> fun = x->Integer.parseInt(x);
            int num = parse("555",fun);
            System.out.println(num);
            
            Function<Integer,Integer> fun1 = x->x*x;
            int result = method(6,fun1);
            System.out.println(result);
            
            int result1 = method01("5",Integer::parseInt,x->x*x);
            System.out.println(result1);
        }
        public static int method01(String str,Function<String,Integer> fun,Function<Integer,Integer> fun1) {
            //andThen()先执行前面的方法,再执行后面的方法,apply()给函数接口传参
            return fun.andThen(fun1).apply(str);
        }
        
        public static int method(int i,Function<Integer,Integer> fun) {
            return fun.apply(i);    
        }
        public static int parse(String str,Function<String,Integer> fun){
            return fun.apply(str);
        }
    }
    函数式接口

    10、断言型接口 Predicate<T>

      抽象方法:boolean test(T t)

      如果需要定义一个函数,接收一个数据,判断数据是否合法,返回一个boolean结果,就可以使用断言型接口

      以前我们只能传入处理好的数据到方法中

      现在可以将原始数据传入,将过滤的条件也传入

    import java.util.ArrayList;
    import java.util.function.Predicate;
    
    public class Test8 {
    
        public static void main(String[] args) {
            ArrayList<Integer> list = new ArrayList<>();
            list.add(10);
            list.add(66);
            list.add(666);
            list.add(35);
            list.add(-20);
            list.add(0);
            list.add(33);
            
            ArrayList<Integer> odds = filt(list, x -> x % 2 == 0);
            System.out.println(odds);
            
            ArrayList<Integer> oddsNeg = filt(odds, x -> x < 0);
            System.out.println(oddsNeg);
            
            ArrayList<Integer> oddsNegS = filt(list, x -> x % 2 == 0, x -> x < 0);
            System.out.println(oddsNegS);
            
            //获得list中大于100的数字或者是偶数
            ArrayList<Integer> results = filtOr(list, x -> x > 100, x -> x % 2 == 0);
            System.out.println(results);
            //取反  非偶数
            ArrayList<Integer> testNeg = filtNeg(list, x -> x % 2 == 0);
            System.out.println(testNeg);
        
        }
    
        
    
        public static ArrayList<Integer> filt(ArrayList<Integer> list, Predicate<Integer> pre) {
            ArrayList<Integer> result = new ArrayList<>();
            for (int  i : list) {
                if (pre.test(i)) {//断言型接口的对象.test()进行判断
                    result.add(i);
                }
            }
            return result;
        }
    
        public static ArrayList<Integer> filt(ArrayList<Integer> list, Predicate<Integer> pre1, Predicate<Integer> pre2) {
            ArrayList<Integer> result = new ArrayList<>();
            for (int  i : list) {
                if (pre1.and(pre2).test(i)) {//and()同时满足
                    result.add(i);
                }
            }
            return result;
        }
    
        public static ArrayList<Integer> filtNeg(ArrayList<Integer> list, Predicate<Integer> pre) {
            ArrayList<Integer> result = new ArrayList<>();
            for (int  i : list) {
                if (pre.negate().test(i)) {//negate()相当于非 !
                    result.add(i);
                }
            }
            return result;
        }
    
        public static ArrayList<Integer> filtOr(ArrayList<Integer> list, Predicate<Integer> pre1, Predicate<Integer> pre2 ) {
            ArrayList<Integer> result = new ArrayList<>();
            for (int  i : list) {
                if (pre1.or(pre2).test(i)) {//or只要满足其中一个条件
                    result.add(i);
                }
            }
            return result;
        }
    }
    断言型接口

     StreamAPI

    1、作用:数据过滤

    2、数据的获取 

      1、Collection的获取:

        调用stream()方法即可,返回Stream类型的对象

      2、Map的获取:不能直接获取Stream类型

        1、keySet().stream()

        2、values().stream()

        3、entrySet().stream()

      3、数组的获取

        Stream中的of方法,Stream.of(数组)

    3、常用方法

      1、终结方法:调用完成之后,返回值不再是Stream类型本身,无法继续调用Stream中的方法

         例如:forEach、count

      2、延迟方法:调用完成之后,返回值还是Stream类型,可以继续调用Stream中的各种方法

              例如:除了终结方法,全都是延迟方法

      3、罗列:

        Stream<T>  filter(Predicate<? super T> pre)

           根据pre描述的判断条件,对流中的数据进行过滤

        Stream<T>  limit(long maxSize)

            根据参数maxSize描述的个数,对流中的数据进行截取

           Stream<T>  skip(long n)

            跳过参数n描述的个数,流中剩余的是n之后的内容

        Stream<R>  map(Function<? super T, R> fun )

            将流中的所有T类型数据,都根据fun这个函数型接口,转换成其他的R类型数据

        forEach(Consumer<? super T>  con)

            将流中的数据,根据con描述的处理方式,进行处理

        long count()

            返回流中的元素数

    4、代码示例

    import java.util.ArrayList;
    
    public class Test1 {
    
        public static void main(String[] args) {
            ArrayList<String> al = new ArrayList();
            al.add("张无忌");
            al.add("张三疯");
            al.add("张五侠");
            al.add("周芷若");
            al.add("赵敏");
            al.add("张辽");
            al.add("赵云");
            //获取集合中,姓张,三个字名字,获取集合之后,再打印出集合的内容
            test_jdk8(al);
            }
                     //利用多重筛选和forEach完成要求
        private static void test_jdk8(ArrayList<String> al) {
            al.stream().filter(x->x.startsWith("张"))
            .filter(x->x.length()==3).forEach(System.out::println);
        }
    }
    筛选
    import java.util.ArrayList;
    
    public class Test02 {
    
        public static void main(String[] args) {
            ArrayList<String> al = new ArrayList();
            al.add("张学友");
            al.add("张学良");
            al.add("张无忌");
            al.add("张三疯");
            al.add("宇文成都");
            al.add("张五侠");
            al.add("周芷若");
            al.add("赵敏");
            al.add("张辽");
            al.add("赵云");
            al.add("张飞");
            
            al.stream().filter(x->x.startsWith("张"))
            .filter(x->x.length()==3).limit(2).forEach(System.out::println);
            
            al.stream().skip(2).filter(x->x.startsWith("张"))
            .filter(x->x.length()==3).limit(2).forEach(System.out::println);
            System.out.println("===========================");
            al.stream().map(x->x.length()).forEach(System.out::println);
            long count = al.stream().count();
            System.out.println(count);
    
        }
    
    }
    各个方法的使用
  • 相关阅读:
    Python入门11 —— 基本数据类型的操作
    Win10安装7 —— 系统的优化
    Win10安装6 —— 系统的激活
    Win10安装5 —— 系统安装步骤
    Win10安装4 —— 通过BIOS进入PE
    Win10安装2 —— 版本的选择与下载
    Win10安装1 —— 引言与目录
    Win10安装3 —— U盘启动工具安装
    虚拟机 —— VMware Workstation15安装教程
    Python入门10 —— for循环
  • 原文地址:https://www.cnblogs.com/xfdhh/p/11260927.html
Copyright © 2011-2022 走看看