Arrays.stream(传入数组);// 把数组转成流
Stream.of(传入数组);
==========
flatMap map的区别
假设某个值要拆分成数组, flatMap可以数值转成流, 合并起来
而map则只能返回数组
==================
list对象转map结构
Map map = list.stream().collect(Collectors.toMap(item -> item.getId(), v -> v,(v1,v2)->v1)); // v1表示如果有重复key时, 只保留先存入map的value
或者
Map map = list.stream().collect(Collectors.toMap(item -> item.getId(), Function.identity(),
(k1,k2)-> {
// 自行处理重复key时, 保留/合并value的逻辑,
return k1; }));
java8利用流和lambda表达式对list遍历处理 - Yusco - 博客园
==============
Collectors.mapping()_技匠而已的博客-CSDN博客_collectors.mapping null
Collectors.mapping()
改变输出的结果类型, 如:获取list中对象的name, 逗号连接
方式一:
names=list.stream().collect(Collectors.mapping(Person:getName,Collectors.joining(","));
方式二:
names=list.stream().map(user->user.getName()).collect(Collectors.joining(","));
效果举例: names = "张三,李四,王五";
如果字段是非String字符串类型, 则需要转换一下
把一个List数据, 分组后, 拿到组中所有的对象id
Map<Integer, String> idByAgeMap = list.stream().collect(
Collectors.groupingBy(user::getAge, Collectors.mapping(user::getId, Collectors.joining(","))));
分组后, 把joinng换成max 等函数, 可以取分组最大值
=======
reduce, 初始化值和当前元素计算后的结果, 再与后面的元素计算
=======
peek() // 方便在steam过程中的增加操作, 比如debug数据
=====================
https://www.jb51.net/article/186960.htm
Java中的函数式编程(七)流Stream的Map-Reduce操作 - 安员外 - 博客园
如何运用Java 8的stream将两个集合合并? - 知乎
java8利用流和lambda表达式对list遍历处理 - Yusco - 博客园
java8 Map 的compute的用法 - 正义的五毛 - 博客园
=============
不会Lambda表达式、函数式编程?你确定能看懂公司代码?-java8函数式编程(Lambda表达式,Optional,Stream流)从入门到精通-最通俗易懂_哔哩哔哩_bilibili
创建optional对象
Optional.ofNullable(xxx); // 安全创建, 推荐
Optional.of(xxx);// 传入对象必须 非null
优雅封装null返回值, 使用 Optional.empty();
xxOpt.ifPresent( lambda表达式 );// 安全消费, 推荐
get()可能会出现null指针的情况
xxOpt.orElseGet( lambda表达式); // 为null时, 使用lambda表达式创建默认值
orElseThrow(略);// 抛出异常的方式
也有filter, map等方法进行过滤, 数据转换
=============
java8 Map 的compute的用法 - 正义的五毛 - 博客园
compute:
格式: map.compute(key, (k, oldValue) -> { 函数逻辑...略 return newValue; })
根据函数返回的新value, 保存k,v映射, 返回null值时会删除key
get(key)是否为null, 都不重要(仅用于remove时的判断)
computeIfAbsent:
格式: map.computeIfAbsent(key, k -> new Value(f(k)));
如果get(key)没值, 根据函数返回的v, 保存k,v映射
如果get(key)有值, 则跳过
computeIfPresent: 用于覆盖操作
格式: map.computeIfPresent("a", (k,oldValue)->{ 函数逻辑...略 return newValue; });
与computeIfAbsent相反
如果get(key)没值, 则跳过
如果get(key)有值才进行操作, 函数传入了 key+旧的value,
函数必须要有返回值, 返回null值时会删除key
getOrDefault:
如果get(key)为null时, 返回指定的默认值(不会保存k,v映射关系)
putIfAbsent:
格式: map.putIfAbsent(k, v)
如果get(key)为null时, put入参中的k,v映射, 并返回 null
如果get(key)不为null时, 返回oldValue
computeIfAbsent 与 putIfAbsent的不同: 前者v支持函数来构造, 后者必须是对象
===案例
value是集合场景, Map<String, List<Integer>>
需要在, get(key)为null时, new 一个 list; 然后再调用该list.add()方法, 添加元素
常规写法:
List<Integer> list = map.get(k);
if(list == null){
list = new ArrayList<>();
}
list.add(id);
map.put(k, list);
方案一: add逻辑放在 函数里操作
map.compute(k, (k1,v)->{
if (v == null) {
v = new ArrayList<>();
}
v.add(id);
return v;
});
方案二:
map.computeIfAbsent(k,v-> new ArrayList<>());
map.computeIfPresent(k, (k1,v)-> {
v.add(id);
return v;
});
方案三:
map.computeIfAbsent(k, v -> new ArrayList<>());
map.get(k).add(id);
方案三(2): List list = map.getOrDefault(k, new ArrayList<>());
map.put(k, list);