JDK8特性函数式接口与Stram流

函数式接口

函数式接口,一般java中一个接口中只有一个方法就可以被认为是函数式接口,用于契合jdk8中的lamda的
在jdk用也有很多函数式接口,比如典型的Runable和Comparable等接口都是函数式接口
jdk1.8中约定函数式接口的接口上要加@FunctionalInterface注解,这个不是必须的,Comparable就没有这个注解,这个注解的意义只起约定作用,如果你在设计接口时候加上这个注解,倘若你要新加方法,这个注解就会爆红,表示这是一个函数式约定的接口,你的方法数量不能不等于1
开发中加入这个注解的意义就是提醒开发者,不要去给这个接口添加方法了

一、JDK8中的新函数式接口

为了方便之后的Stream流的使用,jdk8是新加了4个函数式接口,灵活使用这四个接口将会简化开发,美化代码,不得不说官方的设计给我们了不少设计上的启发

生产接口Supplier

java.util.function.Supplier< T >
接口包含一个无参的方法:T get();用来获取一个泛型参数指定类型的对象数据
这个接口也被称之为生产型接口,指定接口的泛型是什么,就返回什么类型的数据
泛型中可以指定需要生产的类型

public class Demo01Supplier{public static void main(String[] args) {System.out.println(getSupplier(()->"我自己"));//这里生产了一个字符串}public static String getSupplier(Supplier<String> supplier) {return supplier.get();}
}
消费接口Consumer

java.util.function.Consumer< T >
接口包含一个默认方法和一个accept(T t)方法,accept是用来消费传入的规定泛型的对象
这个接口也被称之为消费型接口,指定一个泛型,自定义处理这个泛型对象的逻辑,来消费这个对象
Consumer的默认方法:AndThen 连接两个消费式接口,可以连接很多个
例:
Consumer< String > c1;
Consumer< String > c2;
c1.AndThen(c2).accept(String);
先执行前面的消费式接口

public class Demo02Consumer {public static void main(String[] args) {acceptConsumer("迪丽热巴", (name)->System.out.println(new StringBuilder(name).reverse().toString()));//将输入的字符串反转然后打印到控制台AndThenConsumer("迪丽热巴",(name)->System.out.println(name),(name)->System.out.println(new StringBuilder(name).reverse().toString()));//将输入的字符串先打印一边,然后再反转再打印一遍String[] arr= {"迪丽热巴,女","古力娜扎,女","马尔扎哈,男"};AndThenConsumer(arr,(string)->{String ar=string.split(",")[0];System.out.print("姓名:"+ar+"    ");},(string)->{String ar=string.split(",")[1];System.out.println("性别:"+ar);});//两次处理后 输出的样子是 姓名:迪丽热巴 &nbsp; 性别:女,然后一行一行打印}public static void acceptConsumer(String name,Consumer<String> con) {//对字符串做消费con.accept(name);}public static void AndThenConsumer(String name,Consumer<String> c1,Consumer<String> c2) {//对字符串做两次消费c1.andThen(c2).accept(name);}public static void AndThenConsumer(String[] name,Consumer<String> c1,Consumer<String> c2) {//对字符串数组做两次消费for (String string : name) {c1.andThen(c2).accept(string);}}
}
断言接口Predicate

java.util.function.Predicate< T >
作用:对某种数据类型的数据进行判断,结果返回一个布尔值
这个接口被叫做断言式接口,主要用于对对象的筛选判断,形式类似于junit中的断言
接口中的一个抽象方法:
boolean test(T t)
符合返回true
不符合返回false
接口中的一个默认方法:
and
p1.and(p2).test(T t);
相当于&&,同时满足返回true,可多个and
接口中的另一个默认方法:
p1.or(p2).test(T t);
相当于||,同时不满足返回false
这里就不代码实现了!
接口中的最后一个默认方法:
p1.negate().test(T t);
相当与!,就是非的意思,不满足就返回true,注意!这里并不是两个断言
接口中还有一个静态方法:
isEqual

public class Demo03Predicate {public static void main(String[] args) {String ar="abcdfe";System.out.println(TestPredicate(ar, (str)->str.length()>=6));//字符串长度是否大于等于6   System.out.println(AndTestPredicate(ar, (str)->str.length()>3,(str)->str.contains("a")));//判断长度大于3且包含字符串"a"System.out.println(NegateTestPredicate(ar,(str)->str.length()>3));//长度大于3返回false}public static boolean TestPredicate(String str,Predicate<String> pre) {//testreturn pre.test(str);}public static boolean AndTestPredicate(String str,Predicate<String> p1,Predicate<String> p2) {//andreturn p1.and(p2).test(str);}public static boolean NegateTestPredicate(String str,Predicate<String> pre) {//negatereturn pre.negate().test(str);}
}
转换类型接口Function

java.util.function< T , R >
这个接口用来根据一个类型的数据得到另一个类型的数据。前者为前置条件,后者为后置条件
Function中的最重要的抽象方法为:
R apply(T t),根据T类型的参数获取类型R的结果
使用场景例如:
将String类型转换成Integer类型
Function中的默认方法为
f1.AndThen(f2).apply(T t)

Function中的默认方法identity,用来查看原来是什么类型的

public class Demo04Function {public static void main(String[] args) {String b="赵丽颖,20";String a = "123456";System.out.println(ApplyFunction(a, (s) -> Integer.parseInt(s)));/*将String转成Integer然后给数值减10000再转换回来*/System.out.println(AndThenApplyFunction(a,(s)->Integer.parseInt(s)-10000,(s)->String.valueOf(s)));/*将字符串b分割,取后面的20转成Integer,然后在返回其-2*/System.out.println(FT(b,(s)->b.split(",")[1],(s)->Integer.parseInt(s),(s)->s-2));}public static Integer ApplyFunction(String s, Function<String, Integer> f) {return f.apply(s);}public static String AndThenApplyFunction(String s, Function<String, Integer> f1, Function<Integer, String> f2) {return f1.andThen(f2).apply(s);}public static Integer FT(String s,Function<String,String> f1,Function<String,Integer> f2,Function<Integer,Integer> f3) {//注意每一个Function的泛型return f1.andThen(f2.andThen(f3)).apply(s);}
}

二、Stream流

Stream流属于管道流,用一次就关闭,所以没必要用对象接收流
注意:Stream流最大好处是IO操作大文件时不会内存溢出

Stream流中的终结方法:所有方法最后都要以终结方法作为结尾forEach(Consumer(<? super T> action);long count();这也是终结方法,返回元素个数
Stream流中的过滤方法:filter(Predicate(<? super T> predicate));使用Predicate中的方法test判断筛选过滤
Stream流中的映射方法:map(Function<T,R> fun);将一个一种类型转换成另一种类型数据
Stream流中截取前n个元素的方法:Stream<T> limit(long l);
Stream流中的跳过方法:Stream<T> skip(long l);跳过前l个元素,将后面的元素创建一个新的Stream流
Stream流中的合并方法:Stream<T> Stream.concat(Stream<? extends T> s1,Stream<? extends T> s2)

注意:一下代码中的of作用是返回其元素为指定值的顺序有序流对流进行操作

@SafeVarargs
@SuppressWarnings("varargs") //从arrays创建一个流是安全的
public static<T> Stream<T> of(T... values) {return Arrays.stream(values);
}

我们在使用stream流时也不用每次都of一个对象,要注意下面两点

  • Collection< T >集合中有.stream方法,可以创建一个Stream流对象
  • Map< T , T >集合中没有.stream方法,需要间接导入
public class StreamInMethod {public static void main(String[] args) {Stream.of("张三","李四","王五","赵六").forEach(s->System.out.print(s+" "));//forEach终结方法System.out.println();Stream.of("张三","李四","王五","赵六").filter(s->s.startsWith("张"))//filter过滤方法.forEach(s->System.out.println(s));Stream.of("1","2","3","4").map(s->Integer.parseInt(s))//map映射方法.forEach(s->System.out.print(s+"    "));System.out.println();System.out.println(Stream.of("1","2","3","4").count());//count终结方法,返回longStream.of("1","2","3","4").limit(2).forEach(s->System.out.print(s+"  "));//limit截取方法System.out.println();Stream.of("1","2","3","4").skip(2).forEach(s->System.out.print(s+"    "));//skip跳过方法System.out.println();Stream.concat(Stream.of("我","你"), Stream.of("1","2")).forEach(s->System.out.print(s+"  "));//concat合并方法}
}

个人想法

我感觉在使用这些函数式接口的连用方法时,我们的需求是需要一个流程化的操作,如果中途出现了异常,那可能将会对原有数据进行改动,并且并没有完成剩余逻辑,导致出现问题,这样的方法执行是不满足原子性的(看你的需求),当我们要解决这种中途exception时候,只能在流程中对参数操作的每一步进行筛选判断,或者设置回滚策略,设计的时候也要多考虑一下这样的可能性

JDK8特性函数式接口与Stram流相关推荐

  1. jdk8新特性(接口新特性、lambda表达式、方法引用、函数式接口、Stream流)和单例设计模式

    1.单例设计模式 1.概念: 设计模式:使用固有的流程或方式设计出来的类接口.枚举等元素 2.设计原则: 1.私有化构造方法[private.protected] 2.类中创建最终对象[唯一不能被赋值 ...

  2. JDK8中的新特性——函数式接口

    JDK8 简介 概述 Java 8由Oracle从2014年3月18日发布,此版本是自Java 5(发布于2004年)之后的一个重量级版本,也是java发展史上的一个里程碑式的版本.这个版本在JVM. ...

  3. 学习笔记之-java8的新特性-函数式接口,lambda表达式,方法引用,Stream API,Optional类

    1.Lambda表达式 用匿名内部类的方法去创建多线程1.new Thread2.参数传递new Runnable3.重写run方法4.在run方法中去设置线程任务5.调用start问题:我们最终目标 ...

  4. java8新特性_乐字节-Java8新特性-函数式接口

    上一篇小乐带大家学过 Java8新特性-Lambda表达式,那什么时候可以使用Lambda?通常Lambda表达式是用在函数式接口上使用的.从Java8开始引入了函数式接口,其说明比较简单:函数式接口 ...

  5. java8 interface_Java8新特性:函数式接口@FunctionalInterface使用说明

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

  6. 常用函数式接口及Stream流

    1.常用函数式接口 1.1Supplier接口 ​ 功能 ​ 生产型接口,接口的泛型指定成什么类型,就生产什么类型的数据(提供函数式接口,方便使用Lambda进行简化代码) ​ 抽象方法 ​ T ge ...

  7. 函数式接口和Stream流式思想

    函数式接口和Stream 1. 函数式接口 1.1 函数式接口概述 利用接口操作语法格式,对于方法的声明作出二次封装!!!方法声明:权限修饰符 是否静态 返回值类型 方法名(形式参数列表);对于接口而 ...

  8. 常用函数式接口,Stream流

    01.第一章:常用函数式接口_Predicate判断接口: 1).java.util.Function.Prdedicate(函数式接口): 2).抽象方法:1).boolean test(T t) ...

