Stream流 - 获取Stream和转换操作(含基本数据类型流)

这篇具有很好参考价值的文章主要介绍了Stream流 - 获取Stream和转换操作(含基本数据类型流)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Stream概述

Stream流是jdk1.8对集合对象功能的增强,可以通过将集合转换为流模型,通过声明的方式对集合中的每个元素进行一系列并行或者串行的流水线操作。

Stream只要给出对其包含的元素执行什么操作,Stream就会隐式地在内部进行遍历,并给出响应的数据转换。

Stream可以并行化操作,Stream的并行操作是依赖Java7中引入的Fork/Join框架拆分任务和加速处理过程,并且允许数据源是无限的。

基本的执行流程

使用Stream通常包括3个基本步骤:获取数据源source -> 转换为流 -> 执行操作 -> 获取所想要的结果。每次转换原有的Stream对象,执行结果还是Stream,可以使用串式写法定义多个操作。

  1. List<T> 集合转换为 Stream<T>
  2. 针对Stream进行一系列操作,每次操作结束返回还是Stream。
  3. 可以将Stream转换回集合类型,也可以直接对其中的元素进行处理。

获取Stream

流Stream既可以是串行顺序的stream,也可以是并行的parallelStream。顺序流的操作是在单线程上执行,而并行流是在多线程上并发执行的。

通过集合获取

Arrays.stream(arr)

可以使用 Arrays.stream 将一组数据转换为Stream。

Integer[] arr = new Integer[]{3,4,5,6,78,4};
long count = Arrays.stream(arr).filter(i -> i>20).count();
System.out.println("count=" + count);

输出:
count=1
123456

list.stream()

使用Collection.parallelStream使用并行流,处理任务并行执行。

List<Integer> list = Arrays.asList(1,2,3,4,5,6);
Stream<Integer> stream = list.parallelStream();
stream.forEach(System.out::print);

System.out.println("\n++++++");
Stream<Integer> stream2 = list.stream();
stream2.forEach(System.out::print);

输出:
456321
++++++
123456
123456789101112

parallelStream在使用上和stream没有区别,本质上返回的都是一个流,只不过底层处理时会根据执行环境的条件判断时并行还是串行。

Stream.of()

Integer[] arr = new Integer[]{3,4,5,6,78,4};
List<Integer> list = Arrays.asList(1,2,3,4,5,6);

Stream.of(arr).forEach(System.out::println);
Stream.of(list).forEach(System.out::println);

输出:
3
4
5
6
78
4
[1, 2, 3, 4, 5, 6]
1234567891011121314

基本类型Stream

对于基本类型目前有3中对应的包装类型Stream:IntStreamLongStreamDoubleStream。如果不使用对应的Stream类型,也可以使用 Stream、Stream 和 Stream ,但是针对元素进行装拆箱操作比较耗时,所以才有了常用的基本数据类型的对应Stream。

//参数类型为int...不确定个数的参数,可以根据参数生成一个stream
IntStream.of(3,5,18,1,4).forEach(System.out::println);

//根据指定的返回生成一组连续值,1-10含左不含右
IntStream.range(1,10).forEach(System.out::println);

//根据指定的返回生成一组连续值,10-20含左含右
IntStream.rangeClosed(10,20).forEach(System.out::println);
12345678

从输入流中获取数据的方法

BufferedReader类方法lines()返回Stream

BufferedReader br = new BufferedReader(new FileReader("data.txt"));
Stream<String> stream = br.lines();
stream.foreach(System.out::prinln);
123

转换操作

Stream的操作符基本可以分为转换操作和聚合操作两大类,转换操作符会继续向下传递,聚合操作符直接对数据进行消费或者收集,不会继续向下传递。

  • 转换操作操作符
    • map:转换操作符,用于映射每个元素到对应的结果
    • flatMap:合并转换
    • filter:过滤操作,过滤满足条件的数据
    • limit:限流操作
    • skip:跳过操作
    • distinct:去重操作,底层采用equals进行比对
    • peek:跳出操作
    • sorted:排序操作,Comparable和Comparator接口

map

map方法用于映射每个元素到对应的结果,转换操作函数当做参数传入方法。

List<Integer> list = new ArrayList<Integer>();
list.add(15);
list.add(32);
list.add(67);
list.add(232);
System.out.println(list);
//将Integer类型的元素映射转换为String类型
List<String> result = list.stream().map(i -> String.valueOf(i)).collect(Collectors.toList());
System.out.println(result);Integer类型的元素映射转换为String类型,再过滤字符串长度大于2的元素	
List<String> result2 = list.stream().map(i -> String.valueOf(i)).filter(bb -> bb.length()>2).collect(Collectors.toList());
System.out.println(result2);

输出:
[15, 32, 67, 232]
[15, 32, 67, 232]
[232]
123456789101112131415161718

