当前位置: 首页 > news >正文

java8 新特性 stream

java8 stream
在这里插入图片描述

创建流

集合对象.stream()、Arrays.stream(数组对象)【这个返回的是intStream】、Stream.of()【不推荐】
我理解中Stream.of()更像是直接把参数作为一个个的对象去创建流(看解释符合我的猜想),不过参数是字符串数组的时候又会拿数组里面的数据去创建流,真是疑惑。

Stream.of(数组对象)创建流,如果数组数据类型是基本类型,那么创建的流内部是数组对象(int[ ]),会有问题。如果传入的是list,创建的流是一个list流,也有问题。
基本数据类型的数组创建流,最好用Arrays.stream创建基本(int)流,再调用boxed转包装(integer)流。
顺便提醒一下Arrays.asList()创建的list是不可变的

数组转list(前两个本质上都是一样的流操作)

方法1、先利用Arrays.stream转成int流,然后调用boxed转成integer流,再转list。
方法2、可以先用Arrays.asList转成不可变的list,然后转成流再获取集合,这样集合就是可变集合了。
方法3、可以显式创建list,传入Arrays.asList生成的不可变数组对象,然后得到一个可变的list。

int流转Integer流.boxed
int[ ] a={1,2};
String[ ] a1={"1","2"};
IntStream stream = Arrays.stream(a);//返回intStream
Stream<String> stream1 = Arrays.stream(a1);//正常返回字符串流
Stream<int[]> b1 = Stream.of(a);//基本类型数组创建的流有问题
Stream<String> b2 = Stream.of(a1);//正常返回字符串流
Stream<Integer> boxed = Arrays.stream(a).boxed();//int流转integer流

List<Integer> id = Arrays.asList(20, 10, 38, 49);
Stream<List<Integer>> id1 = Stream.of(id);//这样创建也有问题,要用对象.stream创建
流转数组toArray

需要传入构造数据的方法

Integer[] integers1 = Arrays.asList(1, 2, 3).stream()
                        .toArray(Integer[]::new);
Integer[] integers2 = Arrays.asList(1, 2, 3).stream()
                        .toArray(size -> new Integer[size]);

操作流

转换流map(一对一)

参数部分可以利用lambda表达式,拼接出新的对象流。参数左侧代表原来列表内的单个对象,右侧代表新的流里面的单个对象。(列表对象数量上面一一对应)
常用:对象流到对象流,对象流转基本数据流。
例子:

class User{
    private long id;
    private int gender;
    private int age;
    User(){};
    User(long id,int gender,int age){
        this.id=id;
        this.gender=gender;
        this.age=age;
    }
}
class Student{
    private long id;
    private int age;
    Student(){};
    Student(long id,int age){
        this.id=id;
        this.age=age;
    }
}

List<User> userList=new ArrayList<>();
userList.add(new User(1,0,18));
userList.add(new User(2,0,18));
userList.add(new User(3,1,20));
//对象流转基本数据流
List<Long> userIdList= userList.stream().map(x->x.getId()).collect(Collectors.toList());
//对象流转对象流
List<Student> studentList=userList.stream().map(x->{
    Student stu= new Student();
    stu.setId(x.getId());
    stu.setAge(x.getAge);
    return stu;
}).collect(Collectors.toList());
转换流flatMap(一对多)

在括号内,是一对多的关系,左边是原理的对象,右边是一个新的流。也就是将一个对象转成一个流(流里面可能包含多个对象),最后再将全部流合在一起,形成一个新的流。
例子:

//将一个英文句子数组拆成一个单词数组
List<String> sentences = Arrays.asList("hello world","Jia Gou Wu Dao");
List<String> results = sentences.stream()
             .flatMap(sentence -> Arrays.stream(sentence.split(" ")))             .collect(Collectors.toList());     System.out.println(results);
             .collect(Collectors.toList());
过滤流filter

根据括号内的条件,符合条件的加入返回的流,不符合的就被过滤掉。
例子:

//过滤用户id为空的对象,可以像上面的对象流转对象流一样进行较多逻辑判断
List<User> userIdList= userList.stream()
.filter(x->!Objects.nonNull(x.getVoiceId()))
.collect(Collectors.toList());
排序流sorted
//过滤用户id为空的对象,
List<User> userIdList= userList.stream().sorted((x,y)->x-y).collect(Collectors.toList());
//可以像上面的对象流转对象流一样进行较多逻辑判断,从小到大顺序排序
List<User> userIdList= userList.stream().sorted((x,y)->{
        if(x.getId()>y.getId()){
            return 1;
        }else if(x.getId()<y.getId()){
            return -1;
        }else{
            if(x.getAge()>y.getAge()){
                return 1;
            }else{
                return -1;
            }
        }
}).collect(Collectors.toList());
去重流distinct
//对象的去重流是调用类的hashcode和toString方法来判断是否重复(可以自定义是否重复)
List<User> userIdList= userList.stream()
.distinct().collect(Collectors.toList());
合并流Stream.concat
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4);
Stream<Integer> arr1 = Stream.of(1,2,3);
List<Integer> collect2 = Stream.concat(integerStream, arr1)
.collect(Collectors.toList());
System.out.println(collect2);

在这里插入图片描述

查找符合条件的第一个元素findFirst

一般配合filter以及ifPresent使用,下面语句的意思是查找符合条件的第一个元素,如果存在则输出

userList.stream().findFirst().ifPresent(s -> System.out.println(s));
遍历(peek&foreach)
中间遍历peek

该方法会遍历一遍流里面的元素,必须配合终止流才会进行里面遍历的操作。如果没有调用终止流的操作,那么中间操作并不会执行。

