Lambda表达式与“::“方法引用 & 判空包装类Optional

函数式接口

  • 函数式接口(Functional Interface)就是有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
  • 函数式接口可以被隐式转换为Lambda表达式。

Lambda表达式与"::"方法引用

  • 方法引用主要是对Lambda表达式的一种优化!
  • 方法引用的使用前提是对象和方法都是已经存在的!
  • 方法引用提供了一种引用而不执行方法的方式。
  • 当Lambda表达式中只是执行一个方法调用时,不用Lambda表达式,直接通过方法引用的形式可读性更高一些方法引用是一种更简洁易懂的Lambda表达式!
  • 这种双冒号"::"的写法被称为"方法引用",双冒号"::"也被称为方法引用符或引用计算符,而它所在的表达式被称为方法引用~!
package com.gch.method.references;

/**
 * 定义一个打印的函数式接口
 */
@FunctionalInterface
public interface Printable {
    /**
     * 定义一个打印字符串的抽象方法
     * @param str
     */
    void print(String str);
}
package com.gch.method.references;

/**
 * 方法引用 & Lambda表达式
 */
public class PrintableDemo {
    /**
     * 主函数
     * @param args
     */
    public static void main(String[] args) {
        /**
         * 分析:Lambda表达式的目的,打印参数传递的字符串
         * 把参数s传递给了System.out对象,调用out对象中的方法println()对字符串进行了输出!
         * 注意:
         *   1.System.out对象是已经存在的;
         *   2.println()方法也是已经存在的!
         * 所以我们可以使用方法引用来优化Lambda表达式!
         * 可以使用System.out直接引用(调用)println()方法
         */
        // 调用printString()方法,方法的参数Printable是一个函数式接口,所以可以传递Lambda表达式
        printString((s) -> {
            System.out.println(s);
        });

        /**
         * 方法引用:使用对象来直接引用方法!
         * "::"就是方法引用的运算符
         */
        printString(System.out::println);
    }

    /**
     * 定义一个方法,参数传递Printable接口,对字符串进行打印
     * @param p Printable接口
     */
    public static void printString(Printable p){
        p.print("Hello World!");
    }
}

判空包装类 - Optional

  • Java 8还新增了一个非常重要的判空包装类Optional,这个类可以很有效的处理空指针问题!
比如对于下面这样一个很简单的方法,如果我们在传入参数时,传个null进去,运行时会报错 - 空指针异常 - java.lang.NullPointerException:
package com.gch.optional.demo;

public class Test {
    public static void main(String[] args) {
        // java.lang.NullPointerException
        test(null);
    }

    /**
     * 传入一个字符串,如果字符串不为空,那就打印它的长度!
     * @param str 传入的字符串
     */
    private static void test(String str) {
        if (!str.isEmpty()) {
            System.out.println("字符串长度为:" + str.length());
        }
    }
}
因此,我们还需要在使用之前判断字符串是否为null:
package com.gch.optional.demo;

public class Test {
    public static void main(String[] args) {
        test(null);
    }

    /**
     * 传入一个字符串,如果字符串不为空,那就打印它的长度!
     * @param str 传入的字符串
     */
    private static void test(String str) {
        // 如果字符串为null,则直接结束方法!
        if(str == null) {
            return;
        }
        if (!str.isEmpty()) {
            System.out.println("字符串长度为:" + str.length());
        }
    }
}

虽然这种方式很好,但是在Java 8之后,有了Optional类,它可以更加优雅的处理这种问题:

package com.gch.optional.demo;

import java.util.Optional;

/**
 * 判空包装类 - Optional的用法
 */
public class OptionalDemo {
    public static void main(String[] args) {
        test(null);
    }

    /**
     * 传入一个字符串,如果字符串不为Null,则打印它的长度
     * @param str 传入的字符串
     */
    private static void test(String str){
        Optional // 将传入的对象包装进Optional中
                .ofNullable(str)
                // 如果不为null,则执行这里的Consumer实现!
                .ifPresent(s -> System.out.println("字符串长度为:" + s.length()));
    }
}
private static void test(String str) {
        // get方法可以获取被包装的对象引用,如果被包装的对应为null
        // 则get()方法获取时会抛出异常 - java.util.NuSuchElementException
        String s = Optional.ofNullable(str).get();
    }


 

你可能感兴趣的:(java,开发语言)