Java高级编程——Java8的其它新特性

编程入门 行业动态 更新时间:2024-10-08 18:41:26

Java高级编程——Java8的其它<a href=https://www.elefans.com/category/jswz/34/1767830.html style=新特性"/>

Java高级编程——Java8的其它新特性

Java高级编程——Java8的其它新特性

目录

Java高级编程——Java8的其它新特性

0.Java 8新特性简介

0.1.并行流与串行流 

一、Lambda表达式

1.为什么使用 Lambda 表达式

2.两个例子

3.语法

 4.类型推断

 上代码

二、函数式(Functional)接口

 1.什么是函数式(Functional)接口

 2.如何理解函数式接口

 3.函数式接口举例

 4.自定义函数式接口

 5. 作为参数传递 Lambda 表达式

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

 上代码

总结

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

 1.方法引用(Method References)

 2.方法引用举例

上代码

 3.构造器引用

 4.数组引用

 上代码

四、强大的Stream API

 1.Stream API说明

 2.为什么要使用Stream API

 3.什么是 Stream

 4.Stream 的操作三个步骤

 创建 Stream方式(一)

1.通过集合

2.通过数组

3.通过Stream的of()

4.创建无限流

Stream 的中间操作(二)

1.选与切片

2.映射

3.排序

Stream 的终止操作(三)

1-匹配与查找

2-归约

3-收集

上代码

五、Optional类

1.概述

 上代码


学习的思维方式:
1. "大处着眼,小处着手"

2. 逆向思维、反证法  List<String> list2; List<Object> list1 = list2;

3. 透过问题看本质


两句话:
1. 小不忍则乱大谋

2. 识时务者为俊杰

0.Java 8新特性简介

新特性的优点:

 速度更快

 代码更少(增加了新的语法:Lambda 表达式)

 强大的 Stream API

 便于并行

 最大化减少空指针异常:Optional

 Nashorn引擎,允许在JVM上运行JS应用 

0.1.并行流与串行流 


一、Lambda表达式

1.为什么使用 Lambda 表达式

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

2.两个例子

package com.tyl.java1;import org.junit.Test;import java.util.Comparator;/*** @author tyl 邮箱:tyl202061@gmail* @Package:com.tyl.java1* @Project:workidea* @Filename: LambdaTest* @create 2023-06-26 15:50** Lambda.表达式的使用举例*/
public class LambdaTest {@Testpublic void test2(){Comparator<Integer> com1 = new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return Integerpare(o1,o2);}};int compare1 = com1pare(12, 21);System.out.println(compare1);System.out.println("************************");// Lambda表达式的写法Comparator<Integer> com2 = (o1,o2) -> Integerpare(o1,o2);int compare2 = com2pare(22, 11);System.out.println(compare2);System.out.println("************************");// 方法引用Comparator<Integer> com3 = Integer :: compare;int compare3 = com3pare(22, 11);System.out.println(compare3);}}

3.语法

 4.类型推断

 上代码

