Java学习_Day23

本文详细介绍了Java 8中的Lambda表达式和函数式接口,包括它们的使用方式、特点以及如何实现SAM接口。示例涵盖了Runnable、Consumer、Supplier、Predicate、Function等接口,并演示了方法引用和构造器引用的使用。此外,还讨论了Stream API的基本操作,如filter、map、reduce等,并展示了在实际问题中的应用。
摘要由CSDN通过智能技术生成

函数式编程思想

​ 注重“函数” 函数实现的结果, 以及它必须有 接口

​ 以前: 接口 对象 = new 实现类() ;

​ 现在: 接口 对象 = new 接口() {

​ 实现接口的抽象方法

​ }

JDK1.8新特性
1.lambda表达式
属于jdk的语法塘
分为三部分
(参数列表 参数名) -> {抽象方法的实现体}
①参数列表 当参数列表只有一个参数的时候,()可以省略,但是没有参数的时候,()不能省略; 参数类型可以不写
②-> 中间不能有空格
③{方法 的实现体}:当方法只有一句话时候,{}可以省略,但是当有return时候,{}必须存在,但是只有一句表达式的时候,return可以省略,这时候{}可以省略
补充:参数类型可以省略,但是参数类型必须一致,可以运用泛型
List c = Arrays.asList(12, 15, 11, 2, 5, 3, 6, 8, 42, 8);

/**
 * Lambda语法
 * 接口中有且只有一种方法
 */
public class Test1 {
    public static void main(String[] args) {
        Runnable runnable=new Runnable() {
            @Override
            public void run() {
                System.out.println("hello");
            }
        };
        //简写
        Runnable runnable1=()->{ System.out.println("hello");};

        //再次简写
        Runnable runnable2=()->{int a=8;
        System.out.println(a);};
        System.out.println();;
        new Thread(runnable1).start();
        new Thread(runnable2).start();




        List<Integer> c = Arrays.asList(12, 15, 11, 2, 5, 3, 6, 8, 42, 8);

//        c.sort((o1,o2)->o1.compareTo(o2));//==》c.sort(list);
//        for (Integer integer : c) {
//            System.out.println("-->"+integer);
//        }

        c.forEach((i) ->  System.out.println("-->"+i));

        c.stream().forEach(System.out::println);
    }
}
	**函数式接口**	
	lambda表达式就是实现SAM接口的语法糖(只有一个抽象接口需要实现,但是可以继承和包含其他的非抽象方法)
	@FunctionalInterface注解会强制该接口只有一个非抽象方法
				使用lambda有一些必要前提:
							①必须使接口
							②接口中有且只有一个抽象方法
		1.自定义函数接口
			eg:需求: 定义一个计算器接口,用于 计算两个数 , 该接口既可以 计算两个数之和、 两个数之差、两个数之乘积 ,两个数之商  
@FunctionalInterface
public interface Calc {

    public int calc(int a,int b);
}

import org.junit.Test;

public class Test1 {
    @Test
    public void test1(){
        Calc calc=(a,b)->a+b;
        int calc1 = calc.calc(5, 6);
        System.out.println(calc1);
    }
    @Test
    public void test2(){
        Calc calc=(a,b)->a-b;
        int calc1 = calc.calc(5, 6);
        System.out.println(calc1);
    }

    @Test
    public void test3(){
        Calc calc=(a,b)->a*b;
        int calc1 = calc.calc(5, 6);
        System.out.println(calc1);
    }

    @Test
    public void test4(){
        Calc calc=(a,b)->a/b;
        int calc1 = calc.calc(5, 6);
        System.out.println(calc1);
    }
}


