java Stream 粗解

Stream

什么是Stream

Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选、排序、聚合等。
Stream可以由数组或集合创建,对流的操作分为两种:

  1. 中间操作,每次返回一个新的流,可以有多个。
  2. 终端操作,每个流只能进行一次终端操作,终端操作结束后流无法再次使用。终端操作会产生一个新的集合或值。

Stream 的创建

1、Collect.list() 方法。 如list.stream();

List<String> list = Arrays.asList("a", "b", "c");
// 创建一个顺序流
Stream<String> stream = list.stream();
// 创建一个并行流
Stream<String> parallelStream = list.parallelStream();

2、Arrays.Stream() 。 如 Arrays.stream({1,2,3,4,5});

int[] array={1,3,5,6,8};
IntStream stream = Arrays.stream(array);

3、of(),iterate(),generate()

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);

Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);
stream2.forEach(System.out::println);

Stream<Double> stream3 = Stream.generate(Math::random).limit(3);
stream3.forEach(System.out::println);

stream 类型

stream和parallelStream的简单区分: stream是顺序流,由主线程按顺序对流执行操作,而parallelStream是并行流,内部以多线程并行执行的方式对流进行操作,但前提是流中的数据处理没有顺序要求。例如筛选集合中的奇数,两者的处理不同之处:
在这里插入图片描述

stream 常用方法

遍历、匹配:foreach/find/match

List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);

// 遍历输出符合条件的元素
list.stream().filter(x -> x > 6).forEach(System.out::println);
// 匹配第一个
Optional<Integer> findFirst = list.stream().filter(x -> x > 6).findFirst();
// 匹配任意(适用于并行流)
Optional<Integer> findAny = list.parallelStream().filter(x -> x > 6).findAny();
// 是否包含符合特定条件的元素
boolean anyMatch = list.stream().anyMatch(x -> x < 6);
System.out.println("匹配第一个值:" + findFirst.get());
System.out.println("匹配任意一个值:" + findAny.get());
System.out.println("是否存在大于6的值:" + anyMatch);

过滤:filter

int[] arrs = {1,2,3,4,5,6};
Arrays.stream(arrs).filter(x -> x>3).forEach(System.out::println);

结果: 4 5 6 (有换行符)

映射:map/flatmap

map 传入一个方法作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
flatmap 传入方法作为参数,将流中的每个值都换成另一个流,最终合并一个新的集合

 	List<String> list = Arrays.asList("m-k-l-a", "1-3-5-7");
    List<String> listNew = list.stream().flatMap(s -> {
      // 将每个元素转换成一个stream
      String[] split = s.split("-");
      Stream<String> s2 = Arrays.stream(split);
      return s2;
    }).collect(Collectors.toList());

    System.out.println("处理前的集合:" + list);
    System.out.println("处理后的集合:" + listNew);
    处理前的集合:[m-k-l-a, 1-3-5]
	处理后的集合:[m, k, l, a, 1, 3, 5]

    String[] strArr = { "abcd", "bcdd", "defde", "fTr" };
    List<String> strList = 	Arrays.stream(strArr).map(String::toUpperCase).collect(Collectors.toList());

    List<Integer> intList = Arrays.asList(1, 3, 5, 7, 9, 11);
    List<Integer> intListNew = intList.stream().map(x -> x + 3).collect(Collectors.toList());

    System.out.println("每个元素大写:" + strList);
    System.out.println("每个元素+3:" + intListNew);

聚合:max/min/count

int[] arrs = {1,2,3,4,5,6};
OptionalInt max = Arrays.stream(arrs).max();
OptionalInt max = Arrays.stream(arrs).max();
OptionalInt min = Arrays.stream(arrs).min();
long count = Arrays.stream(arrs).count();

规约:reduce

public class Staff {
   private String name;
    private int salary;

	    public Staff(String name, int salary) {
	        this.name = name;
	        this.salary = salary;
	    }
//	    get/set 忽略
}

    ArrayList<Staff> staffList = new ArrayList() {{
       add(new Staff("zhangSan",10000));
       add(new Staff("liSi",8000));
       add(new Staff("wangWu",12000));
    }};
    //带初始值、累加器、合并器的reduce函数
    Optional<Integer> reduce = staffList.stream().map(Staff::getSalary).reduce((sum, a) -> sum += a);
    Integer reduce1 = staffList.stream().reduce(0, (sum, s) -> sum += s.getSalary(), (sum1, sum2) -> sum1 + sum2);
    Integer reduce2 = staffList.stream().reduce(0, (sum, p) -> sum += p.getSalary(), Integer::sum);
    System.out.println(reduce.get());
    System.out.println(reduce1);
    System.out.println(reduce2);

    Integer maxSalary1 = staffList.stream().reduce(0, (max, p) -> max > p.getSalary() ? max : p.getSalary(), Integer::max);
    Integer maxSalary2 = staffList.stream().reduce(0, (max, p) -> max > p.getSalary() ? max : p.getSalary(), (max1, max2) -> max1 > max2 ? max1 : max2);
    System.out.println(maxSalary1);
    System.out.println(maxSalary2);

集合:collect

toList/toSet/toMap
List<Integer> list = Arrays.asList(1, 6, 3, 4, 6, 7, 9, 6, 20);
List<Integer> listNew = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());
Set<Integer> set = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toSet());

Map<String, Staff> staffMap = staffList.stream().collect(Collectors.toMap(Staff::getName, p -> p));
拼接 joining
String names = staffList.stream().map(p -> p.getName()).collect(Collectors.joining(","));
归约(reducing)

排序(sorted)

sorted,中间操作。有两种排序:
sorted():自然排序,流中元素需实现Comparable接口
sorted(Comparator com):Comparator排序器自定义排序
	   ArrayList<Staff> staffList = new ArrayList() {{
	       add(new Staff("zhangSan",10000,20));
	       add(new Staff("liSi",8000,21));
	       add(new Staff("wangWu",12000,20));
	       add(new Staff("wangLiu",12000,22));
	   }};
	           //先按薪水降序,再按年龄升序
		List<String> nameList = staff.stream().sorted(Comparator.comparing(Staff::getSalary).reversed().thenComparing(Staff::getAge)).map(Staff::getName).collect(Collectors.toList());
		System.out.println(nameList);
        // 自定义 薪水降序,年龄升序
        List<String> nameCollect1 = staff.stream().sorted((p1, p2) -> {
            if (p1.getSalary() == p2.getSalary()) {
                return p1.getAge() - p2.getAge();
            } else {
                return p2.getSalary() - p1.getSalary();
            }
        }).map(Staff::getName).collect(Collectors.toList());

提取/组合

流也可以进行合并、去重、限制、跳过等操作。

String[] arr1 = { "a", "b", "c", "d" };
    String[] arr2 = { "d", "e", "f", "g" };

    Stream<String> stream1 = Stream.of(arr1);
    Stream<String> stream2 = Stream.of(arr2);
    // concat:合并两个流 distinct:去重
    List<String> newList = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());
    // limit:限制从流中获得前n个数据
    List<Integer> collect = Stream.iterate(1, x -> x + 2).limit(10).collect(Collectors.toList());
    // skip:跳过前n个数据
    List<Integer> collect2 = Stream.iterate(1, x -> x + 2).skip(1).limit(5).collect(Collectors.toList());

    System.out.println("流合并:" + newList);
    System.out.println("limit:" + collect);
    System.out.println("skip:" + collect2);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值