生成Stream Source的方式

从Collection和数组生成

* Collection.stream()
* Collection.parallelStream()
* Arrays.stream(T array) or Stream.of()

从BufferedReader

* java.io.BufferedReader.lines();

静态工厂

* java.util.stream.IntStream.range();
* java.nio.file.Files.walk();

使用Spliterator

* java.util.Spliterator

其他

* Random.ints();
* BitSet.stream();
* Pattern.splitAsStream(java.lang.CharSequence);
* JarFile.stream();

流的操作

* Intermediate:一个流后面跟随零个或多个intermediate操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,
交给下一个操作使用。这类操作都是以惰性(lazy)化的,就是说,就是
说,仅仅调用到这类方法,并没有真正开始流的遍历。多个intermediate操作会在Terminal操作的时候融合起来,一次循环完成。Stream你有个操作函数的集合,每次转换操作就把转换函数放入这个集合中,在Terminal操作的时候循环Stream对应的集合,然后对每个元素执行所有的函数
* Terminal:一个流只能有一个terminal操作,当这个操作执行后,流就无法再操作了。也就是说Terminal操作是流的最后一个操作。Terminal操作的执行,才会真正开始流的遍历,并且会生成一个结果,或者一个side effect
* short-circuiting。用以指:

对于一个 intermediate 操作,如果它接受的是一个无限大(infinite/unbounded)的 Stream,但返回一个有限的新 Stream。

对于一个 terminal 操作,如果它接受的是一个无限大的 Stream,但能在有限的时间计算出结果。

当操作一个无限大的 Stream,而又希望在有限时间内完成操作,则在管道内拥有一个 short-circuiting 操作是必要非充分条件。

一个流操作的实例:

int sum = widgets.stream()//获取source
.filter(w->w.getColor() == RED)//filter 进行数据筛选
.mapToint(w->w.getWeight())//mapToint进行数据转换
.sum();

stream()获取当前小物件的source,filter和mapToInt为intermediate操作,进行数据筛选和转换,最后一个sum操作为terminal操作,对符合条件的小物件作重量求和

流的操作

  • Intermediate:

    map(mapToint、flatMap)、filter、distinct、sort、peek、limit、skip、parallel、sequential、unordered
  • Terminal

    forEach 、forEachOrder、toArray、reduce、collect、min、max、count、anyMatch、allMatch、noneMatch、findFirst、findAny、iterator
  • Short-circuiting:

    anyMatch、allMatch、noneMatch、findFirst、findAny、limit

map/flatMap

作用:把InputStream的每一个元素映射成output stream的另一个元素

List output = wordList.stream();

map(String::toUpperCase)

collect(Collector.toList())

例子:

转换大小写
List<String> output = wordList.stream().map(String::toUpperCase).collect(Collectors.toList());
平方数
List<Integer> nums = Arrays.asList(1,2,3,4);
List<Integer> squareNums = nums.stream().map(n-> n*n).collect(Collectors.toList());

从上面的例子可以看出,map生成的是个1:1的映射,每个输入的元素都会按照规则转换成为另外一个元素。还有一些场景,是一对多映射关系的,这时需要flatMap


Stream<List<Intege>> inputStream = Stream.of(Arrays.asList(1),
Arrays.asList(2,3),Arrays.asList(4,5,6));
Stream<Integer> outputStream = inputStream.flatMap((childList)->childList.stream));

flatMap把input Stream 中的层级结构扁平化,就是讲最低层的元素抽出来放到一起,最终output的新stream里已经没有List了,都是Integer

filter

作用:

filter 对原始Stream进行某项测试,通过测试的元素被留下来形成一个新的Stream

例子:

选出偶数

Integer [] sixNums = {1,2,3,4,5,6};
Integer [] evens = Stream.of(sixNums).filter(n->n%2== 0).toArray(Integer[]::new);

forEach

作用:

forEach 方法接收一个 Lambda 表达式,然后在 Stream 的每一个元素上执行该表达式。

forEach 是 terminal 操作,因此它执行后,Stream 的元素就被“消费”掉了,你无法对一个 Stream 进行两次 terminal 运算。

例子

package forEach;

import java.util.ArrayList;
import java.util.stream.Stream; class Person{
private String name;
private String gender;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Person(String name, String gender) {
super();
this.name = name;
this.gender = gender;
} }
public class forEach {
public static void main(String[] args) {
ArrayList<Person> roster =new ArrayList<>();
roster.add(new Person("liu","male"));
roster.add(new Person("jiang","female"));
roster.add(new Person("xiao","female"));
roster.stream().filter(person->((Person) person).getGender().equals("female")).forEach(p->System.out.println(p.getName()));
}
}

peek

作用

与forEach一样,但是peek是非terminal的操作。

例子

package forEach;

