Java—Java 8 新增特性详解(Predicate和Stream)

Predicate接口

Predicate接口介绍

??Predicate是函数式接口,可以使用Lambda表达式作为参数。Java 8为集合Collection新增了removeIf(Predicate filter)方法,可以批量删除符合filter条件的所有元素。

Predicate接口使用范例

测试Collection的removeIf()方法。

示例1

1)运行类:

public class DemoApplication {

    public static void main(String[] args) {

        // 创建集合
        Collection collection = new HashSet();

        // 添加元素
        collection.add("book01");
        collection.add("book02");
        collection.add("book03");
        collection.add("b05");
        collection.add("b06");

        Collection collectionNew = new HashSet();
        // 使用Lambda表达式遍历传入新的集合
        collection.forEach(str -> collectionNew.add(str));
        System.out.println("collectionNew: " + collectionNew);

        // 使用Lambda表达式进行过滤(目标类型是Predicate)
        collection.removeIf(filter -> ((String)filter).length() < 5);

        // 使用Lambda表达式遍历打印
        collection.forEach(str -> System.out.println(str));

        }
}

2)运行结果:

collectionNew: [book02, book01, b05, book03, b06]
book02
book01
book03

??从上述结果中,我们可以看到调用Collection集合的removeIf()方法,可以批量过滤符合条件长度小于5的集合元素,程序是传入一个Lambda表达式进行过滤:collection.removeIf(filter -> ((String)filter).length() < 5);

示例2

使用Predicate接口的boolean test(T t);方法

1)创建工具类:

import java.util.Collection;
import java.util.function.Predicate;

/**
 * @author andya
 * @create 2020-03-24 14:08
 */
public class PredicateUtil {
    public static int countCollectionElement(Collection collection, Predicate predicate){
        int total = 0;
        for (Object object : collection) {
            //通过Predicate的test()方法判断对象是否满足过滤条件
            if (predicate.test(object)) {
                total ++;
            }
        }

        return total;
    }
}

2)运行类:

public class DemoApplication {

    public static void main(String[] args) {

        // 创建集合
        Collection collection = new HashSet();

        // 添加元素
        collection.add("book_java编程思想");
        collection.add("book_c++核心技术");
        collection.add("book_java核心技术");
        collection.add("book_计算机网络");
        collection.add("book01");
        collection.add("book02");

        Collection collectionNew = new HashSet();
        // 使用Lambda表达式遍历传入新的集合
        collection.forEach(str -> collectionNew.add(str));
        System.out.println("collectionNew: " + collectionNew);

        System.out.println("包含java关键字的个数:" +
                PredicateUtil.countCollectionElement(collection, ele -> ((String)ele).contains("java")));
        System.out.println("长度小于7的个数:" +
                PredicateUtil.countCollectionElement(collection, ele -> ((String)ele).length() < 7));
        System.out.println("以book_为前缀的个数:" +
                PredicateUtil.countCollectionElement(collection, ele -> ((String)ele).startsWith("book_")));
        }
}

3)运行结果:

collectionNew: [book02, book01, book_java编程思想, book_java核心技术, book_计算机网络, book_c++核心技术]
包含java关键字的个数:2
长度小于7的个数:2
以book_为前缀的个数:4

??定义了一个countCollectionElement()方法,使用Predicate动态传参,判断每个集合元素是否符合过滤条件。

Stream流式接口

Stream流式接口介绍

??Java 8新特性中还增加了流式处理,如Stream,IntStream,DoubleStream,LongStream等API。每个流式API还提供了对应的Builder,如Stream.Builder、IntStream.Builder、DoubleStream.Builder、LongStream.Builder。

Stream使用步骤

  1. 通过Stream等API的builder()类方法去创建Stream对应的Builder类;
  2. 调用Builder的add()方法向流中添加多个元素;
  3. 调用Builder的build()方法获取对应的Stream;
  4. 调用Stream聚集方法;

Stream使用示例

public class DemoApplication {

