java stream流处理

一、stream介绍

Stream(流)

是一个来自数据源的元素队列并支持聚合操作

元素

是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。

数据源

流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。

聚合操作

类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。
和以前的Collection操作不同, Stream操作还有两个基础的特征:

Pipelining:

中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。

内部迭代:

以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。

二、生成流的方法

stream() – 为集合创建串行流
parallelStream() – 为集合创建并行流

三、Stream流处理方法

1、forEach:用于迭代流中的每一个数据

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
numbers.stream().foreach(System.out::println);

2、map: 用于映射每个元素到对应的结果

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
// 获取对应的平方数
List<Integer> squaresList = numbers.stream().map(i -> i*i).collect(Collectors.toList());
System.out.println(squaresList.toString());

3、filter:用于通过设置的条件过滤出元素

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
//获取数组中不为空的字符串
strings = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
System.out.println(strings.toString());

4、limit:用于获取指定数量的流

//获取前两个
List<String> strings = Arrays.asList("abc", "cde", "bc", "efg", "abcd","", "jkl");
strings.stream().limit(2).forEach(System.out::println);

5、sorted:用于对流进行排序

List<Integer> numbers = Arrays.asList(1, 10, 13, 16, 5, 6, 7);
numbers = numbers.stream().sorted().collect(Collectors.toList());
System.out.println(numbers.toString());

四、Collectors:
实现了很多归约操作,例如将流转换成集合和聚合元素或者对集合分组排序处理

(1)Collectors.toCollection() 将流转换成集合

Stream.of(1,2,3,4,5,6,8,9,0).collect(Collectors.toCollection(ArrayList::new));
Stream.of(1,2,3,4,5,6,8,9,0).collect(Collectors.toCollection(HashSet::new));

(2) Collectors.toList() 将流转换成集合 和Collectors.toCollection() 类似

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

(3) Collectors.toSet() 将流转换成集合 和Collectors.toCollection() 类似

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toSet());

(4)Collectors.toMap() 、Collectors.toConcurrentMap() 将流转成Map、 concurrentMap

class Student{
    //唯一
    private String id;
    private String name;
    public Student(String id, String name) {
        this.id = id;
        this.name = name;
    }
   //get set方法省略。。。。。
}
Student studentA = new Student("20190001","张三");
Student studentB = new Student("20190002","王五");
Student studentC = new Student("20190003","李四");
//Function.identity() 获取这个对象本身,那么结果就是Map<String,Student> 即 id->student
//串行收集
Stream.of(studentA,studentB,studentC)
        .collect(Collectors.toMap(Student::getId, Function.identity()));
//并发收集
Stream.of(studentA,studentB,studentC)
        .parallel()
        .collect(Collectors.toConcurrentMap(Student::getId,Function.identity()));

//Map<String,String> 即 id->name
//串行收集
Stream.of(studentA,studentB,studentC)
        .collect(Collectors.toMap(Student::getId,Student::getName));
//并发收集
Stream.of(studentA,studentB,studentC)
        .parallel()
        .collect(Collectors.toConcurrentMap(Student::getId,Student::getName));
//key重复的该怎么处理?这里我们假设有两个id相同Student,如果他们id相同,在转成Map的时候,取name大一个,小的将会被丢弃。
Stream.of(studentA, studentB, studentC)
        .collect(Collectors
                .toMap(Student::getId,
                        Function.identity(),
                        BinaryOperator
                                .maxBy(Comparator.comparing(Student::getName)))); 

(5)Collectors.joining(", ") 将流转换成字符串

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));

(6)Collectors.counting() 统计元素个数,这个和Stream.count() 作用都是一样的
返回的类型一个是包装Long,另一个是基本long

// Long 8
Stream.of(1,0,-10,9,8,100,200,-80)
        .collect(Collectors.counting());

//如果仅仅只是为了统计,那就没必要使用Collectors了,那样更消耗资源
// long 8
Stream.of(1,0,-10,9,8,100,200,-80)
        .count();

(7)Collectors.minBy()、Collectors.maxBy() 获取最大最小值,这个和Stream.min()、Stream.max()作用一样,适用于高级场景

// maxBy 200
Stream.of(1, 0, -10, 9, 8, 100, 200, -80)
        .collect(Collectors.maxBy(Integer::compareTo)).ifPresent(System.out::println);

// max 200
Stream.of(1, 0, -10, 9, 8, 100, 200, -80)
        .max(Integer::compareTo).ifPresent(System.out::println);

// minBy -80
Stream.of(1, 0, -10, 9, 8, 100, 200, -80)
        .collect(Collectors.minBy(Integer::compareTo)).ifPresent(System.out::println);

// min -80
Stream.of(1, 0, -10, 9, 8, 100, 200, -80)
        .min(Integer::compareTo).ifPresent(System.out::println);

(8)Collectors.groupingBy()、Collectors.groupingByConcurrent()单线程和多线程归类
//这里将一组数整型数分为正数、负数、零
//Map<String,List<Integer>>
Stream.of(-6, -7, -8, -9, 1, 2, 3, 4, 5, 6)
        .collect(Collectors.groupingBy(integer -> {
            if (integer < 0) {
                return "小于";
            } else if (integer == 0) {
                return "等于";
            } else {
                return "大于";
            }
        }));

//Map<String,Set<Integer>>
//自定义下游收集器
Stream.of(-6, -7, -8, -9, 1, 2, 3, 4, 5, 6)
        .collect(Collectors.groupingBy(integer -> {
            if (integer < 0) {
                return "小于";
            } else if (integer == 0) {
                return "等于";
            } else {
                return "大于";
            }
        },Collectors.toSet()));

//Map<String,Set<Integer>>
//自定义map容器 和 下游收集器
Stream.of(-6, -7, -8, -9, 1, 2, 3, 4, 5, 6)
        .collect(Collectors.groupingBy(integer -> {
            if (integer < 0) {
                return "小于";
            } else if (integer == 0) {
                return "等于";
            } else {
                return "大于";
            }
        }, LinkedHashMap::new,Collectors.toSet()));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜未央,流年殇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值