JAVA 8 新特性

,# java 8新特性

一 Lambda

1 Lambda基础语法

java8 增加了"->"操作符

->左侧: 参数列表,右侧:实现的是方法的功能,即lambda体

/*Lambda 基于“函数式的接口”
    * 函数式接口:接口中只有一个抽象方法。
    * Lambda语法格式一:没有参数,没有返回值
    * 语法格式:()->功能语句
    * */
@Test
public void test01(){
    int num=9; 
    //java 7之前如果在匿名内部类的同级别加入局部变量,必须以final修饰,但在java 8就可以不用写       了,但是final还是存在的
    //匿名内部类的写法
    Runnable runnable = new Runnable(){
        @Override
        public void run() {
            System.out.println("hello world"+num);
        }
    };
    runnable.run();

    //lambda写法,语法格式一:()->功能语句
    Runnable r2=()-> System.out.println("hello lambda"+num);
    r2.run();
}

   /*
    * 当有一个参数,但是无返回值
    *lambda语法格式二:(x)->功能语句,如果只有一个参数()可以不写
    * */
@Test
public void test02() {
    // (x)->功能语句
    // Consumer<Integer> consumer=(x)-> System.out.println(x);
    Consumer<Integer> consumer=x-> System.out.println(x);
    consumer.accept(3);
}

/*
    * 有两个参数,并且有返回值,并且有多条语句
    * Lambda语法格式三:()包含多个参数,并且{}来包含多条语句
    * 如果只有一条语句,那么return和{}都可以省略不写
    * 例:Comparator<Integer> comparator2=(x,y)->x+y;
    *    System.out.println( comparator2.compare(2,3));
    * */
@Test
public void test03() {
    Comparator<Integer> comparator=(x,y)->{
        System.out.println("x:"+x+"\n"+"y:"+y);
        return x+y;
    };
    //        Comparator<Integer> comparator2=(x,y)->x+y;
    //        System.out.println(comparator2.compare(2,3));
    int compare = comparator.compare(2, 3);
    System.out.println(compare);
}

/*
    * Lambda语法格式四:lambda的数据列表的数据类型可以省略不写,java的jvm编译器具有类型推断的功能,即:
    * Comparator<Integer> comparator2=(Integer x,Integer y)->x+y;
    * */

/*
    * 注意:以上所有接口都是"函数式接口",函数式接口:只有一个抽象方法,可以用@FunctionalInterface注解来判断是不是函数式接口
    * */

/*
    * 需求:计算一个数
    接口:
    @FunctionalInterface
    public interface Myfun {
        public Integer getVaule(Integer num);

    }
    * */
@Test
public void test04(){
    Myfun myfun=x->x*x;
    Integer nums = operation(3, myfun);
    System.out.println(nums);
}
public Integer operation(Integer num, Myfun myfun){
    return myfun.getVaule(num);
}

2 Lambda练习

 @Test
    public void test05(){
        List<Employee> emps = createEmp();
        /*
        * 首先根据age进行排序,如果名字相同就根据last_name进行排序
        * */
        Comparator<Employee> employeeComparator=(x,y)->{
            if(x.getAge()==y.getAge()){
                return x.getLast_name().compareTo(y.getLast_name());
            }else{
                return Integer.compare(x.getAge(),y.getAge());
            }
        };
        Collections.sort(emps,employeeComparator);
        for (Employee emp : emps) {
            System.out.println(emp);
        }
    }


    /*
    * 将字符串变为大写
    * 接口:
    * public interface StrToUpper {
        public String getVlaue(String str);
      }
    * */
    @Test
    public void test06(){
        StrToUpper strToUpper=x->x.toUpperCase();
        String vlaue = strToUpper.getVlaue("hello world");
        System.out.println(vlaue);
    }


    /*
    * 创建一个泛型为<T,R>的接口,参数类型为T,返回值类型为R,传入的两个参数类型为Long
    * 接口:
    * public interface MyFuncation<T,R> {
           public R getValue(T t1,T t2);
      }
    * */
    @Test
    public void test07(){
        //两个long的加法
        MyFuncation<Long,Long> myFuncation=(x,y)->x+y;
        System.out.println(myFuncation.getValue(100L,100L));
        //两个long的乘法
        MyFuncation<Long,Long> myFuncation2=(x,y)->x*y;
        System.out.println(myFuncation2.getValue(100L,100L));
    }

