Osi*_*ris 3 java lambda method-reference
我对以下行感到困惑:
Seq<String> s1 = seq.zip(split, Function::apply);
Run Code Online (Sandbox Code Playgroud)
在这个片段中:
static String underscoreToCamel(String str) {
UnaryOperator<String> capitalize = s -> s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
Seq<UnaryOperator<String>> seq = c -> {
c.accept(String::toLowerCase);
while (true) {
c.accept(capitalize);
}
};
List<String> split = Arrays.asList(str.split("_"));
Seq<String> s1 = seq.zip(split, Function::apply);
String a = s1.join("");
return a;
}
public interface Seq<T> {
void consume(Consumer<T> consumer);
static <T> Seq<T> unit(T t) {
return consumer -> consumer.accept(t);
}
default <E> Seq<E> map(Function<T, E> function) {
return consumer -> consume(t -> consumer.accept(function.apply(t)));
}
default <E> Seq<E> flatMap(Function<T, Seq<E>> function) {
return consumer -> consume(t -> function.apply(t).consume(consumer));
}
default String join(String sep) {
StringJoiner joiner = new StringJoiner(sep);
consume(t -> joiner.add(t.toString()));
return joiner.toString();
}
static <T> T stop() {
throw StopException.INSTANCE;
}
default void consumeTillStop(Consumer<T> consumer) {
try {
consume(consumer);
} catch (StopException ignore) {}
}
default <U, R> Seq<R> zip(Iterable<U> iterable, BiFunction<T, U, R> function) {
return c -> {
Iterator<U> iterator = iterable.iterator();
consumeTillStop(t -> {
if (iterator.hasNext()) {
c.accept(function.apply(t, iterator.next()));
} else {
stop();
}
});
};
}
}
Run Code Online (Sandbox Code Playgroud)
我确实明白这Function::apply
是一个方法引用,并且该方法需要一个BiFunction<T, U, R>
. 但我不明白这是如何兼容的。
它到底解决了什么?Function::apply
为什么在这种情况下我可以供货?
这确实是一个有趣的规则,因为它使用了方法引用允许的特殊规则之一。
简单的例子,假设您需要一个Function<String, Integer>
,那么可以写String::length
,即使这个方法有不同的签名。请求的签名是:
Integer apply(String x) { ... }
Run Code Online (Sandbox Code Playgroud)
但我们提供了一个只有 的方法int length()
,所以String
根本没有参数。但是,该方法是非静态的,并且在 的实例上运行String
。因此,Java 可以假设您打算在该实例上调用该方法,并由此推导出该方法的第一个参数。IE s -> s.length()
。
您的设置中也会发生同样的情况。首先,您必须了解您请求的泛型BiFunction<T, U, R>
解析的内容。他们是:
T
:UnaryOperator<String>
U
:String
R
:Consumer<T>
, 所以Consumer<UnaryOperator<String>>
相当复杂,但是还可以。
现在,请求的签名是:
Consumer<UnaryOperator<String>> apply(UnaryOperator<String> t, String u)
Run Code Online (Sandbox Code Playgroud)
当您提供方法引用时Function::apply
,其签名为:
R apply(T t)
Run Code Online (Sandbox Code Playgroud)
所以,在这种情况下:
Consumer<UnaryOperator<String>> apply(String u)
Run Code Online (Sandbox Code Playgroud)
然后,再次从所需签名 ( UnaryOperator<String> t
) 中的第一个参数中扣除,该方法Function::apply
是对实例进行操作的非静态方法Function
,该方法恰好与 兼容UnaryOperator<String>
,因为UnaryOperator extends Function
。
所以Function::apply
本质上与实现您的 as 相同BiFunction
:
Consumer<UnaryOperator<String>> apply(UnaryOperator<String> t, String u) {
return t.apply(u);
}
Run Code Online (Sandbox Code Playgroud)
从第一个参数获取函数并将其应用于第二个参数,返回结果。
归档时间: |
|
查看次数: |
102 次 |
最近记录: |