day07--java高级编程:JDK8的新特性,JDK9的新特性,JDK10的新特性,JDK11的新特性,JDK15的新特性

news2024/11/28 22:36:00

1 JDK8的其它新特性

说明:一些8中的新特性在,java高级部分学习的同时顺便讲过了。

1.1 JDK8新特性的总体结构

在这里插入图片描述

1.2 Java 8新特性简介

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1.3 Lambda表达式

1.3.1 出现背景

在这里插入图片描述

1.3.2 Lambda表达式的使用举例

package com.atguigu.java1;


import org.junit.Test;

import java.util.Comparator;

/**
 * Lambda表达式的使用举例
 *
 * @author shkstart
 * @create 2019 上午 11:30
 */
public class LambdaTest {

    @Test
    public void test1(){
        //Runnable:是多线程创建接口的一种方式
        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(32,21);
        System.out.println(compare2);


        System.out.println("***********************");
        //方法引用
        Comparator<Integer> com3 = Integer :: compare;

        int compare3 = com3.compare(32,21);
        System.out.println(compare3);
    }

}

1.3.3 Lambda表达式语法的使用

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体应该使用一对{}包裹;如果lambda体只有一条执行语句(可能是return语句),省略这一对{}和return关键字
 *
 * 4.Lambda表达式的本质:作为函数式接口的实例(可以理解为接口的实现类对象)
 *  要求:接口中的抽象方法只有一个
 *
 * 5. 如果一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口。我们可以在一个接口上使用 @FunctionalInterface 注解,
 *   这样做可以检查它是否是一个函数式接口。(注意:自定义一个接口,接口里面只有一个抽象方法,这样的接口叫做函数式接口。加上这个注解是为了检查
 *       此接口是否为函数式接口,是不是函数是接口和加上此注解没有关系,注解只是起到检查的作用。)
 *
 * 6. 所以以前用匿名实现类表示的现在都可以用Lambda表达式来写。
 *
 * @author shkstart
 * @create 2019 上午 11:40
 */
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();
    }
    //语法格式二:Lambda 需要一个参数,但是没有返回值。
    @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("一个是听得人当真了,一个是说的人当真了");

    }

    //语法格式三:数据类型可以省略,因为可由编译器推断得出,称为“类型推断”
    //优化test2的方式:
    @Test
    public void test3(){

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

        System.out.println("*******************");
        //有泛型指定类型后 ,后面的数据类型可以省略,类似于之前学的如 test4
        Consumer<String> con2 = (s) -> {
            System.out.println(s);
        };
        con2.accept("一个是听得人当真了,一个是说的人当真了");

    }

    @Test
    public void test4(){

        ArrayList<String> list = new ArrayList<>();//类型推断

        int[] arr = {1,2,3};//类型推断

    }

    //语法格式四:Lambda 若只需要一个参数时,参数的小括号可以省略
    //优化test3的方式:
    @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> com1 = 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(com1.compare(12,21));

        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,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(com2.compare(12,21));

    }

    @Test
    public void test8(){
        Consumer<String> con1 = s -> {
            System.out.println(s);
        };
        con1.accept("一个是听得人当真了,一个是说的人当真了");

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

        Consumer<String> con2 = s -> System.out.println(s);

        con2.accept("一个是听得人当真了,一个是说的人当真了");

    }

}

1.4 函数式接口

1.4.1 概述

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

1.4.2 举例

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

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

说明:开发中见到的这几个四大核心函数式接口其它接口,在实例化时都可以使用Lambda表达式简写。
在这里插入图片描述
测试:

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)
 * 断定型接口 Predicate<T>    boolean test(T t)
 * 说明:凡是以前定义过的接口都属性这4种形式,那么就没有必要在进行定义了 直接使用内置的接口即可。
 *
 * @author shkstart
 * @create 2019 下午 2:29
 */
