Java 8 新特性

  • Java 8 新特性简介
    • 思维导图
    • 并行流与串行流
  • Lambda表达式
    • Lambda 表达式语法
      • 语法格式一:无参,无返回值,Lambda体只需一条语句
      • 语法格式二:Lambda需要一个参数
      • 语法格式三:Lambda只需要一个参数时,参数的小括号可以省略
      • 语法格式四:Lambda需要两个参数,并且有返回值
      • 语法格式五:当 Lambda 体只有一条语句时,return 与大括号可以省略
      • 语法格式六:
      • 代码示例
  • 函数式接口介绍
    • 如何理解函数式接口
    • Java内置四大核心函数式接口
    • 其它接口
  • 方法引用
    • 方法引用代码示例
      • Employee
      • MethodRefTest
  • 构造器引用
    • 格式
    • 代码示例
      • ConstructorRefTest
  • 数组引用
    • 格式
    • 代码示例
  • 强大的Stream API
    • 为什么要使用Stream API
    • 什么是Stream
    • Stream 的操作三个步骤
      • 创建 Stream
        • 创建 Stream方式一:通过集合
        • 创建 Stream方式二:由数组创建流
        • 创建 Stream方式三:由值创建流
        • 创建 Stream方式四:由函数创建流:创建无限流
      • 代码示例
        • EmployeeData
        • StreamAPITest
      • 中间操作
        • 筛选与切片
        • 映射
        • 排序
      • 终止操作(终端操作)
        • 查找与匹配
        • 归约
        • 收集
  • Optional类
  • JDK8中的日期时间
    • 新日期时间API的出现背景
    • 新日期时间API
    • LocalDate、LocalTime、LocalDateTime
    • Instant
      • Instant API
      • 格式化与解析日期或时间
      • 时间日期其它API
      • 与传统日期的转换

Java 8 新特性简介

思维导图


并行流与串行流

Lambda表达式

