Stream常用方法

一、如何创建Stream?

1、 由集合创建流

list = list.stream()
        .filter(str -> StringUtils.equals("3", str))
        .collect(Collectors.toList());

2、 由数组创建流

Arrays.stream 方法:从数组创建一个流,接受一个数组作为参数。

int[] numbers = {2, 3, 5, 7, 11, 13};
int sum = Arrays.stream(numbers).sum();

3、由值创建流

Stream.of 静态方法:显式值 创建一个流,它可以接受任意数量的参数。可以接受数组、集合

Stream<String> stream = Stream.of("java 8", "lambdas", "in", "action");
stream.map(String::toUpperCase).forEach(System.out::println);
​
// 空流
Stream<String> emptyStream = Stream.empty();

4、 由文件生成流

java.nio.file.Files 中的很多静态方法都会返回一个流。

Files.lines 方法:会返回一个由指定文件中的各行构成的字符串流。

// 看一个文件中有多少各不相同的词
long uniqueWords = 0;
try(Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset())) {
    uniqueWords = lines.flatMap(line -> Arrays.stream(line.split(" "))).distinct().count();
} catch (Exception e) {
​
}

5、 由函数生成流:创建无限流

Stream.iterate 静态方法:“迭代”,创建无限流,接受一个初始值,还有一个依次应用在每个产生的新值上的Lambda(UnaryOperator<t>类型)。

Stream.iterate(0, n -> n+2).limit(10).forEach(System.out::println);

Stream.generate 静态方法:“生成”,创建无限流。接受一个Supplier<T>类型的lambda提供新的值。

Stream.generate(Math::random).limit(5).forEach(System.out::println);
 

二、Stream中常用方法?短路操作

  • filter()

  • findAny() findFirst()

  • map()

  • flatMap()

  • count

  • min, max

  • allMatch, noneMatch

  • distinct, limit

  • sort

1、Filter & Predicate 过滤

 
names.stream().filter((name) -> (condition.test(name))).forEach((name) -> {
        System.out.println(name + " ");
    });
​
Predicate<String> startsWithJ = (n) -> n.startsWith("J");
Predicate<String> fourLetterLong = (n) -> n.length() == 3;
​
​
Stream<String> stringStream = names.stream().filter(startsWithJ.and(fourLetterLong));
​
Stream<String> stringStream1 = names.stream().filter((name) -> (startsWithJ.test(name)));
 

2、findAny findFirst

findAny方法:返回当前流中的任意一个元素。它可以与其他流操作集合使用。

findFirst方法:找出第一个

// 给定一个数字列表,找出第一个平方能被3整除的数
Integer integer = Arrays.asList(1, 2, 3, 4, 5).stream().filter(x -> x > 2).findFirst().orElse(0);

3、Map

针对管道流中的每一个数据元素进行转换操作。

List<String> thisGeminiSkuNo =
        skuSaleChannels.stream().map(SkuSaleChannel::getSkuNoExternal)
.filter(StringUtils::isNotEmpty).collect(Collectors.toList());


List<String> upperString = Arrays.asList("aa", "bb").stream()
.map(String::toUpperCase).collect(Collectors.toList());

4、flatMap 将多个Stream连接成一个Stream

多个List合并成一个List

List<Integer> result= Stream.of(Arrays.asList(1,3),Arrays.asList(5,6))
.flatMap(a->a.stream()).collect(Collectors.toList());


List<Integer> level1 = Arrays.asList(1, 2);
List<List<Integer>> level0 = new ArrayList<>(); //[[1, 2], [1, 2]]
level0.add(level1);
level0.add(level1);
List<Integer> collect3 = level0.stream()
.flatMap(Collection::stream).collect(Collectors.toList());

5、Count 计总数

int countOfAdult=persons.stream()
                       .filter(p -> p.getAge() > 18)
                       .map(person -> new Adult(person))
                       .count();

6、Min 最小值

Stream.of(integers)
            .filter(Objects::nonNull)
            .min(Long::compareTo).orElse(0L);
}

7、Max 最大值

Stream.of(integers)
        .filter(Objects::nonNull)
        .max(Long::compareTo).orElse(0L);

