这是我的代码:
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();
}
});
};
}
}
我不明白这行的逻辑
Seq<String> s1 = seq.zip(split, Function::apply);
,这个Function::apply
是什么意思
我知道这是一个方法引用,但不知道这个引用的实例是什么
之一。 快速示例,假设您需要一个
Function<String, Integer>
,那么可以写
String::length
,尽管此方法具有不同的签名。要求的签名是:Integer apply(String x) { ... }
但是我们提供了一个只有
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)
现在,当你给出你的方法参考
Function::apply
,其签名是:
R apply(T t)
所以,在这种情况下:
Consumer<UnaryOperator<String>> apply(String u)
并且所需签名 (
UnaryOperator<String> t
) 的第一个参数再次从
Function::apply
是一个在 Function
实例上运行的非静态方法这一事实中推导出来,它恰好与 UnaryOperator<String>
兼容,因为UnaryOperator implements Function
.实施
Function::apply
本质上与将您的
BiFunction
实现为:Consumer<UnaryOperator<String>> apply(UnaryOperator<String> t, String u) {
return t.apply(u);
}
Function::apply
是方法引用,指的是
Seq s1 = seq.zip(split, Function::apply)
行中Function接口的apply方法。它作为 zip 方法的第二个参数,它需要一个 BiFunction
函数接口,并预期一个接受两个类型为 T
和 U
的参数并返回一个类型为 R
的结果。在这个例子中,T
是一个
UnaryOperator<String>
(来自Seq<UnaryOperator<String>> seq)
,U
是一个String(来自List<String> split
),而R
在执行zip方法时是一个String。因为String::apply
与 Function 接口的 apply 方法具有相同的签名,它接受一个 String 类型的参数并返回一个 String,它被用作对 Function::apply
方法的引用。seq 函数序列将通过 zip 方法应用于拆分列表的每个元素,因为迭代拆分列表的元素。 Function 接口的 apply 方法将用于将 seq 中的每个UnaryOperator<String>
应用到 split 中相应的 String 元素。