Java Stream函数式编程图文详解(二):管道数据处理

Java Stream函数式编程?案例图文详解管道数据处理

1、Java Stream管道数据处理操做

在本号以前发布的文章《Java Stream函数式编程?用过都说好,案例图文详解送给你》中,笔者对Java Stream的介绍以及简单的使用方法给你们作了介绍。在开始本文以前,咱们有必要介绍一下这张Java Stream 数据处理过程图,图中主要分三个部分:java

  • 将数组、集合类、文本文件转换为管道流(图中的蓝色方块的部分,在本号的上一篇文章中已经给你们介绍过了)
  • Java Stream管道数据处理操做(也就是下图中中间的虚线内的数据处理操做,本文的主要内容)
  • 管道流处理结果的聚合、累加、计数、转换为集合类等操做(图中的绿色方块部分)

须要注意的是:Java Stream的中间数据处理操做的输入是一个管道流(Stream),输出仍然是一个管道流(Stream)。下面咱们就来详细的学习一下!在上一篇文章中,咱们给你们讲了这样一个例子:spring

List<String> nameStrs = Arrays.asList("Monkey", "Lion", "Giraffe","Lemur");
    
    List<String> list = nameStrs.stream()
            .filter(s -> s.startsWith("L"))
            .map(String::toUpperCase)
            .sorted()
            .collect(toList());
    System.out.println(list);复制代码

这个例子完成的功能就是:首先使用stream()函数将数组转换为管道流,而后对管道流中的元素进行过滤filter(),只保留L开头的元素,而后对每个元素转换为大写(map(String::toUpperCase)),而后排序sorted(),最终转换为List类型。通过处理以后的输出结果是: [LEMUR, LION].在上面的例子中,filter()、map()、sorted()都属于中间数据处理操做,下面就给你们讲解一下这些函数的详细用法。编程

2、filter管道数据过滤

根据笔者的的经验,filter()是Stream API最有用的操做之一,它能够过滤掉不符合条件的元素。下面的代码过滤掉管道中的不是以L开头的字符串元素。处理完成以后,管道中剩下的元素是:[Lion, Lemur]数组

Stream<String> startsWithT = Stream.of("Monkey", "Lion", "Giraffe", "Lemur")
     .filter(s -> s.startsWith("L"));复制代码

若是没有学过lambda表达式的同窗,可能对上面的代码感到困惑。其实很简单,lambda表达式用来表达函数,箭头左侧是参数,箭头右侧是函数体。函数的参数类型和返回值类型,会根据上下文作自动化的判断,不用你管。上文中的lambda表达式写成函数是这样的springboot

public static boolean filterUpperL(String str){
        return str.startsWith("L");
    }
    
    //.filter(BootLaunchApplicationTests::filterUpperL)复制代码

我甚至见过有的人排斥使用lambda表达式,说这种语法使代码的可读性降低。这个怎么说呢,若是一篇专业期刊中包含英语专业名词与引用,而读者恰巧不会英语就不想读了,我以为这不是文章的问题,而是读者的问题。并且lamdba表达式在各类编程语言里面获得普遍的使用,提升编码效率。其实很简单:箭头左侧是参数,箭头右侧是函数体,你已经学会了!编程语言

3、Limit与Skip管道数据截取

Stream<String> startsWithT = Stream.of("Monkey", "Lion", "Giraffe", "Lemur").limit(2);
     Stream<String> startsWithT = Stream.of("Monkey", "Lion", "Giraffe", "Lemur").skip(2);复制代码

  • limt方法传入一个整数n,用于截取管道中的前n个元素。通过管道处理以后的数据是:[Monkey, Lion]。
  • skip方法与limit方法的使用相反,用于跳过前n个元素,截取从n到末尾的元素。通过管道处理以后的数据是: [Giraffe, Lemur]

4、Distinct元素去重

咱们还可使用distinct方法对管道中的元素去重,涉及到去重就必定涉及到元素之间的比较,distinct方法时调用Object的equals方法进行对象的比较的,若是你有本身的比较规则,能够重写equals方法。函数式编程

Stream<String> uniqueAnimals = Stream.of("Monkey", "Lion", "Giraffe", "Lemur", "Lion")
            .distinct();复制代码

上面代码去重以后的结果是: ["Monkey", "Lion", "Giraffe", "Lemur"]函数

5、Sorted排序

默认的状况下,sorted是按照字母的天然顺序进行排序。以下代码的排序结果是:[Giraffe, Lemur, Lion, Monkey],字数按顺序G在L前面,L在M前面。第一位没法区分顺序,就比较第二位字母。学习

Stream<String> alphabeticOrder = Stream.of("Monkey", "Lion", "Giraffe", "Lemur")
            .sorted();复制代码

有的时候,咱们但愿排序的规则可以自定义,这就须要使用到Comparator。有的朋友这里可能忘了,能够自行回顾一下java基础的Comparator和Comparable接口。下面的代码是根据字符串的长度排序,排序结果是:[Lion, Lemur, Monkey, Giraffe]编码

Stream<String> lengthOrder = Stream.of("Monkey", "Lion", "Giraffe", "Lemur")
            .sorted(Comparator.comparing(String::length));复制代码

6、Map数据转换处理

map()函数的做用是将管道流中的每个元素,以某种规则转换为另一个元素。下面代码处理过的管道中的元素为: [monkey, lion, giraffe, lemur],全部元素的字母所有小写。

Stream<String> lowerCase = Stream.of("Monkey", "Lion", "Giraffe", "Lemur")
            .map(String::toLowerCase);
    
    //这两种写法的实现效果是同样的,一个是lambda表达式,一个是函数引用的方式
    Stream<String> lowerCase = Stream.of("Monkey", "Lion", "Giraffe", "Lemur")
            .map(s -> s.toLowerCase());复制代码

map()函数不只能够处理数据,还能够转换数据的类型。以下:

IntStream lengths = Stream.of("Monkey", "Lion", "Giraffe", "Lemur")
            .mapToInt(String::length);复制代码

上面代码的处理结果是:[6, 4, 7, 5],规则是字符串的长度。将管道流的字符串,使用mapToInt方法,以String::length为规则进行转换。固然除了mapToInt,还为咱们提供了mapToDouble()和mapToLong()方法。咱们能够经过自定义转换规则函数,返回int、double、long类型的返回值。

期待您的关注

相关文章
相关标签/搜索