ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

jdk8新特性之方法引用和日期

2022-09-01 00:03:32  阅读:235  来源: 互联网

标签:31 System 日期 jdk8 引用 2022 println TODO out


方法引用的三种表现形式

方法引用的基本思想是,如果一个Lambda代表的只是“直接调用这个方法”,那 最好还是用名称来调用它,而不是去描述如何调用它。事实上,方法引用就是让 你根据已有的方法实现来创建Lambda表达式。但是,显式地指明方法的名称, 你的代码的可读性会更好。所以方法引用只是在内容中只有一个表达式的简写。

当 你 需 要使用 方 法 引用时 , 目 标引用 放 在 分隔符::前 ,方法 的 名 称放在 后 面 ,即ClassName :: methodName 。例如 ,Apple::getWeight就是引用了Apple 类中定义的方法getWeight。请记住,不需要括号,因为你没有实际调用这个方 法。方法引用就是Lambda表达式(Apple a) ­> a.getWeight()的快捷写法。

这里有种情况需要特殊说明,就是类的构造函数情况,这个时候是通过 ClassName::new这种形式创建Class构造函数对应的引用,例如

若lambda体中的内容有方法已经实现了,那么可以使用”方法引用“

也可以理解为方法引用是lambda表达式的另外一种表现形式并且其语法比lambda表达式更加简单

三种表现形式
对象::实例方法名
类::静态方法名
类::实例方法名(lambda参数列表中第一个参数是实例方法的调用者,第二个是实例方法的参数时可用)		
// TODO: 2022/8/29 方法引用-对象::实例方法
Consumer<Integer> con2 = System.out::println;
con2.accept(200);

// TODO: 2022/8/29 方法引用-类::静态方法名
BiFunction<Integer,Integer,Integer> bigFun = (x, y)->Integer.compare(x,y);
BiFunction<Integer,Integer,Integer> bigFun2 = Integer::compareTo;
System.out.println(bigFun.apply(100, 200));
System.out.println(bigFun2.apply(800, 600));

// TODO: 2022/8/29 方法引用-类::实例方法名
BiFunction<String,String,Boolean> bigFun3 = (x,y)->x.equals(y);
BiFunction<String,String,Boolean> bigFun4 = String::equals;
System.out.println(bigFun3.apply("a", "a"));
System.out.println(bigFun4.apply("b", "c"));
注意:

1、lambda体中调用方法的参数列表返回值类型,要与函数式接口抽象方法函数列表返回值类型保持一致!

2、若lambda参数列表中的第一个参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用ClassName::method

特殊例子
// TODO: 2022/8/29 构造方法引用 类名::new
Supplier<String> sup = () -> new String();
System.out.println(sup.get());
Supplier<String> sup2 = String::new;
System.out.println(sup2.get());

// TODO: 2022/8/29 类名::new(带一个参数)
Function<String, Integer> fun = x -> new Integer(x);
Function<String, Integer> fun2 = Integer::new;
System.out.println(fun.apply("1000"));
System.out.println(fun2.apply("2000"));

// TODO: 2022/8/29 数组引用 
Function<Integer, String[]> fun = x -> new String[x];
Function<Integer, String[]> fun2 = String[]::new;
String[] strArray = fun2.apply(10);
Arrays.stream(strArray).forEach(System.out::println);

日期/时间改进

1 * 之前使用的java.util.Date月份从0开始,我们一般会+1使用,很不方便, java.time.LocalDate月份和星期都改成了enum

2 * java.util.Date和SimpleDateFormat都不是线程安全的,而LocalDate和LocalTime 和最基本的String一样,是不变类型,不但线程安全,而且不能修改。

3 * java.util.Date是一个“万能接口”,它包含日期、时间,还有毫秒数,更加明确需求取 舍

4 * 新接口更好用的原因是考虑到了日期时间的操作,经常发生往前推或往后推几天的情 况。用java.util.Date配合Calendar要写好多代码,而且一般的开发人员还不一定能写对。

LocalDate/LocalTime/LocalDateTime

LocalDate为日期处理类、LocalTime为时间处理类、LocalDateTime为日期时间处理类

方法都类似,具体可以看API文档或源码,选取几个代表性的方法做下介绍。

now相关的方法可以获取当前日期或时间

