一.时间
1.获取当前日期(只能精确到年月日)
String formatStr = "yyyy-MM-dd";
LocalDate now = LocalDate.now();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(formatStr);
String nowFormat = now.format(dateTimeFormatter);
System.out.println("格式化后的当前日期:"+nowFormat);
结果: 格式化后的当前日期:2022-03-28
2.获取当前时间(可以精确到秒)
String formatStr = "yyyy-MM-dd HH:mm:ss";
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(formatStr);
String nowFormat = now.format(dateTimeFormatter);
System.out.println("格式化后的当前日期:"+nowFormat);
结果: 格式化后的当前日期:2022-03-28 10:15:51
3.操纵、解析和格式化日期
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime now = LocalDateTime.now();
String nowFormat = now.format(dateTimeFormatter);
System.out.println("格式化后的当前时间:"+nowFormat);
//六小时前
LocalDateTime minusTime = now.minusHours(6);
String minusTimeFormat = minusTime.format(dateTimeFormatter);
System.out.println("格式化后的6小时前的时间:"+minusTimeFormat);
//六小时后
LocalDateTime plusTime = now.plusHours(6);
String plusTimeFormat = plusTime.format(dateTimeFormatter);
System.out.println("格式化后的6小时后的时间:"+plusTimeFormat);
//通过 isBefore或isAfter比较时间大小
System.out.println("minusTime是否比now小: "+minusTime.isBefore(now));
System.out.println("plusTime是否比now大: "+plusTime.isAfter(now));
//指定时间和当前时间进行比较
String str = "2022-03-27 14:41:06";
LocalDateTime date = LocalDateTime.parse(str, dateTimeFormatter);
System.out.println("date是否比now大: "+date.isAfter(now));
//指定时间和当前时间pi
String str1 = "2022-03-29 14:41:06";
LocalDateTime date1 = LocalDateTime.parse(str1, dateTimeFormatter);
System.out.println("date1是否比now大: "+date1.isAfter(now));
输出结果:
备注:LocalDate类,LocalDateTime 类是线程安全,因为类被final类型。
1,写final域的重排序规则:JMM禁止编译器把final域的写重排序到构造函数初始化之外(之后)。
编译器会在final域的写之后,构造函数return之前,插入一个StoreStore内存屏障
2,读final域的重排序规则:在一个线程中,初次读对象引用与初次读该对象包含的final域,
JMM禁止重排序这2个操作。编译器会在读final域操作的前面插入一个LoadLoad屏障。
涉及的概念:
内存屏障(Memory Barrier)与内存栅栏(Memory Fence)是同一个概念
按照内存屏障的分类
- 1.一类是强制读取主内存,强制刷新主内存的内存屏障,叫做Load屏障和Store屏障
Store:将处理器缓存的数据刷新到内存中。
Load:将内存存储的数据拷贝到处理器的缓存中。 - 2.另外一类是禁止指令重排序的内存屏障,有四个分别叫做LoadLoad屏障、StoreStore屏障、LoadStore屏 障、StoreLoad屏障。
如:store1指令 StoreStore屏障 store2指令:在store1指令和store2指令之间加上StoreStore屏障, 强制先 执行store1指令再执行store2指令;store1指令不能和store2指令进行重排序
二.Stream流
Stream(流)是一个来自数据源的元素队列并支持聚合操作
- 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
- 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
- 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。
1. map()
官方: map:Returns a stream consisting of the results of applying the given function to the elements of this stream.
返回一个流,包含给定函数应用在流中每一个元素后的结果
(1)map 方法用于映射每个元素到对应的结果
例子:List numbers = Arrays.asList(1, 2, 3, 4, 5);
List squaresList = numbers.stream().map( i -> i*i).collect(Collectors.toList());
System.out.println(squaresList);
输出结果:[1, 4, 9, 16, 25]
(2)利用stream().map()提取List对象的某一列值
例:List nameList = studentList.stream().map(StudentInfo::getName).collect(Collectors.toList());
flatMap() 返回一个流,包含给定函数应用在流中每一个元素后的结果
官方:flatmap:Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.
用于将原有二维结构扁平化,
Stream<String[]>
Stream<Set<String>>
Stream<List<String>>
以上这三类结构,通过 flatMap
方法,可以将结果转化为 Stream<String>
这种形式,方便之后的其他操作。
Stream map和flatmap的区别,请参考:
www.cnblogs.com/wangjing666…
2. reduce();
reduction 操作(也称为fold),通过反复的对一个输入序列的元素进行某种组合操作(如对数的集合求和、求最大值,或者将所有元素放入一个列表),最终将其组合为一个单一的概要信息
例子一:
public static void main(String[] args) {
ArrayList<Integer> newList = new ArrayList<>();
ArrayList<Integer> accResult_s = Stream.of(1,2,3,4)
.reduce(newList,
(acc, item) -> {
acc.add(item);
System.out.println("item: " + item);
System.out.println("acc+ : " + acc);
return acc;
}, (acc, item) -> null
);
System.out.println("accResult_s: " + accResult_s);
}
结果:
1. 第一个参数:返回实例u,传递你要返回的U类型对象的初始化实例u
2. 第二个参数:累加器accumulator,可以使用lambda表达式,声明你在u上累加你的数据来源t的逻辑,例如(u,t)->u.sum(t),此时lambda表达式的行参列表是返回实例u和遍历的集合元素t,函数体是在u上累加t
3. 第三个参数:参数组合器combiner,接受lambda表达式。
对于第三个函数参数,为什么没有执行,而且其参数必须为返回的数据类型?这是因为Stream是支持并发操作的,为了避免竞争,对于reduce线程都会有独立的result,combiner的作用在于合并每个线程的result得到最终结果。这也说明了了第三个函数参数的数据类型必须为返回数据类型了。
例子二:
Stream<Integer> integerStream = Stream.of(1,2,5,7,8,12,30);
Integer sum = integerStream.reduce(0,(x,y)->x+y);
System.out.println(sum);
3.groupingBy()
1.根据条件范围分组
public static void main(String[] args) {
List<Dish> menu=new ArrayList<>();
menu.add(new Dish("牛肉",300));
menu.add(new Dish("猪肉",500));
menu.add(new Dish("鱼肉",600));
menu.add(new Dish("羊肉",800));
Map<CaloricLevel, List<Dish>> dishesByCaloricLevel = menu.stream().collect(
groupingBy(dish -> {
if (dish.getCalories() <= 400) return CaloricLevel.DIET;
else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL;
else return CaloricLevel.FAT;
} ));
System.out.println(dishesByCaloricLevel);
}
结果是
2.根据某个字段进行分组
public static void main(String[] args) {
List<Dish> menu=new ArrayList<>();
menu.add(new Dish("牛肉",300));
menu.add(new Dish("猪肉",500));
menu.add(new Dish("鱼肉",600));
menu.add(new Dish("羊肉",800));
menu.add(new Dish("",800));
Map<String, List<Dish>> collect = menu.stream().collect(groupingBy(e -> {
if (e.getName() == null || "".equals(e.getName())) {
return "";
}
return e.getName();
}));
System.out.println(collect);
结果:
4.此外还有:
-
filter 方法用于通过设置的条件过滤出元素
-
forEach Stream提供了新的方法 '' 来迭代流中的每个数据
-
limit 方法用于获取指定数量的流
-
sorted 方法用于对流进行排序
-
distinct 元素去重