Lambda表达式的摘要

目录

函数式接口

自定义函数式接口

内置的函数式接口

        方法引用

对象引用实例方法

类引用静态方法

类引用实例方法

类引用构造方法

        流式操作

Stream 对象的创建

通过集合创建Stream

通过数组创建Stream

通过 Stream 的 of() 方法

创建无限流

Stream 的中间操作

筛选与切片

映射

排序

Stream 的终止操作

匹配与查找

归约

收集

        Optional 类

创建 Optional 对象

常用方法


函数式接口

自定义函数式接口

1.定义一个抽象方法:接口中只能有一个抽象方法

2.在接口上标记 @FunctionalInterface 注解后,编辑器就能自动检测自定义函数式接口是否存在问题,也可以不标记。

内置的函数式接口

java内置了4个核心函数式接口:

1. Comsumer<T>  消费型接口:表示接受单个输入参数但不返回结果的操作,包含方法: void accept(T t) ,可以理解为消费者,只消费(接受单个参数),不返回(返回为 void

2.  Supplier<T> 供给型接口:表示结果的供给者,包含方法 T get() ,可以理解为供给者,只提供(返回 T 类型对象)、不消费(不接受参数)

3. Function<T, R> 函数型接口:表示接受一个 T 类型参数并返回 R 类型结果的对象,包含方法 R apply(T t)

4. Predicate<T> 断言型接口:确定 T 类型的对象是否满足约束,并返回 boolean 值,包含方法 boolean test(T t)

Comsumer<T> 实例:

import java.util.function.Consumer;

public class TestFunctionInterface1 {
    public static void main(String[] args) {
        /**
         *         Consumer<String> consumer=new Consumer<String>() {
         *             @Override
         *             public void accept(String s) {
         *                 System.out.println(s);
         *             }
         *         };
         *         consumer.accept("只消费,不返回");
         * */
        Consumer<String> consumer=s -> System.out.println(s);
        consumer.accept("只消费,不返回");
    }
}

运行结果:

只消费,不返回

Supplier<T> 实例:

import java.util.function.Supplier;

public class TestFunctionInterface1 {
    public static void main(String[] args) {
        /**
         *         Supplier<String> supplier=new Supplier<String>() {
         *             @Override
         *             public String get() {
         *                 return "只返回,不消费";
         *             }
         *         };
         *         String s=supplier.get();
         *         System.out.println(s);
         * */

        Supplier<String> supplier=() -> "只返回,不消费"; //return可省略不写
        String s=supplier.get();
        System.out.println(s);
    }
}

运行结果:

只返回,不消费

Predicate<T> 实例:

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

public class TestPredicate {

    public static List<String> filterStringList(List<String> list, Predicate<String> predicate){
        //过滤后的字符串列表
        ArrayList<String> arrayList=new ArrayList<>();
        for (String string:list){
            if (predicate.test(string)){
                //如果 test 是 true,则将元素加入到过滤后的列表中
                arrayList.add(string);
            }
        }
        return arrayList;
    }

    public static void main(String[] args) {
        ArrayList<String> arrayList=new ArrayList<>();
        arrayList.add("Java");
        arrayList.add("PHP");
        arrayList.add("Python");
        arrayList.add("JavaScript");
        System.out.println("过滤前:");
        System.out.println(arrayList);

//        List<String> filterResult=filterStringList(arrayList, new Predicate<String>() {
//            @Override
//            public boolean test(String s) {
//                return s.contains("P");
//            }
//        });

        List<String> filterResult=filterStringList(arrayList,s -> s.contains("P"));

        System.out.println("过滤后:");
        System.out.println(filterResult);
    }
}

运行结果:

过滤前:
[Java, PHP, Python, JavaScript]
过滤后:
[PHP, Python]

方法引用

对象引用实例方法

System.out 就是对象,而 println 就是实例方法

实例:

import java.util.function.Consumer;

public class TestMethodReference {

    public static void main(String[] args) {
//        Consumer<String> consumer = s -> System.out.println(s);
        Consumer<String> consumer = System.out::println;
        consumer.accept("这只是个测试");
    }
}

运行结果:

这只是个测试
类引用静态方法

实例:

import java.util.Comparator;
import java.util.function.Function;

public class TestMethodReference {

    public static void main(String[] args) {
        //使用Lambda表达式
        Comparator<Integer> comparator1 = (t1,t2) -> Integer.compare(t1,t2);
        System.out.println(comparator1.compare(11,12));

        //使用方法引用,类::静态方法( compare() 为静态方法
        Comparator<Integer> comparator2=Integer::compare;
        System.out.println(comparator2.compare(12,11));

        // 使用 Lambda 表达式
        Function<Double, Long> function1 = d -> Math.round(d);
        Long apply1 = function1.apply(1.0);
        System.out.println(apply1);

        // 使用方法引用,类 :: 静态方法( round() 为静态方法)
        Function<Double, Long> function2 = Math::round;
        Long apply2 = function2.apply(2.0);
        System.out.println(apply2);
    }
}

运行结果:

-1
1
1
2

查看 Java 源码,可观察到 compare()round() 方法都是静态方法:

类引用实例方法

当函数式接口中的抽象方法有两个参数时,已实现方法的第 1 个参数作为方法调用者时,也可以使用方法引用。此时,就可以使用类来引用实例方法了(即实例中的String::compareTo

实例:

import java.util.Comparator;

public class TestMethodReference {

    public static void main(String[] args) {

        //使用匿名内部类
        Comparator<String> comparator0=new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        };
        int compare0 = comparator0.compare("YES","NO");
        //compareTo() 如果调用该方法的字符串对象按字典顺序在参数字符串之后,那么返回一个正整数
        System.out.println(compare0);

        // 使用 Lambda 表达式
        Comparator<String> comparator1 = (s1, s2) -> s1.compareTo(s2);
        int compare1 = comparator1.compare("Hello", "Java");
        //compareTo() 如果调用该方法的字符串对象按字典顺序在参数字符串之前,那么返回一个负整数
        System.out.println(compare1);

        // 使用方法引用,类 :: 实例方法( compareTo() 为 String 类的实例方法)
        Comparator<String> comparator2 = String::compareTo;
        int compare2 = comparator2.compare("Hello", "Hello");
        //compareTo() 如果两个字符串相等,那么返回 0
        System.out.println(compare2);
    }
}

运行结果:

11
-2
0
类引用构造方法

实例:

import java.util.function.Function;
import java.util.function.Supplier;

public class TestMethodReference {

    static class Person{
        private String name;

        public Person(){
            System.out.println("无参数构造方法执行了");
        }

        public Person(String name){
            System.out.println("单参数构造方法执行了");
            this.name=name;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    public static void main(String[] args) {
        //使用 Lambda 表达式,调用无参构造方法
        Supplier<Person> supplier1 = () -> new Person();
        supplier1.get();

        //使用方法引用,调用无参构造方法
        Supplier<Person> supplier2 = Person::new;
        supplier2.get();

        //使用 Lambda 表达式,调用单参数构造方法
        Function<String,Person> function1 = name -> new Person(name);
        Person person1 = function1.apply("小慕");
        System.out.println(person1.getName());

        //使用方法引用,调用单参数构造方法
        Function<String,Person> function2 = Person::new;
        Person person2 = function2.apply("小明");
        System.out.println(person2.getName());
     }
}

运行结果:

无参数构造方法执行了
无参数构造方法执行了
单参数构造方法执行了
小慕
单参数构造方法执行了
小明

流式操作

Stream 对象的创建
通过集合创建Stream

串行流并行流的区别是:串行流从集合中取数据是按照集合的顺序的;而并行流是并行操作的,获取到的数据是无序的

// 创建一个集合,并添加几个元素  
List<String> stringList = new ArrayList<>();  
stringList.add("hello");  
stringList.add("world");  
stringList.add("java");  
​  
// 通过集合获取串行 stream 对象  
Stream<String> stream = stringList.stream();  
// 通过集合获取并行 stream 对象  
Stream<String> personStream = stringList.parallelStream();
通过数组创建Stream
// 初始化一个整型数组
int[] arr = new int[]{1,2,3};
// 通过整型数组,获取整形的 stream 对象
IntStream stream1 = Arrays.stream(arr);

// 通过字符串类型的数组,获取泛型类型为 String 的 stream 对象
String[] stringArr = new String[]{"Hello", "imooc"};
Stream<String> stream2 = Arrays.stream(stringArr);
通过 Stream 的 of() 方法
// 通过 Stream 类下的 of() 方法,创建 stream 对象、
Stream<Integer> stream = Stream.of(1, 2, 3);
创建无限流

1.使用 Stream.iterate() 方法:这个方法允许你从一个种子值开始,并应用一个一元操作符来生成一个无限流。并且,你可以通过调用 limit() 方法来限制流中的元素数量,并通过 collect() 方法来终止流并收集结果。

实例:

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class TestStream {

    public static void main(String[] args) {
        Stream<Integer> integerStream = Stream.iterate(1000,i -> i / 2);
        List<Integer> collect = integerStream.limit(15).collect(Collectors.toList());
        int num=1;
        for(int i : collect){
            System.out.println("第" + num++ + "个元素为:" + i);
        }
    }
}

运行结果:

第1个元素为:1000
第2个元素为:500
第3个元素为:250
第4个元素为:125
第5个元素为:62
第6个元素为:31
第7个元素为:15
第8个元素为:7
第9个元素为:3
第10个元素为:1
第11个元素为:0
第12个元素为:0
第13个元素为:0
第14个元素为:0
第15个元素为:0

2.使用 Stream.generate() 方法:这个方法允许你通过提供一个 Supplier 接口来生成元素,从而创建一个无限流。UUID::randomUUID 是一个随机生成一串 UUID 码的方法引用,同样,通过调用 limit() 方法来限制流中的元素数量,并通过 forEach() 方法来遍历并输出流中的结果。

实例:

import java.util.UUID;
import java.util.function.Supplier;
import java.util.stream.Stream;

public class TestStream {

    public static void main(String[] args) {
        Supplier<UUID> uuidSupplier1 = UUID::randomUUID;
        Stream<UUID> uuidStream = Stream.generate(uuidSupplier1);
        uuidStream.limit(10).forEach(System.out::println);
    }
}

运行结果:

c0b19729-70ff-431a-8679-adb511c1f2d5
84277269-3d35-4d46-a741-2ac06a703a0a
7f3cdd33-8c5d-46ac-bb3d-fe43e0047565
80e57c15-3bf4-4da6-9ca6-e19c85b16467
914908fa-23f2-4793-88ae-0c66dc2ba37b
2cf64e8c-0a90-4268-a120-39a8300ec568
3c264ae6-0772-4e34-b563-1b51f3ee483b
4660f1a4-71b8-4c60-a3ea-01e0d4354931
ec1e9023-aecd-4fca-879c-efecf8503d63
822c65fa-be3f-4eb7-aeb1-a7a5358e43a5
Stream 的中间操作
筛选与切片

 filter() 和 limit() 以及 skip() 的实例:

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class TestStream {

    public static void main(String[] args) {
        /************ limit()部分 *************/
        //生成一个无限流,其中每个元素都是0-99之间的整数,并用 limit() 方法截取前10个元素
        Stream<Integer> stream = Stream.generate(() -> (int)(Math.random() * 100)).limit(10);
        //用 collect() 方法 终止流并获取集合
        List<Integer> before = stream.collect(Collectors.toList());
        System.out.println("原始元素有:");
        for (int i : before){
            System.out.print(i + " ");
        }
        System.out.println();

        /************ filter()部分 *************/
        //用集合的元素再创建一个新的串行流
        Stream<Integer> recoverStream1 = before.stream();
        //然后从流中筛选出大于15的元素,并用 collect() 方法 终止流并获取集合
        List<Integer> after = recoverStream1.filter(i -> i > 15).collect(Collectors.toList());
        System.out.println("筛选后:");
        for (int i : after){
            System.out.print(i + " ");
        }
        System.out.println();

        /************ skip()部分 *************/
        Stream<Integer> recoverStream2 = before.stream();
        //跳过前2个元素
        List<Integer> enough = recoverStream2.skip(2).collect(Collectors.toList());
        System.out.println("跳过后:");
        for (int i : enough){
            System.out.print(i + " ");
        }
        System.out.println();

        //跳过前11个元素,此时已经超出流原有的元素数量,所以返回空流,集合自然也是空集
        Stream<Integer> recoverStream3 = before.stream();
        List<Integer> notEnough = recoverStream3.skip(11).collect(Collectors.toList());
        System.out.println("跳过后:");
        if(notEnough.size()==0){
            System.out.println("(空)");
        }
    }
}

运行结果:

原始元素有:
63 66 20 51 69 49 37 93 17 72 
筛选后:
63 66 20 51 69 49 37 93 17 72 
跳过后:
20 51 69 49 37 93 17 72 
跳过后:
(空)

distinct() 的实例:

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

public class TestStream {

    static class Person{
        String name;
        int age;

        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Person person = (Person) o;
            return age == person.age && Objects.equals(name, person.name);
        }

        @Override
        public int hashCode() {
            return Objects.hash(name, age);
        }
    }

    public static void main(String[] args) {
        //使用 distinct() 去除一个列表中重复的元素
        List<Integer> list1 = Arrays.asList(1,2,1,1,5,3);
        Set<Integer> result = list1.stream().distinct().collect(Collectors.toSet());
        System.out.println(result);

        //使用 distinct() 去除一个字符串列表中的重复字符
        List<String> list2 = Arrays.asList("ant","orange","pencil","pencil","piano");
        list2.stream().distinct().forEach(i -> System.out.print(i + " "));
        System.out.println();

        /* 使用 distinct() 去除一个对象列表中的重复对象,
           默认使用 Object.equals() 方法来确定重复性,这个方法只能去除相同的对象,
           按照不同的标准来判断元素是否重复,需要重写 equals() 和 hashCode() 方法
        */
        Person person=new Person("Jack",10);
        Person person1=person;
        List<Person> list3 = Arrays.asList(
                new Person("Mike",20),
                new Person("Sarah",18),
                new Person("Bill",10),
                new Person("Jack",35),
                new Person("Jack",35),
                new Person("Jack",20),
                person,
                person1
        );
        List<Person> result2 = list3.stream().distinct().collect(Collectors.toList());
        for (int i = 0; i < result2.size(); i++) {
            System.out.println(result2.get(i).getName() + "," + result2.get(i).getAge());
        }
    }
}

运行结果:

[1, 2, 3, 5]
ant orange pencil piano 
Mike,20
Sarah,18
Bill,10
Jack,35
Jack,20
Jack,10
映射

实例:

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;

public class TestStream {

    public static void main(String[] args) {
        //创建一个包含小写字母的字符串列表
        List<String> stringList = Arrays.asList("apple","banana","cat","dog","egg");
        //调用 map() 方法,将 String 下的 toUpperCase() 方法作为参数,这个方法会被应用到每个元素,映射成一个新元素,类型由泛型决定
        Set<String> stringSet = stringList.stream().map(String::toUpperCase).collect(Collectors.toSet());
        System.out.println("map() 的应用:");
        System.out.println(stringSet);

        //创建一个整型元素列表
        List<Integer> integerList = Stream.iterate(1,i -> i + 2).limit(5).collect(Collectors.toList());

        //调用 mapToDouble() 方法,将 Integer 下的 doubleValue() 方法作为参数,该方法会被应用到每个元素上,产生一个新的 DoubleStream
        DoubleStream doubleStream = integerList.stream().mapToDouble(Integer::doubleValue);
        System.out.println("mapToDouble() 的应用:");
        doubleStream.forEach(System.out::println);

        //调用 mapToLong() 方法,将 Integer 下的 longValue() 方法作为参数,该方法会被应用到每个元素上,产生一个新的 LongStream
        LongStream longStream = integerList.stream().mapToLong(Integer::longValue);
        System.out.println("mapToLong() 的应用:");
        longStream.forEach(System.out::println);

        /**
         * flatMap 将每个字符串转换为一个新的字符流,然后将这些流“扁平化”为一个单一的字符流。
         * chars() 方法用于将字符串转换为字符的索引流,然后 mapToObj 将索引转换为字符。
         * 最后,我们使用 collect 来收集结果。
         * */
        List<String> strings = Arrays.asList("Hello","World");
        List<Character> characters = strings.stream()
                .flatMap(s -> s.chars().mapToObj(c -> (char)c))
                .collect(Collectors.toList());
        System.out.println("flatMap() 的应用:");
        System.out.println(characters);

    }
}

运行结果:

map() 的应用:
[APPLE, EGG, CAT, BANANA, DOG]
mapToDouble() 的应用:
1.0
3.0
5.0
7.0
9.0
mapToLong() 的应用:
1
3
5
7
9
flatMap() 的应用:
[H, e, l, l, o, W, o, r, l, d]
排序

实例:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class TestStream {

    public static void main(String[] args) {
        List<Integer> integerList1 = Arrays.asList(1,10,5,20,15,16);

        //调用 sorted() 方法自然排序,并打印每个元素
        List<Integer> integerList2 = integerList1.stream().sorted().collect(Collectors.toList());
        System.out.println(integerList2);

        //定制排序,实现数字从大到小的排序
        List<Integer> integerList3 = integerList1.stream().sorted(
                (i1, i2) -> -Integer.compare(i1,i2)
        ).collect(Collectors.toList());
        System.out.println(integerList3);
    }
}

运行结果:

[1, 5, 10, 15, 16, 20]
[20, 16, 15, 10, 5, 1]
Stream 的终止操作
匹配与查找

实例:

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class TestStream {

    public static void main(String[] args) {
        List<Integer> integers = Arrays.asList(1,10,5,20,15,16);
        System.out.println("列表元素:" + integers);

        // 使用 allMatch(Predicate p) 检查是否匹配所有元素,如果匹配,则返回 true;否则返回 false
        boolean b1 = integers.stream().allMatch(integer -> integer > 0);
        if (b1) {
            System.out.println("列表中所有的元素都大于0");
        } else {
            System.out.println("列表中不是所有的元素都大于0");
        }

        // 使用 anyMatch(Predicate p) 检查是否至少匹配一个元素
        boolean b2 = integers.stream().anyMatch(integer -> integer >= 20);
        if (b2) {
            System.out.println("列表中至少存在一个的元素大于等于20");
        } else {
            System.out.println("列表中不存在任何一个大于等于20的元素");
        }

        // 使用 noneMath(Predicate p) 检查是否没有匹配所有元素
        boolean b3 = integers.stream().noneMatch(integer -> integer > 100);
        if (b3) {
            System.out.println("列表中不存在大于100的元素");
        } else {
            System.out.println("列表中存在大于100的元素");
        }

        // 使用 findFirst() 获取当前流中的第一个元素
        Optional<Integer> first = integers.stream().findFirst();
        System.out.println("列表中第一个元素为:" + first);

        // 使用 findAny() 获取当前流中的任意元素
        Optional<Integer> any = integers.stream().findAny();
        System.out.println("列表中任意元素:" + any);

        // 使用 count() 获取当前流中元素总数
        long count = integers.stream().count();
        System.out.println("列表中元素总数为" + count);

        // 使用 max(Comparator c) 获取流中最大值
        Optional<Integer> max = integers.stream().max(Integer::compare);
        System.out.println("列表中最大值为" + max);

        // 使用 min(Comparator c) 获取流中最小值
        Optional<Integer> min = integers.stream().min(Integer::compare);
        System.out.println("列表中最小值为" + min);
    }
}

运行结果:

列表中的元素:[1, 10, 5, 20, 15, 16]
列表中所有的元素都大于0
列表中至少存在一个的元素大于等于20
列表中不存在大于100的元素
列表中第一个元素为:Optional[1]
列表中任意元素:Optional[1]
列表中元素总数为6
列表中最大值为Optional[20]
列表中最小值为Optional[1]
归约

实例:

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class TestStream {

    public static void main(String[] args) {
        //创建一个整形列表
        List<Integer> integerList = Arrays.asList(0,1,5,10,15,20);

        /**
         * 使用 reduce(T identity,BinaryOperator b) 计算列表中所有整数和
         * 第一个参数是累积操作的初始值。
         * 第二个参数是累积操作的函数,它接受两个参数,一个是累积的值(初始值或者上一次操作的结果),另一个是流中的下一个元素。
         * * * * * * * * * * * * * * * * * * * * * * *
         * 如果流中没有元素,reduce 操作会返回你提供的初始值。
         * 如果流有元素但不能进行累积(例如,是一个空流),reduce 会抛出 NullPointerException
         * 或者返回给定的初始值(取决于你提供的函数是否处理 null)
         * */
        Integer sum = integerList.stream().reduce(0, Integer::sum);
        System.out.println(sum);

        // 使用 reduce(BinaryOperator b) 计算列表中所有整数和,返回一个 Optional<T>
        Optional<Integer> reduce = integerList.stream().reduce(Integer::sum);
        System.out.println(reduce);
    }
}

运行结果:

51
Optional[51]
收集

实例:

import java.util.*;
import java.util.stream.Collectors;

public class TestStream {

    public static void main(String[] args) {
        //创建一个整形列表
        List<Integer> integers = Arrays.asList(0,1,5,10,15,20);

        Set<Integer> integerSet1 = integers.stream().collect(Collectors.toSet());
        System.out.println("使用 toSet() 方法收集的列表:");
        System.out.println(integerSet1);

        List<Integer> integerList1 = integers.stream().collect(Collectors.toList());
        System.out.println("使用 toList() 方法收集的列表:");
        System.out.println(integerList1);

        System.out.println("使用 toCollection() 方法收集的列表:");
        List<Integer> integerList2 = integers.stream().collect(Collectors.toCollection(ArrayList::new));
        System.out.println("有序集合:" + integerList2);
        Set<Integer> integerSet2 = integers.stream().collect(Collectors.toCollection(HashSet::new));
        System.out.println("哈希无序集合:" + integerSet2);
        Set<Integer> integerSet3 = integers.stream().collect(Collectors.toCollection(TreeSet::new));
        System.out.println("树状无序集合:" + integerSet3);
        Queue<Integer> integerQueue1 = integers.stream().collect(Collectors.toCollection(PriorityQueue::new));
        System.out.println("队列:" + integerQueue1);
        Collection<Integer> integerCollection = integers.stream().collect(Collectors.toCollection(LinkedHashSet::new));
        System.out.println("链式哈希无序集合:" + integerQueue1);
    }
}

运行结果:

使用 toSet() 方法收集的列表:
[0, 1, 20, 5, 10, 15]
使用 toList() 方法收集的列表:
[0, 1, 5, 10, 15, 20]
使用 toCollection() 方法收集的列表:
有序集合:[0, 1, 5, 10, 15, 20]
哈希无序集合:[0, 1, 20, 5, 10, 15]
树状无序集合:[0, 1, 5, 10, 15, 20]
队列:[0, 1, 5, 10, 15, 20]
链式哈希无序集合:[0, 1, 5, 10, 15, 20]

Optional 类

创建 Optional 对象

实例:

import java.util.Optional;

public class TestOptional {

    public static void main(String[] args) {
        // 创建一个 StringBuilder 对象
        StringBuilder string = new StringBuilder("我是一个字符串");

        // 使用 Optional.of(T t) 方法,创建 Optional 对象,注意 T 不能为空:
        Optional<StringBuilder> stringBuilderOptional = Optional.of(string);
        System.out.println(stringBuilderOptional);

        // 使用 Optional.empty() 方法,创建一个空的 Optional 对象:
        Optional<Object> empty = Optional.empty();
        System.out.println(empty);

        // 使用 Optional.ofNullable(T t) 方法,创建 Optional 对象,注意 t 允许为空:
        stringBuilderOptional = null;
        Optional<Optional<StringBuilder>> stringBuilderOptional1 = Optional.ofNullable(stringBuilderOptional);
        System.out.println(stringBuilderOptional1);
    }
}

运行结果:

Optional[我是一个字符串]
Optional.empty
Optional.empty
常用方法

实例:

package com.imooc.springboot.study;

import java.util.NoSuchElementException;
import java.util.Optional;

public class TestOptional {

    static class Category {
        private String name;

        public Category(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "Category{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }

    static class Goods {
        private String name;

        private Category category;

        public Goods() {

        }

        public Goods(String name, Category category) {
            this.name = name;
            this.category = category;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Category getCategory() {
            return category;
        }

        public void setCategory(Category category) {
            this.category = category;
        }

        @Override
        public String toString() {
            return "Good{" +
                    "name='" + name + '\'' +
                    ", category=" + category +
                    '}';
        }
    }

    /**
     * 获取商品的分类名称(使用 Optional 类包装)
     * @param goods 商品
     * @return 分类名称
     */
    static String getGoodsCategoryName(Goods goods) {
        // 将商品实例包装入 Optional 类,创建 Optional<Goods> 对象
        Optional<Goods> goodsOptional = Optional.ofNullable(goods);
        //orElse(T other):如果有值则将其返回,否则返回指定的other 对象
        Goods goods1 = goodsOptional.orElse(new Goods("默认商品", null));
        // 此时 goods1 一定是非空,不会产生空指针异常
        Category category = goods1.getCategory();

        // 将分类实例包装入 Optional 类,创建 Optional<Category> 对象
        Optional<Category> categoryOptional = Optional.ofNullable(category);
        //orElseGet(Supplier<? extends T other>):如果有值则将其返回,否则返回由Supplier接口实现提供的对象
        Category category1 = categoryOptional.orElseGet(() -> new Category("默认分类"));
        // 此时 category1 一定是非空,不会产生空指针异常
        return category1.getName();
    }

    public static void main(String[] args) {
        // 实例化一个商品类
        Goods goods = null;
        // 获取商品的分类名称
        String categoryName = getGoodsCategoryName(goods);
        System.out.println(categoryName);
        /**
         * 如果 value 不为空,optionalValue 将包含一个值,orElseThrow 将返回该值。
         * 如果 value 为空,optionalValue 将为空,orElseThrow 将抛出一个由我们指定的 IllegalStateException 异常。
         * 这个异常可以根据你的需求进行替换,比如 NullPointerException、IllegalArgumentException 等。
         * */
        try {
            Optional<String> optionalValue = Optional.ofNullable(null);
            //判断是否包含对象
            System.out.println(optionalValue.isPresent()?"包含":"不包含");
            //ifPresent() 如果值存在,执行操作,否则不执行任何操作
            optionalValue.ifPresent(System.out::println);
            //get():如果调用对象包含值,返回该值,否则抛出异常
            String result1 = optionalValue.get();
            String result2 = optionalValue.orElseThrow(() -> new IllegalStateException("Value is NULL"));
        }catch (IllegalStateException e){
            System.out.println(e.getMessage());
        }catch (NoSuchElementException e){
            System.out.println("result1为空");
        }
    }
}

运行结果:

默认分类
不包含
result1为空

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值