Java高级:新特性:lambda 函数式接口 方法引用 StreamAPI Optional类

package com.atguigu.java1;

import org.junit.Test;

import java.util.Comparator;

/**
 * Lambda表达式使用举例:
 *
 * @author
 * @create 2022-07-26 22:04
 */
public class LambdaTest {
    @Test
    public void test1(){

        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("我爱北京天安门");
            }
        };
        r1.run();
        System.out.println("***********************");
        Runnable r2 = () -> System.out.println("我爱故宫");

        r2.run();
    }

    @Test
    public void test2(){

        Comparator<Integer> com1 = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1,o2);
            }
        };

        int compare1 = com1.compare(12, 21);
        System.out.println(compare1);
        System.out.println("***********************");

        //Lambda表达式的写法
        Comparator<Integer> com2 = ( o1,  o2) -> Integer.compare(o1,o2);
        int compare2 = com2.compare(12, 21);
        System.out.println(compare1);

        System.out.println("***********************");

        //方法引用:
        Comparator<Integer> com3 =Integer :: compare;
        int compare3 = com2.compare(12, 21);
        System.out.println(compare1);
    }
}
package com.atguigu.java1;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.function.Consumer;

/**
 * Lambda表达式的使用
 * 1.举例:(o1 o2) -> Integer.compare(o1,o2);
 * 2.格式:
 *      ->:lambda操作符 或者叫箭头操作符
 *      ->左边:lambda形参列表(其实就是接口中的抽象方法的形参列表)
 *      ->右边:lambda体(其实就是重写的的抽象方法的方法体)
 * 3.Lambda表达式的使用:(分为6种情况)
 * 总结:
 * ->左边:lambda形参列表的形参类型可以省略(类型推断);如果参数列表只有一个参数,括号也可以省略。
 *  ->右边:lambda体应该使用一对{}来包裹;如果lambda体只有一条执行语句(可能是return语句),省略这一对{}和return。
 *
 * 4.Lambda表达式的本质:就是作为接口(函数式接口)的实例!
 *
 * 5.函数式接口:如果一个接口中只声明了一个抽象方法,就叫函数式接口。
 *
 * @author
 * @create 2022-07-26 22:20
 */
public class LambdaTest1 {

    //语法格式一:无参,无返回值
    @Test
    public void test1(){
        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("我爱北京天安门");
            }
        };
        r1.run();

        System.out.println("***********************");

        Runnable r2 = () -> {
            System.out.println("我爱故宫");
        };
        r2.run();
    }

    //语法格式二:需要一个参数,无返回值
    @Test
    public void test2(){
        Consumer<String> con = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        con.accept("谎言和誓言的区别是什么呢?");

        System.out.println("***********************");

        Consumer<String> con1 = (String s) -> {
            System.out.println(s);
        };
        con1.accept("一个是听的人当真了");
    }

    //语法格式三:数据类型可以省略,因为可以由编译器推断得出,称为”类型推断“。
    @Test
    public 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("一个是听的人当真了");
    }

    @Test
    public void test4(){
        ArrayList<String> list = new ArrayList<>();//类型推断
        int[] arr = {1,3,4};//类型推断
    }

    //语法格式四:Lmabda若只需要一个参数时,参数的小括号可以省略。
    @Test
    public void test5(){
        Consumer<String> con1 = (s) -> {
            System.out.println(s);
        };
        con1.accept("一个是听的人当真了");

        System.out.println("***********************");

        Consumer<String> con2 = s -> {
            System.out.println(s);
        };
        con2.accept("一个是听的人当真了");
    }

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

        System.out.println("******************");

        Comparator<Integer> com1 = (o1,o2) -> {
            System.out.println(o1);
            System.out.println(o2);
            return o1.compareTo(o2);
        };
        System.out.println(com1.compare(12,6));

    }

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

        System.out.println("******************");

        Comparator<Integer> com2 = (o1,o2) -> o1.compareTo(o2);
        System.out.println(com1.compare(12,23));
    }
}
package com.atguigu.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;

