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);
    }
原文地址:https://www.cnblogs.com/z5452830/p/13903354.html