Java 8 Streams的简单使用方法

 package JDK8Test;
import java.util.ArrayList; public class Main
{
public static void main(String[] args)
{
ArrayList<Integer> nums=new ArrayList<Integer>();
nums.add(1);
nums.add(null);
nums.add(3);
nums.add(4);
nums.add(null);
nums.add(6);
int n=(int)nums.stream().filter(num->num!=null).count();
System.out.println(n);//
}
}

  上面这段代码是获取一个List中,元素不为null的个数。

  

  

  红色框中的语句是一个Stream的生命开始的地方,负责创建一个Stream实例;绿色框中的语句是赋予Stream灵魂的地方,把一个Stream转换成另外一个Stream,红框的语句生成的是一个包含所有nums变量的Stream,通过绿框的filter方法以后,重新生成了一个过滤掉原nums列表所有null以后的Stream;蓝色框中的语句是丰收的地方,把Stream的里面包含的内容按照某种算法来汇聚成一个值。  

  使用Stream的基本步骤:

  1.创建Stream;

  2.转换Stream,每次转换原有Stream对象不改变,返回一个新的Stream对象(可以有多次转换);

  3.对Stream进行聚合操作,获取想要的结果;

  怎么得到Stream:

  ①使用Stream静态方法来创建Stream:

  of方法:有两个重载方法,一个接受变长参数,一个接受单一值 
  Stream integerStream = Stream.of(1, 2, 3, 5);
  Stream stringStream = Stream.of(“taobao”);

  ②通过Collection接口的默认方法stream(),把一个Collection对象转换成Stream。

  转换Stream:

  转换Stream其实就是把一个Stream通过某些行为转换成一个新的Stream。

  ①distinct: 对于Stream中包含的元素进行去重操作(去重逻辑依赖元素的equals方法),新生成的Stream中没有重复的元素;

  ②filter: 对于Stream中包含的元素使用给定的过滤函数进行过滤操作,新生成的Stream只包含符合条件的元素;

  

  

  ③map: 对于Stream中包含的元素使用给定的转换函数进行转换操作,新生成的Stream只包含转换生成的元素。这个方法有三个对于原始类型的变种方法,分别是:mapToInt,mapToLong和mapToDouble。这三个方法也比较好理解,比如mapToInt就是把原始Stream转换成一个新的Stream,这个新生成的Stream中的元素都是int类型。
  

  例子:

 package JDK8Test;
import java.util.*;
import java.util.Arrays;
import java.util.stream.Collectors; public class Main
{
public static void main(String[] args)
{
List<String> list=Arrays.asList(new String[] {"Ni","Hao","Lambda"});
List<String> list2=list.stream().map(item->item.toLowerCase()).collect(Collectors.toList());
System.out.println(list2);
}//[ni, hao, lambda]
}

  这段代码就是对一个字符串的列表,把其中包含的每个字符串都转换成全小写的字符串。注意代码第四行的map方法调用,这里map方法就是接受了一个lambda表达式。

 package JDK8Test;
import java.util.*;
import java.util.Arrays;
import java.util.stream.Collectors; public class Main
{
public static void main(String[] args)
{
List<String> list=Arrays.asList(new String[] {"Ni","Hao","Lambda"});
List<String> list2=list.stream().map(item->{return "lambda:"+item;}).collect(Collectors.toList());
list2.forEach(System.out::println);
}
}
/*
lambda:Ni
lambda:Hao
lambda:Lambda
*/

  集合的forEach()方法,对集合进行遍历,小括号中的方法就是应用到集合中每个元素的身上,以达到遍历的目的。

 package JDK8Test;