mapToInt、mapToLong、mapToDouble

用于 统计 结果收集器产生统计结果值,主要用于int、long、double等基本类型。

List<Integer> nums = Arrays.asList(3, 2, 2, 3, 7, 3, 5); 
IntSummaryStatistics stats = nums.stream().mapToInt((x) -> x).summaryStatistics(); 
System.out.println("最大值:"+stats.getMax()); 
System.out.println("最小值:"+stats.getMin()); 
System.out.println("所有数据之和:"+stats.getSum()); 
System.out.println("所有数据的平均值:"+stats.getAverage()); 
System.out.println("所有数据的个数:"+stats.getCount());

输出:
最大值:7
最小值:2
所有数据之和:25
所有数据的平均值:3.5714285714285716
所有数据的个数:7
1234567891011121314

元素是类

HashSet<Product> products = new HashSet<>();
products.add(new Product("product1","11.2"));
products.add(new Product("product2","22.3"));
products.add(new Product("product3","33.4"));

double sum = products.stream().mapToDouble(v -> Double.valueOf(v.getPrice())).sum();
double max = products.stream().mapToDouble(v -> Double.valueOf(v.getPrice())).max().getAsDouble();
double min = products.stream().mapToDouble(v -> Double.valueOf(v.getPrice())).min().getAsDouble();
double average = products.stream().mapToDouble(v -> Double.valueOf(v.getPrice())).average().getAsDouble();
long count = products.stream().mapToDouble(v -> Double.valueOf(v.getPrice())).count();

System.out.println("最大值:"+ max);
System.out.println("最小值:"+ min);
System.out.println("所有数据之和:"+ sum);
System.out.println("所有数据的平均值:"+ average);
System.out.println("所有数据的个数:"+ count);

输出:
最大值:33.4
最小值:11.2
所有数据之和:66.9
所有数据的平均值:22.3
所有数据的个数:3
1234567891011121314151617181920212223

注:max()min()average() 获取的是 OptionalDouble类型,需要调用 getAsDouble() 返回double类型。

flatMap

flatMap将多个流合并,比如,将List<List<String>> 通过flatMap函数可以变为List<String>

List<Integer> list1 = new ArrayList<>();
list1.add(34);
list1.add(25);
list1.add(35);
List<Integer> list2 = new ArrayList<>();
list2.add(999);
list2.add(888);
list2.add(999);
list2.add(666);
List<List<Integer>> tesList = new ArrayList<>();
tesList.add(list1);
tesList.add( list2);

List<Integer> result = tesList.stream()
        .flatMap(num -> num.stream()).collect(Collectors.toList());
        
System.out.println(result);

输出:
[34, 25, 35, 999, 888, 999, 666]
1234567891011121314151617181920

属性合并

合并两个 list< map >, 并将userId 相同的所有属性合并到一个 map 中。
list1中对象的属性:userId、userName
list2中对象的属性:userId、gender、age
最总集合中对象的属性:userId、userName、gender、age

public class MergeStream {
    public static void main(String[] args) {
        List<Map<String,Object>> list1 = new ArrayList<>();
        Map<String,Object> data=new HashMap<>();
        data.put("userId","100001");
        data.put("userName","唐僧");
        list1.add(data);

        List<Map<String,Object>> list2 = new ArrayList<>();
        data=new HashMap<>();
        data.put("userId","100001");
        data.put("gender","男");
        data.put("age",20);
        list2.add(data);

        List<Map<String, Object>> collect = list1.stream().map(m1 -> {
            list2.stream().filter(m2 -> m1.get("userId").equals(m2.get("userId"))).forEach(m2 -> {
                m1.put("gender", m2.get("gender"));
                m1.put("age", m2.get("age"));
            });
            return m1;
        }).collect(Collectors.toList());

        System.out.println(collect);
    }
}

输出:
[{gender=, userName=唐僧, userId=100001, age=20}]
1234567891011121314151617181920212223242526272829

更多操作详见:jdk8使用stream实现两个list集合合并成一个(对象属性的合并)

filter

filter方法用于对传入的数据流进行过滤处理,只返回满足条件的数据组成的新的数据流。

List<Integer> list = new ArrayList<Integer>();
list.add(15);
list.add(32);
list.add(67);
list.add(232);
System.out.println(list);

List<Integer> result = list.stream().filter(i -> i>50).collect(Collectors.toList());

System.out.println(result);

输出:
[15, 32, 67, 232]
[67, 232]
1234567891011121314

limit

limit方法会返回一个包含指定个数元素的新stream,如果原始数据总长大小不足则返回原始流。

List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
    list.add(i);
}

List<Integer> result = list.stream().limit(5).collect(Collectors.toList());

System.out.println(result);

