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表达式的一种写法,接口的方法已经有了实现的时候

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值