JAVA_8新特性

JAVA8新特性

一、Lambda表达式

1.概念:

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

2.格式举例:

/*
举例:(o1,o2) -> Integer.compare(o1,o2);
格式:
->:Lambda操作符或箭头操作符
-→>左边: Lambda形参列表(其实就是接口中的抽象方法的形参列表)
->右边: Lambda体(其实就是重写的抽象方法的方法体)
*/

3.六种使用方式

/*
 Lambda表达式的使用:(分为6种情况介绍)
总结:
->左边:Lambda形参列表的参数类型可以省略(类型推断);
     如果Lambda形参列表只有一个参数,则()可以省略
->右边:Lambda体应该使用一对{}包裹;如果Lambda体只有一条执行语句(可能是return语句),那么可以同时省略掉{}和return.

*/
//语法格式一:无参,无返回值
@Test
    public  void test1(){
    Runnable run=new Runnable () {
        @Override
        public void run() {
            System.out.println ("大器晚成i");
        }
    };
    run.run ();

    System.out.println ("*************");
    //Lambda表达式改写:
    Runnable run2= ()->{
        System.out.println ("霸王花i");
    };

    run2.run ();
}
//语法格式二:有参,无返回值
@Test
    public  void test2(){
    Consumer<String> consumer=new Consumer<String> () {
        @Override
        public void accept(String s) {
            System.out.println (s);
        }
    };
    consumer.accept ("易烊千玺真帅气");
    System.out.println ("*********************");
    Consumer<String> consumer1=(String s)-> {
            System.out.println (s);
        };
    consumer1.accept ("易烊千玺超级无敌巨无霸帅气");

}
//语法格式三:数据类型可以省略,因为可由编译器推断得出,称为类型推断
@Test
    public  void test3(){
    Consumer<String> consumer3=new Consumer<String> () {
        @Override
        public void accept(String s) {
            System.out.println (s);
        }
    };
    consumer3.accept ("易烊千玺真帅气啊啊啊");
    System.out.println ("*********************");
    Consumer<String> consumer4=( s)-> {
        System.out.println (s);
    };
    consumer4.accept ("是呀,易烊千玺超级无敌巨无霸帅气");

}
//语法格式四:Lambda若只需要一个参数时,参数的小括号可以省略
    @Test
    public  void test4(){
        Consumer<String> consumer6=s-> {
            System.out.println (s);
        };
        consumer6.accept ("我也觉得易烊千玺超级无敌巨无霸帅气");

    }
    //语法格式五: Lambda需要两个或以上的参数,多条执行语句,并且可以有返回值
    @Test
    public void test5(){
        Comparator<Integer> comparator=new Comparator<Integer> () {
            @Override
            public int compare(Integer o1, Integer o2) {
                System.out.println (o1);
                System.out.println (o2);
                return o1.compareTo (o2);
            }
        };
        int compare = comparator.compare (12,6);
        System.out.println (compare);
        System.out.println ("********************");
        Comparator<Integer> comparator2=(o1,o2)-> {
                System.out.println (o1);
                System.out.println (o2);
                return o1.compareTo (o2);
            };
         int compare2 = comparator2.compare (12,36);
          System.out.println (compare2);

    }
    //语法格式六:当Lambda体只有一条语句时,return 与大括号若有,都可以省略
@Test
    public  void test(){
    Comparator<Integer> comparator2=(o1,o2)-> {
        return o1.compareTo (o2);
    };
    int compare2 = comparator2.compare (12,36);
    System.out.println (compare2);
    System.out.println ("*************");
    Comparator<Integer> comparator=(o1,o2)-> o1.compareTo (o2);
    int compare = comparator.compare (12,36);
    System.out.println (compare);
}

4.本质:

作为函数式接口的实例

二、函数式(Functional)接口

1.概念及举例:

如果一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口

举例:

package Java8;
//我们可以在一个接口上使用@Functionallnterface注解,这样做可以检查它是否是一个函数式接口。同时javadoc也会包含一条声明,说明这个接口是一个函数式接口。
@FunctionalInterface
public interface MyInterface {
    void method();
}