输出:
[0, 1, 2, 3, 4]
1234567891011

skip方法

skip方法的含义是跳过多少个元素,继续处理后续元素。

List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
    list.add(i);
}

List<Integer> result2 = list.stream().skip(5).collect(Collectors.toList());

System.out.println(result2);

输出:
[5, 6, 7, 8, 9]
1234567891011

distinct

distinct会根据原始流中的元素返回一个具有相同顺序,剔除了重复值的流。

List<Product> list = new ArrayList<Product>();
list.add(new Product("product1","11.2"));
list.add(new Product("product2","22.3"));
list.add(new Product("product3","33.4"));
list.add(new Product("product1","11.2"));

List<Product> list2 = list.stream().distinct().collect(Collectors.toList());
System.out.println(list2);

输出:
[Product{name='product1', price='11.2'}, Product{name='product2', price='22.3'}, Product{name='product3', price='33.4'}]
1234567891011

元素Product需要重写hashCode()equals()方法。

sorted

sorted方法是遍历整个流的所有数据,并且在产生任何数据元素之前对它进行排序。需要实现 Comparable接口 和 Comparator接口。

List<Integer> list = new ArrayList<Integer>();
list.add(10);
list.add(39);
list.add(10);
list.add(78);

List<Integer> result =list.stream().sorted(Integer::compareTo).collect(Collectors.toList());

System.out.println(result);

输出:
[10, 10, 39, 78]
123456789101112

聚合操作

见下章《Stream流 - 聚合操作和遍历操作》

参考文章:
《Java学习笔记——Stream流》文章来源地址https://www.toymoban.com/news/detail-595654.html

到了这里,关于Stream流 - 获取Stream和转换操作(含基本数据类型流)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java stream 分组操作

    根据单/多字段分组 单字段分组可以直接使用指定字段,多字段分组则采用拼接Key的形式 单字段: 多字段: 多层级: 测试

    2024年02月15日
    浏览(42)
  • Java 8 Stream 流操作

    博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客👦🏻 《java 面试题大全》 《java 专栏》 🍩惟余辈才疏学浅,临摹之作或有不妥之处,还请读者海涵指正。☕🍭 《MYSQL从入门到精通》数据库是开发者必会基础之一~ 🪁 吾期望此文有资助于尔,即使粗浅难及深广,亦

    2024年04月16日
    浏览(27)
  • java Stream去重操作

     1.根据对象的某个属性去重: 网上找的stream流去重方法,可以根据类的某个属性去重,这里记录一下 使用:

    2024年02月10日
    浏览(33)
  • Java Stream 最全操作用法合集

    Java 8 引入了Stream流的操作,让我们在开发的过程中感受到了很多的便利,小宋我也花时间总结了下关于Stream的堪称最全的使用方法,话不多说,直接放大招。 Java 8提供了两种方式去创建流: 1、stream stream是串行的,可以理解为它的执行是 按顺序执行 的。 2、parallelStream par

    2024年02月16日
    浏览(50)
  • stream流的使用-获取list集合中对象的单个字段list集合,进行累加操作

    场景及代码案例源于实际项目 现存一list集合,其中保存了投资人的信息。 Person (name, age, money rateOfReturn) 其中的money表示投资人现有资产,rateOfReturn表示投资年回报率 需求: 1.计算投资人年龄之和; 2.根据现有资产及投资回报率,计算所有投资人一年后的资产总和; 实体

    2023年04月22日
    浏览(67)
  • Java 8:Stream API 流式操作

    💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! Java 8 中的 Stream API 是一组用于对集合数据进行处理的新特性;提供一种以声明式风格对集合进行操作的方式,简化集合的处理,使得代码更加简洁、优雅,并且能够更高效地处理数据; 这种风格将要处理的元素集合看

    2024年02月13日
    浏览(43)
  • redis【stream】:对redis流数据类型的详细介绍

    目录 stream产生原因 stream的概念 stream底层实现 stream的常用指令 常用命令一览: xadd命令 xread命令 xlen命令 xrange命令 xrevrange命令 xtrim命令 xdel命令 xgroup命令 xinfo命令 xpending命令 xreadgroup命令 xack命令 xclaim命令 redis在设计之初,就试图在保证自身缓存作用在市场上占优的基础上开

    2024年02月06日
    浏览(40)
  • Java中通过List中的stream流去匹配相同的字段去赋值,避免for循环去查询数据库进行赋值操作

    Q :上面两个列表怎么使用流,根据equipmentDeviceMessageInfo中的phone字段去匹配userList 中的phone字段再获取userList 中是name赋值给equipmentDeviceMessageInfo 中的name。 A :以前的写法是通过for循环遍历一个一个去查询赋值,这样的话如果数据多的话一个一个遍历会查询的话肯定是很慢的,

    2024年02月07日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包