天天看點

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流還有很多其他的用法有待學習,用的熟練了,确實可以提升不少效率,并且對于一些疑難的問題它都可以很好的解決。