JDK1.8 新特性(全)

https://blog.csdn.net/qq_29411737/article/details/80835658

JDK1.8 新特性(全)

2018年06月27日 22:01:54  阅读数: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>

猜你喜欢

转载自blog.csdn.net/u013452335/article/details/85006798