public class LambdaTest2 {
    //消费型接口测试:
    @Test
    public void test1(){
        //原来写法
        happyTime(500, new Consumer<Double>() {
            @Override
            public void accept(Double aDouble) {
                System.out.println("学习太累了,去天上人间买了瓶矿泉水,价格为:" + aDouble);
            }
        });

        System.out.println("********************");
        //Lambda表达式的写法    这里写aDouble也一样  流程是:在test1()中调用happyTime方法并赋值,而在happyTime中进行回调函数 把值赋给accept().
        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> filterStrs = filterString(list, new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.contains("京");
            }
        });

        System.out.println(filterStrs);


        List<String> filterStrs1 = filterString(list,s -> s.contains("京"));
        System.out.println(filterStrs1);
    }

    //根据给定的规则,过滤集合中的字符串。此规则由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;

    }

}

1.4.4 Java 其他接口

在这里插入图片描述

1.5 方法引用与构造器引用

1.5.1 方法引用概述

在这里插入图片描述

1.5.2 构造器引用和数组引用

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

1.5.3 综合测试

Employee类:

package com.atguigu.java2;

/**
 * @author shkstart 邮箱:shkstart@126.com
 */
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() {
		System.out.println("Employee().....");
	}

	public Employee(int id) {
		this.id = id;
		System.out.println("Employee(int 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;
	}
}

EmployeeData类:

package com.atguigu.java2;

import java.util.ArrayList;
import java.util.List;
/**
 * 提供用于测试的数据
 * 
 * @author shkstart 邮箱:shkstart@126.com
 *
 */
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;
	}
	
}

MethodRefTest类:

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表达式作为函数式接口的实例。所以
 *   方法引用,也是函数式接口的实例。    Lambda表达式的进一步简化。
 *
 * 3. 使用格式:  类(或对象) :: 方法名
 *
 * 4. 具体分为如下的三种情况:
 *    情况1     对象 :: 非静态方法()
 *    情况2     类 :: 静态方法
 *
 *    情况3     类 :: 非静态方法
 *
 * 5. 方法引用使用的要求:要求接口中的抽象方法的形参列表和返回值类型与方法引用的方法的
 *    形参列表和返回值类型相同!(针对于情况1和情况2)
 *
 * Created by shkstart.
 */
public class MethodRefTest {

	// 情况一:对象 :: 实例方法
	//Consumer中的void accept(T t)
	//PrintStream中的void println(T t)
	//解释:Consumer接口中的方法accept和PrintStream类中的println方法进行比较,发现2个方法的形参列表和返回值类型相同 并且accept方法
	//    本质上想要做的事情就是System.out.println(str)  ,System.out.println(str)在accept方法中使用了并且返回值和参数类型相同,
	//    就可以简写为方法的引用。
	@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("beijing");
	}
	
	//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("*******************");
		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 = (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,3));

	}
	
	//Function中的R apply(T t)
	//Math中的Long round(Double d)
	@Test
	public void test4() {
		Function<Double,Long> func = new Function<Double, Long>() {
			@Override
			public Long apply(Double d) {
				return Math.round(d);
			}
		};

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

		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.6));
	}

	// 情况三:类 :: 实例方法  (有难度)
	// Comparator中的int comapre(T t1,T t2)
	// String中的int t1.compareTo(t2)
	@Test
	public 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("abd","abm"));
	}

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

		System.out.println("*******************");
		BiPredicate<String,String> pre2 = String :: equals;
		System.out.println(pre2.test("abc","abd"));
	}
	
	// Function中的R apply(T t)
	// Employee中的String getName();
	@Test
	public void test7() {
		Employee employee = new Employee(1001, "Jerry", 23, 6000);


		Function<Employee,String> func1 = e -> e.getName();
		System.out.println(func1.apply(employee));

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


		Function<Employee,String> func2 = Employee::getName;
		System.out.println(func2.apply(employee));


	}

}

ConstructorRefTest类:

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;

/**
 * 一、构造器引用
 *      和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致。
 *      抽象方法的返回值类型即为构造器所属的类的类型
 *
 * 二、数组引用
 *     大家可以把数组看做是一个特殊的类,则写法与构造器引用一致。
 *
 * Created by shkstart
 */