  9. [jdk8]Predicate 函数式接口

    如何理解里面的and/or等函数 default Predicate<T> and(Predicate<? super T> other) {Objects.requireNo ...

最新文章

  1. 定时器0工作方式1,定时1s
  2. oracle utl_smtp 500 bad syntax,改进oracle utl_mail包的smtp_server设定和密码验证不足
  3. python爬虫电商京东_python爬虫-京东商品爬取
  4. java 多线程监听同一个端口_使用多线程在Java服务器中同时侦听两个端口
  5. 阿里资深技术专家:如何快速成长为技术大牛?
  6. 安装mysql显示有5.0_安装MySQL5.0时到如图这一步提示出错了,~
  7. C++存储区域基础概念详解
  8. python写算法求最短路径,Python实现迪杰斯特拉算法并生成最短路径的示例代码
  9. 计算机编程与数控宏程序实例教程,数控车床编程教程,图文实例详解
  10. 同花顺程序交易接口type-c为什么没普及?
  11. 新元宇宙奇科幻小说原创作品每周连载地球人奇游天球记第六回冬奥登月
  12. Java温习——SUN公司和Java平台
  13. 【概率论】二项分布 Binomial Distribution
  14. Linux系统 D2L 安装
  15. 培训机构出来的程序员进不了大厂?
  16. 室内设计软件除了常用的几款还有7…
  17. 面试官:useLayoutEffect和useEffect的区别
  18. Ubuntu下使用ipmsg(飞鸽传书)
  19. mysql数据给mes_PLC通讯智能网关:MES服务对接,SQL数据库双向通讯,HTTP协议GET/POST请求,MQTT协议JSON发布/订阅...
  20. C# 调整Word页眉页脚的位置高度

热门文章

  1. 毕业设计 - 基于Java web的旅游系统设计【源码+论文】
  2. Ae 表达式语言引用​:Global
  3. 使用“微pe工具”制作pe启动盘,安装纯净系统
  4. 1091: 童年生活二三事(多实例测试) ZZULIOJ
  5. 那些在《JavaEE开发的颠覆者 Spring Boot实战》中遇到的坑,,。(二)
  6. Maven的工作流程和原理
  7. Github无法打开
  8. Oracle Enqueue Lock Type Reference including 11g new locks
  9. 什么是网络安全等保制度
  10. 图片转文字软件哪个好?快把这些软件收好