其实为了更好的使用lamda表达式,java在jdk1.8之后也添加了内置四大核心的函数式接口。什么是函数式接口以及lambda表达式可以看前面一篇 地址
Java内置的四大核心函数式接口如下:
函数式接口 | 参数类型 | 返回值 | 意义 |
---|---|---|---|
Consumer<T> | T | void | 对类似为T的对象应用才做,包含方法void accept(T t) |
Supplier<T> | 无 | T | 返回类型为T的对象,包含方法:T get() |
Function<T,R> | R | T | 对类型为T的对象应用操作,并返回结果。结果是R的对象,包含的方法 R.apply(T t) |
Predicate<T> | T | boolean | 确定类型为T的对象是否满足某约束,并返回boolean值。包含方法:boolean test(T t) |
这四大核心的函数式接口,说白就是为何跟上其他语言的lambda表达式而诞生的,而且其可以使用方法引用(上一篇聊过)
对于这四大核心的函数式接口,简单立即就是定义了一个标准,只要实现了这个接口,按照其要求写即可。不要纠结为什么这样写,因为接口本质就是定义了一个标准而已。
Consumer<T> 消费型接口,返回值 void
这个看名字就知道式一个消费型接口
现在看源码:(后面不在黏贴,毕竟意义不大)
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package java.util.function;
import java.util.Objects;
/**
* Represents an operation that accepts a single input argument and returns no
* result. Unlike most other functional interfaces, {@code Consumer} is expected
* to operate via side-effects.
*
* <p>This is a <a href="package-summary.html">functional interface</a>
* whose functional method is {@link #accept(Object)}.
*
* @param <T> the type of the input to the operation
*
* @since 1.8
*/
@FunctionalInterface
public interface Consumer<T> {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);
/**
* Returns a composed {@code Consumer} that performs, in sequence, this
* operation followed by the {@code after} operation. If performing either
* operation throws an exception, it is relayed to the caller of the
* composed operation. If performing this operation throws an exception,
* the {@code after} operation will not be performed.
*
* @param after the operation to perform after this operation
* @return a composed {@code Consumer} that performs in sequence this
* operation followed by the {@code after} operation
* @throws NullPointerException if {@code after} is null
*/
// 1 :default方法某默认实现,不属于抽象方法
// 2 :接口重写了Object的公共方法也不算入内
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
简单的代码演示
public class test {
public static void main(String[] args) {
// 写法1 传统写法
Consumer<Double> consumer=new Consumer<Double>() {
@Override
public void accept(Double num) {
System.out.println("写法1 输入的数字值是:"+num);
}
};
getName(12.3,consumer);
// 写法2:lambda表达式
Consumer<Double> consumer1= num-> System.out.println("写法2 输入的数字值是:"+num);
getName(12.3,consumer1);
// 写法3 方法引用
Consumer<Double> consumer2= System.out::println;
getName(12.3,consumer2);
}
public static void getName(Double num,Consumer<Double> consumer) {
consumer.accept(num);
}
}
Predicate<T> 断定型接口,返回值 boolean
代码演示
public class test {
public static void main(String[] args) {
String[] arr= {
"张国立","成龙","李连杰","张彻","张三","甄子丹"};
// 要求将数组中的名字带张的人放入一个list中
// 方法1 传统方式
Predicate<String> predicate=new Predicate<String>() {
@Override
public boolean test(String t) {
if (t.contains("张")) {
return true;
}
return false;
}
};
getList(arr,predicate);
// 方法2 lambda表达式
Predicate<String> predicate1= t->{
if (t.contains("张")) {
return true;
}
return false;
};
getList(arr,predicate1);
// 或者结合三目运算符
predicate1= t->{
return t.contains("张") ? true: false;
};
getList(arr,predicate1);
// 不过t.contains("张") 本身就返回boolen值了
predicate1= t->{
return t.contains("张");};
// 也可以省略 return predicate1= t-> t.contains("张");
getList(arr,predicate1);
// 方法3 方法引用 根据前面的总结 这个方法暂时无法写
}
// public static
public static void getList(String[] arr,Predicate<String> predicate) {
List<String> zlist=new ArrayList<String>();
for (String s:arr) {
if(predicate.test(s)) {
zlist.add(s);
}
}
System.out.println(zlist);
}
}
Supplier<T>,供给型接口,返回值 T
返回一个对象。
public class test {
public static void main(String[] args) {
// 方法1 传统方式
Supplier<String> supplier =new Supplier<String>() {
@Override
public String get() {
return "看自己需求写返回的对象";
}
};
getString(supplier);
// 方法2 lambda表达式
Supplier<String> supplier1 =() -> {
return "看自己需求写返回的对象";};
//也可以这样写 Supplier<String> supplier1 =() -> "看自己需求写返回的对象";lambda会自动添加retrun
getString(supplier1);
}
public static void getString(Supplier<String> supplier) {
System.out.println(supplier.get());
}
}
Function<T, R> 函数型接口,返回值 R
public class test{
public static void main(String[] args) {
ObJ obj=new ObJ("张三",12);
// 方法1 传统方式
Function<ObJ, String> function=new Function<ObJ, String>() {
@Override
public String apply(ObJ obj) {
// TODO Auto-generated method stub
return obj.getName();
}
};
getFunc(obj,function);
// 方法2 lambda表达式
Function<ObJ, String> function1 = zobj-> {
return zobj.getName();};
//也可以这样写 Function<ObJ, String> function1 = zobj-> zobj.getName(); lambda会自动添加retrun
getFunc(obj,function1);
}
public static void getFunc(ObJ obj, Function<ObJ, String> function) {
System.out.println(function.apply(obj));
}
}
class ObJ{
private String name;
private int age;
public ObJ(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
这四个本篇只是写了几个简单应用,后面在弄一些应用场景。所以先了解使用过程。