终止流foreach

调用终止流foreach会遍历流里面的元素,并且立刻执行。

public void testPeekAndforeach() {
    List<String> sentences = Arrays.asList("hello world","Jia Gou Wu Dao");
    // 演示点1: 仅peek操作,最终不会执行
    System.out.println("----before peek----");
    sentences.stream().peek(sentence -> System.out.println(sentence));
    System.out.println("----after peek----");
    // 演示点2: 仅foreach操作,最终会执行
    System.out.println("----before foreach----");
    sentences.stream().forEach(sentence -> System.out.println(sentence));
    System.out.println("----after foreach----");
    // 演示点3: peek操作后面增加终止操作,peek会执行
    System.out.println("----before peek and count----");
    sentences.stream().peek(sentence -> System.out.println(sentence)).count();
    System.out.println("----after peek and count----");
}

在这里插入图片描述

取前几个元素limit

通过limit,可以限制获取流里面元素的个数,比如先排序,然后限制数量,就可以获取排序前几的元素。

public void testGetTargetUsers() {
    List<Integer> ids = Arrays.asList(10,20,50,5,6);
// 使用流操作
List<Integer> results = ids.stream()
        .sorted((x,y)->(x-y))
        .limit(3)
        .collect(Collectors.toList());
System.out.println(results);
}

[图片]

跳过前几个元素skip
int[] arr={1,2,3};
 Arrays.stream(arr).skip(2).forEach(System.out::println);

[图片]

终止流

一个流调用了终止流的方法之后,流就不可用了。
比如一些常用的,
计算流内元素数量count
获取流里面元素最大值max
获取流里面元素最小值min
流内是否存在元素anyMatch
流内是否全部元素都匹配allMatch
流内没有匹配的元素noneMatch

收集流collect

将流里面的元素返回一个集合

public void testCollectStopOptions() {
    List<Dept> ids = Arrays.asList(new Dept(17), new Dept(22), new Dept(23));
    // collect成list
    List<Dept> collectList = ids.stream().filter(dept -> dept.getId() > 20)
            .collect(Collectors.toList());
    System.out.println("collectList:" + collectList);
    // collect成Set
    Set<Dept> collectSet = ids.stream().filter(dept -> dept.getId() > 20)
            .collect(Collectors.toSet());
    System.out.println("collectSet:" + collectSet);
    // collect成HashMap,key为id,value为Dept对象
    Map<Integer, Dept> collectMap = ids.stream().filter(dept -> dept.getId() > 20)
            .collect(Collectors.toMap(Dept::getId, dept -> dept));
    System.out.println("collectMap:" + collectMap);
}
利用collect拼接元素
List<String> id = Arrays.asList("205", "10", "308", "49");
String joinResult = id.stream().collect(Collectors.joining(","));
System.out.println(joinResult);

[图片]

统计相关
List<Integer> id = Arrays.asList(205, 10, 308, 49);
IntSummaryStatistics collect = id.stream()
.collect(Collectors.summarizingInt(x -> x));
System.out.println(collect);

[图片]

IntSummaryStatistics 对象还可以中途加数据,加数据之后其他数据会重新计算。
还可以调用combine方法加其他IntSummaryStatistics 对象。

双冒号

lambda表达式的一种写法,接口的方法已经有了实现的时候

相关文章:

  • DAY45(DAY46拓展):SOCKS 代理技术
  • Handler消息传递机制
  • Django之路由匹配
  • Java面试(四)JVM基础
  • 新学期,新FLAG
  • 一文详解C语言文件
  • Java实现的一个编译器源代码(Win11)
  • 内核调试:crash工具与vmcore实践
  • C++ Qt / VS2019 +opencv + onnxruntime 部署语义分割模型【经验】
  • 如何查看线程死锁
  • 代码源每日一题div2 可重排列
  • 【原创】基于Jsp+Servlet的仓库管理系统
  • 堡垒机部署
  • linux的man命令
  • 10 项目沟通管理
  • JS 中的深拷贝与浅拷贝
  • [笔记] php常见简单功能及函数
  • Angular4 模板式表单用法以及验证
  • git 常用命令
  • Javascript 原型链
  • PermissionScope Swift4 兼容问题
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • vue-router的history模式发布配置
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 高度不固定时垂直居中
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 前端_面试
  • 如何邀请好友注册您的网站(模拟百度网盘)
  • 山寨一个 Promise
  • 用element的upload组件实现多图片上传和压缩
  • 由插件封装引出的一丢丢思考
  • 运行时添加log4j2的appender
  • ​比特币大跌的 2 个原因
  • (1/2)敏捷实践指南 Agile Practice Guide ([美] Project Management institute 著)
  • (13):Silverlight 2 数据与通信之WebRequest
  • (4)事件处理——(6)给.ready()回调函数传递一个参数(Passing an argument to the .ready() callback)...
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (二)c52学习之旅-简单了解单片机
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (附源码)ssm教材管理系统 毕业设计 011229
  • (四)库存超卖案例实战——优化redis分布式锁
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (转)linux 命令大全
  • (转)德国人的记事本
  • ../depcomp: line 571: exec: g++: not found
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .Net Memory Profiler的使用举例
  • .NET 常见的偏门问题
  • .net中生成excel后调整宽度
  • /*在DataTable中更新、删除数据*/
  • [ IOS ] iOS-控制器View的创建和生命周期
  • [ solr入门 ] - 利用solrJ进行检索
  • [20180129]bash显示path环境变量.txt
  • [BZOJ 1032][JSOI2007]祖码Zuma(区间Dp)
  • [BZOJ] 2044: 三维导弹拦截