补充:lambda可以省略的原因使规定了接口有且只有一个抽象方法
	
		2.消费性接口
			接口 : Consumer   void  accept(T t)
				解读:无返回值,但是要传递一或两个个泛型(任意类型但是不包括基本类型,基本类型的泛型为包装类)   Consumer ----》为接口名      accept---》为接口里面的抽象方法
 /**
     * 1、消费型接口
     *  Consumer      void accept(T t)
     */
    @Test
    public void Test1(){
        Consumer<Integer> consumer=(a)->{
            int num = 0;
            for (int i = 0; i <= a; i++) {
                num+=i;
            }
            System.out.println(num);
        };
        consumer.accept(100);
    }

    /**
     *
     *  Consumer      void accept(T t,U u)
     */
    @Test
    public void Test2(){
        BiConsumer<String,Integer> biConsumer =new BiConsumer<String, Integer>() {
            @Override
            public void accept(String s, Integer score) {
                System.out.println("亲爱的"+s+",分数:"+score);
            }
        };

        BiConsumer<String,Integer> biConsumer1=(s,score)-> System.out.println("亲爱的"+s+",分数:"+score);

        biConsumer1.accept("baby",100);

    }

		3.供给型接口
			接口:Supplier T get()
				解读:有返回值,无参数
    /**
     * 2、供给型接口
     *   Supplier  T get()  : 有返回值 无参数
     */

    @Test
    public void Test3(){
        Supplier<Integer> supplier=()->{return (int)(Math.random()*101);};
        //省略
        Supplier<Integer> supplier1=()->(int)(Math.random()*101);

        Integer integer = supplier1.get();
        System.out.println(integer);
    }

		4.判断型接口
			接口:  Predicate   boolean  test(T t)
				解读:有一个或两个参数,有返回值但是返回值为boolean类型
**
 * 判断型接口
 *   Predicate   boolean test(T)  判断是否满足 ,返回true/false
 */

@Test
public void Test4(){
    // 判断一个字符串的长度是否大于5
    Predicate<String> predicate =new Predicate<String>() {
        @Override
        public boolean test(String s) {
            return s.length()>5;
        }
    };

    //简写
    Predicate<String> predicate1 =s->s.length()>5;
    System.out.println(predicate1.test("sda"));

}

    /**
     *  BiPredicate  boolean test(T  t,  U u)
     */
    @Test
    public void Test5(){
        // 判断一个字符串是否包含另一个字符串
        BiPredicate<String,String> biPredicate=new BiPredicate<String, String>() {
            @Override
            public boolean test(String s, String s2) {
                return s.contains(s);
            }
        };

        //简写
        BiPredicate<String,String> biPredicate1=(s,s1)->s.contains(s1);

        System.out.println(biPredicate1.test("dada", "da"));

    }

    // 很多时候 是将 这个接口作为一个方法的参数来使用   ,
    @Test
    public void test8(){
        boolean flag  =   myTest("www.atguigu.com" ,"atguigu" , (s1,s2) -> s1.contains(s2));
        System.out.println(flag);
    }
    /**
     * 将接口的类型 作为方法的 形参
     * @param biPredicate
     * @return
     */
    public static boolean  myTest(String s1,String s2, BiPredicate<String , String > biPredicate){
        if(biPredicate.test(s1,s2)){
            System.out.println("条件满足");
            return  true;
        }else{
            System.out.println("条件不满足");
            return  false;
        }
    }
}
			5. 功能型接口(api--》接口)
				接口:Functio(T,R)  R  apply(T t)
								解读:第一个泛型T是方法的参数,第二个参数是返回值类型
				接口:BiFunction(T,U,R)  R apply(T t,U u)
								解读:第一个泛型T和第二个泛型U是方法的参数,第三个参数是返回值类型
   /**
     * 功能型接口
     *  Function(T,R)   R test(T)
     *  第一个泛型T是方法的参数,第二个参数是返回值类型
     */

    @Test
    public void Test6(){
        // 判断一个字符串的长度
        Function<String, Integer> function = new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                return s.length();
            }
        };

        //简写
        Function<String,Integer> function1=(s)->s.length();
        System.out.println(function1.apply("babt love you"));
    }


