如何在Java8流中调用参数化getter作为映射器? 用例

如何在Java8流中调用参数化getter作为映射器? 用例,java,java-8,java-stream,Java,Java 8,Java Stream,我目前在许多适配器中都有这种模式: entries.stream() .filter(Entry.class::isInstance) .map(Entry.class::cast) .map(Entry::getFooBar) .collect(Collectors.toList()); 其中,条目是实现特定接口的对象的列表。不幸的是,接口(第三方库的一部分)没有定义公共getter。要创建所需对象的列表,我需要搜索它们,强制转

我目前在许多适配器中都有这种模式:

entries.stream()
        .filter(Entry.class::isInstance)
        .map(Entry.class::cast)
        .map(Entry::getFooBar)
        .collect(Collectors.toList());
其中,条目是实现特定接口的对象的
列表。不幸的是,接口(第三方库的一部分)没有定义公共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());
}
不幸的是,我无法将getter传递到重构函数并让map调用它,因为
map
需要一个函数

问题:
  • 在重构版本中如何调用getter
    • 一种方法,如:

      class T {
        public O get() { return new O(); }
      }
      
      将映射到一个
      函数

      因此,您只需将方法签名更改为:

      public static <T, O> List<O> entriesToBeans(List<T> entries,
              Class<T> entryClass, Function<T, O> converter) {
      
      public static <T, O> List<O> entriesToBeans(List<?> entries,
              Class<T> entryClass, Function<T, O> converter) {
      

      您应该传递一个
      函数

      public static <T, O> List<O> entriesToBeans(List<T> entries, Class<T> entryClass, 
                                     Function<T, O> mapper) {
          return entries.stream().filter(entryClass::isInstance)
                        .map(entryClass::cast).map(mapper)
                        .collect(Collectors.toList());
      }
      
      publicstaticlist entriesToBeans(列表条目、类entryClass、,
      函数映射器){
      返回条目.stream().filter(entryClass::isInstance)
      .map(entryClass::cast).map(映射器)
      .collect(Collectors.toList());
      }
      
      Java在我尝试此操作时抱怨:
      Helper.entriesToBeans(entries,entry7bean.class,entry7bean::getFooBar)谢谢你的帮助。不幸的是,它仍然在调用端产生错误<代码>类型条目_7Bean没有定义适用的getFooBar(T)
      。出于某种原因,它将方法引用视为一个对象。。。这是有道理的。有没有可能让map使用supplier/converter调用实例方法?@Pete忽略我之前的评论。您不需要将其设置为静态。请参阅我编辑的答案中的完整示例。@正如霍尔格所评论的那样,
      列表
      就足够了。这是什么
      ::应用
      东西?为什么每个人都对将
      函数
      转换为
      函数
      如此感兴趣?就因为方法引用看起来很花哨吗?@Holger该死。我总是这样做:(令人着迷的是,你不是唯一一个……为什么要执行
      .filter(entryClass::isInstance).map(entryClass::cast)
      当源是一个
      列表
      并且
      入口类
      是一个
      时,换句话说,源已经保证只包含适当类型的项?@Holger使用
      List@assylias:只需列出
      ,因为它与
没有任何关系。@Holger yu你又对了!;-)
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());
}
public static <T, O> List<O> entriesToBeans(List<T> entries, Class<T> entryClass, 
                               Function<T, O> mapper) {
    return entries.stream().filter(entryClass::isInstance)
                  .map(entryClass::cast).map(mapper)
                  .collect(Collectors.toList());
}