/**
 *java内置的4大核心函数式接口:
 *
 * 消费型接口 Consumer<T> void accept(T t)
 * 供给型接口 Supplier<T> T get()
 * 函数型接口 Function<T R> R apply(T t)
 * 断定型接口 Predication<T> boolean test(T t)
 *
 * @author
 * @create 2022-07-27 10:48
 */
public class LambdaTest2 {
    @Test
    public void test(){
        happyTime(500, new Consumer<Double>() {
            @Override
            public void accept(Double aDouble) {
                System.out.println("学习好啊" + aDouble);
            }
        });

        System.out.println("**************************");

        happyTime(400, money -> System.out.println("学习好啊" + money));

    }

    public void happyTime(double money, Consumer<Double> con){
        con.accept(money);
    }

    @Test
    public void test2(){
        List<String> list = Arrays.asList("南京","济南");

        List<String> filterString = filterString(list, new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.contains("京");
            }
        });

        System.out.println(filterString);

        List<String> filterString1 = filterString(list,s -> s.contains("京"));

        System.out.println(filterString1);
    }

    //根据给定的规则去过滤字符串
    public List<String> filterString (List<String> list, Predicate<String> pre){
        ArrayList<String> arr = new ArrayList<>();
        for (String s: list){
            if(pre.test(s)){
                arr.add(s);
            }
        }
        return arr;
    }

}
package com.atguigu.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表达式是作为函数时接口的s实例。所以
 * 方法引用也是函数式接口的实例。
 *
 * 3.使用和格式:  类(对象):: 方法名
 *
 * 4 .具体分为如下的三种情况:
 *
 * 情况一:  对象::非静态方法(实例方法)
 * 情况二:  类::静态方法
 *
 * 情况三:  类::非静态方法
 *
 * 5.方法引用的使用要求:要求接口中的抽象方法的形参列表和返回值类型要和方法引用的方法的
 * 形参列表和返回值相同。(针对情况一和情况二)
 */
public class MethodRefTest {

	// 情况一:对象 :: 实例方法
	//Consumer中的void accept(T t)
	//PrintStream中的void println(T t)
	@Test
	public 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()
	@Test
	public void test2() {
		Employee emp = new Employee(1001,"Tom",23,5600);
		Supplier<String> sup1 = () -> emp.getName();
		System.out.println(sup1.get());

		System.out.println("*********************");

		Employee emp2 = new Employee(1001,"Tom",23,5600);
		Supplier<String> sup2 = emp :: getName;
		System.out.println(sup2.get());
	}

	// 情况二:类 :: 静态方法
	//Comparator中的int compare(T t1,T t2)
	//Integer中的int compare(T t1,T t2)
	@Test
	public void test3() {
		Comparator<Integer> com1 = (o1, o2) -> Integer.compare(o1, o2);
		System.out.println(com1.compare(10, 12));

		System.out.println("*********************");

		Comparator<Integer> com2 = Integer :: compare;
		System.out.println(com2.compare(34, 645));
	}
	
	//Function中的R apply(T t)
	//Math中的Long round(Double d)
	@Test
	public void test4() {
		Function<Double, Long> func1 = d -> Math.round(d);
		System.out.println(func1.apply(200.9));

		System.out.println("*********************");
		Function<Double, Long> func2 = Math :: round;
		System.out.println(func2.apply(2345.5));
	}

	// 情况三:类 :: 实例方法 (有难度)
	// Comparator中的int comapre(T t1,T t2)
	// String中的int t1.compareTo(t2)
	@Test
	public void test5() {
		Comparator<String> com1 = (t1, t2) -> t1.compareTo(t2);
		System.out.println(com1.compare("adfs", "fwer"));

		System.out.println("*********************");

		Comparator<String> com2 = String :: compareTo;
		System.out.println(com2.compare("sfg", "fsgrw"));
	}

