• Java 8 Streams的简单使用方法


    Java 8 Streams的简单使用方法

     1 package JDK8Test;
     2 import java.util.ArrayList;
     3 
     4 public class Main 
     5 {
     6     public static void main(String[] args) 
     7     {
     8         ArrayList<Integer> nums=new ArrayList<Integer>();
     9         nums.add(1);
    10         nums.add(null);
    11         nums.add(3);
    12         nums.add(4);
    13         nums.add(null);
    14         nums.add(6);
    15         int n=(int)nums.stream().filter(num->num!=null).count();
    16         System.out.println(n);//4
    17     }
    18 }

      上面这段代码是获取一个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类型。
      

      例子:

     1 package JDK8Test;
     2 import java.util.*;
     3 import java.util.Arrays;
     4 import java.util.stream.Collectors;
     5 
     6 public class Main 
     7 {
     8     public static void main(String[] args) 
     9     {
    10         List<String> list=Arrays.asList(new String[] {"Ni","Hao","Lambda"});
    11         List<String> list2=list.stream().map(item->item.toLowerCase()).collect(Collectors.toList());
    12         System.out.println(list2);
    13     }//[ni, hao, lambda]
    14 }    

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

     1 package JDK8Test;
     2 import java.util.*;
     3 import java.util.Arrays;
     4 import java.util.stream.Collectors;
     5 
     6 public class Main 
     7 {
     8     public static void main(String[] args) 
     9     {
    10         List<String> list=Arrays.asList(new String[] {"Ni","Hao","Lambda"});
    11         List<String> list2=list.stream().map(item->{return "lambda:"+item;}).collect(Collectors.toList());
    12         list2.forEach(System.out::println);
    13     }
    14 }
    15 /*
    16 lambda:Ni
    17 lambda:Hao
    18 lambda:Lambda
    19 */

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

     1 package JDK8Test;
     2 import java.util.*;
     3 import java.util.Arrays;
     4 import java.util.stream.Collectors;
     5 
     6 public class Main 
     7 {
     8     public static void main(String[] args) 
     9     {
    10         String waibu="lambda:";
    11         List<String> proStrs=Arrays.asList(new String[] {"Ni","Hao","Lambda"});
    12         List<String> exeStrs=proStrs.stream().map(chuandi->{
    13             long zidingyi=System.currentTimeMillis();
    14             return waibu+chuandi+"------:"+zidingyi;
    15         }).collect(Collectors.toList());
    16         exeStrs.forEach(System.out::println);
    17     }
    18 }
    19 /*
    20 lambda:Ni------:1559118070052
    21 lambda:Hao------:1559118070052
    22 lambda:Lambda------:1559118070052
    23 */

      

      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的例子:

     1 package JDK8Test;
     2 import java.util.*;
     3 
     4 
     5 public class Main 
     6 {
     7     public static void main(String[] args) 
     8     {
     9         ArrayList<Integer> nums=new ArrayList<Integer>();
    10         nums.add(1);
    11         nums.add(null);
    12         nums.add(3);
    13         nums.add(4);
    14         nums.add(null);
    15         nums.add(6);
    16         System.out.println(nums.stream().filter(item->item!=null).allMatch(item->item<100));
    17     }
    18 }
    19 /*
    20 true
    21 */

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

     1 package JDK8Test;
     2 import java.util.*;
     3 
     4 
     5 public class Main 
     6 {
     7     public static void main(String[] args) 
     8     {
     9         ArrayList<Integer> nums=new ArrayList<Integer>();
    10         nums.add(1);
    11         nums.add(null);
    12         nums.add(3);
    13         nums.add(4);
    14         nums.add(null);
    15         nums.add(6);
    16         nums.stream().filter(item->item!=null).max((o1,o2)->o1-o2).ifPresent(System.out::println);
    17     }
    18 }
    19 /*
    20 6
    21 */

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

      

  • 相关阅读:
    Java NIO与IO
    linux命令
    windows的定时任务设置
    《软硬件接口》课程大纲
    使用SSIS对Dynamics CRM 系统进行数据迁移
    数据库设计中的14个技巧
    背景建模或前景检測之PBAS
    Leetcode 树 Populating Next Right Pointers in Each Node II
    QCon大会上推荐阅读的10本书
    cocos2d-x3.0 Slider
  • 原文地址:https://www.cnblogs.com/baichunyu/p/10944648.html
Copyright © 2020-2023  润新知