of方法可以创建对应的日期或时间

parse方法 可以解析日期或时间

get方法可以获取日期或时间信息

with方法可以设置日期或时间信息

plus或minus方法可以增减日期或时间信息
TemporalAdjusters

这个类在日期调整时非常有用,比如得到当月的第一天、最后一天,当年的第一天、最后一

天,下一周或前一周的某天等。

// TODO: 2022/8/31 获取当前日期,只含年月日 固定格式 yyyy-MM-dd
LocalDate today = LocalDate.now();

// TODO: 2022/8/31 根据年月日去日期,5月就是5
LocalDate oldDate = LocalDate.of(2018, 5, 1);
System.out.println("oldDate = " + oldDate);

// TODO: 2022/8/31 根据字符串取:默认格式yyyy-MM-dd,02不能写成2
LocalDate yesteday = LocalDate.parse("2018-05-03");

// TODO: 2022/8/31 如果不是闰年 传入29号也会报错
//LocalDate localDate = LocalDate.parse("2018-02-29"); 会报错的

// TODO: 2022/8/31 ==========日期转换
// TODO: 2022/8/31
LocalDate today1 = LocalDate.now();
// TODO: 2022/8/31 取本月第一天: 2022-08-01
LocalDate firstDayOfMonth = today1.with(TemporalAdjusters.firstDayOfMonth());
// TODO: 2022/8/31 取本月第二天: 2022-08-02
LocalDate secondDayOfMonth = today1.withDayOfMonth(2);
// TODO: 2022/8/31 取本月最后一天,再也不用计算是28、29、30还是31: 2022-08-31
LocalDate lastDayOfMonth = today1.with(TemporalAdjusters.lastDayOfMonth());
// TODO: 2022/8/31 取本月最后一天的下一天: 2022-09-01
LocalDate nextDay = lastDayOfMonth.plusDays(1);
// TODO: 2022/8/31 取2018年10月第一个周三:2018-10-03
LocalDate firstWednesday = LocalDate.parse("2018-10-01").with(TemporalAdjusters.firstInMonth(DayOfWeek.WEDNESDAY));
DateTimeFormatter

以前日期格式化一般用SimpleDateFormat类,但是不怎么好用,现在1.8引入了 DateTimeFormatter类,默认定义了很多常量格式(ISO打头的),在使用的时候一般配合 LocalDate/LocalTime/LocalDateTime使用,比如想把当前日期格式化成yyyy-MM-dd hh:mm:ss的形式:

LocalDateTime dt = LocalDateTime.now(); 
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy‐MM‐dd hh:mm:ss");
System.out.println(dtf.format(dt));
时间戳转换
// TODO: 2022/8/31 获得时分秒.纳秒 22:26:11.800
LocalTime todayTimeWithMillisTime = LocalTime.now();
// TODO: 2022/8/31 不带纳秒值 22:26:11
LocalTime todayTimeWithNoMillisTime = LocalTime.now().withNano(0);
LocalTime time = LocalTime.parse("23:59:59");

// TODO: 2022/8/31 转化为时间戳 毫秒值
long time1 = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
long time2 = System.currentTimeMillis();

// TODO: 2022/8/31 时间戳转化为LocalDateTime 2022-08-31 22:43:29.645
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
String formatTime = dateTimeFormatter.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(time1), ZoneId.of("Asia/Shanghai")));
System.out.println("formatTime = " + formatTime);
LocalDateTime格式化转换
// TODO: 2022/8/31 DateTimeFormatter: 格式化时间/日期
// 自定义格式
LocalDateTime ldt = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
String strDate = ldt.format(formatter);
String strDate2 = formatter.format(ldt);
System.out.println("strDate = " + strDate);
System.out.println("strDate2 = " + strDate2);

// TODO: 2022/8/31 使用api提供的格式
DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE;
LocalDateTime ldt2 = LocalDateTime.now();
String strDate3 = dtf.format(ldt2);
System.out.println("strDate3 = " + strDate3);