//    运用 把接口作为形参列表
    public static int getlen(String s,Function<String,Integer> fun){
        //调用接口的方法
        int n =fun.apply(s);
        return n;
    }

    @Test
    public void test7(){
        //genlen的参数决定了方法  实现(该繁峙县可以使用lambda表达式)
        int len=getlen("baby i love you", new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                return s.length();
            }
        });

        //简写
        int len1 = getlen("baby i love you", s -> s.length());
        System.out.println(len);
        System.out.println(len1);
    }

    /**
     * bifunction(U,T,R)   R  apply(U u,T t)
     */
    @Test
    public void test9(){
        //eg:求两个字符串的总长度
        BiFunction<String,String,Integer> biFunction = new BiFunction<String, String, Integer>() {
            @Override
            public Integer apply(String s, String s2) {
                return s.length()+s2.length();
            }
        };
        Integer apply = biFunction.apply("hello", "world");
        System.out.println(apply);

        //简写
        BiFunction<String,String,Integer> biFunction1=(s,s1)->s.length()+s1.length();
        Integer apply1 = biFunction1.apply("hello", "world");
        System.out.println(apply1);

    }
		**方法引用和构造器的引用**
				1.方法的引用
					①类的实例名(对象名):实例方法名(没有加static修饰的方法)
 /**
     * 类的实例名(对象名):实例方法名(没有加static修饰的方法)
     * 1.有且只有一个抽象方法
     * 2.抽象方法只有一句话
     * 3.这句话就是方法的调用
     * 4.调用的方法的参数与抽象方法保持一致
     * eg:
     *            public void accept(String s) {
     *                 System.out.println(s+"hekkk"); //此时就不一致
     *             }
     */
    @Test
    public void test1(){
        //eg:通过consumer接口输出helloword

        Consumer<String> consumer=new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s); //方法的调用
            }
        };

        //lambda方法
        Consumer<String> consumer1=s -> System.out.println(s);
        consumer1.accept("helloword");

        //方法调用
        //System.out  类的实例名
        //println    引用的方法
        Consumer<String> consumer2=System.out::println;
        consumer2.accept("baby");

    }

					②类名::静态方法名 (加了static修饰的方法)
   /**
     * 类名:静态方法
     * 1.有且只有一个抽象方法
     * 2.抽象方法只有一句话
     * 3.这句话就是方法的调用
     * 4.调用的方法的参数与抽象方法保持一致
     */
    @Test
    public void test2(){
        //eg:比较2个double类型大小 返回int
        BiFunction<Double,Double,Integer> biFunction=new BiFunction<Double, Double, Integer>() {
            @Override
            public Integer apply(Double aDouble, Double aDouble2) {
                return Double.compare(aDouble,aDouble2);//1 0 -1
            }
        };
        biFunction.apply(5.8,7.3);

        //lambda方法
        BiFunction<Double,Double,Integer> biFunction1=(d1,d2)->Double.compare(d1,d2);
        //方法调用
        BiFunction<Double,Double,Integer> biFunction2=Double::compareTo;

    }

					③类名::实例方法名
 /**
     * 类名:实例方法名
     * 1.有且只有一个抽象方法
     * 2.抽象方法只有一句话
     * 3.这句话就是方法的调用
     * 4.抽象方法的第一个参数是方法的调用者,后面的参数与该方法的参数列表一致
     */
    @Test
    public void test3(){
        //eg:判断一个字符串是否存在另一个字符串  contains是string类的方法
        BiFunction<String,String,Boolean> booleanBiFunction=new BiFunction<String, String, Boolean>() {
            @Override
            public Boolean apply(String s, String s2) {
                return s.contains(s2);
            }
        };

        //lambda方法
        BiFunction<String,String,Boolean> booleanBiFunction1=(s,s1)->s.contains(s1);
        //方法调用
        BiFunction<String,String,Boolean> booleanBiFunction2=String::contains;
        System.out.println(booleanBiFunction2.apply("hello", "he"));
    }

    @Test
    public void test4(){
        //eg:比较2个double类型大小 返回int


        //lambda方法

        //方法调用


    }

		**构造方法的引用**
				① 类名::new
    /**
     * 构造器的引用
     *  类名::new
     *  1.有接口(没有自定义)
     *  2.抽象方法中只有一句代码的实现
     *  3.该代码就是构造器的调用
     *  4.构造器的参数与抽象方法的参数保持一致
     */
    @Test
    public void test1(){
        Student baby = new Student(5, "baby");
        //函数式接口
        BiFunction<Integer,String,Student> function=new BiFunction<Integer, String, Student>() {
            @Override
            public Student apply(Integer id , String s) {
                return new Student(id,s);//构造器的引用
            }
        };
//lambda简写
        BiFunction<Integer,String,Student> function1=(id,s)->new Student(id,s);
//        构造器的引用
        BiFunction<Integer,String,Student> function2=Student::new;
        System.out.println(function2.apply(1, "ly"));
    }
			②数组类型:new
 /**
     * 构造器的引用
     *  数组类型::new
     *  1.有接口(没有自定义)
     *  2.抽象方法中只有一句代码的实现
     *  3.数组的的长度与抽象方法的参数保持一致
     */
    @Test
    public void test2(){
        //eg:创建一个指定长度的int类型数组
        int[] ints = new int[5];//类型为包装类  integer
        //函数式接口
        Function<Integer,int[]> function= new Function<Integer, int[]>() {
            @Override
            public int[] apply(Integer i) {
                return new int[i];
            }
        };
//lambda简写
        Function<Integer,int[]> function1=i->new int[i];
//        构造器的引用
        Function<Integer,int[]> function2=int[]::new;

        //调用方法的时候才赋值参数
        int[] apply = function2.apply(5);
        for (int i = 0; i <apply.length ; i++) {
            System.out.println(apply[i]);
        }
    }