	//BiPredicate中的boolean test(T t1, T t2);
	//String中的boolean t1.equals(t2)
	@Test
	public void test6() {
		BiPredicate<String, String> pre1 = (t1, t2) -> t1.equals(t2);
		System.out.println(pre1.test("abc","abc"));

		System.out.println("*********************");

		BiPredicate<String, String> pre2 = String :: equals;
		System.out.println(pre2.test("abc","abc"));

	}
	
	// Function中的R apply(T t)
	// Employee中的String getName();
	@Test
	public void test7() {
		Function<Employee, String> func1 = e -> e.getName();
		System.out.println(func1.apply(new Employee(1234,"Tom")));

		System.out.println("*********************");

		Function<Employee, String> func2 = Employee :: getName;
		System.out.println(func2.apply(new Employee(1234,"Tom")));
	}
}
package com.atguigu.java2;

import org.junit.Test;

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

/**
 * 一、构造器引用
 *
 *       和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致。
 *       抽象方法的返回值类型即为构造器所属类的类型。
 *
 * 二、数组引用
 *
 *      大家可以把数组看成是一个特殊的类,则写法就与构造器引用一致。
 *
 *
 */
public class ConstructorRefTest {
	//构造器引用
    //Supplier中的T get()
    //Employee的空参构造器:Employee,没有参数有返回值
    @Test
    public void test1(){
        Supplier<Employee> sup1 = new Supplier<Employee>() {
            @Override
            public Employee get() {
                return new Employee();
            }
        };

        System.out.println("**************************");

        Supplier<Employee> sup2 = () -> new Employee();
        System.out.println(sup2.get());

        System.out.println("**************************");

        Supplier<Employee> sup3 = Employee :: new;
        System.out.println(sup3.get());


	}

	//Function中的R apply(T t)
    @Test
    public void test2(){
        Function<Integer, Employee> fun1 = id -> new Employee(id);
        Employee apply = fun1.apply(123);
        System.out.println(apply);

        System.out.println("**************************");

        Function<Integer, Employee> fun2 = Employee :: new;
        Employee apply1 = fun1.apply(123);
        System.out.println(apply1);
    }

	//BiFunction中的R apply(T t,U u)
    @Test
    public void test3(){
        BiFunction<Integer,String,Employee> fun1 = (name,id) -> new Employee(name,id);
        Employee tom = fun1.apply(12, "Tom");
        System.out.println(tom);

        System.out.println("**************************");

        BiFunction<Integer,String,Employee> fun2 = Employee :: new;
        Employee tom1 = fun1.apply(12, "Tom");
        System.out.println(tom1);
    }

	//数组引用:
    //Function中的R apply(T t)
    @Test
    public void test4(){
        Function<Integer,String[]> fun1 = length -> new String[length];
        String[] apply = fun1.apply(10);
        System.out.println(Arrays.toString(apply));

        Function<Integer,String[]> fun2 = String[] :: new;
        String[] apply2 = fun1.apply(10);
        System.out.println(Arrays.toString(apply2));

    }
}
package com.atguigu.java2;

/**
 * @author
 */
public class Employee {

	private int id;
	private String name;
	private int age;
	private double salary;

	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 int getAge() {
		return age;
	}

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

	public double getSalary() {
		return salary;
	}

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

	public Employee(String s, String tom, int i) {

	}

	public Employee(String s, String tom, int age, int id) {

		this.id = id;
	}

	public Employee() {
	}

	public Employee(int id) {
		this.id = id;
	}

	public Employee(int id, String name) {
		this.id = id;
		this.name = name;
	}

	public Employee(int id, String name, int age, double salary) {

		this.id = id;
		this.name = name;
		this.age = age;
		this.salary = salary;
	}

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

	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null || getClass() != o.getClass())
			return false;

		Employee employee = (Employee) o;

		if (id != employee.id)
			return false;
		if (age != employee.age)
			return false;
		if (Double.compare(employee.salary, salary) != 0)
			return false;
		return name != null ? name.equals(employee.name) : employee.name == null;
	}

	@Override
	public int hashCode() {
		int result;
		long temp;
		result = id;
		result = 31 * result + (name != null ? name.hashCode() : 0);
		result = 31 * result + age;
		temp = Double.doubleToLongBits(salary);
		result = 31 * result + (int) (temp ^ (temp >>> 32));
		return result;
	}
}
package com.atguigu.java2;