// TODO: 2022/8/31 解析字符串to时间
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime time = LocalDateTime.now();
String localTime = dateTimeFormatter.format(time);
LocalDateTime ldt4 = LocalDateTime.parse("2017-09-28 17:07:05", dateTimeFormatter);
System.out.println("LocalDateTime转成String类型的时间:"+localTime);
System.out.println("String类型的时间转成LocalDateTime:"+ldt4);
LocalDateTime基本操作
// TODO: 2022/8/31 从默认失去的系统始终获取当前的日期时间,不用考虑时区差
LocalDateTime dateTime = LocalDateTime.now();
// TODO: 2022/8/31  2022-08-31T23:05:02.831
System.out.println("dateTime = " + dateTime);

System.out.println("dateTime.getYear() = " + dateTime.getYear());
System.out.println("dateTime.getMonthValue() = " + dateTime.getMonthValue());
System.out.println("dateTime.getDayOfMonth() = " + dateTime.getDayOfMonth());
System.out.println("dateTime.getHour() = " + dateTime.getHour());
System.out.println("dateTime.getMinute() = " + dateTime.getMinute());
System.out.println("dateTime.getSecond() = " + dateTime.getSecond());
System.out.println("dateTime.getNano() = " + dateTime.getNano());

// TODO: 2022/8/31 手动创建一个LocalDateTime实例 
LocalDateTime date2 = LocalDateTime.of(2017, 12, 17, 9, 34, 31);
System.out.println("date2 = " + date2);
// TODO: 2022/8/31 进行加操作,得到新的日期实例
LocalDateTime date3 = date2.plusDays(12);
System.out.println("date3 = " + date3);
// TODO: 2022/8/31 进行减操作
LocalDateTime date4 = date3.minusYears(2);
System.out.println("date4 = " + date4);
获取时间戳
// TODO: 2022/8/31 获取毫秒值
// TODO: 2022/8/31 时间戳 1970年1月1日00:00:00 到某一个时间点的毫秒值
// TODO: 2022/8/31 默认获取UTC时区
Instant ins = Instant.now();
System.out.println("ins = " + ins);

System.out.println(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
System.out.println(System.currentTimeMillis());

System.out.println(Instant.now().toEpochMilli());
System.out.println(Instant.now().atOffset(ZoneOffset.ofHours(8)).toInstant().toEpochMilli());
计算间隔时间
 // TODO: 2022/8/31 计算时间间隔
// TODO: 2022/8/31 Duration:计算两个时间之间的间隔
// TODO: 2022/8/31 Period:计算两个日期之间的间隔
Instant instant = Instant.now();
//LocalTime localTime = LocalTime.now();

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
Instant instant2 = Instant.now();
//LocalTime localTime2 = LocalTime.now();
Duration duration = Duration.between(instant, instant2);
System.out.println("duration = " + duration);
System.out.println(duration.toMillis());

System.out.println("===================");

LocalDate localDate = LocalDate.now();
try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
LocalDate localDate2 = LocalDate.of(2016, 12, 12);
Period period = Period.between(localDate, localDate2);
System.out.println("period = " + period);
时间操作
// TODO: 2022/8/31 temperalAdjust 时间校验器
LocalDateTime ldt1 = LocalDateTime.now();
System.out.println("ldt1 = " + ldt1);

// TODO: 2022/8/31 获取一年中的第一天
LocalDateTime ldt2 = ldt1.withDayOfYear(1);
System.out.println("ldt2 = " + ldt2);
// TODO: 2022/8/31 获取一个月中的第一天
LocalDateTime ldt3 = ldt1.withDayOfMonth(1);
System.out.println("ldt3 = " + ldt3);

// TODO: 2022/8/31 例如获取下周日
LocalDateTime ldt4 = ldt1.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
System.out.println("ldt4 = " + ldt4);

// TODO: 2022/8/31 获取下一个工作日
LocalDateTime ldt5 = ldt1.with((t) -> {
    LocalDateTime ldt6 = (LocalDateTime) t;
    DayOfWeek dayOfWeek = ldt6.getDayOfWeek();
    if (DayOfWeek.FRIDAY.equals(dayOfWeek)) {
        return ldt6.plusDays(3);
    } else if (DayOfWeek.SATURDAY.equals(dayOfWeek)) {
        return ldt6.plusDays(2);
    } else {
        return ldt6.plusDays(1);
    }
});
System.out.println("ldt5 = " + ldt5);

标签:31,System,日期,jdk8,引用,2022,println,TODO,out
来源: https://www.cnblogs.com/LEPENGYANG/p/16644983.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有