package com.lambda;import org.junit.Test;import java.util.Comparator;/*** Lambda入门** @author wty* @date 2022/11/12 15:53*/
public class Example01 {@Testpublic void example01(){Runnable r1 = new Runnable() {@Overridepublic void run() {System.out.println("run1().");}};r1.run();// Lambda表达式Runnable r2 = ()->System.out.println("run2().");r2.run();}@Testpublic void example02(){Comparator<Integer> comparator1 = new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return Integer.compare(o1,o2);}};int compare = comparator1.compare(12, 21);System.out.println(compare);/*** 返回结果:* -1* 说明前面小,后面大*/// Lambda表达式Comparator<Integer> comparator2 = (o1,o2) -> Integer.compare(o1,o2);int compare2 = comparator2.compare(32, 21);System.out.println(compare2);// 继续简化 方法引用Comparator<Integer> comparator3 = Integer::compare;int compare3 = comparator3.compare(21, 21);System.out.println(compare3);}}

Lambda 表达式语法

语法格式一:无参,无返回值,Lambda体只需一条语句

语法格式二:Lambda需要一个参数

语法格式三:Lambda只需要一个参数时,参数的小括号可以省略

语法格式四:Lambda需要两个参数,并且有返回值

语法格式五:当 Lambda 体只有一条语句时,return 与大括号可以省略

语法格式六:

代码示例

package com.lambda;import org.junit.Test;import java.util.Comparator;
import java.util.function.BinaryOperator;
import java.util.function.Consumer;/*** Lambda 表达式的使用** 1.举例:(o1,o2) -> Integer.compare(o1,o2);* 2.格式*       ->: lambda操作符/箭头操作符*       (o1,o2):lambda形参列表 其实就是接口中抽象方法的形参列表*       Integer.compare(o1,o2):lambda体 其实就是重写的抽象方法的方法体* 3.lambda表达式的使用* 4.本质:作为接口的实例(对象)** 总结*  ->的左边 lambda形参列表的参数类型可以省略(类型推断),如果只有一个参数()可以省略,两个以及以上的不能省略*  ->的右边 lambda体,如果只有一条执行语句,大括号可以省略,如果有两条以及以上,则大括号不能省略,return一定要省略** @author wty* @date 2022/11/12 16:08*/
public class LambdaTest01 {@Testpublic void test01(){//语法格式一:无参,无返回值,Lambda体只需一条语句Runnable runnable = ()->{System.out.println("hello world");};runnable.run();}@Testpublic void test02(){// 语法格式二:Lambda需要一个参数Consumer<String> con = new Consumer<String>() {@Overridepublic void accept(String s) {System.out.println(s);}};con.accept("今天天气不错");System.out.println();// Lambda表示Consumer<String> con2 = (String s)->{System.out.println(s);};con2.accept("今天天气不错2");}@Testpublic void test3(){//语法格式三:Lambda只需要一个参数时,参数的小括号可以省略、参数类型也可以省略// 也可以称为类型推断Consumer<String> con = new Consumer<String>() {@Overridepublic void accept(String s) {System.out.println(s);}};con.accept("hello");Consumer<String> con2 = s -> System.out.println(s);con2.accept("world");}@Testpublic void test04(){BinaryOperator<Long> binaryOperator = new BinaryOperator<Long>() {@Overridepublic Long apply(Long x, Long y) {System.out.println("实现apply");return (x+y);}};System.out.println(binaryOperator.apply((long) 1, (long) 2));// 语法格式四:Lambda需要两个参数,并且有返回值// Lambda表达式BinaryOperator<Long> binaryOperator2 = (x,y) -> {System.out.println("实现apply");return (x+y);};System.out.println(binaryOperator2.apply((long) 2, (long) 3));Comparator<Integer> comparator1 = new Comparator<Integer>() {@Overridepublic int compare(Integer t1, Integer t2) {return Integer.compare(t1,t2);}};comparator1.compare(12,21);// 使用Lambda表达式Comparator<Integer> comparator2 = (t1,t2) -> Integer.compare(t1,t2);comparator2.compare(12,21);// 语法格式五:当 Lambda 体只有一条语句时,return 与大括号可以省略BinaryOperator<Long> binaryOperator3 = (x,y) -> (x+y);System.out.println(binaryOperator3.apply((long) 3, (long) 4));}@Testpublic void test05(){// 语法格式六:Comparator<Integer> comparator1 = new Comparator<Integer>() {@Overridepublic int compare(Integer t1, Integer t2) {return Integer.compare(t1,t2);}};int compare1 = comparator1.compare(12, 45);System.out.println(compare1);// 使用lambda表达式Comparator<Integer> comparator2 = (t1,t2) -> Integer.compare(t1,t2);int compare2 = comparator2.compare(12, 5);System.out.println(compare2);}@Testpublic void test8(){Consumer<String> consumer = new Consumer<String>() {@Overridepublic void accept(String s) {System.out.println(s);}};consumer.accept("天气不错");// 使用lambda表达式Consumer<String> consumer2 = s -> System.out.println(s);consumer2.accept("是的");}
}

函数式接口介绍


例如Runnable接口是函数式接口,上面有注解@FunctionalInterface

@FunctionalInterface
public interface Runnable {void run();
}

自己写一个函数式接口

package com.lambda;/*** 自己写一个函数式接口* * @InterfaceName: MyInterface* @Description:* @Author: wty* @Date: 2022/11/12*/
@FunctionalInterface
public interface MyInterface {void method1();
}

如何理解函数式接口

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

package com.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内置四大核心函数式接口* 1.消费型Consumer<T> void accept(T t)* 2.供给型Suppiler<T> T get()* 3.函数型Function<T,R> R appply(T t)* 4.断定型Predicate<T> boolean test(T t)*** @author wty* @date 2022/11/12 23:00*/
public class Lambda02 {@Testpublic void testLambda02(){// 原来的写法happyTime(599, new Consumer<Double>() {@Overridepublic void accept(Double aDouble) {System.out.println("您消费了"+aDouble);}});// Lambda表达式happyTime(400,aDouble -> System.out.println("您消费了"+aDouble));}// 消费型public void happyTime(double money, Consumer<Double> consumer){consumer.accept(money);}@Testpublic void testLambda03(){String array[] = {"北京","南京","天津","普京","烤面筋"};List<String> list = Arrays.asList(array);List<String> filter = filterString(list, new Predicate<String>() {@Overridepublic boolean test(String s) {return s.contains("京");}});System.out.println(filter);// 使用Lambda表达式System.out.println("使用Lambda表达式");List<String> filter2 = filterString(list, s -> s.contains("京"));System.out.println(filter2);}/*** 根据规则,过滤集合中的字符串,规则由Predicate方法指定** @param* @param: list* @param: predicate* @return java.util.List<java.lang.String>* @date 2022/11/12 23:15* @author wty**/public List<String> filterString(List<String> list, Predicate<String> predicate){ArrayList<String> arrayList = new ArrayList<>();for (String s : list) {if (predicate.test(s)){arrayList.add(s);}}return arrayList;}
}

其它接口

方法引用

方法引用代码示例

Employee

package com.methodreference;/*** @author wty* @date 2022/11/12 23:48*/
@SuppressWarnings("all")
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;}@Overridepublic String toString() {return "Employee{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", salary=" + salary + '}';}@Overridepublic 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;}@Overridepublic 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;}
}

MethodRefTest

package com.methodreference;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.具体分为以下3种情况* (1) 对象 :: 非静态方法* (2) 类 :: 静态方法* (3) 类 :: 非静态方法* 5.方法引用使用的要求:针对情况(1)和情况(2)* 接口 中的抽象方法的形参列表和返回值类型* 与* 方法引用 中的形参列表和返回值类型相同** 6.接口方法的形参列表作为返回函数类型的形参列表之一 则可以使用方法引用*** @author wty* @date 2022/11/12 23:51*/
@SuppressWarnings({"all"})
public class MethodRefTest {// 情况一:对象 :: 实例方法//Consumer中的void accept(T t)//PrintStream中的void println(T t)@Testpublic void test() {Consumer<Double> consumer = new Consumer<Double>() {@Overridepublic void accept(Double money) {System.out.println(money);}};consumer.accept(300.02);// LambdaConsumer<Double> consumer2 = money -> System.out.println(money);consumer2.accept(301.02);// 方法引用/*** 对象 :: 非静态方法*/PrintStream ps = System.out;Consumer<Double> consumer3 = ps::println;consumer2.accept(302.02);}//Supplier中的T get()//Employee中的String getName()@Testpublic void test2() {Employee employee = new Employee(1001,"小明",25,10000.22);Supplier<String> supplier = new Supplier<String>() {@Overridepublic String get() {return employee.getName();}};System.out.println(supplier.get());// 使用Lambda表达式Supplier<String> supplier2 = () -> employee.getName();System.out.println(supplier2.get());// 使用方法引用Supplier<String> supplier3 = employee :: getName;System.out.println(supplier3.get());}// 情况二:类 :: 静态方法//Comparator中的int compare(T t1,T t2)// 静态方法//Integer中的int compare(T t1,T t2)@Testpublic void test3() {// (2) 类 :: 静态方法Comparator<Integer> comparator = new Comparator<Integer>() {@Overridepublic int compare(Integer t1, Integer t2) {return Integer.compare(t1,t2);}};System.out.println(comparator.compare(12, 31));// Lambda表达式Comparator<Integer> comparator2 = (t1,t2) -> Integer.compare(t1,t2);System.out.println(comparator2.compare(0, 0));// 使用 方法引用Comparator<Integer> comparator3 = Integer :: compare;System.out.println(comparator3.compare(12, 1));}//Function中的R apply(T t)//Math中的Long round(Double d)@Testpublic void test4() {Function<Double,Long> function = new Function<Double, Long>() {@Overridepublic Long apply(Double num) {return Math.round(num);}};System.out.println(function.apply(12.33));// Lambda表达式Function<Double,Long> function2 = num ->  Math.round(num);System.out.println(function2.apply(11.33));// 方法引用Function<Double,Long> function3 = Math :: round;System.out.println(function3.apply(10.33));}// 情况三:类 :: 实例方法  (有难度)// Comparator中的int comapre(T t1,T t2)// String中的int t1.compareTo(t2)@Testpublic void test5() {Comparator<String> comparator = new Comparator<String>() {@Overridepublic int compare(String t1, String t2) {return t1.compareTo(t2);}};System.out.println(comparator.compare("我喜欢", "我"));// Lambda表达式Comparator<String> comparator2 = (t1, t2) -> t1.compareTo(t2);System.out.println(comparator2.compare("我和你", "我和你"));// 方法引用Comparator<String> comparator3 = String :: compareTo;System.out.println(comparator3.compare("你", "我和你"));}//BiPredicate中的boolean test(T t1, T t2);//String中的boolean t1.equals(t2)@Testpublic void test6() {BiPredicate<String,String> biPredicate = new BiPredicate<String, String>() {@Overridepublic boolean test(String s1, String s2) {return s1.equals(s2);}};System.out.println(biPredicate.test("我", "你"));// Lambda表达式BiPredicate<String,String> biPredicate2 = (s1,s2) -> s1.equals(s2);System.out.println(biPredicate2.test("我", "我"));// 方法引用BiPredicate<String,String> biPredicate3 = String :: equals;System.out.println(biPredicate3.test("你", "我"));}// Function中的R apply(T t)// Employee中的String getName();@Testpublic void test7() {Employee employee = new Employee(1002,"小玉",25,200.06);Function<Employee,String> function = new Function<Employee, String>() {@Overridepublic String apply(Employee employee) {return employee.getName();}};System.out.println(function.apply(employee));// Lambda表达式employee = new Employee(1003,"小智",24,200.06);Function<Employee,String> function2 = employee2 -> employee2.getName();System.out.println(function2.apply(employee));// 方法引用employee = new Employee(1004,"小霞",21,210.06);Function<Employee,String> function3 = Employee :: getName;System.out.println(function3.apply(employee));}/*** Double 和 Long 的转换** @param* @return void* @date 2022/11/13 10:02* @author wty**/@Testpublic void change(){// Double >  LongDouble a = 12.33;Long b = a.longValue();System.out.println(b);// Long >  DoubleLong d = 17L;Double c = d.doubleValue();System.out.println(c);}
}

构造器引用

格式

类名::new

代码示例

ConstructorRefTest

package com.methodreference;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.抽象方法的返回值类型即为构造器所属的类的类型** @author wty* @date 2022/11/13 10:34*/
public class ConstructorRefTest {//构造器引用//Supplier中的T get()//Employee的空参构造器:Employee()@Testpublic void test() {Supplier<Employee> supplier = new Supplier<Employee>() {@Overridepublic Employee get() {return new Employee();}};System.out.println(supplier.get());// LambdaSupplier<Employee> supplier2 = () -> new Employee();System.out.println(supplier2.get());// 构造器引用Supplier<Employee> supplier3 = Employee :: new;System.out.println(supplier3.get());}//Function中的R apply(T t)@Testpublic void test2() {Function<Integer,Employee> function = new Function<Integer,Employee>() {@Overridepublic Employee apply(Integer t1) {return new Employee(t1);}};function.apply(1006);// LambdaFunction<Integer,Employee> function2 = t1 -> new Employee(t1);function2.apply(1007);// 构造器引用Function<Integer,Employee> function3 = Employee :: new;function3.apply(1008);}//BiFunction中的R apply(T t,U u)@Testpublic void test3() {BiFunction<Integer,String,Employee> biFunction = new BiFunction<Integer, String, Employee>() {@Overridepublic Employee apply(Integer integer, String s) {return new Employee(integer,s);}};biFunction.apply(1009,"小张");// LambdaBiFunction<Integer,String,Employee> biFunction2 = (integer,s) -> new Employee(integer,s);biFunction2.apply(1010,"小李");// 构造器引用BiFunction<Integer,String,Employee> biFunction3 = Employee :: new;biFunction3.apply(1011,"小刚");}
}

数组引用

格式

数组类型 [ ]::new

代码示例

package com.methodreference;import org.junit.Test;import java.sql.Array;
import java.util.function.Function;/*** 数组引用* * 可以把数组看成是一个特殊的类,和构造器引用保持一致即可** @author wty* @date 2022/11/13 11:07*/
public class ArrayRefTest {//数组引用//Function中的R apply(T t)@Testpublic void test4() {Function<Integer, String[]> function = new Function<Integer, String[]>() {@Overridepublic String[] apply(Integer integer) {return new String[integer];}};String[] array = function.apply(2);for (String s : array) {System.out.println(s);}System.out.println("=====Lambda=====");// LambdaFunction<Integer, String[]> function2 = integer -> new String[integer];String[] array2 = function2.apply(3);for (String s : array2) {System.out.println(s);}System.out.println("=====数组引用=====");// 数组引用Function<Integer, String[]> function3 = String[]:: new;String[] array3 = function3.apply(4);for (String s : array3) {System.out.println(s);}}
}

强大的Stream API

为什么要使用Stream API

什么是Stream

Stream 的操作三个步骤

创建 Stream

创建 Stream方式一:通过集合

创建 Stream方式二:由数组创建流

创建 Stream方式三:由值创建流

创建 Stream方式四:由函数创建流:创建无限流

代码示例

EmployeeData

package com.methodreference;import java.util.ArrayList;
import java.util.List;/*** @author wty* @date 2022/11/12 23:49*/
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.Stream;import com.methodreference.Employee;
import com.methodreference.EmployeeData;
import org.junit.Test;import java.io.PrintStream;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import java.util.stream.IntStream;
import java.util.stream.Stream;/*** Stream API** 1.Stream 关注的是数据的运算,与CPU打交道*       集合关注的是数据的存储,与内存打交道* 2.* Stream 自己不会存储元素* Stream 不会改变源对象,相反它们会返回一个持有结果的新Stream* Stream 操作时延迟执行的,这意味着它们会等到需要结果的时候才执行** 3.Stream 执行流程* Stream的实例化* 一系列的中间操作(过滤、映射、……)* 终止操作** 4.说明* 一个中间操作链,对数据源的数据进行处理* 一旦执行终止操作,就执行中间操作链,并产生结果,之后不再使用** @author wty* @date 2022/11/13 12:24*/
public class StreamAPITest {// 测试Stream实例化/*** 创建方式一; 通过集合* default Stream<E> stream() : 返回一个顺序流* default Stream<E> parallelStream() : 返回一个并行流*/@Testpublic void streamAPITest() {List<Employee> employees = EmployeeData.getEmployees();//default Stream<E> stream() : 返回一个顺序流Stream<Employee> stream = employees.stream();//default Stream<E> parallelStream() : 返回一个并行流Stream<Employee> parallelStream = employees.parallelStream();}/*** 创建方式二; 通过数组*/@Testpublic void streamAPITest02() {// 调用Arrays 的静态方法 stream() 可以获取数组流:/*** static <T> Stream<T> stream(T[] array): 返回一个流*/int array[] = new int[]{1,2,3,4,5};IntStream stream = Arrays.stream(array);Employee employee1 = new Employee(1012,"Jerry");Employee employee2 = new Employee(1013,"Timiy");Employee [] arr = new Employee[]{employee1,employee2};Stream<Employee> stream1 = Arrays.stream(arr);}/*** 创建方式三; 由值创建流*/@Testpublic void streamAPITest03() {/*** public static<T> Stream<T> of(T... values) : 返回一个流*/Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);}/*** 创建方式四; 创建无限流** 迭代** public static<T> Stream<T> iterate(final T seed, finalUnaryOperator<T> f)*/@Testpublic void streamAPITest04() {// 遍历前10个偶数Stream.iterate(0, new UnaryOperator<Integer>() {@Overridepublic Integer apply(Integer t) {return t + 2;}});// lambda表达式PrintStream ps = System.out;// limit(10) 中间操作// forEach(ps::println) 终止操作Stream.iterate(0,t -> t + 2).limit(10).forEach(ps::println);}/**** 生成* public static<T> Stream<T> generate(Supplier<T> s) :*/@Testpublic void streamAPITest05() {Employee employee = new Employee(1013,"小帽",22,10300.22);Stream.generate(new Supplier<String>() {@Overridepublic String get() {return employee.getName();}});// lambda表达式Stream.generate(() -> employee.getName());Stream.generate(new Supplier<Double>() {@Overridepublic Double get() {return Math.random();}});// lambda表达式Stream.generate(() -> Math.random());// 方法引用PrintStream ps = System.out;// limit(10) 中间操作// forEach(ps::println) 终止操作Stream.generate( Math::random).limit(10).forEach(ps::println);}}

中间操作

筛选与切片

package com.Stream;import com.methodreference.Employee;
import com.methodreference.EmployeeData;
import org.junit.Test;import java.io.PrintStream;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;/*** 测试Stream的中间操作** @author wty* @date 2022/11/13 22:33*/
public class StreamAPITest1 {private List<Employee> employees = EmployeeData.getEmployees();Stream<Employee> stream = employees.stream();/*** // 1.筛选与切片*/@Testpublic void test1(){/*** filter(Predicate p) 接收 Lambda,从流中排除某些元素。*///        stream.filter(new Predicate<Employee>() {//            @Override
//            public boolean test(Employee employee) {//                return employee.getSalary() > 7000;
//            }
//        });// 使用lambda表达式PrintStream ps = System.out;stream.filter(employee -> employee.getSalary() > 7000).forEach(ps::println);}@Testpublic void test2(){/*** limit(long maxSize) 截断流,使其元素不超过给定数量。** 截取表中前4条数据*/stream.limit(4).forEach(System.out::println);}@Testpublic void test3(){/*** skip(long n) 跳过元素,返回一个扔掉了前 n 个元素的流。* 若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补*/stream.skip(3).forEach(System.out::println);/*** 返回结果:跳过前3个,输出剩下的* Employee{id=1004, name='雷军', age=26, salary=7657.37}* Employee{id=1005, name='李彦宏', age=65, salary=5555.32}* Employee{id=1006, name='比尔盖茨', age=42, salary=9500.43}* Employee{id=1007, name='任正非', age=26, salary=4333.32}* Employee{id=1008, name='扎克伯格', age=35, salary=2500.32}*/stream.skip(30).forEach(System.out::println);/*** 返回空流,因为数据量不足30*/}@Testpublic void test4(){/*** distinct() 筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素*/employees.add(new Employee(1009, "刘强东", 40, 8000.99));employees.add(new Employee(1009, "刘强东", 40, 8000.99));employees.add(new Employee(1009, "刘强东", 40, 8000.99));for (Employee employee : employees) {System.out.println(employee);}System.out.println("=====distinct=====");stream.distinct().forEach(System.out::println);}
}

映射

package com.Stream;import com.methodreference.Employee;
import com.methodreference.EmployeeData;
import org.junit.Test;import java.io.PrintStream;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;/*** 映射** @author wty* @date 2022/11/13 23:00*/
public class StreamAPITest2 {/*** mapToDouble(ToDoubleFunction f) 接收一个函数作为参数,该函数会被应用到每个元* 素上,产生一个新的 DoubleStream。* mapToInt(ToIntFunction f) 接收一个函数作为参数,该函数会被应用到每个元* 素上,产生一个新的 IntStream。* mapToLong(ToLongFunction f) 接收一个函数作为参数,该函数会被应用到每个元* 素上,产生一个新的 LongStream。**/@Testpublic void test1(){/*** map(Function f) 接收一个函数作为参数,该函数会被应用到每个元*  素上,并将其映射成一个新的元素。*/List<String> list = Arrays.asList("aa", "bb", "cc", "dd");Stream<String> stream = list.stream();//        stream.map(new Function<String, String>() {//            @Override
//            public String apply(String s) {//                return s.toUpperCase();
//            }
//        });// Lambda表达式stream.map(s -> s.toUpperCase()).forEach(System.out::println);}@Testpublic void test2(){// 获取员工姓名长度大于3的员工的姓名List<Employee> employees = EmployeeData.getEmployees();Stream<Employee> stream = employees.stream();//        stream.filter(new Predicate<Employee>() {//            @Override
//            public boolean test(Employee employee) {//                return employee.getName().length() >3;
//            }
//        });// Lambda表达式
//        stream.filter(employee -> employee.getName().length() >3).map(new Function<Employee, String>() {//            @Override
//            public String apply(Employee employee) {//                return employee.getName();
//            }
//        }).forEach(System.out::println);// Lambda表达式 优化// 1.先过滤名字长度大于3的对象 2.再从对象中取出名字stream.filter(employee -> employee.getName().length() >3).map(employee -> employee.getName()).forEach(System.out::println);System.out.println("===============");// 2. 先从对象中取出名字 2.再过滤长度大于3的// 这里stream需要重新创建,因为上面终止语句执行后,就关闭了stream = employees.stream();stream.map(employee -> employee.getName()).filter(s -> s.length() > 3).forEach(System.out::println);}@Testpublic void test3(){/*** flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另*  一个流,然后把所有流连接成一个流*/List<String> list = Arrays.asList("aa", "bb", "cc", "dd");Stream<String> stream = list.stream();stream.map(new Function<String, Stream<Character>>() {@Overridepublic Stream<Character> apply(String s) {return fromStringToStream(s);}});// 使用lambda表达式stream = list.stream();stream.map(s -> fromStringToStream(s));// 使用方法引用stream = list.stream();Stream<Stream<Character>> streamStream = stream.map(StreamAPITest2::fromStringToStream);// 遍历看看streamStream里面有什么streamStream.forEach(new Consumer<Stream<Character>>() {@Overridepublic void accept(Stream<Character> characterStream) {PrintStream ps = System.out;characterStream.forEach(ps::println);}});System.out.println("Lambda表达式");// 写成Lambda表达式stream = list.stream();streamStream = stream.map(StreamAPITest2::fromStringToStream);streamStream.forEach(characterStream -> {{PrintStream ps = System.out;characterStream.forEach(ps::println);}});//flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另// 一个流,然后把所有流连接成一个流System.out.println("flatMap");stream = list.stream();Stream<Character> characterStream = stream.flatMap(StreamAPITest2::fromStringToStream);characterStream.forEach(System.out::println);}
/*** 把String中的多个字符构成的集合转换成对应的Stream实例** @param* @param: str* @return void* @date 2022/11/14 10:15* @author wty**/public static Stream<Character> fromStringToStream(String str){ArrayList<Character> list = new ArrayList<>();for (Character character : str.toCharArray()) {list.add(character);}return list.stream();}/*** 由addAll和add引出flatMap** @param* @return void* @date 2022/11/14 10:12* @author wty**/@Testpublic void test4(){ArrayList list1 = new ArrayList();list1.add(1);list1.add(2);list1.add(3);ArrayList list3 = new ArrayList();for (int i = 0; i < list1.size(); i++) {list3.add(i);}Collections.copy(list3,list1);System.out.println("list3:" +list3);ArrayList list2 = new ArrayList();list2.add(4);list2.add(5);list2.add(6);ArrayList list4 = new ArrayList();for (int i = 0; i < list2.size(); i++) {list4.add(i);}Collections.copy(list4,list2);list1.add(list2);for (Object o : list1) {System.out.println(o);}System.out.println("addAll");list3.addAll(list4);for (Object o : list3) {System.out.println(o);}}}

逐段分析

