1、Stream流的定义

Stream是Java中的一个接口。它的作用类似于迭代器,但其功能比迭代器强大,主要用于对数组和集合的操作。

Stream中的流式思想:每一步只操作,不存储。

2、Stream流的获取

可以获取Stream流的有数组和集合。对于数组而言,获取Stream流的方式如下:

StreamMethodCount of(数组)

代码示例:

 	//数组变为Stream流
int[] arr={1,2,3,4,5,6,7};
Stream<int[]> stream = Stream.of(arr);

对于集合而言,获取Stream流的方式如下:

集合.stream()

代码示例:

 		//把集合转换为Stream流
List<String> list=new ArrayList<>();
Stream<String> stream1=list.stream(); Set<String> set=new HashSet<>();
Stream<String> stream2=set.stream(); Map<String,Integer> map=new HashMap<>();
//获取键,存储到Set中
Set<String> key_set=map.keySet();
Stream<String> stream3=key_set.stream();
//获取值,存储到collection集合中
Collection<Integer> values=map.values();
Stream<Integer> stream4 = values.stream();
//获取键值对
Set<Map.Entry<String, Integer>> entries = map.entrySet();
Stream<Map.Entry<String, Integer>> stream5 = entries.stream();

3、对于Stream流进行操作的方法

当数组和集合转化为Stream流之后,可以直接使用Stream流中定义好的方法对于原始的数组和集合进行遍历和过滤等一系列操作,从而使其更加简洁方便。Stream 流自身可以调用的方法大致可以分为两类:

(1)终结方法:返回值不再是stream接口自身类型的方法。

(2)延迟方法:stream流调用该类方法后得到的返回值还是一个Stream流,

故而使用此类方法可以实现链式调用。

3.1、终结方法

3.1.1、forEach方法

该方法的具体定义如下:void forEach(Consumer<? super T> action);

该方法返回值为空,故而在终结方法之列。

该方法要求传入参数是对于函数式接口Consumer的实现类,实现方式可使用匿名内部类、lambda表达式以及方法引用来实现。

关于该函数式接口的具体使用可以参考我写过的上一篇博文: link.

在此处只对其功能做简要介绍。

Consume接口中的唯一的抽象式方法是为了接受给定类型数据,并使用所得到的的数据。

该方法的主要作用是:对流中的元素进行遍历。

代码示例:

public static void main(String[] args) {
//获取Stream流
Stream<String> stream = Stream.of("jay","jj","vae");
//使用Stream流的方法forEach对流进行遍历
stream.forEach((String name)->{
System.out.println(name);//输出结果:jay,jj,vae
});
}

此处对于函数式接口Consume的实现采用的是lambda表达式方法,以下再次出现时就不在重复介绍。

3.1.2、count方法

该方法的具体定义如下:long count();

该方法返回值为long类型的整数,故而在终结方法之列。

该方法无需传参。

该方法的主要作用是:对流中的元素的总个数进行统计。

代码示例:

public static void main(String[] args) {
//获取一个Stream流
List<Integer> list=new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
list.add(6);
list.add(7);
Stream<Integer> stream1 = list.stream(); long count1 = stream1.count();
System.out.println(count1);//输出结果为:7
}

3.2、延迟方法

该类方法的最重要的一个性质就是可以进行链式调用,提升数据处理效率。

3.2.1、filter方法

该方法的具体定义如下: Stream filter(Predicate<? super T> predicate);

该方法返回值为Stream类型,故而在延迟方法之列。

该方法要求传入参数是对于函数式接口Predicate的实现类,实现方式可使用匿名内部类、lambda表达式以及方法引用来实现。

关于该函数式接口的具体使用可以参考我写过的上一篇博文: link.

在此处只对其功能做简要介绍。

Predicate接口中的唯一的抽象式方法是为了对比接受数据类型和要求类型是否一致,并根据结果返回boolean值

该方法的主要作用是:对流中的元素按照某种规则进行筛选后得到一个新的流。其功能等价于一个for循环语句+一个条件判断语句。

代码示例:

public static void main(String[] args) {
//创建一个流
Stream<String> stream = Stream.of("朱元璋", "李世民", "张三丰", "周芷若", "赵敏");
//对流中的元素进行过滤,只要姓张的
Stream<String> stream2 = stream.filter((String name)->{
return name.startsWith("张");
});
stream2.forEach((name)->{
System.out.println(name);//输出结果:"张三丰"
});
}

3.2.2、concat方法

