zoukankan      html  css  js  c++  java
  • JAVA笔记整理-JDK8的特性

    JDK8的特性

    在JDK8中新增一些特殊功能,一般开发时方便使用, 其中最主要的功能如下

    1、接口的默认函数

    public interface MyInterface {
    
        public default void defaultMethods(){
            System.out.println("这是一个接口的默认方法。");
            // 静态方法可以在default方法中调用
            staticMethods();
        }
    
        public void service();
    
        public static void staticMethods(){
            System.out.println("这是接口的静态方法");
        }
    }
    
    
     public static void main(String[] args) {
            // 创建匿名内部类的方式
            MyInterface my = new MyInterface() {
                @Override
                public void service() {
                    System.out.println("service方法.....");
                }
            };
            my.defaultMethods();
            //通过接口名 调用静态方法
            MyInterface.staticMethods();
    
        }
    

    2、Lambda表达式

    ​ JDK8中支持一种对方法调用的 简写方式 ,也是一种特殊写法

    语法: ([形参名]) ->{ 方法的实现}

    这个接口中有且只有一个方法,并对方法实现

    原始代码

          ArrayList<String> list = new ArrayList<>();
            list.add("aaa");
            list.add("bbb");
            list.add("ccc");
            list.add("ddd");
            // 降序
            Collections.sort(list, new Comparator<String>() {
                @Override
                public int compare(String o1, String o2) {
                    return o2.compareTo(o1); //降序
                }
            })
    

    由于JDK能识别sort的参数二是Comparator , 并Comparator是函数式接口(一个接口中有且只有一个方法。),实现的一定是唯一的方法名, 所有这里方法名和返回值也省略, 它的简写方式

         // 使用lambda表达式   ([形参])->{方法体}  
            Collections.sort(list ,(String o1,String o2)->{
                return o2.compareTo(o1);
            });
    

    由于形参的数据类与集合的元素类型一致,这里的形参类型也省略 、return也省略

    // 最精简的Lambda
            Collections.sort(list ,(o1,o2)->o2.compareTo(o1));
    

    3、函数式接口

    函数式接口主要用于满足前面Lambda表达式的语法的使用。 在一个接口中 有且只有一个方法的接口称为 “函数式接口” ,

    ​ 如何将一个接口定义为函数式接口呢? 在接口上增加注解 “@FunctionalInterface”

    package com.j2008.functionalFun;
    @FunctionalInterface  // 该注解的意义在于 约束接口只能由一个方法
    public interface ConverterInterface<T> {
        public String convertStr(T t);
    
    
    }
    
        //传统写法
    ConverterInterface<Integer> con = new ConverterInterface<Integer>() {
                 @Override
                 public String convertStr(Integer o) {
                     return  o.toString();
                 }
             };
    
            String ss =  con.convertStr(100);
            System.out.println(ss);
    	//使用 lambda表达式写法
            ConverterInterface<Date> cons = (o)->o.toLocaleString();
            String s =  cons.convertStr(new Date());
            System.out.println(s);
    
    

    4、方法和构造器的引用

    4.1 方法的引用

    在以上接口函数中 这个convert方法的实现 对于java.lang包中是存在相同的方法的,所以 convert的实现可以直接引用已有静态方法 Integer.valueOf 或者 Integer.parseInt

    ​ 以上代码的实现可以改成这样 :

    ​ 语法: 类名 :: 静态方法名

    @FunctionalInterface
    public interface Convert<F,T> {
        //将F转成T
        public T convertType (F f);
    }
    
     public static void main(String[] args) {
             // 原始使用lambda表达式 可以这样写
            // 把字符串转成  Integer
            Convert<String ,Integer> con = (f)->{
                return Integer.parseInt(f);
            };
            Integer n = con.convertType("888");
    
            // 在lambda基础上,如果实现的方法 已存在,则可直接调用  类名::方法名
            Convert<String ,Integer> con2 = Integer::valueOf;
            Convert<String ,Integer> con3= Integer::parseInt;
    
            //调用方法实现
            Integer n2 = con2.convertType("123");
            int n3 = con3.convertType("555");
    
     }
    

    4.2 构造器的引用

    当方法的实现 是构造器时,可直接引用构造器

    语法: 类名::new

    @FunctionalInterface
    public interface StudentFactory<T> {
        // 参数是创建对象时 的 属性
        public T create(int id ,String name);
    }
    
    public class Student {
        private int sid;
        private String sname;
          public Student(int sid, String sname) {
            this.sid = sid;
            this.sname = sname;
        }
      }
    
     public static void main(String[] args) {
            //使用Lambda实现 函数接口的方法
            StudentFactory<Student> factory = (id,name)->{
                return new Student(id ,name);
            };
            Student stu1 =  factory.create(1001,"张三丰");
            System.out.println(stu1);
    
            // 以上写法可以直接换成 引用构造器方式
            StudentFactory<Student> factory1 = Student::new;
            //创建
            Student stu2 = factory1.create(1002,"张无忌");
            System.out.println(stu2);
        }
    

    5、集合的流式处理

    在JDK8以后,提供对集合的流式操作,对集合的元素可以向“流水”一样,依次方便,遍历,排序等,它是“不可逆的”(访问后面元素之后不能再次返回前面元素 ) , 根据流的处理方式不同,可以分为 串行流和并行流, 串行流表示同一时间只能有一个流式操作,而并行流可以有多个流式操作。

    ​ 流返回的结果包括中间操作和 最终操作

    中间操作:它的返回值依然是 流对象 ,例如 排序、过滤、去重

    最终操作: 返回值是特定的结果类型 ,例如 遍历,取最大值,最小值或返回新的集合

    常用方法:

    ​ stream() :将一个集合流式化

    ​ filter(): 按条件过滤,里面使用lambda表达式

    ​ sort(): 排序集合元素

    ​ distinct: 过滤重复元素

    ​ reduce() : 将集合的所有元素累加或拼接

    ​ map(); 映射一个新的集合 对集合元素变更输出

    ​ collect():返回一个新集合

    ​ max() min():返回集合最大值或最小值

    ​ get (): 获取集合计算的结果

     public static void main(String[] args) {
            List<Integer> list = new ArrayList();
            for(int i = 0 ;i<7;i++){
                  list.add(i+1);
            }
             // 1、过滤 filter()   过滤掉偶数
            list.stream().filter( param ->param%2==1 )
                        .forEach(System.out::println); //遍历元素
    
            // 2、排序 sort()   降序
            list.stream().sorted((o1,o2)->o2-o1).forEach(System.out::println);
    
            //  3 map() 映射一个新的集合 , 如果是奇数 输出奇数 ,否则偶数
            list.stream().map(
                    param -> param%2==1?"这个元素是奇数":"这是偶数"
                    ).forEach(System.out::println);
    
            list.add(1);
            list.add(1);
            System.out.println("去重元素");
            // 4 distinct()  去除重复元素
            list.stream().distinct().forEach(System.out::println);
    
            // 5 reduce() 将集合的所有元素 累加(或拼接)
    
            int sum =  list.stream().reduce((o1,o2)->o1+o2).get();
            System.out.println("总和:"+sum);
    
            // 6 collect 返回一个新的集合
            List<Integer> list2= list.stream().filter(param->param%2==1).collect(Collectors.toList());
            System.out.println("遍历新集合");
            list2.stream().forEach(System.out::println);
    
            // 7、最大和最小
            int max = list2.stream().max((o1,o2)->o1-o2 ).get();
            System.out.println("最大值:"+max);
            int min = list2.stream().min((o1,o2)->o1-o2 ).get();
            System.out.println("最小值:"+min);
        }
    
  • 相关阅读:
    黑马程序员_Java学习日记num13
    黑马程序员_Java学习日记num12
    黑马程序员_Java学习日记num11
    黑马程序员_Java学习日记num10
    黑马程序员_Java学习日记num9
    黑马程序员_Java学习日记num8
    黑马程序员_Java学习日记num7
    黑马程序员_Java学习日记num6
    黑那程序员_Java学习日记num5
    Happy May!
  • 原文地址:https://www.cnblogs.com/z5452830/p/13903354.html
Copyright © 2011-2022 走看看