2. Java内置四大核心函数式接口

函数式接口参数类型返回类型用途
Consumer消费型接口Tvoid对类型为T的对象应用操作,包含方法:void accept(T t)
Supplier供给型接口T返回类型为T的对象,包含方法:T get()
Function<T,R>函数型接口TR对类型为T的对象应用操作,并返回结果。结果是R类型的对象。包含方法:R apply(T t)
Predicate断定型接口Tboolean确定类型为T的对象是否满足某约束,并返回boolean值。包含方法:boolean test(T t)

3.消费型接口举例

   //Consumer<T>---->void accept(T t) 举例:
  @Test
  public void test(){
      happyTime (3, new Consumer<Double> () {
          @Override
          public void accept(Double aDouble) {
              System.out.println ("我花费了"+aDouble+"元去买了一瓶快乐肥宅水");
          }
      });
      System.out.println ("************************");
      happyTime (6, money->System.out.println ("我花费了"+money+"元去买了双倍快乐"));
  }
      public void happyTime(double money, Consumer<Double> con){
      con.accept (money);

      }

4.断定型接口举例

//断定型接口Predicate<T>---->boolean test(T t)   举例:
      @Test
    public  void test2(){
          List<String> list = Arrays.asList ("北京", "天津", "东京", "京曲", "昆曲", "秦腔");
          List<String> filterList= filterString (list, new Predicate<String> () {
              @Override
              public boolean test(String s) {
                  return s.contains ("京");
              }
          });
          System.out.println (filterList);
          System.out.println ("**********");
          List<String> filterList2= filterString(list,s-> s.contains ("曲"));
          System.out.println (filterList2);
      }
    //根据给定的规则,过滤集合中的字符串。此规则由Predicate的方法决定
    public List<String> filterString(List<String>list, Predicate<String> pre ){
        ArrayList<String> stringArrayList=new ArrayList<> ();
        for (String s:list) {
            if(pre.test (s)){
                stringArrayList.add (s);
            }

        }
        return stringArrayList;
    }

三、方法引用与构造器引用

1.方法引用的使用

/*
方法引用的使用
1.使用情境:当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!
2.方法引用,本质上就是Lambda表达式,而Lambda表达式作为函数式接口的实例。所以方法引用,也是函数式接口的实例。
3.使用格式:类(或对象)::方法名
4.具体分为如下的三种情况:
情况一:      对象:∶非静态方法
情况二:      类::静态方法

情况三:      类::非静态方法
5.方法引用使用的要求:要求接口中的抽象方法的形参列表和返回值类型与方法引用的方法的形参列表和返回值类型相同!(主要针对情况一和情况二)
*/

2.方法引用的使用的具体三种情况

情况一: 对象:∶非静态方法
   //情况一:对象∶∶实例方法
    //Consumer中的void accept( T t)
    // PrintStream中的void printLn(T t)
    @Test
    public  void test1(){
        Consumer<String> consumer=s -> System.out.println (s);
        consumer.accept ("易烊千玺");
        System.out.println ("*************");
        PrintStream ps=System.out;
        Consumer<String> consumer2= ps::println;
        consumer2.accept ("YiYangQianXi");
    }
    // Supplier中的T get()
    //Employee中的StringGetName()
    @Test
    public void test2(){
       Employee employee=new Employee("Tom",18);
        Supplier<String> supplier=()->employee.getName ();
        System.out.println (supplier.get ());
        System.out.println ("***************");
        Supplier<String> supplier1=employee::getName;
        System.out.println (supplier1.get ());
    }
情况二: 类::静态方法
  //情况二:类::静态方法
    //Comparator中的int compare( T t1,T t2)
    // Integer中的int compare(T t1,T t2)
    @Test
    public  void test3(){
        Comparator<Integer> comparator=(o1,o2)->Integer.compare (o1,o2);
        System.out.println (comparator.compare (12, 36));
        System.out.println ("******************");
        Comparator<Integer> comparator2=Integer::compareTo;
        System.out.println (comparator2.compare (12,6));
    }
