Java8函数式编程之四: 常见的函数式接口及实例

来源:互联网 发布:网络驱动器重启后没了 编辑:程序博客网 时间:2024/06/06 01:32

上一篇博客中留下的问题是关于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.*/@FunctionalInterfacepublic 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.*/@FunctionalInterfacepublic 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();//现在相当于传递了一个行为/动作给computeSystem.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)}.*/@FunctionalInterfacepublic 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);}//使用andThenpublic 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*/@FunctionalInterfacepublic 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()}.*/@FunctionalInterfacepublic 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)}.*/@FunctionalInterfacepublic 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));//如果里面没有值,就打出wordSystem.out.print(optional.orElse("world"));}}