    @Testpublic void test1(){/*** map(Function f) 接收一个函数作为参数,该函数会被应用到每个元*  素上,并将其映射成一个新的元素。*/List<String> list = Arrays.asList("aa", "bb", "cc", "dd");Stream<String> stream = list.stream();//        stream.map(new Function<String, String>() {//            @Override
//            public String apply(String s) {//                return s.toUpperCase();
//            }
//        });// Lambda表达式stream.map(s -> s.toUpperCase()).forEach(System.out::println);}

输出结果

AA
BB
CC
DD
@Testpublic void test2(){// 获取员工姓名长度大于3的员工的姓名List<Employee> employees = EmployeeData.getEmployees();Stream<Employee> stream = employees.stream();//        stream.filter(new Predicate<Employee>() {//            @Override
//            public boolean test(Employee employee) {//                return employee.getName().length() >3;
//            }
//        });// Lambda表达式
//        stream.filter(employee -> employee.getName().length() >3).map(new Function<Employee, String>() {//            @Override
//            public String apply(Employee employee) {//                return employee.getName();
//            }
//        }).forEach(System.out::println);// Lambda表达式 优化// 1.先过滤名字长度大于3的对象 2.再从对象中取出名字stream.filter(employee -> employee.getName().length() >3).map(employee -> employee.getName()).forEach(System.out::println);System.out.println("===============");// 2. 先从对象中取出名字 2.再过滤长度大于3的// 这里stream需要重新创建,因为上面终止语句执行后,就关闭了stream = employees.stream();stream.map(employee -> employee.getName()).filter(s -> s.length() > 3).forEach(System.out::println);}

输出结果

比尔盖茨
扎克伯格
===============
比尔盖茨
扎克伯格
 @Testpublic void test3(){/*** flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另*  一个流,然后把所有流连接成一个流*/List<String> list = Arrays.asList("aa", "bb", "cc", "dd");Stream<String> stream = list.stream();stream.map(new Function<String, Stream<Character>>() {@Overridepublic Stream<Character> apply(String s) {return fromStringToStream(s);}});// 使用lambda表达式stream = list.stream();stream.map(s -> fromStringToStream(s));// 使用方法引用stream = list.stream();Stream<Stream<Character>> streamStream = stream.map(StreamAPITest2::fromStringToStream);// 遍历看看streamStream里面有什么streamStream.forEach(new Consumer<Stream<Character>>() {@Overridepublic void accept(Stream<Character> characterStream) {PrintStream ps = System.out;characterStream.forEach(ps::println);}});System.out.println("Lambda表达式");// 写成Lambda表达式stream = list.stream();streamStream = stream.map(StreamAPITest2::fromStringToStream);streamStream.forEach(characterStream -> {{PrintStream ps = System.out;characterStream.forEach(ps::println);}});//flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另// 一个流,然后把所有流连接成一个流System.out.println("flatMap");stream = list.stream();Stream<Character> characterStream = stream.flatMap(StreamAPITest2::fromStringToStream);characterStream.forEach(System.out::println);}

输出结果

a
a
b
b
c
c
d
d
Lambda表达式
a
a
b
b
c
c
d
d
flatMap
a
a
b
b
c
c
d
d
@Testpublic void test4(){ArrayList list1 = new ArrayList();list1.add(1);list1.add(2);list1.add(3);ArrayList list3 = new ArrayList();for (int i = 0; i < list1.size(); i++) {list3.add(i);}Collections.copy(list3,list1);System.out.println("list3:" +list3);ArrayList list2 = new ArrayList();list2.add(4);list2.add(5);list2.add(6);ArrayList list4 = new ArrayList();for (int i = 0; i < list2.size(); i++) {list4.add(i);}Collections.copy(list4,list2);list1.add(list2);for (Object o : list1) {System.out.println(o);}System.out.println("addAll");list3.addAll(list4);for (Object o : list3) {System.out.println(o);}}

输出结果

list3:[1, 2, 3]
1
2
3
[4, 5, 6]
addAll
1
2
3
4
5
6

排序

package com.Stream;import com.methodreference.Employee;
import com.methodreference.EmployeeData;
import org.junit.Test;import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;/*** 排序** @author wty* @date 2022/11/14 10:48*/
public class StreamAPITest3 {@Testpublic void test1(){/*** sorted() 产生一个新流,其中按自然顺序排序* sorted(Comparator comp) 产生一个新流,其中按比较器顺序排序*/List<Integer> list = Arrays.asList(0,-98,-3, 3, 12, 29, 33,1);Stream<Integer> stream = list.stream();Stream<Integer> sorted = stream.sorted();sorted.forEach(System.out::println);System.out.println("====EmployeeData====");
//        List<Employee> employees = EmployeeData.getEmployees();
//        employees.stream().sorted().forEach(System.out::println);/*** 返回结果:抛出异常,因为Employee没有实现Comparable接口** java.lang.ClassCastException: com.methodreference.Employee* cannot be cast to java.lang.Comparable*/// 引出定制排序}@Testpublic void test2(){// 工资由小到大排序List<Employee> employees = EmployeeData.getEmployees();employees.stream().sorted((e1,e2) -> Double.compare(e1.getSalary(),e2.getSalary())).forEach(System.out::println);}@Testpublic void test3(){// 年龄相同的时候,工资由小到大排序List<Employee> employees = EmployeeData.getEmployees();employees.stream().sorted((e1,e2) -> {int compare = Integer.compare(e1.getAge(), e2.getAge());if (compare != 0){return compare;}else {return Double.compare(e1.getSalary(),e2.getSalary());}}).forEach(System.out::println);}
}

终止操作(终端操作)

查找与匹配


package com.Stream;import com.methodreference.Employee;
import com.methodreference.EmployeeData;
import org.junit.Test;import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Stream;/*** 终止操作** 匹配与查找** @author wty* @date 2022/11/14 11:08*/
public class StreamAPI4 {@Testpublic void test1(){/*** allMatch(Predicate p) 检查是否匹配所有元素* anyMatch(Predicate p) 检查是否至少匹配一个元素* noneMatch(Predicate p) 检查是否没有匹配所有元素* findFirst() 返回第一个元素* findAny() 返回当前流中的任意元素*/// 是否所有的员工的年龄都大于18岁// allMatch(Predicate p) 检查是否匹配所有元素 所有都是true才返回trueList<Employee> employees = EmployeeData.getEmployees();employees.stream().allMatch(new Predicate<Employee>() {@Overridepublic boolean test(Employee employee) {return employee.getAge() > 18;}});// 使用Lambda表达式System.out.println("是否所有的员工的年龄都大于18岁");boolean b = employees.stream().allMatch(employee -> employee.getAge() > 18);System.out.println(b);//anyMatch(Predicate p) 检查是否至少匹配一个元素// 是否存在一个员工的工资大于9000System.out.println("是否存在一个员工的工资大于9000");boolean b1 = employees.stream().anyMatch(employee -> employee.getSalary() > 9000);System.out.println(b1);// 是否存在员工姓"雷"//noneMatch(Predicate p) 检查是否没有匹配所有元素System.out.println("员工是否都姓雷");boolean b3 = employees.stream().noneMatch(employee -> employee.getName().startsWith("雷"));System.out.println(b3);//findFirst() 返回id最大的第一个元素System.out.println("=====findFirst() 返回id最大的第一个元素=====");Optional<Employee> first = employees.stream().sorted((e1,e2) -> -Integer.compare(e1.getId(),e2.getId())).findFirst();System.out.println(first);// findAny() 返回当前流中的任意元素System.out.println("=====findAny() 返回任意一个元素=====");// 这里用并行流而不是串行流for (int i = 1; i <= 1000 ; i++) {Optional<Employee> any = employees.parallelStream().findAny();System.out.println(any);}}/*** 匹配与查找*/@Testpublic void test2(){/*** count() 返回流中元素总数* max(Comparator c) 返回流中最大值* min(Comparator c) 返回流中最小值* forEach(Consumer c) 内部迭代(使用 Collection 接口需要用户去做迭* 代,称为外部迭代。相反,Stream API 使用内部* 迭代——它帮你把迭代做了)*/List<Employee> employees = EmployeeData.getEmployees();// count() 返回流中元素总数long count = employees.stream().count();System.out.println(count);// max(Comparator c) 返回流中最大值 返回最高工资System.out.println("=====返回最高工资 方法一=====");Optional<Employee> max = employees.stream().max((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));System.out.println(max);System.out.println("=====返回最高工资 方法二=====");// 先把对象转换成工资取出来Stream<Double> doubleStream = employees.stream().map(employee -> employee.getSalary());Optional<Double> max1 = doubleStream.max((sal1, sal2) -> Double.compare(sal1, sal2));System.out.println(max1);System.out.println("=====返回最高工资 方法三=====");// 先把对象转换成工资取出来Stream<Double> doubleStream1 = employees.stream().map(employee -> employee.getSalary());Optional<Double> max2 = doubleStream1.max(Double::compare);System.out.println(max2);//min(Comparator c) 返回流中最小值 返回最低工资System.out.println("=====返回最低工资的员工名 方法一=====");Optional<Employee> min = employees.stream().min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));System.out.println(min);System.out.println("=====返回最低工资 方法一=====");Optional<Double> min1 = employees.stream().map(employee -> employee.getSalary()).min((d1, d2) -> Double.compare(d1, d2));System.out.println(min1);System.out.println("=====返回最低工资 方法二=====");Optional<Double> min2 = employees.stream().map(employee -> employee.getSalary()).min(Double::compare);System.out.println(min2);// forEach(Consumer c) 内部迭代(使用 Collection 接口需要用户去做迭System.out.println("=====forEach(Consumer c) 内部迭代=====");employees.stream().forEach(System.out::println);// 使用集合的遍历操作System.out.println("=====集合的遍历操作=====");employees.forEach(System.out::println);}
}

归约

package com.Stream;import com.methodreference.Employee;
import com.methodreference.EmployeeData;
import org.junit.Test;import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.BinaryOperator;
import java.util.stream.Stream;/*** 规约** @author wty* @date 2022/11/14 11:56*/
public class StreamAPITest5 {@Testpublic void test1(){/*** reduce(T iden, BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。* 返回 T* reduce(BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。* 返回 Optional<T>* 备注:map 和 reduce 的连接通常称为map-reduce 模式,因 Google 用它* 来进行网络搜索而出名。*/// reduce(T iden, BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。// 返回 T// 计算自然数1-10的合List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);list.stream().reduce(new BinaryOperator<Integer>() {@Overridepublic Integer apply(Integer t1, Integer t2) {return t1+t2;}});// 使用Lambda表达式 方式一Optional<Integer> reduce = list.stream().reduce((t1, t2) -> t1 + t2);System.out.println(reduce);// 使用Interger.sum 方式二list.stream().reduce(new BinaryOperator<Integer>() {@Overridepublic Integer apply(Integer t1, Integer t2) {return Integer.sum(t1,t2);}});// 使用Interger.sum 方式二 使用Lambda表达式System.out.println("=====使用Interger.sum 方式二 使用Lambda表达式=====");Optional<Integer> reduce1 = list.stream().reduce((t1, t2) -> Integer.sum(t1, t2));System.out.println(reduce1);// 使用Interger.sum 方式二 使用方法引用System.out.println("=====使用Interger.sum 方式二 使用方法引用=====");Optional<Integer> reduce2 = list.stream().reduce(Integer::sum);System.out.println(reduce2);//使用reduce(T var1, BinaryOperator<T> var2);System.out.println("使用reduce(T var1, BinaryOperator<T> var2)");Integer reduce3 = list.stream().reduce(0, (t1, t2) -> Integer.sum(t1, t2));System.out.println(reduce3);//使用reduce(T var1, BinaryOperator<T> var2);方法引用System.out.println("使用reduce(T var1, BinaryOperator<T> var2)方法引用");Integer reduce4 = list.stream().reduce(0, Integer::sum);System.out.println(reduce4);}@Testpublic void test2(){/**reduce(BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。* 返回 Optional<T>*/// 计算公司所有员工工资的总和 方法一List<Employee> employees = EmployeeData.getEmployees();Stream<Double> doubleStream = employees.stream().map(employee -> employee.getSalary());Double reduce = doubleStream.reduce(0.00, (sal, sal2) -> Double.sum(sal, sal2));System.out.println(reduce);// 计算公司所有员工工资的总和 方法二System.out.println("=====计算公司所有员工工资的总和 方法二=====");doubleStream = employees.stream().map(Employee::getSalary);Double reduce2 = doubleStream.reduce(0.00, Double::sum);System.out.println(reduce2);}
}

收集



package com.Stream;import com.methodreference.Employee;
import com.methodreference.EmployeeData;
import org.junit.Test;import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Collectors;/*** 收集** @author wty* @date 2022/11/14 15:28*/
public class StreamAPITest6 {@Testpublic void test1(){/*** collect(Collector c) 将流转换为其他形式。接收一个 Collector接口的* 实现,用于给Stream中元素做汇总的方法*/// 查找工资大于6000的员工,返回一个list或者setList<Employee> employees = EmployeeData.getEmployees();// 先筛选后组装成ListList<Employee> collect = employees.stream().filter(employee -> employee.getSalary() > 6000).collect(Collectors.toList());for (Employee employee : collect) {System.out.println(employee);}System.out.println("=======组装成Set=====");// 先筛选后组装成SetSet<Employee> collect1 = employees.stream().filter(employee -> employee.getSalary() > 6000).collect(Collectors.toSet());for (Employee employee : collect1) {System.out.println(employee);}System.out.println("=======toCollection=====");Collector<Employee, ?, ArrayList<Employee>> collector = Collectors.toCollection(ArrayList::new);employees.stream().filter(employee -> employee.getSalary() > 6000).collect(collector).forEach(System.out::println);}
}

Optional类

package com.optional;import org.junit.Test;import java.util.Optional;/*** Optional类:为了在程序中避免出现空指针异常而创建的** 常用的方法;*s*          * Optional.of(T t) : 创建一个 Optional 实例*          * Optional.empty() : 创建一个空的 Optional 实例*          * Optional.ofNullable(T t):若 t 不为 null,创建 Optional 实例,否则创建空实例*          * isPresent() : 判断是否包含值*          * orElse(T t) : 如果调用对象包含值,返回该值,否则返回t*          * orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回 s 获取的值*          * map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()*          * flatMap(Function mapper):与 map 类似,要求返回值必须是Optiona* @author wty* @date 2022/11/14 15:44*/
public class OPtionalEx {@Testpublic void test1(){/*** Optional.of(T t) : 创建一个 Optional 实例 必须保证t是非空的*/Girl girl = new Girl();Optional<Girl> girl1 = Optional.of(girl);}@Testpublic void test2(){/*** Optional.ofNullable(T t):若 t 不为 null,创建 Optional 实例,否则创建空实例*/Girl girl = new Girl();girl = null;Optional<Girl> girl1 = Optional.ofNullable(girl);System.out.println(girl1);//对象.orElse(T t) : 如果调用对象包含值,返回该值,否则返回tGirl girl2 = girl1.orElse(new Girl("赵丽颖"));System.out.println(girl2);}/*** 空指针异常示例*/@Testpublic void test3(){Boy boy = new Boy();String girlName = getGirlName(boy);System.out.println(girlName);/*** 结果* java.lang.NullPointerException*/}public String getGirlName(Boy boy){return boy.getGirl().getName();}/*** 优化后,去掉空指针异常*/@Testpublic void test4(){Boy boy = new Boy();String girlName = getGirlNameUpdate(boy);System.out.println(girlName);}public String getGirlNameUpdate(Boy boy){if (boy != null){Girl girl = boy.getGirl();if (null != girl){return girl.getName();}}return null;}/*** 使用Optional杜绝空指针异常*/@Testpublic void test5(){Boy boy = null;String girlNameUpdateOptional = getGirlNameUpdateOptional(boy);System.out.println(girlNameUpdateOptional);System.out.println("==========");boy = new Boy();girlNameUpdateOptional = getGirlNameUpdateOptional(boy);System.out.println(girlNameUpdateOptional);System.out.println("==========");Boy boy1 = new Boy(new Girl("钟楚曦"));girlNameUpdateOptional = getGirlNameUpdateOptional(boy1);System.out.println(girlNameUpdateOptional);}public String getGirlNameUpdateOptional(Boy boy){Optional<Boy> boyOptional = Optional.ofNullable(boy);// 此时boy1一定非空Boy boy1 = boyOptional.orElse(new Boy(new Girl("迪丽热巴")));Girl girl = boy1.getGirl();Optional<Girl> girl1 = Optional.ofNullable(girl);// 此时girl2一定非空Girl girl2 = girl1.orElse(new Girl("古力娜扎"));return girl2.getName();}@Testpublic void test6(){// Optional.empty() : 创建一个空的 Optional 实例Optional<Object> empty = Optional.empty();// isPresent() : 判断是否包含值对象,不包含对象返回 false,包含对象返回trueif (empty.isPresent()) {System.out.println("包含对象");}else {System.out.println("不包含对象");}//System.out.println(empty.get());System.out.println(empty);/*** 输出结果;*不包含对象* Optional.empty*/}@Testpublic void test7(){String str = "hello";str = null;Optional<String> str1 = Optional.of(str);// str1 是null 调用get会报异常// get()方法通常与of()方法搭配使用String s = str1.get();System.out.println(s);/*** 抛出异常* java.lang.NullPointerException*/}
}

JDK8中的日期时间

新日期时间API的出现背景


新日期时间API

LocalDate、LocalTime、LocalDateTime


package com.date;import org.junit.Test;import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;/*** @author wty* @date 2022/11/14 23:03*/
public class JDK8DateTimeTest {/*** LocalDate、LocalTime、LocalDateTime*/@Testpublic void test1(){// LocalDateTime 使用的频率较高// now()获取当前时间LocalDate localDate = LocalDate.now();LocalTime localTime = LocalTime.now();LocalDateTime localDateTime = LocalDateTime.now();System.out.println(localDate);System.out.println(localTime);System.out.println(localDateTime);/*** 输出结果* 2022-11-14* 23:07:17.720* 2022-11-14T23:07:17.720*/// of() 设置指定的年月日时分秒 没有偏移量LocalDateTime localDateTime1 = LocalDateTime.of(2022, 11, 14, 23, 9, 33);System.out.println(localDateTime1);// getXXX()获取System.out.println("========getXXX()=======");// 获取当月的第几天System.out.println("获取当月的第几天\t"+localDateTime.getDayOfMonth());// 获取本周的第几天System.out.println("获取本周的第几天\t"+localDateTime.getDayOfWeek());// 获取月System.out.println("获取月\t"+localDateTime.getMonth());// 获取月份的阿拉伯数字System.out.println("获取月份的阿拉伯数字\t"+localDateTime.getMonthValue());// 获取分钟System.out.println("获取分钟\t"+localDateTime.getMinute());// withXXX()设置时间// 设置时间 把日期更改成22日 体现了不可变性LocalDate localDate2 = localDate.withDayOfMonth(22);System.out.println("localDate:" +localDate+"\tlocalDate2:"+localDate2);// 设置时间 把小时更改为0LocalTime localTime1 = localTime.withHour(0);System.out.println("localTime:" +localTime+"\tlocalTime1:"+localTime1);//plus()时间的加 加三个月LocalDateTime localDateTime2 = localDateTime.plusMonths(3);System.out.println("localDateTime:" +localDateTime+"\tlocalDateTime1:"+localDateTime2);// minus 减6天LocalDateTime localDateTime3 = localDateTime.minusDays(6);System.out.println("localDateTime:" +localDateTime+"\tlocalDateTime3:"+localDateTime3);// }
}

Instant

Instant API


package com.date;import org.junit.Test;import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;/*** Instant 时间点,瞬时点* 类似于java.util.Date类** @author wty* @date 2022/11/14 23:26*/
public class InstanceExercise {@Testpublic void test(){// now() 本初子午线对应的标准时间Instant instant = Instant.now();System.out.println(instant);/**结果;* 2022-11-14T15:41:50.412Z* 早了8小时,是格林威治时间*/// 根据对应的时区添加时间偏移量OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));System.out.println(offsetDateTime);// 获取瞬时点,距离1970年1月1日0时0分0秒对应毫秒数long l = instant.toEpochMilli();System.out.println("毫秒数"+l);// 通过给定毫秒数,获取对应时间 -->Date 类的getTime()Instant instant1 = Instant.ofEpochMilli(l);System.out.println("毫秒数对应的时间是:"+instant1);}
}

格式化与解析日期或时间

package com.date;import org.junit.Test;import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.time.temporal.TemporalAccessor;/*** DateTimeFormatter 格式化日期和时间** 类似于SimpleDateFormat** @author wty* @date 2022/11/14 23:51*/
public class Format {@Testpublic void test(){// 方式一:DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;// 格式化 日期 -> 字符串LocalDateTime now = LocalDateTime.now();String format = formatter.format(now);System.out.println("LocalDateTime:"+now+"\nDateTimeFormatter.ISO_LOCAL_DATE_TIME:" + format);// 解析  字符串 -> 日期TemporalAccessor parse = formatter.parse("2022-11-14T23:56:31.433");System.out.println("parse"+parse);// 方式二: ofLocalizedDateTime() 本地化相关格式// FormatStyle.LONG// FormatStyle.MEDIUM// FormatStyle.SHORTDateTimeFormatter formatter1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);String format1 = formatter1.format(now);System.out.println("format1\t" + format1);/*** 输出结果:* 2022年11月15日 上午12时02分04秒*/// 解析TemporalAccessor parse1 = formatter1.parse("2022年11月15日 上午12时03分59秒");System.out.println("parse1" + parse1);DateTimeFormatter formatter2 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);String format2 = formatter2.format(now);System.out.println("format2 "+format2);/**输出结果:* 2022-11-15 0:03:20*/DateTimeFormatter formatter3 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);String format3 = formatter3.format(now);System.out.println("format3 "+format3);/***22-11-15 上午12:03*/// FormatStyle.FULL// FormatStyle.FULL// FormatStyle.FULL// FormatStyle.FULLLocalDate localDate = LocalDate.now();DateTimeFormatter formatter4 = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);String format4 = formatter4.format(localDate);System.out.println("format4 "+format4);/*** 2022年11月15日 星期二*/DateTimeFormatter formatter5 = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG);String format5 = formatter5.format(localDate);System.out.println("format5 " + format5);/*** 2022年11月15日*/DateTimeFormatter formatter6 = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);String format6 = formatter6.format(localDate);System.out.println("format6 " + format6);/*** 2022-11-15*/DateTimeFormatter formatter7 = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT);String format7 = formatter7.format(localDate);System.out.println("format7:" + format7);/*** 22-11-15*/// 方式三:自定义格式LocalDateTime localDateTime = LocalDateTime.now();DateTimeFormatter formatter8 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");String format8 = formatter8.format(localDateTime);System.out.println("format8 " + format8);/*** 2022-11-15 12:12:22*/// 解析TemporalAccessor parse2 = formatter8.parse("2022-11-15 00:12:49");System.out.println("parse2 "+parse2);}
}

时间日期其它API

与传统日期的转换

Java 8 新特性 宋红康跟学相关推荐

  1. 尚硅谷 宋红康老师 Java视频全程课程目录

    尚硅谷 Java 语言全程课程目录, 尚硅谷 Java&大数据研究院 宋红康 B站视频链接 已看完,感谢宋红康老师! [视频很长,但看完你一定会收获很多] 30天课程目录 Java 编程基础部 ...

  2. java 技术训练营 宋红康老师、 佟刚老师 金牌讲师课件分享

    宋红康老师. 佟刚老师 金牌讲师课件分享 宋红康:先后担任过高级软件开发工程师,系统架构师,高级讲师.具备丰富的软件开发经验和教学经验.精通C/C++.JAVA.Objective-C 等开发语言, ...

  3. JVM宋红康(二): JVM与Java体系结构

    1.Java高级语言 2.JVM:跨语言的平台 作为一个平台,Java虚拟机扮演着举足轻重的作用.Groovy.Scala.JRuby.Kotlin等都是Java平台的一部分 作为灯种文化,Java几 ...

  4. MySQL数据库教程天花板,mysql安装到mysql高级,强|硬 宋红康版

    MySQL数据库教程天花板,mysql安装到mysql高级,强|硬 宋红康版(自用不可外传) 文章目录 MySQL数据库笔记 第一部分 MySQL基础篇 第01章 数据库概述 1. 为什么要使用数据库 ...

  5. java新版本新特性

    2. Java8新特性:Lambda表达式 2.1 关于Java8新特性简介 Java 8 (又称为 JDK 8或JDK1.8) 是 Java 语言开发的一个主要版本. Java 8 是oracle公 ...

  6. 尚硅谷 宋红康 JVM教程_01_内存与垃圾回收篇——02

    本系列相关链接 尚硅谷 宋红康 JVM教程_01_内存与垃圾回收篇--01 (20210103-20210110) https://blog.csdn.net/wei198621/article/de ...

  7. JVM从入门到精通(尚硅谷宋红康)

    不动笔墨不读书,先把书读厚,再把书读薄是我学习方式. 所以等理解了再整理一次笔记,目前笔记和视频一一对应. 笔记连载中 <尚硅谷2020最新版宋红康JVM> 第1章:JVM与Java体系结 ...

  8. 尚硅谷 宋红康 JVM教程_02_字节码与类的加载篇

    本系列相关链接 尚硅谷 宋红康 JVM教程_01_内存与垃圾回收篇--01 (20210103-20210110) https://blog.csdn.net/wei198621/article/de ...

  9. JVM学习笔记汇总:结合尚硅谷宋红康老师视频教程及PPT

    JVM学习笔记汇总:结合尚硅谷宋红康老师视频教程及PPT 第一章:JVM虚拟机的介绍 1.1虚拟机的分类 虚拟机通常分为两类:系统虚拟机和程序虚机.其中,系统虚拟机是指完全对物理计算机的仿真,而程序虚 ...

最新文章

  1. 移动端网站页面优化的关键点
  2. PyQt5 技术篇-鼠标移动控件显示提示,Qt Designer控件提示设置方法。
  3. Effective C++: 06继承与面向对象设计
  4. Lucene搜索引擎
  5. 5G NR协议栈----总体架构
  6. 123. 买卖股票的zui佳时机 III(JavaScript)
  7. python与java区别-Java与Python到底有什么区别和共同点详细对比
  8. 【数控雕刻】【刀具路径】北京精雕JDPaint5.19+诺诚NC转换器4.0+SDU NCEdit1.0(什么是ENG和NC文件)
  9. Protel99SE教程(一)——原理图封装
  10. java简单幸运抽奖系统_java实现幸运抽奖系统
  11. python执行excel公式 语法_Python读取excel文件中带公式的值的实现
  12. windows下的_vimrc设置
  13. html base64在线解码,HTML5原生支持Base64编码解码
  14. Android性能优化系列之App启动优化
  15. 3dmax运动混合器的使用
  16. 攻防世界mfw_攻防世界-Web-mfw
  17. 用java语言编写选课系统_求用JAVA为我写一个简单的选课系统程序,实现增,删,改,查功能...
  18. Docker——使用docker工具管理软件/组件的运行,镜像、容器、数据卷的基本概念,常用指令,使用docker搭建Java微服务运行环境
  19. VUE 获奖名单滚动显示的两种方式
  20. 服务器光驱坏了怎么虚拟化,光驱坏了或者没有光驱怎么装系统?

热门文章

  1. iNavFlight之MSP v2 Sensor报文格式
  2. Vibosoft ePub Converter(ePub转换器)v2.1.24官方版
  3. 由于应用程序的配置不正确,应用程序未能启动,重新安装应用程序可能会纠正这个问题
  4. 怎样解决spoolsv.exe应用程序错误
  5. 质因数知识以及相关代码(C语言)
  6. 数据库-jdbc、spring-jdbc、spring-boot-starter-jdbc
  7. 果园大二下英方课学习姿势
  8. Topk实现(C++)
  9. DS-5 csat简单使用-dump memory
  10. 利用pyechart绘制简单的迁徙流向图、世界地图