//Function中的R T apply(T t)
// Math中的Long round( Double d)
    @Test
    public  void test4(){
        Function<Double, Long> function=new Function<Double, Long> () {
            @Override
            public Long apply(Double aDouble) {
                return Math.round (aDouble);
            }
        };
        System.out.println (function.apply (12.3));
        System.out.println ("***********");
        Function<Double, Long> function2=aDouble -> Math.round (aDouble);
        System.out.println (function2.apply (12.8));
        System.out.println ("********************");
        Function<Double, Long> function3=Math::round;
        System.out.println (function3.apply (19.1));
    }
情况三: 类::非静态方法
    //情况三:类:实例方法
    //Comparator中的int compare(T t1,T t2)
    //String中的int t1.compareTo(t2)
    @Test
    public  void test5(){
        Comparator<String> comparator=new Comparator<String> () {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo (o2);
            }
        };
        System.out.println (comparator.compare ("abc", "ab"));
        System.out.println ("***********");
        Comparator<String> comparator2=(o1,o2)->o1.compareTo (o2);
        System.out.println (comparator2.compare ("am", "abm"));
        System.out.println ("***********");
        Comparator<String> comparator3=String::compareTo;
        System.out.println (comparator3.compare ("a", "f"));
    }

//BiPredicate中的booLean test(T t1,T t2);
// String中的boolean t1.equals(t2)
    @Test
    public  void test6(){
        BiPredicate<String,String> biPredicate=new BiPredicate<String, String> () {
            @Override
            public boolean test(String o, String o2) {
                return o.equals (o2);
            }
        };
        System.out.println (biPredicate.test ("ab", "ab"));
        System.out.println ("****************");
        BiPredicate<String,String> biPredicate2=(o,o2)-> o.equals (o2);
        System.out.println (biPredicate2.test ("abc", "ab"));
        System.out.println ("****************");
        BiPredicate<String,String> biPredicate3=String::equals;
        System.out.println (biPredicate3.test ("b", "ab"));
    }

   //Function中的R appLy(T t)
    //Employee中的String getName();
  @Test
    public void test7(){
      Employee e1=new Employee ("Jerry",66);
      Function<Employee,String> function=new Function<Employee, String> () {
          @Override
          public String apply(Employee employee) {
              return employee.getName ();
          }
      };
      System.out.println (function.apply (e1));
      System.out.println ("*****************");
      Function<Employee,String> function2=employee->e1.getName ();
      System.out.println (function2.apply (e1));
      System.out.println ("*****************");
      Function<Employee,String> function3=Employee::getName;
      System.out.println (function3.apply (e1));
  }

3.构造器引用

和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致。
抽象方深的返回值类型即为构造器所属的类的类型

    //构造器引用
    // Supplier中的T get()
    @Test
    public void test1(){
Supplier<Employee> supplier=new Supplier<Employee> () {
        @Override
        public Employee get() {
            return new Employee ();
        }
    };
        System.out.println (supplier.get ());
        System.out.println ("**************");
        Supplier<Employee> supplier2=()->new Employee ();
        System.out.println (supplier2.get ());
        System.out.println ("*****************");
        Supplier<Employee> supplier3=Employee::new;
        System.out.println (supplier3.get ());
    }
//Function中的R appLy(T t)
    @Test
    public void test2(){
        Function<Integer,Employee> function=age->new Employee(age);
        Employee employee = function.apply (13);
        System.out.println (employee);
        System.out.println ("***************");
        Function<Integer,Employee> function2=Employee::new;
        Employee employee1 = function2.apply (19);
        System.out.println (employee1);

    }
//BiFunction中的apply(T t,U u)
    @Test
    public  void test3(){
        BiFunction<String,Integer,Employee> biFunction=(name,age ) -> new Employee (name,age);
        Employee employee = biFunction.apply ( "霸王花",16);
        System.out.println (employee);
        System.out.println ("************");
        BiFunction<String,Integer,Employee> biFunction2=Employee::new;
        Employee employee2 = biFunction2.apply ( "易烊千玺",21);
        System.out.println (employee2);

    }

