stream集合操作符笔记

前言

用了这么久的jdk8 的stream集合 感觉还是很吊的 特别是作统计计算、集合转化之类的操作

虽然有parallelStream 来进行并行计算 但是 不推荐这么去使用 原因如下 虽然有并行 但是 parallelStream 的并行数量是按照jvm的核心数量去启动的 这个时候就有点蛋疼了 如果真的需要并行 还是建议使用 threadPool去执行 而不是简单的使用 parallelStream parallelStream 只是把任务并行了 但是该有的竞争状态 还是有 就是说和你使用线程池是差不多的也是要考虑竞争状态的问题

常用操作符列表

名称表达式作用备注
filtert->boolean过滤数 据
mapt->r处理数据为每一个数据作map中的操作
flatMapt->r.stream()处理数据并且扁平化为每个数据进行处理 并且会返回一个Stream 处理List> 这种数据的时候可以通过此操作扁平化内部的那个list
distinct-去重并且返回一个新的stream进行数据去重的时候使用 必须是有限的stream
sorted-排序并且返回一个新的stream进行stream排序使用 但是这个必须要是有限的stream
peekt->void预览、执行某个不返回的操作 每次返回新的stream 避免消耗stream做一些void的操作使用
limit-截断数据截断前x个数据 返回新的stream
skip-跳过数据跳过前x个数据 返回新的stream
forEacht->void迭代数据内部迭代 每啥好说的
reduce(identity,(x,y)->result)、((x,y)->result)计数器做一些复杂的综合统计适合
collect(void->t,r->void,r->void)、(collector)收集结果将结果收集返回给其他对象
min(o1,o2)->o1 or o2获取最小的元素必须是有限的元素
max(o1,o2)->o1 or o2获取最大的元素必须是有限的元素
count-统计数量统计数量
anyMatcht->boolean匹配只要有一个匹配就返回true
allMatcht->boolean匹配必须所有元素匹配才返回true
noneMatcht->boolean匹配必须所有元素不匹配返回true
findFirst-获取第一个元素获取到第一个元素马上返回
findAny-获取返回的元素

案例

package com.ming;

import org.junit.Test;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 测试 stream 用法
 *
 * @author ming
 * @date 2018-06-26 15:45:08
 */
public class TestStream {


    /**
     * 将List<T1>  转换成 Map<id,T1>
     *
     * @author ming
     * @date 2018-06-26 15:54:54
     */
    @Test
    public void listToMap() {
        List<T1> list = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            list.add(new T1("id" + i, "name" + i));
        }
        //转换成 id 为key  T1为value的map
        Map<String, T1> map = list.stream().collect(Collectors.toMap(T1::getId, t -> t));
        System.out.println(map);
        //当出现重复值 按照 (oV, nV) -> nV 来选择新的value
        Map<String, T1> map1 = list.stream().collect(Collectors.toMap(T1::getId, t -> t, (oV, nV) -> nV));
        System.out.println(map1);
    }


    /**
     * 获取List<T2> 中的t1的list的合集
     *
     * @author ming
     * @date 2018-06-26 16:02:35
     */
    @Test
    public void ListToFlatList() {
        List<T2> list = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            List<T1> t1List = new ArrayList<>();
            for (int j = 0; j < 3; j++) {
                t1List.add(new T1("id" + i, "name" + i));
            }
            list.add(new T2("id" + i, "name" + i, t1List));
        }
        List<T1> resultList = list.stream().flatMap(f -> f.getT1List().stream()).collect(Collectors.toList());
        System.out.println(resultList);
    }

    /**
     * 将 List<T3>中的num进行累加计数
     *
     * @author ming
     * @date 2018-06-26 16:06:24
     */
    @Test
    public void numReduce() {
        List<T3> list = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            list.add(new T3("id" + i, i));
        }
        Integer countNum = list.stream().map(T3::getNum).reduce(0, (sum, item) -> sum + item);
        System.out.println(countNum);
        Integer countNum1 = list.stream().map(T3::getNum).reduce(0, Integer::sum);
        System.out.println(countNum1);
    }


    /**
     * 将List<T4>按照id 分组并且 累加price
     * 分两种方案
     * 一是先分组 然后map->reduce
     * 二直接分组 进行reduce 取巧进行对象的累加
     *
     * @author ming
     * @date 2018-07-05 09:58:01
     */
    @Test
    public void testGroupByAndReduce() {
        List<T4> list = new ArrayList<>();
        list.add(new T4(1, BigDecimal.valueOf(1)));
        list.add(new T4(1, BigDecimal.valueOf(10)));
        list.add(new T4(2, BigDecimal.valueOf(1)));
        list.add(new T4(2, BigDecimal.valueOf(10)));
/*

        //方案一 先分组 然后迭代处理
        Map<Integer, BigDecimal> result = new HashMap<>();
        list.stream().collect(Collectors.groupingBy(T4::getId, Collectors.toSet()))
                .forEach((k, v) -> {
                    result.put(k, v.stream().map(T4::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add));
                });
        System.out.println(result);
*/

/*

        //方案二 使用取巧的方案 进行对象累加  这样 分组id不变 而且内部的属性也可以按照自己的定义去计算
        Map<Integer, T4> result = list.stream()
                .collect(Collectors.groupingBy(T4::getId
                        , Collectors.reducing(new T4(1, BigDecimal.ZERO), (o, item) -> new T4(o.getId(), o.getPrice().add(item.getPrice())))));
        System.out.println(result);
*/
    }

}

class T1 {
    private String id;
    private String name;


    public T1() {
    }

    public T1(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

class T2 {
    private String id;
    private String name;
    private List<T1> t1List;

    public T2() {
    }

    public T2(String id, String name, List<T1> t1List) {
        this.id = id;
        this.name = name;
        this.t1List = t1List;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<T1> getT1List() {
        return t1List;
    }

    public void setT1List(List<T1> t1List) {
        this.t1List = t1List;
    }
}

class T3 {
    private String id;
    private Integer num;


    public T3() {
    }

    public T3(String id, Integer num) {
        this.id = id;
        this.num = num;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Integer getNum() {
        return num;
    }

    public void setNum(Integer num) {
        this.num = num;
    }
}


class T4 {
    private Integer id;
    private BigDecimal price;

    public T4() {
    }

    public T4(Integer id, BigDecimal price) {
        this.id = id;
        this.price = price;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "T4{" +
                "id=" + id +
                ", price=" + price +
                '}';
    }
}

总结

jdk8 出了很多实用的功能 这个stream只是其中之一 算是常用的 在大多数 集合转换、数据计算类型的操作中 用stream 操作会节省很多代码 而且看起来容易理解 并且性能还稍高一点

© 2024 ming博客. All rights reserved.基于rust salvo性能猛的很!