Java8新特性

Java8概述

Java8(又称JDK1.8)是Java语言开发的一个主要版本。Oracle公司于2014年3月18日发布Java8。

  •  支持Lambda表达式
  • 函数式接口
  • 新的Stream API
  • 新的日期API
  • 其他特性

对于公司而言,会用稳定版本,而非最新版本,因此Java8现在还是大多数企业的选择。

Lambda表达式

 Lambda表达式:可以理解为特殊的匿名内部类,但语法更简介。

Lambda表达式允许把函数作为一个方法的参数(函数作为方法参数传递),将代码像数据一样传递。

基本语法(=号左侧就是接口的声明,和匿名内部类一样)

<函数式接口> <变量名> = (参数1,参数2...) -> {
    //方法体
}

Lambda引入了新的操作符:->(箭头操作符),->将表达式分成两部分

  • 左侧:(参数1,参数2...)表示参数列表
  • 右侧:{}内部是方法体

注意事项(使用时的规则)

  • 形参列表的数据类型会自动推断
  • 如果形参列表为空,只需保留()
  • 如果形参只有1个,()可以省略,只需要形参的名称即可
  • 如果执行语句只有一句,且无返回值,{}可以省略,若又返回值,则若想省去{},则必须同时省略return,且执行语句也保证只有一句
  • Lambda不会生成一个单独的内部类文件,而匿名内部类会

函数式接口

 如果一个接口只有一个抽象方法,则该接口称之为函数式接口,只有函数式接口可以使用Lambda表达式,Lambda表达式会被匹配到这个抽象方法上。

@FunctionalInterface注解检测接口是否符合函数式接口。

 常见的函数式接口

这些是JDK直接提供给外面的函数式接口,我们可以直接使用。

函数式接口 参数类型 返回类型 说明
Consumer<T>消费型接口 T void void accept(T t);对类型为T的对象应用操作
Supplier<T>供给型接口 T T get();返回类型为T的对象
Function<T,R>函数型接口 T R R apply(T t);对类型为T的对象应用操作,并返回类型为R类型的对象。
Predicate<T>断言型接口 T boolean boolean test(T t);确定类型为T的对象是否满足条件,并返回boolean类型。
Runnable      
Comparator      
       

下面来演示函数式接口的使用:

package com.qf;
import java.util.function.Consumer;
//Consumer接口
public class FunctionalInterfaceDemo02 {
    public static void main(String[] args) {
        //匿名内部类
        Consumer<Double> consumer = new Consumer<Double>() {
            @Override
            public void accept(Double t) {
                System.out.println("聚餐消费:" +t);
            }
        };
        happy(consumer,1000);
        //Lambda表达式
        Consumer<Double> consumer1 = t-> System.out.println("聚餐消费:" +t);
        happy(consumer1,1000);
        //Lambda表达式
        happy(t-> System.out.println("聚餐消费:" +t),1000);
        happy(t-> System.out.println("唱歌消费:" +t),2000);
        happy(t-> System.out.println("足疗消费:" +t),3000);
    }
    //Consumer 消费型接口
    public static void happy(Consumer<Double> consumer,double money) {
        consumer.accept(money);
    }
}
//运行结果:
/*聚餐消费:1000.0
        聚餐消费:1000.0
        聚餐消费:1000.0
        唱歌消费:2000.0
        足疗消费:3000.0*/
package com.qf;
import java.util.Arrays;
import java.util.Random;
import java.util.function.Supplier;
//Supplier
public class FunctionalInterfaceDemo03 {
    public static void main(String[] args) {
        //0-100随机数5个
        int[] arr = getNums(()->new Random().nextInt(100),5);
        System.out.println(Arrays.toString(arr));
    }
    public static int[] getNums(Supplier<Integer> supplier,int count) {
        int[] arr = new int[count];
        for (int i = 0; i < count; i++) {
            arr[i] = supplier.get();
        }
        return arr;
    }
}
package com.qf;
import java.util.function.Function;
//Function函数型接口
public class FunctionalInterfaceDemo04 {
    public static void main(String[] args) {
        String res = handlerString(s->s.toUpperCase(),"hello");
        System.out.println(res);
        String result = handlerString(s->s.trim(),"     hello    ");
        System.out.println(result);
    }
    public static String handlerString(Function<String, String> function, String str) {
        return function.apply(str);
    }
}
package com.qf;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
//Predicate断言型接口
public class FunctionalInterfaceDemo05 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("zhangsan");
        list.add("zhangwuji");
        list.add("lisi");
        list.add("wangwu");
        list.add("zhaoliu");
        List<String> res = filterNames(s -> s.startsWith("zhang"), list);
        System.out.println(res.toString());
        List<String> result = filterNames(s -> s.length()>5, list);
        System.out.println(result.toString());
    }
    //Predicate断言型接口
    public static List<String> filterNames(Predicate<String> predicate, List<String> list) {
        ArrayList<String> resultList = new ArrayList<>();
        for (String string : list) {
            if (predicate.test(string)) {
                resultList.add(string);
            }
        }
        return resultList;
    }
}

方法引用

Lambda可以看作是匿名内部类的一种简写形式,而方法引用则是Lambda表达式第一种简写形式。如果Lambda表达式方法体中只是调用一个特定都已经存在的方法,则可以使用方法引用。

 常用形式

  • 对象::实例方法
  • 类::静态方法
  • 类::实例方法
  • 类::new

Stream API

新时间API

原文地址:https://www.cnblogs.com/G-JT/p/13921963.html