当前位置: 首页 > ai >正文

java8新特性

文章目录

  • 1.Lambda
  • 2.函数式接口
  • 3.方法应用和构造器引用
  • 4.StreamAPI
  • 5.Optional类

1.Lambda

  • 匿名函数,Lambad表达式可以理解为一段可以传递的代码(将代码像数据一样传递)
  • 格式:
    • -> : lambda操作符
    • -> 左边: 形参列表(其实就是接口中的抽象方法的形参列表)
    • ->右边: lambda体(其实就是重写的抽象方法的方法体)
  • 使用:(六种情况)
    • 1.无参无返回值
    • 2.lambda需要一个参数,但是没有返回值
    • 3.数据类型可以省略,因为可由编辑器推断得出,称为"类型推断"
    • 4.只需要一个参数时,参数的小括号可以省略
    • 5.需要两个或以上的参数,多条执行语句,并且可以有返回值
    • 6.lambda只有1条语句时,return和{}都可以省略
    • 总结:
      • 左边:形参列表的参数类型可以省略(类型推断);如果只有一个参数,()也可以省略
      • 右边:lambda {}在只有一条语句时(可能是return语句)可以省略,return关键字也要省略
  • 本质:作为函数式接口的一个实例(一定是借助接口存在)
    • 接口是只能有一个抽象方法
    • 以前用匿名实现类表示的现在都可以用Lambda表达式来写
