3.Consumer接口

java.util.function.Consumer 接口则正好与Supplier接口相反,它不是生产一个数据,而是消费一个数据,其数据类型由泛型决定

抽象方法:accept
Consumer 接口中包含抽象方法 void accept(T t) ,意为消费一个指定泛型的数据。基本使用如:

package com.wjl.test;import java.util.function.Consumer;/*** Consumner接口* @author wjl**/
public class Demo6Consumer {private static void consumerString(Consumer<String> function) {function.accept("Hello");}public static void main(String[] args) {consumerString(s ->System.out.println(s));}
}

当然,更好的写法是使用方法引用

默认方法:andThen

如果一个方法的参数和返回值全都是 Consumer 类型,那么就可以实现效果:消费数据的时候,首先做一个操作,然后再做一个操作,实现组合。而这个方法就是 Consumer 接口中的default方法 andThen 。下面是JDK的源代码

    default Consumer<T> andThen(Consumer<? super T> after) {Objects.requireNonNull(after);return (T t) -> { accept(t); after.accept(t); };}
备注: java.util.Objects 的 requireNonNull 静态方法将会在参数为null时主动抛出
NullPointerException 异常。这省去了重复编写if语句和抛出空指针异常的麻烦。

要想实现组合,需要两个或多个Lambda表达式即可,而 andThen 的语义正是“一步接一步”操作。例如两个步骤组合的情况:

package com.wjl.test;
import java.util.function.Consumer;
public class Demo7ConsumerAndThen {private static void consumerString(Consumer<String> one,Consumer<String> two) {one.andThen(two).accept("Hello");}public static void main(String[] args) {consumerString(s->System.out.println(s.toUpperCase()),s->System.out.println(s.toLowerCase()));}
}

运行结果将会首先打印完全大写的HELLO,然后打印完全小写的hello。当然,通过链式写法可以实现更多步骤的组合。

格式化打印信息
下面的字符串数组当中存有多条信息,请按照格式“ 姓名:XX。性别:XX。 ”的格式将信息打印出来。要求将打印姓名的动作作为第一个 Consumer 接口的Lambda实例,将打印性别的动作作为第二个 Consumer 接口的Lambda实例,将两个 Consumer 接口按照顺序“拼接”到一起。

package com.wjl.test;import java.util.function.Consumer;public class Demo8Printinfo {private static void printInfo(Consumer<String> one,Consumer<String> two,String[] array) {for(String info:array) {one.andThen(two).accept(info);}}public static void main(String[] args) {String[] array = { "迪丽热巴,女", "古力娜扎,女", "马尔扎哈,男" };printInfo(s->System.out.print("姓名:"+s.split(",")[0]),s->System.out.println(" 性别:"+s.split(",")[1]), array);}
}

输出
姓名:迪丽热巴 性别:女
姓名:古力娜扎 性别:女
姓名:马尔扎哈 性别:男

4.Predicate接口

有时候我们需要对某种类型的数据进行判断,从而得到一个boolean值结果。这时可以使用java.util.function.Predicate 接口。

抽象方法:test
Predicate 接口中包含一个抽象方法: boolean test(T t) 。用于条件判断的场景:

package com.wjl.test;import java.util.function.Predicate;public class Demo9Predicate {private static void method(Predicate<String> predicate) {boolean isLong=predicate.test("Helloworld");System.out.println("字符串很长吗?"+isLong);}public static void main(String[] args) {method(s->s.length()>5);}
}

条件判断的标准是传入的Lambda表达式逻辑,只要字符串长度大于5则认为很长。

默认方法:and
既然是条件判断,就会存在与、或、非三种常见的逻辑关系。其中将两个 Predicate 条件使用“”逻辑连接起来实现“并且”的效果时,可以使用default方法 and 。其JDK源码为

    default Predicate<T> and(Predicate<? super T> other) {Objects.requireNonNull(other);return (t) -> test(t) && other.test(t);}

如果要判断一个字符串既要包含大写“H”,又要包含大写“W”,那么:

package com.wjl.test;import java.util.function.Predicate;public class Demo10PredicateAnd {private static void method(Predicate<String> one,Predicate<String> two) {boolean isValid=one.and(two).test("Helloworld");System.out.println("是否包含H和W:"+isValid);}public static void main(String[] args) {method(s->s.contains("H"),s->s.contains("W"));}
}

输出结果

是否包含H和W:false

默认方法:or
与 and 的“与”类似,默认方法 or 实现逻辑关系中的“或”。JDK源码为:

    default Predicate<T> or(Predicate<? super T> other) {Objects.requireNonNull(other);return (t) -> test(t) || other.test(t);}

如果希望实现逻辑“字符串包含大写H或者包含大写W”,那么代码只需要将“and”修改为“or”名称即可,其他都不变。

默认方法:negate
“与”、“或”已经了解了,剩下的“非”(取反)也会简单。默认方法 negate 的JDK源代码为:

    default Predicate<T> negate() {return (t) -> !test(t);}

从实现中很容易看出,它是执行了test方法之后,对结果boolean值进行“!”取反而已。一定要在 test 方法调用之前调用 negate 方法,正如 and 和 or 方法一样:

package com.wjl.test;import java.util.function.Predicate;public class Demo11PredicateNegate {private static void method(Predicate<String> predicate) {boolean isLong=predicate.negate().test("Helloworld");System.out.println("字符串很长吗:"+isLong);}public static void main(String[] args) {method(s->s.length()<5);}
}

输出

字符串很长吗:true

集合信息筛选

数组当中有多条“姓名+性别”的信息如下,请通过 Predicate 接口的拼装将符合要求的字符串筛选到集合
ArrayList 中,需要同时满足两个条件:

  1. 必须为女生;
  2. 姓名为4个字
package com.wjl.test;import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;public class Demo12Predicate {private static List<String> filter(String[] array,Predicate<String> one ,Predicate<String> two) {List<String> list=new ArrayList<>();for (String info : array) {if(one.and(two).test(info)) {list.add(info);}}return list;}public static void main(String[] args) {String[] array = { "迪丽热巴,女", "古力娜扎,女", "马尔扎哈,男", "赵丽颖,女" };List<String> list = filter(array,s->"女".equals(s.split(",")[1]), s->s.split(",")[0].length()==4);System.out.println(list);}
}

5.Function接口

java.util.function.Function<T,R> 接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件

抽象方法:apply
Function 接口中最主要的抽象方法为: R apply(T t) ,根据类型T的参数获取类型R的结果。使用的场景例如:将 String 类型转换为 Integer 类型