package com.tyl.java1;import org.junit.Test;import java.util.ArrayList;
import java.util.Comparator;
import java.util.function.Consumer;/*** @author tyl 邮箱:tyl202061@gmail* @Package:com.tyl.java1* @Project:workidea* @Filename: LambdaTest1* @create 2023-06-26 16:11**Lambda.表达式的使用* 1.举例:*          (o1,o2) -> Integerpare(o1,o2)* 2.格式:* ->:Lambda.操作符或箭头操作符* ->左边:Lambda形参列表(其实就是接口中的抽象方法的形参列表)* ->右边:Lambda体(其实就是重写的抽象方法的方法体)** 3.Lambda表达式的使用: (分为6种情况介绍)* 总结:* ->左边:Lambda形参列表的参数类型可以省略(类型推断);如果Lambda形参列表只有一个参数,其一对()也可以省略。* ->右边:Lambda体应该使用一对{}包裹;如果Lambda体只有一条执行语句(可能是return语句).省略这一对{}和return** 4.Lambda表达式的本质:  作为函数式接口的实例** 5.如果一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口.* 我们可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口。** 6.所以以前用匿名实现类表示的现在都可以用Lambda表达式来写。*/
public class LambdaTest1 {// 语法格式一:无参,无返回值@Testpublic void test1(){Runnable r1 = new Runnable(){@Overridepublic void run() {System.out.println("我爱你!!!");}};r1.run();Runnable r2 = () -> {System.out.println("你爱我");};r2.run();}// 语法格式二:Lambda 需要一个参数,但是没有返回值。@Testpublic void test2(){Consumer<String> con = new Consumer<String>() {@Overridepublic void accept(String s) {System.out.println(s);}};con.accept("谎言和誓言的区别?");System.out.println("***********************************");Consumer<String> con1 = (String s) -> {System.out.println(s);};con1.accept("一个越打一个越爱");}// 语法格式三:数据类型可以省略,因为可由编译器推断得出,称为“类型推断”@Testpublic void test3(){Consumer<String> con1 = (String s) -> {System.out.println(s);};con1.accept("一个越打一个越爱");System.out.println("***********************************");Consumer<String> con2 = (s) -> {System.out.println(s);};con2.accept("一个越打一个越爱");}@Testpublic void test4(){ArrayList<String> list = new ArrayList<>();  //类型推断//        int[] arr = new int[]{1,2,3};int[] arr = {1,2,3};}// 语法格式四:Lambda 若只需要一个参数时,参数的小括号可以省略@Testpublic void test5(){Consumer<String> con3 = (s) -> {System.out.println(s);};con3.accept("一个越打一个越爱");System.out.println("***********************************");Consumer<String> con1 = s -> {System.out.println(s);};con1.accept("一个越打一个越爱");}// 语法格式五:Lambda 需要两个或以上的参数,多条执行语句,并且可以有返回值@Testpublic void test6(){Comparator<Integer> com1 = new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {System.out.println(o1);System.out.println(o2);return o1pareTo(o2);}};System.out.println(com1pare(12, 21));System.out.println("***********************************");Comparator<Integer> com2 = (o1,o2) -> {System.out.println(o1);System.out.println(o2);return o1pareTo(o2);};System.out.println(com2pare(12, 6));}// 语法格式六:当 Lambda 体只有一条语句时,return 与大括号若有,都可以省略@Testpublic void test7(){Comparator<Integer> com2 = (o1,o2) -> {return o1pareTo(o2);};System.out.println(com2pare(12, 6));System.out.println("***********************************");Comparator<Integer> com = (o1,o2) -> o1pareTo(o2);System.out.println(compare(12, 1));}@Testpublic void test8(){Consumer<String> con3 = (s) -> {System.out.println(s);};con3.accept("一个越打一个越爱");System.out.println("***********************************");Consumer<String> con1 = s -> System.out.println(s);con1.accept("12121321313");}}

二、函数式(Functional)接口

1.什么是函数式(Functional)接口

 2.如何理解函数式接口

 3.函数式接口举例

 4.自定义函数式接口

 5. 作为参数传递 Lambda 表达式

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