    public static void main(String[] args) {

        //通过xxxStream的builder()方法去创建Builder
        IntStream intStream = IntStream.builder()
                .add(1)
                .add(-2)
                .add(3)
                .add(10)
                .build();

        // 聚集方法(每次只能使用其中一条去执行,其他代码需注释,否则会报错)
        System.out.println("intStream的元素最大值是: " + intStream.max().getAsInt());
        System.out.println("intStream的元素最小值是: " + intStream.min().getAsInt());
        System.out.println("intStream的元素平均值是: " + intStream.average());
        System.out.println("intStream的元素总和是: " + intStream.sum());
        System.out.println("intStream的元素个数是: " + intStream.count());
        System.out.println("intStream是否包含任何元素平方大于10: "
                + intStream.anyMatch(ele -> ele * ele > 10));
        System.out.println("intStream的所有元素立方是否大于10: "
                + intStream.allMatch(ele -> ele * ele * ele > 10));

        // 每个元素都加1后映射成新的Stream
        IntStream intStreamNew = intStream.map(ele -> ele + 1);
        intStreamNew.forEach(ele -> System.out.println(ele));
        }
}

运行结果:将上述聚集方法所有执行结果放在一个里面进行展示,其实只能执行一条;

intStream的元素最大值是: 10
intStream的元素最小值是: -2
intStream的元素平均值是: OptionalDouble[3.0]
intStream的元素总和是: 12
intStream的元素个数是: 4
intStream是否包含任何元素平方大于10: true
intStream的所有元素立方是否大于10: false
2
-1
4
11

在上述示例中存在两种聚集方法:“中间方法”和“末端方法”。

  • 中间方法:中间操作允许流保持打开状态,并允许直接调用后续方法,如map()方法,返回值为另一个流;
  • 末端方法:末端方法是对流进行的最终操作,如sum()方法执行后,流就不可用,如果再用会报错Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed

Stream的常用方法

中间方法

  • filter(Predicate predicate):过滤Stream中不符合predicate过滤条件的元素。
  • mapToXxx(ToXxxFunction mapper):使用ToXxxFunction对流中的元素执行一对一的转换,方法返回的是新流中包含了ToXxxFunction转换生成的所有元素。
  • peek(Consumer action):依次操作每个元素,返回的流与原有流包含相同的元素,用于调试。
  • distinct():用于排序流中所有重复的元素,有状态的方法;
  • sorted():用于保证流中的元素在后续的访问中处于有序状态,也是有状态的方法。
  • limit(long maxSize):用于保证对该流的后续访问中最大允许访问的元素个数,是一个有状态的、短路方法。

末端方法

  • forEach(Consumer action):遍历流中所有元素,执行action。
  • toArray():将流中所有元素转换成一个数组。
  • reduce():用于某个操作合并流中元素。
  • min():返回流中元素的最小值。
  • max():返回流中元素的最大值。
  • sum():返回流中元素的总和。
  • count():返回流中所有元素的数量。
  • anyMatch(Predicate predicate):判断流中是否至少包含一个元素符合predicate过滤条件。
  • allMatch(Predicate predicate):判断流中是否所有元素符合predicate过滤条件。
  • noneMatch(Predicate predicate):判断流中是否所有元素都不符合predicate过滤条件。
  • findFirst():返回流中的第一个元素。
  • findAny():返回流中的任意一个元素。

原文地址:https://www.cnblogs.com/Andya/p/12560672.html

时间: 2024-08-01 07:04:14

Java—Java 8 新增特性详解(Predicate和Stream)的相关文章

【转】C#各个版本中的新增特性详解

转自:http://www.cnblogs.com/knowledgesea/p/6694979.html 序言 自从2000年初期发布以来,c#编程语言不断的得到改进,使我们能够更加清晰的编写代码,也更加容易维护我们的代码,增强的功能已经从1.0搞到啦7.0甚至7.1,每一次改过都伴随着.NET Framework库的相应支持,也不断的带给我们期待与惊喜.下面我们就对c#一路走到现在,做一个回顾与学习. C#语言目标与前行 c#的设计目标是有以下几点: 旨在是一种简单,现代,通用的面向对象编程

Java8特性详解 lambda表达式 Stream