import java.util.*;
import java.util.Arrays;
import java.util.stream.Collectors; public class Main
{
public static void main(String[] args)
{
String waibu="lambda:";
List<String> proStrs=Arrays.asList(new String[] {"Ni","Hao","Lambda"});
List<String> exeStrs=proStrs.stream().map(chuandi->{
long zidingyi=System.currentTimeMillis();
return waibu+chuandi+"------:"+zidingyi;
}).collect(Collectors.toList());
exeStrs.forEach(System.out::println);
}
}
/*
lambda:Ni------:1559118070052
lambda:Hao------:1559118070052
lambda:Lambda------:1559118070052
*/

  

  lambda表达式可以访问给它传递的变量,访问自己内部定义的变量,同时也能访问它外部的变量。 不过lambda表达式访问外部变量有一个非常重要的限制:变量不可变(只是引用不可变,而不是真正的不可变)。 当在表达式内部修改waibu = waibu + " ";时,IDE就会报错。因为变量waibu被lambda表达式引用,所以编译器会隐式的把其当成final来处理。
  以前Java的匿名内部类在访问外部变量的时候,外部变量必须用final修饰。现在java8对这个限制做了优化,可以不用显示使用final修饰,但是编译器隐式当成final来处理。

  ④peek: 生成一个包含原Stream的所有元素的新Stream,同时会提供一个消费函数(Consumer实例),新Stream每个元素被消费的时候都会执行给定的消费函数;

  

  ⑤limit: 对一个Stream进行截断操作,获取其前N个元素,如果原Stream中包含的元素个数小于N,那就获取其所有的元素;

  

  ⑥skip: 返回一个丢弃原Stream的前N个元素后剩下元素组成的新Stream,如果原Stream中包含的元素个数小于N,那么返回空Stream;

  

  汇聚Stream:

  

  汇聚操作(也称为折叠)接受一个元素序列为输入,反复使用某个合并操作,把序列中的元素合并成一个汇总的结果。比如查找一个数字列表的总和或者最大值,或者把这些数字累积成一个List对象。Stream接口有一些通用的汇聚操作,比如reduce()和collect();也有一些特定用途的汇聚操作,比如sum(),max()和count()。注意:sum方法不是所有的Stream对象都有的,只有IntStream、LongStream和DoubleStream实例才有。

  ①reduce():把 Stream 元素组合起来。它提供一个起始值(种子),然后依照运算规则(BinaryOperator),返回单个的结果值,并且reduce操作每处理一个元素总是创建一个新值。

  

  ②collect:正如其名字显示的,它可以把Stream中的所有元素收集到一个结果容器中(比如Collection)。

  Java 8还给我们提供了Collector的工具类——Collectors,其中已经定义了一些静态工厂方法,比如Collectors.toCollection()收集到Collection中, Collectors.toList()收集到List中和Collectors.toSet()收集到Set中。
  List numsWithoutNull = nums.stream().filter(num -> num != null).collect(Collectors.toList());

  ③count方法:获取Stream中元素的个数。

  – 搜索相关
  – allMatch:是不是Stream中的所有元素都满足给定的匹配条件
  – anyMatch:Stream中是否存在任何一个元素满足匹配条件
  – findFirst: 返回Stream中的第一个元素,如果Stream为空,返回空Optional
  – noneMatch:是不是Stream中的所有元素都不满足给定的匹配条件
  – max和min:使用给定的比较器(Operator),返回Stream中的最大|最小值
  下面给出allMatch和max的例子:

 package JDK8Test;
import java.util.*; public class Main
{
public static void main(String[] args)
{
ArrayList<Integer> nums=new ArrayList<Integer>();
nums.add(1);
nums.add(null);
nums.add(3);
nums.add(4);
nums.add(null);
nums.add(6);
System.out.println(nums.stream().filter(item->item!=null).allMatch(item->item<100));
}
}
/*
true
*/

  以上代码,判断nums列表里的不为null元素是否都满足“小于100“这个条件,输出为true。

 package JDK8Test;
import java.util.*; public class Main
{
public static void main(String[] args)
{
ArrayList<Integer> nums=new ArrayList<Integer>();
nums.add(1);
nums.add(null);
nums.add(3);
nums.add(4);
nums.add(null);
nums.add(6);
nums.stream().filter(item->item!=null).max((o1,o2)->o1-o2).ifPresent(System.out::println);
}
}
/*
6
*/

  以上代码,先把nums里为null的元素过滤掉,然后输出nums里元素的最大值。输出为6。

  