import java.util.stream.Collectors;
import java.util.stream.Stream; public class peekTest {
public static void main(String[] args) {
Stream.of("one","two","three","four")
.filter(e->e.length()>3).peek(e->System.out.println("Filtered value:"+e))
.map(String::toUpperCase).peek(e->System.out.println("Mapped value:"+e))
.collect(Collectors.toList());
}
}

findFirst

作用

返回stream中的第一个元素或者空。

返回值类型是Optional。Optional是一个容器,可能含有值,也可能不包含。使用Optional的目的是尽可能避免NullPointerException

例子

package findAnyORfindFirst;

import java.util.stream.Stream;

public class findAnyORfindFirst {
public static void main(String[] args) {
String[] strArr= {"A","B","C"};
Stream.of(strArr).findAny().ifPresent(System.out::println);
Stream.of(strArr).findFirst().ifPresent(System.out::println);
}
}

reduce

作用

把Stream元素组合起来。它提供一个起始值(种子),然后按照运算规则(BinaryOperator),和前面Stream的第一个、第二个、第三个、第n个元素组合。从这个意义上说,字符串拼接、数值的sum、min、max、average都是特殊的reduce.

例子

//字符串连接
String concat = Stream.of("A","B","C","D").reduce("",String::concat);

reduce()的第一参数为起始值,第二个人参数为BinaryOperator。这类有起始值的reduce()都返回具体的对象。但是如果没有给reduce()指定起始值,由于可能没有足够的元素导致不能生成对象,这时返回的是Optional。

limit/skip

作用

limit返回Stream的前面n个元素

skip跳过前n个元素

例子

package limitORskip;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream; public class LimitORskipDemo {
public static void main(String[] args) {
Integer [] nums= {1,2,3,4,5,6,7,8,9,10};
List<Integer> list=Stream.of(nums).limit(5).skip(3).collect(Collectors.toList());
list.forEach(System.out::println);
}
}

sorted

作用

对集合排序

例子

package sorted;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream; public class SortedTest {
public static void main(String[] args) {
Integer [] nums= {1,2,3,4,5};
List<Integer> list=Stream.of(nums).sorted((a,b)->a.compareTo(b)).collect(Collectors.toList());
list.forEach(System.out::println);
}
}

max/min/distinct

作用

max 找最大值

min 找最小值

distinct 去重

例子

package MaxMinDistinct;

import java.util.stream.Stream;

public class MaxMinDistinct {
public static void main(String[] args) {
Integer[] nums= {5,3,5,3,4,6,7,8,6,8};
Stream.of(nums).distinct().max((a,b)->a.compareTo(b)).ifPresent(System.out::println);;
Stream.of(nums).distinct().min((a,b)->a.compareTo(b)).ifPresent(System.out::println);;
}
}

Match

作用

Stream 中有三个match方法

* allMatch:Stream中所有元素符合传入的 predicate,返回true

* anyMatch:Stream中只要有一个元素符合传入的 predicate,返回true

* noneMatch:Stream中没有一个元素符合传入的predicate,返回true

 package Match;

import java.util.stream.Stream;

public class MatchDemo {
public static void main(String[] args) {
Integer[] nums1= {1,3,5,-5,2,10};
boolean hasNegtive=Stream.of(nums1).anyMatch(x->x<0);
System.out.println("有负数:"+hasNegtive);
Integer[] nums2= {1,3,5,5,2,10};
boolean a=Stream.of(nums2).allMatch(x->x>0);
System.out.println("全是正数:"+a);
Integer[] nums3= {-1,-3,-5,-5,-2,-10};
boolean none=Stream.of(nums2).noneMatch(x->x>0);
System.out.println("没有正数:"+a);
}
}

generate

作用

通过实现Supplier接口,然后把 Supplier 实例传递给 Stream.generate() ,你可以自己来控制流的生成。

例子

package generate;

import java.util.stream.IntStream;

public class GenerateDemo {
public static void main(String[] args) {
IntStream.generate(()->(int)(Math.random()*10)).limit(20).forEach(System.out::println);
}
}

iterate

作用

第一个参数是起始值(seed),第二个参数是一元操作符函数(UnaryOperator)。

如果seed是第一个元素,那么第二个就是f(seed),第三个就是f(f(seed))….以此类推

例子

package generate;

import java.util.stream.Stream;

public class Iterate {
public static void main(String[] args) {
Stream.iterate(0,x->x+3).limit(15).forEach(System.out::println);
}
}

