jdk8.0相关特性(一)

JDK8.0相关特性

一、JDK8.0中接口新语法

  • JDK8.0,接口中可以定义静态的方法,带有方法的实现部分。

    • 语法:public static 返回值类型 方法名(形参列表){ //实现部分 }
  • JDK8.0,接口中可以定义带有默认实现的非抽象方法

    • 语法:public default 返回值类型 方法名(形参列表){ // 方法实现 }

二、Lambda表达式的相关语法

  • Lambda表达式实现接口,并创建对象(匿名内部类的简化写法)

  • Lambda表达式在Java语言中引入一个新的语法元素和符号: “->”,该操作符被称为Lambda操作符或是箭头操作符,此操作符将Lambda表达式分为两个部分:

    • 左侧:指定Lambda表达式所需要的参数
    • 右侧:指定Lambda表达式的执行功能部分
  • 语法格式一:无参数、无返回值

    接口名 引用名 = ()->{ //执行功能部分 };

    案例:

    public class Test {
        public static void main(String[] args) {
            IA ia = ()->{
                System.out.println("m1方法....");
            };
            ia.m1();
        }
    }
    interface IA{
        void m1();
    }
    

    注意:

    • 利用Lambda表达式实现的接口,接口中必须只定义一个抽象方法;
    • 如果Lambda表达式的实现体仅有一行语句,则{}可以省略,不建议省略。

  • 语法格式二:带有参数,没有返回值

    接口名 引用 = (数据类型 变量名) ->{//实现体…};

    案例一:一个参数

    public class Test {
        public static void main(String[] args) {
           IA ia = (int n)->{
               if(n%2==0){
                   System.out.println(n+"是偶数....");
               }else{
                   System.out.println(n+"是奇数....");
               }
           };
           ia.m1(6);
        }
    }
    interface IA{
        void m1(int n);
    }
    

    案例二:多个参数

    public class Test {
        public static void main(String[] args) {
            IA ia = (int a,double b)-> {
                System.out.println("a="+a+",b="+b);
            };
            ia.m1(3,9.8);
        }
    }
    interface IA{
        void m1(int n,double d);
    }
    

    注意:Lambda表达式中的数据类型可以省略,因为编译器可进行类型推断。

  • 语法格式三:带有返回值

    接口名 引用名 = (参数列表) -> { return 语句;}

    public class Test {
        public static void main(String[] args) {
            IA ia = (a)->{
                if(a<5){
                    a=a+1;
                }
                return a;
            };
            int r=ia.m1(3);
            System.out.println("r="+r);
        }
    }
    interface IA{
        int m1(int a);
    }
    

    注意:如果Lambda表达式中仅一条return语句,则可以写为

    ​ 接口名 引用 = (形参列表) ->表达式;不建议使用。

三、Lambda表达式的实际应用

  • 实际应用一:利用Lambda表达式实现Ruannble接口

    public class Test {
        public static void main(String[] args) {
           Runnable r = ()->{
               for(int i=0;i<10;i++){
                   System.out.println("+++++++++++++++"+i);
               }
           };
           new Thread(r).start();
        }
    }
    
  • 实际应用二:利用Lambda表达式,完成Consumer的实现,接收数据完成对应操作

    public class Test {
        public static void main(String[] args) {
            Consumer<String> c = (String s)->{
                System.out.println(s);
            };
            c.accept("百知威武....");
        }
    }
    
  • 实际应用三:利用Lambda表达式完成,List集合遍历

    • 利用匿名内部类完成:

       ```
       List<String> list=Arrays.asList("胡老八","李四,"张三","胡明");
       list.forEach(new Consumer<String>() {
       		public void accept(String s) {
            	if(s.contains("胡")){
                	System.out.println(s);
                 }
            }
       });
      
    • 利用Lambda表达式完成:

      List<String> list=Arrays.asList("胡老八","李四,"张三","胡明");
      list.forEach((s)-> {
      	if (s.contains("胡")) {
      		System.out.println(s);
      	}
      });
      
      只是List集合打印遍历输出: list.for((s)-> System.out.println(s))        
      
  • 练习:在集合ArrayList中存储多个学生对象:

    • 在学生集合中筛选出所有男生

    • 在学生集合中筛选出所有不及格的学生

    • 在学生集合中筛选出所有不及格的男生学生

    • 在学生集合中筛选出所有不及格的姓刘的男生

  • 练习二:调用Collections.sort()方法,通过定制排序比较两个Srudent(先按照年龄比较,年龄相同再按照成绩排序),使用Lambda表达式作为参数进行传递。

    public class Test {
        public static void main(String[] args) {
            ArrayList<Student> list = new ArrayList();
    
            list.add(new Student("张三",23,88.0));
            list.add(new Student("李四",26,98.0));
            list.add(new Student("胡八一",25,78.0));
            list.add(new Student("胡八一",25,88.0));
    
            Collections.sort(list,(s1,s2)->{
                if(s1.getAge()>s2.getAge()){
                    return 1;
                }else if(s1.getAge()<s2.getAge()){
                    return -1;
                }else{
                    return Double.compare(s1.getScore(),s2.getScore());
                }
            });
            list.forEach((s)-> System.out.println(s));
        }
    }
    

四、函数式接口(Lambda表达式需要函数式接口的支持)

  • 含义:接口中只有一个抽象方法的接口被称为函数式接口。

  • 自定义函数式接口:可以利用注解@FunctionalInterface检测接口是否为函数式接口。

    @FunctionalInterface
    interface IA{
        int m1(int a);
    }
    

    注意:添加@FunctionalInterface注解的接口中必须只能有一个抽象方法。自定义函数式接口案例:

    public class Test {
        public static void main(String[] args) {
            int r = optional(5,(m)->{return m*m;});
            System.out.println("r="+r);
        }
        public static Integer optional(int n,MyFuntion f){
            return f.getValue(n);
        }
    }
    //对一个整数进行计算操作,将计算的结果作为返回值返回
    interface MyFuntion{
        Integer getValue(int n);
    }
    
  • Java8.0内置的四大核心函数式接口

    • 消费型接口:Consumer

      • void accept(T t); —> 参数为T类型,返回值为 void类型
    • 供给型接口:Supplier

      • T get(); —>参数为无参,返回值为T类型
    • 函数型接口:Function<T,R>

      • R apply(T t); —>参数类型为T类型,返回值为R类型
    • 断言型接口:Predicate

      • boolean test(T t); —>参数为T类型,返回值为boolean类型


      • 案例一:消费型接口:

        public class TestFirst {
            public static void main(String[] args) {
                happy(20000.0,(s)-> System.out.println("拿着"+s+"元去消费...."));
            }
            public static void happy(double money, Consumer<Double> c){
                c.accept(money);
            }
        }
        
      • 案例二:供给型接口

        public class TestFirst {
            public static void main(String[] args) {
                happy(20000.0,(s)-> System.out.println("拿着"+s+"元去消费...."));
                String str=getString(10,()->{
                    String s = "anhjshfjshsairiweriwir89863lkkqljrkql";
                    java.util.Random rd = new java.util.Random();
                    int n=rd.nextInt(s.length());
                    return s.charAt(n);
                });
                System.out.println(str);
            }
            public static String getString(int num, Supplier<Character> s){
                String result=null;
                for(int i=0;i<num;i++){
                    String str=s.get()+"";
                    result +=str;
                }
                return result;
            }
         }
        
      • 案例三:函数式接口

         public class TestFirst {
            public static void main(String[] args) {
                String r=changString("helloworld",(s)->s.toUpperCase());
                System.out.println(r);
                System.out.println(changString("helloworld",(s)->s.substring(1,4)));
            }
            public static String changString(String s, Function<String,String> f){
                return f.apply(s);
            }
        }
        
      • 案例四:断言型接口

        public class TestFirst {
            public static void main(String[] args) {
                List<String> list= Arrays.asList("zhangsan","lisi","wangwu","lily","tom");
                List<String> asList=filterString(list,(s)->s.length()>4);
                for(String s:asList){
                    System.out.println(s);
                }
            }
            //将集合中所有的数据元素,根据条件进行过滤
            public static List<String> filterString(List<String> list,Predicate<String> p){
                List<String> asList=new ArrayList<>();
                for(String s:list){
                    if(p.test(s)){
                        asList.add(s);
                    }
                }
                return asList;
            }
        }
        
    • 其他函数式接口:

      在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Java_lover_zpark/article/details/89888188