1.lambda表达式 Java8最值得学习的特性就是Lambda表达式和Stream API,如果有python或者javascript的语言基础,对理解Lambda表达式有很大帮助,因为Java正在将自己变的更高(Sha)级(Gua),更人性化.--------可以这么说lambda表达式其实就是实现SAM接口的语法糖. lambda写的好可以极大的减少代码冗余,同时可读性也好过冗长的内部类,匿名类. 先列举两个常见的简化(简单的代码同样好理解) 创建线程 排序 lambda表达式配合Jav

【PHP系列】PHP 7.0新增特性详解

开始介绍PHP7.0新特性,具体的可以参照官网的介绍,我来挑一些给大家详细讲解下 http://php.net/manual/en/migration70.new-features.php 1. ?? 运算符(NULL 合并运算符) $a = $_GET['a'] ?? 1; 它相当于: $a = empty($_GET['a']) ? 1 : $_GET['a']; 我们知道三元运算符是可以这样用的: $a ?: 1 但是这是建立在 $a 已经定义了的前提上.新增的 ?? 运算符可以简化判断.

MySQL 8.0新增特性详解

1. MySQL8.0的版本历史 2016-09-12第一个DM(development milestone)版本8.0.0发布 2018-04-19第一个GA(General Availability)版本开始,8.0.11发布 2018-07-27 下一个GA版本,8.0.12发布 2018-10-22 下一个GA版本,8.0.13发布 2019-01-21 下一个GA版本,8.0.14发布 最新的GA版本为8.0.15,于2019-02-01发布 最近待GA的版本为8.0.16, 8.0.

Java垃圾回收机制(GC)详解

Java垃圾回收机制(GC)详解 简介: 垃圾回收GC(Garbage Collection)是Java语言的核心技术之一,之前我们曾专门探讨过Java 7新增的垃圾回收器G1的新特性,但在JVM的内部运行机制上看,Java的垃圾回收原理与机制并未改变.垃圾收集的目的在于清除不再使用的对象.GC通过确定对象是否被活动对象引用来确定是否收集该对象.GC首先要判断该对象是否是时候可以收集.两种常用的方法是引用计数和对象引用遍历. 垃圾收集的算法分析: Java语言规范没有明确地说明JVM使用哪种垃圾

Java下static关键字用法详解

Java下static关键字用法详解 本文章介绍了java下static关键字的用法,大部分内容摘自原作者,在此学习并分享给大家. Static关键字可以修饰什么? 从以下测试可以看出, static 可以修饰: 1. 语句块 2. 成员变量(但是不能修饰局部变量) 3. 方法 4. 接口(内部接口) 5. 类(只能修饰在类中的类, 即静态内部类) 6. jdk 1.5 中新增的静态导入 那么static 修饰的表示什么呢? 当创建一个类时,就是在创建一个新类型,描述这个类的对象的外观和行为,除

Java虚拟机之垃圾回收详解一

Java虚拟机之垃圾回收详解一 Java技术和JVM(Java虚拟机) 一.Java技术概述: Java是一门编程语言,是一种计算平台,是SUN公司于1995年首次发布.它是Java程序的技术基础,这些程序包括:实用程序.游戏.商业应用程序.在全世界范围内,Java运行在超过数十亿台个人计算机上,数十亿台设备上,还包括手机和电视设备.Java由一系列的关键组件作为一个整体构建出了Java平台. Java Runtime Edition 当你下载Java,你就得到了Java运行环境(JRE).JR

Java 8的default方法详解

Java 8的default方法详解 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs Java 8新增了default方法,它可以在接口添加新功能特性,而且还不影响接口的实现类.下面我们通过例子来说明这一点. public class MyClass implements InterfaceA { public static void main(String[] args){ } @Override public void saySomething(

Java网络编程和NIO详解开篇:Java网络编程基础

Java网络编程和NIO详解开篇:Java网络编程基础 计算机网络编程基础 转自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我们是幸运的,因为我们拥有网络.网络是一个神奇的东西,它改变了你和我的生活方式,改变了整个世界. 然而,网络的无标度和小世界特性使得它又是复杂的,无所不在,无所不能,以致于我们无法区分甚至无法描述. 对于一个码农而言,了解网络的基础知识可能还是从了解定义开始,认识OSI的七层协议模型,深入Socket内部,进而熟练地