接口中默认方法+静态方法 − 默认方法就是一个在接口里面有了一个实现的方法。静态方法就是接口中有个已经使用的静态方法,可直接调用
Lambda 表达式(拉姆达) − Lambda 允许把函数作为一个方法的参数(函数作为参数传递到方法中)。
方法引用 (Method Reference)− 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
// ctrl + shift + k // ```java // 方法引用的代码 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.qf.jdk.interface_;public interface Demo1 {void m1();/*** 接口中设计方法带static,方法就可以有方法体* 但是子类不能重写!!* 但是可以通过接口名之间调用执行: Demo1.m3()* 子实现类不能调用!*/static void m3(){System.out.println("这就是龙井!!!" );}// void clear();default void clear() {}/*** 因为接口中的抽象方法必须要重写!* 加了default的方法,有方法体,那就不是抽象方法* 那就不要求重写* ----------------------* 好处就是,在项目开发中,对已有的项目进行扩展时,比较优雅* 即,给接口设计了default修饰的方法后,所有子实现类并没有强制重写* 这样,就可以有选择对某个子实现类中重写该方法*/default void m2(){}
}
Lambda 允许把函数(方法)作为一个方法的参数(函数作为参数传递到方法中)。
其实就是简化了匿名内部类的写法
package com.qf.jdk.lambda;public class Demo1Lambda {public static void main(String[] args) {// 1 之前使用匿名内部类,开启线程new Thread(new Runnable( ) {@Overridepublic void run() {System.out.println("匿名内部类开启线程" );}}).start();// 以上代码,主要关注的是线程的执行任务,即run()内部的代码// 2 换成lambda后new Thread(() -> System.out.println("lambda开启线程" )).start();// lambda基本结构是// () -> 语句// 参数列表,箭头符号,执行语句}
}
能够使用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) -> 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,直接写值
- 如果代码比较多,又要返回数据,就必须写上return
lambda就是匿名内部类的简化.
package com.qf.jdk.lambda;/*** --- 天道酬勤 ---** @author QiuShiju* @desc*/
public class Demo2TestLambda {/*** lambda* 1 方法有参数* 2 参数是接口* 3 接口只有一个方法*/public static void main(String[] args) {// 用匿名内部类来一遍m1(new M1( ) {@Overridepublic void test1() {System.out.println("test1执行-无参无返回值" );}});// 改造成lambdam1(() -> System.out.println("lambda执行-无参无返回值" ));}public static void m1(M1 m1) {m1.test1();}
}// 定义一个接口
// 像这种只能有一个抽象方法的接口,用于lambda的接口
// 称之为函数式接口
interface M1{void test1();// void test11();
}
package com.qf.jdk.lambda;/*** --- 天道酬勤 ---** @author QiuShiju* @desc 有参无返回值的lambda*/
public class Demo3TestLambda {/*** 1 方法有参数* 2 参数是接口* 3 接口只有一个抽象方法*/public static void main(String[] args) {// 匿名内部类实现m2(10, new M2( ) {@Overridepublic void test2(int a) {System.out.println(a*10);}});m22(8, "8", new M22( ) {@Overridepublic void test22(int a, String b) {System.out.println(a+b);}});// lambda改造// 一个参数时,圆括号可以加m2(5,(a) -> System.out.println(a*10));// 一个参数时,圆括号也可以不加m2(6,a -> System.out.println(a*10));// 数据类型可加可不加m2(7,(int a) -> System.out.println(a*10));// 多个参数,圆括号必须加m22(9,"9",(a,b) -> System.out.println(a+b ));// 数据类型可加可不加m22(10,"10",(int a,String b) -> System.out.println(a+b ));}public static void m2(int x,M2 m2) {m2.test2(x);}public static void m22(int x,String y,M22 m22) {m22.test22(x,y);}}interface M2{void test2(int a);
}interface M22{void test22(int a,String b);
}
package com.qf.jdk.lambda;/*** --- 天道酬勤 ---** @author QiuShiju* @desc 无参有返回值得lambda*/
public class Demo4TestLambda {/*** 1 方法得有参数* 2 参数得是接口* 3 接口中只能有一个抽象方法*/public static void main(String[] args) {// 匿名内部类m3(new M3( ) {@Overridepublic int test3() {int a = 1;a++;return 200;}});// lambda// lambda 中有且只有一行语句时,return可以省略m3(() -> 302);m3(() -> {return 302;});// lambda中有多行语句,return不能省略m3(() -> {int a = 1;a++;return 302;});}public static void m3(M3 m3){int i = m3.test3( );System.out.println(i );}}interface M3 {int test3();
}
设计一个方法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);
}
ArrayList 集合中的元素使用 Collections 工具类进行排序.
Collections.sort(list,compartor) 其中可以指定一个比较器,进行自定义排序
用lambda
package com.qf.jdk.lambda;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;/*** --- 天道酬勤 ---** @author QiuShiju* @desc 实战*/
public class Demo6TestLambda {public static void main(String[] args) {ArrayList 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 );}}
}
接口中只有一个抽象方法时,该接口就是函数式接口
.为什么叫做函数式接口?因为这种接口,放在方法中档参数时,可以改造成lambda,进行运算.
Java提供了一个注解可以校验接口是否是函数式接口
@FunctionalInterface
Java中提供了几个特别常用的函数式接口
- Supplier 供应,即返回一个数据
- Consumer 消费,即给其传入数据做运算
- Function 函数,传入2个参数,用于转换数据的
- Predicate 判断,返回时boolean
@FunctionalInterface
public interface Supplier {/*** Gets a result.** @return a result*/T get();
}
// 该接口用来返回一个数据,所以叫供应商
// 其实就是无参数有返回值的接口,用的时候就是无参有返回值的lambda
练习,设计方法,通过Supplier接口,获得字符串的长度
public static void main(String[] args) {String str = "java";// 获得字符串长度getStringLength(() -> str.length());// 获得字符串首字母getStringLength(() -> (int) str.charAt(0));// 获得某个字符下标getStringLength(() -> str.indexOf('v'));}public static void getStringLength(Supplier supplier){Integer length = supplier.get();System.out.println(length);}
@FunctionalInterface
public interface Consumer {/*** Performs this operation on the given argument.* 给传入一个值,对该值进行操作* @param t the input argument*/void accept(T t);
}
// 其实就是有参数无返回值的接口,用的时候就是有参无返回值的lambda
练习:设计方法,传入字符串,将字符串全部转大写,后输出
public static void main(String[] args) {String str = "java";// 这次使用一个字符串,将字符串变大写toUpperCase("java",s -> {String string = s.toUpperCase( );System.out.println("string = " + string);});// 这次是使用一个字符串,截取后缀toUpperCase("从入门到精通.txt",s -> System.out.println(s.substring(s.length() - 3) ));}public static void toUpperCase(String str, Consumer consumer){consumer.accept(str);}
@FunctionalInterface
public interface Function {/*** Applies this function to the given argument.** @param t the function argument* @return the function result*/R apply(T t);
}
// 该接口用于,转换数据
// 其实就是有参数有返回值的接口,用的时候就是有参有返回值的lambda
练习,设计方法,将传入的字符串数字,转为整形数字
public static void main(String[] args) {// 将传入的字符串变为数字返回change("1122",(string) -> Integer.parseInt(string));// 将传入的数字放大10倍后变为字符串返回change2(100,i -> String.valueOf(i * 10));}public static void change2(Integer i, Function function) {String str = function.apply(i);System.out.println("str = " + str);}public static void change(String str, Function function) {Integer num = function.apply(str);System.out.println("num = " + num);}
@FunctionalInterface
public interface Predicate {/*** 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
设计方法,判断数据
public static void main(String[] args) {// 判断人名,是否太长,大于3即认为太长isTrue("迪丽热巴",name -> name.length() > 3);// 判断年龄,年龄不能超过 0-150之间isTrue2(220,age -> age <= 150 && age >= 0);}public static void isTrue2(Integer age, Predicate predicate){boolean test = predicate.test(age);System.out.println("test = " + test);}public static void isTrue(String name, Predicate predicate){boolean test = predicate.test(name);System.out.println("test = " + test);}
作业
定义一个方法,传入一个字符串,输出字符串的长度
定义一个方法,传入一个数组,获取数组最大值
定义一个方法,返回100内最大质数
定义一个方法,传入一个数组,返回指定数组的和
定义一个方法,传入一个数,判断他是否是3的倍数
Stream流,不要和之前学的IO流进行联想,他们之间没有关系.
IO流,数据像水流一样在传输
Stream流,数据像车间流水线,在一直往下走动,不是保存数据,也不纯粹的传输数据,而是像车间流水线一样,在
处理数据
.Stream流可以让我们更快的处理数据.
分别演示之前处理数据,和使用Stream流来处理数据
package com.qf.jdk.stream;import java.util.ArrayList;/*** --- 天道酬勤 ---** @author QiuShiju* @desc 分别演示之前处理数据,和使用Stream流来处理数据*/
public class Demo1 {public static void main(String[] args) {// 现有集合如下ArrayList list = new ArrayList<>( );list.add("迪丽热巴-甲龙");list.add("马尔扎哈-鹏龙");list.add("杨顺博");list.add("刘路");list.add("古力娜扎-王莹莹");// show1();show2(list);}// 使用Stream来完成public static void show2(ArrayList list) {list.stream().filter(name-> name.length()>2).filter(name -> name.contains("龙")).forEach(name -> System.out.println(name ));}// 未使用Stream流public static void show1(ArrayList list) {// 条件1: 找到人名中长度大于2的// 条件2: 在1的基础上,再找名字里面包含"龙"的人名for (String name : list) {if (name.length() > 2) {if (name.contains("龙")) {System.out.println("name = " + name);}}}}
}
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;/*** --- 天道酬勤 ---** @author QiuShiju* @desc 获得流*/
public class Demo2 {public static void main(String[] args) {// 现有集合如下ArrayList list = new ArrayList<>( );list.add("迪丽热巴-甲龙");list.add("马尔扎哈-鹏龙");list.add("杨顺博");list.add("刘路");list.add("古力娜扎-王莹莹");// 1 通过集合获得流Stream stream = list.stream( );// stream.forEach();// 2 通过数组创建流String[] address = {"郑州","驻马店","周口","商丘","濮阳"};Stream stream1 = Arrays.stream(address);// 3 通过Stream的静态方法来完成Stream stream2 = Stream.of(1, 2, 3, 4);}
}
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;/*** --- 天道酬勤 ---** @author QiuShiju* @desc 流使用时注意事项*/
public class Demo3 {public static void main(String[] args) {// 现有集合如下ArrayList list = new ArrayList<>( );list.add("迪丽热巴-甲龙");list.add("马尔扎哈-鹏龙");list.add("杨顺博");list.add("刘路");list.add("古力娜扎-王莹莹");Stream stream = list.stream( );// 第一次使用流// stream.forEach((e) -> System.out.println(e));// 第2次使用流,报错!! 只能用一次// stream.forEach((e) -> System.out.println(e));// 中间操作的方法,会返回新的流Stream stream2 = stream.filter((name) -> name.length( ) > 2);Stream stream3 = stream2.filter((name) -> name.contains("龙"));// 有终止操作,上面的中间操作才会执行stream3.forEach((name) -> System.out.println(name ));}
}
下面演示流的操作使用 - 中间操作
package com.qf.jdk.stream;import java.util.stream.Stream;/*** --- 天道酬勤 ---** @author QiuShiju* @desc 操作流*/
public class Demo4 {public static void main(String[] args) {// 1 获得流Stream stream = Stream.of("11", "11","22","22", "33");Stream 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 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 stream = Stream.of("11", "22", "33");// 2 流操作,map映射,传入元素,转换后再返回// 需求,将字符串数字,映射为整形数字返回// Stream 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;/*** --- 天道酬勤 ---** @author QiuShiju* @desc*/
public class Demo5 {public static void main(String[] args) {Stream stream = Stream.of(5, 3, 2, 1, 4);// 1 终止操作min,返回的是Optional类// Optional类中有个方法,get() ,可以获得其中的数据// min方法返回的是,排序后的第一个// Optional 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 iterator = stream.iterator( );// while (iterator.hasNext()) {// Integer next = iterator.next( );// System.out.println(next );// }}
}
是将数组,集合等数据变成流,然后才进行操作
操作完,将数据再返回成数组和集合呢? --> 这就是收集流
将流收集到集合或数组中
- 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;/*** --- 天道酬勤 ---** @author QiuShiju* @desc*/
public class Demo6 {public static void main(String[] args) {Stream stream = Stream.of(5, 5,3, 2, 1, 4,4);// 流中数据转成list集合// List list = stream.filter(i -> i > 3).collect(Collectors.toList( ));// System.out.println(list );// 流中数据转成set集合// Set 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));}
}
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; }
}
LocalDate
@Testpublic 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);}
LocalTime
@Testpublic 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);}
LocalDateTime
@Testpublic 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));}