上一篇博客中Java8函数式编程之三:函数式接口 - 简书 留下的问题是关于Consumer接口的,本篇博客就来介绍一下Java8提供的重要的函数式接口。
1.Consumer接口:
我们首先看一下Consumer接口的Javadoc,比任何资料都正规的解释。
'
/**
* Represents an operation that accepts a single input argument and returns no
* result. Unlike most other functional interfaces, {@codeConsumer} is expected
* to operate via side-effects.
*/
@FunctionalInterface
public interfaceConsumer {
/**
* Performs this operation on the given argument. 通过给定的参数执行操作
*/
voidaccept(Tt);
/**
* Returns a composed {@codeConsumer} that performs, in sequence, this
* operation followed by the {@codeafter} 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 {@codeafter} operation will not be performed.
*/
defaultConsumer andThen(Consumer after) {
Objects.requireNonNull(after);
return(Tt) -> { accept(t);after.accept(t); };
}
}
'
Consumer接口中定义了一个accept()的抽象方法,它接收泛型T的对象,没有返回(void).
一句话解释就是:接收一个输入参数,不返回结果。
——————————————————————————————————
2.Function接口 :
/**
* Represents a function that accepts one argument and produces a result.
*/
@FunctionalInterface
public interfaceFunction {
/**
* Applies this function to the given argument.
*/
Rapply(Tt);
/**
* Returns a composed function that first applies the {@codebefore}
* function to its input, and then applies this function to the result.
* If evaluation of either function throws an exception, it is relayed to
* the caller of the composed function.
*/
default Function compose(Function before) {
Objects.requireNonNull(before);
return(Vv) -> apply(before.apply(v));
}
/**
* Returns a composed function that first applies this function to
* its input, and then applies the {@codeafter} function to the result.
* If evaluation of either function throws an exception, it is relayed to
* the caller of the composed function.
*/
default Function andThen(Function after) {
Objects.requireNonNull(after);
return(Tt) ->after.apply(apply(t));
}
/**
* Returns a function that always returns its input argument.
*
*@paramthe type of the input and output objects to the function
*@returna function that always returns its input argument
*/
static Function identity() {
returnt -> t;
}
}
Function接口定义了一个apply()方法,它接收一个泛型T的对象,并返回一个R对象。
一句话解释就是:输入一个参数,返回一个结果。
——————————————————
Function接口实例:
public classFunctionTest {
public static voidmain(String[] args) {
FunctionTest test =newFunctionTest();
//现在相当于传递了一个行为/动作给compute
System.out.print(test.compute(2, value -> {
return2* value;
}));
System.out.print(test.compute(5, value -> {
returnvalue +7;
}));
}
//一个计算函数
public intcompute(inta, Function function) {
returnfunction.apply(a);
}
}
————————————————————————————————————
3.BiFunction函数式接口:
/**
* Represents a function that accepts two arguments and produces a result.
* This is the two-arity specialization of {@linkFunction}.
*
*
This is afunctional interface
* whose functional method is {@link#apply(Object, Object)}.
*/
@FunctionalInterface
public interfaceBiFunction {
/**
* Applies this function to the given arguments.
*/
Rapply(Tt,Uu);
/**
* Returns a composed function that first applies this function to
* its input, and then applies the {@codeafter} function to the result.
* If evaluation of either function throws an exception, it is relayed to
* the caller of the composed function.
*/
default BiFunction andThen(Function after) {
Objects.requireNonNull(after);
return(Tt,Uu) ->after.apply(apply(t, u));
}
}
一句话总结就是:接收两个参数,得到一个结果。
——————
Bifunction实例:
public classBiFunctionTest {
public static voidmain(String[] atgs) {
BiFunctionTest test =newBiFunctionTest();
System.out.print(test.compute(1,3, (value1, value2) -> value1 + value2));
System.out.print(test.compute(1,3, (value1, value2) -> value1 - value2));
//
System.out.print(test.compute2(3,2, (value1, value2) -> value1 + value2, value -> value - value));
}
public intcompute(inta,intb, BiFunction biFunction) {
returnbiFunction.apply(a, b);
}
//使用andThen
public intcompute2(inta,intb, BiFunction biFunction, Function function) {
returnbiFunction.andThen(function).apply(a, b);
}
}
————————————————————————
4.Predicate函数式接口:
/**
* Represents a predicate (boolean-valued function) of one argument.
*
*
This is afunctional interface
* whose functional method is {@link#test(Object)}.
*
*@paramthe type of the input to the predicate
*
*@since1.8
*/
@FunctionalInterface
public interfacePredicate {
/**
* Evaluates this predicate on the given argument.
*/
booleantest(Tt);
/**
* Returns a composed predicate that represents a short-circuiting logical
* AND of this predicate and another. When evaluating the composed
* predicate, if this predicate is {@codefalse}, then the {@codeother}
* predicate is not evaluated.
*/
defaultPredicate and(Predicate other) {
Objects.requireNonNull(other);
return(t) -> test(t) &&other.test(t);
}
/**
* Returns a predicate that represents the logical negation of this
* predicate.
*/
defaultPredicate negate() {
return(t) -> !test(t);
}
/**
* Returns a composed predicate that represents a short-circuiting logical
* OR of this predicate and another. When evaluating the composed
* predicate, if this predicate is {@codetrue}, then the {@codeother}
* predicate is not evaluated.
*/
defaultPredicate or(Predicate other) {
Objects.requireNonNull(other);
return(t) -> test(t) ||other.test(t);
}
/**
* Returns a predicate that tests if two arguments are equal according
* to {@linkObjects#equals(Object, Object)}.
*/
static Predicate isEqual(Object targetRef) {
return(null== targetRef)
? Objects::isNull
: object ->targetRef.equals(object);
}
}
一句话解释就是:接收一个参数,返回一个布尔值。
Predicate接口里的其他方法:
1.逻辑与
defaultPredicate and(Predicate other) {
Objects.requireNonNull(other);
return(t) -> test(t) &&other.test(t);
}
2.逻辑非 (取反)
defaultPredicate negate() {
return(t) -> !test(t);
}
3.逻辑或
defaultPredicate or(Predicate other) {
Objects.requireNonNull(other);
return(t) -> test(t) ||other.test(t);
}
4.静态方法,相等性/
static Predicate isEqual(Object targetRef) {
return(null== targetRef)
? Objects::isNull
: object ->targetRef.equals(object);
}
——————————
实例1:
public classPredicateTest {
public static voidmain(String[] args) {
List list = Arrays.asList(1,2,3,4,5,6,7,8,9);
PredicateTest test =newPredicateTest();
//找到集合中所有的奇数
test.conditionFilter(list, item -> item %2!=0);
//大于5的数
test.conditionFilter(list, item -> item >5);
//打印所有的元素
test.conditionFilter(list, item ->true);
//测试与
test.conditionFilter2(list, item -> item >5, item -> item %2==0);
//测试或
test.conditionFilter3(list, item -> item >5, item -> item %2==0);
//测试非
test.conditionFilter4(list, item -> item >5, item -> item %2==0);
//相等性判断
System.out.print(test.isEqual("test").test("test"));
}
//函数式编程提供了一种更高层次的抽象
public voidconditionFilter(List list, Predicate predicate) {
for(Integer integer : list) {
if(predicate.test(integer)) {
System.out.print(integer +" ");
}
}
}
//与
public voidconditionFilter2(List list, Predicate predicate1, Predicate predicate2) {
for(Integer integer : list) {
if(predicate1.and(predicate2).test(integer)) {
System.out.print(integer);
}
}
}
//或
public voidconditionFilter3(List list, Predicate predicate1, Predicate predicate2) {
for(Integer integer : list) {
if(predicate1.or(predicate2).test(integer)) {
System.out.print(integer);
}
}
}
//非
public voidconditionFilter4(List list, Predicate predicate1, Predicate predicate2) {
for(Integer integer : list) {
if(predicate1.and(predicate2).negate().test(integer)) {
System.out.print(integer);
}
}
}
//想等性判断
publicPredicate isEqual(Object object) {
returnPredicate.isEqual(object);
}
}
————————————————
5.Supplier函数式接口:
/**
* Represents a supplier of results.
*
*
There is no requirement that a new or distinct result be returned each
* time the supplier is invoked.
*
*
This is afunctional interface
* whose functional method is {@link#get()}.
*/
@FunctionalInterface
public interfaceSupplier {
/**
* Gets a result.
*/
Tget();
}
一句话解释就是:不接收任何参数,返回一个结果。
——————————————————————————
public classSupplierTest {
public static voidmain(String[] args){
//不接收参数,返回一个结果
Supplier supplier = () ->"hello world";
System.out.print(supplier.get());
}
}
————————————
实例2:
public classStudent {
privateStringname="zhangsan";
private intage;
publicStudent(){
}
publicStudent(String name,intage){
this.name= name;
this.age= age;
}
publicString getName() {
returnname;
}
public voidsetName(String name) {
this.name= name;
}
public intgetAge() {
returnage;
}
public voidsetAge(intage) {
this.age= age;
}
}
——————————————
public classStudentTest {
public static voidmain(String[] args){
Supplier supplier = () ->newStudent();
System.out.print(supplier.get().getName());
//使用构造方法引用
Supplier supplier1 = Student::new;
System.out.print(supplier1.get().getName());
}
}
————————————————
6.BinaryOperator函数式接口
/**
* Represents an operation upon two operands of the same type, producing a result
* of the same type as the operands. This is a specialization of
* {@linkBiFunction} for the case where the operands and the result are all of
* the same type.
*
*
This is afunctional interface
* whose functional method is {@link#apply(Object, Object)}.
*/
@FunctionalInterface
public interfaceBinaryOperatorextendsBiFunction {
/**
* Returns a {@linkBinaryOperator} which returns the lesser of two elements
* according to the specified {@codeComparator}.
*/
public static BinaryOperator minBy(Comparator comparator) {
Objects.requireNonNull(comparator);
return(a, b) ->comparator.compare(a, b) <=0? a : b;
}
/**
* Returns a {@linkBinaryOperator} which returns the greater of two elements
* according to the specified {@codeComparator}.
*/
public static BinaryOperator maxBy(Comparator comparator) {
Objects.requireNonNull(comparator);
return(a, b) ->comparator.compare(a, b) >=0? a : b;
}
}
一句话解释就是:接收两个相同类型的参数,返回一个结果。
————————————————
public classBinaryOperatorTest {
public static voidmain(String[] args){
BinaryOperatorTest test =newBinaryOperatorTest();
System.out.print(test.compute(1,2,(a,b) -> a +b));
}
public intcompute(inta,intb, BinaryOperator binaryOperator){
returnbinaryOperator.apply(a,b);
}
publicString getShort(String a, String b, Comparator comparator){
returnBinaryOperator.minBy(comparator).apply(a,b);
}
}
——————————————————————
6.Optinal函数式接口:
/**
* A container object which may or may not contain a non-null value.
* If a value is present, {@codeisPresent()} will return {@codetrue} and
* {@codeget()} will return the value.
*
*
Additional methods that depend on the presence or absence of a contained
* value are provided, such as {@link#orElse(java.lang.Object) orElse()}
* (return a default value if value not present) and
* {@link#ifPresent(java.util.function.Consumer) ifPresent()} (execute a block
* of code if the value is present).
*/
public final classOptional
一句话解释就是:为了解决Java中的NPE问题(NullPointerExeception)
(程序员认为某个对象不会为空,而去使用这个对象调用某个方法,导致出现NullPointerExeception)
————————————————
Optinal是一个容器对象,里面可以包含或者不包含一个非空值。如果这个值存在,isPresent()方法会返回true,get()方法会返回这个值。
——————
几个工厂方法构造对象
1.构造一个值为null的对象
public static Optional empty() {
@SuppressWarnings("unchecked")
Optional t = (Optional)EMPTY;
returnt;
}
2.构造一个不为null的对象
public static Optional of(Tvalue) {
return newOptional<>(value);
}
3.构造出可能为null,也可能不为null的对象
public static Optional ofNullable(Tvalue) {
returnvalue ==null?empty() :of(value);
}
————————————————————
4.取值get();
publicTget() {
if(value==null) {
throw newNoSuchElementException("No value present");
}
returnvalue;
}
5.判断对象是否存在 isPresent()
public booleanisPresent() {
returnvalue!=null;
}
——————————————
public classOptionalTest {
public static voidmain(String[] args){
//不能new,需要用工厂方法创建
Optional optional = Optional.of("hello");
optional.ifPresent(item -> System.out.print(item));
//如果里面没有值,就打出word
System.out.print(optional.orElse("world"));
}
}