 上代码

package com.tyl.java1;import org.junit.Test;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;/*** @author tyl 邮箱:tyl202061@gmail* @Package:com.tyl.java1* @Project:workidea* @Filename: LambdaTest2* @create 2023-06-26 17:30** java内置的4大核心函数式接口* 消费型接口Consumer<T>    void accept(T t)* 供给型接口Supplier<T>    T get()* 函数型接口Function<T,R>  R apply(Tt)* 断定型接口Predicate<T>   boolean test(T t)*/
public class LambdaTest2 {@Testpublic void test1(){happyTime(500, new Consumer<Double>() {@Overridepublic void accept(Double aDouble) {System.out.println("学习太累了,休息一下!!!" + aDouble);}});System.out.println("******************************");happyTime(410, money -> System.out.println("学习太累了,休息一下下!!!" + money));}public void happyTime(double money, Consumer<Double> con){con.accept(money);}@Testpublic void test2(){List<String> list = Arrays.asList("天津","吴京","南京","北京","东京");List<String> filterStr = filterString(list, new Predicate<String>() {@Overridepublic boolean test(String s) {return s.contains("京");}});System.out.println(filterStr);System.out.println("******************Lambda表达式*************");List<String> filterStr1 = filterString(list,s -> s.contains("京"));System.out.println(filterStr1);}// 根据给定的规则,过滤集合中的字符串。此规则由Predicate的方法决定public List<String> filterString(List<String> list, Predicate<String> pred){ArrayList<String> filterList = new ArrayList<>();for(String s: list){if(pred.test(s)){filterList.add(s);}}return filterList;}
}

总结

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

1.方法引用(Method References)

 2.方法引用举例

上代码

package com.tyl.java2;import org.junit.Test;import java.io.PrintStream;
import java.util.Comparator;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;/*** 方法引用的使用** 1.使用情境:当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!** 2.方法引用,本质上就是Lambda.表达式,而Lambda.表达式作为函数式接口的实例。所以* 方法引用,也是函数式接口的实例。** 3.使用格式:类(或对象):方法名** 4.具体分为如下的三种情况:* 情况1  对象 :: 非静态方法* 情况2  类 :: 静态方法* 情况3  类 :: 非静态方法** 5.方法引用使用的要求:要求接口中的抽象方法的形参列表和返回值类型与方法引用的方法的*   形参列表和返回值类型相同!(适合第一种和第二种情况)*** Created by shkstart.*/
public class MethodRefTest {// 情况一:对象 :: 实例方法// Consumer中的void accept(T t)// PrintStream中的void println(T t)@Testpublic void test1() {Consumer<String> con1 = str -> System.out.println(str);con1.accept("西安");System.out.println("********************************");PrintStream ps = System.out;Consumer<String> con2 = ps::println;con2.accept("xian");}// Supplier中的T get()// Employee中的String getName()@Testpublic void test2() {Employee tyl = new Employee(2001, "tyl", 23, 55555);Supplier<String> sup1 = () -> tyl.getName();System.out.println(sup1.get());System.out.println("********************************");Supplier<String> sup2 = tyl ::getName;System.out.println(sup2.get());}// 情况二:类 :: 静态方法// Comparator中的int compare(T t1,T t2)// Integer中的int compare(T t1,T t2)@Testpublic void test3() {Comparator<Integer> com1 = (t1,t2) -> Integerpare(t1,t2);int compare1 = com1pare(88, 55);if(compare1 == -1){System.out.println("前面的数小,后面的数大");}else {System.out.println("前面的数大,后面的数小");}System.out.println("********************************");Comparator<Integer> com2 = Integer::compare;System.out.println(com2pare(12, 33));}// Function中的R apply(T t)// Math中的Long round(Double d)@Testpublic void test4() {Function<Double,Long> func = new Function<Double, Long>() {@Overridepublic Long apply(Double d) {return Math.round(d);}};System.out.println("********************************");Function<Double,Long> func2 = d -> Math.round(d);System.out.println(func2.apply(12.3));System.out.println("********************************");Function<Double,Long> func3 = Math::round;System.out.println(func3.apply(15.3));}// 情况三:类 :: 实例方法 (有难度)// Comparator中的int comapre(T t1,T t2)// String中的int t1pareTo(t2)@Testpublic void test5() {Comparator<String> com1 = (s1,s2) -> s1pareTo(s2);System.out.println(com1pare("abc", "abd"));System.out.println("********************************");Comparator<String> com2 = String::compareTo;System.out.println(com2pare("acc", "aaa"));}// BiPredicate中的boolean test(T t1, T t2);// String中的boolean t1.equals(t2)@Testpublic void test6() {BiPredicate<String,String> pre1 = (t1,t2) -> t1.equals(t2);System.out.println(pre1.test("aaa", "aaa"));System.out.println("********************************");BiPredicate<String,String> pre2 = String::equals;System.out.println(pre2.test("aaa", "ccc"));}// Function中的R apply(T t)// Employee中的String getName();@Testpublic void test7() {Employee tyl = new Employee(2001, "tyl", 23, 55555);Function<Employee,String> func1 = e -> e.getName();System.out.println(func1.apply(tyl));System.out.println("********************************");Function<Employee,String> func2 = Employee::getName;System.out.println(func2.apply(tyl));}}

