方法引用
我们都知道现在,我们可以使用方法引用,就像String::isEmpty在Java 8,当我们使用引用一个方法,例如,流在元素。 看看这个代码片段:
Stream.of("A", "", "B").filter(String::isEmpty).count();
这将产生结果1(因为只有一个空元素流)。 但是,如果我们想要过滤掉非空字符串,我们需要编写.filter(s -> !s.isEmpty())这是一个λ。 显然,这里有一个恼人的不对称。 我们可以使用一个方法参考,但不是它的否定。 我们可以写predicate.negate()但我们不能写String::isEmpty.negate()或!String::isEmpty。
这是为什么呢? 这是因为一个方法引用不是λ或功能接口。 然而,一个方法可以参考解决一个或多个功能接口使用Java的类型推断。 我们的String::isEmpty
事实上,可以至少得到解决:
Predicate<String>
Function<String, Boolean>
因此,我们需要以某种方式解决所有潜在的歧义和决定哪些功能接口我们想把方法参考。 读这篇文章,找出如何解决这个问题。 我已经使用本文提供的代码的开源项目Speedment使数据库看起来像Java 8流。 随时尝试Speedment。
Speedment还包含谓词建筑商,允许您使用功能实体。 名称::isEmpty和实体。 名字::isNotEmpty直接。
解决方法引用
问题可以通过引入部分固定一些“管道”的形式一个静态方法,参考和方法返回一个视图的一个特定的功能界面。 考虑一下这个简短的静态方法:
public static <T> Predicate<T> as(Predicate<T> predicate) {
return predicate;
}
现在,如果我们进口,静态方法我们可以,事实上,更容易使用方法参考,这个简单的例子所示:
Stream.of("A", "", "B").filter(as(String::isEmpty).negate()).count();
的代码将返回2流中的非空元素的数量。 这是一个进步的方法参考使用。 另一个好处是,这种解决方案允许我们组成谓词更容易,像这样:
.filter(as(String::isEmpty).negate().and("A"::equals))
解决所有方法引用
但是仍然有一个问题我们必须解决。 我们不仅可以创造很多静态的as()功能,因为方法引用可能可分解的几种类型的潜力as()方法以同样的方式列在这篇文章的开始。 所以,更好的方法是添加功能接口类型名称为每个静态方法,允许我们以编程方式选择一个特定的方法引用功能接口转换方法。 这是一个实用程序类,允许引用被转换为方法任何匹配功能界面,驻留在标准的Java包java.util.function。
直接从下拉的最新版本
GitHub在这里。
import java.util.function.*;
/**
*
* @author Per Minborg
*/
public class FunctionCastUtil {
public static <T, U> BiConsumer<T, U> asBiConsumer(BiConsumer<T, U> biConsumer) {
return biConsumer;
}
public static <T, U, R> BiFunction<T, U, R> asBiFunction(BiFunction<T, U, R> biFunction) {
return biFunction;
}
public static <T> BinaryOperator<T> asBinaryOperator(BinaryOperator<T> binaryOperator) {
return binaryOperator;
}
public static <T, U> BiPredicate<T, U> asBiPredicate(BiPredicate<T, U> biPredicate) {
return biPredicate;
}
public static BooleanSupplier asBooleanSupplier(BooleanSupplier booleanSupplier) {
return booleanSupplier;
}
public static <T> Consumer<T> asConsumer(Consumer<T> consumer) {
return consumer;
}
public static DoubleBinaryOperator asDoubleBinaryOperator(DoubleBinaryOperator doubleBinaryOperator) {
return doubleBinaryOperator;
}
public static DoubleConsumer asDoubleConsumer(DoubleConsumer doubleConsumer) {
return doubleConsumer;
}
public static <R> DoubleFunction<R> asDoubleFunction(DoubleFunction<R> doubleFunction) {
return doubleFunction;
}
public static DoublePredicate asDoublePredicate(DoublePredicate doublePredicate) {
return doublePredicate;
}
public static DoubleToIntFunction asDoubleToIntFunction(DoubleToIntFunction doubleToIntFunctiontem) {
return doubleToIntFunctiontem;
}
public static DoubleToLongFunction asDoubleToLongFunction(DoubleToLongFunction doubleToLongFunction) {
return doubleToLongFunction;
}
public static DoubleUnaryOperator asDoubleUnaryOperator(DoubleUnaryOperator doubleUnaryOperator) {
return doubleUnaryOperator;
}
public static <T, R> Function<T, R> asFunction(Function<T, R> function) {
return function;
}
public static IntBinaryOperator asIntBinaryOperator(IntBinaryOperator intBinaryOperator) {
return intBinaryOperator;
}
public static IntConsumer asIntConsumer(IntConsumer intConsumer) {
return intConsumer;
}
public static <R> IntFunction<R> asIntFunction(IntFunction<R> intFunction) {
return intFunction;
}
public static IntPredicate asIntPredicate(IntPredicate intPredicate) {
return intPredicate;
}
public static IntSupplier asIntSupplier(IntSupplier intSupplier) {
return intSupplier;
}
public static IntToDoubleFunction asIntToDoubleFunction(IntToDoubleFunction intToDoubleFunction) {
return intToDoubleFunction;
}
public static IntToLongFunction asIntToLongFunction(IntToLongFunction intToLongFunction) {
return intToLongFunction;
}
public static IntUnaryOperator asIntUnaryOperator(IntUnaryOperator intUnaryOperator) {
return intUnaryOperator;
}
public static LongBinaryOperator asLongBinaryOperator(LongBinaryOperator longBinaryOperator) {
return longBinaryOperator;
}
public static LongConsumer asLongConsumer(LongConsumer longConsumer) {
return longConsumer;
}
public static <R> LongFunction<R> asLongFunction(LongFunction<R> longFunction) {
return longFunction;
}
public static LongPredicate asLongPredicate(LongPredicate longPredicate) {
return longPredicate;
}
public static <T> LongSupplier asLongSupplier(LongSupplier longSupplier) {
return longSupplier;
}
public static LongToDoubleFunction asLongToDoubleFunction(LongToDoubleFunction longToDoubleFunction) {
return longToDoubleFunction;
}
public static LongToIntFunction asLongToIntFunction(LongToIntFunction longToIntFunction) {
return longToIntFunction;
}
public static LongUnaryOperator asLongUnaryOperator(LongUnaryOperator longUnaryOperator) {
return longUnaryOperator;
}
public static <T> ObjDoubleConsumer<T> asObjDoubleConsumer(ObjDoubleConsumer<T> objDoubleConsumer) {
return objDoubleConsumer;
}
public static <T> ObjIntConsumer<T> asObjIntConsumer(ObjIntConsumer<T> objIntConsumer) {
return objIntConsumer;
}
public static <T> ObjLongConsumer<T> asObjLongConsumer(ObjLongConsumer<T> objLongConsumer) {
return objLongConsumer;
}
public static <T> Predicate<T> asPredicate(Predicate<T> predicate) {
return predicate;
}
public static <T> Supplier<T> asSupplier(Supplier<T> supplier) {
return supplier;
}
public static <T, U> ToDoubleBiFunction<T, U> asToDoubleBiFunction(ToDoubleBiFunction<T, U> toDoubleBiFunction) {
return toDoubleBiFunction;
}
public static <T> ToDoubleFunction<T> asToDoubleFunction(ToDoubleFunction<T> toDoubleFunction) {
return toDoubleFunction;
}
public static <T, U> ToIntBiFunction<T, U> asToIntBiFunction(ToIntBiFunction<T, U> toIntBiFunction) {
return toIntBiFunction;
}
public static <T> ToIntFunction<T> asToIntFunction(ToIntFunction<T> ioIntFunction) {
return ioIntFunction;
}
public static <T, U> ToLongBiFunction<T, U> asToLongBiFunction(ToLongBiFunction<T, U> toLongBiFunction) {
return toLongBiFunction;
}
public static <T> ToLongFunction<T> asToLongFunction(ToLongFunction<T> toLongFunction) {
return toLongFunction;
}
public static <T> UnaryOperator<T> asUnaryOperator(UnaryOperator<T> unaryOperator) {
return unaryOperator;
}
private FunctionCastUtil() {
}
}
所以之后我们有进口相关的静态方法,我们可以写:
Stream.of("A", "", "B").filter(asPredicate(String::isEmpty).negate()).count();
一个更好的解决方案
如果所有的那就更好了功能接口本身包含一个静态方法,可能需要一个合适的方法引用,并把它变成一个类型的功能界面。 例如,Java的标准Predicate功能界面就会是这个样子:
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {...}
default Predicate<T> negate() {...}
default Predicate<T> or(Predicate<? super T> other) {...}
static <T> Predicate<T> isEqual(Object targetRef) {...}
// New proposed support method to return a
// Predicate view of a Functional Reference
public static <T> Predicate<T> of(Predicate<T> predicate) {
return predicate;
}
}
这将允许我们写:
Stream.of("A", "", "B").filter(Predicate.of(String::isEmpty).negate()).count();
我个人认为这看起来不错!
JDK开发者联系离你最近的开放,使提案!
如果你想学好JAVA这门技术,也想在IT行业拿高薪,可以参加我们的训练营课程,选择最适合自己的课程学习,技术大牛亲授,7个月后,进入名企拿高薪。我们的课程内容有:Java工程化、高性能及分布式、高性能、深入浅出。高架构。性能调优、Spring,MyBatis,Netty源码分析和大数据等多个知识点。如果你想拿高薪的,想学习的,想就业前景好的,想跟别人竞争能取得优势的,想进阿里面试但担心面试不过的,你都可以来,群号为:654675708
注:加群要求
1、具有1-5工作经验的,面对目前流行的技术不知从何下手,需要突破技术瓶颈的可以加。
2、在公司待久了,过得很安逸,但跳槽时面试碰壁。需要在短时间内进修、跳槽拿高薪的可以加。
3、如果没有工作经验,但基础非常扎实,对java工作机制,常用设计思想,常用java开发框架掌握熟练的,可以加。
4、觉得自己很牛B,一般需求都能搞定。但是所学的知识点没有系统化,很难在技术领域继续突破的可以加。
5.阿里Java高级大牛直播讲解知识点,分享知识,多年工作经验的梳理和总结,带着大家全面、科学地建立自己的技术体系和技术认知!
6.小号加群一律不给过,谢谢。