java8 Stream API笔记的更多相关文章

  1. 如何用Java8 Stream API找到心仪的女朋友

    传统的的Java 集合操作是有些啰嗦的,当我们需要对结合元素进行过滤,排序等操作的时候,通常需要写好几行代码以及定义临时变量. 而Java8 Stream API 可以极大简化这一操作,代码行数少,且 ...

  2. 何用Java8 Stream API进行数据抽取与收集

    上一篇中我们通过一个实例看到了Java8 Stream API 相较于传统的的Java 集合操作的简洁与优势,本篇我们依然借助于一个实际的例子来看看Java8 Stream API 如何抽取及收集数据 ...

  3. 使用Java8 Stream API对Map按键或值进行排序

    一.什么是Java 8 Stream 使用Java 8 Streams,我们可以按键和按值对映射进行排序.下面是它的工作原理: 将Map或List等集合类对象转换为Stream对象 使用Streams ...

  4. Fork/Join框架与Java8 Stream API 之并行流的速度比较

    Fork/Join 框架有特定的ExecutorService和线程池构成.ExecutorService可以运行任务,并且这个任务会被分解成较小的任务,它们从线程池中被fork(被不同的线程执行)出 ...

  5. Java8 Stream API

    Stream是Java8中,操作集合的一个重要特性. 从iteration到Stream操作 当你操作一个集合的时候,你通常的做法是迭代每一个元素,然后处理你想要的事情.举个例子: String co ...

  6. JAVA8 Stream API的使用

    /** * @auther hhh * @date 2018/12/31 12:48 * @description Stream流:用来处理数组.集合的API * 1.不是数据结构,没有内部存储(只是 ...

  7. java8 stream api流式编程

    java8自带常用的函数式接口 Predicate boolean test(T t) 传入一个参数返回boolean值 Consumer void accept(T t) 传入一个参数,无返回值 F ...

  8. 1.分类维护-通过Java8 Stream API 获取商品三级分类数据

    实体类 @Data @TableName("pms_category") public class CategoryEntity implements Serializable { ...

  9. 【Java8新特性】面试官:谈谈Java8中的Stream API有哪些终止操作?

    写在前面 如果你出去面试,面试官问了你关于Java8 Stream API的一些问题,比如:Java8中创建Stream流有哪几种方式?(可以参见:<[Java8新特性]面试官问我:Java8中 ...

随机推荐

  1. TensorFlow——MNIST手写数据集

    MNIST数据集介绍 MNIST数据集中包含了各种各样的手写数字图片,数据集的官网是:http://yann.lecun.com/exdb/mnist/index.html,我们可以从这里下载数据集. ...

  2. 从头学pytorch(十八):GoogLeNet

    GoogLeNet GoogLeNet和vgg分别是2014的ImageNet挑战赛的冠亚军.GoogLeNet则做了更加大胆的网络结构尝试,虽然深度只有22层,但大小却比AlexNet和VGG小很多 ...

  3. 什么样的项目适合docker部署,docker应用场景

    docker官网上说明了docker的典型场景: 使应用的打包与部署自动化 创建轻量.私密的PAAS环境 实现自动化测试和持续的集成/部署 根据这些特性,我们可以想象一下,如果你的项目有如下痛点或者需 ...

  4. cogs 1963. [HAOI 2015] 树上操作 树链剖分+线段树

    1963. [HAOI 2015] 树上操作 ★★★☆   输入文件:haoi2015_t2.in   输出文件:haoi2015_t2.out   简单对比时间限制:1 s   内存限制:256 M ...

  5. java: integer number is too large

    今天想定义一个类常量,结果如下面那样定义,确报错了.error is: Integer number too large public static final Long STARTTIME = 14 ...

  6. Proxmox VE:自建虚拟化方案

    Proxmox VE 简介 Proxmox Virtual Environment,或 Proxmox VE,是来自德国的开源虚拟化方案.软件和社区支持都是免费的,企业用户则可以通过订阅制获得付费商业 ...

  7. 「雅礼集训 2017 Day2」棋盘游戏

    祝各位圣诞后快乐(逃) 题目传送门 分析: 首先棋盘上的路径构成的图是一张二分图 那么对于一个二分图,先求出最大匹配,先手如果走到关键匹配点,只要后手顺着匹配边走,由于不再会出现增广路径,所以走到最后 ...

  8. Matplotlib API汉化 Pyplot API

    https://www.cnblogs.com/chenxygx/p/9554443.html

  9. mysql--->mysql慢查询

    简介 > 开启慢查询日志,可以让MySQL记录下查询超过指定时间的语句,通过定位分析性能的瓶颈,才能更好的优化数据库系统的性能 参数及命令说明 查看慢查询是否开启和日志存储地址 show var ...

  10. vscode python开发插件推荐

    vscode作为一款好用的轻量级代码编辑器,不仅支持代码调试,而且还有丰富的插件库,可以说是免费好用,对于初学者来说用来写写python是再合适不过了.下面就推荐几款个人觉得还不错的插件,希望可以帮助 ...