 3.构造器引用

 4.数组引用

 上代码

package com.tyl.java2;import org.junit.Test;import java.util.Arrays;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;/*** 一、构造器引用*     和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致。*     抽象方法的返回值类型即为构造器所属的类的类型** 二、数组引用*     大家可以把数组看做是一个特殊的类,则写法与构造器引用一致。*** Created by shkstart*/
public class ConstructorRefTest {//构造器引用// Supplier中的T get()// EmpLoyee的空参构造器:EmpLoyee()@Testpublic void test1(){Supplier<Employee> sup = new Supplier<Employee>() {@Overridepublic Employee get() {return new Employee();}};System.out.println("********************************");Supplier<Employee> sup1 = () -> new Employee();System.out.println(sup1.get());System.out.println("********************************");Supplier<Employee> sup2 = Employee::new;System.out.println(sup2.get());}// Function中的R apply(T t)@Testpublic void test2(){Function<Integer,Employee> func1 = id -> new Employee(id);Employee employee = func1.apply(1001);System.out.println(employee);System.out.println("********************************");Function<Integer,Employee> func2 = Employee::new;Employee employee1 = func2.apply(1002);System.out.println(employee1);}// BiFunction中的R apply(T t,U u)@Testpublic void test3(){BiFunction<Integer,String,Employee> func1 = (id,name) -> new Employee(id,name);System.out.println(func1.apply(1001, "tyl"));System.out.println("********************************");BiFunction<Integer,String,Employee> func2 = Employee::new;System.out.println(func2.apply(1002, "tyl"));}//数组引用//Function中的R apply(T t)@Testpublic void test4(){Function<Integer,String[]> func1 = Length -> new String[Length];String[] arr1 = func1.apply(5);System.out.println(Arrays.toString(arr1));System.out.println("********************************");Function<Integer,String[]> func2 = String[]::new;String[] arr2 = func2.apply(10);System.out.println(Arrays.toString(arr2));}
}

四、强大的Stream API

1.Stream API说明

 2.为什么要使用Stream API

 3.什么是 Stream

 4.Stream 的操作三个步骤

 创建 Stream方式(一)

1.通过集合

2.通过数组

3.通过Stream的of()

4.创建无限流

Stream 的中间操作(二)