import java.util.ArrayList;
import java.util.List;
/**
 * 提供用于测试的数据
 * 
 * @author
 *
 */
public class EmployeeData {
	
	public static List<Employee> getEmployees(){
		List<Employee> list = new ArrayList<>();
		
		list.add(new Employee(1001, "马化腾", 34, 6000.38));
		list.add(new Employee(1002, "马云", 12, 9876.12));
		list.add(new Employee(1003, "刘强东", 33, 3000.82));
		list.add(new Employee(1004, "雷军", 26, 7657.37));
		list.add(new Employee(1005, "李彦宏", 65, 5555.32));
		list.add(new Employee(1006, "比尔盖茨", 42, 9500.43));
		list.add(new Employee(1007, "任正非", 26, 4333.32));
		list.add(new Employee(1008, "扎克伯格", 35, 2500.32));
		
		return list;
	}	
}
package com.atguigu.java3;

import com.atguigu.java2.Employee;
import com.atguigu.java2.EmployeeData;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

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

    //创建Stream方式一:通过集合

    @Test
    public 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方式二:通过数组
    @Test
    public void test2(){
        int[] arr = new int[]{1,23,4};
        //static <T> Stream<T> stream(T[] array): 返回一个流
        IntStream intStream = Arrays.stream(arr);

        Employee e1 = new Employee(1001,"Tom");
        Employee e2 = new Employee(1003,"Jerry");
        Employee[] arr1 = new Employee[]{e1, e2};
        Stream<Employee> stream = Arrays.stream(arr1);
    }

    //创建 Stream方式三:通过Stream的of()
    @Test
    public void test3(){
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 44, 3);

    }

    //创建 Stream方式四:创建无限流:
    @Test
    public 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.atguigu.java3;

import com.atguigu.java2.Employee;
import com.atguigu.java2.EmployeeData;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

/**
 * 测试Stream的中间操作
 *
 * @author
 * @create 2022-07-27 20:11
 */
public class StreamAPITest1 {
    @Test
    public void test1(){
        List<Employee> list = EmployeeData.getEmployees();
//        filter(Predicate p) 接收 Lambda ,从流中排除某些元素
        Stream<Employee> stream = list.stream();
        //练习:查询员工表中薪资大于7000的员工信息
        stream.filter(e -> e.getSalary() > 7000).forEach(System.out :: println);
        System.out.println();

//        limit(long maxSize) 截断流,使其元素不超过给定数量

        List<Employee> list1 = EmployeeData.getEmployees();
        Stream<Employee> stream1 = list1.stream();

        stream1.limit(3).forEach(System.out :: println);
        System.out.println();

//        skip(long n)跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补
        list.stream().skip(2).forEach(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));
        list.add(new Employee(1010,"刘强东",40,8000));

//        System.out.println(list);
        list.stream().distinct().forEach(System.out :: println);
    }

    //映射
    @Test
    public void test2(){
//  map(Function f) 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
        List<String> list = Arrays.asList("AA", "BB", "CC");
        list.stream().map(str -> str.toUpperCase()).forEach(System.out :: println);
// 练习1:获取姓名长度大于三的员工的姓名
        List<Employee> employees = EmployeeData.getEmployees();
        Stream<Employee> stream = employees.stream();
        Stream<String> namesStream = stream.map(e -> e.getName());
        namesStream.filter(name -> name.length() > 3).forEach(System.out :: println);
        System.out.println();

        //练习2:
        Stream<Stream<Character>> streamStream = list.stream().map(str -> fromStringToStream(str));
        streamStream.forEach(s -> {
            s.forEach(System.out :: println);
        });

    // flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
        Stream<Character> characterStream = list.stream().flatMap(str -> fromStringToStream(str));
        characterStream.forEach(System.out :: println);
    }

    //将字符串中的多个字符构成的集合,转换为对应的Stream的实例。
    public Stream<Character> fromStringToStream(String str){//aa
        ArrayList<Character> list = new ArrayList<>();//a,a
        for(Character c :str.toCharArray()){
            list.add(c);
        }
        return list.stream();
    }

    @Test
    public void test3(){
        ArrayList list1 = new ArrayList();
        list1.add(1);
        list1.add(2);
        list1.add(3);

        ArrayList list2 = new ArrayList();
        list2.add(4);
        list2.add(5);
        list2.add(6);

        list1.add(list2);
        list1.addAll(list2);
        System.out.println(list1);
    }
    //3-排序
    @Test
    public void test4(){
//        sorted() 产生一个新流,其中按自然顺序排序
        List<Integer> list = Arrays.asList(231, 423, 5, 345, 352);
        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) -> Integer.compare(e1.getAge(), e2.getAge())).forEach(System.out::println);
    }
}
package com.atguigu.java3;