public class ConstructorRefTest {
	//构造器引用
    //Supplier中的T get()
    //Employee的空参构造器:Employee()
    @Test
    public void test1(){
        //面向对象写法:
        Supplier<Employee> sup = new Supplier<Employee>() {
            @Override
            public Employee get() {
                return new Employee();
            }
        };
        System.out.println("*******************");
        //Lambda表达式写法:
        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)
    @Test
    public 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)
    @Test
    public void test3(){
        BiFunction<Integer,String,Employee> func1 = (id,name) -> new Employee(id,name);
        System.out.println(func1.apply(1001,"Tom"));

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

        BiFunction<Integer,String,Employee> func2 = Employee :: new;
        System.out.println(func2.apply(1002,"Tom"));

    }

	//数组引用
    //Function中的R apply(T t)
    @Test
    public 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));

    }
}


1.6 强大的Stream API

1.6.1 概述

在这里插入图片描述

1.6.2 出现背景

在这里插入图片描述

1.6.3 什么是 Stream

在这里插入图片描述

1.6.4 Stream 的操作三个步骤

在这里插入图片描述

1.6.5 Stream的四种实例化方式(步骤一)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
测试·:
EmployeeData:

package com.atguigu.java2;

import java.util.ArrayList;
import java.util.List;
/**
 * 提供用于测试的数据
 * 
 * @author shkstart 邮箱:shkstart@126.com
 *
 */
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;
	}
	
}

StreamAPITest类:

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关注的是对数据的运算,与CPU打交道
 *    集合关注的是数据的存储,与内存打交道
 *
 * 2.
 * ①Stream 自己不会存储元素。
 * ②Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
 * ③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行
 *
 * 3.Stream 执行流程
 * ① Stream的实例化(四种方式创建对象)
 * ② 一系列的中间操作(过滤、映射、...)
 * ③ 终止操作
 *
 * 4.说明:
 * 4.1 一个中间操作链,对数据源的数据进行处理
 * 4.2 一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用
 *
 *
 *  测试Stream的实例化
 *
 * @author shkstart
 * @create 2019 下午 4:25
 */
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(){
        //stream的类型: 如果放的是int类型的数组则是 IntStream
        int[] arr = new int[]{1,2,3,4,5,6};
        //调用Arrays类的static <T> Stream<T> stream(T[] array): 返回一个流
        IntStream stream = Arrays.stream(arr);
        //自定义类的数组stream的类型 :通过泛型体现
        Employee e1 = new Employee(1001,"Tom");
        Employee e2 = new Employee(1002,"Jerry");
        Employee[] arr1 = new Employee[]{e1,e2};
        Stream<Employee> stream1 = Arrays.stream(arr1);

    }
    //创建 Stream方式三:通过Stream的of()
    @Test
    public void test3(){

        Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);//认为里面的数据是引用类型  包装类

    }

    //创建 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);


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

    }

}

1.6.6 Stream的中间操作(步骤二)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
测试:
EmployeeData类:

package com.atguigu.java2;

import java.util.ArrayList;
import java.util.List;
/**
 * 提供用于测试的数据
 * 
 * @author shkstart 邮箱:shkstart@126.com
 *
 */
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;
	}
	
}

StreamAPITest1类:

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 shkstart
 * @create 2019 下午 4:42
 */
public class StreamAPITest1 {

    //1-筛选与切片
    @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(n)——截断流,使其元素不超过给定数量。
        list.stream().limit(3).forEach(System.out::println);
        System.out.println();

//        skip(n) —— 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补
        list.stream().skip(3).forEach(System.out::println);

        System.out.println();
//        distinct()——筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素

        list.add(new Employee(1010,"刘强东",40,8000));
        list.add(new Employee(1010,"刘强东",41,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", "dd");
        list.stream().map(str -> str.toUpperCase()).forEach(System.out::println);

//        练习1:获取员工姓名长度大于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();
        //练习2:
        Stream<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);

    }

    //将字符串中的多个字符构成的集合转换为对应的Stream的实例
    public static Stream<Character> fromStringToStream(String str){//aa
        ArrayList<Character> list = new ArrayList<>();
        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(12, 43, 65, 34, 87, 0, -98, 7);
        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 ageValue = Integer.compare(e1.getAge(),e2.getAge());
            if(ageValue != 0){
                return ageValue;
            }else{
                return -Double.compare(e1.getSalary(),e2.getSalary());
            }

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

}

1.6.7 Stream 的终止操作

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
测试:
EmployeeData类:

package com.atguigu.java2;

import java.util.ArrayList;
import java.util.List;
/**
 * 提供用于测试的数据
 * 
 * @author shkstart 邮箱:shkstart@126.com
 *
 */
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;
	}
	
}