- 引入
package Lambda;import org.junit.Test;import java.util.Comparator;public class LambdaTest {
@Testpublic void test1() {Runnable r1= new Runnable() {@Overridepublic void run() {System.out.println("我爱北京天安门");}};r1.run();//---------------------------------------------Runnable r2= ()-> System.out.println("我爱北京天安门");r2.run();}@Testpublic void test2() {Comparator<Integer> com1 = new Comparator<Integer>() {@Overridepublic int compare(Integer s1, Integer s2) {return Integer.compare(s1,s2);}};int res1=com1.compare(12,18);System.out.println(res1);System.out.println("**************");//Comparator接口中只有比较的这个方法,所以这些步骤可以是省略Comparator<Integer> com2 =  (s1, s2) -> Integer.compare(s1,s2);int res2=com2.compare(1282,181);System.out.println(res2);System.out.println("**************");//更简洁写法:方法引用Comparator<Integer> com3 = Integer::compare;int res3=com2.compare(1282,181);System.out.println(res3);}
}-----------------------------------------------------------------------------------------------------
package Lambda;import org.junit.Test;import java.util.Comparator;
import java.util.function.Consumer;public class LambdaTest {@Test//1.无参无返回值public void test1() {Runnable r1 = new Runnable() {@Overridepublic void run() {//看方法System.out.println("我爱北京天安门");}};r1.run();//---------------------------------------------System.out.println("------------------");Runnable r2 = () -> {System.out.println("我爱北京天安门");};r2.run();}//2.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("哈哈哈哈");}//3.数据类型可以省略,因为可由编辑器推断得出,称为"类型推断"//在列表创建中可以知道@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("哈哈哈哈");}//4.只需要一个参数时,参数的小括号可以省略@Testpublic void test4() {Consumer<String> con1 = (s) -> {//类型推断,可以省略System.out.println(s);};con1.accept("哈哈哈哈");System.out.println("-----------------------------");Consumer<String> con3 = s -> {//少了小括号System.out.println(s);};con3.accept("哈哈哈哈");}//5.需要两个或以上的参数,多条执行语句,并且可以有返回值@Testpublic void test5() {Comparator<Integer> com1 = new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {System.out.println(o1);System.out.println(o2);return o1.compareTo(o2);}};System.out.println(com1.compare(1,3));System.out.println("-----------------------------");Comparator<Integer> com2= (o1,o2) ->{System.out.println(o1);System.out.println(o2);return o1.compareTo(o2);};System.out.println(com2.compare(12,3));}//6.lambda只有1条语句时,return和{}都可以省略@Testpublic void test6() {Comparator<Integer> com1= (o1,o2) ->{return o1.compareTo(o2);};System.out.println(com1.compare(12,3));System.out.println("-----------------------------");Comparator<Integer> com2= (o1,o2) ->o1.compareTo(o2);System.out.println(com2.compare(12,3));}@Testpublic void test7() {Consumer<String> con1 = (s) -> {//类型推断,可以省略System.out.println(s);};con1.accept("哈哈哈哈");System.out.println("-----------------------------");Consumer<String> con3 = s ->  System.out.println(s);con3.accept("哈哈哈哈");}
}

2.函数式接口

  • 如果一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口
  • 在接口上使用@FunctionalInterface注解,这样做可以检查它是否是一个函数式接口,同时javadoc也会包含一条声明,说明这个接口是一个函数式接口
  • 何时使用函数式接口
    • 如果我们开发中需要定义一个函数式接口,首先看看在已有的jdk提供的函数式接口是否提供了能满足需求的函数式接口 ,如果有直接调用,不需要自己定义了
  • 在这里插入图片描述- 自定义函数式接口
package Lambda;@FunctionalInterface
public interface MyInterface {void method1();
}
  • java内置四大核心函数式接口
函数式接口参数类型返回类型用途
Consumer 消费型接口Tvoid对对象为T的对象应用操作, 包含方法 : void accept(T t)
Supplier供给型接口T返回类型为T的对象,包含方法: T get()
Function<T,R> 函数型TR对对象为T的对象应用操作,并返回结果.结果是R类型的对象,包含方法: R apply(T t)
Predicate 断定型Tbollean确定对象是否满足约束,并返回boolean值.包含方法:boolean test(T t)
package Lambda;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;/**java 内置4大核心函数式接口* 1.消费型接口 Consumer<T>  void accept(T t)* 2.供给型接口 Supplier<T>  T get()* 3.函数型接口 Function<T,R> R apply(T t)* 4.断言型接口 Predicate<T> boolean test(T t)*/
public class LambdaFunctionTest {@Testpublic void test1(){happyTime(100,new Consumer<Double>(){@Overridepublic void accept(Double aDouble) {System.out.println("消费"+aDouble);}});System.out.println("*******************************");happyTime(100,money -> System.out.println("消费"+money));}public void happyTime(double money, Consumer<Double> con){con.accept(money);}@Testpublic void test2(){List<String> list = Arrays.asList("aaa","bb","ccc","ddd");List<String> filterString =filterString(list, new Predicate<String>() {@Overridepublic boolean test(String s) {return s.length() > 2;}});System.out.println(filterString);System.out.println("*******************************");List<String> filterString2 =filterString(list,s -> s.length() <3);System.out.println(filterString2);}//根据给定的规则,过滤结合汇总的字符串,此规则由Predicate的方法决定public List<String> filterString(List<String> list, Predicate<String> pre){//集合根据某种规则来做一个过滤ArrayList<String> filterList= new ArrayList<>();for(String s:list){if(pre.test(s)){filterList.add(s);}}return filterList;}
}
  • 在这里插入图片描述

3.方法应用和构造器引用

  • 使用情景:当要传递个Lambda体的操作,已经有实现的方法了,可以使用方法引用
  • 可以看做Lambda表达式的深层次的表达
  • 本质上就是Lambda表达式,而Lambda表达式作为函数式接口的实例,所以方法引用也是函数表达式的接口
  • 使用: ==类/对象 : : 调用的方法名 ==
  • 分三种情况:
    • 对象 : : 非静态方法
    • 类 : : 非静态方法
    • 类 : : 静态方法
  • 要求:
    • 要求接口中的抽象方法的形参列表和返回值类型 与方法引用的方法的形参列表和返回值类型相同(情况1,2)
    • 当函数式接口方法的第一个参数是需要引用方法的调用者,并且第二个参数是需要引用地方免费参数(或无参数)时:ClassName::methodName(情况3)
方法引用
package MethodTest;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;public class MethodTest {//1.对象 :: 实例方法//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("呵呵");}//Supplier 中的 T get()//Employee 中的String getName()@Testpublic void test2(){//什么也不放,但是返回值Employee emp = new Employee(1,"QQ",23,000);Supplier<String> sup1 = () -> emp.getName();//对象//非静态方法用对象去调用System.out.println(sup1.get());System.out.println("--------------------------------");Supplier<String> sup2 = emp::getName;System.out.println(sup2.get());//本身这个方法有一个抽象方法已经实现,而且参数列表返回类型一样}//2.类 :: 静态方法//Comparator 中的int compare(T t1,T t2)//Integar 中的int compare(T t1,T t2)@Testpublic void test3(){Comparator<Integer> com1= (t1, t2) -> Integer.compare(t1,t2);System.out.println(com1.compare(12,21));System.out.println("--------------------------------");Comparator<Integer> com2 = Integer::compare;//不用写括号方原因是因为,参数与形参列表的参数一样System.out.println(com2.compare(12,21));}//Function 中的 R apply(T t)//Math 中的Long  round(double d)@Testpublic void test4(){Function<Double ,Long> funn2 = new Function<Double, Long>() {@Overridepublic Long apply(Double d) {return Math.round(d);}};Function<Double,Long> func1 = d-> Math.round(d);System.out.println(func1.apply(12.3));System.out.println("--------------------------------");Function<Double,Long> func2 = Math::round;System.out.println(func2.apply(12.3));}//3.类 :: 实例方法 (难)//Comparator 中的int compare(T t1,T t2)//String 中的int t1.compareTo(t2) //变为调用者@Testpublic void test5(){Comparator<String> com1 = (s1,s2) -> s1.compareTo(s2);System.out.println(com1.compare("abc","abd"));System.out.println("--------------------------------");Comparator<String> com2 = String::compareTo;System.out.println(com2.compare("abc","abm"));}//BiPrecdicate 中的boolean test(T t1,T t2)//String 中的boolean t1.equals(t2)@Testpublic void test6(){BiPredicate<String,String> bp1 = (s1, s2) -> s1.equals(s2);System.out.println(bp1.test("abc","abc"));System.out.println("--------------------------------");BiPredicate<String,String> bp2 = String::equals;System.out.println(bp2.test("abc","abc"));}//Function 中的R apply(T t)//Employee 中的String getName()@Testpublic void test7(){Employee employee = new Employee(1001,"hh",12,120.1);Function<Employee,String> fun1 = (e) -> e.getName();System.out.println(fun1.apply(employee));System.out.println("--------------------------------");Function<Employee,String> fun2 = Employee::getName;System.out.println(fun2.apply(employee));}
}
构造器引用
package MethodTest;import org.junit.Test;import java.util.Arrays;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;/*** 1.构造器引用*      和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一样*      抽象方法的返回值类型即为构造器所属的类的类型* 2.数组引用*      可以把数组看做应该特殊的类,则写法与构造器引用一样**/
public class ConstructtoRefTest {//构造器引用 类名::new//Supplier 中的T get()//无参有返回值//Employee的空参构造器 :Employee()//抽象方法有一个返回值T,T就是要创建的类型的对象@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> fun1 = id -> new Employee(id);Employee employee = fun1.apply(1001);System.out.println(employee);System.out.println("*************************");Function<Integer, Employee> fun2 = Employee::new;Employee employee1 = fun2.apply(1002);System.out.println(employee1);}//BiFunction 中的R apply(T t,U u)@Testpublic void test3() {BiFunction<Integer, String, Employee> fun1 = (id, name) -> new Employee(id, name);System.out.println(fun1.apply(1001, "Tom"));System.out.println("*************************");BiFunction<Integer, String, Employee> fun2 = Employee::new;}//2.数组引用 数组类型[] :: new@Testpublic void test4() {//长度Function<Integer, String[]> fun1 = length -> new String[length];String[] arr1 = fun1.apply(10);System.out.println(Arrays.toString(arr1));System.out.println("*************************");Function<Integer, String[]> fun2 = String[]::new;String[] arr2 = fun2.apply(20);System.out.println(Arrays.toString(arr2));}
}

4.StreamAPI

在这里插入图片描述

  • Stream与Collection集合的区别:Collection是一种静态的内存数据机构,面向内存,存储在内存中;Stream是有关于计算,面向CPU,通过CPU实现计算.
  • 注意:
    • Stream不会自己存储元素

    • 不会改变源对象,会返回一个持有结果的新Stream

    • 操作是延迟执行的,意味着他们会等到需要结果的时候才执行

    • 步骤:

    • 1.创建Stream

      • 一个数据源(如:集合,数组),获取一个流
    • 2.中间操作

      • 一个中间操作(过滤,映射等)链,对数据源的数据进行处理
      • 在这里插入图片描述
      • 在这里插入图片描述
      • 在这里插入图片描述
    • 3.终止操作

      • 一旦执行终止操作,就执行中间操作链,并产生结果,之后就不会再被使用
      • 在这里插入图片描述
      • 在这里插入图片描述
      • 在这里插入图片描述
      • 在这里插入图片描述
package StreamAPI;
//1.对数据的运算,与CPU
//集合对数据的存储,与内存import MethodTest.Employee;
import MethodTest.EmployeeData;
import org.junit.Test;import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;/****/
public class StreamTest {//创建方式:
//    1.通过集合//default Stream<E> stream() :返回一个顺序流//default Stream<E> parallelStream() :返回一个并行流@Testpublic void test1(){List<Employee> employees = EmployeeData.getEmployees();//返回一个顺序流Stream<Employee> stream = employees.stream();//返回一个并行流Stream<Employee> parallelStream = employees.parallelStream();}
//    2.通过数组//调用Arrays类中的static <T> Stream<T> stream(T[] array):返回一个流//通过泛型来识别类型@Testpublic void test2(){int[] arr = new int[]{1,2,3,4,5,6};IntStream stream =Arrays.stream(arr);Employee e1= new Employee(1001,"Tom",23,5600);Employee e2= new Employee(1002,"Jerry",34,6600);Employee[] arr1 = new Employee[]{e1,e2};//静态初始化Stream<Employee> stream1 = Arrays.stream(arr1);}//    3.通过Stream的of()@Testpublic void test3(){Stream<String> stream = Stream.of("aa", "bb", "cc", "dd");//包装类对象}//    4.创建无限流(不常用)//4.1 迭代//public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)//4.2 生成//public static<T> Stream<T> generate(Supplier<T> s)@Testpublic void test4(){//迭代//遍历前10个偶数Stream.iterate(0,t-> t+2).limit(10).forEach(System.out::println);//生成Stream.generate(Math::random).limit(10).forEach(System.out::println);}
}
---------------------------------------------------------------------------------------------------------------------------------------------
package StreamAPI;import MethodTest.Employee;
import MethodTest.EmployeeData;
import org.junit.Test;import java.util.List;
import java.util.stream.Stream;/*** 测试Stream的中间操作*/
public class StreamTest1 {//1.筛选与切片/*** filter(Predicate p)——接收Lambda,从流中排除某些元素* limit(long maxSize)——截断流,使其元素不超过给定数量* skip(long n)——跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与limit(n)互补* distinct()——筛选,通过流所生成元素的hashCode()和equals()去除重复元素*/
//    1.1filter@Testpublic void test1(){List<Employee> list = EmployeeData.getEmployees();Stream<Employee> stream= list.stream();//查询员工表>1000stream.filter(e->e.getSalary()>1000).forEach(System.out::println);//一旦执行终止操作,stream流就会关闭,不可以再次使用
//     1.2limit()System.out.println("limit()----------------");//重新调用list.stream().limit(3).forEach(System.out::println);
//     1.3skip()//跳过前面的数据System.out.println("skip()----------------");list.stream().skip(3).forEach(System.out::println);
//     1.4distinct()//去 重System.out.println("distinct()----------------");list.add(new Employee(1010,"张三",23,9999.99));list.add(new Employee(1010,"张三",23,9999.99));list.add(new Employee(1010,"张三",23,9999.99));list.add(new Employee(1010,"张三",23,9999.99));list.add(new Employee(1010,"张三",23,9999.99));list.stream().distinct().forEach(System.out::println);}}
---------------------------------------------------------------------------------------------------------------------------------------------
package StreamAPI;
//2.映射import MethodTest.Employee;
import MethodTest.EmployeeData;
import org.junit.Test;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;/*** map(Function f) 接收一个函数作为参数,将元素转换成其他形式或提取信息,该函数,会被应用到每个元素上,并将其映射成一个新的元素* flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流*/
public class StreamTest2 {//map(Function f) 接收一个函数作为参数,将元素转换成其他形式或提取信息,该函数,会被应用到每个元素上,并将其映射成一个新的元素//类似于add@Testpublic void test1(){List<String> list= Arrays.asList("aaa","bbb","ccc");list.stream().map(str->str.toUpperCase()).forEach(System.out::println);System.out.println("----------------");List<Employee> employees= EmployeeData.getEmployees();//练习1.获取员工姓名长度 的员工姓名Stream<String> nameStream=employees.stream().map(Employee::getName);nameStream.filter(name ->name.length()>3).forEach(System.out::println);System.out.println("----------------");//练习2Stream<Stream<Character>> streamStream=list.stream().map(StreamTest2::fromStringToStream);streamStream.forEach(s->s.forEach(System.out::println));System.out.println("----------------");//flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流//类似于addALlStream<Character> characterStream = list.stream().flatMap(StreamTest2::fromStringToStream);characterStream.forEach(System.out::println);}@Testpublic void test2(){}@Testpublic void test3(){ArrayList  list1=new ArrayList();list1.add(1);list1.add(2);ArrayList list2=new ArrayList();list2.add(3);list2.add(4);//        list1.add(list2);list1.addAll(list2);System.out.println(list1);}//将字符串中的多个字符构成的集合转换为响应的Stream的实例public static Stream<Character> fromStringToStream(String str){ArrayList<Character> list = new ArrayList<>();for (Character c : str.toCharArray()) {list.add(c);}return list.stream();}}
--------------------------------------------------------------------------------------------------------------------------------------------
package StreamAPI;import MethodTest.Employee;
import MethodTest.EmployeeData;
import org.junit.Test;import java.util.Arrays;
import java.util.List;//3.排序/*** sorted() 自然排序* sorted(Comparator com) 定制排序*/
public class StreamTest3 {@Testpublic void test1(){//sortedList<String> list = Arrays.asList("ccc","aaa","bbb","ddd","eee");list.stream().sorted().forEach(System.out::println);
//抛异常,原因:Employee没有实现Comparable接口
//        List<Employee> employees = EmployeeData.getEmployees();
//        employees.stream().sorted().forEach(System.out::println);
//List<Employee> employees = EmployeeData.getEmployees();
//        employees.stream().sorted((e1,e2) ->{
//                return Integer.compare(e1.getAge(),e2.getAge());
//        }).forEach(System.out::println);employees.stream().sorted((e1,e2) ->Integer.compare(e1.getAge(),e2.getAge())).forEach(System.out::println);System.out.println("--------------------------");//年龄一样,按照薪水来比较employees.stream().sorted((e1,e2) -> {int result = Integer.compare(e1.getAge(), e2.getAge());if (result != 0) {return result;} else {return Double.compare(e1.getSalary(), e2.getSalary());}}).forEach(System.out::println);}
}
--------------------------------------------------------------------------------------------------------------------------------------------
package StreamAPI;import MethodTest.Employee;
import MethodTest.EmployeeData;
import org.junit.Test;import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
//1.匹配与查找
//1.1 allMatch(Predicate p)——检查是否匹配所有元素
//练习:是否所有员工的年龄都大于18\
//1.2 anyMatch(Predicate p)——检查是否至少匹配一个元素
//练习:是否存在员工的工资大于10000
//1.3 noneMatch(Predicate p)——检查是否没有匹配的元素
//练习:是否不存在员工姓王
//1.4 findFirst()——返回第一个元素
//1.5 findAny()——返回当前流中的任意元素
//1.6 count()——返回流中元素的总个数
//1.7 max(Comparator c)——返回流中最大值
//        练习:返回最高的工资
//1.8 min(Comparator c)——返回流中最小值
//练习:返回最低的工资
//1.9 foreach(Consumer c)——内部迭代public class StreamEndTest1 {@Testpublic void test1(){List<Employee> employees = EmployeeData.getEmployees();//1.1allMatch(Predicate p)——检查是否匹配所有元素//练习:是否所有员工的年龄都大于18boolean allMatch = employees.stream().allMatch(e->e.getAge()>18);System.out.println(allMatch);//1.2anyMatch(Predicate p)——检查是否至少匹配一个元素//练习:是否存在员工的工资大于10000boolean anyMatch = employees.stream().anyMatch(e->e.getSalary()>1000 );System.out.println(anyMatch);//1.3noneMatch(Predicate p)——检查是否没有匹配的元素//练习:是否不存在员工姓王boolean noneMatch = employees.stream().noneMatch(e->e.getName().startsWith("王"));System.out.println(noneMatch);//1.4findFirst()——返回第一个元素Optional<Employee> first = employees.stream().findFirst();System.out.println(first);//1.5findAny()——返回当前流中的任意元素Optional<Employee> any1 = employees.stream().findAny();//串行流,从第一个取Optional<Employee> any2 = employees.parallelStream().findAny();//并行流,从任意一个取System.out.println(any1+"\n"+any2);}@Testpublic void test2(){//1.6count()——返回流中元素的总个数List<Employee> employees = EmployeeData.getEmployees();long count = employees.stream().filter(e->e.getSalary()>5000).count();System.out.println(count);//1.7max(Comparator c)——返回流中最大值//练习:返回最高的工资Stream<Double> salaryStream = employees.stream().map(e -> e.getSalary());Optional<Double> max1 = salaryStream.max(Double::compare);Optional<Employee> max2 = employees.stream().max((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));System.out.println(max1+"\n"+max2);//1.8min(Comparator c)——返回流中最小值//练习:返回最低工资的员工Optional<Employee> employee=employees.stream().min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));System.out.println(employee);Optional<Double> min = employees.stream().map(Employee::getSalary).min(Double::compare);System.out.println(min);//1.9forEach(Consumer c)——内部迭代//使用方法引用employees.stream().forEach(System.out::println);//使用集合的遍历employees.forEach(System.out::println);//2.}//2.归约//2.1 reduce(T identity,BinaryOpretor) 可以将流中元素反复结合起来,得到一个值,返回T//练习:计算1-10的自然数的和//2.2 reduce(BinaryOpretor) 可以将流中元素反复结合起来,得到一个值,返回 Optional<T>//练习:计算公司所有员工工资的总和@Testpublic void test3(){//2.1 reduce(T identity,BinaryOpretor) 可以将流中元素反复结合起来,得到一个值,返回//练习:计算1-10的自然数的和List<Integer> lsit= Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);Integer sum = lsit.stream().reduce(0, Integer::sum);//Integer有个静态方法,sum传两个参数;函数式接口reduce也是传入两个参数System.out.println(sum);//2.2 reduce(BinaryOpretor) 可以将流中元素反复结合起来,得到一个值,返回 Optional<T>//练习:计算公司所有员工工资的总和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.收集//collect 将流转换为其他形式,接收一个Collector接口的实现,用于给Stream中元素做汇总的方法@Testpublic void test4(){//练习:查找工资大于6000的员工,结果返回为一个List(有序)或Set(无序)List<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);}}

5.Optional类

在这里插入图片描述
在这里插入图片描述

package OptionalTest;import org.junit.Test;import java.util.Optional;/*** Optional类:用于解决空指针异常的问题,为了不出现空指针出现异常而创建的** Optional.of(T t) : 创建一个 Optional 实例,t 不能为 null* Optional.empty() : 创建一个空的 Optional 实例* Optional.ofNullable(T t) : t 可以为 null*/
public class OptionalTest {@Testpublic void test1(){Girl girl= new Girl("哈哈");
//        girl = null;//of(T t) 方法必须保证t不能为空,否则报空指针异常Optional<Girl> optionalGirl =Optional.of(girl);System.out.println(optionalGirl);}@Testpublic void test2(){Girl girl= new Girl("哈哈");
//        girl = null;//ofNullable(T t) 方法t可以为空Optional<Girl> optionalGirl =Optional.ofNullable(girl);System.out.println(optionalGirl);//orElse(T t1) 方法如果optionalGirl内部封装的t是非空,则返回内部的t;// 如果内部的t为空,则返回orElse()方法中的参数t1Girl girl1 = optionalGirl.orElse(new Girl("哈哈"));System.out.println(girl1);}@Testpublic void test3(){Girl girl= new Girl("哈哈");girl = null;//empty() 方法创建一个空的 Optional 实例Optional<Girl> optionalGirl =Optional.empty();System.out.println(optionalGirl);}public String getGirlName1(Boy boy){return boy.getGirl().getName();}@Testpublic void test4(){Boy boy = new Boy();String girlName = getGirlName1(boy);System.out.println(girlName);//NullPointerException}//优化以后public String getGirlName2(Boy boy){if(boy != null){Girl girl = boy.getGirl();if (girl !=null){return girl.getName();}}return null;}@Testpublic void test5(){Boy boy = new Boy();String girlName = getGirlName2(boy);System.out.println(girlName);//NullPointerException}//典型练习,保证如下的方法执行中不会出现空指针异常//使用Optional类优化以后public String getGirlName3(Boy boy){Optional<Boy> optionalBoy = Optional.ofNullable(boy);//此时boy1一定非空Boy boy1 = optionalBoy.orElse(new Boy(new Girl("呵呵")));//orElse方法,如果为空,就返回一个默认值Girl girl = boy1.getGirl();Optional<Girl> girlOptional=Optional.ofNullable(girl);//不空就是本身数据Girl girl1 = girlOptional.orElse(new Girl("嘿嘿"));//为空就是orElse()中的数据//girl1一定非空return girl1.getName();}@Testpublic void test6(){Boy boy = null;boy = new Boy();boy= new Boy(new Girl("嘻嘻"));String girlName = getGirlName3(boy);System.out.println(girlName);//哈哈}
}
----------------------------------------------------------------------
package OptionalTest;import org.junit.Test;import java.util.Optional;public class OptionalTest1 {@Testpublic void test1() {Optional<Object> op1 = Optional.empty();
//        if (op1.isPresent()){//Optional封装的数据是否为空if (!op1.isPresent()) {//Optional封装的数据是否包含数据System.out.println("数据为空");}System.out.println(op1);System.out.println(op1.isPresent());//如果Optional封装的数据为空,则get()报错;如果不为空,则返回参数值
//        System.out.println(op1.get());}@Testpublic void test2() {String str = "hello";str= null;//Optional.ofNullable(str);//允许为空//of(T t)方法要求传入的参数t不能为空,如果为空,会抛出NullPointerExceptionOptional<String> op1 = Optional.of(str);//明确不是空使用 get() 和 of()//get()通常与of()方法搭配,用于获取内部的封装的数据String str1 = op1.get();System.out.println(str1);}@Testpublic void test3() {//有可能为空,使用//ofNullable和orElseString str ="哈哈";//ofNullable(T t)封装数据t赋给Optional内部的value,不要求t非空
//        Optional<String> op1 = Optional.ofNullable(str);Optional<String> op1 = Optional.ofNullable(null);//orElse(T t1)方法,如果Optional封装的数据为空,则返回参数t//value为空,则返回t1String str1 = op1.orElse("默认值");System.out.println(str1);}
}
http://www.xdnf.cn/news/6225.html

相关文章:

  • 第七节第二部分:接口的综合案例
  • 一文介绍电路交换、报文交换和分组交换
  • Shell
  • Apollo学习——aem问题
  • AI时代的弯道超车之第十二章:英语和编程重要性?
  • 【ROS2】【分步讲解】节点的使用以及引入消息接口的方法
  • 软件设计师考试《综合知识》计算机编码考点分析——会更新软设所有知识点的考情分析,求个三连
  • Qt之Qfile类
  • STM32-USART串口通信(9)
  • 材料疲劳E-N曲线的优势及其在疲劳仿真中的应用
  • 18、时序数据库 (TSDB) 存储高密度传感器数据组件 - /数据与物联网组件/tsdb-power-plant-archive
  • OpenSHMEM 介绍和使用指南
  • contains方法的实现对比
  • Java 源码 HashMap源码分析
  • ConcurrentHashMap
  • GeoServer发布WMTS详细过程
  • javaScript简单版
  • 详解Windows(十三)——Windows防火墙
  • k8s监控方案实践补充(一):部署Metrics Server实现kubectl top和HPA支持
  • ESG时代,EcoVadis认证如何提升企业国际竞争力
  • 苍穹外卖--菜品分页查询
  • 优雅的请求接口(java)
  • 制造业降本增效的核心要素
  • 通过SMTP协议实现Linux邮件发送配置指南
  • 0514得物、0509滴滴面试总结复盘
  • 20250514 无限空间,当 a(t)→0,所有‌物理距离‌ d→0 ‌,这个状态是什么,是无限大的无限致密状态吗
  • 什么是临时对象?临时对象在什么情况下产生?
  • 网络检测工具InternetTest v8.9.1.2504 单文件版,支持一键查询IP/DNS、WIFI密码信息
  • 自营交易考试中,怎么用“黄昏之星”形态做出漂亮反转单?
  • 2025年文化传播、心理学与公共管理国际会议(CPPM 2025)