 1.选与切片

2.映射

3.排序

Stream 的终止操作(三)

1-匹配与查找

2-归约

3-收集

Collector需要使用Collectors(如下)提供实例。

上代码

package com.tyl.java3;import com.tyl.java2.Employee;
import com.tyl.java2.EmployeeData;
import org.junit.Test;import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;/*** @author tyl 邮箱:tyl202061@gmail* @Package:com.tyl.java3* @Project:workidea* @Filename: StreamAPITest* @create 2023-06-27 15:11** 1.Stream关注的是对数据的运算,与CPU打交道* 集合关注的是数据的存储,与内存打交道** 2.①Stream 自己不会存储元素。*  ②Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。*  ③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。** 3.Stream执行流程* ① Stream的实例化* ② 一系列的中间操作(过滤、映射、··)* ③ 终止操作** 4.说明:* 4.1一个中间操作链,对数据源的数据进行处理* 4.2一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用*/
public class StreamAPITest {// 创建 Stream方式一:通过集合@Testpublic void test1(){List<Employee> employees = EmployeeData.getEmployees();//         default Stream<E> stream() : 返回一个顺序流Stream<Employee> stream = employees.stream();//         default Stream<E> parallelStream() : 返回一个并行流Stream<Employee> parallelStream = employees.parallelStream();}//    创建 Stream方式二:通过数组@Testpublic void test2(){int[] arr = {1, 2, 3, 4, 5, 6};// /用Arrays类static<T> Stream<T> stream(T[] array):返回一个流IntStream stream = Arrays.stream(arr);Employee e1 = new Employee(1001, "tyl");Employee e2 = new Employee(1002, "wc");Employee[] arr1 = new Employee[]{e1, e2};Stream<Employee> stream1 = Arrays.stream(arr1);}// 创建 Stream方式三:通过Stream的of()@Testpublic void test3(){Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);}// 创建 Stream方式四:创建无限流@Testpublic void test4(){
//         迭代
//        public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)Stream.iterate(0,t -> t+2).limit(10).forEach(System.out::println);//         生成
//        public static<T> Stream<T> generate(Supplier<T> s)Stream.generate(Math::random).limit(10).forEach(System.out::println);}}
package com.tyl.java3;import com.tyl.java2.Employee;
import com.tyl.java2.EmployeeData;
import org.junit.Test;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;/*** @author tyl 邮箱:tyl202061@gmail* @Package:com.tyl.java3* @Project:workidea* @Filename: StreamAPITest1* @create 2023-06-27 16:42** 测试Stream的中间操作*/
public class StreamAPITest1 {// 1-筛选与切片@Testpublic void test1(){List<Employee> list = EmployeeData.getEmployees();
//        filter(Predicate p)一接收Lambda,从流中排除某些元素。Stream<Employee> stream = list.stream();// 练习:查询员工表中薪资大于79阳阳的员工信息stream.filter(e -> e.getSalary() > 7000).forEach(System.out::println);System.out.println("************************");//        limit(n)一截断流,使其元素不超过给定数量.list.stream().limit(4).forEach(System.out::println);System.out.println("************************");
//        skip(n)一跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空的list.stream().skip(4).forEach(System.out::println);System.out.println("************************");
//        distinct()一筛选,通过流所生成元素的hashCode()和equals()去除重复元素list.add(new Employee(1010, "刘强东",40,8000));list.add(new Employee(1010, "刘强东",40,8000));list.add(new Employee(1010, "刘强东",40,8000));list.add(new Employee(1010, "刘强东",40,8000));//        System.out.println(list);list.stream().distinct().forEach(System.out::println);}// 2-映射@Testpublic void test2(){// map(Function f)--接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd");list.stream().map(str -> str.toUpperCase()).forEach(System.out::println);// 练习:获取员工姓名长度大于3的员工的姓名。List<Employee> employees = EmployeeData.getEmployees();Stream<String> namesStream = employees.stream().map(Employee::getName);namesStream.filter(name -> name.length() > 3).forEach(System.out::println);System.out.println();// 练习2Stream<Stream<Character>> streamStream = list.stream().map(StreamAPITest1::fromStringToStream);streamStream.forEach(s ->{s.forEach(System.out::println);});System.out.println();// fLatMap(Function f)--接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流Stream<Character> characterStream = list.stream().flatMap(StreamAPITest1::fromStringToStream);characterStream.forEach(System.out::println);}public static Stream<Character> fromStringToStream(String str){ArrayList<Character> list = new ArrayList<>();for(Character c : str.toCharArray()){list.add(c);}return list.stream();}// 3-排序@Testpublic void test3(){// sorted() 产生一个新流,其中按自然顺序排序List<Integer> list = Arrays.asList(12, 545, 545, 54564, 56461, 11111);list.stream().sorted().forEach(System.out::println);// 抛异常,原因:EmpLoyee没有实现ComparabLe接口
//        List<Employee> employees = EmployeeData.getEmployees();
//        employees.stream().sorted().forEach(System.out::println);//sorted(Comparator com) 产生一个新流,其中按比较器顺序排序List<Employee> employees = EmployeeData.getEmployees();employees.stream().sorted((e1,e2) -> {int agevAalue = Integerpare(e1.getAge(), e2.getAge());if(agevAalue != 0){return agevAalue;}else {return Doublepare(e1.getSalary(),e2.getSalary());}}).forEach(System.out::println);}}
package com.tyl.java3;import com.tyl.java2.Employee;
import com.tyl.java2.EmployeeData;
import org.junit.Test;import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;/*** @author tyl 邮箱:tyl202061@gmail* @Package:com.tyl.java3* @Project:workidea* @Filename: StreamAPITest2* @create 2023-06-27 18:03* <p>* 测stream的终止操作*/
public class StreamAPITest2 {// 1-匹配与查找@Testpublic void test1() {List<Employee> employees = EmployeeData.getEmployees();//    allMatch(Predicate p) 检查是否匹配所有元素//  练习:是否所有的员工的年龄都大于18boolean allMatch = employees.stream().allMatch(e -> e.getAge() > 18);System.out.println(allMatch);//    anyMatch(Predicate p) 检查是否至少匹配一个元素
//        练习:是否存在员工的工资大于19000boolean anyMatch = employees.stream().anyMatch(e -> e.getSalary() > 19000);System.out.println(anyMatch);//    noneMatch(Predicate p) 检查是否没有匹配所有元素// 练习:是否存在员工姓“雷"boolean noneMatch = employees.stream().noneMatch(e -> e.getName().startsWith("雷"));System.out.println(noneMatch);//    findFirst() 返回第一个元素Optional<Employee> optionalEmployee = employees.stream().findFirst();System.out.println(optionalEmployee);
//    findAny() 返回当前流中的任意元素Optional<Employee> optionalEmployee1 = employees.stream().findAny();System.out.println(optionalEmployee1);Optional<Employee> optionalEmployee2 = employees.parallelStream().findAny();System.out.println(optionalEmployee2);}@Testpublic void test2() {List<Employee> employees = EmployeeData.getEmployees();
//        count() 返回流中元素总数long count = employees.stream().filter(e -> e.getSalary() > 5000).count();System.out.println(count);//        max(Comparator c) 返回流中最大值// 练习:返回最高的工资:Stream<Double> doubleStream = employees.stream().map(e -> e.getSalary());Optional<Double> max = doubleStream.max(Double::compare);System.out.println(max);//        min(Comparator c) 返回流中最小值// 练习:返回最低工资的员工Optional<Employee> min = employees.stream().min((e1, e2) -> Doublepare(e1.getSalary(), e2.getSalary()));System.out.println(min);System.out.println();
//        forEach(Consumer c)   内部迭代employees.stream().forEach(System.out::println);// 使用集合的遍历操作employees.forEach(System.out::println);}// 2-归约@Testpublic void test3() {
//        reduce(T iden, BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。返回 T
//        练习1:计算1-10的自然数的和List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);Integer sum = list.stream().reduce(0, Integer::sum);System.out.println(sum);//        reduce(BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。返回 Optional<T>// 练习2:计算公司所有员工工资的总和List<Employee> employees = EmployeeData.getEmployees();Stream<Double> salaryStream = employees.stream().map(Employee::getSalary);
//        Optional<Double> sumMoney = salaryStream.reduce(Double::sum);Optional<Double> sumMoney = salaryStream.reduce((d1,d2) -> d1 + d2);System.out.println(sumMoney);}// 3-收集@Testpublic void test4() {// collect(Collector c)-将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法// 练习1:查拔工资大于6880的员工,结果返回为一个List和setList<Employee> employees = EmployeeData.getEmployees();List<Employee> employeeList = employees.stream().filter(e -> e.getSalary() > 6000).collect(Collectors.toList());employeeList.forEach(System.out::println);System.out.println();Set<Employee> employeeSet = employees.stream().filter(e -> e.getSalary() > 6000).collect(Collectors.toSet());employeeSet.forEach(System.out::println);}}

五、Optional类

1.概述