streamAPI
streamAPI:java.util.stream类中
功能:可以将集合数组的元素进行查找,过滤,筛选等若干处理
好处:简化程序,写更精简的,高效的代码
注意:
1.不能存数组
2.不会改变源数据,每次操作后会返回一个新的stream流
3.stream流是延迟操作,只有出现结果的时候,才会执行过程
stream流分为三步:
1.创建流
2.中间处理
3.最终操作
在这里插入图片描述


public class Test1 {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("hsd", "addsa", "fasda", "dasdua", "hello");
        //创建流
        Stream<String> stream = list.stream();
        //中间操作 (会得到新的流,流操作后会自动关闭)
        Stream<String> stringStream = stream.filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length() > 4;
            }
        });
        //最终操作  //消费型接口
        stringStream.forEach(s -> System.out.println(s));


        //jdk8可以采取链式操作(中间操作不断,流不会终止和产生新的)
        long count = list.stream()//开始操作 只能一个
                .filter(s -> s.length() > 4) //中间操作  可以很多个
                .count();//最终操作  只能有一个

    }
}

练习:
/**
  • 需求:通过streamAPI 查询年龄在35岁以上的
  • 需求:查询35随以上的,工资8000
  • 需求:查询工资20000 35岁以上 火箭1
    */

/**
 * 需求:通过streamAPI 查询年龄在35岁以上的
 * 需求:查询35随以上的,工资8000
 * 需求:查询工资20000 35岁以上  火箭1
 */
public class Test1 {

    @Test
    public void Test1(){
        List<Emyee> list = Arrays.asList(
                new Emyee(1,"s",10000,18,"火箭1"),
                new Emyee(2,"s1",100000,25,"火箭2"),
                new Emyee(3,"s2",1000000,35,"火箭3"),
                new Emyee(4,"s3",10000,45,"火箭2"),
                new Emyee(5,"s4",10000,55,"火箭1"),
                new Emyee(6,"s5",100000,33,"火箭2"),
                new Emyee(7,"s6",10000,22,"火箭3")
        );
        // 1、 创建流
        Stream<Emyee> stream =list.stream();
//中间操作
        Stream<Emyee> stream1 =stream.filter(new Predicate<Emyee>() {
            @Override
            public boolean test(Emyee e) {
                return e.getAge()>35;
            }
        });
        stream1.forEach(System.out::println);

        list.stream()
                .filter(emyee -> emyee.getAge()>35 &&emyee.getSalary()>8000)
//                .forEach(System.out::println);
                    .forEach(emyee-> System.out.println(emyee.getName()));

        list.stream()
                .filter(emyee -> emyee.getAge()>35 &&emyee.getSalary()>8000 &&emyee.getSection().equals("火箭1"))
                .forEach(System.out::println);

    }
}



public class Emyee {
    private  int id;
    private  String name;
    private double salary;
    private int age;
    private String section;

    public Emyee() {
    }