4.数组引用

大家可以把数组看做是一个特殊的类,则写法与构造器引用一致

 //数组引用
 //Function中的R appLy(T t)
    @Test
    public  void test4(){
        Function<Integer,String[]> function=len->new String[len];
        String[] apply = function.apply (5);
        System.out.println (Arrays.toString (apply));
        System.out.println ("****************");
        Function<Integer,String[]> function2=String[]::new;
        String[] apply2 = function2.apply (3);
        System.out.println (Arrays.toString (apply2));
    }

四、 Stream API

1. Stream API 的概述

/*
StreamAPI的概述
1.stream关注的是对数据的运算,与CPU打交道,集合关注的是数据的存储,与内存打交道
2.注意:
①Stream自己不会存储元素。
②Stream 不会改变源对象。相反,他们会返回一个持有络果的新Stream .
③Stream操作是延迟执行的。这意味着他们会等到需要结果的时候才执行
3.Stream执行流程
   ① Stream的实例化
   ②一系列的中间操作(过滤、映射、...)
   ③终止操作
4.说明:
① 一个中间操作链,对数据源的数据进行处理
②一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用

 */

2.创建Stream的实例化

①通过集合
  //创建Stream的方式一:通过集合
    @Test
    public void test(){
        List<Employee> employeeList = EmployeeData.getEmployees ();

        //default Stream<E> stream() :返回一个顺序流
        Stream<Employee> employeeStream = employeeList.stream ();


        //default Stream<E> parallelStream:返回一个并行流
        Stream<Employee> parallelStream = employeeList.parallelStream ();

    }
②通过数组
//创建Stream方式二:通过数组
    @Test
    public void test2(){
        int arr[]=new int[]{1,2,44,21,12};
    //调用Arrays类的static <T> Stream<T> stream(T[ ] array):返回一个流
        IntStream intStream = Arrays.stream (arr);

        Employee e1=new Employee ("Tom",18);
        Employee e2=new Employee ("Linda",12);
        Employee ep[]=new Employee[]{e1,e2};
        Stream<Employee> employeeStream = Arrays.stream (ep);

    }
③通过Stream的of()
 //创建Stream方式三:通过Stream的of()
    @Test
    public  void test3(){
        Stream<Integer> integerStream = Stream.of (1, 32, 12, 33, 13);


    }
④创建无限流

    //创建Stream方式四:创建无限流
    @Test
    public  void test4(){
     //迭代
     // public static <T>Stream<T> iterate(final T seed,final UnaryOperator<T> f)
        //循环前10个
        Stream.iterate (0,t->t+2).limit (10).forEach (System.out::println);
        System.out.println ("*********************");

     // 生成
      //public static<T> Stream<T> generate (Supplier<T> s)
        Stream.generate (Math::random).limit (5).forEach (System.out::println);
    }

3. Stream的中间操作

①筛选与切片
方法名含义
filter(Predicate p)接收Lambda ,从流中排除某些元素
limit(n)截断流,使其元素不超过给定数量
skip(n)跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n 个,则返回
distinct()筛选,通过流所生成元素的 hashCode()和equals()去除重复元素
  //1.筛选与切片
   @Test
   public  void test1(){
      List<Employee> employeeList = EmployeeData.getEmployees ();
      Stream<Employee> stream = employeeList.stream ();

//filter(Predicate p)—-接收Lambda ,从流中排除某些元素。
      stream.filter (e -> e.getAge () > 25).forEach (System.out::println);
      System.out.println ("**************");

//limit(n)--截断流,使其元素不超过给定数量。
     //错误写法: stream.limit (2).forEach (System.out::println);
      employeeList.stream ().limit (1).forEach (System.out::println);
      System.out.println ("**************");

//skip(n)--跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n 个,则返回
      employeeList.stream ().skip (2).forEach (System.out::println);
      System.out.println ("*******************");

      //暂时未实现去重效果
//distinct()—筛选,通过流所生成元素的 hashCode()和equals()去除重复元素
      employeeList.add (new Employee ("AAA",16));
      employeeList.add (new Employee ("AAA",18));
      employeeList.add (new Employee ("AAA",18));
      employeeList.add (new Employee ("AAA",18));
//      System.out.println (employeeList.toString ());
//      System.out.println ("**************");

      employeeList.stream ().distinct ().forEach (System.out::println);

   }
