栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JDK8新特性

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JDK8新特性

1. 介绍匿名内部类和 Lambda 表达式 (1) Lambda 表达式创建多线程
package com.jdk8;

public class TestDemo {

    public static void main(String[] args) {
        // 用匿名内部类创建多线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("新线程执行代码了");
            }
        }).start();

        
        // 体验 Lambda 表达式
        new Thread(() -> {
            System.out.println("Lambda 表达式执行了");
        }).start();
    }
}
(2) Lambda 表达式对集合排序
package com.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
    private String name;
    private Integer age;
    private Integer height;
}
package com.jdk8;

import com.entity.Person;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class TestDemo {

    public static void main(String[] args) {
        List list = new ArrayList<>();
        Collections.addAll(list,
                new Person("刘德华",54,174),
                new Person("张学友", 58, 176),
                new Person("刘德华", 52, 171),
                new Person("黎明",53,178));

        

        // Lambda 表达式的书写
        Collections.sort(list, (Person o1, Person o2) -> {
            return o2.getAge() - o1.getAge(); //对年龄进行倒叙
        });
        System.out.println(list);
    }
}

  上面我们可以看到 Lambda 表达式的好处:可以简化匿名内部类,让代码变得更加精简

2. Lambda 表达式的标准格式

  (接口中重写方法的参数列表) -> {接口中重写方法的方法体}
  以后我们看到一个方法的参数是接口就可以考虑使用 Lambda 表达式来替换匿名内部类。Lambda 表达式就是对接口的抽象方法进行重写
  Lambda 表达式的底层原理就是对接口的一个实现,并且重写了抽象方法

3. Lambda 表达式的省略格式
  1. 小括号内参数的类型可以省略
  2. 如果小括号内有且仅有一个参数,则小括号可以省略
  3. 如果大括号内有且仅有一个语句,可以同时省略大括号,return 关键字以及语句分号(这三个必须同时省略,否则报错)
(int a) -> {
    return new Person();
}

  省略后

a -> new Person()
4. Lambda 表达式的前提条件
  1. 方法的参数或局部变量类型必须为接口才能使用 Lambda
  2. 这个接口中只能有一个抽象方法才能使用 Lambda(只有一个抽象方法的接口称为函数式接口)
5. Lambda 和匿名内部类对比

  匿名内部类需要的类型可以是类、抽象类、接口,并且匿名内部类所需的接口中抽象方法是任意的。而 Lambda 表达式的类型必须是接口,而且这个接口只能有一个抽象方法。

6. 接口的默认方法和静态方法

  在 JDK8 以前,接口只能有抽象方法。
  JDK8 对接口进行了增强,接口中还可以有默认方法和静态方法。

interface 接口名 {
    静态变量;
    抽象方法;
    默认方法;
    静态方法;
}
(1) 接口默认方法的定义格式
interface 接口名 {
    修饰符 default 返回值类型 方法名() {
        代码;
    }
}
(2) 接口默认方法的使用
  1. 实现类直接调用接口默认方法
  2. 实现类重写接口默认方法
(3) 接口静态方法的定义格式
interface 接口名 {
    修饰符 static 返回值类型 方法名() {
        代码;
    }
}
(4) 接口静态方法的使用

  直接使用接口名调用即可:接口名.静态方法名();
  接口中的静态方法不能被继承,实现类不能重写接口的静态方法,只能使用接口名调用。

7. 方法引用

  如果 Lambda 表达式中只调用已有的方法,那么则可以使用方法引用。让这个引用的方法去重写接口的抽象方法,到时候调用接口的抽象方法就是调用传递过去的这个方法。符号:::

(1) 方法引用常见的方式
  1. 对象::方法名
  2. 类名::静态方法
  3. 类名::普通方法
  4. 类名::new (调用的是构造器)
(2) 对象名::引用成员方法
package com.jdk8;

import java.util.Date;
import java.util.function.Supplier;

public class TestDemo {

    public static void main(String[] args) {
        Date date = new Date();

        // 使用 Lambda 表达式
        

        // 使用方法引用
        Supplier su1 = date::getTime;

        Long aLong = su1.get();
        System.out.println(aLong);
    }
}

  注意:1. 被引用的方法,参数要和接口中抽象方法的参数一样。  2. 当接口抽象方法有返回值时,被引用的方法也必须有返回值。

(3) 类名::引用静态方法
package com.jdk8;

import java.util.function.Supplier;

public class TestDemo {

