IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Java8 Stream流 (二) -> 正文阅读

[数据结构与算法]Java8 Stream流 (二)

一、Stream流的具体使用

1.1??筛选 filter

filter 函数接收一个Lambda表达式作为参数,该表达式返回boolean,在执行过程中,流将元素逐一输送给filter,并筛选出执行结果为true的元素。

//输出大于3的元素
 List<Integer> list =Arrays.asList(1,2,3,4,6);
        list.stream()
                .filter(num->num>3)
                .collect(Collectors.toList()).forEach( n-> 
 System.out.println(n.toString()));

1.2 去重 distinct

去掉重复的结果:

//去除重复的3元素
    List<Integer> list =Arrays.asList(1,3,3,4,6);
    list.stream()
                .distinct().collect(Collectors.toList()).forEach( n-> 
  System.out.println(n.toString()));

1.3 截取 limit

截取流的前N个元素:

//截取前3个元素后面的 元素        
List<Integer> list =Arrays.asList(1,3,3,4,6);
        list.stream()
                .limit(3).collect(Collectors.toList()).forEach( n-> System.out.println(n.toString()));

1.5 跳过 skip

跳过流的前n个元素:

//跳过前3个元素
        List<Integer> list =Arrays.asList(1,3,3,4,6);
        list.stream()
                .skip(3).collect(Collectors.toList()).forEach( n-> System.out.println(n.toString()));

1.6 映射map

对流中的每个元素执行一个函数,使得元素转换成另一种类型输出。流会将每一个元素输送给map函数,并执行map中的Lambda表达式,最后将执行结果存入一个新的流中。
           
        //integer流 转换为字符串
        List<Integer> list =Arrays.asList(1,3,3,4,6);
        List<String> mapList= list.stream()
                .map(num->num.toString()).collect(Collectors.toList());

1.7 流的合并 flatmap

//截取之后 流的合并
        List<String> list =Arrays.asList(" 1 1 "," 2 2 "," 3 3 ");
        List<String> mapList= list.stream()
                .map(str->str.split(" ")).flatMap(Arrays::stream).distinct().collect(Collectors.toList());

1.8?匹配元素

### 匹配元素:

# allMatch 匹配全部元素
allMatch用于判断流中的所有元素是否都满足指定条件,这个判断条件通过Lambda表达式传递给anyMatch,执行结果为boolean类型。

      List<Integer> list =Arrays.asList(1,2,3,4);
      boolean flag= list.stream()
                .allMatch(num->num>3);

# anyMatch 匹配单个元素
anyMatch用于判断流中是否存在至少一个元素满足指定的条件,这个判断条件通过Lambda表达式传递给anyMatch,执行结果为boolean类型。

        List<Integer> list =Arrays.asList(1,2,3,4);
        boolean flag= list.stream()
                .anyMatch(num->num>3);

# 是否未匹配所有元素
#noneMatch
noneMatch与allMatch恰恰相反,它用于判断流中的所有元素是否都不满足指定条件:
        List<Integer> list =Arrays.asList(1,2,3,4);
        boolean flag= list.stream()
                .anyMatch(num->num>100);

#获取任一元素findAny 返回optional
#findAny
      List<Integer> list =Arrays.asList(1,2,3,4);
        Optional optional = list.stream()
                .findAny();

#获取第一个元素findFirst 返回optional
#findFirst
      List<Integer> list =Arrays.asList(1,2,3,4);
        Optional optional = list.stream()
                .findFirst();

#返回流中元素的最小值 min
#min
        List<Integer> list =Arrays.asList(1,2,3,4);
        Integer minValue = list.stream()
                .min(Integer::compareTo).get();

#返回流中的元素的最大值 max
#max      
        List<Integer> list =Arrays.asList(1,2,3,4);
        Integer minValue = list.stream()
                .max(Integer::compareTo).get();

 

1.9 归约 reduce

### 归约

归约是将集合中的所有元素经过指定运算,折叠成一个元素输出,如:求最值、平均数等,这些操作都是将一个集合的元素折叠成一个元素输出。

在流中,reduce函数能实现归约。
reduce函数接收两个参数:

1. 初始值
2. 进行归约操作的Lambda表达式

**元素求和:自定义Lambda表达式实现求和**

例:计算总和

  List<Integer> list =Arrays.asList(1,2,3,4);

  Integer value = list.stream().reduce(0,(num1,num2)->num1+num2);

1. reduce的第一个参数表示初试值为0;
2. reduce的第二个参数为需要进行的归约操作,它接收一个拥有两个参数的Lambda表达式,reduce会把流中的元素两两输给Lambda表达式,最后将计算出累加之和。