StreamAPITest2类:

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 shkstart
 * @create 2019 下午 6:37
 */
public class StreamAPITest2 {

    //1-匹配与查找
    @Test
    public void test1(){
        List<Employee> employees = EmployeeData.getEmployees();

//        allMatch(Predicate p)——检查是否匹配所有元素。
//          练习:是否所有的员工的年龄都大于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> employee = employees.stream().findFirst();
        System.out.println(employee);
//        findAny——返回当前流中的任意元素
        Optional<Employee> employee1 = employees.parallelStream().findAny();
        System.out.println(employee1);

    }

    @Test
    public 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> salaryStream = employees.stream().map(e -> e.getSalary());
        Optional<Double> maxSalary = salaryStream.max(Double::compare);
        System.out.println(maxSalary);
//        min(Comparator c)——返回流中最小值
//        练习:返回最低工资的员工
        Optional<Employee> employee = employees.stream().min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        System.out.println(employee);
        System.out.println();
//        forEach(Consumer c)——内部迭代
        employees.stream().forEach(System.out::println);

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

    //2-归约
    @Test
    public void test3(){
//        reduce(T identity, BinaryOperator)——可以将流中元素反复结合起来,得到一个值。返回 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) ——可以将流中元素反复结合起来,得到一个值。返回 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.get());

    }

    //3-收集
    @Test
    public void test4(){
//        collect(Collector c)——将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法
//        练习1:查找工资大于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);




    }
}

1.7 Optional 类

1.7.1 概述

在这里插入图片描述

1.7.2 常用方法

在这里插入图片描述

1.7.3 测试

Boy类:

package com.atguigu.java4;

/**
 * @author shkstart
 * @create 2019 下午 7:22
 */
public class Boy {
    private Girl girl;

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

    public Girl getGirl() {
        return girl;
    }

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

    public Boy() {

    }

    public Boy(Girl girl) {

        this.girl = girl;
    }
}

Girl类:

package com.atguigu.java4;

/**
 * @author shkstart
 * @create 2019 下午 7:23
 */
public class Girl {

    private String name;

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

    public String getName() {
        return name;
    }

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

    public Girl() {

    }

    public Girl(String name) {

        this.name = name;
    }
}

OptionalTest类:

package com.atguigu.java4;

import org.junit.Test;

import java.util.Optional;

/**
 * Optional类:为了在程序中避免出现空指针异常而创建的。
 *
 * 常用的方法:ofNullable(T t)
 *            orElse(T t)
 *
 * @author shkstart
 * @create 2019 下午 7:24
 */
public class OptionalTest {

    /*
    Optional.of(T t) : 创建一个 Optional 实例,t必须非空;
    Optional.empty() : 创建一个空的 Optional 实例
    Optional.ofNullable(T t):t可以为null

     */
    @Test
    public void test1(){
        Girl girl = new Girl();
//        girl = null;
        //of(T t):保证t是非空的
        Optional<Girl> optionalGirl = Optional.of(girl);

    }

    @Test
    public void test2(){
        Girl girl = new Girl();
//        girl = null;
        //ofNullable(T t):t可以为null
        Optional<Girl> optionalGirl = Optional.ofNullable(girl);
        System.out.println(optionalGirl);
        //orElse(T t1):如果单前的Optional内部封装的t是非空的,则返回内部的t.
        //如果内部的t是空的,则返回orElse()方法中的参数t1.
        Girl girl1 = optionalGirl.orElse(new Girl("赵丽颖"));
        System.out.println(girl1);

    }


    public String getGirlName(Boy boy){
        return boy.getGirl().getName();
    }

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

    }
    //优化以后的getGirlName():
    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();
        boy = null;
        String girlName = getGirlName1(boy);
        System.out.println(girlName);

    }

    //使用Optional类的getGirlName():
    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);

    }



}

2JDK9的新特性