    public static void main(String[] args) {
        // 使用 Lambda 表达式
        

        // 使用方法引用
        Supplier su = System::currentTimeMillis;

        Long aLong = su.get();
        System.out.println(aLong);
    }
}
(4) 类名::引用实例方法
package com.jdk8;

import java.util.function.Function;

public class TestDemo {

    public static void main(String[] args) {
        

        //使用方法引用
        Function f1 = String::length;

        Integer length = f1.apply("hello");
        System.out.println(length);
    }
}

  注意:类名::实例方法 实际上会将第一个参数作为方法的调用者,后面其他的参数作为方法的参数

(5) 类名::new 引用类的构造器
package com.jdk8;

import com.entity.Person;

import java.util.function.Supplier;

public class TestDemo {

    public static void main(String[] args) {
        // 使用 Lambda 表达式
        

        // 使用方法引用
        Supplier su1 = Person::new;
        
        Person person = su1.get();
        System.out.println(person);
    }
}
8. Stream 流

  当我们操作集合时每次都需要循环遍历,还要创建新集合,很麻烦。而 Stream 流的出现大大简化了我们对集合的操作。

(1) 获取 Stream 流的两种方式

  方式一:根据 Collection 获取流:我们使用 Collection 接口中的默认方法 stream() 来获取流,因为是默认方法,所以 Collection 接口的所有子集合类也都可以通过 stream() 方法来获取流。

package com.jdk8;

import java.util.*;
import java.util.stream.Stream;

public class TestDemo {

    public static void main(String[] args) {
        List list = new ArrayList<>();
        Stream stream1 = list.stream();

        Set set = new HashSet<>();
        Stream stream2 = set.stream();

        Map map = new HashMap<>();
        Stream stream3 = map.keySet().stream();
        Stream stream4 = map.values().stream();
        Stream> stream5 = map.entrySet().stream();
    }
}

  方式二:Stream 中的静态方法 of 来获取流

package com.jdk8;

import java.util.stream.Stream;

public class TestDemo {

    public static void main(String[] args) {
        Stream stream = Stream.of("aa", "bb", "cc");

        String[] arr = {"aa", "bb", "cc"};
        Stream stream6 = Stream.of(arr); // 数组中的数据必须是引用类型,不能是基本类型
    }
}
(2) Stream 常用方法

  • 终结方法:包括 count 和 foreach 方法,返回值类型不再是 Stream 类型,不再支持链式调用。
  • 非终结方法:其余方法都是非终结方法,返回值类型仍然是 Stream 类型的方法,支持链式调用。
(3) Stream 的注意事项
  1. Stream 只能操作一次
  2. Stream 方法返回的是最新的流
  3. Stream 不调用终结方法,中间的操作不会执行
(4) Stream 流的 forEach 方法

  forEach 方法遍历集合里面的数据

package com.jdk8;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class TestDemo {

    public static void main(String[] args) {
        List list = new ArrayList<>();
        Collections.addAll(list, "迪丽热巴", "宋远桥", "苏星河", "老子", "庄子", "孙子");

        // 得到流,调用流中的方法
        
        // 简化代码
        //list.stream().forEach(str -> System.out.println(str));
        list.stream().forEach(System.out::println);
    }
}
(5) Stream 流的 count 方法

  count 方法统计集合里面元素的个数

package com.jdk8;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class TestDemo {

    public static void main(String[] args) {
        List list = new ArrayList<>();
        Collections.addAll(list, "迪丽热巴", "宋远桥", "苏星河", "老子", "庄子", "孙子");

        long count = list.stream().count();
        System.out.println(count);
    }
}
(6) Stream 流的 filter 方法

  filter 方法用于过滤数据,返回复合过滤条件的数据

package com.jdk8;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class TestDemo {

    public static void main(String[] args) {
        List list = new ArrayList<>();
        Collections.addAll(list, "迪丽热巴", "宋远桥", "苏星河", "老子", "庄子", "孙子");

        // 得到名字长度为3个字的人(过滤)
        
        // 简化代码
        list.stream().filter(s -> s.length() == 3).forEach(System.out::println);
    }
}
(7) Stream 流的 limit 方法

  取集合中数据的前几个

package com.jdk8;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class TestDemo {

    public static void main(String[] args) {
        List list = new ArrayList<>();
        Collections.addAll(list, "迪丽热巴", "宋远桥", "苏星河", "老子", "庄子", "孙子");

        // 获取前3个数据
        list.stream().limit(3).forEach(System.out::println);
    }
}
(8) Stream 流的 skip 方法

  跳过集合中的前几个元素,获取后面的元素