**元素求和:使用Integer.sum函数求和**

上面的方法中我们自己定义了Lambda表达式实现求和运算,如果当前流的元素为数值类型,那么可以使用Integer提供了sum函数代替自定义的Lambda表达式,如:

   Integer value = list.stream().reduce(0,Integer::sum);

Integer类还提供了 `min`、`max` 等一系列数值操作,当流中元素为数值类型时可以直接使用。


### 一般性归约

若你需要自定义一个归约操作,那么需要使用 `Collectors.reducing` 函数,该函数接收三个参数:

* 第一个参数为归约的初始值
* 第二个参数为归约操作进行的字段
* 第三个参数为归约操作的过程

2.0 数值流

### 数值流的使用

采用reduce进行数值操作会涉及到基本数值类型和引用数值类型之间的装箱、拆箱操作,因此效率较低。
当流操作为纯数值操作时,使用数值流能获得较高的效率。

**将普通流转换成数值流**

StreamAPI提供了三种数值流:IntStream、DoubleStream、LongStream,也提供了将普通流转换成数值流的三种方法:mapToInt、mapToDouble、mapToLong。
如,将Person中的age转换成数值流:


IntStream stream = list.stream().mapToInt(Person::getAge);


**数值计算**

每种数值流都提供了数值计算函数,如max、min、sum等。如,找出最大的年龄:


OptionalInt maxAge = list.stream()
                                .mapToInt(Person::getAge)
                                .max();


由于数值流可能为空,并且给空的数值流计算最大值是没有意义的,因此max函数返回OptionalInt,它是Optional的一个子类,能够判断流是否为空,并对流为空的情况作相应的处理。
此外,mapToInt、mapToDouble、mapToLong进行数值操作后的返回结果分别为:OptionalInt、OptionalDouble、OptionalLong

2.1 分组?collect

Person p1 = new Person("zhangsan",26);
Person p2 = new Person("lisi",22);
Person p3 = new Person("wangwu",23);
List<Person> list = Arrays.asList(p1,p2,p3);
//装成list
List<Integer> ageList = list.stream().map(Person::getAge).collect(Collectors.toList());//[26,22,22]
//转成set
Set<Integer> ageSet = list.stream().map(Person::getAge).collect(Collectors.toSet());//[26,22]

//转成map,注:key不能相同,否则报错
Map<String, Integer> studentMap = list.stream().collect(Collectors.toMap(Person::getName, Person::getAge)); 
// {zhangsan=26, lisi=22, wangwu=22}

//字符串分隔符连接
String joinName = list.stream().map(Person::getName).collect(Collectors.joining(",", "(", ")")); 
// (zhangsan,lisi,wangwu)

//聚合操作
//1.总数
Long count = list.stream().collect(Collectors.counting()); // 3
//2.最大年龄 (最小的minBy同理)
Integer maxAge = list.stream().map(Person::getAge).collect(Collectors.maxBy(Integer::compare)).get(); // 26
//3.所有人的年龄求和
Integer sumAge = list.stream().collect(Collectors.summingInt(Person::getAge)); // 70
//4.平均年龄
Double averageAge = list.stream().collect(Collectors.averagingDouble(Person::getAge)); // 23.333333333333332
// 带上以上所有方法
DoubleSummaryStatistics statistics = list.stream().collect(Collectors.summarizingDouble(Person::getAge));
System.out.println("count:" + statistics.getCount() + ",max:" + statistics.getMax() + ",sum:" + statistics.getSum() + ",average:" + statistics.getAverage());
        
//分组 按年龄分组
Map<Integer, List<Person>> ageMap = list.stream().collect(Collectors.groupingBy(Person::getAge));
//分区
//分成两部分,一部分大于10岁,一部分小于等于10岁
Map<Boolean, List<Person>> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 10));
//规约
Integer allAge = list.stream().map(Person::getAge).collect(Collectors.reducing(Integer::sum)).get(); //40 

2.2?Collectors.toList() 解析

public <T> Collector<T, ?, List<T>> toList() {
    Supplier<List<T>> supplier = () -> new ArrayList();
    BiConsumer<List<T>, T> accumulator = (list, t) -> list.add(t);
    BinaryOperator<List<T>> combiner = (list1, list2) -> {
        list1.addAll(list2);
        return list1;
   };

参考文档

半城抹茶Java 8 教程

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-01 15:57:51  更:2022-05-01 15:59:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 5:52:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码