https://blog.csdn.net/qq_29411737/article/details/80835658
JDK1.8 新特性(全)
2018年06月27日 22:01:54 qq_29411737 阅读数:6952
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29411737/article/details/80835658
JDK1.8 新特性
本文主要介绍了JDK1.8版本中的一些新特性,乃作者视频观后笔记,仅供参考。
jdk1.8新特性知识点:
- Lambda表达式
- 函数式接口
- *方法引用和构造器调用
- Stream API
- 接口中的默认方法和静态方法
- 新时间日期API
在jdk1.8中对hashMap等map集合的数据结构优化。hashMap数据结构的优化
原来的hashMap采用的数据结构是哈希表(数组+链表),hashMap默认大小是16,一个0-15索引的数组,如何往里面存储元素,首先调用元素的hashcode
方法,计算出哈希码值,经过哈希算法算成数组的索引值,如果对应的索引处没有元素,直接存放,如果有对象在,那么比较它们的equals方法比较内容
如果内容一样,后一个value会将前一个value的值覆盖,如果不一样,在1.7的时候,后加的放在前面,形成一个链表,形成了碰撞,在某些情况下如果链表
无限下去,那么效率极低,碰撞是避免不了的
加载因子:0.75,数组扩容,达到总容量的75%,就进行扩容,但是无法避免碰撞的情况发生
在1.8之后,在数组+链表+红黑树来实现hashmap,当碰撞的元素个数大于8时 & 总容量大于64,会有红黑树的引入
除了添加之后,效率都比链表高,1.8之后链表新进元素加到末尾
ConcurrentHashMap (锁分段机制),concurrentLevel,jdk1.8采用CAS算法(无锁算法,不再使用锁分段),数组+链表中也引入了红黑树的使用
Lambda表达式
lambda表达式本质上是一段匿名内部类,也可以是一段可以传递的代码
先来体验一下lambda最直观的优点:简洁代码
<span style="color:#000000"><code> <span style="color:#880000 !important"><em>//匿名内部类</em></span>
Comparator<span style="color:#4f4f4f !important"><</span><span style="color:#4f4f4f !important">Integer</span><span style="color:#4f4f4f !important">></span> cpt <span style="color:#4f4f4f !important">=</span> <span style="color:#006666 !important">new</span> Comparator<span style="color:#4f4f4f !important"><</span><span style="color:#4f4f4f !important">Integer</span><span style="color:#4f4f4f !important">></span>() {
@Override
<span style="color:#000088 !important">public</span> int compare(<span style="color:#4f4f4f !important">Integer</span> o1, <span style="color:#4f4f4f !important">Integer</span> o2) {
<span style="color:#000088 !important">return</span> <span style="color:#4f4f4f !important">Integer</span><span style="color:#4f4f4f !important">.</span>compare(o1,o2);
}
};
TreeSet<span style="color:#4f4f4f !important"><</span><span style="color:#4f4f4f !important">Integer</span><span style="color:#4f4f4f !important">></span> <span style="color:#4f4f4f !important">set</span> <span style="color:#4f4f4f !important">=</span> <span style="color:#006666 !important">new</span> TreeSet<span style="color:#4f4f4f !important"><></span>(cpt);
System<span style="color:#4f4f4f !important">.</span>out<span style="color:#4f4f4f !important">.</span>println(<span style="color:#009900 !important">"========================="</span>);
<span style="color:#880000 !important"><em>//使用lambda表达式</em></span>
Comparator<span style="color:#4f4f4f !important"><</span><span style="color:#4f4f4f !important">Integer</span><span style="color:#4f4f4f !important">></span> cpt2 <span style="color:#4f4f4f !important">=</span> (x,y) <span style="color:#4f4f4f !important">-> </span><span style="color:#4f4f4f !important">Integer</span><span style="color:#4f4f4f !important">.</span>compare(x,y);
TreeSet<span style="color:#4f4f4f !important"><</span><span style="color:#4f4f4f !important">Integer</span><span style="color:#4f4f4f !important">></span> set2 <span style="color:#4f4f4f !important">=</span> <span style="color:#006666 !important">new</span> TreeSet<span style="color:#4f4f4f !important"><></span>(cpt2);</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
只需要一行代码,极大减少代码量!!
这样一个场景,在商城浏览商品信息时,经常会有条件的进行筛选浏览,例如要选颜色为红色的、价格小于8000千的….
<span style="color:#000000"><code><span style="color:#880000 !important"><em>// 筛选颜色为红色</em></span>
<span style="color:#000088 !important">public</span> <span style="color:#000088 !important">List</span><Product> filterProductByColor(<span style="color:#000088 !important">List</span><Product> <span style="color:#000088 !important">list</span>){
<span style="color:#000088 !important">List</span><Product> prods = <span style="color:#000088 !important">new</span> ArrayList<>();
<span style="color:#000088 !important">for</span> (Product product : <span style="color:#000088 !important">list</span>){
<span style="color:#000088 !important">if</span> (<span style="color:#009900 !important">"红色"</span>.equals(product.getColor())){
prods.add(product);
}
}
<span style="color:#000088 !important">return</span> prods;
}
<span style="color:#880000 !important"><em>// 筛选价格小于8千的</em></span>
<span style="color:#000088 !important">public</span> <span style="color:#000088 !important">List</span><Product> filterProductByPrice(<span style="color:#000088 !important">List</span><Product> <span style="color:#000088 !important">list</span>){
<span style="color:#000088 !important">List</span><Product> prods = <span style="color:#000088 !important">new</span> ArrayList<>();
<span style="color:#000088 !important">for</span> (Product product : <span style="color:#000088 !important">list</span>){
<span style="color:#000088 !important">if</span> (product.getPrice() < <span style="color:#006666 !important">8000</span>){
prods.add(product);
}
}
<span style="color:#000088 !important">return</span> prods;
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
我们发现实际上这些过滤方法的核心就只有if语句中的条件判断,其他均为模版代码,每次变更一下需求,都需要新增一个方法,然后复制黏贴,假设这个过滤方法有几百行,那么这样的做法难免笨拙了一点。如何进行优化呢?
优化一:使用设计模式
定义一个MyPredicate接口
<span style="color:#000000"><code><span style="color:#000088 !important">public</span> <span style="color:#000088 !important">interface</span> MyPredicate <T> {
boolean test(T t);
}</code></span>
- 1
- 2
- 3
如果想要筛选颜色为红色的商品,定义一个颜色过滤类
<span style="color:#000000"><code><span style="color:#000088 !important">public</span> <span style="color:#000088 !important">class</span> <span style="color:#4f4f4f !important">ColorPredicate</span> <span style="color:#000088 !important">implements</span> <span style="color:#4f4f4f !important">MyPredicate</span> <<span style="color:#4f4f4f !important">Product</span>> {
<span style="color:#000088 !important">private</span> <span style="color:#000088 !important">static</span> <span style="color:#000088 !important">final</span> String RED = <span style="color:#009900 !important">"红色"</span>;
@Override
<span style="color:#000088 !important">public</span> <span style="color:#000088 !important">boolean</span> test(Product product) {
<span style="color:#000088 !important">return</span> RED.equals(product.getColor());
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
定义过滤方法,将过滤接口当做参数传入,这样这个过滤方法就不用修改,在实际调用的时候将具体的实现类传入即可。
<span style="color:#000000"><code><span style="color:#000088 !important">public</span> <span style="color:#000088 !important">List</span><Product> filterProductByPredicate(<span style="color:#000088 !important">List</span><Product> <span style="color:#000088 !important">list</span>,MyPredicate<Product> mp){
<span style="color:#000088 !important">List</span><Product> prods = <span style="color:#000088 !important">new</span> ArrayList<>();
<span style="color:#000088 !important">for</span> (Product prod : <span style="color:#000088 !important">list</span>){
<span style="color:#000088 !important">if</span> (mp.test(prod)){
prods.add(prod);
}
}
<span style="color:#000088 !important">return</span> prods;
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
例如,如果想要筛选价格小于8000的商品,那么新建一个价格过滤类既可
<span style="color:#000000"><code><span style="color:#000088 !important">public</span> <span style="color:#000088 !important">class</span> <span style="color:#4f4f4f !important">PricePredicate</span> <span style="color:#000088 !important">implements</span> <span style="color:#4f4f4f !important">MyPredicate</span><<span style="color:#4f4f4f !important">Product</span>> {
@Override
<span style="color:#000088 !important">public</span> <span style="color:#000088 !important">boolean</span> test(Product product) {
<span style="color:#000088 !important">return</span> product.getPrice() < <span style="color:#006666 !important">8000</span>;
}
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
这样实现的话可能有人会说,每次变更需求都需要新建一个实现类,感觉还是有点繁琐呀,那么再来优化一下
优化二:使用匿名内部类
定义过滤方法:
<span style="color:#000000"><code><span style="color:#000088 !important">public</span> <span style="color:#000088 !important">List</span><Product> filterProductByPredicate(<span style="color:#000088 !important">List</span><Product> <span style="color:#000088 !important">list</span>,MyPredicate<Product> mp){
<span style="color:#000088 !important">List</span><Product> prods = <span style="color:#000088 !important">new</span> ArrayList<>();
<span style="color:#000088 !important">for</span> (Product prod : <span style="color:#000088 !important">list</span>){
<span style="color:#000088 !important">if</span> (mp.test(prod)){
prods.add(prod);
}
}
<span style="color:#000088 !important">return</span> prods;
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
调用过滤方法的时候:
<span style="color:#000000"><code><span style="color:#880000 !important"><em>// 按价格过滤</em></span>
<span style="color:#000088 !important">public</span> <span style="color:#000088 !important">void</span> <span style="color:#009900 !important">test2</span>(){
filterProductByPredicate(proList, <span style="color:#000088 !important">new</span> MyPredicate<Product>() {
<span style="color:#9b859d !important">@Override</span>
<span style="color:#000088 !important">public</span> <span style="color:#000088 !important">boolean</span> <span style="color:#009900 !important">test</span>(Product product) {
<span style="color:#000088 !important">return</span> product.getPrice() < <span style="color:#006666 !important">8000</span>;
}
});
}
<span style="color:#880000 !important"><em>// 按颜色过滤</em></span>
<span style="color:#000088 !important">public</span> <span style="color:#000088 !important">void</span> <span style="color:#009900 !important">test3</span>(){
filterProductByPredicate(proList, <span style="color:#000088 !important">new</span> MyPredicate<Product>() {
<span style="color:#9b859d !important">@Override</span>
<span style="color:#000088 !important">public</span> <span style="color:#000088 !important">boolean</span> <span style="color:#009900 !important">test</span>(Product product) {
<span style="color:#000088 !important">return</span> <span style="color:#009900 !important">"红色"</span>.equals(product.getColor());
}
});
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
使用匿名内部类,就不需要每次都新建一个实现类,直接在方法内部实现。看到匿名内部类,不禁想起了Lambda表达式。
优化三:使用lambda表达式
定义过滤方法:
<span style="color:#000000"><code><span style="color:#000088 !important">public</span> <span style="color:#000088 !important">List</span><Product> filterProductByPredicate(<span style="color:#000088 !important">List</span><Product> <span style="color:#000088 !important">list</span>,MyPredicate<Product> mp){
<span style="color:#000088 !important">List</span><Product> prods = <span style="color:#000088 !important">new</span> ArrayList<>();
<span style="color:#000088 !important">for</span> (Product prod : <span style="color:#000088 !important">list</span>){
<span style="color:#000088 !important">if</span> (mp.test(prod)){
prods.add(prod);
}
}
<span style="color:#000088 !important">return</span> prods;
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
使用lambda表达式进行过滤
<span style="color:#000000"><code>@Test
public void test4(){
List<Product> products = filterProductByPredicate<span style="color:#4f4f4f !important">(proList, (p) -> p.getPrice() < <span style="color:#006666 !important">8000</span>)</span>;
<span style="color:#009900 !important">for</span> <span style="color:#4f4f4f !important">(Product pro : products)</span>{
<span style="color:#009900 !important">System</span>.<span style="color:#009900 !important">out</span>.<span style="color:#009900 !important">println</span><span style="color:#4f4f4f !important">(pro)</span>;
}
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
在jdk1.8中还有更加简便的操作 Stream API
优化四:使用Stream API
甚至不用定义过滤方法,直接在集合上进行操作
<span style="color:#000000"><code><span style="color:#008800 !important">//</span> 使用jdk1<span style="color:#006666 !important">.8</span>中的Stream API进行集合的操作
@Test
public void test(){
<span style="color:#008800 !important">//</span> 根据价格过滤
proList.stream()
.fliter<span style="color:#4f4f4f !important">((p) -> p.getPrice() <<span style="color:#006666 !important">8000</span>)</span>
.<span style="color:#009900 !important">limit</span><span style="color:#4f4f4f !important">(<span style="color:#006666 !important">2</span>)</span>
.<span style="color:#009900 !important">forEach</span><span style="color:#4f4f4f !important">(System.out::println)</span>;
// 根据颜色过滤
<span style="color:#009900 !important">proList</span>.<span style="color:#009900 !important">stream</span><span style="color:#4f4f4f !important">()</span>
.<span style="color:#009900 !important">fliter</span><span style="color:#4f4f4f !important">((p) -> <span style="color:#009900 !important">"红色"</span>.equals(p.getColor()))</span>
.<span style="color:#009900 !important">forEach</span><span style="color:#4f4f4f !important">(System.out::println)</span>;
// 遍历输出商品名称
<span style="color:#009900 !important">proList</span>.<span style="color:#009900 !important">stream</span><span style="color:#4f4f4f !important">()</span>
.<span style="color:#009900 !important">map</span><span style="color:#4f4f4f !important">(Product::getName)</span>
.<span style="color:#009900 !important">forEach</span><span style="color:#4f4f4f !important">(System.out::println)</span>;
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
Lmabda表达式的语法总结: () -> ();
前置 | 语法 |
---|---|
无参数无返回值 | () -> System.out.println(“Hello WOrld”) |
有一个参数无返回值 | (x) -> System.out.println(x) |
有且只有一个参数无返回值 | x -> System.out.println(x) |
有多个参数,有返回值,有多条lambda体语句 | (x,y) -> {System.out.println(“xxx”);return xxxx;}; |
有多个参数,有返回值,只有一条lambda体语句 | (x,y) -> xxxx |
口诀:左右遇一省括号,左侧推断类型省
注:当一个接口中存在多个抽象方法时,如果使用lambda表达式,并不能智能匹配对应的抽象方法,因此引入了函数式接口的概念
函数式接口
函数式接口的提出是为了给Lambda表达式的使用提供更好的支持。
什么是函数式接口?
简单来说就是只定义了一个抽象方法的接口(Object类的public方法除外),就是函数式接口,并且还提供了注解:@FunctionalInterface
常见的四大函数式接口
- Consumer 《T》:消费型接口,有参无返回值
<span style="color:#000000"><code> <span style="color:#9b859d !important">@Test</span>
<span style="color:#000088 !important">public</span> <span style="color:#000088 !important">void</span> <span style="color:#009900 !important">test</span>(){
changeStr(<span style="color:#009900 !important">"hello"</span>,(str) -> System.out.println(str));
}
<span style="color:#880000 !important">/**
* Consumer<T> 消费型接口
*<span style="color:#4f4f4f !important"> @param</span> str
*<span style="color:#4f4f4f !important"> @param</span> con
*/</span>
<span style="color:#000088 !important">public</span> <span style="color:#000088 !important">void</span> <span style="color:#009900 !important">changeStr</span>(String str, Consumer<String> con){
con.accept(str);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- Supplier 《T》:供给型接口,无参有返回值
<span style="color:#000000"><code> <span style="color:#9b859d !important">@Test</span>
<span style="color:#000088 !important">public</span> <span style="color:#000088 !important">void</span> <span style="color:#009900 !important">test2</span>(){
String value = getValue(() -> <span style="color:#009900 !important">"hello"</span>);
System.out.println(value);
}
<span style="color:#880000 !important">/**
* Supplier<T> 供给型接口
*<span style="color:#4f4f4f !important"> @param</span> sup
*<span style="color:#4f4f4f !important"> @return</span>
*/</span>
<span style="color:#000088 !important">public</span> String <span style="color:#009900 !important">getValue</span>(Supplier<String> sup){
<span style="color:#000088 !important">return</span> sup.get();
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- Function 《T,R》::函数式接口,有参有返回值
<span style="color:#000000"><code> <span style="color:#9b859d !important">@Test</span>
<span style="color:#000088 !important">public</span> <span style="color:#000088 !important">void</span> <span style="color:#009900 !important">test3</span>(){
Long result = changeNum(<span style="color:#006666 !important">100</span>L, (x) -> x + <span style="color:#006666 !important">200</span>L);
System.out.println(result);
}
<span style="color:#880000 !important">/**
* Function<T,R> 函数式接口
*<span style="color:#4f4f4f !important"> @param</span> num
*<span style="color:#4f4f4f !important"> @param</span> fun
*<span style="color:#4f4f4f !important"> @return</span>
*/</span>
<span style="color:#000088 !important">public</span> Long <span style="color:#009900 !important">changeNum</span>(Long num, Function<Long, Long> fun){
<span style="color:#000088 !important">return</span> fun.apply(num);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- Predicate《T》: 断言型接口,有参有返回值,返回值是boolean类型
<span style="color:#000000"><code><span style="color:#000088 !important">public</span> <span style="color:#000088 !important">void</span> <span style="color:#009900 !important">test4</span>(){
<span style="color:#000088 !important">boolean</span> result = changeBoolean(<span style="color:#009900 !important">"hello"</span>, (str) -> str.length() > <span style="color:#006666 !important">5</span>);
System.out.println(result);
}
<span style="color:#880000 !important">/**
* Predicate<T> 断言型接口
*<span style="color:#4f4f4f !important"> @param</span> str
*<span style="color:#4f4f4f !important"> @param</span> pre
*<span style="color:#4f4f4f !important"> @return</span>
*/</span>
<span style="color:#000088 !important">public</span> <span style="color:#000088 !important">boolean</span> <span style="color:#009900 !important">changeBoolean</span>(String str, Predicate<String> pre){
<span style="color:#000088 !important">return</span> pre.test(str);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
在四大核心函数式接口基础上,还提供了诸如BiFunction、BinaryOperation、toIntFunction等扩展的函数式接口,都是在这四种函数式接口上扩展而来的,不做赘述。
总结:函数式接口的提出是为了让我们更加方便的使用lambda表达式,不需要自己再手动创建一个函数式接口,直接拿来用就好了,贴
方法引用
若lambda体中的内容有方法已经实现了,那么可以使用“方法引用”
也可以理解为方法引用是lambda表达式的另外一种表现形式并且其语法比lambda表达式更加简单
(a) 方法引用
三种表现形式:
1. 对象::实例方法名
2. 类::静态方法名
3. 类::实例方法名 (lambda参数列表中第一个参数是实例方法的调用 者,第二个参数是实例方法的参数时可用)
<span style="color:#000000"><code> <span style="color:#000088 !important">public</span> <span style="color:#006666 !important">void</span> test() {
<span style="color:#880000 !important"><em>/**
*注意:
* 1.lambda体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的函数列表和返回值类型保持一致!
* 2.若lambda参数列表中的第一个参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用ClassName::method
*
*/</em></span>
Consumer<span style="color:#4f4f4f !important"><</span><span style="color:#4f4f4f !important">Integer</span><span style="color:#4f4f4f !important">></span> con <span style="color:#4f4f4f !important">=</span> (x) <span style="color:#4f4f4f !important">-> </span>System<span style="color:#4f4f4f !important">.</span>out<span style="color:#4f4f4f !important">.</span>println(x);
con<span style="color:#4f4f4f !important">.</span>accept(<span style="color:#006666 !important">100</span>);
<span style="color:#880000 !important"><em>// 方法引用-对象::实例方法</em></span>
Consumer<span style="color:#4f4f4f !important"><</span><span style="color:#4f4f4f !important">Integer</span><span style="color:#4f4f4f !important">></span> con2 <span style="color:#4f4f4f !important">=</span> System<span style="color:#4f4f4f !important">.</span>out<span style="color:#006666 !important">::println</span>;
con2<span style="color:#4f4f4f !important">.</span>accept(<span style="color:#006666 !important">200</span>);
<span style="color:#880000 !important"><em>// 方法引用-类名::静态方法名</em></span>
BiFunction<span style="color:#4f4f4f !important"><</span><span style="color:#4f4f4f !important">Integer</span>, <span style="color:#4f4f4f !important">Integer</span>, <span style="color:#4f4f4f !important">Integer</span><span style="color:#4f4f4f !important">></span> biFun <span style="color:#4f4f4f !important">=</span> (x, y) <span style="color:#4f4f4f !important">-> </span><span style="color:#4f4f4f !important">Integer</span><span style="color:#4f4f4f !important">.</span>compare(x, y);
BiFunction<span style="color:#4f4f4f !important"><</span><span style="color:#4f4f4f !important">Integer</span>, <span style="color:#4f4f4f !important">Integer</span>, <span style="color:#4f4f4f !important">Integer</span><span style="color:#4f4f4f !important">></span> biFun2 <span style="color:#4f4f4f !important">=</span> <span style="color:#4f4f4f !important">Integer</span><span style="color:#006666 !important">::compare</span>;
<span style="color:#4f4f4f !important">Integer</span> result <span style="color:#4f4f4f !important">=</span> biFun2<span style="color:#4f4f4f !important">.</span>apply(<span style="color:#006666 !important">100</span>, <span style="color:#006666 !important">200</span>);
<span style="color:#880000 !important"><em>// 方法引用-类名::实例方法名</em></span>
BiFunction<span style="color:#4f4f4f !important"><</span><span style="color:#4f4f4f !important">String</span>, <span style="color:#4f4f4f !important">String</span>, Boolean<span style="color:#4f4f4f !important">></span> fun1 <span style="color:#4f4f4f !important">=</span> (str1, str2) <span style="color:#4f4f4f !important">-> </span>str1<span style="color:#4f4f4f !important">.</span><span style="color:#000088 !important">equals</span>(str2);
BiFunction<span style="color:#4f4f4f !important"><</span><span style="color:#4f4f4f !important">String</span>, <span style="color:#4f4f4f !important">String</span>, Boolean<span style="color:#4f4f4f !important">></span> fun2 <span style="color:#4f4f4f !important">=</span> <span style="color:#4f4f4f !important">String</span><span style="color:#006666 !important">::equals</span>;
Boolean result2 <span style="color:#4f4f4f !important">=</span> fun2<span style="color:#4f4f4f !important">.</span>apply(<span style="color:#009900 !important">"hello"</span>, <span style="color:#009900 !important">"world"</span>);
System<span style="color:#4f4f4f !important">.</span>out<span style="color:#4f4f4f !important">.</span>println(result2);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
(b)构造器引用
格式:ClassName::new
<span style="color:#000000"><code><span style="color:#000088 !important">public</span> <span style="color:#000088 !important">void</span> <span style="color:#009900 !important">test2</span>() {
<span style="color:#880000 !important"><em>// 构造方法引用 类名::new</em></span>
Supplier<Employee> sup = () -> <span style="color:#000088 !important">new</span> Employee();
System.<span style="color:#000088 !important">out</span>.println(sup.<span style="color:#000088 !important">get</span>());
Supplier<Employee> sup2 = Employee::<span style="color:#000088 !important">new</span>;
System.<span style="color:#000088 !important">out</span>.println(sup2.<span style="color:#000088 !important">get</span>());
<span style="color:#880000 !important"><em>// 构造方法引用 类名::new (带一个参数)</em></span>
Function<Integer, Employee> fun = (x) -> <span style="color:#000088 !important">new</span> Employee(x);
Function<Integer, Employee> fun2 = Employee::<span style="color:#000088 !important">new</span>;
System.<span style="color:#000088 !important">out</span>.println(fun2.apply(<span style="color:#006666 !important">100</span>));
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
(c)数组引用
格式:Type[]::new
<span style="color:#000000"><code>public <span style="color:#000088 !important">void</span> test(){
<span style="color:#880000 !important"><em>// 数组引用</em></span>
<span style="color:#4f4f4f !important">Function</span><Integer, <span style="color:#4f4f4f !important">String</span>[]> fun = (x) -> <span style="color:#000088 !important">new</span> <span style="color:#4f4f4f !important">String</span>[x];
<span style="color:#4f4f4f !important">Function</span><Integer, <span style="color:#4f4f4f !important">String</span>[]> fun2 = <span style="color:#4f4f4f !important">String</span>[]::<span style="color:#000088 !important">new</span>;
<span style="color:#4f4f4f !important">String</span>[] strArray = fun2.apply(<span style="color:#006666 !important">10</span>);
Arrays.stream(strArray).forEach(System.out::println);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
Stream API
Stream操作的三个步骤
- 创建stream
- 中间操作(过滤、map)
- 终止操作
stream的创建:
<span style="color:#000000"><code> <span style="color:#880000 !important"><em>// 1,校验通过Collection 系列集合提供的stream()或者paralleStream()</em></span>
List<<span style="color:#4f4f4f !important">String</span>> list = <span style="color:#000088 !important">new</span> ArrayList<>();
Strean<<span style="color:#4f4f4f !important">String</span>> stream1 = list.stream();
<span style="color:#880000 !important"><em>// 2.通过Arrays的静态方法stream()获取数组流</em></span>
<span style="color:#4f4f4f !important">String</span>[] str = <span style="color:#000088 !important">new</span> <span style="color:#4f4f4f !important">String</span>[<span style="color:#006666 !important">10</span>];
Stream<<span style="color:#4f4f4f !important">String</span>> stream2 = Arrays.stream(str);
<span style="color:#880000 !important"><em>// 3.通过Stream类中的静态方法of</em></span>
Stream<<span style="color:#4f4f4f !important">String</span>> stream3 = Stream.of(<span style="color:#009900 !important">"aa"</span>,<span style="color:#009900 !important">"bb"</span>,<span style="color:#009900 !important">"cc"</span>);
<span style="color:#880000 !important"><em>// 4.创建无限流</em></span>
<span style="color:#880000 !important"><em>// 迭代</em></span>
Stream<Integer> stream4 = Stream.iterate(<span style="color:#006666 !important">0</span>,(x) -> x+<span style="color:#006666 !important">2</span>);
<span style="color:#880000 !important"><em>//生成</em></span>
Stream.generate(() -><span style="color:#4f4f4f !important">Math</span>.random());</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
Stream的中间操作:
<span style="color:#000000"><code><span style="color:#880000 !important">/**
* 筛选 过滤 去重
*/</span>
emps.stream()
.filter(e -> e.getAge() > <span style="color:#006666 !important">10</span>)
.limit(<span style="color:#006666 !important">4</span>)
.skip(<span style="color:#006666 !important">4</span>)
<span style="color:#880000 !important"><em>// 需要流中的元素重写hashCode和equals方法</em></span>
.distinct()
.forEach(System.out::println);
<span style="color:#880000 !important">/**
* 生成新的流 通过map映射
*/</span>
emps.stream()
.map((e) -> e.getAge())
.forEach(System.out::println);
<span style="color:#880000 !important">/**
* 自然排序 定制排序
*/</span>
emps.stream()
.sorted((e1 ,e2) -> {
<span style="color:#000088 !important">if</span> (e1.getAge().equals(e2.getAge())){
<span style="color:#000088 !important">return</span> e1.getName().compareTo(e2.getName());
} <span style="color:#000088 !important">else</span>{
<span style="color:#000088 !important">return</span> e1.getAge().compareTo(e2.getAge());
}
})
.forEach(System.out::println);
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
Stream的终止操作:
<span style="color:#000000"><code> /**
* 查找和匹配
* allMatch-检查是否匹配所有元素
* anyMatch-检查是否至少匹配一个元素
* noneMatch-检查是否没有匹配所有元素
* findFirst-返回第一个元素
* findAny-返回当前流中的任意元素
* count-返回流中元素的总个数
* max-返回流中最大值
* min-返回流中最小值
*/
/**
* 检查是否匹配元素
*/
boolean b1 = emps.stream()
.allMatch<span style="color:#4f4f4f !important">((e) -> e.getStatus().equals(Employee.Status.BUSY))</span>;
<span style="color:#009900 !important">System</span>.<span style="color:#009900 !important">out</span>.<span style="color:#009900 !important">println</span><span style="color:#4f4f4f !important">(b1)</span>;
<span style="color:#009900 !important">boolean</span> <span style="color:#009900 !important">b2</span> = <span style="color:#009900 !important">emps</span>.<span style="color:#009900 !important">stream</span><span style="color:#4f4f4f !important">()</span>
.<span style="color:#009900 !important">anyMatch</span><span style="color:#4f4f4f !important">((e) -> e.getStatus().equals(Employee.Status.BUSY))</span>;
<span style="color:#009900 !important">System</span>.<span style="color:#009900 !important">out</span>.<span style="color:#009900 !important">println</span><span style="color:#4f4f4f !important">(b2)</span>;
<span style="color:#009900 !important">boolean</span> <span style="color:#009900 !important">b3</span> = <span style="color:#009900 !important">emps</span>.<span style="color:#009900 !important">stream</span><span style="color:#4f4f4f !important">()</span>
.<span style="color:#009900 !important">noneMatch</span><span style="color:#4f4f4f !important">((e) -> e.getStatus().equals(Employee.Status.BUSY))</span>;
<span style="color:#009900 !important">System</span>.<span style="color:#009900 !important">out</span>.<span style="color:#009900 !important">println</span><span style="color:#4f4f4f !important">(b3)</span>;
<span style="color:#009900 !important">Optional</span><<span style="color:#009900 !important">Employee</span>> <span style="color:#009900 !important">opt</span> = <span style="color:#009900 !important">emps</span>.<span style="color:#009900 !important">stream</span><span style="color:#4f4f4f !important">()</span>
.<span style="color:#009900 !important">findFirst</span><span style="color:#4f4f4f !important">()</span>;
<span style="color:#009900 !important">System</span>.<span style="color:#009900 !important">out</span>.<span style="color:#009900 !important">println</span><span style="color:#4f4f4f !important">(opt.get())</span>;
// 并行流
<span style="color:#009900 !important">Optional</span><<span style="color:#009900 !important">Employee</span>> <span style="color:#009900 !important">opt2</span> = <span style="color:#009900 !important">emps</span>.<span style="color:#009900 !important">parallelStream</span><span style="color:#4f4f4f !important">()</span>
.<span style="color:#009900 !important">findAny</span><span style="color:#4f4f4f !important">()</span>;
<span style="color:#009900 !important">System</span>.<span style="color:#009900 !important">out</span>.<span style="color:#009900 !important">println</span><span style="color:#4f4f4f !important">(opt2.get())</span>;
<span style="color:#009900 !important">long</span> <span style="color:#009900 !important">count</span> = <span style="color:#009900 !important">emps</span>.<span style="color:#009900 !important">stream</span><span style="color:#4f4f4f !important">()</span>
.<span style="color:#009900 !important">count</span><span style="color:#4f4f4f !important">()</span>;
<span style="color:#009900 !important">System</span>.<span style="color:#009900 !important">out</span>.<span style="color:#009900 !important">println</span><span style="color:#4f4f4f !important">(count)</span>;
<span style="color:#009900 !important">Optional</span><<span style="color:#009900 !important">Employee</span>> <span style="color:#009900 !important">max</span> = <span style="color:#009900 !important">emps</span>.<span style="color:#009900 !important">stream</span><span style="color:#4f4f4f !important">()</span>
.<span style="color:#009900 !important">max</span><span style="color:#4f4f4f !important">((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))</span>;
<span style="color:#009900 !important">System</span>.<span style="color:#009900 !important">out</span>.<span style="color:#009900 !important">println</span><span style="color:#4f4f4f !important">(max.get())</span>;
<span style="color:#009900 !important">Optional</span><<span style="color:#009900 !important">Employee</span>> <span style="color:#009900 !important">min</span> = <span style="color:#009900 !important">emps</span>.<span style="color:#009900 !important">stream</span><span style="color:#4f4f4f !important">()</span>
.<span style="color:#009900 !important">min</span><span style="color:#4f4f4f !important">((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))</span>;
<span style="color:#009900 !important">System</span>.<span style="color:#009900 !important">out</span>.<span style="color:#009900 !important">println</span><span style="color:#4f4f4f !important">(min.get())</span>;</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
还有功能比较强大的两个终止操作 reduce和collect
reduce操作: reduce:(T identity,BinaryOperator)/reduce(BinaryOperator)-可以将流中元素反复结合起来,得到一个值
<span style="color:#000000"><code> /**
* reduce :规约操作
*/
List<Integer> list = Arrays.asList(<span style="color:#006666 !important">1</span>,<span style="color:#006666 !important">2</span>,<span style="color:#006666 !important">3</span>,<span style="color:#006666 !important">4</span>,<span style="color:#006666 !important">5</span>,<span style="color:#006666 !important">6</span>,<span style="color:#006666 !important">7</span>,<span style="color:#006666 !important">8</span>,<span style="color:#006666 !important">9</span>,<span style="color:#006666 !important">10</span>);
Integer count2 = list.stream()
.reduce<span style="color:#4f4f4f !important">(<span style="color:#006666 !important">0</span>, (x, y) -> x + y)</span>;
<span style="color:#009900 !important">System</span>.<span style="color:#009900 !important">out</span>.<span style="color:#009900 !important">println</span><span style="color:#4f4f4f !important">(count2)</span>;
<span style="color:#009900 !important">Optional</span><<span style="color:#009900 !important">Double</span>> <span style="color:#009900 !important">sum</span> = <span style="color:#009900 !important">emps</span>.<span style="color:#009900 !important">stream</span><span style="color:#4f4f4f !important">()</span>
.<span style="color:#009900 !important">map</span><span style="color:#4f4f4f !important">(Employee::getSalary)</span>
.<span style="color:#009900 !important">reduce</span><span style="color:#4f4f4f !important">(Double::sum)</span>;
<span style="color:#009900 !important">System</span>.<span style="color:#009900 !important">out</span>.<span style="color:#009900 !important">println</span><span style="color:#4f4f4f !important">(sum)</span>;
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
collect操作:Collect-将流转换为其他形式,接收一个Collection接口的实现,用于给Stream中元素做汇总的方法
<span style="color:#000000"><code> <span style="color:#880000 !important">/**
* collect:收集操作
*/</span>
List<Integer> ageList = emps.stream()
.map(Employee::getAge)
.collect(Collectors.toList());
ageList.stream().forEach(System.out::println);</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
并行流和串行流
在jdk1.8新的stream包中针对集合的操作也提供了并行操作流和串行操作流。并行流就是把内容切割成多个数据块,并且使用多个线程分别处理每个数据块的内容。Stream api中声明可以通过parallel()与sequential()方法在并行流和串行流之间进行切换。
jdk1.8并行流使用的是fork/join框架进行并行操作
ForkJoin框架
Fork/Join 框架:就是在必要的情况下,将一个大任务,进行拆分(fork)成若干个小任务(拆到不可再拆时),再将一个个的小任务运算的结果进行 join 汇总。
关键字:递归分合、分而治之。
采用 “工作窃取”模式(work-stealing):
当执行新的任务时它可以将其拆分分成更小的任务执行,并将小任务加到线
程队列中,然后再从一个随机线程的队列中偷一个并把它放在自己的队列中
相对于一般的线程池实现,fork/join框架的优势体现在对其中包含的任务的
处理方式上.在一般的线程池中,如果一个线程正在执行的任务由于某些原因
无法继续运行,那么该线程会处于等待状态.而在fork/join框架实现中,如果
某个子问题由于等待另外一个子问题的完成而无法继续运行.那么处理该子
问题的线程会主动寻找其他尚未运行的子问题来执行.这种方式减少了线程
的等待时间,提高了性能.。
<span style="color:#000000"><code><span style="color:#880000 !important">/**
* 要想使用Fark—Join,类必须继承
* RecursiveAction(无返回值)
* Or
* RecursiveTask(有返回值)
*
*/</span>
public <span style="color:#000088 !important">class</span> <span style="color:#4f4f4f !important">ForkJoin</span> <span style="color:#000088 !important">extends</span> <span style="color:#4f4f4f !important">RecursiveTask</span><<span style="color:#4f4f4f !important">Long</span>> {
<span style="color:#880000 !important">/**
* 要想使用Fark—Join,类必须继承RecursiveAction(无返回值) 或者
* RecursiveTask(有返回值)
*
* <span style="color:#4f4f4f !important">@author</span> Wuyouxin
*/</span>
<span style="color:#000088 !important">private</span> static <span style="color:#000088 !important">final</span> long serialVersionUID = <span style="color:#006666 !important">23423422</span>L;
<span style="color:#000088 !important">private</span> long start;
<span style="color:#000088 !important">private</span> long end;
public ForkJoin() {
}
public ForkJoin(long start, long end) {
<span style="color:#000088 !important">this</span>.start = start;
<span style="color:#000088 !important">this</span>.end = end;
}
<span style="color:#880000 !important"><em>// 定义阙值</em></span>
<span style="color:#000088 !important">private</span> static <span style="color:#000088 !important">final</span> long THRESHOLD = <span style="color:#006666 !important">10000</span>L;
<span style="color:#9b859d !important">@Override</span>
<span style="color:#000088 !important">protected</span> Long compute() {
<span style="color:#000088 !important">if</span> (end - start <= THRESHOLD) {
long sum = <span style="color:#006666 !important">0</span>;
<span style="color:#000088 !important">for</span> (long i = start; i < end; i++) {
sum += i;
}
<span style="color:#000088 !important">return</span> sum;
} <span style="color:#000088 !important">else</span> {
long middle = (end - start) / <span style="color:#006666 !important">2</span>;
ForkJoin left = <span style="color:#000088 !important">new</span> ForkJoin(start, middle);
<span style="color:#880000 !important"><em>//拆分子任务,压入线程队列</em></span>
left.fork();
ForkJoin right = <span style="color:#000088 !important">new</span> ForkJoin(middle + <span style="color:#006666 !important">1</span>, end);
right.fork();
<span style="color:#880000 !important"><em>//合并并返回</em></span>
<span style="color:#000088 !important">return</span> left.join() + right.join();
}
}
<span style="color:#880000 !important">/**
* 实现数的累加
*/</span>
<span style="color:#9b859d !important">@Test</span>
public void test1() {
<span style="color:#880000 !important"><em>//开始时间</em></span>
Instant start = Instant.now();
<span style="color:#880000 !important"><em>//这里需要一个线程池的支持</em></span>
ForkJoinPool pool = <span style="color:#000088 !important">new</span> ForkJoinPool();
ForkJoinTask<Long> task = <span style="color:#000088 !important">new</span> ForkJoin(<span style="color:#006666 !important">0</span>L, <span style="color:#006666 !important">10000000000</span>L);
<span style="color:#880000 !important"><em>// 没有返回值 pool.execute();</em></span>
<span style="color:#880000 !important"><em>// 有返回值</em></span>
long sum = pool.invoke(task);
<span style="color:#880000 !important"><em>//结束时间</em></span>
Instant end = Instant.now();
System.out.println(Duration.between(start, end).getSeconds());
}
<span style="color:#880000 !important">/**
* java8 并行流 parallel()
*/</span>
<span style="color:#9b859d !important">@Test</span>
public void test2() {
<span style="color:#880000 !important"><em>//开始时间</em></span>
Instant start = Instant.now();
<span style="color:#880000 !important"><em>// 并行流计算 累加求和</em></span>
LongStream.rangeClosed(<span style="color:#006666 !important">0</span>, <span style="color:#006666 !important">10000000000</span>L).parallel()
.reduce(<span style="color:#006666 !important">0</span>, Long :: sum);
<span style="color:#880000 !important"><em>//结束时间</em></span>
Instant end = Instant.now();
System.out.println(Duration.between(start, end).getSeconds());
}
<span style="color:#9b859d !important">@Test</span>
public void test3(){
List<Integer> list = Arrays.asList(<span style="color:#006666 !important">1</span>, <span style="color:#006666 !important">2</span>, <span style="color:#006666 !important">3</span>, <span style="color:#006666 !important">4</span>, <span style="color:#006666 !important">5</span>);
list.stream().forEach(System.out::print);
list.parallelStream()
.forEach(System.out::print);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
展示多线程的效果:
<span style="color:#000000"><code>@Test
public void test(){
// 并行流 多个线程执行
List<Integer> numbers = Arrays<span style="color:#009900 !important">.asList</span>(<span style="color:#006666 !important">1</span>, <span style="color:#006666 !important">2</span>, <span style="color:#006666 !important">3</span>, <span style="color:#006666 !important">4</span>, <span style="color:#006666 !important">5</span>, <span style="color:#006666 !important">6</span>, <span style="color:#006666 !important">7</span>, <span style="color:#006666 !important">8</span>, <span style="color:#006666 !important">9</span>)<span style="color:#880000 !important"><em>;</em></span>
numbers<span style="color:#009900 !important">.parallelStream</span>()
<span style="color:#009900 !important">.forEach</span>(System<span style="color:#009900 !important">.out</span>::print)<span style="color:#880000 !important"><em>;</em></span>
//
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(<span style="color:#009900 !important">"========================="</span>)<span style="color:#880000 !important"><em>;</em></span>
numbers<span style="color:#009900 !important">.stream</span>()
<span style="color:#009900 !important">.sequential</span>()
<span style="color:#009900 !important">.forEach</span>(System<span style="color:#009900 !important">.out</span>::print)<span style="color:#880000 !important"><em>;</em></span>
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
Optional容器
<span style="color:#000000"><code>使用Optional容器可以快速的定位NPE,并且在一定程度上可以减少对参数非空检验的代码量。
</code></span>
- 1
<span style="color:#000000"><code><span style="color:#880000 !important"><em>/**
* 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类似。返回值是Optional
*
* 总结:Optional.of(null) 会直接报NPE
*/</em></span>
Optional<Employee> op = Optional<span style="color:#009900 !important">.of</span>(new Employee(<span style="color:#009900 !important">"zhansan"</span>, <span style="color:#006666 !important">11</span>, <span style="color:#006666 !important">12.32</span>, Employee<span style="color:#009900 !important">.Status</span><span style="color:#009900 !important">.BUSY</span>))<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(op<span style="color:#009900 !important">.get</span>())<span style="color:#880000 !important"><em>;</em></span>
// NPE
Optional<Employee> op2 = Optional<span style="color:#009900 !important">.of</span>(null)<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(op2)<span style="color:#880000 !important"><em>;</em></span>
@Test
public void test2(){
Optional<Object> op = Optional<span style="color:#009900 !important">.empty</span>()<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(op)<span style="color:#880000 !important"><em>;</em></span>
// No value present
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(op<span style="color:#009900 !important">.get</span>())<span style="color:#880000 !important"><em>;</em></span>
}
@Test
public void test3(){
Optional<Employee> op = Optional<span style="color:#009900 !important">.ofNullable</span>(new Employee(<span style="color:#009900 !important">"lisi"</span>, <span style="color:#006666 !important">33</span>, <span style="color:#006666 !important">131.42</span>, Employee<span style="color:#009900 !important">.Status</span><span style="color:#009900 !important">.FREE</span>))<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(op<span style="color:#009900 !important">.get</span>())<span style="color:#880000 !important"><em>;</em></span>
Optional<Object> op2 = Optional<span style="color:#009900 !important">.ofNullable</span>(null)<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(op2)<span style="color:#880000 !important"><em>;</em></span>
// System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(op2<span style="color:#009900 !important">.get</span>())<span style="color:#880000 !important"><em>;</em></span>
}
@Test
public void test5(){
Optional<Employee> op1 = Optional<span style="color:#009900 !important">.ofNullable</span>(new Employee(<span style="color:#009900 !important">"张三"</span>, <span style="color:#006666 !important">11</span>, <span style="color:#006666 !important">11.33</span>, Employee<span style="color:#009900 !important">.Status</span><span style="color:#009900 !important">.VOCATION</span>))<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(op1<span style="color:#009900 !important">.orElse</span>(new Employee()))<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(op1<span style="color:#009900 !important">.orElse</span>(null))<span style="color:#880000 !important"><em>;</em></span>
}
@Test
public void test6(){
Optional<Employee> op1 = Optional<span style="color:#009900 !important">.of</span>(new Employee(<span style="color:#009900 !important">"田七"</span>, <span style="color:#006666 !important">11</span>, <span style="color:#006666 !important">12.31</span>, Employee<span style="color:#009900 !important">.Status</span><span style="color:#009900 !important">.BUSY</span>))<span style="color:#880000 !important"><em>;</em></span>
op1 = Optional<span style="color:#009900 !important">.empty</span>()<span style="color:#880000 !important"><em>;</em></span>
Employee employee = op1<span style="color:#009900 !important">.orElseGet</span>(() -> new Employee())<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(employee)<span style="color:#880000 !important"><em>;</em></span>
}
@Test
public void test7(){
Optional<Employee> op1 = Optional<span style="color:#009900 !important">.of</span>(new Employee(<span style="color:#009900 !important">"田七"</span>, <span style="color:#006666 !important">11</span>, <span style="color:#006666 !important">12.31</span>, Employee<span style="color:#009900 !important">.Status</span><span style="color:#009900 !important">.BUSY</span>))<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(op1<span style="color:#009900 !important">.map</span>( (e) -> e<span style="color:#009900 !important">.getSalary</span>())<span style="color:#009900 !important">.get</span>())<span style="color:#880000 !important"><em>;</em></span>
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
接口中可以定义默认实现方法和静态方法
在接口中可以使用default和static关键字来修饰接口中定义的普通方法
<span style="color:#000000"><code><span style="color:#000088 !important">public</span> <span style="color:#000088 !important">interface</span> Interface {
<span style="color:#000088 !important">default</span> String getName(){
<span style="color:#000088 !important">return</span> <span style="color:#009900 !important">"zhangsan"</span>;
}
<span style="color:#000088 !important">static</span> String getName2(){
<span style="color:#000088 !important">return</span> <span style="color:#009900 !important">"zhangsan"</span>;
}
}
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
在JDK1.8中很多接口会新增方法,为了保证1.8向下兼容,1.7版本中的接口实现类不用每个都重新实现新添加的接口方法,引入了default默认实现,static的用法是直接用接口名去调方法即可。当一个类继承父类又实现接口时,若后两者方法名相同,则优先继承父类中的同名方法,即“类优先”,如果实现两个同名方法的接口,则要求实现类必须手动声明默认实现哪个接口中的方法。
新的日期API LocalDate | LocalTime | LocalDateTime
新的日期API都是不可变的,更使用于多线程的使用环境中
<span style="color:#000000"><code> @Test
public void test(){
// 从默认时区的系统时钟获取当前的日期时间。不用考虑时区差
LocalDateTime date = LocalDateTime<span style="color:#009900 !important">.now</span>()<span style="color:#880000 !important"><em>;</em></span>
//<span style="color:#006666 !important">2018</span>-<span style="color:#006666 !important">07</span>-<span style="color:#006666 !important">15</span>T14:<span style="color:#006666 !important">22</span>:<span style="color:#006666 !important">39.759</span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(date)<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(date<span style="color:#009900 !important">.getYear</span>())<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(date<span style="color:#009900 !important">.getMonthValue</span>())<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(date<span style="color:#009900 !important">.getDayOfMonth</span>())<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(date<span style="color:#009900 !important">.getHour</span>())<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(date<span style="color:#009900 !important">.getMinute</span>())<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(date<span style="color:#009900 !important">.getSecond</span>())<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(date<span style="color:#009900 !important">.getNano</span>())<span style="color:#880000 !important"><em>;</em></span>
// 手动创建一个LocalDateTime实例
LocalDateTime date2 = LocalDateTime<span style="color:#009900 !important">.of</span>(<span style="color:#006666 !important">2017</span>, <span style="color:#006666 !important">12</span>, <span style="color:#006666 !important">17</span>, <span style="color:#006666 !important">9</span>, <span style="color:#006666 !important">31</span>, <span style="color:#006666 !important">31</span>, <span style="color:#006666 !important">31</span>)<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(date2)<span style="color:#880000 !important"><em>;</em></span>
// 进行加操作,得到新的日期实例
LocalDateTime date3 = date2<span style="color:#009900 !important">.plusDays</span>(<span style="color:#006666 !important">12</span>)<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(date3)<span style="color:#880000 !important"><em>;</em></span>
// 进行减操作,得到新的日期实例
LocalDateTime date4 = date3<span style="color:#009900 !important">.minusYears</span>(<span style="color:#006666 !important">2</span>)<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(date4)<span style="color:#880000 !important"><em>;</em></span>
}
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
<span style="color:#000000"><code> @Test
public void test2(){
// 时间戳 <span style="color:#006666 !important">1970</span>年<span style="color:#006666 !important">1</span>月<span style="color:#006666 !important">1</span>日<span style="color:#006666 !important">00</span>:<span style="color:#006666 !important">00</span>:<span style="color:#006666 !important">00</span> 到某一个时间点的毫秒值
// 默认获取UTC时区
Instant ins = Instant<span style="color:#009900 !important">.now</span>()<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(ins)<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(LocalDateTime<span style="color:#009900 !important">.now</span>()<span style="color:#009900 !important">.toInstant</span>(ZoneOffset<span style="color:#009900 !important">.of</span>(<span style="color:#009900 !important">"+8"</span>))<span style="color:#009900 !important">.toEpochMilli</span>())<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(System<span style="color:#009900 !important">.currentTimeMillis</span>())<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(Instant<span style="color:#009900 !important">.now</span>()<span style="color:#009900 !important">.toEpochMilli</span>())<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(Instant<span style="color:#009900 !important">.now</span>()<span style="color:#009900 !important">.atOffset</span>(ZoneOffset<span style="color:#009900 !important">.ofHours</span>(<span style="color:#006666 !important">8</span>))<span style="color:#009900 !important">.toInstant</span>()<span style="color:#009900 !important">.toEpochMilli</span>())<span style="color:#880000 !important"><em>;</em></span>
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
<span style="color:#000000"><code> @Test
public void test3(){
// Duration:计算两个时间之间的间隔
// Period:计算两个日期之间的间隔
Instant ins1 = Instant<span style="color:#009900 !important">.now</span>()<span style="color:#880000 !important"><em>;</em></span>
try {
Thread<span style="color:#009900 !important">.sleep</span>(<span style="color:#006666 !important">1000</span>)<span style="color:#880000 !important"><em>;</em></span>
} catch (InterruptedException e) {
e<span style="color:#009900 !important">.printStackTrace</span>()<span style="color:#880000 !important"><em>;</em></span>
}
Instant ins2 = Instant<span style="color:#009900 !important">.now</span>()<span style="color:#880000 !important"><em>;</em></span>
Duration dura = Duration<span style="color:#009900 !important">.between</span>(ins1, ins2)<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(dura)<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(dura<span style="color:#009900 !important">.toMillis</span>())<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(<span style="color:#009900 !important">"======================"</span>)<span style="color:#880000 !important"><em>;</em></span>
LocalTime localTime = LocalTime<span style="color:#009900 !important">.now</span>()<span style="color:#880000 !important"><em>;</em></span>
try {
Thread<span style="color:#009900 !important">.sleep</span>(<span style="color:#006666 !important">1000</span>)<span style="color:#880000 !important"><em>;</em></span>
} catch (InterruptedException e) {
e<span style="color:#009900 !important">.printStackTrace</span>()<span style="color:#880000 !important"><em>;</em></span>
}
LocalTime localTime2 = LocalTime<span style="color:#009900 !important">.now</span>()<span style="color:#880000 !important"><em>;</em></span>
Duration du2 = Duration<span style="color:#009900 !important">.between</span>(localTime, localTime2)<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(du2)<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(du2<span style="color:#009900 !important">.toMillis</span>())<span style="color:#880000 !important"><em>;</em></span>
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
<span style="color:#000000"><code>@Test
<span style="color:#000088 !important">public</span> <span style="color:#000088 !important">void</span> <span style="color:#009900 !important">test4</span>(){
LocalDate localDate =LocalDate.now();
<span style="color:#000088 !important">try</span> {
Thread.sleep(<span style="color:#006666 !important">1000</span>);
} <span style="color:#000088 !important">catch</span> (InterruptedException e) {
e.printStackTrace();
}
LocalDate localDate2 = LocalDate.of(<span style="color:#006666 !important">2016</span>,<span style="color:#006666 !important">12</span>,<span style="color:#006666 !important">12</span>);
Period pe = Period.between(localDate, localDate2);
System.<span style="color:#000088 !important">out</span>.println(pe);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
<span style="color:#000000"><code> @Test
public void test5(){
// temperalAdjust 时间校验器
// 例如获取下周日 下一个工作日
LocalDateTime ldt1 = LocalDateTime<span style="color:#009900 !important">.now</span>()<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(ldt1)<span style="color:#880000 !important"><em>;</em></span>
// 获取一年中的第一天
LocalDateTime ldt2 = ldt1<span style="color:#009900 !important">.withDayOfYear</span>(<span style="color:#006666 !important">1</span>)<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(ldt2)<span style="color:#880000 !important"><em>;</em></span>
// 获取一个月中的第一天
LocalDateTime ldt3 = ldt1<span style="color:#009900 !important">.withDayOfMonth</span>(<span style="color:#006666 !important">1</span>)<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(ldt3)<span style="color:#880000 !important"><em>;</em></span>
LocalDateTime ldt4 = ldt1<span style="color:#009900 !important">.with</span>(TemporalAdjusters<span style="color:#009900 !important">.next</span>(DayOfWeek<span style="color:#009900 !important">.FRIDAY</span>))<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(ldt4)<span style="color:#880000 !important"><em>;</em></span>
// 获取下一个工作日
LocalDateTime ldt5 = ldt1<span style="color:#009900 !important">.with</span>((t) -> {
LocalDateTime ldt6 = (LocalDateTime)t<span style="color:#880000 !important"><em>;</em></span>
DayOfWeek dayOfWeek = ldt6<span style="color:#009900 !important">.getDayOfWeek</span>()<span style="color:#880000 !important"><em>;</em></span>
if (DayOfWeek<span style="color:#009900 !important">.FRIDAY</span><span style="color:#009900 !important">.equals</span>(dayOfWeek)){
return ldt6<span style="color:#009900 !important">.plusDays</span>(<span style="color:#006666 !important">3</span>)<span style="color:#880000 !important"><em>;</em></span>
}
else if (DayOfWeek<span style="color:#009900 !important">.SATURDAY</span><span style="color:#009900 !important">.equals</span>(dayOfWeek)){
return ldt6<span style="color:#009900 !important">.plusDays</span>(<span style="color:#006666 !important">2</span>)<span style="color:#880000 !important"><em>;</em></span>
}
else {
return ldt6<span style="color:#009900 !important">.plusDays</span>(<span style="color:#006666 !important">1</span>)<span style="color:#880000 !important"><em>;</em></span>
}
})<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(ldt5)<span style="color:#880000 !important"><em>;</em></span>
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
<span style="color:#000000"><code> @Test
public void test6(){
// DateTimeFormatter: 格式化时间/日期
// 自定义格式
LocalDateTime ldt = LocalDateTime<span style="color:#009900 !important">.now</span>()<span style="color:#880000 !important"><em>;</em></span>
DateTimeFormatter formatter = DateTimeFormatter<span style="color:#009900 !important">.ofPattern</span>(<span style="color:#009900 !important">"yyyy年MM月dd日"</span>)<span style="color:#880000 !important"><em>;</em></span>
String strDate1 = ldt<span style="color:#009900 !important">.format</span>(formatter)<span style="color:#880000 !important"><em>;</em></span>
String strDate = formatter<span style="color:#009900 !important">.format</span>(ldt)<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(strDate)<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(strDate1)<span style="color:#880000 !important"><em>;</em></span>
// 使用api提供的格式
DateTimeFormatter dtf = DateTimeFormatter<span style="color:#009900 !important">.ISO</span>_DATE<span style="color:#880000 !important"><em>;</em></span>
LocalDateTime ldt2 = LocalDateTime<span style="color:#009900 !important">.now</span>()<span style="color:#880000 !important"><em>;</em></span>
String strDate3 = dtf<span style="color:#009900 !important">.format</span>(ldt2)<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(strDate3)<span style="color:#880000 !important"><em>;</em></span>
// 解析字符串to时间
DateTimeFormatter df = DateTimeFormatter<span style="color:#009900 !important">.ofPattern</span>(<span style="color:#009900 !important">"yyyy-MM-dd HH:mm:ss"</span>)<span style="color:#880000 !important"><em>;</em></span>
LocalDateTime time = LocalDateTime<span style="color:#009900 !important">.now</span>()<span style="color:#880000 !important"><em>;</em></span>
String localTime = df<span style="color:#009900 !important">.format</span>(time)<span style="color:#880000 !important"><em>;</em></span>
LocalDateTime ldt4 = LocalDateTime<span style="color:#009900 !important">.parse</span>(<span style="color:#009900 !important">"2017-09-28 17:07:05"</span>,df)<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(<span style="color:#009900 !important">"LocalDateTime转成String类型的时间:"</span>+localTime)<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(<span style="color:#009900 !important">"String类型的时间转成LocalDateTime:"</span>+ldt4)<span style="color:#880000 !important"><em>;</em></span>
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
<span style="color:#000000"><code> // ZoneTime ZoneDate ZoneDateTime
@Test
public void test7(){
LocalDateTime now = LocalDateTime<span style="color:#009900 !important">.now</span>(ZoneId<span style="color:#009900 !important">.of</span>(<span style="color:#009900 !important">"Asia/Shanghai"</span>))<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(now)<span style="color:#880000 !important"><em>;</em></span>
LocalDateTime now2 = LocalDateTime<span style="color:#009900 !important">.now</span>()<span style="color:#880000 !important"><em>;</em></span>
ZonedDateTime zdt = now2<span style="color:#009900 !important">.atZone</span>(ZoneId<span style="color:#009900 !important">.of</span>(<span style="color:#009900 !important">"Asia/Shanghai"</span>))<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(zdt)<span style="color:#880000 !important"><em>;</em></span>
<span style="color:#000088 !important">Set</span><String> <span style="color:#000088 !important">set</span> = ZoneId<span style="color:#009900 !important">.getAvailableZoneIds</span>()<span style="color:#880000 !important"><em>;</em></span>
<span style="color:#000088 !important">set</span><span style="color:#009900 !important">.stream</span>()<span style="color:#009900 !important">.forEach</span>(System<span style="color:#009900 !important">.out</span>::println)<span style="color:#880000 !important"><em>;</em></span>
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
补充:
表示日期的LocalDate
表示时间的LocalTime
表示日期时间的LocalDateTime
新的日期API的几个优点:
<span style="color:#000000"><code> * 之前使用的java.util.Date月份从0开始,我们一般会+1使用,很不方便,java.time.LocalDate月份和星期都改成了enum
* java.util.Date和SimpleDateFormat都不是线程安全的,而LocalDate和LocalTime和最基本的String一样,是不变类型,不但线程安全,而且不能修改。
* java.util.Date是一个“万能接口”,它包含日期、时间,还有毫秒数,更加明确需求取舍
* 新接口更好用的原因是考虑到了日期时间的操作,经常发生往前推或往后推几天的情况。用java.util.Date配合Calendar要写好多代码,而且一般的开发人员还不一定能写对。
</code></span>
- 1
- 2
- 3
- 4
- LocalDate
<span style="color:#000000"><code><span style="color:#000088 !important">public</span> <span style="color:#000088 !important">static</span> <span style="color:#000088 !important">void</span> <span style="color:#009900 !important">localDateTest</span>() {
<span style="color:#880000 !important"><em>//获取当前日期,只含年月日 固定格式 yyyy-MM-dd 2018-05-04</em></span>
LocalDate today = LocalDate.now();
<span style="color:#880000 !important"><em>// 根据年月日取日期,5月就是5,</em></span>
LocalDate oldDate = LocalDate.of(<span style="color:#006666 !important">2018</span>, <span style="color:#006666 !important">5</span>, <span style="color:#006666 !important">1</span>);
<span style="color:#880000 !important"><em>// 根据字符串取:默认格式yyyy-MM-dd,02不能写成2</em></span>
LocalDate yesteday = LocalDate.parse(<span style="color:#009900 !important">"2018-05-03"</span>);
<span style="color:#880000 !important"><em>// 如果不是闰年 传入29号也会报错</em></span>
LocalDate.parse(<span style="color:#009900 !important">"2018-02-29"</span>);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- LocalDate常用转化
<span style="color:#000000"><code> <span style="color:#880000 !important">/**
* 日期转换常用,第一天或者最后一天...
*/</span>
<span style="color:#000088 !important">public</span> <span style="color:#000088 !important">static</span> <span style="color:#000088 !important">void</span> <span style="color:#009900 !important">localDateTransferTest</span>(){
<span style="color:#880000 !important"><em>//2018-05-04</em></span>
LocalDate today = LocalDate.now();
<span style="color:#880000 !important"><em>// 取本月第1天: 2018-05-01</em></span>
LocalDate firstDayOfThisMonth = today.with(TemporalAdjusters.firstDayOfMonth());
<span style="color:#880000 !important"><em>// 取本月第2天:2018-05-02</em></span>
LocalDate secondDayOfThisMonth = today.withDayOfMonth(<span style="color:#006666 !important">2</span>);
<span style="color:#880000 !important"><em>// 取本月最后一天,再也不用计算是28,29,30还是31: 2018-05-31</em></span>
LocalDate lastDayOfThisMonth = today.with(TemporalAdjusters.lastDayOfMonth());
<span style="color:#880000 !important"><em>// 取下一天:2018-06-01</em></span>
LocalDate firstDayOf2015 = lastDayOfThisMonth.plusDays(<span style="color:#006666 !important">1</span>);
<span style="color:#880000 !important"><em>// 取2018年10月第一个周三 so easy?: 2018-10-03</em></span>
LocalDate thirdMondayOf2018 = LocalDate.parse(<span style="color:#009900 !important">"2018-10-01"</span>).with(TemporalAdjusters.firstInMonth(DayOfWeek.WEDNESDAY));
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- LocalTime
<span style="color:#000000"><code> <span style="color:#000088 !important">public</span> <span style="color:#000088 !important">static</span> <span style="color:#000088 !important">void</span> <span style="color:#009900 !important">localTimeTest</span>(){
<span style="color:#880000 !important"><em>//16:25:46.448(纳秒值)</em></span>
LocalTime todayTimeWithMillisTime = LocalTime.now();
<span style="color:#880000 !important"><em>//16:28:48 不带纳秒值</em></span>
LocalTime todayTimeWithNoMillisTime = LocalTime.now().withNano(<span style="color:#006666 !important">0</span>);
LocalTime time1 = LocalTime.parse(<span style="color:#009900 !important">"23:59:59"</span>);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- LocalDateTime
<span style="color:#000000"><code>public static void localDateTimeTest(){
//转化为时间戳 毫秒值
long time1 = LocalDateTime<span style="color:#009900 !important">.now</span>()<span style="color:#009900 !important">.toInstant</span>(ZoneOffset<span style="color:#009900 !important">.of</span>(<span style="color:#009900 !important">"+8"</span>))<span style="color:#009900 !important">.toEpochMilli</span>()<span style="color:#880000 !important"><em>;</em></span>
long time2 = System<span style="color:#009900 !important">.currentTimeMillis</span>()<span style="color:#880000 !important"><em>;</em></span>
//时间戳转化为localdatetime
DateTimeFormatter df= DateTimeFormatter<span style="color:#009900 !important">.ofPattern</span>(<span style="color:#009900 !important">"YYYY-MM-dd HH:mm:ss.SSS"</span>)<span style="color:#880000 !important"><em>;</em></span>
System<span style="color:#009900 !important">.out</span><span style="color:#009900 !important">.println</span>(df<span style="color:#009900 !important">.format</span>(LocalDateTime<span style="color:#009900 !important">.ofInstant</span>(Instant<span style="color:#009900 !important">.ofEpochMilli</span>(time1),ZoneId<span style="color:#009900 !important">.of</span>(<span style="color:#009900 !important">"Asia/Shanghai"</span>))))<span style="color:#880000 !important"><em>;</em></span>
}</code></span>