3 Java 8四大内置核心函数式接口

Consumer<T>:  //消费型接口
  void accept(T t);
Supplier<T>:  //供给型接口
  T get();
Funcation<T,R>: //函数式接口
  R apply(T t);
Prediccate<T>: //断言式接口
  boolean test(T t);

4 方法引用和构造器引用

① 方法引用

方法引用:若lambda体中的内容有方法已经实现,我们可以使用“方法引用”

主要有三种方法引用语法格式:

  • 对象::实例方法名
  • 类::静态方法名
  • 类::实例方法名

注意:① 若lambda体中调用方法的参数列表与返回值类型,要与函数式接口的抽象列表和返回值类型保持一致

​ ② 若lambda参数列表中的第一个参数是 实例方法的调用者,而第二各参数是实例方法的参数时,可以使用类::实例方法名

例:

 /*
    * 对象::实例方法名
    * */
    @Test
    public void test01() {
        Consumer<String> con=x-> System.out.println(x);
        //对象::实例方法名,注:实例方法名的参数列表和返回值要和函数式接口的方法的参数列表和返回类型保持一致
        Consumer<String> con2=System.out::println;
        con2.accept("hello");
    }

    @Test
    public void test02(){
        /*
        * 对象::实例方法名
        * */
        Employee emp = new Employee();
        Supplier<String> sup=()->emp.getLast_name();
        Supplier<Integer> sup2=emp::getAge;

        /*可以直接方法引用,不用去创建lambda体
        *   Employee emp = new Employee();
            emp.setAge(20);
            Supplier<Integer> sup2=emp::getAge;
            System.out.println(sup2.get());
        * */
    }

    @Test
    public void test03(){
        /*
        * 类::静态方法名
        * */
        Comparator<Integer> comparator=(x,y)->Integer.compare(x,y);
        Comparator<Integer> comparator2=Integer::compare;
    }

    @Test
    public void test04(){
        /*
        * 类::实例方法名
        * 若lambda参数列表中的第一个参数是 实例方法的调用者,而第二各参数是实例方法的参数时,可以使用类::实例方法名
        * */
        BiPredicate<String,String> biPredicate=(x,y)->x.equals(y);
        BiPredicate<String,String> biPredicate2=String::equals;
    }
② 构造器引用

例:

 /*
    * 构造器引用
    * 格式语法:
    * 类::new
    * */
    @Test
    public void test05(){
        Supplier<Employee> sup1=()->new Employee();
        Supplier<Employee> sup=Employee::new;
        //引用有参构造器
        // public Employee(Integer age) {
        //        this.age = age;
        //  }
        Function<Integer,Employee> function=Employee::new;
        /*
        *public Employee(String last_name, Integer age) {
        this.last_name = last_name;
        this.age = age;
         }
        * */
        BiFunction<String,Integer,Employee> biFunction=Employee::new;
    }
③ 数组引用

例:

 /*
    * 数组引用:
    * type[]::new
    * */
    @Test
    public void test06(){
        Function<Integer,String []> function=x->new String[x];
        //type[]::new
        Function<Integer,String[]> function2=String[]::new;
    }

二 Stream API

1 创建Stream流

  • 创建Stream
  • 中间操作
  • 最后终止

例;

//第一种创建stream流,通过Collections集合的stream()【串行流】方法或者parallelStream()【并行流】方法
List<Employee> emps = new ArrayList<>();
Stream<Employee> stream = emps.stream();
Stream<Employee> employeeStream = emps.parallelStream();
//第二种方法创建stream流,通过Arrays中的静态方法Stream()方法
Employee[] emp=new Employee[10];
Stream<Employee> employeeStream2 = Arrays.stream(emp);
//第三种Stream中的of方法
Stream<Employee> employeeStream1 = Stream.of(emp);
//创建无限流
//1 iterate方法
Stream<Integer> iterate = Stream.iterate(0, x -> (int)Math.random());
//2 generate方法
Stream<Employee> generate = Stream.generate(Employee::new);

2 筛选与切片操作

  • filter 接受lambda从流中排除某些元素
  • limit 截断流,是元素不超过给定数量
  • skip(n) 跳过元素,返回一个扔掉前n个元素的流。如流中元素不足n个,则返回一个空流,与limit对应
  • distinct 筛选,通过流所生成的元素的hashcode()和equals()去除重复元素

