【jdk1.8特性】之Function
笔者日常: 来吧,Function~
相关声明:
本文按照以下顺序进行说明并给出简单的使用示例:
序号 接口 1 Function<T, R> 2 IntFunction<R> 3 DoubleFunction<R> 4 LongFunction<R> 5 ToIntFunction<T> 6 ToLongFunction<T> 7 ToDoubleFunction<T> 8 IntToDoubleFunction 9 IntToLongFunction 10 LongToDoubleFunction 11 LongToIntFunction 12 DoubleToIntFunction 13 DoubleToLongFunction 14 BiFunction<T, U, R> 15 ToIntBiFunction<T, U> 16 ToLongBiFunction<T, U> 17 ToDoubleBiFunction<T, U> 先给出下文的示例中所涉及到的模型:
/*** 员工实体模型** @author JustryDeng* @date 2019/7/15 19:48*/ @Data @AllArgsConstructor @NoArgsConstructor @Builder public class Staff implements Serializable {/** 姓名 */private String name;/** 年龄 */private Integer age;/** 工号 */private String staffNo;}
Function<T, R>:
R apply(T t): 输入T类型的参数,运行相关逻辑后,返回R类型的结果。
使用示例:/*** R apply(T t): 输入T类型的参数,运行相关逻辑后,返回R类型的结果。*/ @Test public void test1() {Function<String, Staff> function = x -> {Staff s = new Staff();s.setName(x + ", 咿呀咿呀哟!");return s;};Staff staff = function.apply("邓某");// 输出: 邓某, 咿呀咿呀哟!System.out.println(staff.getName()); }
Function<V, R> compose(Function<? super V, ? extends T> before): 由两个旧的Function得到一个新的Function。
假设: 现有式子functionC = functionB.compose(functionA),functionA 泛型为<P1, R1>, functionB泛型为<R1, R2>。
那么, 上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值作为functionB<R1, R2>的apply方法的入参,执行functionB<R1, R2>的apply方法,返回一个泛型为<P1, R2>的functionC<P1, R2>。
使用示例:
/*** <V> Function<V, R> compose(Function<? super V, ? extends T> before):由两个旧的Function得到一个新的Function。** 假设:现有式子functionC = functionB.compose(functionA),* functionA泛型为<P1, R1>, functionB泛型为<R1, R2>。** 那么,上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值* 作为functionB<R1, R2>的apply方法的入参,执行* functionB<R1, R2>的apply方法,返回一个泛型为* <P1, R2>的functionC<P1, R2>。*/@Testpublic void test2() {Function<String, Integer> functionA = x -> {Objects.requireNonNull(x, "参数不能为空");x = x.replace(" ", "");return x.length();};Function<Integer, Staff> functionB = x -> {Objects.requireNonNull(x, "参数不能为空");Staff s = new Staff();s.setAge(x);return s;};Function<String, Staff> functionC = functionB.compose(functionA);Staff staff = functionC.apply(" 我 是 参 数 ! ");// 输出: Staff(name=null, age=5, staffNo=null)System.out.println(staff);}
Function<T, V> andThen(Function<? super R, ? extends V> after: 由两个旧的Function得到一个新的Function。
假设: 现有式子functionC = functionA.andThen(functionB),functionA泛型为<P1, R1>, functionB泛型为<R1, R2>。
那么, 上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值作为functionB<R1, R2>的apply方法的入参,执行functionB<R1, R2>的apply方法,返回一个泛型为<P1, R2>的functionC<P1, R2>。
注: functionA.andThen(functionB)是先执行functionA,再执行functionB;而functionA.compose(functionB)是先执行functionB,再执行functionA。
使用示例:/*** <V> Function<T, V> andThen(Function<? super R, ? extends V> after):由两个旧的Function得到一个新的Function。** 假设:现有式子functionC = functionA.andThen(functionB),* functionA泛型为<P1, R1>, functionB泛型为<R1, R2>。** 那么,上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值* 作为functionB<R1, R2>的apply方法的入参,执行* functionB<R1, R2>的apply方法,返回一个泛型为* <P1, R2>的functionC<P1, R2>。** 注: functionA.andThen(functionB)是先执行functionA,再执行functionB;* 而functionA.compose(functionB)是先执行functionB,再执行functionA。*/@Testpublic void test3() {Function<String, Integer> functionA = x -> {Objects.requireNonNull(x, "参数不能为空");x = x.replace(" ", "");return x.length();};Function<Integer, Staff> functionB = x -> {Objects.requireNonNull(x, "参数不能为空");Staff s = new Staff();s.setAge(x);return s;};Function<String, Staff> functionC = functionA.andThen(functionB);Staff staff = functionC.apply(" 我 是 参 数 ! ");// 输出: Staff(name=null, age=5, staffNo=null)System.out.println(staff);}
static Function<T, T> identity(): 将输入的参数进行返回,即: return t -> t。
注: 在某些情景下,使用Function.identity(),会让代码更优雅。
使用示例:/*** static <T> Function<T, T> identity(): 将输入的参数进行返回,即: return t -> t。** 说明: 在某些情景下,使用Function.identity(),会让代码更优雅。*/@Testpublic void test4() {/** 使用普通的lambda表达式*/Map<Integer, String> mapOne = Stream.of("a", "ab", "abc", "abcd", "abcde").collect(Collectors.toMap(String::length, param -> param));// 输出: {1=a, 2=ab, 3=abc, 4=abcd, 5=abcde}System.out.println(mapOne);/** 使用Function.identity()无疑更优雅*/Map<Integer, String> mapTwo = Stream.of("a", "ab", "abc", "abcd", "abcde").collect(Collectors.toMap(String::length, Function.identity()));// 输出: {1=a, 2=ab, 3=abc, 4=abcd, 5=abcde}System.out.println(mapTwo);}
IntFunction<R>:
- R apply(int value): 入参类型必须为int, (运行相关逻辑后)返回R类型的数据。
使用示例:/*** R apply(int value): 入参类型必须为int, (运行相关逻辑后)返回R类型的数据。*/@Testpublic void test5() {IntFunction<Staff> intFunction = x -> {Staff staff = new Staff();staff.setAge(x);return staff;};Staff res = intFunction.apply(100);// 输出: Staff(name=null, age=100, staffNo=null)System.out.println(res);}
DoubleFunction<R>:
- R apply(double value): 入参类型必须为double,(运行相关逻辑后)返回R类型的数据。
使用示例:/*** R apply(double value): 入参类型必须为double, (运行相关逻辑后)返回R类型的数据*/@Testpublic void test6() {DoubleFunction<String> doubleFunction = x -> (x + "").replace(".", "_");String res = doubleFunction.apply(10.01);// 输出: 10_01System.out.println(res);}
LongFunction<R>:
R apply(long value): 入参类型必须为long, (运行相关逻辑后)返回R类型的数据。
使用示例:
/*** R apply(long value): 入参类型必须为long, (运行相关逻辑后)返回R类型的数据。*/@Testpublic void test7() {LongFunction<String> longFunction = x -> (x + "").replace("4", " 8484884 ").trim();String res = longFunction.apply(484);// 输出: 8484884 8 8484884System.out.println(res);}
ToIntFunction<T>:
- int applyAsInt(T value): 入参类型为T,(运行相关逻辑后)返回类型必为int。
使用示例:/*** int applyAsInt(T value): 入参类型为T, (运行相关逻辑后)返回类型必为int。*/@Testpublic void test8() {ToIntFunction<String> toIntFunction = x -> x == null ? 0 : x.length();int res = toIntFunction.applyAsInt("蚂蚁呀~嘿!嘿!");// 输出: 8System.out.println(res);}
ToLongFunction<T>:
- long applyAsLong(T value): 入参类型为T, (运行相关逻辑后)返回类型必为long。
使用示例:/*** long applyAsLong(T value): 入参类型为T, (运行相关逻辑后)返回类型必为long。*/@Testpublic void test9() {ToLongFunction<String> toLongFunction = x -> x == null ? 0 : new SecureRandom(x.getBytes()).nextLong();long res = toLongFunction.applyAsLong("蚂蚁呀~嘿!嘿!");// 输出: 2677168598702751372System.out.println(res);}
ToDoubleFunction<T>:
- double applyAsDouble(T value): 入参类型为T,(运行相关逻辑后)返回类型必为double。
使用示例:/*** double applyAsDouble(T value): 入参类型为T, (运行相关逻辑后)返回类型必为double。*/@Testpublic void test10() {ToDoubleFunction<Float> toDoubleFunction = x -> x == null ? 0.0 : x;double res = toDoubleFunction.applyAsDouble(123.4F);// 输出: 123.4000015258789 (注:精度问题不在本文的讨论范围内)System.out.println(res);}
IntToDoubleFunction:
- double applyAsDouble(int value): 入参类型必须为int,(运行相关逻辑后)返回类型必为double。
使用示例:/*** double applyAsDouble(int value): 入参类型必须为int, (运行相关逻辑后)返回类型必为double。*/@Testpublic void test11() {IntToDoubleFunction intToDoubleFunction = x -> x + 88.8;double res = intToDoubleFunction.applyAsDouble(12300);// 输出: 12388.8System.out.println(res);}
IntToLongFunction:
- long applyAsLong(int value): 入参类型必须为int,(运行相关逻辑后)返回类型必为long。
使用示例:/*** long applyAsLong(int value): 入参类型必须为int, (运行相关逻辑后)返回类型必为long。*/@Testpublic void test12() {IntToLongFunction intToLongFunction = x -> x + 1000L;long res = intToLongFunction.applyAsLong(12345);// 输出: 13345System.out.println(res);}
LongToDoubleFunction:
- double applyAsDouble(long value): 入参类型必须为long, (运行相关逻辑后)返回类型必为double。
使用示例:/*** double applyAsDouble(long value): 入参类型必须为long, (运行相关逻辑后)返回类型必为double。*/@Testpublic void test13() {LongToDoubleFunction longToDoubleFunction = x -> x + 1000000D;double res = longToDoubleFunction.applyAsDouble(12345L);// 输出: 1012345.0System.out.println(res);}
LongToIntFunction:
- int applyAsInt(long value): 入参类型必须为long,(运行相关逻辑后)返回类型必为int。
使用示例:/*** int applyAsInt(long value): 入参类型必须为long, (运行相关逻辑后)返回类型必为int。*/@Testpublic void test14() {LongToIntFunction longToIntFunction = x -> (int)(x / 1000);int res = longToIntFunction.applyAsInt(12345L);// 输出: 12System.out.println(res);}
DoubleToIntFunction:
- int applyAsInt(double value): 入参类型必须为double,(运行相关逻辑后)返回类型必为int。
使用示例:/*** int applyAsInt(double value): 入参类型必须为double, (运行相关逻辑后)返回类型必为int。*/@Testpublic void test15() {DoubleToIntFunction doubleToIntFunction = x -> (int)x;int res = doubleToIntFunction.applyAsInt(123.45);// 输出: 123System.out.println(res);}
DoubleToLongFunction:
- long applyAsLong(double value): 入参类型必须为double,(运行相关逻辑后)返回类型必为long。
使用示例:/*** long applyAsLong(double value): 入参类型必须为double, (运行相关逻辑后)返回类型必为long。*/@Testpublic void test16() {DoubleToLongFunction doubleToLongFunction = x -> (long)x;long res = doubleToLongFunction.applyAsLong(112233.4455);// 输出: 112233System.out.println(res);}
BiFunction<T, U, R>:
R apply(T t, U u): 输入T类型、U类型的参数,运行相关逻辑后,返回R类型的结果。
使用示例:/*** R apply(T t, U u): 输入T类型、U类型的参数,运行相关逻辑后,返回R类型的结果。*/@Testpublic void test17() {BiFunction<Integer, String, Staff> biFunction = (x, y) -> {Staff s = new Staff();s.setAge(x);s.setName(y);return s;};Staff staff = biFunction.apply(25, "单身邓");// 输出: 单身邓, 25岁!System.out.println(staff.getName() + ", " + staff.getAge() + "岁!");}
BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after): 由一个旧的BiFunction以及一个旧的Function得到一个新的BiFunction<T, U, V>。
假设: 现有式子biFunctionC = biFunctionA.andThen(functionB),biFunctionA泛型为<P1, T1, R1>, functionB泛型为<R1, R2>。
那么, 上述式子的逻辑是:先运行biFunctionA<P1, T1, R1>的apply方法,然后将其返回值作为functionB<R1, R2>的apply方法的入参,执行functionB<R1, R2>的apply方法,返回一个泛型为<P1, T1, R2>的biFunctionC<P1, T1, R2>。
使用示例:/*** <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after):* 由一个旧的BiFunction以及一个旧的Function得到一个新的BiFunction<T, U, V>。** 假设:现有式子biFunctionC = biFunctionA.andThen(functionB),* biFunctionA泛型为<P1, T1, R1>, functionB泛型为<R1, R2>。** 那么,上述式子的逻辑是:先运行biFunctionA<P1, T1, R1>的apply方法,然后将其返回值* 作为functionB<R1, R2>的apply方法的入参,执行* functionB<R1, R2>的apply方法,返回一个泛型为* <P1, T1, R2>的biFunctionC<P1, T1, R2>。*/@Testpublic void test18() {BiFunction<Integer, String, Staff> biFunctionA = (x, y) -> {Staff s = new Staff();s.setAge(x);s.setName(y);return s;};Function<Staff, Map<String, Staff>> functionB = x -> {Map<String, Staff> map = new HashMap<>(4);map.put(x.getName(), x);return map;};BiFunction<Integer, String, Map<String, Staff>> biFunctionC = biFunctionA.andThen(functionB);Map<String, Staff> map = biFunctionC.apply(25, "单身邓");// 输出: {单身邓=Staff(name=单身邓, age=25, staffNo=null)}System.out.println(map);}
ToIntBiFunction<T, U>:
- int applyAsInt(T t, U u): 入参类型为T和U,(运行相关逻辑后)返回类型必为int。
使用示例:/*** int applyAsInt(T t, U u): 入参类型为T和U, (运行相关逻辑后)返回类型必为int。*/@Testpublic void test19() {ToIntBiFunction<String, Double> toIntBiFunction = (x, y) -> Integer.parseInt(x) + y.intValue();int res = toIntBiFunction.applyAsInt("123000", 456.789);// 输出: 123456System.out.println(res);}
ToLongBiFunction<T, U>:
- long applyAsLong(T t, U u): 入参类型为T和U, (运行相关逻辑后)返回类型必为long。
使用示例:/*** long applyAsLong(T t, U u): 入参类型为T和U, (运行相关逻辑后)返回类型必为long。*/@Testpublic void test20() {ToLongBiFunction<String, Double> toLongBiFunction = (x, y) -> Integer.parseInt(x) + y.intValue();long res = toLongBiFunction.applyAsLong("123000", 456.789);// 输出: 123456System.out.println(res);}
ToDoubleBiFunction<T, U>:
- double applyAsDouble(T t, U u): 入参类型为T和U,(运行相关逻辑后)返回类型必为double。
使用示例:/*** double applyAsDouble(T t, U u): 入参类型为T和U, (运行相关逻辑后)返回类型必为double。*/@Testpublic void test21() {ToDoubleBiFunction<String, Double> toDoubleBiFunction = (x, y) -> Integer.parseInt(x) + y;double res = toDoubleBiFunction.applyAsDouble("123000", 456.789);// 输出: 123456.789System.out.println(res);}
^_^ 如有不当之处,欢迎指正
^_^ 参考资料
《jdk api 1.8_google.CHM》
^_^ 测试代码托管链接
https://github.com/JustryDeng…Jdk8Feature
^_^ 本文已经被收录进《程序员成长笔记》 ,笔者JustryDeng
【jdk1.8特性】之Function相关推荐
- 【jdk1.8特性】之Optional
简介:Optional类是jdk1.8开始为我们提供的一个处理null的类. 代码实例说明: 声明:下面只示例介绍jdk1.8里Optional的用法,对于更高版本jdk里对Optional的进一步优 ...
- JDK1.8特性之StringJoiner
StringBuilder.StringBuffer.String这三个的区别,很多文章都有在说. 这边也给大家做一个简要的概述 一:String.StringBuilder.StringBuffer ...
- java8 function 固定0_Java8特性使用Function代替分支语句
传统的多分支方式(圈复杂度为6): public String order(String type) { if ("1".equals(type)) { return " ...
- java8新特性之Function.identity()
Function.identity()是什么? // 将Stream转换成容器或Map Stream<String> stream = Stream.of("I", & ...
- 精读《Function VS Class 组件》
1. 引言 为什么要了解 Function 写法的组件呢?因为它正在变得越来越重要. 那么 React 中 Function Component 与 Class Component 有何不同? how ...
- javascript 高级特性探讨A4-A5(call和原型.对象复制)
在js中,call和apply是二个神奇的方法,但同时也是容易令人迷惑的二个方法,call和apply的功能是以不同的对象作为上下文来调用某个函数的,简而言之,就是允许一个对象去调用另一个对象的成员函 ...
- 微信授权扫码点餐-新特性React16
首先,需要对静态方法做一个理解.static静态方法,在es5中怎么实现呢?网易云课堂 微信授权扫码点餐-新特性React16 function Person() {} Person.getCount ...
- C++11新特性(原封不动转载待查)
C++11标准发布已有一段时间了, 维基百科上有对C++11新标准的变化和C++11新特性介绍的文章. 我是一名C++程序员,非常想了解一下C++11. 英文版的维基百科看起来非常费劲,而中文版维基百 ...
- 关于html5支持与否的判断(JS检测是否支持HTML5新特性)
未来使用H5的场景会越来越多,这是令 web开发者欢欣鼓舞的事情.然而有一个现实我们不得不看清,那就是IE系列浏览器还占有一大部分市场份额,以IE8.9为主,windows8.1的用户已经用上了IE1 ...
- ES5和ES6声明变量特性与区别
在进行javascript详细学习之前,对ES5和ES6的变量声明有个简单的了解,方便我们进行学习理解 变量:存储信息的容器,在ES中变量是松散类型. 松散类型:不对数据类型做限制,前端js的基本数据 ...
最新文章
- Fraction+mysql_MySQL 数据类型总结
- Oracle 扼杀 Java EE!
- cydia 未能连接服务器,cydia闪退解决办法_cydia无法连接网络问题怎么解决
- 初中信息技术说课稿_语文说课稿模板一等奖
- ios storyboard 传参 返回传参(segue)
- Excel技巧:如何将数值改成以万为单位,且保留小数点两位?
- 数据分析师工作的一点点感悟
- 搜索功能这样设计,大家都说我有点东西
- 【渝粤教育】广东开放大学 公共经济学 形成性考核 (33)
- QT学习串口编程之串口软件的UI设计
- 一个JavaScript变量应用实例
- win10更改IP地址遇错(出现了一个意外情况,不能完成你的更改)
- Python xlrd 读取Excel数字 数字丢失精度 小数位太长 求大神的解决方法(已解决)
- 我的兄弟姐妹中感人的亲情
- CPU基础知识1------Intel CPU 地址空间
- 利用Scanner和Random类写的java猜字小游戏
- 汽车行驶工况构建 2019D题
- linux禁止普通用户切换,扣丁学堂Linux培训简述Linux禁止普通用户切换至root用户的实例...
- 如何在服务器右下角显示时间,win7 64位右下角怎么显示时间日期与星期?
- java实现第七届蓝桥杯圆圈舞