package com.jdk8;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class TestDemo {

    public static void main(String[] args) {
        List list = new ArrayList<>();
        Collections.addAll(list, "迪丽热巴", "宋远桥", "苏星河", "老子", "庄子", "孙子");

        // 跳过前2个数据
        list.stream().skip(2).forEach(System.out::println);
    }
}
(9) Stream 流的 map 方法

  把集合中的一种类型转换成另外一种类型,可以用 map 方法

package com.jdk8;

import java.util.stream.Stream;

public class TestDemo {

    public static void main(String[] args) {
        Stream original = Stream.of("11", "22", "33");

        // 将 Stream 流中的字符串转成 Integer
        
        // 简化代码
        original.map(Integer::parseInt).forEach(System.out::println);
    }
}
(10) Stream 流的 sorted 方法

  将集合中的元素进行排序

package com.jdk8;

import java.util.stream.Stream;

public class TestDemo {

    public static void main(String[] args) {
        Stream stream = Stream.of(33, 22, 11, 55);

        //stream.sorted().forEach(System.out::println); // 没有参数默认升序排列

        
        // 简化代码
        stream.sorted((i1, i2) -> i2 - i1).forEach(System.out::println);
    }
}
(11) Stream 流的 distinct 方法

  去掉集合中的重复元素

package com.jdk8;

import com.entity.Person;

import java.util.stream.Stream;

public class TestDemo {

    public static void main(String[] args) {
        // 数字或字符串去重
        Stream stream = Stream.of(22, 33, 22, 11, 33);
        stream.distinct().forEach(System.out::println);

        // 对自定义对象去除重复(自定义类一定要重写 hashCode 和 equals 方法才能实现去重)
        Stream personStream = Stream.of(
                new Person("貂蝉", 18),
                new Person("西施", 16),
                new Person("杨玉环", 20),
                new Person("西施", 16),
                new Person("王昭君", 25),
                new Person("杨玉环", 20)
        );
        personStream.distinct().forEach(System.out::println);
    }
}
(12) Stream 流的 match 方法

  判断集合中的所有元素是否匹配指定条件,返回值类型是布尔类型

package com.jdk8;

import java.util.stream.Stream;

public class TestDemo {

    public static void main(String[] args) {
        Stream stream = Stream.of(5, 3, 6, 1);

        
        // 简化代码
        //boolean b = stream.allMatch(i -> i > 5); // allMatch 是匹配所有元素,所有元素都满足条件
        //boolean b = stream.anyMatch(i -> i > 5); // anyMatch 是匹配某个元素,只要其中一个元素满足条件即可
        boolean b = stream.noneMatch(i -> i < 0); // noneMatch 是匹配所有元素,所有元素都不满足条件
        System.out.println(b);
    }
}
(13) Stream 流的 reduce 方法

  将集合中的数据进行归纳总结,最后得到一个数据

package com.jdk8;

import java.util.stream.Stream;

public class TestDemo {

    public static void main(String[] args) {
        // reduce的第一个参数是默认值,第二个参数是对数据处理的方式
        // reduce 如何执行?
        // 第一次,将默认值赋值给 x,取出集合第一个元素赋值给 y
        // 第二次,将上一次返回的结果赋值给 x,取出集合第二个元素赋值给 y
        // 第三次,将上一次返回的结果赋值给 x,取出集合第三个元素赋值给 y
        // 第四次,将上一次返回的结果赋值给 x,取出集合第四个元素赋值给 y
        Integer reduce = Stream.of(4, 5, 3, 9).reduce(0, (x, y) -> {
            return x + y;
        });
        System.out.println(reduce);

        // 使用 reduce 获取最大值
        Integer reduce1 = Stream.of(4, 5, 3, 9).reduce(0, (x, y) -> {
            return x > y ? x : y;
        });
        System.out.println(reduce1);
    }
}
(14) Stream 流的 map 和 reduce 组合
package com.jdk8;

import com.entity.Person;
import java.util.stream.Stream;

public class TestDemo {

    public static void main(String[] args) {
        // 求出所有年龄的总和
        // 1. 得到所有的年龄
        // 2. 让年龄相加
        Integer totalAge = Stream.of(
                new Person("刘德华", 58),
                new Person("张学友", 56),
                new Person("郭富城", 54),
                new Person("黎明", 52)
        ).map(p -> p.getAge()).reduce(0, Integer::sum);
        System.out.println(totalAge);

        // 统计 a 出现的次数
        Integer count = Stream.of("a", "c", "b", "a", "b", "a").map(s -> s.equals("a") ? 1 : 0)
                .reduce(0, Integer::sum);
        System.out.println(count);
    }
}
(15) Stream 流的 concat 方法

  把两个集合合并成一个,可以使用 Stream 接口的静态方法 concat

