天天看点

stream流的使用-获取list集合中对象的单个字段list集合,进行累加操作Stream流的使用

Stream流的使用

场景及代码案例源于实际项目

1. 需求描述

现存一list集合,其中保存了投资人的信息。

Person (name, age, money rateOfReturn)

其中的money表示投资人现有资产,rateOfReturn表示投资年回报率

需求:

1.计算投资人年龄之和;

2.根据现有资产及投资回报率,计算所有投资人一年后的资产总和;

2. 代码

实体类

package com.drc.java8.stream.practice.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.math.BigDecimal;

/**
 * @author dairuichuang
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
    private String name;
    private Integer age;
    private BigDecimal money;
    private BigDecimal rateOfReturn;
}
           

主程序

package com.drc.java8.stream.practice;

import com.drc.java8.stream.practice.domain.Person2;
import org.junit.Test;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class ListPersonPractice {
	// 投资人集合
    List<Person> PersonList = new ArrayList<>();
    // 初始化投资人
    {
        PersonList.add(new Person2("张三", 11, BigDecimal.valueOf(10000), BigDecimal.valueOf(0.08)));
        PersonList.add(new Person2("李四", 21, BigDecimal.valueOf(20000), BigDecimal.valueOf(0.18)));
        PersonList.add(new Person2("王五", 31, BigDecimal.valueOf(30000), BigDecimal.valueOf(0.28)));
        PersonList.add(new Person2("赵四", 41, BigDecimal.valueOf(40000), BigDecimal.valueOf(0.38)));
    }
    /**
    *  计算
    */
    @Test
    public void testCalcAgeAndMoney() {
        // 计算年龄之和
        Integer ages = PersonList.stream().map(Person::getAge).reduce((a, b) -> (a + b)).get();
        System.out.println(ages);
        
        // money是资产,rateOfReturn 是资产年收益率,计算一年后几人的资产总额
        BigDecimal assetsAmt = PersonList.stream().map(person ->
                person.getMoney().multiply(person.getRateOfReturn().add(BigDecimal.ONE))).reduce(BigDecimal::add).get();
        System.out.println(assetsAmt);
    }
}
           

3. 涉及方法

stream()

/*
* 返回以此集合为源的顺序流。
* 当spliterator()方法不能返回IMMUTABLE、CONCURRENT或后期绑定的分裂器时,应该重写此方法。(详见spliterator())
*/
default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }
           

stream是Collection的一个默认方法,它的作用是返回集合的stream流

用法:

List<String> list = new ArrayList<>();
Stream<String> stream = list.stream();
           

map(Function<? super T, ? extends R> mapper)

// 返回一个流,由将给定函数应用于此流的元素的结果组成。
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
           

Stream的方法,作用是返回一个流,里面的数据使我们定义的,比如:

其中

Person::getAge

定义的就是“年龄”,map方法会为我们返回一个仅包含“年龄”的stream

我们可以接着调用collect方法,获取到一个list集合。

reduce

// 使用关联累加函数对此流的元素执行缩减,并返回描述缩减值(如果有的话)的Optional。
Optional<T> reduce(BinaryOperator<T> accumulator);
           

其中的参数表示对两个相同类型的操作数的操作,产生与操作数相同类型的结果。这是BiFunction的专门化,用于操作数和结果都是同一类型的情况。其中的参数:

@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T,T,T>
           

简单来说,reduce方法就是将stream流中的多个元素缩减为一个我们想要的结果。缩减的规则,就是我们传入的表达式 ,比如

(a,b) -> (a + b)

表示将流中的元素进行累加操作,并返回包含累加结果的Option,而

get()

方法,则是获取Option中的累加结果。

通过一系列的操作,便获得了集合中投资人年龄之和。Stream流还有很多其他的用法有待学习,用的熟练了,确实可以提升不少效率,并且对于一些疑难的问题它都可以很好的解决。