 上代码

package com.tyl.java4;import org.junit.Test;import java.util.Optional;/*** @author tyl 邮箱:tyl202061@gmail* @Package:com.tyl.java4* @Project:workidea* @Filename: OptionalTest* @create 2023-06-27 21:27** Optional类:为了在程序中避免出现空指针异常而创建的。** 常用的方法:ofNullable(T t)*            orELse(T t)*/
public class OptionalTest {/* 创建Optional类对象的方法: Optional.of(T t) : 创建一个 Optional 实例,t必须非空; Optional.empty() : 创建一个空的 Optional 实例 Optional.ofNullable(T t):t可以为null*/@Testpublic void test1(){Gril gril = new Gril();
//        gril = null;// of(T t):保证t是非空的Optional<Gril> optionalGril = Optional.of(gril);}@Testpublic void test2(){Gril gril = new Gril();gril = null;// ofNuLLable(T t):t可以为nuLLOptional<Gril> optionalGril = Optional.ofNullable(gril);System.out.println(optionalGril);//orELse(T t1):如果单前的optional内部封装的t是非空的,则返回内部的t,//如果内部的t是空的,则返回orELse()方法中的参数t1.Gril gril1 = optionalGril.orElse(new Gril("wc"));System.out.println(gril1);}//使用optional.类的getGirLName():public String getGrilName2(Boy boy){Optional<Boy> boyOptional = Optional.ofNullable(boy);// 此时的boy1一定非空Boy boy1 = boyOptional.orElse(new Boy(new Gril("tyl")));Gril gril = boy1.getGril();// girL1一定非空Optional<Gril> grilOptional = Optional.ofNullable(gril);Gril gril1 = grilOptional.orElse(new Gril("wccc"));return gril1.getName();}@Testpublic void test3(){Boy boy = null;boy = new Boy();boy = new Boy(new Gril("chuanglaoshi"));String grilName = getGrilName2(boy);System.out.println(grilName);}}
package com.tyl.java;import org.junit.Test;import java.util.Optional;/*** @author tyl 邮箱:tyl202061@gmail* @Package:com.tyl.java* @Project:workidea* @Filename: OptionalTest* @create 2023-06-28 13:52*/
public class OptionalTest {@Testpublic void test1() {// empty():创建的optional对象内部value = nullOptional<Object> op1 = Optional.empty();if (!op1.isPresent()) { // Optional封装的数据是否包含数据System.out.println("数据为空");}System.out.println(op1);System.out.println(op1.isPresent());// 如果Optional.封装的数据value为空,则get()报错。否则,value.不为空时,返回value
//        System.out.println(op1.get());}@Testpublic void test2() {String str = "wc是个小仙女";
//        str = null;// of(T t):封装数据t生成optional对象。要求t非空,否则报错Optional<String> op1 = Optional.of(str);// get()通常与of()方法搭配使用。用于获取内部的封装的数据valueSystem.out.println(op1.get());}@Testpublic void test3() {String str = "beijing";str = null;// ofNulLable(T t):封装数据t赋给Optional内部的value。不要求t非空Optional<String> str1 = Optional.ofNullable(str);// orELse(Tt1):如果optional内部value.非空,则返回此value值。如果value为空,则返回t1.System.out.println(str1.orElse("sahnghai"));}}

基础接近尾声,继续加油!!!

更多推荐

Java高级编程——Java8的其它新特性

本文发布于:2024-02-27 19:59:59,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1766125.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:新特性   高级编程   Java

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!