package com.jdk8;

import java.util.stream.Stream;

public class TestDemo {

    public static void main(String[] args) {
        Stream stream1 = Stream.of("张三");
        Stream stream2 = Stream.of("李四");
        // 把两个流合并成一个
        Stream stream = Stream.concat(stream1, stream2);
        stream.forEach(System.out::println);
    }
}

  两个流合并之后,不能操作之前的流。只支持将两个流合并成一个流。

(16) 将 Stream 流中的结果保存到集合中
package com.jdk8;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class TestDemo {

    public static void main(String[] args) {
        Stream stream = Stream.of("aa", "bb", "cc");
        // collect 收集流中的数据到 List 集合中
        List list = stream.collect(Collectors.toList());
        System.out.println(list);

        Stream stream1 = Stream.of("张三丰", "张作霖", "张学良", "张作霖");
        // collect 收集流中的数据到 Set 集合中
        Set set = stream1.collect(Collectors.toSet());
        System.out.println(set);
    }
}
(17) 将 Stream 流中的数据收集到数组中
package com.jdk8;

import java.util.stream.Stream;

public class TestDemo {

    public static void main(String[] args) {
        Stream stream = Stream.of("aa", "bb", "cc");
        String[] strings = stream.toArray(String[]::new); // 括号里的内容是指定数组的类型
        for (String string : strings) {
            System.out.println(string);
        }
    }
}
(18) 对 Stream 流中的结果进行聚合计算

  在流中的结果获取最大值,最小值,总和,平均值,统计数量

package com.jdk8;

import com.entity.Student;

import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class TestDemo {

    public static void main(String[] args) {
        Stream stream = Stream.of(
                new Student("赵丽颖", 58, 95),
                new Student("杨颖", 56, 88),
                new Student("迪丽热巴", 56, 99),
                new Student("柳岩", 52, 77)
        );

        // 获取成绩的最大值
        

        // 获取成绩的最小值
        

        // 求年龄总和
        

        // 求成绩的平均值
        //Double avg = stream.collect(Collectors.averagingInt(s -> s.getScore()));
        //换成方法引用
        

        // 统计数量
        Long count = stream.collect(Collectors.counting());
        System.out.println(count);
    }
}
(19) Stream 对流中数据进行分组
package com.jdk8;

import com.entity.Student;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class TestDemo {

    public static void main(String[] args) {
        Stream stream = Stream.of(
                new Student("赵丽颖", 58, 95),
                new Student("杨颖", 56, 59),
                new Student("迪丽热巴", 56, 99),
                new Student("柳岩", 52, 77)
        );

        // Stream 流根据年龄进行分组
        
        // 简化代码
        

        // 将分数大于60的分为一组,小于60分成另一组
        Map> map1 = stream.collect(Collectors.groupingBy(s -> {
            if (s.getScore() > 60) {
                return "及格";
            } else {
                return "不及格";
            }
        }));
        map1.forEach((k, v) -> System.out.println(k + "::" + v));
    }
}
(20) Stream 对流中数据进行多级分组
package com.jdk8;

import com.entity.Student;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class TestDemo {

    public static void main(String[] args) {
        Stream stream = Stream.of(
                new Student("赵丽颖", 52, 95),
                new Student("杨颖", 56, 88),
                new Student("迪丽热巴", 56, 55),
                new Student("柳岩", 52, 33)
        );

        // 先根据年龄分组,每组中再根据成绩分组
        Map>> map = stream.collect(Collectors.groupingBy(s -> s.getAge(), Collectors.groupingBy(s -> {
            if (s.getScore() > 60) {
                return "及格";
            } else {
                return "不及格";
            }
        })));
        // 遍历
        map.forEach((k, v) -> {
            System.out.println(k);
            // v 还是一个 map
            v.forEach((k2, v2) -> {
                System.out.println(k2 + "==" + v2);
            });
        });
    }
}
(21) 对流中数据进行分区

  把集合中的数据根据指定的条件,true 的分一个区,false 的分一个区(分区就分为两个区,一个 true,一个 false)

package com.jdk8;