8、 Match 检查流是否匹配所有元素

allMatch方法:检查流中元素是否都能匹配给定的元素

// 是否所有元素都大于0
boolean flag = Arrays.asList(1, 2, 3, 4, 5).stream().allMatch(d -> d > 0);

noneMatch方法:流中没有任何元素与给定的谓词匹配

// 是否所有元素都大于 1000
boolean flag = Arrays.asList(1, 2, 3, 4, 5).stream().noneMatch(d -> d > 1000);

9、Distinct 去重

List<Integer> distinctList = Arrays.asList(1, 2, 3, 4, 5, 5, 5).stream()
.distinct().collect(Collectors.toList());

10、 sort 排序

谨慎使用,sort操作会很昂贵,尤其对于大型流。

(1)一个无参的方法

Stream<T> sorted();

查看它的实现类,往里进,发现它默认使用的是自然排序compareTo

List<String> natualSort = Arrays.asList("b", "a", "g").stream()
.sorted().collect(Collectors.toList());

(2)一个有参的方法

Stream<T> sorted(Comparator<? super T> comparator);

该方法需要传一个比较器参数,你可以通过实现 java.util.Comparator定制一个比较器

list.stream().sorted((o1, o2) -> {
    if((o1.getAge() - o2.getAge()) < 0){
        return -1
    }else if ((o1.getAge() - o2.getAge()) > 0){
        return 1
    }else {
        return 0;
    }
}

11、数组 转 List

String[] arr = {"aa", "bb"};
List<String> collect = Stream.of(arr).collect(Collectors.toList());

12、List 转 Map

key是Sudent对象的id,value是Sudent对象的某个属性

Map<String, String> map = list.stream()
.collect(Collectors.toMap(Student::getId,Student::getName));

将list转成以id为key的map,value是id对应的Sudent对象:

Map<String, Student> map = list.stream()
.collect(Collectors.toMap(Student::getId, Function.identity()));

三、collect Collector Collectors 结果收集

1、分组

1)groupingBy()操作需要指定一个关键输入,即分组函数

groupingBy(Function<? super T, ? extends K> classifier)

// 根据skuno分组
Map<String, List<SkuMetaRequest>> skuMetaRequestListMap = skuMetaRequestList.stream()
.collect(Collectors.groupingBy(SkuMetaRequest::getSkuNo));

2)groupingBy()操作需要指定两个关键输入,即分组函数值收集器

groupingBy(Function<? super T, ? extends K> classifier, Collector<? super T, A, D> downstream)

// 根据skuno分组,每组统计数量
Map<String, Long> skuMetaRequestCountMap = skuMetaRequestList.stream()
.collect(Collectors.groupingBy(SkuMetaRequest::getSkuNo, Collectors.counting()));

3)groupingBy()操作需要指定三个关键输入,即分组函数收集容器值收集器

groupingBy(Function<? super T, ? extends K> classifier, Supplier<M> mapFactory, Collector<? super T, A, D> downstream)

// 根据skuno分组,每组统计数量
Map<String, Long> collect5 = challist.stream()
.collect(Collectors.groupingBy(SkuSaleChannel::getSkuNo, HashMap::new, Collectors.counting()));

2、拼接

// 利用-作为连接符
String splitStr = Stream.of("1", "2", "3").collect(Collectors.joining("-"));

3、多参数

<R> R collect(Supplier<R> supplier,
              BiConsumer<R, ? super T> accumulator,
              BiConsumer<R, R> combiner);

Supplier 新建对象, 用来返回的最终结果 BiConsumer accumulator 累加器直接取,将流中每个被遍历的元素添加到新建对象中 BiConsumer combiner 合并器, 在有并行流的时候才会有用, 一个流时代码不会走到这里

// list转为String
String concat = Stream.of("1", "2", "3")
.collect(StringBuilder::new, StringBuilder::append,
        StringBuilder::append)
        .toString();

四、Stream调试神器 Stream Trace(IDEA自带)

设置断点,然后以debug模式运行,然后点击如下所示“按钮”,就可以进入到StreamTrace可视化调试视图,分为Flat Mode 和 Split Mode两种视图,如下所示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值