例:

//fifter
Stream<Employee> stream = createEmp().stream().filter(emp -> emp.getAge() > 24);
stream.forEach(System.out::println);
//limit
System.out.println("limit...........................");
Stream<Employee> stream2 = createEmp().stream().filter(emp -> {
    System.out.println("filter操作");
    return emp.getAge() > 24;
});
stream2.limit(1).forEach(System.out::println);
//skip(n)
System.out.println("skip...........");
Stream<Employee> stream3= createEmp().stream();
//丢弃stream的前1+1个元素
stream3.filter(emp->emp.getAge()>24).skip(1).forEach(System.out::println);
//distinct
System.out.println("distinct............");
Stream<Employee> stream4= createEmp().stream();
stream4.distinct().forEach(x-> System.out.println(x));

3 Stream映射

@Test
public void test03(){
    List<String> list=Arrays.asList("aaa","bbb","ccc","ddd","eee");
    //stream 映射
    Stream<String> stream = createEmp().stream().map(employee -> employee.getLast_name()).distinct();
    stream.forEach(System.out::println);

    //map
    Stream<Stream<Character>> streamStream = list.stream().map(str -> fiterCharacter(str));
    streamStream.forEach(streamcharater->streamcharater.forEach(System.out::println));
    
    //flatMap
      Stream<Character> characterStream  =list.stream().flatMap(str -> fiterCharacter(str));
        streamStream.forEach(System.out::println);

}
public Stream<Character> fiterCharacter(String str){
    List<Character> list = new ArrayList<>();
    for (char c : str.toCharArray()) {
        list.add(c);
    }
    return list.stream();
}

4 排序

/*
* sort()自然排序
* sort(Compadator) //自定义条件排序
* */
Stream<Employee> stream = createEmp().stream().distinct().sorted((x, y) -> Integer.compare(x.getAge(), y.getAge()));
stream.forEach(System.out::println);

5 Stream的查找与匹配

  • allMatch 检查是否匹配所有元素
  • anyMacth 检查是否至少匹配一个元素
  • noneMatch 检查是否没有匹配所有元素
  • findFirst 返回第一个元素
  • findAny 返回当前流中的任意元素
  • count 返回流中元素的总个数
  • max 返回流中的最大值
  • min 返回流中最小值

例:

/*
    *
    - allMatch  检查是否匹配所有元素
    - anyMacth  检查是否至少匹配一个元素
    - noneMatch  检查是否没有匹配所有元素
    - findFirst  返回第一个元素
    - findAny  返回当前流中的任意元素
    - count  返回流中元素的总个数
    - max  返回流中的最大值
    - min   返回流中最小值
    * */
@Test
public void test05(){
    //allMatch
    boolean match1 = createEmp().stream().allMatch(employee -> employee.getAge() > 30);
    System.out.println(match1);
    //anyMatch
    boolean match2 = createEmp().stream().anyMatch(employee -> employee.getAge() > 30);
    System.out.println(match2);
    //noneMath
    boolean match3 = createEmp().stream().noneMatch(employee -> employee.getAge() > 30);
    System.out.println(match3);
    //findFirst
    Optional<Employee> emp1 = createEmp().stream().findFirst();
    System.out.println(emp1);
    //findAny
    Optional<Employee> emp2 = createEmp().stream().findAny();
    System.out.println(emp2.get());
    //count
    long count = createEmp().stream().count();
    System.out.println(count);
    //max
    Optional<Integer> max = createEmp().stream().map(employee -> employee.getAge()).max((x, y) -> Integer.compare(x, y));
    System.out.println(max.get());
    //min
    Optional<Employee> min = createEmp().stream().min((x, y) -> Integer.compare(x.getAge(), y.getAge()));
    System.out.println(min.get());
}
public List<Employee> createEmp() {
    List<Employee> employees = Arrays.asList(
        new Employee("张三", 29, 9999.99),
        new Employee("李四", 22, 8888.88),
        new Employee("王五", 35, 7777.77),
        new Employee("赵六", 23, 6666.66),
        new Employee("田七", 39, 5555.55),
        new Employee("田七", 39, 5555.55),
        new Employee("田七", 39, 5555.55)
    );
    return employees;
}

6 Stream的归约和收集

例:

