我有兴趣编写一个通用的 split 方法,它可以像这样调用:
List<String> names = splitField("John, Nate, Larry", String::valueOf);
List<Integer> ages = splitField("35, 23, 48", Integer::valueOf);
Run Code Online (Sandbox Code Playgroud)
这是我的实现:
private <T, R> List<R> splitField(String stringWithComma, Function<T, R> valueOf) {
List<R> elements = new ArrayList<>();
if (stringWithComma != null && !stringWithComma.isEmpty()) {
elements = Arrays.stream(stringWithComma.split(","))
.map(valueOf)
.collect(Collectors.toList());
}
return elements;
}
Run Code Online (Sandbox Code Playgroud)
它没有建立,我在这里错过了什么?
谢谢!
编辑 1:
此实现构建并运行良好,使用 调用String::valueOf
,但在调用时抛出异常Integer::valueOf
private <R> List<R> splitField(String elementsWithComma, Function<String, R> valueOf) {
List<R> elements = new ArrayList<>();
if (elementsWithComma != null && !elementsWithComma.isEmpty()) {
elements = Arrays.stream(elementsWithComma.split(","))
.map(valueOf)
.collect(Collectors.toList());
}
return elements;
}
Run Code Online (Sandbox Code Playgroud)
您声明的类型参数T
,你真正想要的String
,因为函数应该要处理,你知道是一个值String
来R
。删除类型参数T
并将函数更改为Function<String, R>
.
private <R> List<R> splitField(String stringWithComma, Function<String, R> valueOf) {
List<R> elements = new ArrayList<>();
if (stringWithComma != null && !stringWithComma.isEmpty()) {
elements = Arrays.stream(stringWithComma.split(",\\s*"))
.map(valueOf)
.collect(Collectors.toList());
}
return elements;
}
Run Code Online (Sandbox Code Playgroud)
请注意,我还更改了拆分模式以使其占用逗号后的空间,以避免解析异常。
遵循PECS规则,您可以放宽函数签名,以支持更多用例。
private <R> List<R> splitField(String stringWithComma, Function<String, R> valueOf) {
List<R> elements = new ArrayList<>();
if (stringWithComma != null && !stringWithComma.isEmpty()) {
elements = Arrays.stream(stringWithComma.split(",\\s*"))
.map(valueOf)
.collect(Collectors.toList());
}
return elements;
}
Run Code Online (Sandbox Code Playgroud)