在java8之后使⽤stream将list转成map,以及对list中的map分组求和;S。。。
import Arrays;
import List;
import Map;
import Collectors;
import Test;
/**
* Created by Jackielee on 2017
* @author: lizhilong
* @date: 2017-11-24 10:13:57
* @Copyright: 2017 www.aliyun Inc. All rights reserved.
*/
public class DemoListToMap {
List<Student> list = Arrays.asList(new Student(1,18,"阿龙", Code()),
new Student(2,17,"⼩花", Code()),
new Student(3,17,"阿浪", Code()));
@Test
public void listToMapByObjectValue(){
// value 为对象 student -> student jdk1.8返回当前对象
Map<Integer, Student> map = list.stream().Map(Student::getId, student -> student));
// 遍历打印结果
map.forEach((key, value)->{
System.out.println("key: "+ key +" value: "+ value);
});
}
@Test
public void listToMapByNameValue(){
// value 为对象中的属性
Map<Integer, String> map = list.stream().Map(Student::getId, Student::getName));
map.forEach((key, value)->{
System.out.println("key: "+ key +" value: "+ value);
});
}
}
value为对象执⾏结果:
key:1 value: Student [id=1, age=18, name=阿龙, gender=0]
key:2 value: Student [id=2, age=17, name=⼩花, gender=1]
key:3 value: Student [id=3, age=17, name=阿浪, gender=2]
value为字段执⾏结果:
key:1 value:阿龙
key:2 value:⼩花
key:3 value:阿浪
要注意的是map的key必须唯⼀,所以有可能出现不唯⼀的时候,就会报错
@Test
public void listToMapByAgeKey(){
// value 为对象中的属性
Map<Integer, String> map = list.stream().Map(Student::getAge, Student::getName));
}
会有key重复异常
java.lang.IllegalStateException: Duplicate key ⼩花
因为age有相同就会报错此时stream包下Map⽅法有⼀个重载⽅法的参数,这个参数可以传⼀个合并的函数解决冲突
@Test
public void listToMapByAgeKey(){
// value 为对象中的属性
Map<Integer, String> map = list.stream().collect(
map.forEach((key, value)->{
System.out.println("key: "+ key +" value: "+ value);
});
}
执⾏结果:
key:17 value:⼩花
key:18 value:阿龙
对List<Map>分组求和
Map<String,Integer> test =new HashMap(){{
put("id",1);
put("qty",1);
}};
list.add(test);
test =new HashMap(){{
put("id",1);
put("qty",2);
}};
list.add(test);
test =new HashMap(){{
put("id",2);
put("qty",2);
}};
list.add(test);
test =new HashMap(){{
put("id",2);
put("qty",2);
}};
list.add(test);
test =new HashMap(){{
put("id",3);
put("qty",2);
}};
list.add(test);
test =new HashMap(){{
put("id",4);
put("qty",2);
}};
list.add(test);
Map<Object,List<Map>> result = list.stream().upingBy(it -> it.get("id")));
System.out.println(result);
Map tmpResult =new HashMap();
result.forEach((k,v)->{
tmpResult.put(k,v.stream().mapToInt(e ->(int) e.get("qty")).sum());
});
System.out.println(tmpResult);
简化⼀些
理解了上⾯的操作后其实代码还可以简化
这⾥回顾下 list 的声明类型是List<Map<String,Integer>>
在经过 upingBy(it -> it.get("id"))) 之后获得的数据类型是Map<String,List<Map>>
list.stream()
.upingBy(it -> it.get("id")))
.forEach((k,v)->{
tmpResult.put(k,v.stream().mapToInt(e ->(int) e.get("qty")).sum());
});
System.out.println("tmpResult:"+ tmpResult);
中间
list.stream()
.upingBy(it -> it.get("id")))
获得的是⼀个Map但是这个map不是我们的要最终结果,需要的是最后的tmpResult这个map
再进⼀步简化
经过了上⾯2遍的操作后,逐渐加深对stream的理解
其实还可以更加简化
Map result = list.stream()
.upingBy(it -> it.get("id")))
.
entrySet().stream()
.Map(e -> e.getKey(),e -> e.getValue().stream().mapToInt(a ->(int) a.get("qty")).sum(),(key1,key2)->key1));
System.out.println("result:"+ result);
和之前的结果是⼀样的,但是这个更简化⼀步到位
filter过滤
该操作会接受⼀个谓词(⼀个返回boolean的函数)作为参数,并返回⼀个包括所有符合谓词的元素的流
filter中的⽅法返回 boolean类型 即 true/false,当⾥⾯的表达式 = true的时候表明当前元素被过滤掉了,剩下的都是返回false的元素。
list.stream()
.filter(TestObject::isMng)
.List());
distinct去重
distinct返回⼀个元素各异(根据流所⽣成元素的hashCode和equals⽅法实现)的流
List<Integer> numbers = Arrays.asList(1,2,1,3,3,2,4);
numbers.stream()
.filter(i -> i %2==0)
.distinct()
.forEach(System.out::println);
limit直接获取前⼏条记录
流⽀持limit(n)⽅法,该⽅法会返回⼀个不超过给定长度的流
获取前5条
list.stream()
.filter(u-&Sex().equals("M"))
java stream.limit(5).forEach(u->System.out.Name()));
skip跳过元素
流还⽀持skip(n)⽅法,返回⼀个扔掉了前n个元素的流
如果流中元素不⾜n个,则返回⼀个空流。
list.stream()
.filter(u-&Sex().equals("M"))
//传⼊⾃定义⽐较排个序
.sorted(Comparatorparing(TestObject::getName))
.skip(1)
.forEach(u->System.out.Name()));
map将集合中的元素通过⼀个闭包转成其他类型
流⽀持map⽅法,它会接受⼀个函数作为参数。这个函数会被应⽤到每个元素上,并将其映射成⼀个新的元素
list.stream()
.map(TestObject::getName)
.List())
.forEach(System.out::println);
anyMatch检查集合中是否⾄少有⼀个元素满⾜条件
anyMatch返回boolean类型true/false
if(list.stream().anyMatch(u-&Name().equals("Ron"))){
System.out.println("Ron已经到了");
}
allMatch检查集合中的所有元素是否都满⾜条件
allMatch返回boolean类型true/false
if(list.stream().allMatch(u-&Age()>=10)){
System.out.println("很棒,都⼤于10岁");
}else{
System.out.println("原来都还没发育");
}
noneMatch检查集合中的元素是否都不满⾜条件,和allMatch相反
if(list.stream().noneMatch(u-&Age()<10)){
System.out.println("很棒,都⼤于10岁");
}else{
System.out.println("原来都还没发育");
}
findAny返回任意⼀个元素
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论