① 归约
//归约
Double reduce1 = createEmp().stream().map(employee -> employee.getSalary()).distinct().reduce((double) 0, (x, y) -> x + y);
System.out.println(reduce1);
Optional<Integer> reduce2 = createEmp().stream().map(employee -> employee.getAge()).distinct().reduce((x, y) -> x + y);
System.out.println(reduce2.get());
② 收集
public List<Employee> createEmp() {
    List<Employee> employees = Arrays.asList(
        new Employee("张三", 29, 9999.99),
        new Employee("李四", 22, 8888.88),
        new Employee("王五", 35, 7777.77),
        new Employee("赵六", 23, 6666.66),
        new Employee("田七", 39, 5555.55),
        new Employee("田七", 39, 5555.55),
        new Employee("田七", 39, 5555.55)
    );
    return employees;
}

@Test
public void test01(){
    //归约
    Double reduce1 = createEmp().stream().map(employee -> employee.getSalary()).distinct().reduce((double) 0, (x, y) -> x + y);
    System.out.println(reduce1);
    Optional<Integer> reduce2 = createEmp().stream().map(employee -> employee.getAge()).distinct().reduce((x, y) -> x + y);
    System.out.println(reduce2.get());
}
@Test
public void test02(){
    //将名字收集起来添加到一个list中
    List<String> list = createEmp().stream().map(Employee::getLast_name).distinct().collect(Collectors.toList());
    System.out.println(list);
    //将名字收集起来添加到一个set中
    Set<String> set = createEmp().stream().map(Employee::getLast_name).collect(Collectors.toSet());
    set.forEach(System.out::println);
    //将Employee集合的元素转换为HashSet中
    HashSet<Employee> hashset = createEmp().stream().collect(Collectors.toCollection(HashSet::new));
    hashset.forEach(System.out::println);
    //求createEmp()集合的总数
    Long count = createEmp().stream().collect(Collectors.counting());
    System.out.println(count);
    //工资的平均值
    Double avarSalary = createEmp().stream().collect(Collectors.averagingDouble(emp -> emp.getSalary()));
    System.out.println(avarSalary);
    //工资综合
    DoubleSummaryStatistics sumSalay = createEmp().stream().collect(Collectors.summarizingDouble(emp -> emp.getSalary()));
    System.out.println(sumSalay.getSum());
    System.out.println(sumSalay);
    //工资最大者
    Optional<Employee> maxSalary = createEmp().stream().collect(Collectors.maxBy((x, y) -> Double.compare(x.getSalary(), y.getSalary())));
    System.out.println(maxSalary.get());
    //工资最小值
    Optional<Double> minSalary = createEmp().stream().map(z -> z.getSalary()).min((x, y) -> Double.compare(x, y));
    System.out.println(minSalary.get());
}

收集-分组:

public List<Employee> createEmp() {
    List<Employee> employees = Arrays.asList(
        new Employee("张三", 29, 9999.99, Status.FREE),
        new Employee("李四", 22, 8888.88,Status.BUSY),
        new Employee("王五", 35, 7777.77,Status.HOLIDAY),
        new Employee("赵六", 23, 6666.66,Status.HOLIDAY),
        new Employee("田七", 39, 5555.55,Status.BUSY),
        new Employee("田七", 39, 3333.33,Status.HOLIDAY),
        new Employee("小李", 45, 2222.22,Status.BUSY),
        new Employee("小张", 40, 1111.11,Status.FREE)

    );
    return employees;
}

@Test
public void test03(){
    //通过对员工状态进行分组
    Map<Status, List<Employee>> map1 = createEmp().stream().collect(Collectors.groupingBy(emp -> emp.getStatus()));
    Set<Map.Entry<Status, List<Employee>>> entrySet = map1.entrySet();
    for (Map.Entry<Status, List<Employee>> entry : entrySet) {
        System.out.println(entry.getKey()+":"+entry.getValue());
    }
    System.out.println("........................");
    //先通过对员工的状态分组,然后对员工的资金分组
    Map<Status, Map<String, List<Employee>>> map2 = createEmp().stream().collect(Collectors.groupingBy(emp -> emp.getStatus(), Collectors.groupingBy(emp -> {
        if (emp.getSalary() > 8000) {
            return "中高层收入";
        } else {
            return "底层收入";
        }
    })));
    Set<Map.Entry<Status, Map<String, List<Employee>>>> entrySet1 = map2.entrySet();
    for (Map.Entry<Status, Map<String, List<Employee>>> mapEntry : entrySet1) {
        for (Map.Entry<String, List<Employee>> entry : mapEntry.getValue().entrySet()) {
            for (Employee employee : entry.getValue()) {
                System.out.println(entry.getKey()+":"+employee);
            }
        }
    }
}