import com.atguigu.java2.Employee;
import com.atguigu.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;

/**
 * 测试Stream的终止操作
 *
 * @author
 * @create 2022-07-27 23:17
 */
public class StreamAPITest2 {
    //1-匹配与查找:
    @Test
    public void test(){
//        allMatch(Predicate p) 检查是否匹配所有元素
        List<Employee> employees = EmployeeData.getEmployees();
        //是否所有员工的年龄都大于18
        boolean allMatch = employees.stream().allMatch(e -> e.getAge() > 18);
        System.out.println(allMatch);

//        anyMatch(Predicate p) 检查是否至少匹配一个元素
        //是否有员工工资大于10000
        boolean anyMatch = employees.stream().anyMatch(e -> e.getSalary() > 10000);
        System.out.println(anyMatch);

//        noneMatch(Predicate p) 检查是否没有匹配所有元素
        boolean noneMatch = employees.stream().noneMatch(e -> e.getName().startsWith("雷"));
        System.out.println(noneMatch);

//        findFirst() 返回第一个元素
        Optional<Employee> first = employees.stream().findFirst();
        System.out.println(first);
//        findAny() 返回当前流中的任意元素
        Optional<Employee> any = employees.parallelStream().findAny();
        System.out.println(any);
//
//        count() 返回流中元素总数
        long count = employees.stream().filter(s -> s.getSalary() > 13000).count();
        System.out.println(count);
//        max(Comparator c) 返回流中最大值
        //返回最高的工资:
        Stream<Double> salaryStream = employees.stream().map(e -> e.getSalary());
//        Optional<Double> max = salaryStream.max((Double::compare));
        Optional<Double> max = salaryStream.max((d1, d2) -> {
            double do1 = d1;
            double do2 = d2;
            int i1 = (int)do1;
            int i2 = (int)do2;
            return i1 - i2;
        });
        System.out.println(max);
//        min(Comparator c) 返回流中最小值
        //返回最低的工资的员工
        Optional<Employee> employee = employees.stream().min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        System.out.println(employee);

//        forEach(Consumer c) -内部迭代(使用 Collection 接口需要用户去做迭代,称为外部迭代。相反,Stream API 使用内部迭 代——它帮你把迭代做了)
        employees.stream().forEach(System.out :: println);

        //使用集合的遍历操作
        employees.forEach(System.out :: println);

    }
    //2-归约
    @Test
    public void test1(){
//        reduce(T iden, BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。返回 T
        //计算1-10的总和:
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
        Integer reduce = list.stream().reduce(0, Integer::sum);
        System.out.println(reduce);

//        reduce(BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。返回 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-收集
    @Test
    public void test2(){
//        collect(Collector c) 将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法
        //练习:查找工资大于6000的员工,结果返回一个List或者Set
        List<Employee> employees = EmployeeData.getEmployees();
        Stream<Employee> employeeStream = employees.stream().filter(e -> e.getSalary() > 6000);
        List<Employee> collect = employeeStream.collect(Collectors.toList());
        collect.forEach(System.out :: println);

        Stream<Employee> employeeStream1 = employees.stream().filter(e -> e.getSalary() > 6000);
        Set<Employee> collect1 = employeeStream1.collect(Collectors.toSet());
        collect1.forEach(System.out :: println);
    }
}
package com.atguigu.java4;

import org.junit.Test;

import java.util.Optional;

/**
 *
 *Optional类:为了在程序中出现空指针异常而创建的。
 *
 *  常用的方法:ofNullable(T t)
 *             orElse(T t)
 *
 * @author
 * @create 2022-07-28 13:44
 */
public class OptionalTest {
    /*
    创建Optional类对象的方法:
   Optional.of(T t) : 创建一个 Optional实例,t必须非空;
   Optional.empty() : 创建一个空的 Optional 实例
   Optional.ofNullable(T t):t可以为null
     */
    @Test
    public void test(){
        Girl girl = new Girl();
        //of(T t):必须保证t是非空的
        Optional<Girl> girl1 = Optional.of(girl);

    }
    @Test
    public void test1(){
        Girl girl = new Girl();
        girl = null;
        //ofNullable(T t):可以是空的
        Optional<Girl> girl1 = Optional.ofNullable(girl);
        System.out.println(girl1);

        //orElse(T t1):如果当前的Optional类封装的是非空的,则返回内部的T,如果内部的t是空的,
        // 则返回orElse(T t1)方法中的参数t1.
        Girl girl2 = girl1.orElse(new Girl("赵丽颖"));
        System.out.println(girl2);


    }

