Fork me on Gitee

JDK 1.8新特性 Stream流

一、Stream流介绍

从支持数据处理操作生成的元素序列

​ -----《Java 8 实战》

流的特点在于支持函数式编程、提供管道运算能力、提供并行计算能力及提供大量的操作。

二、Stream流的操作步骤

  1. 创建Stream流 从一个数据源,如集合、数组中获取流。
  2. 中间操作 一个操作的中间链,对数据源的数据进行操作
  3. 终止操作 一个终止操作,执行中间操作链,并产生结果。

image-20230310115315704

三、获得Stream流

获取一个流非常简单,有以下几种常见的方式:

  • 通过Collection对象的stream()或者parallelStream()
List<Integer> list = Lists.newArrayList();
//串行 单线程
list.stream();
//并行 多线程
list.parallelStream();
  • Stream接口的静态方法of可以获取数组对应的流。
Stream.of(1, 2, 3, 4, 5, 6);
  • Arrays的静态方法stream也可以获取流
int[] numbers = {1, 2, 3, 4, 5};

IntStream stream = Arrays.stream(numbers);
stream.forEach(System.out::println);
  • 通过文件流获取

四、Stream常见操作

Sku对象

@Getter
@AllArgsConstructor
public class Sku {
    /**
     * sku编号
     */
    private Integer skuId;

    /**
     * 商品名称
     */
    private String skuName;
    /**
     * 商品价格(仅测试使用Double类型)
     */
    private Double skuPrice;

    /**
     * 购买个数
     */
    private Integer totalNum;

    /**
     * 总价
     */
    private Double totalPrice;

    /**
     * 商品分类
     */
    private Enum skuCategory;
    
}

CartService,购物车服务类,用于将选购的sku放入购物车。

public class CartService {
    // 加入到购物车中的商品信息
    private static List<Sku> cartSkuList =
            new ArrayList<Sku>(){
                {
                    add(new Sku(654032, "无人机",
                            4999.00, 1,
                            4999.00, SkuCategoryEnum.ELECTRONICS));

                    add(new Sku(642934, "VR一体机",
                            2299.00, 1,
                            2299.00, SkuCategoryEnum.ELECTRONICS));

                    add(new Sku(645321, "纯色衬衫",
                            409.00, 3,
                            1227.00, SkuCategoryEnum.CLOTHING));

                    add(new Sku(654327, "牛仔裤",
                            528.00, 1,
                            528.00, SkuCategoryEnum.CLOTHING));

                    add(new Sku(675489, "跑步机",
                            2699.00, 1,
                            2699.00, SkuCategoryEnum.SPORTS));

                    add(new Sku(644564, "Java编程思想",
                            79.80, 1,
                            79.80, SkuCategoryEnum.BOOKS));

                    add(new Sku(678678, "Java核心技术",
                            149.00, 1,
                            149.00, SkuCategoryEnum.BOOKS));

                    add(new Sku(697894, "算法",
                            78.20, 1,
                            78.20, SkuCategoryEnum.BOOKS));

                    add(new Sku(696968, "TensorFlow进阶指南",
                            85.10, 1,
                            85.10, SkuCategoryEnum.BOOKS));
                }
            };

    /**
     * 获取商品信息列表
     * @return
     */
    public static List<Sku> getCartSkuList() {
        return cartSkuList;
    }
}

商品分类Enum类型

public enum SkuCategoryEnum {
    CLOTHING(10, "服装类"),
    ELECTRONICS(20, "数码类"),
    SPORTS(30, "运动类"),
    BOOKS(40, "图书类");

    // 商品类型的编号
    private Integer code;
    // 商品类型的名称
    private String name;

    /**
     * 构造函数
     * @param code
     * @param name
     */
    SkuCategoryEnum(Integer code, String name) {
        this.code = code;
        this.name = name;
    }
}

采用JUnit4进行单元测试,所有单元测试方法前执行初始化方法

