如何更好的使用Java8中方法引用详解
前言
方法引用是用来直接访问类或者实例的已经存在的方法或者构造方法。方法引用提供了一种引用而不执行方法的方式,它需要由兼容的函数式接口构成的目标类型上下文。计算时,方法引用会创建函数式接口的一个实例。
当Lambda表达式中只是执行一个方法调用时,不用Lambda表达式,直接通过方法引用的形式可读性更高一些。方法引用是一种更简洁易懂的Lambda表达式。
注意:方法引用是一个Lambda表达式,其中方法引用的操作符是双冒号"::"。
在Java8中,使用方法引用非常简单,如String::isEmpty,但无法使用它否定的方法引用。本文内容即如何解决此问题使得我们能够更加全面地使用方法引用。
首先看一个使用方法引用的例子:
Stream.of("A","","B").filter(String::isEmpty).count()
上面代码的输出为1,即空字符串的数目。如果我们想要获取非空字符串的数目,就不能直接使用方法引用了。
Stream.of("A","","B").filter(s->!s.isEmpty()).count()
Java8中的Predicate,有predicate.negate()可以转换为断言的否定形式,但String::isEmpty却无法这么做(String::isEmpty.negate()或者!String::isEmpty)。因为方法引用并不是一个lambda或者函数接口,它能够被解析为一个或者多个函数接口。如,String::isEmpty至少可以被解析如下:
PredicateFunction
为了解决上述的问题,我们可以通过某种机制显式地将方法引用转换为一个函数接口:
publicstaticPredicate as(Predicate predicate){ returnpredicate; }
通过使用一个静态方法,接受方法引用参数,返回一个函数接口,即可实现方法引用到函数接口的转换。接着,我们就可以使用方法引用来实现上面例子中的获取非空字符串的数目。
Stream.of("A","","B").filter(as(String::isEmpty).negate()).count();
进一步还能使用各种组合的Predicate。
.filter(as(String::isEmpty).negate().and("A"::equals))
由于一个方法引用可能会被解析为多种函数接口,因此如果我们实现很多参数不同的as方法,那么很容易造成混淆。更好的方式则是在方法名中加入函数参数的类型来区分。
importjava.util.function.*; publicclassFunctionCastUtil{ publicstaticBiConsumer asBiConsumer(BiConsumer biConsumer){ returnbiConsumer; } publicstatic BiFunction asBiFunction(BiFunction biFunction){ returnbiFunction; } publicstatic BinaryOperator asBinaryOperator(BinaryOperator binaryOperator){ returnbinaryOperator; } publicstatic BiPredicate asBiPredicate(BiPredicate biPredicate){ returnbiPredicate; } publicstaticBooleanSupplierasBooleanSupplier(BooleanSupplierbooleanSupplier){ returnbooleanSupplier; } publicstatic Consumer asConsumer(Consumer consumer){ returnconsumer; } publicstaticDoubleBinaryOperatorasDoubleBinaryOperator(DoubleBinaryOperatordoubleBinaryOperator){ returndoubleBinaryOperator; } publicstaticDoubleConsumerasDoubleConsumer(DoubleConsumerdoubleConsumer){ returndoubleConsumer; } publicstatic DoubleFunction asDoubleFunction(DoubleFunction doubleFunction){ returndoubleFunction; } publicstaticDoublePredicateasDoublePredicate(DoublePredicatedoublePredicate){ returndoublePredicate; } publicstaticDoubleToIntFunctionasDoubleToIntFunction(DoubleToIntFunctiondoubleToIntFunctiontem){ returndoubleToIntFunctiontem; } publicstaticDoubleToLongFunctionasDoubleToLongFunction(DoubleToLongFunctiondoubleToLongFunction){ returndoubleToLongFunction; } publicstaticDoubleUnaryOperatorasDoubleUnaryOperator(DoubleUnaryOperatordoubleUnaryOperator){ returndoubleUnaryOperator; } publicstatic Function asFunction(Function function){ returnfunction; } publicstaticIntBinaryOperatorasIntBinaryOperator(IntBinaryOperatorintBinaryOperator){ returnintBinaryOperator; } publicstaticIntConsumerasIntConsumer(IntConsumerintConsumer){ returnintConsumer; } publicstatic IntFunction asIntFunction(IntFunction intFunction){ returnintFunction; } publicstaticIntPredicateasIntPredicate(IntPredicateintPredicate){ returnintPredicate; } publicstaticIntSupplierasIntSupplier(IntSupplierintSupplier){ returnintSupplier; } publicstaticIntToDoubleFunctionasIntToDoubleFunction(IntToDoubleFunctionintToDoubleFunction){ returnintToDoubleFunction; } publicstaticIntToLongFunctionasIntToLongFunction(IntToLongFunctionintToLongFunction){ returnintToLongFunction; } publicstaticIntUnaryOperatorasIntUnaryOperator(IntUnaryOperatorintUnaryOperator){ returnintUnaryOperator; } publicstaticLongBinaryOperatorasLongBinaryOperator(LongBinaryOperatorlongBinaryOperator){ returnlongBinaryOperator; } publicstaticLongConsumerasLongConsumer(LongConsumerlongConsumer){ returnlongConsumer; } publicstatic LongFunction asLongFunction(LongFunction longFunction){ returnlongFunction; } publicstaticLongPredicateasLongPredicate(LongPredicatelongPredicate){ returnlongPredicate; } publicstatic LongSupplierasLongSupplier(LongSupplierlongSupplier){ returnlongSupplier; } publicstaticLongToDoubleFunctionasLongToDoubleFunction(LongToDoubleFunctionlongToDoubleFunction){ returnlongToDoubleFunction; } publicstaticLongToIntFunctionasLongToIntFunction(LongToIntFunctionlongToIntFunction){ returnlongToIntFunction; } publicstaticLongUnaryOperatorasLongUnaryOperator(LongUnaryOperatorlongUnaryOperator){ returnlongUnaryOperator; } publicstatic ObjDoubleConsumer asObjDoubleConsumer(ObjDoubleConsumer objDoubleConsumer){ returnobjDoubleConsumer; } publicstatic ObjIntConsumer asObjIntConsumer(ObjIntConsumer objIntConsumer){ returnobjIntConsumer; } publicstatic ObjLongConsumer asObjLongConsumer(ObjLongConsumer objLongConsumer){ returnobjLongConsumer; } publicstatic Predicate asPredicate(Predicate predicate){ returnpredicate; } publicstatic Supplier asSupplier(Supplier supplier){ returnsupplier; } publicstatic ToDoubleBiFunction asToDoubleBiFunction(ToDoubleBiFunction toDoubleBiFunction){ returntoDoubleBiFunction; } publicstatic ToDoubleFunction asToDoubleFunction(ToDoubleFunction toDoubleFunction){ returntoDoubleFunction; } publicstatic ToIntBiFunction asToIntBiFunction(ToIntBiFunction toIntBiFunction){ returntoIntBiFunction; } publicstatic ToIntFunction asToIntFunction(ToIntFunction ioIntFunction){ returnioIntFunction; } publicstatic ToLongBiFunction asToLongBiFunction(ToLongBiFunction toLongBiFunction){ returntoLongBiFunction; } publicstatic ToLongFunction asToLongFunction(ToLongFunction toLongFunction){ returntoLongFunction; } publicstatic UnaryOperator asUnaryOperator(UnaryOperator unaryOperator){ returnunaryOperator; } privateFunctionCastUtil(){ } } Stream.of("A","","B").filter(asPredicate(String::isEmpty).negate()).count();
英文原文:https://dzone.com/articles/put-your-java-8-method-references-to-work
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。