import com.entity.Student;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class TestDemo {

    public static void main(String[] args) {
        Stream stream = Stream.of(
                new Student("赵丽颖", 52, 95),
                new Student("杨颖", 56, 88),
                new Student("迪丽热巴", 56, 55),
                new Student("柳岩", 52, 33)
        );

        // 把分数大于60的分一个区,其余的分另外一个区
        Map> map = stream.collect(Collectors.partitioningBy(s -> {
            return s.getScore() > 60;
        }));
        map.forEach((k, v) -> {
            System.out.println(k + "::" + v);
        });
    }
}
(22) 对流中数据进行拼接

  会根据指定的连接符,将流中指定的所有元素连接到一块

package com.jdk8;

import com.entity.Student;

import java.util.stream.Collectors;
import java.util.stream.Stream;

public class TestDemo {

    public static void main(String[] args) {
        Stream stream = Stream.of(
                new Student("赵丽颖", 52, 95),
                new Student("杨颖", 56, 88),
                new Student("迪丽热巴", 56, 55),
                new Student("柳岩", 52, 33)
        );

        // 将 Stream 流中姓名的字符串进行拼接
        

        // 第一个参数:字符串拼接的符号;第二个参数:拼接的前缀;第三个参数:拼接的后缀
        String names = stream.map(s -> s.getName()).collect(Collectors.joining("_", "start", "end"));
        System.out.println(names);
    }
}
9. 并行的 Stream 流

  上面学的 Stream 流都是串行的,都是通过一个线程进行操作的,运行效率不高。所以我们引入并行的 Stream 流,可以大大提高程序执行的效率。

package com.jdk8;

import java.util.stream.Stream;

public class TestDemo {

    public static void main(String[] args) {
        Stream stream = Stream.of(4, 5, 3, 9, 1, 2, 6);
        stream.forEach(s -> {
            System.out.println(Thread.currentThread());
        });
    }
}

  通过打印线程名称发现,都是一个线程,所以说是串行的 Stream 流。

(1) 获取并行 Stream 流的两种方式

  方式一:直接获取并行的 Stream 流

package com.jdk8;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class TestDemo {

    public static void main(String[] args) {
        List list = new ArrayList<>();
        Collections.addAll(list, 4, 5, 3, 9, 1, 2, 6);
        list.parallelStream().forEach(i -> System.out.println(Thread.currentThread()));
    }
}

  方式二:将串行流转成并行流

package com.jdk8;

import java.util.stream.Stream;

public class TestDemo {

    public static void main(String[] args) {
        Stream.of(4, 5, 3, 9, 1, 2, 6)
                .parallel() // 将串行流转成并行流
                .forEach(i -> System.out.println(Thread.currentThread()));
    }
}
(2) 解决 parallelStream 的线程安全问题

  产生线程安全的代码

package com.jdk8;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

public class TestDemo {

    public static void main(String[] args) {
        List list = new ArrayList<>();
        // 在 Stream 流中得到1-1000的数字
        IntStream.rangeClosed(1, 1000)
                .parallel()
                .forEach(i -> list.add(i)); // 多线程操作 forEach,因为 ArrayList 是线程不安全的,所以会导致错误
        System.out.println(list.size());
    }
}

  解决线程安全问题方案一
  使用同步代码块将共享资源锁住

package com.jdk8;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

public class TestDemo {

    public static void main(String[] args) {
        List list = new ArrayList<>();
        Object obj = new Object();
        // 在 Stream 流中得到1-1000的数字
        IntStream.rangeClosed(1, 1000)
                .parallel()
                .forEach(i -> {
                    synchronized (obj) { //对共享资源加入同步锁
                        list.add(i);
                    }
                });
        System.out.println(list.size());
    }
}

  解决线程安全问题方案二
  使用线程安全的集合

package com.jdk8;

import java.util.Vector;
import java.util.stream.IntStream;

public class TestDemo {

    public static void main(String[] args) {
        Vector v = new Vector<>(); // Vector 是线程安全的集合
        // 在 Stream 流中得到1-1000的数字
        IntStream.rangeClosed(1, 1000)
                .parallel()
                .forEach(i -> v.add(i));
        System.out.println(v.size());
    }
}
package com.jdk8;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.IntStream;

public class TestDemo {

    public static void main(String[] args) {
        List list = new ArrayList<>();
        // 将线程不安全的 list 返回一个线程安全的 list
        List synchronizedList = Collections.synchronizedList(list);
        // 在 Stream 流中得到1-1000的数字
        IntStream.rangeClosed(1, 1000)
                .parallel()
                .forEach(i -> synchronizedList.add(i));
        System.out.println(synchronizedList.size());
    }
}

  解决线程安全问题方案三
  调用 Stream 流的 collect 方法