List<Sku> list;
@Before
public void init(){
  list = CartService.getCartSkuList();

}

4.1 filter

过滤掉不符合断言判断的数据记录

list.stream().filter(sku -> SkuCategoryEnum.BOOKS.equals(sku.getSkuCategory())).forEach(
                item ->{
                    System.out.println(JSON.toJSONString(item,true));
                }
);

{
	"skuCategory":"BOOKS",
	"skuId":644564,
	"skuName":"Java编程思想",
	"skuPrice":79.8,
	"totalNum":1,
	"totalPrice":79.8
}
{
	"skuCategory":"BOOKS",
	"skuId":678678,
	"skuName":"Java核心技术",
	"skuPrice":149.0,
	"totalNum":1,
	"totalPrice":149.0
}
{
	"skuCategory":"BOOKS",
	"skuId":697894,
	"skuName":"算法",
	"skuPrice":78.2,
	"totalNum":1,
	"totalPrice":78.2
}
{
	"skuCategory":"BOOKS",
	"skuId":696968,
	"skuName":"TensorFlow进阶指南",
	"skuPrice":85.1,
	"totalNum":1,
	"totalPrice":85.1
}

4.2 map

将一个元素转换为另一个元素

list.stream().map(sku -> sku.getSkuName()).forEach(
                item -> System.out.println(JSON.toJSONString(item,true))
"无人机"
"VR一体机"
"纯色衬衫"
"牛仔裤"
"跑步机"
"Java编程思想"
"Java核心技术"
"算法"
"TensorFlow进阶指南"

4.3 flatMap

将一个流转换为另一个流

list.stream()
                .flatMap(sku-> Arrays.stream(sku.getSkuName().split(""))).forEach(
                item -> System.out.println(JSON.toJSONString(item,true))
        );
"无"
"人"
"机"
"V"
"R"
"一"
"体"
"机"
"纯"
"色"
"衬"
"衫"
"牛"
"仔"
"裤"
"跑"
"步"
"机"
"J"
"a"
"v"
"a"
"编"
"程"
"思"
"想"
"J"
"a"
"v"
"a"
"核"
"心"
"技"
"术"
"算"
"法"
"T"
"e"
"n"
"s"
"o"
"r"
"F"
"l"
"o"
"w"
"进"
"阶"
"指"
"南"

4.4 peek

对流中的元素进行遍历,但不会销毁对象

list.stream().peek(sku -> System.out.println(sku.getSkuName())).forEach(
                item -> System.out.println(JSON.toJSONString(item,true))
        );
无人机
{
	"skuCategory":"ELECTRONICS",
	"skuId":654032,
	"skuName":"无人机",
	"skuPrice":4999.0,
	"totalNum":1,
	"totalPrice":4999.0
}
VR一体机
{
	"skuCategory":"ELECTRONICS",
	"skuId":642934,
	"skuName":"VR一体机",
	"skuPrice":2299.0,
	"totalNum":1,
	"totalPrice":2299.0
}
纯色衬衫
{
	"skuCategory":"CLOTHING",
	"skuId":645321,
	"skuName":"纯色衬衫",
	"skuPrice":409.0,
	"totalNum":3,
	"totalPrice":1227.0
}
牛仔裤
{
	"skuCategory":"CLOTHING",
	"skuId":654327,
	"skuName":"牛仔裤",
	"skuPrice":528.0,
	"totalNum":1,
	"totalPrice":528.0
}
跑步机
{
	"skuCategory":"SPORTS",
	"skuId":675489,
	"skuName":"跑步机",
	"skuPrice":2699.0,
	"totalNum":1,
	"totalPrice":2699.0
}
Java编程思想
{
	"skuCategory":"BOOKS",
	"skuId":644564,
	"skuName":"Java编程思想",
	"skuPrice":79.8,
	"totalNum":1,
	"totalPrice":79.8
}
Java核心技术
{
	"skuCategory":"BOOKS",
	"skuId":678678,
	"skuName":"Java核心技术",
	"skuPrice":149.0,
	"totalNum":1,
	"totalPrice":149.0
}
算法
{
	"skuCategory":"BOOKS",
	"skuId":697894,
	"skuName":"算法",
	"skuPrice":78.2,
	"totalNum":1,
	"totalPrice":78.2
}
TensorFlow进阶指南
{
	"skuCategory":"BOOKS",
	"skuId":696968,
	"skuName":"TensorFlow进阶指南",
	"skuPrice":85.1,
	"totalNum":1,
	"totalPrice":85.1
}

4.5 sort

对流中元素进行排序,可以选择自然排序或者指定排序规则

list.stream().sorted(Comparator.comparing(Sku::getTotalPrice)).forEach(
                item -> System.out.println(JSON.toJSONString(item,true))
        );
{
	"skuCategory":"BOOKS",
	"skuId":697894,
	"skuName":"算法",
	"skuPrice":78.2,
	"totalNum":1,
	"totalPrice":78.2
}
{
	"skuCategory":"BOOKS",
	"skuId":644564,
	"skuName":"Java编程思想",
	"skuPrice":79.8,
	"totalNum":1,
	"totalPrice":79.8
}
{
	"skuCategory":"BOOKS",
	"skuId":696968,
	"skuName":"TensorFlow进阶指南",
	"skuPrice":85.1,
	"totalNum":1,
	"totalPrice":85.1
}
{
	"skuCategory":"BOOKS",
	"skuId":678678,
	"skuName":"Java核心技术",
	"skuPrice":149.0,
	"totalNum":1,
	"totalPrice":149.0
}
{
	"skuCategory":"CLOTHING",
	"skuId":654327,
	"skuName":"牛仔裤",
	"skuPrice":528.0,
	"totalNum":1,
	"totalPrice":528.0
}
{
	"skuCategory":"CLOTHING",
	"skuId":645321,
	"skuName":"纯色衬衫",
	"skuPrice":409.0,
	"totalNum":3,
	"totalPrice":1227.0
}
{
	"skuCategory":"ELECTRONICS",
	"skuId":642934,
	"skuName":"VR一体机",
	"skuPrice":2299.0,
	"totalNum":1,
	"totalPrice":2299.0
}
{
	"skuCategory":"SPORTS",
	"skuId":675489,
	"skuName":"跑步机",
	"skuPrice":2699.0,
	"totalNum":1,
	"totalPrice":2699.0
}
{
	"skuCategory":"ELECTRONICS",
	"skuId":654032,
	"skuName":"无人机",
	"skuPrice":4999.0,
	"totalNum":1,
	"totalPrice":4999.0
}

4.6 distinct

对流中元素进行去重

//对类别进行去重
        list.stream().map(Sku::getSkuCategory).distinct().forEach(
                item -> System.out.println(JSON.toJSONString(item,true))
        );
"ELECTRONICS"
"CLOTHING"
"SPORTS"
"BOOKS"

4.7 skip

跳过前N条记录

# 总价格按照从低到高排序,并跳过前3个
list.stream().sorted(Comparator.comparing(Sku::getTotalPrice))
                .skip(3)
                .forEach(
                        item -> System.out.println(JSON.toJSONString(item,true))
                );
{
	"skuCategory":"BOOKS",
	"skuId":678678,
	"skuName":"Java核心技术",
	"skuPrice":149.0,
	"totalNum":1,
	"totalPrice":149.0
}
{
	"skuCategory":"CLOTHING",
	"skuId":654327,
	"skuName":"牛仔裤",
	"skuPrice":528.0,
	"totalNum":1,
	"totalPrice":528.0
}
{
	"skuCategory":"CLOTHING",
	"skuId":645321,
	"skuName":"纯色衬衫",
	"skuPrice":409.0,
	"totalNum":3,
	"totalPrice":1227.0
}
{
	"skuCategory":"ELECTRONICS",
	"skuId":642934,
	"skuName":"VR一体机",
	"skuPrice":2299.0,
	"totalNum":1,
	"totalPrice":2299.0
}
{
	"skuCategory":"SPORTS",
	"skuId":675489,
	"skuName":"跑步机",
	"skuPrice":2699.0,
	"totalNum":1,
	"totalPrice":2699.0
}
{
	"skuCategory":"ELECTRONICS",
	"skuId":654032,
	"skuName":"无人机",
	"skuPrice":4999.0,
	"totalNum":1,
	"totalPrice":4999.0
}

4.8 limit

截断前n条记录

list.stream().sorted(Comparator.comparing(Sku::getTotalPrice))
                .limit(5)
                .forEach(
                        item -> System.out.println(JSON.toJSONString(item,true))
                );
{
	"skuCategory":"BOOKS",
	"skuId":697894,
	"skuName":"算法",
	"skuPrice":78.2,
	"totalNum":1,
	"totalPrice":78.2
}
{
	"skuCategory":"BOOKS",
	"skuId":644564,
	"skuName":"Java编程思想",
	"skuPrice":79.8,
	"totalNum":1,
	"totalPrice":79.8
}
{
	"skuCategory":"BOOKS",
	"skuId":696968,
	"skuName":"TensorFlow进阶指南",
	"skuPrice":85.1,
	"totalNum":1,
	"totalPrice":85.1
}
{
	"skuCategory":"BOOKS",
	"skuId":678678,
	"skuName":"Java核心技术",
	"skuPrice":149.0,
	"totalNum":1,
	"totalPrice":149.0
}
{
	"skuCategory":"CLOTHING",
	"skuId":654327,
	"skuName":"牛仔裤",
	"skuPrice":528.0,
	"totalNum":1,
	"totalPrice":528.0
}

4.9AllMatch/anyMatch/noneMatch

  • AllMatch:所有元素匹配,返回true

  • anyMatch:任何元素匹配,返回true

  • noneMatch:任何元素都不匹配,返回true

/**
  * allMatch使用: 操作,短路操作。所有元素匹配,返回true
  */
@Test
public void allMatchTest(){
  boolean match = list.stream()
    .allMatch(sku -> sku.getTotalPrice()>100);
  System.out.println(match);
}

/**
     * anyMatch使用:任何元素匹配,返回true
     */
@Test
public void anyMatchTest(){
  boolean match = list.stream()
    .anyMatch(sku -> sku.getTotalPrice()>100);
  System.out.println(match);
}

/**
     * noneMatch使用:任何元素都不匹配,返回true
     */
@Test
public void testNoneMatch(){
  boolean match = list.stream()
    .noneMatch(sku -> sku.getTotalPrice()<0);
  System.out.println(match);
}

4.10 findFirst/findAny

  • findFirst:找到第一个
  • findAny:找到任意一个
 /**
   * 找到第一个
   */
@Test
public void findFirstTest(){
  Optional<Sku> optional = list.stream()
    .peek(sku -> System.out.println(sku.getSkuName()))
    .findFirst();
  System.out.println(JSON.toJSONString(optional.get(),true));
}

/**
  * 找到任意一个
  */
@Test
public void findAnyTest(){
  Optional<Sku> optional = list.stream()
    .peek(sku -> System.out.println(sku.getSkuName()))
    .findAny();
  System.out.println(JSON.toJSONString(optional.get(),true));
}

4.11 min/max/count

  • min: 找出最小的项
  • max:找出最大的项
  • count:统计总数
@Test
public void maxTest(){
  OptionalDouble optionalDouble = list.stream()
    // 获取总价
    .mapToDouble(Sku::getTotalPrice)

    .max();

  System.out.println(optionalDouble.getAsDouble());
}

@Test
public void minTest(){
  OptionalDouble optionalDouble = list.stream()
    // 获取总价
    .mapToDouble(Sku::getTotalPrice)

    .min();

  System.out.println(optionalDouble.getAsDouble());
}

/**
 * count
 */
@Test
public void countTest(){
  long count = list.stream().count();
  System.out.println(count);
}

5.流的收集

5.1 toList

将处理后的结果收集为list

// 收集总价格超过100的Sku
List<Sku> cartSkuList = CartService.getCartSkuList();
List<Sku> result = cartSkuList
  .stream()
  .filter(sku -> sku.getTotalPrice() > 100)
  .collect(Collectors.toList());
System.out.println(JSON.toJSONString(result,true));

输出结果

[
	{
		"skuCategory":"ELECTRONICS",
		"skuId":654032,
		"skuName":"无人机",
		"skuPrice":4999.0,
		"totalNum":1,
		"totalPrice":4999.0
	},
	{
		"skuCategory":{"$ref":"$[0].skuCategory"},
		"skuId":642934,
		"skuName":"VR一体机",
		"skuPrice":2299.0,
		"totalNum":1,
		"totalPrice":2299.0
	},
	{
		"skuCategory":"CLOTHING",
		"skuId":645321,
		"skuName":"纯色衬衫",
		"skuPrice":409.0,
		"totalNum":3,
		"totalPrice":1227.0
	},
	{
		"skuCategory":{"$ref":"$[0][2].skuCategory"},
		"skuId":654327,
		"skuName":"牛仔裤",
		"skuPrice":528.0,
		"totalNum":1,
		"totalPrice":528.0
	},
	{
		"skuCategory":"SPORTS",
		"skuId":675489,
		"skuName":"跑步机",
		"skuPrice":2699.0,
		"totalNum":1,
		"totalPrice":2699.0
	},
	{
		"skuCategory":"BOOKS",
		"skuId":678678,
		"skuName":"Java核心技术",
		"skuPrice":149.0,
		"totalNum":1,
		"totalPrice":149.0
	}
]

5.3 toMap

@Test
public void testMapTest(){
  List<Sku> cartSkuList = CartService.getCartSkuList();
  //如果两个id重复,两个value可以映射到同一个id,如 678678重复
  Map<Integer, String> map = cartSkuList.stream().collect(Collectors.toMap(Sku::getSkuId, Sku::getSkuName,
                                                                           (e1, e2) -> e1 + "," + e2));
  System.out.println(map.get(678678));
  System.out.println(JSON.toJSONString(map,true));
}
Java核心技术
{
	645321:"纯色衬衫",
	696968:"TensorFlow进阶指南",
	654032:"无人机",
	675489:"跑步机",
	697878:"算法",
	678678:"Java核心技术",
	644564:"Java编程思想",
	654327:"牛仔裤",
	642934:"VR一体机"
}

详细关于toMap方法可参考博客https://blog.csdn.net/goldfishsky/article/details/126260153

5.3 groupBy

按照指定条件进行分组

 @Test
public void groupTest(){
  List<Sku> cartSkuList = CartService.getCartSkuList();
  Map<Enum, List<Sku>> group = cartSkuList
    .stream()
    .collect(Collectors.groupingBy(sku -> sku.getSkuCategory()));
  System.out.println(JSON.toJSONString(group,true));
}
{
	"SPORTS":[
		{
			"skuCategory":"SPORTS",
			"skuId":675489,
			"skuName":"跑步机",
			"skuPrice":2699.0,
			"totalNum":1,
			"totalPrice":2699.0
		}
	],
	"BOOKS":[
		{
			"skuCategory":"BOOKS",
			"skuId":644564,
			"skuName":"Java编程思想",
			"skuPrice":79.8,
			"totalNum":1,
			"totalPrice":79.8
		},
		{
			"skuCategory":{"$ref":"$[0][0].skuCategory"},
			"skuId":678678,
			"skuName":"Java核心技术",
			"skuPrice":149.0,
			"totalNum":1,
			"totalPrice":149.0
		},
		{
			"skuCategory":{"$ref":"$[0][0].skuCategory"},
			"skuId":697894,
			"skuName":"算法",
			"skuPrice":78.2,
			"totalNum":1,
			"totalPrice":78.2
		},
		{
			"skuCategory":{"$ref":"$[0][0].skuCategory"},
			"skuId":696968,
			"skuName":"TensorFlow进阶指南",
			"skuPrice":85.1,
			"totalNum":1,
			"totalPrice":85.1
		}
	],
	"CLOTHING":[
		{
			"skuCategory":"CLOTHING",
			"skuId":645321,
			"skuName":"纯色衬衫",
			"skuPrice":409.0,
			"totalNum":3,
			"totalPrice":1227.0
		},
		{
			"skuCategory":{"$ref":"$[0][0][0].skuCategory"},
			"skuId":654327,
			"skuName":"牛仔裤",
			"skuPrice":528.0,
			"totalNum":1,
			"totalPrice":528.0
		}
	],
	"ELECTRONICS":[
		{
			"skuCategory":"ELECTRONICS",
			"skuId":654032,
			"skuName":"无人机",
			"skuPrice":4999.0,
			"totalNum":1,
			"totalPrice":4999.0
		},
		{
			"skuCategory":{"$ref":"$[0][0][0][0].skuCategory"},
			"skuId":642934,
			"skuName":"VR一体机",
			"skuPrice":2299.0,
			"totalNum":1,
			"totalPrice":2299.0
		}
	]
}

5.4 partition

按分区条件进行筛选

List<Sku> cartSkuList = CartService.getCartSkuList();
Map<Boolean, List<Sku>> result =
  cartSkuList.stream()
  .collect(
  Collectors
  .partitioningBy(sku -> sku.getTotalPrice() > 100));
System.out.println(JSON.toJSONString(result,true));
{
	false:[
		{
			"skuCategory":"BOOKS",
			"skuId":644564,
			"skuName":"Java编程思想",
			"skuPrice":79.8,
			"totalNum":1,
			"totalPrice":79.8
		},
		{
			"skuCategory":{"$ref":"$[0].skuCategory"},
			"skuId":697878,
			"skuName":"算法",
			"skuPrice":78.2,
			"totalNum":1,
			"totalPrice":78.2
		},
		{
			"skuCategory":{"$ref":"$[0].skuCategory"},
			"skuId":696968,
			"skuName":"TensorFlow进阶指南",
			"skuPrice":85.1,
			"totalNum":1,
			"totalPrice":85.1
		}
	],
	true:[
		{
			"skuCategory":"ELECTRONICS",
			"skuId":654032,
			"skuName":"无人机",
			"skuPrice":4999.0,
			"totalNum":1,
			"totalPrice":4999.0
		},
		{
			"skuCategory":{"$ref":"$[0][0].skuCategory"},
			"skuId":642934,
			"skuName":"VR一体机",
			"skuPrice":2299.0,
			"totalNum":1,
			"totalPrice":2299.0
		},
		{
			"skuCategory":"CLOTHING",
			"skuId":645321,
			"skuName":"纯色衬衫",
			"skuPrice":409.0,
			"totalNum":3,
			"totalPrice":1227.0
		},
		{
			"skuCategory":{"$ref":"$[0][0][2].skuCategory"},
			"skuId":654327,
			"skuName":"牛仔裤",
			"skuPrice":528.0,
			"totalNum":1,
			"totalPrice":528.0
		},
		{
			"skuCategory":"SPORTS",
			"skuId":675489,
			"skuName":"跑步机",
			"skuPrice":2699.0,
			"totalNum":1,
			"totalPrice":2699.0
		},
		{
			"skuCategory":{"$ref":"$[0].skuCategory"},
			"skuId":678678,
			"skuName":"Java核心技术",
			"skuPrice":149.0,
			"totalNum":1,
			"totalPrice":149.0
		}
	]
}

参考博客

  1. JDK1.8新特性——Stream流

  2. Collectors.toMap使用详解

posted @ 2023-03-10 16:37  shine-rainbow  阅读(276)  评论(0编辑  收藏  举报