收集-分区

@Test
public void test04(){
    //根据工资是否大于8000分区
    final Map<Boolean, List<Employee>> empSalary = createEmp().stream().collect(Collectors.partitioningBy(emp -> emp.getSalary() > 8000));
    for (Map.Entry<Boolean, List<Employee>> entry : empSalary.entrySet()) {
        System.out.println(entry.getKey()+":"+entry.getValue());
    }
}

7 StreamAPI 练习

List<Transaction> transactions=null;
@Before
public void before(){
    Trader raoul = new Trader("Cambridge", "Raoul");
    Trader mario = new Trader("Milan", "Mario");
    Trader alan = new Trader("Cambridge", "Alan");
    Trader brian = new Trader("Cambridge", "Brian");

    transactions= Arrays.asList(
        new Transaction(brian,2011,300),
        new Transaction(raoul,2012,1000),
        new Transaction(raoul,2011,400),
        new Transaction(mario,2012,710),
        new Transaction(mario,2012,700),
        new Transaction(alan,2012,950)
    );
}

@Test
public void test01(){
    //找出2011年所有的交易,并按交易额排序(升序)
    Stream<Transaction> value = transactions.stream().filter(transaction -> transaction.getYear().equals(2011)).sorted((x, y) -> Integer.compare(x.getValue(), y.getValue()));
    value.forEach(System.out::println);
}
@Test
public void test02(){
    //交易员都在哪些不同的城市工作
    Map<String, List<Trader>> trader_city =transactions.stream().map(transaction -> transaction.getTrader()).collect(Collectors.groupingBy(trader -> trader.getName()));
    Set<Map.Entry<String, List<Trader>>> entries = trader_city.entrySet();
    for (Map.Entry<String, List<Trader>> entry : entries) {
        System.out.println(entry.getKey()+":"+entry.getValue());
    }
}

@Test
public void test03(){
    //查询所有来自剑桥的交易员,并按姓名进行排序
    Stream<Trader> trader2 = transactions.stream().map(transaction -> transaction.getTrader()).filter(trader -> trader.getCity().equals("Cambridge")).sorted((x,y)->x.getName().compareTo(y.getName())).distinct();
    trader2.forEach(System.out::println);
}
@Test
public void test04(){
    //返回所有交易员名字的字符串,按字母顺序排列
    Stream<String> stream = transactions.stream().map(transaction -> transaction.getTrader().getName()).sorted().distinct();
    stream.forEach(System.out::println);
    System.out.println("..........................");
    Optional<String> stream2 = transactions.stream().map(transaction -> transaction.getTrader().getName()).sorted().reduce((x, y) -> x.concat(y));
    System.out.println(stream2.get());
    System.out.println(".......................");
    Stream<String> stream3 = transactions.stream().map(transaction -> transaction.getTrader().getName()).flatMap(str -> getCharacter(str)).sorted((x, y) -> x.compareToIgnoreCase(y));
    stream3.forEach(System.out::print);

}
public Stream<String> getCharacter(String str){
    List<String> list = new ArrayList<>();
    for (Character ch: str.toCharArray()) {
        list.add(ch.toString());
    }
    return list.stream();
}
//有没有交易员在米兰工作的
@Test
public void test05(){
    boolean milan = transactions.stream().anyMatch(transaction -> transaction.getTrader().getCity().equals("Milan"));
    System.out.println(milan);
}

//打印生活在剑桥的交易员的所有交易金额
@Test
public void test06(){
    Optional<Integer> sumvalue = transactions.stream().filter(transaction -> transaction.getTrader().getCity().equals("Cambridge")).map(transaction -> transaction.getValue()).reduce(Integer::sum);
    System.out.println(sumvalue.get());
}

//所有交易中,最高交易金额是多少
@Test
public void test07(){
    Optional<Integer> max = transactions.stream().map(transaction -> transaction.getValue()).max(Integer::compareTo);
    System.out.println(max.get());
}
//找到交易金额最小的交易
@Test
public void test08(){
    Optional<Transaction> max = transactions.stream().max((x, y) -> Integer.compare(x.getValue(), y.getValue()));
    System.out.println(max.get());
}

