java8 笔记

来源:互联网 发布:淘宝店铺模板一键安装 编辑:程序博客网 时间:2024/06/05 21:07

常用函数式接口

Predicate

Predicate接口的test方法,接收一个参数,返回一个布尔值。

@FunctionalInterfacepublic interface Predicate<T> {    boolean test(T var1);}

举例:

先看个简单的例子:判断字符串长度是否大于5

public class LambdaTest {    public static void main(String[] args) {        //Predicate接收一个参数,返回布尔值        Predicate<String> predict = (String str) -> { return str.length() > 5; };        System.out.println(predict.test("hello"));        System.out.println(predict.test("welcome"));    }}输出:falsetrue

再看一个例子,有一个Apple集合,现在要筛选出红色的苹果

public class Apple {    private String category;    private String color;    private double weight;    public Apple(String category, String color, double weight) {        this.category = category;        this.color = color;        this.weight = weight;    }    // getter and setter and toString}
public class LambdaTest {    public static void main(String[] args) {        Apple apple1 = new Apple("红星", "Red", 280);        Apple apple2 = new Apple("黄元帅", "Yello", 470);        Apple apple3 = new Apple("红将军", "Red", 320);        Apple apple4 = new Apple("国光", "Green", 300);        List<Apple> appleList = Arrays.asList(apple1, apple2, apple3, apple4);        //filter方法接收一个Predicate类型的参数        appleList.stream().filter(apple -> "Red".equals(apple.getColor()))                          .forEach(apple -> System.out.println(apple));    }}输出:Apple{category='红星', color='Red', weight=280.0}Apple{category='红将军', color='Red', weight=320.0}
  • stream 是Collection的一个方法,将集合转换成流。
  • filter是stream的一个方法表示过滤。
  • forEach是Iterable的方法,迭代处理。

我们先不关注stream、filter、forEach方法,主要关注filter方法的参数,它接收一个Predict类型的参数,Predict,接收一个参数,返回一个布尔值,

apple -> “Red”.equals(apple.getColor()): 一个输入参数,返回布尔值,符合Predict接口定义。如果需要筛选出红色的,重量大于300克的苹果,方法如下:

appleList.stream().filter(apple -> "Red".equals(apple.getColor()) && (300 < apple.getWeight()))                .forEach(apple -> System.out.println(apple)); //或者(filter方法返回的还是Stream)               appleList.stream().filter(apple -> "Red".equals(apple.getColor()))                .filter(apple -> 300 < apple.getWeight())                .forEach(apple -> System.out.println(apple));

Supplier

Supplier 不接收参数,返回一个值。

@FunctionalInterfacepublic interface Supplier<T> {    T get();}

举例:返回一个随机int值:() -> new SecureRandom().nextInt(20) 符合不接收参数,返回一个值的定义

public class LambdaTest {    public static void main(String[] args) {        Supplier<Integer> randomInt = () -> new SecureRandom().nextInt(20);        System.out.println(randomInt.get());    }}

BinaryOperator

BinaryOperator 接口继承自BiFunction,接收两个参数,返回一个值,与BiFunction不同的是,它的两个输入参数和返回值都是同一种类型。其实第二节的四则运算的例子用BinaryOperator实现更为方便。

@FunctionalInterfacepublic interface BinaryOperator<T> extends BiFunction<T, T, T> {    static default <T> BinaryOperator<T> minBy(Comparator<? super T> var0) {        Objects.requireNonNull(var0);        return (var1, var2) -> {            return var0.compare(var1, var2) <= 0?var1:var2;        };    }    static default <T> BinaryOperator<T> maxBy(Comparator<? super T> var0) {        Objects.requireNonNull(var0);        return (var1, var2) -> {            return var0.compare(var1, var2) >= 0?var1:var2;        };    }}

举例:

public class LambdaTest {    public static void main(String[] args) {        Integer num1 = 16, num2 = 2;        MyCalculator<Integer> calculator = new MyCalculator<>();        System.out.println(calculator.comput(num1, num2, (n1, n2) -> n1 + n2));        System.out.println(calculator.comput(num1, num2, (n1, n2) -> n1 - n2));        System.out.println(calculator.comput(num1, num2, (n1, n2) -> n1 * n2));        System.out.println(calculator.comput(num1, num2, (n1, n2) -> n1 / n2));    }}class MyCalculator<T> {    public T comput(T t1, T t2, BinaryOperator<T> binaryOperator) {        return binaryOperator.apply(t1, t2);    }}输出:1814328

我们看到BinaryOperator有两个静态方法minBy,maxBy,这两个静态方法返回一个BinaryOperator结果,这个BinaryOperator的返回值是根据minBy的参数Comparator来决定的。

public class LambdaTest {    public static void main(String[] args) {        //返回一个BinaryOperator对象        BinaryOperator<String> binaryOperator = BinaryOperator.minBy((str1, str2) -> str1.compareTo(str2));        //BinaryOperator返回的结果,是有minBy的参数Comparator决定的,也就是比较大小,取较小的那个字符串        System.out.println(binaryOperator.apply("hello", "abcdef"));    }}输出:abcdef

BiConsumer

接收两个参数,不返回值

@FunctionalInterfacepublic interface BiConsumer<T, U> {    void accept(T t, U u);}

举例:

(key, value) -> System.out.println(key + ” : ” + value)

接收两个参数,不返回值,符合BiConsumer定义

public class LambdaTest {    public static void main(String[] args) {        Map<String, String> map = new HashMap<>(2);        map.put("java8", "netty");        map.put("jvm", "nodejs");        map.put("hbase", "spring");        map.forEach((key, value) -> System.out.println(key + " : " + value));    }}输出:jvm : nodejsjava8 : nettyhbase : spring

以上就是常用的函数式接口,函数式接口还是很容易理解和使用的,函数式接口可以用lambda表达式来创建,之前的例子中,都是用的是常规的,符合标准形式(或简写)的lambda表达式。下一节介绍方法引用。

(Type1 param1, Type2 param2......) -> { body }

Optional

Optional是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
可以类比基本数据类型的包装类,Optional可以包装任何值,并且可以通过isPresent()判断是否值存在

public class OptionalTest {    public static void main(String[] args) {        Optional<String> optional = Optional.of("optional");        if(optional.isPresent()){            System.out.println(optional.get());        }    }}输出:optional

上面的例子并不是推荐的写法,因为上面的这种写法和之前的写法没有本质区别:

public class OptionalTest {    public static void main(String[] args) {        String str = "optional";        if(null != str){            System.out.println(str);        }    }}输出:optional

推荐的写法如下:

    public static void main(String[] args) {        Optional<String> optional = Optional.of("optional");        //为空则不做任何操作        optional.ifPresent(System.out::println);    }}输出:optional

orElse 如果Optional包装的值为空,用默认值来替代

public class OptionalTest {    public static void main(String[] args) {        //创建一个包装了空值的Optional        Optional<String> optional = Optional.empty();        //为空则用默认值替代        System.out.println(optional.orElse("java8"));    }}输出:java8

orElseGet 或者如果Optional包装的值为空,提供一个Supplier,从Supplier获取值

public class OptionalTest {    public static void main(String[] args) {        //创建一个包装了空值的Optional        Optional<String> optional = Optional.empty();        //为空则使用用户提供的Supplier获取值        System.out.println(optional.orElseGet(()->"hello world"));    }}输出:hello world

Optional.of(object) object一定不能为空,如果不能确定object是否为空,可以用Optional.ofNullable(object) 

不要将Optional做为方法的参数,或者类的成员变量,Optional没有实现序列化,Optional一般只做为方法的返回值。