该方法的具体定义如下: Stream concat(Stream<? extends T> a, Stream<? extends T> b)

该方法返回值为Stream类型,故而在延迟方法之列。

该方法要求传入参数两个Stream流。

该方法的主要作用是:将两个Stream流整合为一个Stream流。

代码示例:

public static void main(String[] args) {
Map<String,String> map=new HashMap<>();
map.put("张无忌","赵敏");
map.put("宋青书","周芷若");
map.put("灭绝师太","圆空");
map.put("黄晓明","章金莱");
map.put("孙悟空","白骨精");
map.put("猪八戒","嫦娥");
Set<String> setKey = map.keySet();
Collection<String> values = map.values();
Stream<String> stream1 = setKey.stream();
Stream<String> stream2 = values.stream();
Stream<String> concatStream = Stream.concat(stream1, stream2); concatStream.forEach((s)->{
System.out.println(s);//输出结果过长,就不再一一赘述
});

3.2.3、map方法

该方法的具体定义如下:Stream map(Function<? super T, ? extends R> mapper);

该方法返回值为Stream类型,故而在延迟方法之列。

该方法要求传入参数是对于函数式接口Function的实现类,实现方式可使用匿名内部类、lambda表达式以及方法引用来实现。

关于该函数式接口的具体使用可以参考我写过的上一篇博文: link.

在此处只对其功能做简要介绍。

Function接口中的唯一的抽象式方法是为了将接受数据的类型转化为另一个类型。

该方法的主要作用是:将一个流中的元素映射到另一个流中。

代码示例:

 public static void main(String[] args) {
//获取Stream流
Stream<String> stringStream = Stream.of("1", "2", "3", "4");
//使用map方法,将字符串类型转化为int型
Stream<Integer> stream=stringStream.map((String s)->{
return Integer.parseInt(s);
});
stream.forEach((i)->{
System.out.println(i);
});
}

3.2.4、limit方法

该方法的具体定义如下: Stream limit(long maxSize);

该方法返回值为Stream类型,故而在延迟方法之列。

该方法要求传入的参数是要截取给定Stream流的前多少个元素的数目。

该方法的主要作用是:用于截取给定Stream流中的元素,从而形成一个新的流。

代码示例:

  public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("李");
list.add("张");
list.add("许");
list.add("王");
list.add("朱");
Stream<String> stream = list.stream(); //limit方法
Stream<String> limitStream = stream.limit(3);
limitStream.forEach((s)->{
System.out.println(s);//输出结果:李、张、王
});
}

3.2.5、skip方法

该方法的具体定义如下: Stream skip(long maxSize);

该方法返回值为Stream类型,故而在延迟方法之列。

该方法要求传入的参数是要跳过给定Stream流的前多少个元素的数目。

该方法的主要作用是:用于跳过给定Stream流中前几个元素,从而形成一个新的流。

代码示例:

   public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("李");
list.add("张");
list.add("许");
list.add("王");
list.add("朱");
Stream<String> stream = list.stream(); //skip方法
Stream<String> skipStream = stream.skip(3);
try{
skipStream.forEach((s1)->{
System.out.println(s1);//输出结果:王、朱
});
}catch (Exception e){
e.printStackTrace();
}
}

4、总结

Stream流主要是对于集合和数组的遍历操作做了一系列改进。

将集合和数组转化为stream流后,结合stream中已经定义好的各种方法,可以更加简洁的对于数组和结合中的元素进行操作。

当以后需要遍历一个集合和数组之前,不妨想想使用stream流会不会更合适。