②映射
方法含义
map(Function f)接收一个函数作为参数,将元素转换成其他形式或提取信息,该函数会将元素转换成其他形式或提取信息,该函数会被应用到每个元素上,并将其映射成一个新的元素。
flatNap(Function f)接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
 //2.映射
   @Test
   public  void test(){
      List<String> arrayList= Arrays.asList ("aa","bb","cc");
//map(Function f)—接收一个函数作为参数,将元素转换成其他形式或提取信息,
//该函数会将元素转换成其他形式或提取信息,该函数会被应用到每个元素上,并将其映射成一个新的元素。
       arrayList.stream ().map (s -> s.toUpperCase ()).forEach (System.out::println);
      System.out.println ("*****************");

//练习:获取员工姓名长度大于2的员工的姓名。
      List<Employee> employees = EmployeeData.getEmployees ();
//      employees.stream ().map (e->e.getName ().length ()>2).forEach (System.out::println);
      Stream<String> stringStream = employees.stream ().map (e -> e.getName ());
      stringStream.filter (name->name.length ()>2).forEach (System.out::println);
      System.out.println ("*****************");

//flatNap(Function f)-接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
//略
/*类似于把一个数组添加到另一个数组中的情况二:
      情况一:把数组b添加到数组a中,新数组的长度为数组a的长度+1,即数组b作为一个整体添加到数组a中
      情况二:把数组b添加到数组a中,新数组的长度为数组a的长度+数组b的长度。
 */
   }
③排序
方法含义
sorted()产生一个新流,其中按自然顺序排序
sorted(Comparator com)产生一个新流,其中按比较器顺序排序
   //3.排序
   @Test
   public  void test3(){
      List<Integer> list=Arrays.asList (1,23,12,56,32);
   //sorted()  --产生一个新流,其中按自然顺序排序
      list.stream ().sorted ().forEach (System.out::println);
      System.out.println ("*********************");

  //sorted(Comparator com) 产生一个新流,其中按比较器顺序排序
      List<Employee> employees = EmployeeData.getEmployees ();
      employees.stream ().sorted ((e1,e2)->Integer.compare (e1.getAge (),e2.getAge ())).forEach (System.out::println);

   }

4.测试Stream的终止操作

