• jdk新特性


    1.1 lambda表达式

    一、处理匿名内部类

    1、Runnable接口

    1         new Thread(new Runnable() {
    2             public void run() {
    3                 System.out.println("hello world!!!");
    4             }
    5         }).start();
    6         
    7         // lambda
    8         new Thread(()->System.out.println("hello lambda!!!")).start();

    说明:

    • 上边的方式是原本匿名内部类方式
    • 下边的方法是lambda表达式方式

    lambda基本语法:(形参列表)->{方法体}

    注意:

    • 形参列表:(String x, String y)这样的基本形式
      • 如果没有形参,使用"()",如上
      • 如果参数类型可以被推断出来,使用(x,y)
      • 如果是单个参数且类型可以被推断出来,直接使用x
    • 方法体:如果只有一句话,可以去掉"{}",如上

    2、Comparator接口

     1         List<String> strList = Arrays.asList("zhaojigang","nana","tianya");
     2         //原来的方式
     3         Collections.sort(strList, new Comparator<String>() {
     4             @Override
     5             public int compare(String s1, String s2) {
     6                 return s1.compareTo(s2);
     7             }
     8         });
     9         
    10         //lambda
    11         Collections.sort(strList, (s1, s2)->s1.compareTo(s2));

    说明:这里的s1和s2就被根据comparator的泛型和strList的泛型推断出了类型为String,可以省略参数类型。

    二、方法引用

    1         //lambda
    2         Collections.sort(strList, (s1, s2)->s1.compareTo(s2));
    3         //方法引用
    4         Collections.sort(strList, String::compareTo);
    5         //lambda
    6         strList.forEach(x->System.out.println(x));
    7         //方法引用
    8         strList.forEach(System.out::println);

    说明:

    • 前两个语句效果一样,后两个效果一样,自己比对方法引用与lambda的哪些部分等价
    • 集合类的foreach方法就是增强型for循环的再增强。

    注意:

    • 方法引用的语法
      • 对象::实例方法=>等价于"提供方法参数的lambda表达式"
      • 类::静态方法=>等价于"提供方法参数的lambda表达式"
        • eg. System.out::println等价于x->System.out.println(x)
      • 类::实例方法=>第一个参数是执行方法的对象
        • eg. String::compareTo等价于(s1, s2)->s1.compareTo(s2)

    三、局部变量

    lambda操作的局部变量必须是final型的,即:在lambda表达式所使用到的局部变量(方法体内的变量或形参)只能被读取,不能被改变。

    注意:列出这条约束的原因是防止线程不安全,可能会有疑问,局部变量是方法私有的,怎么会有线程安全问题?

    解释:假设我在该方法体内,启动了一个线程并使用lambda表达式去操作一个局部变量count(注意该变量并没有在lambda中进行声明,但是lambda却可以用,这就是"闭包"),而在该线程外且在该方法体内,该方法也操作了count,这时可能就会有线程安全问题了。

    四、接口的改变

    java的接口也可以写实现default级别的实例方法和静态方法了。

     1 public interface LambdaInterface {
     2     //default方法
     3     default void defaultMethod(){
     4         System.out.println("xxxx");
     5     }
     6     //static方法
     7     static void staticMethod(){
     8         System.out.println("xxxx");
     9     }
    10 }
    1 public class TestInterface implements LambdaInterface{
    2     public static void main(String[] args) {
    3         LambdaInterface test = new TestInterface();
    4         test.defaultMethod();//default方法测试
    5         
    6         LambdaInterface.staticMethod();//static方法测试
    7     }
    8 }

    用途:当改造老的项目时,想在旧的接口中添加一些方法,但是又不想让该接口的旧的实现类去实现这些方法时,可以使用这个技巧。

    1.2 Stream API

    引例:

    1         List<String> strList = Arrays.asList("zhaojigang","nana","tianya","nana");
    2         Stream<String> streamList = strList.stream();//集合转为stream
    3         strList = streamList.distinct().filter(str->!str.equals("tianya")).sorted(String::compareTo).collect(Collectors.toList());
    4         strList.forEach(System.out::println);

    说明:

    • 第一行:创建数组并转为List
    • 第二行:根据List创建stream
    • 第三行:对该stream进行去重-->选择-->排序-->stream转为List
    • 第四行:遍历该List

    以上代码显示了stream API的方便。当然,上边的代码可以更为简洁,如下改为一行:

    Arrays.asList("zhaojigang","nana","tianya","nana").stream().distinct().filter(str->!str.equals("tianya")).sorted(String::compareTo).collect(Collectors.toList()).forEach(System.out::println);

    以上代码有一个易错点:filter是选择而不是过滤,即filter是选择满足条件的元素

    一、创建Stream

    三种常用API:

    • 集合-->Stream:stream()
    • 数组-->Stream:Stream.of(T t)或者Arrays.stream(T[] t)
    • 任意元素-->Stream:Stream.of(T... values)
     1         List<String> strList = Arrays.asList("zhaojigang","nana","tianya","nana");
     2         Stream<String> streamList = strList.stream();//集合转为stream
     3         
     4         String[] strArray = {"java","c++","c"};
     5         Stream<String> streamArray = Stream.of(strArray);//数组转为Stream
     6         Stream<String> streamArray2 = Arrays.stream(strArray);//数组转为Stream
     7         
     8         Stream<String> streamPartArray = Arrays.stream(strArray, 0, 2);//转换部分数组,范围:[0,2)
     9         
    10         Stream<String> streamSelf = Stream.of("python","basic","php");//任意元素

    还有一种:用于产生无限流的,Stream.generate(Supplier<T> s)。

    二、Stream 2 array/collection/String/map

    1、stream2array

    1         Stream<String> strStream = Stream.of("java","c++","c","python");
    2         Object[] objectArray = strStream.toArray();//只能返回Object[]
    3         String[] strArray = strStream.toArray(String[]::new);//构造器引用(类似于方法引用),可以返回String[]

    说明:

    通过构造器引用(类似于方法引用),可以构造出具体类型的数组。

    2、stream2collection

    1         List<String> strList = strStream.collect(Collectors.toList());//返回List
    2         Set<String> strSet = strStream.collect(Collectors.toSet());//返回set
    3         ArrayList<String> strArrayList = strStream.collect(Collectors.toCollection(ArrayList::new));//收集到指定的List集合,例如收集到ArrayList

    说明:

    通过构造器引用,可以构造出具体类型的集合。

    3、将stream中的元素拼接起来(joining()、joining(","))

    1         Stream<String> strStream = Stream.of("java","c++","c","python");
    2         String str = strStream.collect(Collectors.joining());//将所有字符串拼接起来,结果:javac++cpython
    3         System.out.println(str);
    4         
    5         String str2 = strStream.collect(Collectors.joining(","));//将所有字符串拼接起来,中间用","隔开,结果:java,c++,c,python
    6         System.out.println(str2);

    4、stream2map(toMap、toConcurrentMap)

     1         Stream<String> strStream = Stream.of("java","c++","c","python");
     2         Map<String, Integer> map1 = strStream.collect(Collectors.toMap(Function.identity(), (x)->0));
     3         //Function.identity()-->返回strStream中的元素,toMap方法的我两个参数都是Function接口型的,所以第二个参数即使只放0,也不能直接写作0,可以使用如上的方式进行操作
     4         
     5         for(String key : map1.keySet()){
     6             System.out.println("key:"+key+"->"+"value:"+map1.get(key));
     7         }
     8         //结果
     9         /*
    10         key:python->value:0
    11         key:c++->value:0
    12         key:c->value:0
    13         key:java->value:0
    14          */

    说明:

    • toMap-->stream转为map
    • Function.identity()-->返回stream中的元素

    如果key重复的话,这时就会出现问题"duplicate key",采用如下方式解决(增加第三个参数):

    1         Stream<String> strStream = Stream.of("java","c++","c","python","java");
    2         Map<String, Integer> map1 = strStream.collect(Collectors.toMap(Function.identity(), //key
    3                                                                         (x)->0,             //value
    4                                                                         (existingValue, newValue) -> existingValue));//如果key重复,取旧值

    需要指定返回map的具体类型(增加第四个参数)。

    1         Map<String, Integer> map1 = strStream.collect(Collectors.toMap(Function.identity(), //key
    2                                                                         (x)->0,             //value
    3                                                                         (existingValue, newValue) -> existingValue,//如果key重复,取旧值
    4                                                                         TreeMap::new));//返回TreeMap

    注意:每一个toMap就会对应一个相应的toConcurrentMap

    5、groupingBy partitioningBy

     1         /***************************groupingBy partitioningBy**************************/
     2         Stream<Locale> localeStream = Stream.of(Locale.getAvailableLocales());
     3         Map<String, List<Locale>> country2localeList = localeStream.collect(Collectors.groupingBy(Locale::getCountry));//根据国家分组,groupBy的参数是分类器
     4         List<Locale> locales = country2localeList.get("CH");
     5         
     6         Map<String, Set<Locale>> country2localeSet = localeStream.collect(Collectors.groupingBy(Locale::getCountry, Collectors.toSet()));//根据国家分组,groupBy的参数是分类器,返回set
     7         Set<Locale> localeSet = country2localeSet.get("CH");
     8         
     9         Map<Boolean, List<Locale>> country2locales = localeStream.collect(Collectors.partitioningBy(locale->locale.getLanguage().equals("en")));//分成两组,一组为true(即语言是en的),一组为false(即语言不是en的)
    10         List<Locale> trueLocale = country2locales.get(true);

    三、filter(Predicate p)

    注意:是选择而非过滤

    1         Stream<String> streamSelf = Stream.of("python","basic","php");
    2         streamSelf.filter(str->str.startsWith("p")).forEach(System.out::println);

    注意:

    • stream也是可以foreach的,没必要一定要转化成集合再foreach

    更好的写法可能是下边这种:

    1         Predicate<String> startCondition = str->str.startsWith("p");
    2         streamSelf.filter(startCondition).forEach(System.out::println);

    说明:将条件(通常是lambda表达式)抽取出来。这种方式在多个条件的情况下比较清晰。

    注意:函数式接口 = lambda表达式 (即lambda表达式只能返回为函数式接口)

    1         Stream<String> s = Stream.of("java1","java3","java","php12");
    2         Predicate<String> condition1 = str->str.length()==5;//条件1
    3         Predicate<String> condition2 = str->str.startsWith("j");//条件2
    4         s.filter(condition1.and(condition2)).forEach(System.out::println);//and条件

    说明:

    多条件运算:and or

    四、map(Function mapper)

    作用:对流中的每一个元素进行操作。

    1         Stream<String> streamSelf = Stream.of("python","basic","php");
    2         streamSelf.map(String::toUpperCase).forEach(System.out::println);

    说明:将流内的每一个String全部转换为了大写。

    五、reduce 

    作用:对stream中的每一个元素做聚合操作。

    1         Stream<Integer> reduceStream = Stream.of(1,2,3,4,5);
    2         Optional<Integer> sumOption = reduceStream.reduce((x,y)->x+y);//计算1+2+3+4+5,即对元素中的元素进行聚合计算,而map是对元素中的每一个元素分别计算(注意:如果stream为null的话,就会产生无效的结果,需要使用Optional接收)
    3         //Optional<Integer> sumOption = reduceStream.reduce(Integer::sum);//计算1+2+3+4+5,即对元素中的元素进行聚合计算,而map是对元素中的每一个元素分别计算
    4 
    5         Integer result = reduceStream.reduce(0, Integer::sum);//0为标识值,即计算:0+1+2+。。+5,如果整个stream为null,就返回标识值。
    6         System.out.println(result);

    注意:以上是reduce的简单形式,即内联函数是(T,T)->T,即返回值和参数类型是一样的,返回值和参数类型不同的场景需要自己编写函数(用的较少)

    六、Optional

    两种用法:

    • ifPresent(xxx):存在的就执行xxx,不存在就什么都不执行
    • orElse(xxx):存在就返回存在的值,不存在就返回xxx(可以理解为是默认值)
    1         Stream<String> optionalStream = Stream.of("java","python","basic");
    2         Optional<String> optionValue = optionalStream.filter(str->str.startsWith("p")).findFirst();
    3         optionValue.ifPresent(str->System.out.println(str));//if optionalValue为true,即str存在,则输出str,当然也可以使用如下
    4         String str = optionValue.orElse("xxx");//如果optionValue为false,即不存在以p开头的字符串时,使用"xxx"来替代
    5         System.out.println(str);

    七、limit skip contact

    1、limit(long size)

    作用:截取stream的前size个元素。

    1         Stream<String> streamSelf = Stream.of("python","basic","php");
    2         streamSelf.limit(2).forEach(System.out::println);//截取前两个

    2、skip(long size)

    作用:跳过stream的钱size个元素

    1         Stream<String> streamSelf = Stream.of("python","basic","php");
    2         streamSelf.skip(2).forEach(System.out::println);//跳过前两个

    3、contact(Stream<T>,Stream<T>)

    作用:拼接两个stream

    1         Stream<String> streamSelf = Stream.of("python","basic","php");
    2         Stream<String> streamSelf2 = Stream.of("python2","basic2","php2");
    3         Stream.concat(streamSelf, streamSelf2).forEach(System.out::println);

    八、聚合函数 count max min findFirst findAny anyMatch allMatch noneMatch

    1         Stream<String> streamSelf = Stream.of("python","basic","php","b");
    2         System.out.println(streamSelf.count());//计算流中的元素个数
    3         Optional<String> largest = streamSelf.max(String::compareToIgnoreCase);//寻找最大值
    4         if(largest.isPresent()){
    5             System.out.println(largest.get());
    6         }

    说明:min函数也一样。

    注意:Optional的使用,上边的是最差的一种形式,见"六"。

     1         Optional<String> firstMatch = streamSelf.filter(str->str.startsWith("b")).findFirst();//寻找第一个符合条件的元素
     2         firstMatch.ifPresent(System.out::println);//这是Optional的第一种用法
     3         
     4         Optional<String> anyMatch = streamSelf.parallel().filter(str->str.startsWith("b")).findAny();//返回集合中符合条件的任意一个元素,对于并行处理非常好(因为多个线程只要有一个线程找到了,整个计算就会结束)
     5         if(anyMatch.isPresent()){
     6             System.out.println(anyMatch.get());//这里的结果可能是b,有可能是basic
     7         }
     8         
     9         boolean isAnyMatch = streamSelf.parallel().anyMatch(str->str.startsWith("c"));//集合中是否有一个满足条件
    10         System.out.println(isAnyMatch);
    11         
    12         Stream<String> streamSelf3 = Stream.of("basic","b");
    13         boolean isAllMatch = streamSelf3.parallel().allMatch(str->str.startsWith("b"));//集合中是否所有元素都满足条件
    14         System.out.println(isAllMatch);
    15         
    16         boolean isAllNotMatch = streamSelf.parallel().noneMatch(str->str.startsWith("p"));//集合中是否没有一个元素满足条件
    17         System.out.println(isAllNotMatch);

    注意:

    • optional的最佳用法:ifPresent()-->如果有就输出,如果没有,什么都不做
    • parallel():将stream转为并行流,并行流的使用一定要注意线程安全

    九、原始类型流

    • IntStream:int、short、char、byte、boolean
    • LongStream:long
    • DoubleStream:double、float

    1.3 java8新特性总结

    java8中重要的4个新特性:

    • Lambda
    • Stream
    • Optional
    • 日期时间API
    • 接口方法(default和static方法,jdk9可定义private方法)

    一、Lambda

     1 import java.util.Comparator;
     2 import java.util.function.Consumer;
     3 
     4 /**
     5  * @author zhaojigang
     6  * @date 2018/5/19
     7  */
     8 public class LambdaTest {
     9     /**
    10      * Lambda 是一个匿名函数。
    11      * 1、语法
    12      * Lambda表达式引入了操作符为"->",该操作符将Lambda分为两个部分:
    13      * 左侧:指定了Lambda表达式需要的所有参数
    14      * 右侧:指定了Lambda体,即Lambda表达式要执行的功能。
    15      *
    16      * 2、示例
    17      */
    18     public void testLambda() {
    19         /**
    20          * 语法格式一:无参,无返回值
    21          */
    22         Runnable task = () -> System.out.println("hello lambda");
    23         /**
    24          * 语法格式二:一个参数,无返回值
    25          * 注意:参数类型可以通过
    26          */
    27         Consumer<String> consumer = str -> System.out.println(str);
    28         /**
    29          * 语法格式三:一个参数,有返回值
    30          * 注意:当Lambda体只有一条语句时,省略大括号和return
    31          */
    32         Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);
    33     }
    34 
    35     /**
    36      * 函数式接口:只包含一个抽象方法的接口。
    37      * 1、可以通过Lambda表达式来创建该接口的对象
    38      * 2、可以在任意函数式接口上使用@FunctionalInterface注解,这样做可以检查它是否是一个函数式接口
    39      *
    40      * Java内置了四大核心函数式接口:
    41      * 1、Consumer<T>:void accept(T t),消费型接口
    42      * 2、Supplier<T>:T get(),供给型接口
    43      * 3、Function<T, R>:R apply(T t),函数型接口
    44      * 4、Predicate<T>:boolean test(T t),断言型接口
    45      * 还有部分子接口。
    46      */
    47     public void testFunctionalInterface() {
    48         Consumer<String> consumer = str -> System.out.println(str);
    49     }
    50 }

    二、Stream

      1 import java.util.ArrayList;
      2 import java.util.HashMap;
      3 import java.util.List;
      4 import java.util.Map;
      5 import java.util.Optional;
      6 import java.util.OptionalLong;
      7 import java.util.stream.LongStream;
      8 
      9 /**
     10  * @author zhaojigang
     11  * @date 2018/5/19
     12  */
     13 public class StreamTest {
     14 
     15     static List<Integer> integerList = new ArrayList<Integer>() {{
     16         add(1);
     17         add(2);
     18         add(3);
     19         add(4);
     20         add(5);
     21         add(5);
     22         add(5);
     23     }};
     24 
     25     static List<Integer> integerList2 = new ArrayList<Integer>() {{
     26         add(10);
     27         add(20);
     28         add(30);
     29     }};
     30 
     31     static Map<String, List<Integer>> map1 = new HashMap<>();
     32 
     33     static {
     34         map1.put("list1", integerList);
     35         map1.put("list2", integerList2);
     36     }
     37 
     38     /**
     39      * 分片与筛选
     40      */
     41     public static void test1() {
     42         integerList.stream()
     43                 .filter(x -> x > 2) // 3,4,5,5,5
     44                 .skip(2) //5,5,5
     45                 .limit(2) //5,5 短路:一旦获取到2个元素后不再向后迭代
     46                 .distinct() //5
     47                 .forEach(System.out::println);
     48     }
     49 
     50     /**
     51      * 映射
     52      * map(Function f):接收一个函数作为参数,该函数会被应用到每个元 素上,并将其映射成一个新的元素
     53      * flatMap(Function f):接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
     54      */
     55     public static void test2() {
     56         integerList.stream()
     57                 .map(x -> x + 10)
     58                 .forEach(System.out::println);
     59 
     60         map1.values().stream()
     61                 .flatMap(x -> x.stream()) // x是每一个List,flatMap将每一个List的Stream合并起来
     62                 .forEach(System.out::println);
     63 
     64     }
     65 
     66     /**
     67      * 排序
     68      * sorted():产生一个新流,其中按自然顺序排序(按照元素的Comparable接口)
     69      * sorted(Comparator comp):产生一个新流,其中按比较器顺序排序(按照自定义的Comparator)
     70      */
     71     public static void test3() {
     72         integerList.stream()
     73                 .sorted()
     74                 .forEach(System.out::println);
     75 
     76         integerList.stream()
     77                 .sorted((x, y) -> {
     78                     if (x < y) {
     79                         return 1;
     80                     } else {
     81                         return -1;
     82                     }
     83                 })
     84                 .forEach(System.out::println);
     85 
     86     }
     87 
     88     /**
     89      * 查找与匹配
     90      * allMatch(Predicate p):检查是否匹配所有元素
     91      * anyMatch(Predicate p):检查是否至少匹配一个元素
     92      * noneMatch(Predicate p):检查是否没有匹配所有元素
     93      * findFirst():返回第一个元素
     94      * findAny():返回当前流中的任意元素
     95      * count():返回流中元素总数
     96      * max(Comparator c):返回流中最大值
     97      * min(Comparator c):返回流中最小值
     98      */
     99     public static void test4() {
    100         final boolean allMatch = integerList.stream().allMatch(x -> x > 4);
    101         final boolean anyMatch = integerList.stream().anyMatch(x -> x > 4);
    102         final boolean noneMatch = integerList.stream().noneMatch(x -> x > 4);
    103         final Optional<Integer> first = integerList.stream().filter(x -> x > 3).findFirst();
    104         final Optional<Integer> any = integerList.stream().filter(x -> x > 3).findAny();
    105         final long count = integerList.stream().filter(x -> x > 4).count();
    106         final Optional<Integer> max = integerList.stream()
    107                 .max((x, y) -> {
    108                     if (x < y) {
    109                         return 1;
    110                     } else {
    111                         return -1;
    112                     }
    113                 });
    114 
    115     }
    116 
    117     /**
    118      * 规约
    119      * <p>
    120      * reduce(T iden, BinaryOperator b):可以将流中元素反复结合起来,得到一个值。返回T,其中iden是初始值
    121      * reduce(BinaryOperator b):可以将流中元素反复结合起来,得到一个值。返回Optional<T>
    122      */
    123     public static void test5() {
    124         // 计算:100+1+2+3+4+5+5+5
    125         final Integer sum = integerList.stream().reduce(100, (x, y) -> x + y);
    126         final Optional<Integer> sumOptional = integerList.stream().reduce((x, y) -> x + y);
    127     }
    128 
    129     /**
    130      * 收集
    131      * 常用:
    132      * 1、将流元素收集到List:List<Employee> emps= list.stream().collect(Collectors.toList());
    133      * 2、将流元素收集到Set:List<Employee> emps= list.stream().collect(Collectors.toSet());
    134      * 3、连接流中每个字符串:String str= list.stream().map(Employee::getName).collect(Collectors.joining());
    135      * 4、分组: Map<Emp.Status, List<Emp>> map= list.stream().collect(Collectors.groupingBy(Employee::getStatus));
    136      *
    137      * 不常用:
    138      * 1、根据true或false进行分区:Map<Boolean,List<Emp>>vd= list.stream().collect(Collectors.partitioningBy(Employee::getManage));
    139      * 2、根据比较器选择最大值:Optional<Emp>max= list.stream().collect(Collectors.maxBy(comparingInt(Employee::getSalary)));
    140      * 3、根据比较器选择最小值:Optional<Emp> min = list.stream().collect(Collectors.minBy(comparingInt(Employee::getSalary)));
    141      * 4、将流元素收集到任意指定集合:Collection<Employee> emps=list.stream().collect(Collectors.toCollection(ArrayList::new));
    142      * 5、计算流中元素的个数:long count = list.stream().collect(Collectors.counting());
    143      * 6、对流中元素的属性求和:int total=list.stream().collect(Collectors.summingInt(Employee::getSalary));
    144      * 7、计算流中元素Integer属性的平均值:double avg= list.stream().collect(Collectors.averagingInt(Employee::getSalary));
    145      */
    146     public static void test6() {
    147     }
    148 
    149     /**
    150      * 并行流与串行流
    151      * 并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。
    152      * 底层:fork/join
    153      * Stream API可以声明性地通过parallel()与sequential()在并行流与顺序流之间进行切换
    154      */
    155     public static void test7(){
    156         long start = System.currentTimeMillis();
    157 
    158         final OptionalLong sum = LongStream.rangeClosed(0, 100000000000L)
    159                 .parallel()
    160                 .reduce(Long::sum);
    161 
    162         System.out.println(sum + "-" + (System.currentTimeMillis() - start));
    163     }
    164 
    165     public static void main(String[] args) {
    166         test7();
    167     }
    168 }

    三、Optional

     1 import java.util.Optional;
     2 
     3 /**
     4  * @author zhaojigang
     5  * @date 2018/5/19
     6  */
     7 public class OptionalTest {
     8 
     9     public static void main(String[] args) {
    10 //        String godName = "shijia";
    11         String godName = null;
    12         // 常用方式
    13         final String god = Optional.ofNullable(godName).orElse("yesu");
    14         System.out.println(god);
    15     }
    16 }

    四、日期时间API

     1 import java.time.Duration;
     2 import java.time.Instant;
     3 import java.time.LocalDateTime;
     4 import java.time.format.DateTimeFormatter;
     5 
     6 /**
     7  * @author zhaojigang
     8  * @date 2018/5/19
     9  */
    10 public class TimeTest {
    11 
    12     /**
    13      * 一、日期创建:
    14      * LocalDate localDate = LocalDate.now();
    15      * LocalTime localTime = LocalTime.now();
    16      * LocalDateTime localDateTime = LocalDateTime.now();
    17      *
    18      * LocalDate localDate = LocalDate.of(2016, 10, 26);
    19      * LocalTime localTime = LocalTime.of(02, 22, 56);
    20      * LocalDateTime localDateTime = LocalDateTime.of(2016, 10, 26, 12, 10, 55);
    21      *
    22      * 二、日期加减运算
    23      * plusDays, plusWeeks, plusMonths, plusYears
    24      * minusDays, minusWeeks, minusMonths, minusYears
    25      * plus, minus
    26      *
    27      * 三、日期比较计算
    28      * isBefore, isAfter
    29      *
    30      * 四、是否闰年
    31      * isLeapYear
    32      *
    33      * 五、时间戳与时间间隔运算
    34      * Instant 时间戳:以Unix元年(传统的设定为UTC时区1970年1月1日午夜时分)开始所经历的描述进行运算
    35      * Duration:用于计算两个“时间”间隔
    36      * Period:用于计算两个“日期”间隔
    37      *
    38      * 六、时间校正器
    39      * TemporalAdjuster/TemporalAdjusters 调整时间:例如获取下一个周日等
    40      *
    41      * 七、日期解析和格式化
    42      * java.time.format.DateTimeFormatter类
    43      */
    44     public static void main(String[] args) {
    45         /**
    46          * 计算时间间隔
    47          */
    48         Instant in1 = Instant.now();
    49         Instant in2 = Instant.now();
    50         System.out.println(Duration.between(in1, in2).toMillis());
    51 
    52         /**
    53          * 日期格式化
    54          */
    55         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    56         LocalDateTime time1 = LocalDateTime.now();
    57         String formatDateTime = time1.format(formatter);
    58 
    59         /**
    60          * 日期解析
    61          */
    62         LocalDateTime dateTime = LocalDateTime.parse(formatDateTime, formatter);
    63     }
    64 }

    日期操作我们通常会使用Apache commons包,但是这样就会引入一个包,能够使用java本身的就是用java本身的。

    五、接口方法

     1 /**
     2  * @author zhaojigang
     3  * @date 2018/5/19
     4  */
     5 public class InterfaceTest {
     6     public static void main(String[] args) {
     7         MyImpl myClass = new MyImpl();
     8         System.out.println(myClass.getName());
     9         System.out.println(MyInterface.getAge());
    10     }
    11 }
    12 
    13 interface MyInterface {
    14     default String getName(){
    15         return "nana";
    16     }
    17 
    18     static Integer getAge(){
    19         return 18;
    20     }
    21 }
    22 
    23 /**
    24  * 若一个接口中定义了一个默认方法,而另外一个父类中又定义了一个同名的方法时,取父类
    25  * 若一个接口中定义了一个默认方法,而另外一个实现接口中又定义了一个同名的方法时,实现类需要执行重写其中一个
    26  */
    27 class MyImpl implements MyInterface {
    28 }
  • 相关阅读:
    System.TypeInitializationException 类型初始值设定项引发异常
    asp.net webapi下json传值方式
    The remote name could not be resolved: 'nuget.org'(未能解析此远程名称:’nuget.org’)
    关于集成Paypal Express Checkout支付功能
    Syntax error at line 16 while loading: expected ')', got keyword 'in' or(i.isArray(t)||(t in e?t=[t]:(t=i.came
    如何在MVC3 razor视图下的ViewsStart文件中设置使用两套不同的Layout布局视图
    knockout使用技巧:告知knockout忽略页面容器内特定部分的绑定
    LINQ to Entities已知问题及注意事项
    jQuery中.live()方法的使用方法
    Uncaught TypeErroe: Uncaught TypeError: Cannot call method 'push' of undefined 和 Uncaught TypeError: undefined is not a function
  • 原文地址:https://www.cnblogs.com/hanease/p/16302568.html
Copyright © 2020-2023  润新知