一、JDK 8新性现介绍
接口中默认方法+静态方法 − 默认方法就是一个在接口里面有了一个实现的方法。静态方法就是接口中有个已经使用的静态方法,可直接调用
Lambda 表达式(拉姆达) − Lambda 允许把函数作为一个方法的参数(函数作为参数传递到方法中)。
方法引用 (Method Reference)− 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
// 方法引用的代码 System.out.println() —> System::println();
Stream API −新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。
Optional 类 − Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。
Date Time API − 加强对日期与时间的处理。
二、接口新特性
JDK8以后,运行接口中有被default和static修饰的方法带方法体
package com.qfFirst.qf0306.haveClass;
/**
* @escription:
* @author:等,一起
* @data:
* 接口新特性
*/
public interface NewInterface {
void m1();
// 允许有default修饰的方法带方法体
default void m2(){
System.out.println("m2");
}
/**
* 因为接口中的抽象方法必须要重写!
* 加了default的方法,有方法体,那就不是抽象方法
* 那就不要求重写
* ----------------------
* 好处就是,在项目开发中,对已有的项目进行扩展时,比较优雅
* 即,给接口设计了default修饰的方法后,所有子实现类并没有强制重写
* 这样,就可以有选择对某个子实现类中重写该方法
* 另一个好处: 类似于抽象类,带default修饰的方法,子类不重写,子类对象
* 可以直接调用使用
*/
// 允许有static修饰的方法带方法体
// 子类不能重写
static void m3(){
System.out.println("m3");
}
/**
* 接口中设计方法带static,方法就可以有方法体
* 但是子类不能重写!!
* 但是可以通过接口名之间调用执行: Demo1.m3()
* 子实现类不能调用!
*/
}
class NewInterfaceImpl implements NewInterface{
@Override
public void m1() {
System.out.println("m1");
}
// @Override
// public void m2() {
// System.out.println("m2");
// }
}
class Test {
public static void main(String[] args) {
NewInterface newInterface = new NewInterfaceImpl();
newInterface.m2();
// 接口名字直接调用
NewInterface.m3();
}
}
三、Lambda表达式[重要]
Lambda 允许把函数(方法)作为一个方法的参数(函数作为参数传递到方法中)。
其实就是简化了匿名内部类的写法
3.1 初识Lambda
package com.qfFirst.qf0306.haveClass;
public class Demo1 {
public static void main(String[] args) {
// 之前用匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("匿名内部类开启线程");
}
}).start();
// 使用Lambda改写
new Thread(() -> System.out.println("Lambda开启线程")).start();
// lambda基本结构是
// () -> 语句
// 参数列表,箭头符号,执行语句
}
}
3.2 语法特点
能够使用lambda的前提是
方法得有参数
参数的必须是接口
接口中的方法有且只能有一个!!!
lambda就是对接口的抽象方法重写new Thread(Runable run) Thread构造方法有参数
参数Runnable是接口
且Runnable接口内只有一个方法run语法特征
(参数) -> {执行语句} 或者 参数 -> 执行语句
参数圆括号,当参数是一个的时候,圆括号可加可不加
(x) -> System.out.println(x)
x -> System.out.println(x)
参数圆括号,当参数是多个的时候,圆括号必须加
(x,y) -> System.out.println(x+y)
参数数据类型可写可不写,编译时会自动推断是什么类型
(x,y) -> System.out.println(x)
(int x,String y) -> System.out.println(x+y)
执行语句的花括号,当且仅当执行语句只有一句时,可以不加花括号
new Thread(() -> System.out.println(“匿名内部类开启线程”)).start();
执行语句的花括号,当执行语句不只一句时,必须加花括号
new Thread(() -> { int a = 1; a++; System.out.println(“lambda开启线程” ); }).start();
关于返回值
如果方法有返回值,且执行语句只有一行语句时,可以不用写return,直接写值
test(() -> 1); test(() -> return 1);
如果代码比较多,又要返回数据,就必须写上return
test(() -> { int a = 1; a++; return a; })
3.3 无参无返回值的lambda
lambda就是匿名内部类的简化.
package com.qfFirst.qf0306.haveClass;
public class TestLambda {
/** lambda是简化了匿名内部类
* lambda其实是对接口中方法的重写
*
* lambda运行的前提条件
* 1.方法有参数 2.方法是接口 3.接口中有且仅有一个方法
*/
public static void main(String[] args) {
// 演示无参无返回值的lambda方法
test1(() -> System.out.println("lambda重写m1()"));
public static void test1(M1 m1) {
m1.test1();
}
}
interface M1 {
void test1();
}
interface M2 {
void test2(int a);
}
3.4 有参数无返回值
public class TestLambda {
public static void main(String[] args) {
// 有参无返回值
test2(x ->{
x *= 10;
System.out.println(x);
});
}
public static void test2(M2 m2) {
m2.test2(1);
}
}
interface M2 {
void test2(int a);
}
3.5 无参有返回值
public class TestLambda {
public static void main(String[] args) {
// 无参有返回值
test3(() -> 1);
}
public static void test3(M3 m3) {
System.out.println("lambda无参有返回值返回 -" + m3.testM3());
}
}
interface M3 {
int testM3();
}
3.6 有参有返回值
设计一个方法m4,方法的参数列表是接口
该接口中有1个抽象方法,能接收两个int类型参数,返回值是String
要求,给m4方法传入lambda表达式,功能是将传入的两个参数拼接为String后返回
public class Demo5TestLambda {
/**
* 设计一个方法m4,方法的参数列表是接口
* 该接口中有1个抽象方法,能接收两个int类型参数,返回值是String
* 要求,给m4方法传入lambda表达式,功能是将传入的两个参数拼接为String后返回
*/
public static void main(String[] args) {
m4(10,20,(x,y) ->x+""+y);
}
public static void m4(int a,int b,M4 m4) {
String str = m4.test4(a,b);
System.out.println(str );
}
}
interface M4{
String test4(int a,int b);
}
3.7 练习
ArrayList 集合中的元素使用 Collections 工具类进行排序.
Collections.sort(list,compartor) 其中可以指定一个比较器,进行自定义排序
用lambda
package com.qf.jdk.lambda;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
public class Demo6TestLambda {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>( );
list.add(5);
list.add(5);
list.add(3);
list.add(2);
list.add(1);
list.add(4);
for (Integer integer : list) {
System.out.println(integer );
}
System.out.println("------" );
// 集合工具类,sort()方法,默认对集合中元素进行升序
// Collections.sort(list);
//
// for (Integer integer : list) {
// System.out.println(integer );
// }
// 重载的方法,可以传入一个比较器,进行自定义排序
// 使用lambda 完成对list降序排序
/**
* 1 方法有参数
* 2 参数是接口
* 3 接口只有一个抽象方法
* ---------------
* lambda就是对接口的抽象方法重写
*/
Collections.sort(list,(x,y) -> y-x);
for (Integer integer : list) {
System.out.println(integer );
}
}
}
TreeSet(Comparator c)创建TreeSet时也可以指定一个Comparator接口的实现类对象,指定排序规则,就可以使用Lambda改写
3.8 总结
lambda就是简化了匿名内部类的写法
lambda其实就是接口方法的重写
lambda的参数和返回值是根据接口方法决定的
四、函数式接口
==接口中只有一个抽象方法时,该接口就是函数式接口==.
为什么叫做函数式接口?因为这种接口,放在方法中当参数时,可以改造成lambda,进行运算.Java提供了一个注解可以校验接口是否是函数式接口
@FunctionalInterfaceJava中提供了几个特别常用的函数式接口
Supplier 供应,即返回一个数据 (无参有返回值的方法)
Consumer 消费,即给其传入数据做运算 (有参无返回值的方法)
Function 函数,传入2个参数,用于转换数据的 (有参有返回值的方法)
Predicate 判断,返回时boolean (有参,返回值是boolean)
4.1 Supplier
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
// 该接口用来返回一个数据,所以叫供应商
// 其实就是无参数有返回值的接口,用的时候就是无参有返回值的lambda
练习,设计方法,通过Supplier接口,获得字符串的长度
public class TestSupplier {
public static void main(String[] args) {
teat1(() -> "java".length());
teat2(() -> {
int[] arr = {1,2,3,4,5};
Random random = new Random();
int i = random.nextInt(arr.length);
int i1 = arr[i];
return i1;
});
}
// test1获得字符串长度
public static void teat1(Supplier<Integer> supplier) {
Integer lenth = supplier.get();
System.out.println("长度:" + lenth);
}
// test2 获得数组中随机的一个数字
public static void teat2(Supplier<Integer> supplier) {
Integer e = supplier.get();
System.out.println("数组中随机的元素:" + e);
}
}
4.2 Consumer
@FunctionalInterface
public interface Consumer<T> {
/**
* Performs this operation on the given argument.
* 给传入一个值,对该值进行操作
* @param t the input argument
*/
void accept(T t);
}
// 其实就是有参数无返回值的接口,用的时候就是有参无返回值的lambda
练习:设计方法,传入字符串,将字符串全部转大写,后输出
package com.qfFirst.qf0306.haveClass;
import java.util.Locale;
import java.util.function.Consumer;
public class TestConsumer {
public static void main(String[] args) {
// 对传入字符串变大写后输出
test("java",s -> System.out.println(s.toUpperCase()));
}
// test方法消费一个字符串
// test方法可以接受一个字符串,然后对其操作
public static void test(String str, Consumer<String> consumer){
consumer.accept(str);
}
}
4.3 Function
@FunctionalInterface
public interface Function<T, R> {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
}
// 该接口用于,转换数据
// 其实就是有参数有返回值的接口,用的时候就是有参有返回值的lambda
练习,设计方法,将传入的字符串数字,转为整形数字
package com.qfFirst.qf0306.haveClass;
import java.util.function.Function;
public class TestFunction {
public static void main(String[] args) {
// 传入字符串,解析为数字后返回
test("111",i -> Integer.parseInt(i));
}
// 传入字符串,返回一个数字
public static void test(String target, Function<String,Integer> function) {
Integer r = function.apply(target);
System.out.println(r);
}
}
4.4 Predicate
@FunctionalInterface
public interface Predicate<T> {
/**
* Evaluates this predicate on the given argument.
*
* @param t the input argument
* @return {@code true} if the input argument matches the predicate,
* otherwise {@code false}
*/
boolean test(T t);
}
// 用于判断数据
// 其实就是有参数有返回值为boolean的接口,用的时候就是有参有返回值为boolean的lambda
设计方法,判断数据
package com.qfFirst.qf0306.haveClass;
import java.util.function.Predicate;
public class TestPredicate {
public static void main(String[] args) {
// 判断名字是否过长
test("迪丽热巴",s -> s.length() > 3);
}
public static void test(String t, Predicate<String> predicate) {
boolean test = predicate.test(t);
System.out.println(test);
}
}
五、Stream流
Stream流,不要和之前学的IO流进行联想,他们之间没有关系.
IO流,数据像水流一样在传输
Stream流,数据像车间流水线,在一直往下走动,不是保存数据,也不纯粹的传输数据,而是像车间流水线一样,在==处理数据==.
Stream流可以让我们更快的处理数据.
分别演示之前处理数据,和使用Stream流来处理数据
package com.qfFirst.qf0306.haveClass;
import java.util.ArrayList;
public class TestStream {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("暗影龙");
list.add("星界龙");
list.add("金龙");
list.add("土龙");
list.add("赏金");
list.add("海盗");
// 1.名字长度大于2
// 2.名字里面含有“龙”
for (String s:list) {
if (s.length() > 2) {
if (s.contains("龙")) {
System.out.println(s);
}
}
}
// 使用stream流
list.stream()
.filter(e -> e.length() > 2)
.filter(e -> e.contains("龙"))
.forEach(e -> System.out.println(e));
}
}
要操作Stream流操作数据,需要3步:
获得流
处理流
收集流
5.1 获得流
Java提供了几种方式,可以让我们获得Stream流
[集合创建流]Collection 接口的 stream()或 parallelStream()方法
[自由值创建]静态的 Stream.of()、Stream.empty()方法
[数组创建流]Arrays.stream(array)
静态的 Stream.generate()方法生成无限流,接受一个不包含引元的函数
静态的 Stream.iterate()方法生成无限流,接受一个种子值以及一个迭代函数
Pattern 接口的 splitAsStream(input)方法
静态的 Files.lines(path)、Files.lines(path, charSet)方法
静态的 Stream.concat()方法将两个流连接起来
package com.qf.jdk.stream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Stream;
public class Demo2 {
public static void main(String[] args) {
// 现有集合如下
ArrayList<String> list = new ArrayList<>( );
list.add("迪丽热巴-甲龙");
list.add("马尔扎哈-鹏龙");
list.add("杨顺博");
list.add("刘路");
list.add("古力娜扎-王莹莹");
// 1 通过集合获得流
Stream<String> stream = list.stream( );
// stream.forEach();
// 2 通过数组创建流
String[] address = {"郑州","驻马店","周口","商丘","濮阳"};
Stream<String> stream1 = Arrays.stream(address);
// 3 通过Stream的静态方法来完成
Stream<Integer> stream2 = Stream.of(1, 2, 3, 4);
}
}
5.2 流的操作
Stream流就是流式处理数据,流的操作有很多种
获得流
中间操作(真正处理数据的操作)
中间操作就是执行完返回一个流可以继续中间操作
终止操作(将操作完的结果返回)
操作 |
函数 |
说明 |
中间操作 |
==filter(Predicate)== |
将结果为false的元素过滤掉 |
中间操作 |
==map(Function)== |
转换元素的值,可以用方法引元或者lambda表达式 |
中间操作 |
limit(long n) |
保留前n个元素 |
中间操作 |
skip(long n) |
跳过前n个元素 |
中间操作 |
concat(Stream s1, Stream s2) |
将两个流拼接起来 |
中间操作 |
flatMap(Function) |
若元素是流,将流摊平为正常元素,再进行元素转换 |
中间操作 |
distinct() |
剔除重复元素 |
中间操作 |
==sorted()== |
将Comparable元素的流排序 |
中间操作 |
sorted(Comparator) |
将流元素按Comparator排序 |
中间操作 |
peek(Consumer) |
流不变,但会把每个元素传入fun执行,可以用作调试 |
终结操作 |
max(Comparator) |
取最大值 |
终结操作 |
min(Comparator) |
取最小值 |
终结操作 |
count() |
统计元素数量 |
终结操作 |
findFirst() |
获得流的第一个元素 |
终结操作 |
findAny() |
返回任意元素 |
终结操作 |
anyMatch(Predicate) |
任意元素匹配时返回true |
终结操作 |
allMatch(Predicate) |
所有元素匹配时返回true |
终结操作 |
noneMatch(Predicate) |
没有元素匹配时返回true |
终结操作 |
reduce(Function) |
从流中计算某个值,接受一个二元函数作为累积器,从前两个元素开始持续应用它,累积器的中间结果作为第一个参数,流元素作为第二个参数 |
终结操作 |
iterator() |
迭代器迭代元素 |
终结操作 |
==forEach(Consumer)== |
lambda的方式迭代 |
终结操作 |
forEachOrdered(Consumer) |
可以应用在并行流上以保持元素顺序 |
Stream流的操作注意事项
流的操作只能使用一次
使用中间操作,返回新的流
没有终止操作,就不会有结果,换句话说,没有终结操作,中间操作是 不会执行的
package com.qf.jdk.stream;
import java.util.ArrayList;
import java.util.stream.Stream;
public class Demo3 {
public static void main(String[] args) {
// 现有集合如下
ArrayList<String> list = new ArrayList<>( );
list.add("迪丽热巴-甲龙");
list.add("马尔扎哈-鹏龙");
list.add("杨顺博");
list.add("刘路");
list.add("古力娜扎-王莹莹");
Stream<String> stream = list.stream( );
// 第一次使用流
// stream.forEach((e) -> System.out.println(e));
// 第2次使用流,报错!! 只能用一次
// stream.forEach((e) -> System.out.println(e));
// 中间操作的方法,会返回新的流
Stream<String> stream2 = stream.filter((name) -> name.length( ) > 2);
Stream<String> stream3 = stream2.filter((name) -> name.contains("龙"));
// 有终止操作,上面的中间操作才会执行
stream3.forEach((name) -> System.out.println(name ));
}
}
下面演示流的操作使用 – 中间操作
package com.qf.jdk.stream;
import java.util.stream.Stream;
public class Demo4 {
public static void main(String[] args) {
// 1 获得流
Stream<String> stream = Stream.of("11", "11","22","22", "33");
Stream<String> stream2 = Stream.of("aa", "bb", "cc");
// 2 limit(long n) 保留流里面的前几个
// stream.limit(2).forEach(s -> System.out.println(s ));
// 3 skip(long n) 跳过前几个
// stream.skip(2).forEach(s -> System.out.println(s ));
// 4 concat 拼接两个流为新的流
// 该方法是Stream接口中的静态方法,直接通过接口名调用
// Stream.concat(stream,stream2).forEach(s -> System.out.println(s ));
// 5 distinct 将流中的数据去重
// stream.distinct().forEach(s -> System.out.println(s ));
// 6 sorted 排序,默认是升序
Stream<Integer> stream3 = Stream.of(5,3,2,1,4);
// stream3.sorted().forEach(s -> System.out.println(s ));
stream3.sorted((o1,o2) -> o2 - o1).forEach(s -> System.out.println(s ));
}
private static void testMap() {
// 1 获得流
Stream<String> stream = Stream.of("11", "22", "33");
// 2 流操作,map映射,传入元素,转换后再返回
// 需求,将字符串数字,映射为整形数字返回
// Stream<Integer> integerStream = stream.map((str) -> Integer.parseInt(str));
// 3 终止操作
// integerStream.forEach((i) -> System.out.println(i));
stream.map(str -> Integer.parseInt(str)).forEach(i -> System.out.println(i));
}
}
下面演示流的操作使用 – 终止操作
package com.qf.jdk.stream;
import jdk.nashorn.internal.ir.IfNode;
import java.util.Iterator;
import java.util.Optional;
import java.util.stream.Stream;
public class Demo5 {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(5, 3, 2, 1, 4);
// 1 终止操作min,返回的是Optional类
// Optional类中有个方法,get() ,可以获得其中的数据
// min方法返回的是,排序后的第一个
// Optional<Integer> optional = stream.min((o1, o2) -> o1 - o2);
// Integer min = optional.get( );
// System.out.println(min );
// Integer min = stream.min((o1, o2) -> o1 - o2).get( );
// 2 count() 计数
// System.out.println(stream.count( ));
// long count = stream.filter(e -> e > 2).count( );
// System.out.println(count );
// 3 findFirst() 获得流里面第一个,返回Optional
// System.out.println(stream.findFirst( ).get( ));
// 4 anyMatch(Predicate) 任意元素匹配时返回true
// 判断流里面的元素,任意一个都>3
// 任意一个是,只要有一个就可以
// System.out.println(stream.anyMatch(i -> i > 3));
// 5 allMatch(Predicate) 全部元素匹配时返回true
// System.out.println(stream.allMatch(i -> i > 3));
// 6 reduce() 将元素归纳
// 假设我们对一个集合中的值进行求和
// System.out.println(stream.reduce(0, (sum, e) -> {
// System.out.println("sum = " + sum);
// System.out.println("e = " + e);
// return sum + e;
// }));
// 7 iterator() 迭代器迭代元素
// Iterator<Integer> iterator = stream.iterator( );
// while (iterator.hasNext()) {
// Integer next = iterator.next( );
// System.out.println(next );
// }
}
}
5.3 流的收集
是将数组,集合等数据变成流,然后才进行操作
操作完,将数据再返回成数组和集合呢? –> 这就是收集流
将流收集到集合或数组中
collect() 收集到集合
toArray 收集到数组
package com.qf.jdk.stream;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Demo6 {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(5, 5,3, 2, 1, 4,4);
// 流中数据转成list集合
// List<Integer> list = stream.filter(i -> i > 3).collect(Collectors.toList( ));
// System.out.println(list );
// 流中数据转成set集合
// Set<Integer> set = stream.filter(i -> i > 3).collect(Collectors.toSet( ));
// System.out.println(set );
// 流可以转成数组
// Object[] array = stream.toArray( );
// 也可转成指定类型的数组
Integer[] array = stream.toArray((length) -> new Integer[length]);
System.out.println(Arrays.toString(array));
}
}
给一个ArrayList 的集合,先过滤数据只保留偶数,再进行降序排序,去除重复元素,将元素转成String类型后返回一个ArrayList
ArrayList<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(5);
list1.add(4);
list1.add(76);
list1.add(134);
System.out.println(list1.stream().
filter(e -> e % 2 == 0).
sorted((o1, o2) -> o2 - o1).
distinct().
map(e -> String.valueOf(e)).
collect(Collectors.toList()));
六、新日期API
Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理。
在旧版的 Java 中,日期时间 API 存在诸多问题,其中有:
非线程安全 − java.util.Date 是非线程安全的,所有的日期类都是可变的,这是Java日期类最大的问题之一。
设计很差 − Java的日期/时间类的定义并不一致,在java.util和java.sql的包中都有日期类,此外用于格式化和解析的类在java.text包中定义。java.util.Date同时包含日期和时间,而java.sql.Date仅包含日期,将其纳入java.sql包并不合理。另外这两个类都有相同的名字,这本身就是一个非常糟糕的设计。
时区处理麻烦 − 日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar和java.util.TimeZone类,但他们同样存在上述所有的问题。
/*一些吐槽:
1.java.util.Date被设计为日期 + 时间的结合体。也就是说如果只需要日期,或者只需要单纯的时间,用Date是做不到的。
2. 年要减1900… 月从0-11 …
3. Date是可变的,也就是说我把一个Date日期时间对象传给方法,方法内竟然还能更改
*/
@Test
public void test() {
Date currDate = new Date();
System.out.println("当前日期是①:" + currDate);
boolean holiday = isHoliday(currDate);
System.out.println("是否是假期:" + holiday);
System.out.println("当前日期是②:" + currDate);
}
/**
* 是否是假期
*/
private static boolean isHoliday(Date date) {
// 架设等于这一天才是假期,否则不是
Date holiday = new Date(2021 - 1900, 10 - 1, 1);
if (date.getTime() == holiday.getTime()) {
return true;
} else {
// 模拟写代码时不注意,使坏
date.setTime(holiday.getTime());
return true;
}
}
1、日期
LocalDate
@Test
public void test02() {
// ========== 获得日期 ==========
// 获得当前日期
LocalDate now = LocalDate.now();
System.out.println(now);
// 获得指定日期的时间
LocalDate date = LocalDate.of(2020, 1, 1);
System.out.println(date);
// 获得年
System.out.println(now.getYear());
// 获得月
System.out.println(now.getMonthValue());
// 获得日
System.out.println(now.getDayOfMonth());
// ========== 设置日期 ==========
// 设置之后返回的日期是一个新的日期对象,之前的日期并未更改
// 设置年
LocalDate withYear = now.withYear(1990);
// 设置月
LocalDate withMonth = now.withMonth(8);
// 设置日
LocalDate withDayOfMonth = now.withDayOfMonth(8);
System.out.println(now);
System.out.println(withYear);
// 增加日期,返回新的日期对象
// 增加的方法plusXxx()
LocalDate plusYears = now.plusYears(2);
// 减少日期
// 减少的方法 minusXxx()
LocalDate minusYears = now.minusYears(2);
}
2、时间
LocalTime
@Test
public void test03() {
// ========== 获得时间 ==========
// 获得当前时间
LocalTime now = LocalTime.now();
System.out.println(now);
// 获得指定时间
LocalTime of1 = LocalTime.of(10, 10); // 时分
LocalTime of2 = LocalTime.of(10, 10,10);// 时分秒
LocalTime of3 = LocalTime.of(10, 10,10,10);// 时分秒纳秒
System.out.println(of1);
// 获得时,分,秒
System.out.println(now.getHour());
System.out.println(now.getMinute());
System.out.println(now.getSecond());
// ========== 设置时间 ==========
// 设置时
LocalTime hour = now.withHour(8);
// 设置分
LocalTime minute = now.withMinute(8);
// 设置秒
LocalTime second = now.withSecond(8);
System.out.println(now);
System.out.println(hour);
// 增加时间,返回新的时间对象
// 增加的方法plusXxx()
LocalTime plus = now.plusHours(2);
// 减少时间
// 减少的方法 minusXxx()
LocalTime minus = now.minusHours(2);
}
3、日期时间
LocalDateTime
@Test
public void test04() {
// ========== 获得日期时间 ==========
// 获得当前时间
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
// 获得指定时间
LocalDateTime of1 = LocalDateTime.of(1900, 1, 1, 10, 10); //年月日时分
LocalDateTime of2 = LocalDateTime.of(2000, 10,10,8,8,8);// 年月日时分秒
System.out.println(of1);
// 获得年,月,日
System.out.println(now.getYear());
System.out.println(now.getMonthValue());
System.out.println(now.getDayOfMonth());
// 获得时,分,秒
System.out.println(now.getHour());
System.out.println(now.getMinute());
System.out.println(now.getSecond());
// ========== 设置日期时间 ==========
// 设置时
LocalDateTime hour = now.withHour(8);
// 设置分
LocalDateTime minute = now.withMinute(8);
// 设置秒
LocalDateTime second = now.withSecond(8);
System.out.println(now);
System.out.println(hour);
// 增加时间,返回新的时间对象
// 增加的方法plusXxx()
LocalDateTime plus = now.plusHours(2);
// 减少时间
// 减少的方法 minusXxx()
LocalDateTime minus = now.minusHours(2);
System.out.println(now.isAfter(plus));
System.out.println(now.isBefore(plus));
System.out.println(now.isEqual(plus));
}