①匹配与查找
方法含义
allMatch(Predicate p)检查是否匹配所有元素
anyMatch(Predicate p)检查是否至少匹配一个元素
noneMatch(Predicate p)检查是否没有匹配的元素
findFirst返回第一个元素
findAny返回当前流中的任意元素
count返回流中元素的总个数
max ( Comparator c)返回流中最大值
min(comparator c)返回流中最小值
forEach(Consumer c内部迭代
    //1.匹配与查找
    @Test
    public  void test(){
List<Employee> employees = EmployeeData.getEmployees ();
//allMatch(Predicate p)—检查是否匹配所有元素。
//练习:是否所有的员工的年龄都大于18
        boolean b = employees.stream ().allMatch (e -> e.getAge () > 18);
        System.out.println (b);

//anyMatch(Predicate p)—检查是否至少匹配一个元素。
//练习:是否存在员工的年龄大于30
        boolean b1 = employees.stream ().anyMatch (e -> e.getAge () > 30);
        System.out.println (b1);

//noneMatch(Predicate p)--检查是否没有匹配的元素。
//练习:是否存在员工”张三”
        boolean b2 = employees.stream ().noneMatch (e -> e.getName ().contains ("张三"));
        System.out.println (b2);
    }
@Test
    public  void test2(){
    List<Employee> employees = EmployeeData.getEmployees ();
//findFirst——返回第一个元素
    Optional<Employee> first = employees.stream ().findFirst ();
    System.out.println (first);
//findAny一-返回当前流中的任意元素
    Optional<Employee> any = employees.stream ().findAny ();
    System.out.println (any);
// count—-返回流中元素的总个数
    long count = employees.stream ().count ();
    System.out.println (count);
//max ( Comparator c)一返回流中最大值
//练习:返回最大的年龄:
    Stream<Integer> integerStream = employees.stream ().map (e -> e.getAge ());
    Optional<Integer> max = integerStream.max (Double::compare);
    System.out.println (max);
//min(comparator c)—返回流中最小值
//练习:返回最小年龄的员工
    Optional<Employee> min = employees.stream ().min ((e1, e2) -> Double.compare (e1.getAge (), e2.getAge ()));
    System.out.println (min);
//forEach(Consumer c)—内部迭代

}
②规约
方法含义
reduce(T identity, BinaryOperator b)可以将流中元素反复结合起来,得到一个值。返回T
reduce(BinaryOperator b)可以将流中元素反复结合起来,得到一个值。返回Optional
//2.规约
@Test
    public void test3(){
//reduce(T identity, BinaryOperator b)可以将流中元素反复结合起来,得到一个值。返回T
    //练习1:计算1-10的自然数的和
    List<Integer> list= Arrays.asList (12,9,33,23);
    Integer sum = list.stream ().reduce (0, Integer::sum);
    System.out.println (sum);

//reduce(BinaryOperator b)可以将流中元素反复结合起来,得到一个值。返回Optional<T>
    //练习2:计算公司所有员工年龄的总和
    List<Employee> employees = EmployeeData.getEmployees ();
    Stream<Integer> integerStream = employees.stream ().map (e -> e.getAge ());
    //写法一:
    Optional<Integer> agesum = integerStream.reduce (Integer::sum);
    System.out.println (agesum);
    //写法二:
//    Optional<Integer> agesum2 = integerStream.reduce ((e1, e2) -> e1 + e2);
//    System.out.println (agesum2);


}
③收集
方法含义
collect(Collector c)将流转换为其他形式。接收一个

//3.收集
    @Test
    public  void test5(){
//collect(Collector c)将流转换为其他形式。接收一个Collector接口的实现,用于给Stream中元素做汇总的方法
        //练习1:查找年龄大于25员工,结果返回为一个List
        List<Employee> employees = EmployeeData.getEmployees ();
        List<Employee> list = employees.stream ().filter (e->e.getAge ()>25).collect (Collectors.toList ());
        System.out.println (list);

        //练习1:查找年龄大于18员工,结果返回为一个Set
        Set<Employee> set = employees.stream ().filter (e -> e.getAge () > 18).collect (Collectors.toSet ());
        System.out.println (set);
    }

五、 Optional 类

1.概念:

Optional类(java.util.Optional)是一个容器类、它可以保存类型T的值,代表这个值存在。或者仅仅保存null,表示这个值不存在。
原来用null表示一个值不存在,现在 Optional可以更好的表达这个概念。并且可以避免空指针异常。

Optional类:为了在程序中避免出现空指针异常而创建的。

2.常用方法及举例

①创建Optional类对象的方法
Optional.of(T t)创建一个Optional实例,t必须非空
Optional.empty( )创建一个空的Optional实例
Optional.ofNullable(T t)t可以为null
  @Test
    public void test1(){
        Girl girl=new Girl ();
        //of(T t) :创建一个optional实例,t必须非空;
        Optional<Girl> girlOptional = Optional.of (girl);

    }
  @Test
    public  void test2(){
        Girl girl=new Girl ();
        girl=null;
        //ofNullable(T t): t可以为null
        Optional<Girl> girlOptional = Optional.ofNullable (girl);
        System.out.println (girlOptional);
    }
②判断Optional容器中是否包含对象
boolean isPresent判断是否包含对象
void ifPresent(Consum<? super T> consumer)接口的实现代码,并且该值会作为参数传给它
③获取Optional容器的对象
T get()如果调用对象包含值,返回该值,否则抛异常
T orElse(T other)如果有值则将其返回,否则返回指定的other对象
T orElseGet(Supplier<? extends T> other)如果有值则将其返回,否则返回指定的Supplier接口实现提供的对象
T orElseThrow(Supplier<? extends T> exceptionSupplier)如果有值则将其返回,否则返回,否则抛出Supplier接口实现提供的异常
优化前:使用if防止其为空
    @Test
    public  void test2(){
        Girl girl=new Girl ();
        girl=null;
        //ofNullable(T t): t可以为null
        Optional<Girl> girlOptional = Optional.ofNullable (girl);
        System.out.println (girlOptional);
        Girl girl1 = girlOptional.orElse (new Girl ("霸王花"));
        System.out.println (girl1);
        //orElse(T t1):如果单前的Optional内部封装的t是非空的,则返回内部的t.
        // 如果内部的t是空的,则返回orElse()方法中的参数t1.
    }
    //方式一:getGirlName
    public String getGirlName(Boy boy){
        return  boy.getGirl ().getName ();
    }
    //空指针异常:NullPointerException
    //因为Girl可能是空的,这里只new了boy
    @Test
    public void test3(){
      Boy boy=new Boy ();
//      boy=null;
        String name = getGirlName (boy);
        System.out.println (name);
    }
    //优化以后的getGirlName1()
    public String getGirlName1(Boy boy){
        if(boy!=null){
            Girl girl = boy.getGirl ();
            if(girl!=null){
              return   girl.getName ();
            }
        }
        return  null;
    }
  
优化后:使用Optional类
  @Test
    public void test4(){
        Boy boy=new Boy ();
        boy=null;
        String name1 = getGirlName1 (boy);
        System.out.println (name1);
    }
    //使用Optional类的getGirlName2()
    public String getGirlName2(Boy boy){
        Optional<Boy> optionalBoy = Optional.ofNullable (boy);
        //此时的boy1一定非空
        Boy boy1 = optionalBoy.orElse (new Boy (new Girl ("大器晚成")));
        Girl girl = boy1.getGirl ();
        Optional<Girl> optionalGirl = Optional.ofNullable (girl);
        //此时的girl1一定非空
        Girl girl1 = optionalGirl.orElse (new Girl ("霸王花"));
        String name = girl1.getName ();
        return name;
    }
    @Test
    public void test5(){
         Boy boy=null; //大器晚成
         boy=new Boy ();//霸王花
        String girlName = getGirlName2 (boy);
        System.out.println (girlName);
    }

六、补充:

补充一:

Boy类
package Java8.day1;

public class Boy {
    private  Girl girl;

    public Boy() {
    }

    public Boy(Girl girl) {
        this.girl = girl;
    }

    public Girl getGirl() {
        return girl;
    }

    public void setGirl(Girl girl) {
        this.girl = girl;
    }

    @Override
    public String toString() {
        return "Boy{" + "girl=" + girl + '}';
    }
}

Girl类
package Java8.day1;

import java.util.stream.Stream;

public class Girl {
    private String name;

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

    public Girl() {
    }

    public String getName() {
        return name;
    }

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

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

补充二:

Employee类
package Java8;

public class Employee {
    private String name;
    private  int  age;


    public Employee(int age) {
        System.out.println ("Employee(Integer age)");
    this.age=age;
    }

    public Employee() {
    }

    public Employee(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 String toString() {
        return "Employee{" + "name='" + name + '\'' + ", age=" + age + '}';
    }
}

EmployeeData类
package Java8.day2;

import java.util.ArrayList;
import java.util.List;

public class EmployeeData {
    public static List<Employee> getEmployees(){
        ArrayList<Employee> list=new ArrayList<> ();
        list.add (new Employee ("张三",30));
        list.add (new Employee ("李四",36));
        list.add (new Employee ("王麻子",23));
        return list;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值