package com.wjl.test;import java.util.function.Function;public class Demo13Function {private static void method(Function<String, Integer> function) {int num=function.apply("100");System.out.println(num+20);}public static void main(String[] args) {method(s->Integer.parseInt(s));//Lambda表达式method(Integer::parseInt);//方法引用的写法}
}

默认方法:andThen
Function 接口中有一个默认的 andThen 方法,用来进行组合操作。JDK源代码如

    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {Objects.requireNonNull(after);return (T t) -> after.apply(apply(t));}

该方法同样用于“先做什么,再做什么”的场景,和 Consumer 中的 andThen 差不多:

package com.wjl.test;import java.util.function.Function;public class Demo14FunctionAndThen {private static void method(Function<String, Integer> one,Function<Integer, Integer> two) {int num=one.andThen(two).apply("10");System.out.println(num+20);}public static void main(String[] args) {method(str->Integer.parseInt(str)+10, i->i*=10);//220  第一个20 第二个20*10=200  andThen 220}
}

JDK8新特性—常用函数式接口相关推荐

  1. JDK8新特性之函数式接口

    转载自 JDK8新特性之函数式接口 什么是函数式接口 先来看看传统的创建线程是怎么写的 Thread t1 = new Thread(new Runnable() {@Overridepublic v ...

  2. JDK8新特性:函数式接口@FunctionalInterface的使用说明

    我们常用的一些接口Callable.Runnable.Comparator等在JDK8中都添加了@FunctionalInterface注解. 通过JDK8源码javadoc,可以知道这个注解有以下特 ...

  3. 【Java】JDK8新特性之函数式接口

    原文:http://www.javastack.cn/article/2017/jdk8-new-feature-functional-interface/ 什么是函数式接口 先来看看传统的创建线程是 ...

  4. jdk8 新特性之 函数式接口

    一.函数式接口说明 1.函数式接口条件 (1).只包含一个抽象方法的接口,称为函数式接口. (2).你可以通过Lambda表达式来创建该接口的对象.(若Lambda表达式抛出一个受检异常,那么该异常需 ...

  5. JAVA8的新特性之函数式接口

    JAVA8的新特性之函数式接口 1.Lambda表达式使用的前提,就是接口必须是一个函数式接口 2.定义 在接口中,只有一个抽象方法 3.检查是否是函数式接口用的注解 @FunctionalInter ...

  6. 【JavaSE】JDK新特性(二)————接口新特性,函数式接口(Suppier,Comsumer,Predicate,Function)

    文章目录 1.接口新特性 1.1 接口组成更新概述 1.2 接口中的默认方法 1.3 接口中的静态方法 1.4 接口中的私有方法 2. 函数式接口 2.1 函数式接口概述 2.2 函数式接口作为方法的 ...

  7. JDK1.8新特性:函数式接口

    文章目录 函数式接口 函数式接口概念 @FunctionalInterface 函数式接口使用方式 常用函数式接口 Supplier Comsumer Predicate Function 常用函数式 ...

  8. JDK1.8新特性之函数式接口

    函数式接口 ​ 函数式接口在java指定的是:有且仅有一个抽象方法的接口就称为函数式接口. ​ 函数式接口,设用于函数式编程的,在java当中的函数式编程体现在Lambda,所以函数式接口就是用来服务 ...

  9. Java8新特性之函数式接口,呦呦呦

    什么时候可以使用 Lambda?通常 Lambda 表达式是用在函数式接口上使用的.从 Java8 开始引入了函数式接口,其说明比较简单:函数式接口(Functional Interface)就是一个 ...

最新文章

  1. JDK源码分析 NIO实现
  2. grub error:unknown filesystem的解决方案
  3. Node.js Stream - 基础篇
  4. php 常用rpc框架,php的轻量级rpc框架yar
  5. .net2.0 orm_Java 8:深入研究速度3.0.1“森林”流ORM
  6. android 远程下载与pull解析技术
  7. linux 日文 字体,安装Fedora 11的程序用的竟然是日文字体?!
  8. 使用DevExpress.XtraTabbedMdi.XtraTabbedMdiManager控件来加载MDI窗体
  9. 百度AI市场MYNT EYE小觅双目摄像机开箱试用全记录
  10. 区分计算机和服务器的内存条,AMD专用内存是什么意思 AMD专用内存和普通内存条的区别及真相...
  11. layui表格(table)排序
  12. 论如何进行培养独立解决问题的能力
  13. Android 和 H5 交互-框架篇
  14. Spring Cloud Task 主要是干什么的啊?跟 Quartz 和 Spring Task 有啥关系?
  15. 【苹果推iMessage】软件安装命令打开工程: open ios/AwesomeProject.xcodeproj
  16. python嵌入式怎么学_怎么自学嵌入式?
  17. 如何构建一个从创意出发的工作室
  18. 巴塔机器人_《超级机器人大战V》全SR流程攻略
  19. 大学物理实验计算机仿真 光电效应,光电效应仿真实验的教学探究
  20. Asp net实现下拉框和列表框的连动

热门文章

  1. 针对宽带拨号错误代码及解决方法
  2. FS_S5PC100平台上Linux Camera驱动开发详解(二)
  3. Lua脚本快速上手(附示例程序代码)
  4. 解决idea运行Tomcat报错:Unable to ping server at localhost:1099
  5. org.activiti.engine.ActivitiIllegalArgumentException: inputStream for resource '**' is null 的解决办法
  6. 中国五个城市(北上广、成都、沈阳)PM 2.5含量分析
  7. linux下串口设备文件,linux下各种串口调试助手
  8. Java基于springboot+vue的房屋出租租房系统 前后端分离
  9. 《CMOS集成电路后端设计与实战》——导读
  10. c语言int作用,c语言中int的用法有哪些