    public Emyee(int id, String name, double salary, int age, String section) {
        this.id = id;
        this.name = name;
        this.salary = salary;
        this.age = age;
        this.section = section;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public int getAge() {
        return age;
    }

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

    public String getSection() {
        return section;
    }

    public void setSection(String section) {
        this.section = section;
    }

    @Override
    public String toString() {
        return "Emyee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", salary=" + salary +
                ", age=" + age +
                ", section='" + section + '\'' +
                '}';
    }
}

stream流三步的主要方法
①创建流的方法:
1.顺序流
2.并列流
3.数组创建流
4.stream of创建流
创建无限流(2种方法)


/**
     * 创建流stream
     */
    public class Test1 {

    /**
         * 创建顺序流 和并行流
         */
        @Test
        public void test1(){
            List<String> list = Arrays.asList("jaa", "sada", "jafafa");
            //创建顺序流
            Stream<String> stream = list.stream();

            //创建并行流 (由多个线程创建一个stream对象)
            //数据量大可以用并行流 该流的输出顺序不一定
            Stream<String> stream1 = list.parallelStream();

            stream.forEach(System.out::println);
            System.out.println();
            stream1.forEach(System.out::println);
        }


        /**
         * 创建数组 流
         */
        @Test
        public void test2(){
            String[] list = {"jaa", "sada", "jafafa"};
            //数组创建流
            Stream<String> stream = Arrays.stream(list);

            stream.forEach(System.out::println);
        }

    /**
     * stream of(T。。。)   创建流
     */
    @Test
    public void test3(){
        
        //数组创建流
        Stream<String> stream = Stream.of("jaa", "sada", "jafafa");

        long count = stream.filter(s -> s.length() > 1).count();
        System.out.println("元素个数:"+count);

    }

    /**
     * 创建一个无限流
     */
    @Test
    public void test4(){

        //数组创建流
      Stream.generate(new Supplier<Double>() {
//          返回一个double类型的随机数
          @Override
          public Double get() {
              return Math.random();
          }
      });
//?  源源不断的产生数据
        Stream<Double> generate = Stream.generate(() -> Math.random());

        generate.forEach(System.out::println);
    }


    /**
     * 创建一个无限流
     */
    @Test
    public void test5(){

        //数组创建流
        Stream<Integer> iterate = Stream.iterate(0, new UnaryOperator<Integer>() {
            @Override
            public Integer apply(Integer i) {
                return i += 1;
            }
        });


//?  源源不断的产生数据


        iterate.forEach(System.out::println);
    }


}

②中间操作


/**
 * stream流的中间操作
 */
public class Test1 {

    @Test
    public void teat1(){
        List<String> list = Arrays.asList("sdadaada","java", "jdbc", "mysql", "servlet", "maven","java","java");

        list.stream()
                .filter(s-> s.length()>2)//判断字符个数
//                .sorted()//判断数组的排列
                .sorted(new Comparator<String>() {
                    @Override
                    public int compare(String o1, String o2) {
                        return o1.length()-o2.length();
                    }
                })
                .skip(1)//跳过一个
                .limit(2)//取前两个
                .peek(s -> System.out.println("study="+s))  //这里的s与20行的s相对应  表示修饰哪些  不会改变元素本身
//                .forEach(s->System.out::println);
                .forEach(s->System.out.println());

//        .distinct()  自动过滤重复的元素
        list.stream().distinct().forEach(System.out::println);
//   map  对元素进行处理,并返回处理结果
        list.stream().map(new Function<String, Integer>() {//会改变元素本身
            @Override
            public Integer apply(String s) {
                return s.length();
            }
        }).forEach(System.out::println);


        list.stream().map(s-> "元素:"+s).forEach(System.out::println);
    //map和peek的区别:
    //map(Function)将处理的结果放入流中
    //peek(Consumer)知识处理过程,没有返回值,不会将结果放入stream流中


    }

        @Test
    public void test2(){
            List<String> list = Arrays.asList("sdadaada","java", "jdbc", "mysql", "servlet", "maven","java","java");
//          根据flatMap的实现,将元素先拆分成指定的一段流,最后每一个元素的流数据合并一个流
            list.stream().flatMap(new Function<String, Stream<String>>() {
                @Override
                public Stream<String> apply(String s) {
                    return Arrays.stream(s.split("a"));//由于split拆分的返回的是数组 ---》转化为流
                }
            }).forEach(System.out::println);
        }

}

③最终操作


/**
 * 最终操作
 */
public class Test1 {
    /**
     * allMatch  检查元素是否都匹配
     */
    @Test
    public void test1(){
        List<Integer> list = Arrays.asList(1, 8, 6, 3, 2, 4, 5);
//返回该元素是否全都小于5
        boolean b = list.stream().allMatch(n -> n <= 6);
        System.out.println(b);
    }