注意:需要下载安装新版本的JDK才能使用这些新特性。

2.1 概述

在这里插入图片描述

3 JDK10的新特性

4 JDK11的新特性

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/646497.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023年软件测试简历没有邀约?为什么?8类细节通通告诉你(附赠高薪简历)

求职不顺&#xff0c;没有邀约&#xff0c;大概率是你的简历出现了问题。 本篇文章列出高薪简历应该注意的细节&#xff0c;合计36处&#xff0c;涉及简历的八大组成部分。 现在就讲&#xff1a; 一、简历样式要求&#xff08;3点要求&#xff09; 1、简历格式&#xff0c;…

某游戏登录密码加密,webpack

注意&#xff1a;文章内容仅用于学习和技术交流&#xff0c;切勿做出违法的事情&#xff0c;如有侵权请联系我删除。 网址&#xff08;今天的大冤种&#xff09;&#xff1a;aHR0cHM6Ly93d3cuZ205OS5jb20v 一&#xff0c;分析 从上面图片可以看到&#xff0c;他的密码是加密了…

FinGPT:以数据为中心的方法革新开源金融

FinGPT 由 AI4Finance Foundation 开发&#xff0c;是一种以数据为中心的工具&#xff0c;可使大型语言模型 (LLM) 的金融数据民主化。它旨在成为开放式金融的开源解决方案&#xff0c;旨在彻底改变金融业。本文将深入探讨 FinGPT 的复杂性、它的好处&#xff0c;以及它如何成为…

vscode使用latex环境无法编译,是否与anaconda环境冲突

Vscode使用latex环境无法编译&#xff0c;是否与anaconda环境冲突 在 VSCode 中使用 LaTeX 环境无法编译&#xff0c;可能与 Anaconda 环境冲突。这是因为 Anaconda 默认会将环境变量PATH 设置为 Anaconda 所在的路径&#xff0c;如果你使用的是 Anaconda 内置的 Python环境&am…

如何三分钟快速制作自定义ppt

目录 利用ChatGPTMindShow三分钟生成PPT 机器人 道合顺 莓用ai 百晓生 aichat 结合提词器以达到更好地提问效果&#xff1a; 更好地提问ChatGPT_常用prompt表_小黄同学LL的博客-CSDN博客 举个栗子&#xff1a; 利用ChatGPTMindShow三分钟生成PPT 提词&#xff1a;…

LeCun世界模型出场!Meta震撼发布首个「类人」模型,理解世界后补全半张图,自监督学习众望所归

LeCun世界模型出场&#xff01;Meta震撼发布首个「类人」模型&#xff0c;理解世界后补全半张图&#xff0c;自监督学习众望所归 原创 新智元 新智元 2023-06-14 12:19 发表于北京 【新智元导读】LeCun的世界模型终于来了&#xff0c;可谓是众望所归。既然大模型已经学会了理解…

Unity入门6——光源组件

一、参数面板 二、参数介绍 Type&#xff1a;光源类型 Spot&#xff1a;聚光灯 Range&#xff1a;发光距离Spot Angle&#xff1a;光锥角度Directional&#xff1a;方向光Point&#xff1a;点光源Area&#xff08;Baked Only&#xff09;&#xff1a;面光源 仅烘焙。预先算好&…

如何选择好用的效果图渲染平台

在现代的建筑设计、室内设计、电影动画等行业中&#xff0c;效果图已经成为了一个重要的工具&#xff0c;能够帮助设计师和制作人员更好地呈现他们的想法和概念。而要制作出高质量的效果图&#xff0c;一个好用的效果图渲染平台是非常必要的。 如何选择好用的效果图渲染平台呢…

【Flutter】Flutter 如何获取安装来源信息

文章目录 一、 前言二、 安装来源信息的基本概念1. 什么是安装来源信息2. 为什么我们需要获取安装来源信息 三、 如何在 Flutter 中获取安装来源信息1. 准备工作2. 安装必要的依赖库3. 编写代码获取安装来源信息 四、 完整示例代码五、总结 一、 前言 在这篇文章中&#xff0c…

图像处理实战01-OpenCV 入门指南

