java新特性
发表于|更新于
|字数总计:3.4k|阅读时长:16分钟|阅读量:
技巧
map.forEach
1 2 3 4 5 6 7 8 9 10 11 12 13
| Map<String, Object> map= new HashMap<>(); infoMap.put("a", "a"); infoMap.put("b", "b"); infoMap.put("c", "c");
for (Map.Entry<String, Object> entry : map.entrySet()) { System.out.println(entry.getKey() + ":" + entry.getValue()); }
map.forEach((key, value) -> { System.out.println(key + ":" + value); });
|
字符串与列表转换
java8 stream流
主要是用来更好的过滤或加工成想要的内容
contains包含
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @SpringBootTest class Study {
@Test void filter() { List<String> strings = Arrays.asList("abc", "abcd", "abcde", "f"); List<String> filter = strings.stream().filter(str -> str.contains("a")).collect(Collectors.toList()); System.out.println(filter); }
|
distinct:去除重复的
1 2 3 4 5 6 7 8 9 10
|
@Test void distinct(){ List<String> strings = Arrays.asList("abc", "abcd", "abcde", "f","","f","c","abc"); List<String> distinct = strings.stream().distinct().collect(Collectors.toList()); System.out.println(distinct); }
|
limit 边界长度
1 2 3 4 5 6 7 8 9 10
|
@Test void limit(){ List<String> strings = Arrays.asList("abc", "abcd", "abcde", "f","","f","c","abc"); List<String> limit = strings.stream().limit(4).collect(Collectors.toList()); System.out.println(limit); }
|
anyMatch 一个满足
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
@Test public void anyMatch(){ List<String> strings = Arrays.asList("abc", "abcd", "abcde", "f","","f","c","abc"); boolean bc = strings.stream().anyMatch(s -> s.contains("bc")); System.out.println(bc);
boolean q = strings.stream().anyMatch(s -> s.contains("q")); System.out.println(q); }
|
集体满足
1 2 3 4 5 6 7 8 9
|
@Test public void allMatch(){ List<String> strings = Arrays.asList("abc", "abcd", "abcde", "f","","f","c","abc"); boolean length = strings.stream().allMatch(s -> s.length() > 3); System.out.println(length); }
|
返回元素
1 2 3 4 5 6 7 8 9 10 11 12 13
|
@Test public void findAny(){ List<String> strings = Arrays.asList("abc", "abcd", "abcde", "f","","f","c","abc"); Optional<String> any = strings.stream().findAny(); System.out.println(any.get());
Optional<String> first = strings.stream().findFirst(); System.out.println(first.get()); }
|
forEach 简单的循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @Test void forEach(){ List<String> strings = Arrays.asList("abc", "abcd", "abcde", "f","","f","c","abc"); strings.stream().forEach(s -> System.out.println(s));
}
|
skip 去掉前面 n 个元素
1 2 3 4 5 6 7 8 9 10 11
|
@Test void skip(){ List<String> strings = Arrays.asList("abc","bc","bc","efg","abcd","","f","jkl"); List<String> collect = strings.stream().skip(3).collect(Collectors.toList()); System.out.println(collect); }
|
map : 对流中的所有元素作统一处理
1 2 3 4 5 6 7 8 9 10
|
@Test void map(){ List<String> strings = Arrays.asList("abc","bc","bc","efg","abcd","","f","jkl"); List<String> collect = strings.stream().map(str -> "Hulu_" + str.concat("_Bye")).collect(Collectors.toList()); System.out.println(collect); }
|
flatMap 小集合合并成大集合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
@Test void en(){ Student z3 = new Student("z3", 22,Arrays.asList("语文", "数学")); Student l4 = new Student("l4", 18,Arrays.asList("英语", "化学")); Student w5 = new Student("w5", 20,Arrays.asList("科学")); List<Student> students = Arrays.asList(z3, l4, w5); List<String> collect = students.stream().flatMap(stu -> stu.getSubject().stream()).collect(Collectors.toList());
System.out.println(collect); }
|
sorted:排序
Comparator.comparing () 对象特定排序
更多排序参考:
https://www.cnblogs.com/zhangliang88/p/14341348.html
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
|
@Test void sorted(){ List<String> strings = Arrays.asList("abc","bc","bc","efg","abcd","","f","jkl"); List<String> collect = strings.stream().sorted().collect(Collectors.toList()); System.out.println(collect); Collator.getInstance(Locale.CHINA); }
@Test void paiXu(){ Student z3 = new Student("z3", 22); Student l4 = new Student("l4", 18); Student w5 = new Student("w5", 20); ArrayList<Student> objects = new ArrayList<>(); objects.add(z3); objects.add(l4); objects.add(w5);
List<Student> collect = objects.stream().sorted(Comparator.comparing(Student::getAge)).collect(Collectors.toList()); System.out.println(collect); }
|
summaryStatistics 统计
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
@Test void summaryStatistics(){ List<Integer> primes = Arrays.asList(1,2,3,4,5,6,7,8,9,10); IntSummaryStatistics stats = primes.stream().mapToInt(x->x).summaryStatistics(); System.out.println("max : " + stats.getMax()); System.out.println("min : " + stats.getMin()); System.out.println("sum : " + stats.getSum()); System.out.println("average : " + stats.getAverage());
} }
|
java8 日期时间类
部分转载自
https://blog.csdn.net/lemon_TT/article/details/109145432
LocalDate
只会获取年月日
1 2 3 4
| LocalDate localDate = LocalDate.now();
LocalDate localDate1 = LocalDate.of(2020, 10, 10);
|
获取年、月、日、星期几
1 2 3 4 5 6 7 8 9 10 11 12
| int year = localDate.getYear(); int year1 = localDate.get(ChronoField.YEAR);
Month month = localDate.getMonth(); int month1 = localDate.get(ChronoField.MONTH_OF_YEAR);
int day = localDate.getDayOfMonth(); int day1 = localDate.get(ChronoField.DAY_OF_MONTH);
DayOfWeek dayOfWeek = localDate.getDayOfWeek(); int dayOfWeek1 = localDate.get(ChronoField.DAY_OF_WEEK);
|
LocalTime
只会获取几点几分几秒
1 2
| LocalTime localTime = LocalTime.of(13, 51, 10); LocalTime localTime1 = LocalTime.now();
|
1 2 3 4 5 6 7 8 9
| int hour = localTime.getHour(); int hour1 = localTime.get(ChronoField.HOUR_OF_DAY);
int minute = localTime.getMinute(); int minute1 = localTime.get(ChronoField.MINUTE_OF_HOUR);
int second = localTime.getSecond(); int second1 = localTime.get(ChronoField.SECOND_OF_MINUTE);
|
LocalDateTime
获取年月日时分秒,等于LocalDate+LocalTime
1 2 3 4 5
| LocalDateTime localDateTime = LocalDateTime.now(); LocalDateTime localDateTime1 = LocalDateTime.of(2020, Month.SEPTEMBER, 10, 14, 46, 56); LocalDateTime localDateTime2 = LocalDateTime.of(localDate, localTime); LocalDateTime localDateTime3 = localDate.atTime(localTime); LocalDateTime localDateTime4 = localTime.atDate(localDate);
|
1 2 3 4
| LocalDate localDate2 = localDateTime.toLocalDate();
LocalTime localTime2 = localDateTime.toLocalTime();
|
Instant
获取秒数
如果只是为了获取秒数或者毫秒数,使用System.currentTimeMillis()
来得更为方便
1 2 3 4 5
| Instant instant = Instant.now();
long currentSecond = instant.getEpochSecond();
long currentMilli = instant.toEpochMilli();
|
日期时间的修改与计算
LocalDate、LocalTime、LocalDateTime、Instant为不可变对象,修改这些对象对象会返回一个副本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| LocalDateTime localDateTime = LocalDateTime.of(2020, Month.SEPTEMBER, 10, 14, 46, 56);
localDateTime = localDateTime.plusYears(1); localDateTime = localDateTime.plus(1, ChronoUnit.YEARS);
localDateTime = localDateTime.minusMonths(1); localDateTime = localDateTime.minus(1, ChronoUnit.MONTHS);
localDateTime = localDateTime.withYear(2020);
localDateTime = localDateTime.with(ChronoField.YEAR, 2022);
|
另外比如有些时候想知道这个月的最后一天是几号、下个周末是几号,通过提供的时间和日期API可以很快得到答案,比如通过firstDayOfYear()
返回了当前日期的第一天日期
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| System.out.println("//本月的第一天"); System.out.println(localDate.now().with(TemporalAdjusters.firstDayOfMonth()));
System.out.println("//今年的程序员日"); System.out.println(LocalDate.now().with(TemporalAdjusters.firstDayOfYear()).plusDays(255));
System.out.println("//今天之前的一个周六"); System.out.println(LocalDate.now().with(TemporalAdjusters.previous(DayOfWeek.SATURDAY)));
System.out.println("//本月最后一个工作日"); System.out.println(LocalDate.now().with(TemporalAdjusters.lastInMonth(DayOfWeek.FRIDAY)));
System.out.println("//自定义逻辑"); System.out.println(LocalDate.now().with(temporal -> temporal.plus(ThreadLocalRandom.current().nextInt(100), ChronoUnit.DAYS)));
|
Java 8 中有一个专门的类 Period 定义了日期间隔,通过 Period.between
得到了两个 LocalDate
的差,返回的是两个日期差几年零几月零几天。如果希望得知两个日期之间差几天,直接调用Period
的 getDays()
方法得到的只是最后的“零几天”,而不是算总的间隔天
1 2 3 4 5 6 7 8 9 10 11 12
| public static void main(String[] args) throws Exception { System.out.println("//计算日期差"); LocalDate today = LocalDate.of(2019, 12, 12); LocalDate specifyDate = LocalDate.of(2019, 10, 1); System.out.println(Period.between(specifyDate, today).getDays()); System.out.println(Period.between(specifyDate, today)); System.out.println(ChronoUnit.DAYS.between(specifyDate, today)); }
|
格式化日期(常用)
DateTimeFormatter默认提供了多种格式化方式,如果默认提供的不能满足要求,可以通过DateTimeFormatter的ofPattern方法创建自定义格式化方式
1 2 3 4 5 6 7 8 9 10 11
| LocalDate localDate1 = LocalDate.parse("20201010", DateTimeFormatter.BASIC_ISO_DATE); System.out.println("localDate1 = " + localDate1); LocalDate localDate2 = LocalDate.parse("2020-10-10", DateTimeFormatter.ISO_LOCAL_DATE); System.out.println("localDate2 = " + localDate2);
LocalDateTime longTime = LocalDateTime.of(1999, 10, 2, 1, 2,3); System.out.println(longTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
自定义DateTimeFormatterBuilder。用得比较少
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder() .appendValue(ChronoField.YEAR) .appendLiteral("/") .appendValue(ChronoField.MONTH_OF_YEAR) .appendLiteral("/") .appendValue(ChronoField.DAY_OF_MONTH) .appendLiteral(" ") .appendValue(ChronoField.HOUR_OF_DAY) .appendLiteral(":") .appendValue(ChronoField.MINUTE_OF_HOUR) .appendLiteral(":") .appendValue(ChronoField.SECOND_OF_MINUTE) .appendLiteral(".") .appendValue(ChronoField.MILLI_OF_SECOND) .toFormatter();
System.out.println(LocalDateTime.now().format(dateTimeFormatter));
|
时区
Java 8 推出了新的时间日期类 ZoneId、ZoneOffset、LocalDateTime、ZonedDateTime和 DateTimeFormatter,处理时区问题更简单清晰
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| String stringDate = "2020-01-02 22:00:00"; ZoneId timeZoneSH = ZoneId.of("Asia/Shanghai"); ZoneId timeZoneNY = ZoneId.of("America/New_York"); ZoneId timeZoneJST = ZoneOffset.ofHours(9);
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); ZonedDateTime date = ZonedDateTime.of(LocalDateTime.parse(stringDate, dateTimeFormatter), timeZoneJST);
DateTimeFormatter outputFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss Z"); System.out.println(timeZoneSH.getId() +"------"+ outputFormat.withZone(timeZoneSH).format(date)); System.out.println(timeZoneNY.getId() +"------"+ outputFormat.withZone(timeZoneNY).format(date)); System.out.println(timeZoneJST.getId() +"------"+ outputFormat.withZone(timeZoneJST).format(date));
Asia/Shanghai------2020-01-02 21:00:00 +0800 America/New_York------2020-01-02 08:00:00 -0500 +09:00------2020-01-02 22:00:00 +0900
|
前后端日期时间转化问题
项目一般在实体类上加@DatetimeFormat
与@JsonFormat
注解
两个需要同时加,否则会有时区的问题
1 2 3 4
| @ApiModelProperty("创建时间") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime createTime;
|
或者在配置文件加
1 2 3
| #时间戳统一转换 spring.jackson.date-format=yyyy-MM-dd HH:mm:ss spring.jackson.time-zone=GMT+8
|
消失的八小时
日期字符串存入DB后差8小时
在后端与数据库交互的时候,可能会遇到一个问题,就是往DB中存储了一个时间字段之后,后面再查询的时候,就会发现时间数值差了8个小时,这个需要在DB的连接信息中指定下时区信息:
spring.datasource.druid.url=jdbc:mysql://127.0.0.1:3306/test?serverTimezone=Asia/Shanghai
界面时间与后台时间差8小时
在有一些前后端交互的项目中,可能会遇到一个问题,就是前端选择并保存了一个时间信息,再查询的时候就会发现与设置的时间差了8个小时,这个其实就是后端时区转换设置的问题。SpringBoot的配置文件中,需要指定时间字符串转换的时区信息:
spring.jackson.time-zone=GMT+8
这样从接口json中传递过来的时间信息,jackson框架可以根据对应时区转换为正确的Date数据进行处理。
模板解释
字母 |
使用说明 |
yyyy |
4位数的年 |
yy |
显示2位数的年份,比如2022年,则显示为22年 |
MM |
显示2位数的月份,不满2位数的,前面补0,比如7月份显示07月 |
M |
月份,不满2位的月份不会补0 |
dd |
天, 如果1位数的天数,则补0 |
d |
天,不满2位数字的,不补0 |
HH |
24小时制的时间显示,小时数,两位数,不满2位数字的前面补0 |
H |
24小时制的时间显示,小时数,不满2位数字的不补0 |
hh |
12小时制的时间显示,小时数,两位数,不满2位数字的前面补0 |
ss |
秒数,不满2位的前面补0 |
s |
秒数,不满2位的不补0 |
SSS |
毫秒数 |
z |
时区名称,比如北京时间东八区,则显示CST |
Z |
时区偏移信息,比如北京时间东八区,则显示+0800 |
|
|