    /**
     * antMatch  检查元素是否由一个满足
     */
    @Test
    public void test2(){
        List<Integer> list = Arrays.asList(1, 8, 6, 3, 2, 4, 5);
//返回该元素是否全都小于5
        boolean b = list.stream().anyMatch(n -> n <= 6);
        System.out.println(b);
    }

    /**
     * onneMatch  检查元素是否没有匹配
     */
    @Test
    public void test3(){
        List<Integer> list = Arrays.asList(1, 8, 6, 3, 2, 4, 5);
//返回该元素是否全存在偶数 (存在一个为false)
        boolean b = list.stream().noneMatch(n -> n%2==0);
        System.out.println(b);
    }

    /**
     *findFirst()  返回第一个元素
     */
    @Test
    public void test4(){
        List<Integer> list = Arrays.asList(1, 8, 6, 3, 2, 4, 5);
//返回值Optional  :用于封装返回值的一个工具  可避免空指针异常
        Optional<Integer> first = list.stream().findFirst();
        System.out.println(first);//Optional.empty为空
//        System.out.println(first.get());//返回第一个元素
        System.out.println(first.isPresent());//判断元素是否存在
    }


    /**
     *findAny()  返回任意一个元素
     */
    @Test
    public void test5(){
        List<Integer> list = Arrays.asList(1, 8, 6, 3, 2, 4, 5);
//返回值Optional  :用于封装返回值的一个工具  可避免空指针异常
        Optional<Integer> first = list.stream().findAny();
        System.out.println(first);//Optional.empty为空
        System.out.println(first.get());//返回first中的一个元素
        System.out.println(first.isPresent());//判断元素是否存在
    }

    /**
     *max()  最大的元素
     * min() 最小的元素
     */
    @Test
    public void test6(){
        List<Integer> list = Arrays.asList(1, 8, 6, 3, 2, 4, 5);
        Optional<Integer> max = list.stream().max((o1, o2) -> o1.compareTo(o2));
        Optional<Integer> min = list.stream().min((o1, o2) -> o1.compareTo(o2));
        System.out.println(max);
        System.out.println(min);

    }

    /**
     *reduce()  求和
     */
    @Test
    public void test7(){
        List<Integer> list = Arrays.asList(1, 8, 6, 3, 2, 4, 5);
        Optional<Integer> reduce = list.stream().reduce(new BinaryOperator<Integer>() {
            @Override
            public Integer apply(Integer a, Integer b) {
                return a + b;
            }
        });

        //可以设置初始值
        Integer reduce1 = list.stream().reduce(10, new BinaryOperator<Integer>() {
            @Override
            public Integer apply(Integer a, Integer b) {
                return a + b;
            }
        });

        System.out.println(reduce);
        System.out.println(reduce1);

    }


    /**
     * 遍历 计算总数 如果需要将中间操作的结果进行接收 可以用collect()
     * 可将处理的流收集成  集合类型
     */
    @Test
    public void test8(){
        List<String> list = Arrays.asList("sdadaada","java", "jdbc", "mysql", "servlet", "maven","java","java");
        List<String> a = list.stream().flatMap(new Function<String, Stream<String>>() {
            @Override
            public Stream<String> apply(String s) {
                return Arrays.stream(s.split("a"));//由于split拆分的返回的是数组 ---》转化为流
            }
        }).collect(Collectors.toList());//收集成新的集合
        System.out.println("新的集合:" + a);

    }







}

知识补充:
optiona类型

public class TestOptional {
    public static void main(String[] args) {
          // Optional避免空指针异常
        Employee emp = null;
     //   System.out.println(emp.getName());  // 空指针

        // of : 将一个对象封装成 option
        Optional<Employee> optional = Optional.of(null);
        // 判断对象是否存在
        if(optional.isPresent()){
            System.out.println(optional.get());
        }else{
            System.out.println("不存在");
        }

        //  orElse(obj) : 如果对象为空则使用obj初始化
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值