Python OpenCV 入门指南 OpenCV是一个强大的计算机视觉库&#xff0c;它可以用于处理图像和视频数据&#xff0c;以及进行目标检测和跟踪等任务。&#xff0c;将学会如何使用Python编写OpenCV代码来进行基础和进阶的图像处理和分析。 学习OpenCV可以帮助你掌握基本的图像处理…

(哈希表) 1002. 查找共用字符 ——【Leetcode每日一题】

❓1002. 查找共用字符 难度&#xff1a;简单 给你一个字符串数组 words &#xff0c;请你找出所有在 words 的每个字符串中都出现的共用字符&#xff08; 包括重复字符&#xff09;&#xff0c;并以数组形式返回。你可以按 任意顺序 返回答案。 示例 1&#xff1a; 输入&…

Apache Hive安装部署

Apache Hive安装部署 &#x1f683;Hive元数据 描述数据的数据&#xff0c;主要描述数据属性信息&#xff0c;用来支持如指示存储位置&#xff0c;历史数据&#xff0c;资源查找&#xff0c;文件记录等功能。存储在关系型数据库中。如hive内置Derby&#xff0c;或第三方MySql…

微服务: 00-rabbitmq出现的异常以及解决方案

目录 前言: 问题概述: 1. rabbitmq初始安装配置异常 -> 1.1 rabbitmq报您与此网站连接不是私密连接 --->1.1.1 上述问题解决方案 ---> 1.1.2 依次执行下面代码 -> 1.2 解决用户的No access情况 -> 1.2.1 使用设置的账号密码进行登录 -> 1.2.2 点击 Ad…

参加完京东的面试,感觉面试官有点菜...

前言 去年年底面试了京东&#xff0c;现整理面经&#xff0c;希望各位不要觉得太迟&#xff08;这该死的拖延症???&#xff09;。 没有截图是因为他根本没给我发邮件&#xff0c;直接boss开聊的&#xff0c;但是boss的聊天记录只有30天&#xff0c;此处点名批评下&#xf…

VMware Tools 12.2.5 发布下载 - 虚拟机必备工具

VMware Tools 12.2.5 发布下载 - 虚拟机必备工具 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-tools-12/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org 简介 VMware Tools 中包含一系列服务和组件&#xff0c…

ThreadLocal了解

文章目录 概述源码原理内存泄露应用场景 概述 ThreadLocal提供线程的局部变量&#xff0c;这种变量与普通变量的区别在于&#xff0c;每个访问这种变量的线程都有自己的、独立的变量副本。用于解决多线程间的数据隔离问题。 源码 //返回Thread实例的成员变量threadLocals Th…

Pytest教程__测试用例的执行方式(2)

在pytest框架中&#xff0c;编写测试用例有如下约束&#xff1a; 所有的测试用例文件名都需要满足test_*.py格式或*_test.py格式。在测试用例文件中&#xff0c;测试类以Test开头&#xff0c;并且不能带有__init__方法&#xff0c;否则pytest不会执行该class。在测用例的class…

企业如何选择最佳的CDN服务?

根据研究表明&#xff0c;47%的客户更喜欢能在2秒内加载完成的网页&#xff0c;不仅如此&#xff0c;如果一个网站的加载时间超过3秒&#xff0c;那么40%的访问者会毫不犹豫的离开你的网站。所以使用正确的内容交付网络对初创公司尤为关键。它有助于实现快速、安全的内容交付。…

10_python——模块

目录 模块的概述 自定义模块 Python中的包 以主程序的形式执行 引用其他模块 模块的概述 什么是模块&#xff1a;在python中模块就是python程序&#xff0c;一个模块就是一个*.py的文件&#xff0c;通常情况下把能够实现某一特定功能的代码放置在一个文件中作为一个模块&…

前后端分离,就浅浅的看看

目录 前言 一、优点 二、跨域 1、概念 2、解决跨域 三、CORS 总结 前言 前后端分离是Web应⽤的⼀种前后端解耦的架构模式&#xff0c;‘前后端分离‘’&#xff0c;“前”&#xff0c;就是客户端&#xff0c;“后”就是服务器端&#xff0c;专门处理数据和业务逻辑&…