Java8新特性简介

前言

Java8即JDK版本1.8,Java8与Java8之前的JDK版本的内容相差还是很大的,其中最主要的因该就是Lambda 表达式和 Stream API了。

Java8的优点:

1.速度更快
2.代码更少(增加了新的语法lambda表达式)
3.强大的Stream API
4.便于并行
5.最大化减少空指针异常Optional

其中最为核心的就是Lambda表达式和Stream API

为什么使用Lambda表达式?

Lambda是一个匿名函数,我们可以把Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语法表达能力得到了提升。

Lambda 表达式的基础语法

/*
Java8引入了一个新的操作符 "->" 该操作符称为箭头操作符或Lambda 操作符
 * 左侧:Lambda 表达式的参数列表
 * 右侧:Lambda 表达式中所需执行的功能,即Lambda体
 *
 * 语法格式1:无参数,无返回值
 *     () -> System.out.println("hello lambda");
 *
 * 语法格式2:有一个参数,并且无返回值
 *     (x) -> System.out.println(x);
 *
 * 语法格式3:若只有一个参数,小括号可以省略不写
 *     x -> System.out.println(x);
 *
 * 语法格式4:二个以上的参数,有返回值,并且Lambda体中有多条语句
 *     有多个Lambda提必须使用大括号
 *     Comparator<Integer> com = (x,y) -> {
 *        System.out.println("test3");
 *        return Integer.compare(x,y);
 *     };
 * 语法格式5:若Lambda体中只有一条语句, return 和 大括号都可可以省略不写
 *     Comparator<Integer> com = (x,y) -> Integer.compare(x,y);
 *
 * 语法格式6:Lambda表达式的参数列表的数据类型可以省略不写
 * 
 * 2.Lambda表达式需要“函数接口”的支持
 * 函数式接口:接口中只有一个抽象方法的接口,称为函数式接口,可以使用注解,@FunctionalInterface 修饰
 *            可以检查是否是函数式接口
 * /

Java8 内置的四大核心函数式接口

1.Consumer :消费型接口
void accept(T t);

Supplier : 供给型接口
T get();

3.Function<T, R> : 函数型接口
R apply(T t);

4.Predicate : 断言型接口
Boolean test(T t);

示例

public class Lambda4 {
    
    

    //1.Consumer<T> :消费型接口
    @Test
    public void test1(){
    
    
        happy(1000,(m) -> System.out.println("happy"+m));
    }

    public void happy(double money, Consumer<Double> con){
    
    
        con.accept(money);
    }
    //2.Supplier<T> : 供给型接口
    @Test
    public void test2(){
    
    
        List<Integer> num = getNumList(10, () -> (int)(Math.random() * 100));
        for (Integer nums: num) {
    
    
            System.out.println(nums);
        }
    }

    /**
     * 随机产生整数
     * @param num
     * @param sup
     * @return
     */
    public List<Integer> getNumList(int num, Supplier<Integer> sup){
    
    
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < num; i++){
    
    
            Integer n = sup.get();
            list.add(n);
        }
        return list;
    }
    //3.Function<T, R> : 函数型接口
    @Test
    public void test3(){
    
    
        //去除首尾空格
        String result= strHandler("  s sss ", (str) -> str.trim());
        System.out.println(result);
    }

    /**
     * 用于处理字符串
     * @param str
     * @param fun
     * @return
     */
    public String strHandler(String str, Function<String, String> fun){
    
    
        return fun.apply(str);
    }
    //4.Predicate<T> : 断言型接口
    @Test
    public void test4(){
    
    
        List<String> list = Arrays.asList("hello", "hi", "joker", "king", "a");
        List<String> strList = filterStr(list,(s) -> s.length() > 3);
        for (String str: strList) {
    
    
            System.out.println(str);
        }

    }
    public List<String> filterStr(List<String> list, Predicate<String> pre){
    
    
        List<String> stringList= new ArrayList<>();
        for (String str: list) {
    
    
            if(pre.test(str)){
    
    
                stringList.add(str);
            }
        }
        return stringList;
    }
}

方法引用与构造器引用

一.方法引用:若Lambda 体中的内容有方法已经实现了,我们可以使用”方法引用“(可以理解为方法引用是Lambda 表达式的另一种表现形式)
主要有三种语法格式:

  1. 对象::实例方法名
  2. 类::静态方法名
  3. 类::实例方法名

注意:
1.Lambda 体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的函数列表和返回值类型保持一致!
2.若Lambda 参数列表中的第一参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用 类名::方法名

扫描二维码关注公众号,回复: 11923732 查看本文章
  @Test  //对象::实例方法名
    public void test1(){
    
    
        PrintStream ps1 = System.out;
        Consumer<String> con = (x) -> ps1.println(x);

        PrintStream ps = System.out;
        Consumer<String> con1 = ps::println;

        Consumer<String> con2 = System.out::println;
        con2.accept("aaaa");

    }

    @Test
    public void test2(){
    
    

        UserOrder order0 = new UserOrder("年会", "张三", 1);

        Supplier<String> sup = () -> order0.getPhotographerName();
        String str = sup.get();
        System.out.println(str);

        //方法引用
        Supplier<String> sup2 = order0::getPhotographerName;
        String str2 = sup2.get();
        System.out.println(str2);
    }
    @Test //类::静态方法名
    public void test3(){
    
    
        Comparator<Integer> com = (x, y) -> Integer.compare(x, y);

        Comparator<Integer> com1 = Integer::compare;
    }

    @Test //类::实例方法名
    public void test4(){
    
    
        BiPredicate<String, String> bp = (x, y) -> x.equals(y);

        BiPredicate<String, String> bp2 = String::equals;

    }

二:构造器引用

格式:
类名::new

注意:
需要调用的构造器的参数列表要与函数式接口中的抽象方法的参数列表保持一致

    @Test //构造器引用
    public void test5(){
    
    
        Supplier<UserOrder> sup = () -> new UserOrder("年会", "张三", 1);
        UserOrder str = sup.get();
        System.out.println(str);

        Supplier<UserOrder> sup2 = UserOrder::new;
        UserOrder str2 = sup2.get();
        System.out.println(str2);
    }

三:数组引用
数组类型::new

    @Test //数组引用
    public void test6(){
    
    
        Function<Integer, String[]> fun = (x) -> new String[x];
        String[] strs = fun.apply(10);
        System.out.println(strs.length);

        Function<Integer, String[]> fun2 = String[]::new;
        String[] strs2 = fun2.apply(20);
        System.out.println(strs2.length);
    }

猜你喜欢

转载自blog.csdn.net/javaasd/article/details/109012381