一、Lambda表达式
1、Lambda表达式对接口的要求
Lambda表达式本质上来讲就是是一个匿名内部类,因此使用Lambda表达式实现的接口中,必须有且只有一个方法是实现类必须实现的
lambda没有方法的名字,在我们使用Lambda表达式的时候我们只需要关注参数和方法体
2、lambda语法:Lmabda表达式的语法总结: () -> ();
前置 | 语法 |
---|---|
无参数无返回值 | () -> System.out.println(“Hello WOrld”) |
有一个参数无返回值 | (x) -> System.out.println(x) |
有且只有一个参数无返回值 | x -> System.out.println(x) |
有多个参数,有返回值,有多条lambda体语句 | (x,y) -> {System.out.println(“xxx”);return xxxx;}; |
有多个参数,有返回值,只有一条lambda体语句 | (x,y) -> xxxx |
二、Stream API
jdk8中的Stream是对集合(Collection)对象功能的增强。它专注于对集合对象进行各种非常遍历、高效的集合操作,或者大批量数据操作
1、过滤操作(filter)
在我的日常开发中,主要是对集合进行过滤,挑选自己需要的数据;
例如我们需要将list里面status等于30的数据提取出来
List list=new ArrayList<>();
…
List result=list.sream().filter(t->t.getStatus.equals(“30”)) .collect(Collectors.toList());
2、迭代操作(forEach)
这个操作就是等价于我们的常用的for(T t:list){}和if(i=0;i<list.size();i++){}
3、去除重复元素(distinct)
4、匹配操作(anyMatch、allMatch、noneMatch)
anyMatch、allMatch、noneMatch都是用来判断某一种规则是否和刘对象相互吻合的。所有的匹配类型都是中介操作,只返回一个boolean值
anyMatch:用于判断集合中是否有任意元素满足条件
allMatch:用于判断集合中是否所有元素满足条件
noneMatch:用于判断集合中欧冠是否所有元素不满足条件
5、limit和skip
limit:用于返回前面n个元素
skip:用于舍弃前面n和元素
5、sorted
sorted方法用于对流进行排序。sorted是一个中间操作,能够返回一个排过序的流对象。流对象中的元素会按照自然顺序进行排序,除非你自指定一个Comparator接口来改变排序规则
6、map
map:接收一个方法作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
三、HahMap的变化
四、java8中的Collectors.groupingBy用法
Collectors.groupingBy根据一个或多个属性对集合中的项目进行分组
数据准备:
1、按照类目分组:
Map<String, List<Product>> prodMap= prodList.stream().collect(Collectors.groupingBy(Product::getCategory));
//{"啤酒":[{"category":"啤酒","id":4,"name":"青岛啤酒","num":3,"price":10},{"category":"啤酒","id":5,"name":"百威啤酒","num":10,"price":15}],"零食":[{"category":"零食","id":1,"name":"面包","num":1,"price":15.5},{"category":"零食","id":2,"name":"饼干","num":2,"price":20},{"category":"零食","id":3,"name":"月饼","num":3,"price":30}]}
2、按照几个属性拼接分组:
Map<String, List<Product>> prodMap = prodList.stream().collect(Collectors.groupingBy(item -> item.getCategory() + "_" + item.getName()));
//{"零食_月饼":[{"category":"零食","id":3,"name":"月饼","num":3,"price":30}],"零食_面包":[{"category":"零食","id":1,"name":"面包","num":1,"price":15.5}],"啤酒_百威啤酒":[{"category":"啤酒","id":5,"name":"百威啤酒","num":10,"price":15}],"啤酒_青岛啤酒":[{"category":"啤酒","id":4,"name":"青岛啤酒","num":3,"price":10}],"零食_饼干":[{"category":"零食","id":2,"name":"饼干","num":2,"price":20}]}
五、Collectors.toMap()问题
1、出现重复的key会报错
Collectors.toMap(HomePageDoctorDO::getId, y -> y,(oldValue,newValue)->newValue)
2、导致集合乱序
Collectors.toMap(HomePageDoctorDO::getId, y -> y,(oldValue,newValue)->newValue, LinkedHashMap::new)
3、toMap()三个重载方法
toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper);
toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction);
toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier);
对应实现
public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
}
public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction) {
return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
}
public static <T, K, U, M extends Map<K, U>>
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction,
Supplier<M> mapSupplier) {
BiConsumer<M, T> accumulator
= (map, element) -> map.merge(keyMapper.apply(element),
valueMapper.apply(element), mergeFunction);
return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
}
参数含义分别是:
-
keyMapper:Key 的映射函数
-
valueMapper:Value 的映射函数
-
mergeFunction:当 Key 冲突时,调用的合并方法
-
mapSupplier:Map 构造器,在需要返回特定的 Map 时使用
乱序原因:
由源码可知toMap()底层默认是使用HashMap集合的,而HashMap存储数据是无序的