5.JDK8中Stream流常用方法操作总结(详细)

目录

一、遍历修改集合元素

1. forEach

2. peek

3. forEach和peek的比较

二、提取集合元素值

1.提取集合中对象的某一属性,组成新集合

2.提取集合中对象的某两个属性,组成map

3.提取map的value值,组成一个集合

4.flatMap与map的区别

三、对集合元素求和

1.对List求和

2.对List求和

3.将对象集合根据某一属性求和

4.将对象集合的某一属性进行求和,元素属性名不固定,需要通过反射获取得到

 四、对集合元素进行分组,再统计

1.将对象集合按照某一属性分组,得到一个分组后的map 

2.根据对象集合中元素的某一属性分组,并保证原来的排序

3.将对象集合按照某多个属性分组,得到一个分组后的map 

4.将对象集合按照某属性分组,再取分组后对象某一属性组成list

5.将对象集合按照元素的某一属性进行分组,并求和某一属性,得到map

6.将对象集合按照元素的某一属性进行分组,并统计个数,得到map

五、取对象集合的属性做运算

1.将对象的某两个属性(BigDecimal类型)做乘积操作,再求和

2.将对象的某两个属性(Double类型)做乘积操作,再求和

六、集合元素去重

1.去重集合元素

2.筛选出集合中重复的元素

 七、判断是否条件匹配

1.allMatch

2.anyMatch

 八、条件筛选集合

1.将对象集合按照元素的某一属性进行筛选,得到新的集合

2. 将对象集合按照元素的某一属性进行筛选,再提取某一属性组成新的集合

九、查找元素

1.findFirst()

2.findAny()

十、集合元素排序

1.排序List

2.将集合逆序

3.根据对象集合中元素的某一属性排序

4.根据对象集合中的多个属性排序

5.根据对象集合中元素的某一对象属性的属性排序

十一、最大、最小、均值

十二、注意

1.元素存在null值

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()方法,但实际上程序并不会去调用。

  • 24
    点赞
  • 170
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值