Java提升四:Stream流的更多相关文章

  1. Java 8创建Stream流的5种方法

    不知不觉间,Java已经发展到13了,来不及感慨时间过得真的太快了,来不及学习日新月异的技术更新,目前大多数公司还是使用的JDK8版本,一方面是版本的稳定,另一方面是熟悉,所以很多公司都觉得不升级也挺 ...

  2. java中的Stream流

    java中的Stream流 说到Stream便容易想到I/O Stream,而实际上,谁规定"流"就一定是"IO流"呢?在Java 8中,得益于Lambda所带 ...

  3. Java 8 (6) Stream 流 - 并行数据处理与性能

    在Java 7之前,并行处理集合非常麻烦.首先你要明确的把包含数据的数据结构分成若干子部分,然后你要把每个子部分分配一个独立的线程.然后,你需要在恰当的时候对他们进行同步来避免竞争,等待所有线程完成. ...

  4. Java学习:Stream流式思想

    Stream流 Java 8 API添加了一种新的机制——Stream(流).Stream和IO流不是一回事. 流式思想:像生产流水线一样,一个操作接一个操作. 使用Stream流的步骤:数据源→转换 ...

  5. Java 8 (3) Stream 流 - 简介

    什么是流? 流是Java API的新成员,它允许你以声明性方式处理数据集合(通过查询语言来表达,而不是临时编写一个实现).就现在来说你可以先把它当做是一个遍历数据集的高级迭代器.此外,流还支持并行,你 ...

  6. 双层for循环用java中的stream流来实现

    //双重for循环for (int i = 0; i < fusRecomConfigDOList.size(); i++) { for (int j = 0; j < fusRecomC ...

  7. Java 8 (5) Stream 流 - 收集数据

    在前面已经使用过collect终端操作了,主要是用来把Stream中的所有元素结合成一个List,在本章中,你会发现collect是一个归约操作,就像reduce一样可以接受各种做法作为参数,将流中的 ...

  8. Java 8 (4) Stream 流 - 使用

    在本节中将介绍Stream API支持的许多操作,这些操作可以完成更复杂的数据查询,如筛选.切片.映射.查找.匹配和归约.还有一些特殊的流如:数值流.来自文件和数组等多种来源的流. 筛选和切片 1.用 ...

  9. java 数据类型:Stream流 对象转换为集合collect(Collectors.toList()) ;常用方法count,limit,skip,concat,max,min

    集合对象.stream() 获取流对象,对元素批处理(不改变原集合) 集合元素循环除了用for循环取出,还有更优雅的方式.forEach 示例List集合获取Stream对象进行元素批处理 impor ...

随机推荐

  1. 3.ORM框架一对多的关系及使用

    一对多就是主键与外键的关系,通过一个用户表,角色表进行举例子 角色表role:有外键,对应的是user表的主键 用户表users: from flask import Flask, render_te ...

  2. P1029最大公约数和最小公倍数

    P1029最大公约数和最小公倍数 #include <iostream> #include <cmath> #include <algorithm> #define ...

  3. Primecoin在windows上的部署和启动服务

     Primecoin在windows上的部署和启动服务: 一.从官方获得Primecoin的windows版安装包: 二.一路像安装客户端一样的安装: 三.安装成功后它会自动弹出客户端运行,同步数据, ...

  4. vmware 因误删Linux 虚拟机磁盘,无法启动处理方法

    有可能我们在做了以下误操作,导致Linux系统无法启动: 1). 磁盘损坏或虚拟机磁盘被我们删除了,而fstab文件没有更新: 2). 由于误操作或其它原因使动态库错误. 1. 首先准备好系统安装盘, ...

  5. kubernetes 1.17.2 kubeadm部署 证书修改为100年

    [root@hs-k8s-master01 ~]# cd /data/ [root@hs-k8s-master01 data]# ls docker [root@hs-k8s-master01 dat ...

  6. Python正则表达式就是这么简单【新手必学】

    一前言本篇文章带大家快速入门正则表达式的使用,正则表达式的规则不仅适用python语言,基本大多数编程语言都适用,在日常使用中极为广泛,读者们有必要学好正则表达式.看完这篇文章,读者们要理解什么是正则 ...

  7. Java 在Excel单元格中应用一种/多种字体样式

    在Excel表格中,设置单元格字体样式时,可以对单元格内的所有字符应用同一样式,即获取指定单元,应用样式即可:另外也可以对单元格内的不同字符内容应用不同字体样式,即获取单元格中的字符位置,应用样式:本 ...

  8. STP 指定端口 根端口 区别和理解

    不多说,先上图,A为指定端口,B为非指定端口. 看本文的网友应该知道根端口和指定端口的选举,但是对指定端口和根端口的理解不清楚.这里我就略过选举过程,直接描述这两者的区别和存在的意义. 指定端口:转发 ...

  9. spark广播变量定时更新

    广播变量 先来简单介绍下spark中的广播变量: 广播变量允许程序员缓存一个只读的变量在每台机器上面,而不是每个任务保存一份拷贝.例如,利用广播变量,我们能够以一种更有效率的方式将一个大数据量输入集合 ...

  10. mac访问mysql

    常用操作 开启Mysql服务 1.在终端中输入添加MySQL路径的命令: PATH="$PATH":/usr/local/mysql/bin; 2.在终端输入 mysql -uro ...