    public String getGirlName(Boy boy){
        return boy.getGirl().getName();
    }
    @Test
    public void test3(){
        Boy boy = new Boy();
        String girlName = getGirlName(boy);
        System.out.println(girlName);
    }

    //优化方法
    public String getGirlName1(Boy boy){
        if(boy != null){
            Girl girl = boy.getGirl();
            if (girl != null){
                return girl.getName();
            }
        }
        return null;
    }
    @Test
    public void test4(){
        Boy boy = new Boy();
        String girlName = getGirlName1(boy);
        System.out.println(girlName);
    }

    //优化方法2:使用Optional类
    public String getGirlName2(Boy boy){

        Optional<Boy> boyOptional = Optional.ofNullable(boy);

        //此时的boy1一定非空:
        Boy boy1 = boyOptional.orElse(new Boy(new Girl("迪丽热巴")));

        Girl girl = boy1.getGirl();

        Optional<Girl> girlOptional = Optional.ofNullable(girl);

        //此时的girl1一定非空:
        Girl girl1 = girlOptional.orElse(new Girl("古力娜扎"));

        return girl1.getName();
    }

    @Test
    public void test5(){
        Boy boy = null;
        boy = new Boy();
        boy = new Boy(new Girl("杨幂"));
        String girlName = getGirlName2(boy);
        System.out.println(girlName);
    }
}
package com.atguigu.java4;

/**
 * @author
 * @create 2022-07-28 13:41
 */
public class Girl {
    private String name;

    public Girl() {
    }

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

    public String getName() {
        return name;
    }

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

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

package com.atguigu.java4;

/**
 * @author
 * @create 2022-07-28 13:41
 */
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 +
                '}';
    }
}
package com.atguigu.java;

import org.junit.Test;

import java.util.Optional;

/**
 * @author
 * @create 2022-07-28 16:16
 */
public class OptionalTest {
    @Test
    public void test(){
        Optional<Object> op1 = Optional.empty();
        if (!op1.isPresent()) {
            System.out.println("数据为空");
        }
        System.out.println(op1);
    }

    @Test
    public void test1(){
        Optional<String> op1 = Optional.of("Hello");
        String s = op1.get();
        System.out.println(s);
    }

    @Test
    public void test2(){
        Optional<String> optional = Optional.ofNullable(null);
//        Optional<String> optional = Optional.ofNullable("beijing");

        String orElse = optional.orElse("上海");

        System.out.println(orElse);
    }
}

猜你喜欢

转载自blog.csdn.net/m0_63104578/article/details/126040132