8 并行流与串行流

ForkJoin

public class ForkjoinCalculate extends RecursiveTask<Long> {

    private Long start;
    private Long end;

    private final static Long THRESHOLD=10000L;

    public ForkjoinCalculate(Long start, Long end) {
        this.start = start;
        this.end = end;
    }


    @Override
    protected Long compute() {
        Long length=end-start;
        if(length<=THRESHOLD){
            long sum=0;
            for(long i=0;i<=end;i++){
                sum+=i;
            }
            return sum;
        }else {
            long middle=(start+end)/2;
            ForkjoinCalculate left = new ForkjoinCalculate(start, middle);
            left.fork(); //拆分子任务,压入线程
            ForkjoinCalculate right = new ForkjoinCalculate(middle+1, end);
            right.fork();
            return left.join()+right.join();
        }
    }
}

测试:

@Test
public void test09(){
    Instant start = Instant.now();
    ForkJoinPool pool = new ForkJoinPool();
    ForkjoinCalculate calculate = new ForkjoinCalculate(0L, 1000000000L);
    Long sum = pool.invoke(calculate);
    Instant end = Instant.now();
    System.out.println(sum+"时间:"+ Duration.between(start,end).toMillis());
}

@Test
public void test10(){
    Instant start = Instant.now();
    long sum=0L;
    for(long i=0;i<=1000000000L;i++){
        sum+=i;
    }
    Instant end = Instant.now();
    System.out.println(sum+"时间:"+ Duration.between(start,end).toMillis());
}
//java 8以后
@Test
public void test011(){
    Instant start = Instant.now();
    OptionalLong sum = LongStream.rangeClosed(0, 10000000L).parallel().reduce(Long::sum);
    Instant end = Instant.now();
    System.out.println(sum+"时间:"+ Duration.between(start,end).toMillis());
}

三 Optional类

//常用方法
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(Funcation f) //如果有值对其处理,并返回处理后的Optional。否则返回Optional.empty()
flatMap(Funcation mapper) //与map类似,要求传入参数必须是Optional

四 java 8接口默认方法与静态方法

@FunctionalInterface
public interface Myfun {

    public Integer getVaule(Integer num);

    default String getName(){
        return "hello  world";
    }