package com.jdk8;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class TestDemo {

    public static void main(String[] args) {
        // 在 Stream 流中得到1-1000的数字
        List list = IntStream.rangeClosed(1, 1000)
                .parallel()
                .boxed() // 将 int 类型转化为 Integer 类型
                .collect(Collectors.toList());
        System.out.println(list.size());
    }
}
10. JDK8 新的日期和时间 api

  旧版的日期和时间 api 设计有些不合理,并且是线程不安全。而新版的设计合理,并且线程安全。

(1) LocalDate:表示日期,有年月日
package com.jdk8;

import java.time.LocalDate;

public class TestDemo {

    public static void main(String[] args) {
        // 创建当前日期
        LocalDate now = LocalDate.now();
        System.out.println(now);

        // 创建指定日期
        LocalDate date = LocalDate.of(2018, 8, 8);
        System.out.println(date);

        // 单独拿到 LocalDate 中的年月日
        System.out.println(date.getYear());
        System.out.println(date.getMonthValue());
        System.out.println(date.getDayOfMonth());
    }
}
(2) LocalTime:表示时间,有时分秒
package com.jdk8;

import java.time.LocalTime;

public class TestDemo {

    public static void main(String[] args) {
        // 创建当前时间
        LocalTime now = LocalTime.now();
        System.out.println(now);

        // 创建指定时间
        LocalTime time = LocalTime.of(13, 26, 39);
        System.out.println(time);

        // 获取 LocalTime 中的时分秒
        System.out.println(time.getHour()); // 时
        System.out.println(time.getMinute()); // 分
        System.out.println(time.getSecond()); // 秒
        System.out.println(time.getNano()); // 纳秒
    }
}
(3) LocalDateTime:表示日期和时间,有年月日时分秒
package com.jdk8;

import java.time.LocalDateTime;

public class TestDemo {

    public static void main(String[] args) {
        // 创建现在的日期和时间
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);

        // 创建指定的日期和时间
        LocalDateTime dateTime = LocalDateTime.of(2018, 7, 12, 13, 28, 59);
        System.out.println(dateTime);

        // 获取 LocalDateTime 中的年月日时分秒
        System.out.println(dateTime.getYear());
        System.out.println(dateTime.getMonthValue());
        System.out.println(dateTime.getDayOfMonth());
        System.out.println(dateTime.getHour());
        System.out.println(dateTime.getMinute());
        System.out.println(dateTime.getSecond());
    }
}
(4) 对日期时间进行修改

  LocalDate,LocalTime,LocalDateTime 三个类对日期和时间的修改都相同。修改后会产生一个新的对象,不会对以前的对象进行修改

package com.jdk8;

import java.time.LocalDateTime;

public class TestDemo {

    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();
        // 修改时间,修改后返回新的时间对象
        LocalDateTime dateTime = now.withYear(1234).withMonth(12);
        System.out.println(dateTime);

        // 增加或减去时间
        // plus 表示增加指定的时间。minus 表示减去指定的时间
        System.out.println(now.plusYears(2)); // 增加2年
        System.out.println(now.minusYears(3)); //减3年
    }
}
(5) 对日期时间进行比较
package com.jdk8;

import java.time.LocalDateTime;

public class TestDemo {

    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();

        LocalDateTime dateTime = LocalDateTime.of(2018, 9, 9, 14, 28, 59);

        System.out.println(now.isAfter(dateTime)); // 当前时间在指定时间后面吗
        System.out.println(now.isBefore(dateTime)); // 当前时间在指定时间前面吗
        System.out.println(now.isEqual(dateTime)); // 当前时间和指定时间相等吗
    }
}
(6) 时间的格式化与解析
package com.jdk8;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class TestDemo {

    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();

        // 将当前时间进行格式化
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");
        String format = now.format(dtf);
        System.out.println(format);

        // 将格式化的时间解析成 LocalDateTime
        LocalDateTime parse = LocalDateTime.parse("2018年09月28日 18时26分27秒", dtf);
        System.out.println(parse);
    }
}
(7) 将 Date 转化为 LocalDateTime
package com.jdk8;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

public class TestDemo {

    public static void main(String[] args) {
        Date date = new Date();
        LocalDateTime dateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
        System.out.println(dateTime);
    }
}
(8) 将 LocalDateTime 转化为 Date
package com.jdk8;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

public class TestDemo {

    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();
        Date date = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());
        System.out.println(date);
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/459624.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号