Pet*_*ete 3 java java-8 java-stream
我目前在许多适配器中都有这种模式:
entries.stream()
.filter(Entry.class::isInstance)
.map(Entry.class::cast)
.map(Entry::getFooBar)
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
条目是List实现特定接口的对象.不幸的是,界面 - 它是第三方库的一部分 - 没有定义常见的getter.要创建我想要的对象列表,我需要搜索它们,投射它们,并调用适当的getter方法.
我打算将它重构为一个帮助类:
public static <T, O> List<O> entriesToBeans(List<T> entries,
Class<T> entryClass, Supplier<O> supplier) {
return entries.stream()
.filter(entryClass::isInstance)
.map(entryClass::cast)
.map(supplier) // <- This line is invalid
.collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)
然后我会调用此方法进行转换:
Helper.entriesToBeans(entries,
Entry_7Bean.class,
Entry_7Bean::getFooBar);
Run Code Online (Sandbox Code Playgroud)
不幸的是,我无法将getter传递给重构函数并让地图调用它,因为map它期待一个函数.
像这样的方法:
class T {
public O get() { return new O(); }
}
Run Code Online (Sandbox Code Playgroud)
将映射到Function<T, O>.
因此,您只需将方法签名更改为:
public static <T, O> List<O> entriesToBeans(List<T> entries,
Class<T> entryClass, Function<T, O> converter) {
Run Code Online (Sandbox Code Playgroud)
更新:我怀疑,投射的原因是你的原始列表可能包含不是Ts的元素.所以你也可以将签名更改为:
public static <T, O> List<O> entriesToBeans(List<?> entries,
Class<T> entryClass, Function<T, O> converter) {
Run Code Online (Sandbox Code Playgroud)
然后你可以传递一个List<Object>,例如,只保留列表中的Ts,转换和转换.
作为参考,这是一个工作示例(打印John, Fred):
static class Person {
private final String name;
Person(String name) { this.name = name; }
String name() { return name; }
}
public static void main(String[] args) {
List<String> result = entriesToBeans(Arrays.asList(new Person("John"), new Person("Fred")),
Person.class, Person::name);
System.out.println("result = " + result);
}
public static <T, O> List<O> entriesToBeans(List<?> entries,
Class<T> entryClass, Function<T, O> converter) {
return entries.stream()
.filter(entryClass::isInstance)
.map(entryClass::cast)
.map(converter)
.collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)