    public static String speak(){
        return "hello lambda";
    }
  • 如果A类继承B类(B类中具有getName()方法),同时A实现Myfun接口,此时类优先,会忽略接口的方法
  • 如果A类同时实现Myfun接口,并且实现C接口(C接口中具有getName()方法),此时会根据你的选择实现的接口的方法进行调用

五 新时间日期API

1 LocalDateTime

@Test
public void test01(){
    //LocalDate  LocalTime LocalDateTime
    LocalDateTime time = LocalDateTime.now();
    System.out.println(time);
    LocalDateTime dateTime = LocalDateTime.of(2017, 9, 10, 9, 35, 25);
    System.out.println(dateTime);
    LocalDateTime plusYears = time.plusYears(6);
    System.out.println(plusYears.getYear()+"我是什么样子?尬笑。。。");
    System.out.println(time.minusYears(2));
}

2 Instant

@Test
public void test02() {
    Instant instant1 = Instant.now();
    System.out.println(instant1);
    System.out.println(instant1.toEpochMilli());
    OffsetDateTime offsetDateTime = instant1.atOffset(ZoneOffset.ofHours(8));
    System.out.println(offsetDateTime);
}

@Test
public void test03() throws Exception {
    //Duration  计算两个“时间”的间隔
    //Period  计算两个“日期”的间隔
    Instant ins1 = Instant.now();
    Thread.sleep(1000);
    Instant ins2 = Instant.now();
    System.out.println(Duration.between(ins1, ins2).toMillis());

    LocalTime localTime1 = LocalTime.now();
    Thread.sleep(1000);
    LocalTime localTime2 = LocalTime.now();
    System.out.println(Duration.between(localTime1, localTime2).toMillis());

    LocalDate localDate1 = LocalDate.of(2017, 12, 15);
    LocalDate localDate = LocalDate.now();
    Period period = Period.between(localDate1, localDate);
    System.out.println(period.getYears());
    System.out.println(period.getMonths());
    System.out.println(period.getDays());

}

3 计算以记录的时间与现在的时间的差

//传入以 "毫秒" 为单位的时间,否则会出错
public String timediff(Long starttime) {
    long epochMilli = Instant.now().toEpochMilli();
    long timediff = (epochMilli - starttime)/1000;

    long minute = timediff / 60;
    long hour = timediff / (60 * 60);
    long date = timediff / (60 * 60 * 24);
    long month = timediff / (60 * 60 * 24 * 30);
    long year = timediff / (60 * 60 * 24 * 30 * 12);
    if (timediff <= 0) {
        return null;
    } else if (minute < 1) {
        return "刚刚";
    } else if (minute >= 1 && minute < 60) {
        return minute + "分钟前";
    } else if (hour >= 1 && hour < 24) {
        return hour + "小时前";
    } else if (date >= 1 && date < 30) {
        return date + "日前";
    } else if (month >= 1 && month < 12) {
        return month + "月前";
    } else {
        return year + "年前";
    }
}

4 时间矫正器

@Test
public void test05(){
    //TemporalAdjuster(时间矫正器)可使用TemporalAdjusters工具类
    LocalDateTime localDateTime = LocalDateTime.now();
    System.out.println(localDateTime);
    LocalDateTime localDateTime2 = localDateTime.withDayOfMonth(11); //指定某月的第几天
    System.out.println(localDateTime2);
    LocalDateTime localDateTime3 = localDateTime.withDayOfYear(1);
    System.out.println(localDateTime3);
    //获取下一个月的第一天
    LocalDateTime localDateTime4 = localDateTime.with(TemporalAdjusters.firstDayOfNextMonth());
    System.out.println(localDateTime4);
    //自定义:下一个工作日
    LocalDateTime nextWorkDay = localDateTime.with(adjuster -> {
        LocalDateTime time = LocalDateTime.now();
        if (time.getDayOfWeek().equals(DayOfWeek.FRIDAY)) {
            return (Temporal) time.plusDays(3);
        } else if (time.getDayOfWeek().equals(DayOfWeek.SATURDAY)) {
            return (Temporal) time.plusDays(2);
        } else {
            return (Temporal) time.plusDays(1);
        }
    });
    System.out.println(nextWorkDay);
}

5 时间的格式化和时区的处理

@Test
public void test06(){
    //DateTimeFormatter
    LocalDateTime localDateTime = LocalDateTime.now();
    DateTimeFormatter dateTimeFormatter=DateTimeFormatter.ISO_DATE; //只显示日期
    String format = localDateTime.format(dateTimeFormatter);
    System.out.println(format);

    DateTimeFormatter dateTimeFormatter2=DateTimeFormatter.ofPattern("yyyy:MM:dd hh:mm:ss");
    String format2 = dateTimeFormatter2.format(localDateTime);
    System.out.println(format2);
    //将时间字符串解析
    //        LocalDateTime parse = localDateTime.parse(format2, dateTimeFormatter2);
    //        System.out.println(parse);
}
@Test
public void test07(){
    //ZonedDate  ZonedDateTime  ZonedTime
    Set<String> set = ZoneId.getAvailableZoneIds();  //获取所有时区
    set.forEach(System.out::println);
}

@Test
public void test08(){
    LocalDateTime localDateTime = LocalDateTime.now(ZoneId.of("America/New_York")); //获取当前America/New_York的时间
    System.out.println(localDateTime);

    ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("Asia/Shanghai"));  //检测当前America/New_York与Asia/Shanghai时区的时差的详细信息
    System.out.println(zonedDateTime);
}

6 重复注解与类型注解

① 重复注解

//使用重复注解必须要把注解加入到另一个注解容器中
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotations {
    MyAnnotation [] value();
}
//在注解的头上加入@Repeatable(MyAnnotations.class)
@Repeatable(MyAnnotations.class)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    public String value() default "";
}

测试:

@Test
public void test01() throws Exception {
    Method method = this.getClass().getMethod("show");
    MyAnnotation[] annotations = method.getAnnotationsByType(MyAnnotation.class);
    for (MyAnnotation annotation : annotations) {
        System.out.println(annotation.value());
    }

}

@MyAnnotation(value = "hello")
@MyAnnotation(value = "world")
public void show(){

}

② 类型注解:

//@Target(ElementType.PARAMETER) ElementType.PARAMETER类型注解
@Repeatable(MyAnnotations.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface MyAnnotation {

    public String value() default "";
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值