目录
4.将对象集合的某一属性进行求和,元素属性名不固定,需要通过反射获取得到
4.将对象集合按照某属性分组,再取分组后对象某一属性组成list
5.将对象集合按照元素的某一属性进行分组,并求和某一属性,得到map
6.将对象集合按照元素的某一属性进行分组,并统计个数,得到map
1.将对象的某两个属性(BigDecimal类型)做乘积操作,再求和
2.将对象的某两个属性(Double类型)做乘积操作,再求和
2. 将对象集合按照元素的某一属性进行筛选,再提取某一属性组成新的集合
一、遍历修改集合元素
1. forEach
//stream流的forEach方法遍历修改每个元素的address、type属性
list.stream().forEach(info->{
info.setAddress("kkkk");
info.setType(1);
});
//Iterable<T>接口提供的forEach方法遍历修改每个元素的id属性
list.forEach(info -> info.setId(111l));
//以上两种forEach方法都无返回值,即返回类型为void
2. peek
//遍历集合,修改集合中所有元素的name为xxx
//1)修改失败
list.stream().peek(info -> info.setName("xxx"));
//2)修改成功,peek()方法必须要加上.collect(Collectors.toList())才会生效
list.stream().peek(info -> info.setName("xxx")).collect(Collectors.toList());
//3)有返回值,返回的是list
list = list.stream().peek(info -> info.setName("xxx")).collect(Collectors.toList());
3. forEach和peek的比较
两种方法都可以实现遍历修改元素。但是forEach没有返回值,无法操作结果。如果需要对遍历后的结果再进行操作,就选择使用peek方法:
//遍历修改元素的name属性,再根据age进行升序排序
list.stream().peek(info -> info.setName("xxx")).sorted(Comparator.comparingInt(Student::getAge)).collect(Collectors.toList());
二、提取集合元素值
1.提取集合中对象的某一属性,组成新集合
例子:提取List<Student>集合中Student对象的Num字段值
List<String> numList = studentList.stream().map(tmp ->
tmp.getNum()).collect(Collectors.toList());
2.提取集合中对象的某两个属性,组成map
Map<String,BigDecimal> elecPriceMap =
contractInfoList1.stream().collect(Collectors.toMap(Contract::getId,
Contract::getPrice));
3.提取map的value值,组成一个集合
elecMap.entrySet().stream().map(tmp ->
tmp.getValue()).collect(Collectors.toList());
4.flatMap与map的区别
//flapMap:将结果集合合并到了一个集合
List<Clothes> collect = humanBeingList.stream()
.flatMap(aPerson -> aPerson.getClothesList().stream())
.collect(Collectors.toList());
//map:将结果集合添加到一个集合中,相当于一个二维数组;
List<List<Clothes>> collect1 = humanBeingList.stream()
.map(item -> item.getClothesList())
.collect(Collectors.toList());
//更多例子:map、flatmap操作List<Map>
public List<BigDecimal> getValues(List<Map<Integer, String>> list, Integer key) {
//map方法:
List<Collection<String>> collect = list.stream().map(map -> map.values()).collect(Collectors.toList());
//flatMap方法:
List<String> collect1 = list.stream().flatMap(map -> map.values().stream()).collect(Collectors.toList());
//flatMap方法后,再map()
List<BigDecimal> collect2 = list.stream()
.flatMap(map -> map.values().stream())
.map(v -> ObjectUtil.isNull(v) ? null : new BigDecimal(v)).collect(Collectors.toList());
//faltMap方法后,再filter(),再map()
List<BigDecimal> dataList = list.stream()
.flatMap(map -> map.entrySet().stream())
.filter(entry -> entry.getKey() == key)
.map(Map.Entry::getValue)
.map(data -> {
return data == null ? null : new BigDecimal(data);
})
.collect(Collectors.toList());
return dataList;
}
三、对集合元素求和
1.对List<Double>求和
totalElec += yAxis1.stream().reduce(Double::sum).orElse(0.0);
2.对List<BigDecimal>求和
monthTotalElec = monthYAxis.stream().reduce(BigDecimal.ZERO,BigDecimal::add);
3.将对象集合根据某一属性求和
BigDecimal value=
contract2List.stream().map(Contract::getPrice)
.reduce(BigDecimal.ZERO,BigDecimal::add);
注意:getPrice()值不能为null,否则会报错。
4.将对象集合的某一属性进行求和,元素属性名不固定,需要通过反射获取得到
for(int i = 0; i<xAxis.size();i++)
{int j = i;
Double theHourlElec1 = hourlyDataList1.stream().map(hourlyData -> {
//反射,取集合中各元素的某属性
Double theElec = 0.0;
try {
Field field = hourlyData.getClass().getDeclaredField("h" + j);
field.setAccessible(true);
theElec = (Double) field.get(hourlyData);
} catch (NoSuchFieldException | IllegalAccessException e) {
log.error(e.getMessage());
}
return theElec;
}).collect(Collectors.toList()).stream().reduce(Double::sum).orElse(0.0);
//对属性值求和
}
四、对集合元素进行分组,再统计
1.将对象集合按照某一属性分组,得到一个分组后的map
Map<String, List<HourlyData>> map=
hourlyDataList1.stream().collect(Collectors.groupingBy(HourlyData::getContractId,
Collectors.toList()));
对分组后的map的key做进一步操作
hourlyDataList1.stream().collect(Collectors.groupingBy(HourlyData::getContractId))
.keySet().stream().map(item->item.concat("xxx").collect(Collectors.toList());
2.根据对象集合中元素的某一属性分组,并保证原来的排序
Map<String, List<EquityStructureVo>> groupByNameMap = list.stream().
collect(Collectors.groupingBy(EquityStructureVo::getName,
LinkedHashMap::new,Collectors.toList()));
3.将对象集合按照某多个属性分组,得到一个分组后的map
Map<String, List<Student>> map =
voDataList.stream().collect(Collectors.groupingBy(item -> item.getName() + "-" +
item.getAge(), Collectors.toList()));
4.将对象集合按照某属性分组,再取分组后对象某一属性组成list
//根据学生姓名分组,取出分组后每组学生的年龄list
Map<String,List<Integer>> map=voDataList.stream
.collect(Collectors.groupingBy(item->item.getName(),
Collectors.mapping(Student::getAge,Collectors.toList())));
5.将对象集合按照元素的某一属性进行分组,并求和某一属性,得到map
例子1:根据日期,分组统计电量(统计的属性为double类型);list集合为空时,会返回空map;
Map<String,Double> theMap =
hourlyDataList.stream().collect(Collectors.groupingBy(HourlyData::getDate,
Collectors.summingDouble(HourlyData::getTotalPower)));
例子2: 根据日期,分组统计电量;(统计的属性为BigDecimal类型)
Map<String, BigDecimal> theMap =
quarterDataList.stream().collect(Collectors.groupingBy(QuarterData::getDate,
Collectors.reducing(BigDecimal.ZERO,QuarterData::getTotalPower,BigDecimal::add)));
6.将对象集合按照元素的某一属性进行分组,并统计个数,得到map
描述:根据日期进行分组并统计个数。 虽然map的key和value都可以为null,但是在用getDate来分组时,getDate不能为null,否则会报错。所以在分组之前先要对list做筛选。
Map<String, Long> netWorkLoadCntMap =
networkLoadList.stream().collect(Collectors.groupingBy(NetworkLoad::getDate,
Collectors.counting()));
五、取对象集合的属性做运算
1.将对象的某两个属性(BigDecimal类型)做乘积操作,再求和
BigDecimal contractTotalPrice = contractInfoList.stream().reduce(
BigDecimal.ZERO, (x, y) ->
{
return x.add(y.getTotal().multiply(y.getPrice()));
}, BigDecimal::add);
2.将对象的某两个属性(Double类型)做乘积操作,再求和
orderList.stream().reduce(0.0, (x, y) -> x + (y.getNum() * y.getPrice()),
Double::sum);
六、集合元素去重
1.去重集合元素
List<String> list = Arrays.asList("xxx","vvv","xxx","yyy","zzz","vvv");
List<String> collect = list.stream().distinct().collect(Collectors.toList());
2.筛选出集合中重复的元素
Map<String, Long> collect=
strings.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
collect.forEach((k,v)->{ if(v>1) result.add(k);});
//if(v<=1)则筛选出没有重复的元素
七、判断是否条件匹配
1.allMatch
//判断valueList集合是否每个元素都是null
boolean is = valueList.stream().allMatch(Objects::isNull);
//判断valueList集合是否每个元素的age都大于10
boolean is2 = valueList.stream().allMatch(e->e.getAge()>10);
2.anyMatch
//判断valueList集合是否存在元素为null
boolean is = valueList.stream().anyMatch(Objects::isNull);
//判断valueList集合是否存在元素的age大于10
boolean is2 = valueList.stream().anyMatch(e->e.getAge()>10);
八、条件筛选集合
1.将对象集合按照元素的某一属性进行筛选,得到新的集合
contractInfoList = contractInfoList.stream().filter(contract ->
contract.getName().equals("xx");
).collect(Collectors.toList());
2. 将对象集合按照元素的某一属性进行筛选,再提取某一属性组成新的集合
List<Double>list = netWorkList.stream().filter(tmp ->
theDate.equals(tmp.getDate()))
.map(NetworkLoad::getActualValue).collect(Collectors.toList());
九、查找元素
1.findFirst()
//对list做筛选,查找年龄大于10的第一个元素;如果未找到,则赋值为null;
list.stream().filter(model -> model.getAge() > 1000).findFirst().orElse(null);//null
//对list做筛选,查找年龄大于10的第一个元素;如果未找到,而又调用了get方法,会报错NoSuchElementException: No value presen
list.stream().filter(model -> model.getId() > 1000).findFirst().get();
//对list做筛选,查找年龄大于10的第一个元素,如果找到,则设置名字为lxx;
list.stream().filter(model -> model.getAge() > 10).findFirst().ifPresent(model -> model.setName("lxx"));
2.findAny()
findAny与findFirst用法类似,只是findAny()是获取流中随机的某一个元素;
十、集合元素排序
1.排序List<Object>
List<Object> list = Arrays.asList(3,1,4,11);
list = list.stream().sorted().collect(Collectors.toList());
注意:在调用.sorted()方法之后必须要带上.collect(Collectors.toList())并最终赋值给list,否则结果还是未排序的。
2.将集合逆序
Collections.reverse(dateList);//方式一
eoList.stream().sorted(Comparator.comparing(STPowerForecastEO::getDate,Comparator.reverseOrder())).collect(Collectors.toList());//方式二
3.根据对象集合中元素的某一属性排序
List<StudentInfo> studentsSortName =
studentList.stream().sorted(Comparator.comparing(StudentInfo::getAge))
.collect(Collectors.toList();//正序
List<StudentInfo> studentsSortName =
studentList.stream().sorted(Comparator.comparing(StudentInfo::getAge,Comparator.reverseOrder()))
.collect(Collectors.toList();//逆序
4.根据对象集合中的多个属性排序
eoList = eoList.stream().sorted(Comparator.comparing(STPowerForecastEO::getDate).thenComparing(STPowerForecastEO::getTime,Comparator.reverseOrder())).collect(Collectors.toList()); //先根据date正序排序,再根据time逆序排序
5.根据对象集合中元素的某一对象属性的属性排序
list.stream().sorted(Comparator.comparing(
o -> o.getPerson().getAge())).collect(Collectors.toList());
十一、最大、最小、均值
BigDecimal max = filterList.stream().reduce(BigDecimal::max).get();
BigDecimal min = filterList.stream().reduce(BigDecimal::min).get();
BigDecimal avg = filterList.stream().reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(filterList.size()), 6, BigDecimal.ROUND_HALF_UP);
十二、注意
1.元素存在null值
List<BigDecimal> list=
Arrays.asList(BigDecimal.valueOf(1),null,BigDecimal.valueOf(2));
BigDecimal sum = list.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
reduce(BigDecimal.ZERO,BigDecimal::add)第一个参数是我们给出的初值,第二个参数是累加器。由于在list的元素中存在null值,所以上述代码会报错NullPointerException。在排序时也会存在此问题。因此,在用stream流进行操作时,要先筛选掉null值。
2.调用方法无效
list.stream().map(item->{
Integer n = this.getNum();
return n;
});
在stream流里面写了需要调用getNum()方法,但实际上程序并不会去调用。