函数式接口
随着JDK 不断升级,大多数企业都采用了JDK1.8 版本 ,函数式接口 也普遍被应用在底层源码中,目前主要和大家分享1.8包中Function
什么是java.util.function.Function包?
Function<T, R>中的Java 8中引入的内置功能接口java.util.function。Function<T, R>已创建的主要目的是用于映射方案,即将类型的对象作为输入并将其转换(或映射)到另一种类型时。Function的常见用法是在流中,其中流的map函数接受Function的实例以将一种类型的流转换为另一种类型的流。
Function<T,R>
Function<T, R>函数描述符的函数描述符是T -> R T的对象被输入到lambda 且类型R的对象被获得作为返回值.
在特定类型的对象输入的所有场景中,对其执行操作并且返回另一类型的对象作为输出,Function<T, R>可以使用内置功能接口而无需每次定义。源码
@FunctionalInterface
public interface Function<T, R> {
//主要方法apply接收一个参数,返回一个值
R apply(T t);
// compose方法是一个默认方法,这个方法接收一个function作为参数
// 将参数function执行的结果作为参数给调用的function,以此来实现两个function组合的功能
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
//功能相似 一个是优先 一个连续
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
//它只返回它作为输入获取的参数
static <T> Function<T, T> identity() {
return t -> t;
}
}
详细流程讲解
apply()用法
public class FunctionOneExample{
public static void main(String args[]){
Function<User, String> funcUserToString= (User e)-> {return e.getName();};
List<User> UserList=
Arrays.asList(new User("A-0", 13),
new User("A-1", 25),
new User("B-2", 10),
new User("C-3", 15),
new User("D-4", 29));
List<String> userNameList=convertUserListToNamesList(UserList, funcUserToString);
userNameList.forEach(System.out::println);
}
public static List<String> convertUserListToNamesList(List<User> UserList, Function<User, String> funcUserToString){
List<String> userNameList=new ArrayList<String>();
for(User user:UserList){
userNameList.add(funcUserToString.apply(user));
}
return userNameList;
}
}
输出结果:
A-0
A-1
B-2
C-3
D-4
1.funcUserToString 是一个实例Function<User,String>。这是java.util.function.Function用于将User 对象转换/映射到String 值的实例。
2.定义funcUserToString的lambda是 - (User e)-> {return e.getName();}。它将一个User对象作为输入,并返回其名称,即一个String 值,作为输出。
3.员工列表convertUserListToNamesList()与Function对象一起传递给方法funcUserToString;
4.该方法convertUserListToNamesList()迭代员工列表中的所有员工,将该功能funcUserToString应用于每个User对象,以String格式获取员工姓名,将其放入员工姓名列表并将其发送回main()方法。
5.在打印员工姓名列表时,我们会根据需要获取所有员工的姓名。
andThen()用法
public class FunctionAndThenOneExample{
public static void main(String args[]){
Function<User, String> funcUserToString= (User e)-> {return e.getName();};
List<User> UserList=
Arrays.asList(new User("Tike-one", 13),
new User("Hello-world", 25),
new User("Earth-one", 10),
new User("Nanshou-one", 15),
new User("Dogkeep-one", 29));
Function<String,String> initialFunction= (String s)->s.substring(0,1);
List<String> userNameListInitials=convertUserListToNamesList(UserList, funcUserToString.andThen(initialFunction));
userNameListInitials.forEach(str->{System.out.print(" "+str);});
}
public static List<String> convertUserListToNamesList(List<User> UserList, Function<User, String> funcUserToString){
List<String> userNameList=new ArrayList<String>();
for(User user:UserList){
userNameList.add(funcUserToString.apply(user));
}
return userNameList;
}
}
1.函数实例funcUserToString映射将User对象转换String为其姓名。
2.函数实例initialFunction映射将a String转换为其首字母或第一个字母。
3.默认的方法andThen()来结合initialFunction使用funcUserToString。组合方法的作用是首先将一个映射User到他的名称,然后从名称中取出第一个字母作为String值。此组合函数作为Function参数传递给convertUserListToNamesList()方法以及员工列表。
4.当convertUserListToNamesList()将组合函数应用于每个User对象时,结果是String列出每个雇员的名字的第一个字母。
5.这是所需的输出,即 THEND
Compose()用法
public class FunctionComposeExample{
public static void main(String args[]){
Function<User, String> funcUserToString= (User e)-> {return e.getName();};
Function<User, User> funcuserFirstName=
(User e)-> {int index= e.getName().indexOf("-");
String firstName=e.getName().substring(0,index);
e.setName(firstName);
return e;};
List<User> UserList=
Arrays.asList(new User("Tike one", 13),
new User("Hello-world", 25),
new User("Earth-one", 10),
new User("Nanshou-one", 15),
new User("Dogkeep-one", 29));
List<String> userFirstNameList= convertUserListToNamesList(UserList,funcUserToString.compose(funcuserFirstName));
userFirstNameList.forEach(str->{System.out.print(" "+str);});
}
public static List<String> convertUserListToNamesList(List<User> UserList, Function<User, String> funcUserToString){
List<String> userNameList=new ArrayList<String>();
for(User user:UserList){
userNameList.add(funcUserToString.apply(user));
}
return userNameList;
}
}
结果
Tike Hello Earth Nanshou Dogkeep
函数实例funcUserToString映射 用User对象转换String为其 name 的值。
函数实例funcuserFirstName映射 使用方法name将User对象内部转换为第一个名称。substringString
默认方法compose()用于funcuserFirstName与funcUserToStringString 结合使用。组合方法的作用是首先将a的名称转换User为他的名字,然后User使用更改后的值返回同一个对象name。然后它转换将User对象映射到它name作为a String。这个组合函数作为Function<User, String>参数传递给convertUserListToNamesList()方法以及员工列表。
当convertUserListToNamesList()将组合函数应用于每个User对象时,结果是每个雇员的名字列表。
这是必需的输出,即Tom Harry Ethan Nancy Deborah
identity() 用法
public class FunctionTRIdentityExample{
public static void main(String args[]){
Function<User, String> funcUserToString= (User e)-> {return e.getName();};
List<User> UserList=
Arrays.asList(new User("Tike-one", 13),
new User("Hello-world", 25),
new User("Earth-one", 10),
new User("Nanshou-one", 15),
new User("Dogkeep-one", 29));
List<User> userNameListInitials=applyIdentityTouserList(UserList, Function.identity());
userNameListInitials.forEach(System.out::println);
}
public static List<User> applyIdentityTouserList(List<User> UserList, Function<User, User> funcuserTouser){
List<User> userNameList=new ArrayList<User>();
for(User user:UserList){
userNameList.add(funcuserTouser.apply(user));
}
return userNameList;
}
}
结果
User Name:Tike-one Age:13
User Name:Hello-world Age:25
User Name:Earth-one Age:10
User Name:Nanshou-one Age:15
User Name:Dogkeep-one Age:29
函数实例funcUserToString映射\将User对象转换String为其姓名。
员工列表applyIdentityTouserList()与实例一起传递给方法Function.identity()。的参数applyIdentityTouserList()这需要Function.identity()值是什么,但Function<User, User>即的等效Function这需要User作为输入,并且还给(下同)User作为输出。
方法applyIdentityTouserList()获取输入员工列表,遍历它,将该identity()功能应用于列表中的每个员工,并返回由于应用该identity()功能而获得的员工列表。
我们现在知道,身份函数什么都不做,它只返回它作为输入接收的对象。所以,我们得到的是我们传递给applyIdentityTouserList()方法的员工名单 同样的原始员工名单也作为输出打印
这就是静态方法的Function.identity()工作原理。
贴两个简单的Demo 功能
public class TestOne {
public static int compute(int a, Function<Integer, Integer> function) {
int result = function.apply(a);
return result;
}public static int compute(int a, Function<Integer, Integer> function1, Function<Integer, Integer> beForeFunction) {
return function1.compose(beForeFunction).apply(a);
}
//
public static int compute2(int a, Function<Integer, Integer> function1, Function<Integer, Integer> afterfunction2) {
return function1.andThen(afterfunction2).apply(a);
}
@Test
public void testFunctionApply() {
int a=TestOne.compute(5,value -> value * value);
int a1=TestOne.compute(5,value -> value + value);
int a2=TestOne.compute(5,value -> value - 2);
System.out.println(a+""+ "-"+a1+ "-"+a2);//25-10-3
}
@Test
public void testCompose() {
int a=TestOne.compute(2, value -> value * 3, value -> value * value);
int a1=TestOne.compute2(2, value -> value * 3, value -> value * value);
System.out.println(a+"-"+a1); //12-36
}
}