Java 8 Streams的简单使用方法的更多相关文章

  1. Ubuntu 14.04 Sublime Text3 Java编译运行(最简单的方法)

    Sublime,结果发现只能编译,无法直接运行,于是就在网上搜解决方法,发现大部分方法都是告诉你要进入Java.sublime-packag这个文件,然后再修改JavaC.sublime-build, ...

  2. Java并发编程基础--基本线程方法详解

    什么是线程 线程是操作系统调度的最小单位,一个进程中可以有多个线程,这些线程可以各自的计数器,栈,局部变量,并且能够访问共享的内存变量.多线程的优势是可以提高响应时间和吞吐量. 使用多线程 一个进程正 ...

  3. js,java,浮点数运算错误及应对方法

    js,java浮点数运算错误及应对方法 一,浮点数为什么会有运算错误 IEEE 754 标准规定了计算机程序设计环境中的二进制和十进制的浮点数自述的交换.算术格式以及方法. 现有存储介质都是2进制.2 ...

  4. java内省机制及PropertyUtils使用方法

    背景 一般情况下,在Java中你可以通过get方法轻松获取beans中的属性值.但是,当你事先不知道beans的类型或者将要访问或修改的属性名时,该怎么办?Java语言中提供了一些像java.bean ...

  5. 计算机网络(13)-----java nio手动实现简单的http服务器

    java nio手动实现简单的http服务器  需求分析 最近在学习HTTP协议,还是希望动手去做一做,所以就自己实现了一个http服务器,主要功能是将http请求封装httpRequest,通过解析 ...

  6. Java设计模式(二) 工厂方法模式

    本文介绍了工厂方法模式的概念,优缺点,实现方式,UML类图,并介绍了工厂方法(未)遵循的OOP原则 原创文章.同步自作者个人博客 http://www.jasongj.com/design_patte ...

  7. Java中的equals和hashCode方法

    本文转载自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要 ...

  8. Java ConcurrentModificationException异常原因和解决方法

    Java ConcurrentModificationException异常原因和解决方法 在前面一篇文章中提到,对Vector.ArrayList在迭代的时候如果同时对其进行修改就会抛出java.u ...

  9. Java提高篇——equals()与hashCode()方法详解

    java.lang.Object类中有两个非常重要的方法: 1 2 public boolean equals(Object obj) public int hashCode() Object类是类继 ...

随机推荐

  1. Gym - 100781A Adjoin the Networks (树的直径)

    题意: n个点,m条边,m <= n <= 100000,边的长度都为1. 点从 0 ~ n-1 编号.开始时图是不连通的,并且没有环. 通过加入一些边后,可以使图连通.要求加入的边不能多 ...

  2. debian安装之后使用android手机上网

    安装debian的过程中,没有连接网线.因为路由器在客厅,电脑在卧室,拖条长长的线很不方便. 断网安装完成之后,通过usb连上i9250. 在i9250上,执行以下操作: “设置”--->“更多 ...

  3. optimize table在优化mysql时很重要

    一个表的数据量有1000W条,那么查看这么表占据的硬盘空间时会发现,数据本身是300M,索引是200M 这个时候,删除掉500W条数据,这个时候数据本身150M,而索引还是200M左右 你删除数据时, ...

  4. UVa 12167 & HDU 2767 强连通分量 Proving Equivalences

    题意:给出一个有向图,问最少添加几条有向边使得原图强连通. 解法:求出SCC后缩点,统计一下出度为0的点和入度为0的点,二者取最大值就是答案. 还有个特殊情况就是本身就是强连通的话,答案就是0. #i ...

  5. 光学字符识别OCR-5 文本切割

    经过前面文字定位得到单行的文本区域之后,我们就可以想办法将单行的文本切割为单个的字符了.因为第三步的模型是针对单个的字符建立的,因此这一步也是必须的. 均匀切割 基于方块汉字的假设,事实上最简单的切割 ...

  6. RF操作滚动条(竖拉)

    方式一:window.scrollBy(0, document.body.scrollHeight) 方式二:window.scrollTo(0, document.body.scrollHeight ...

  7. 正在创建模型,此时不可使用上下文“的解决办法。 正在创建模型,此时不可使用上下文。如果在 OnModelCreating 方法内使用上下文或如果多个线程同时访问同一上下文实例,可能引发此异常。请注意不

    //默认为: Database.SetInitializer<testContext>(null);//这里报错, 检查原因:catch(Exception ex) 错误提示: 基础连接未 ...

  8. LiveScript 流程控制、循环以及列表推导式

    The LiveScript Book     The LiveScript Book Generators and Yield 你可以在你的 LiveScript 代码中使用 Ecmascript ...

  9. Educational Codeforces Round 20 C. Maximal GCD

    C. Maximal GCD time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  10. python相关——如何安装pip

    今天在新的一台电脑上安装了pip.流程有点忘记了,在这里再次记录下来. 本教程基于python3.4,并且需要连接互联网,总共需要两步. 1.要安装pip,首先要安装setuptools,链接:htt ...