如何指定Stream.map的输出类型?

How to specify output type of Stream.map?

试图用我的 class Establishment 包装流元素,但它无法推断构造函数的输出类型,认为它是一个对象流:

java: cannot find symbol
  symbol:   method getEstablishment()
  location: class java.lang.Object

为什么以及如何修复?

无法以任何方式指定类型

return q.getResultStream().<Establishment>map(Establishment::new).findFirst().orElse(new Establishment()).getEstablishment();

还有可能吗?

好像,某处有raw types:

To create a parameterized type of Box, you supply an actual type argument for the formal type parameter T:

Box<Integer> intBox = new Box<>();

If the actual type argument is omitted, you create a raw type of Box:

Box rawBox = new Box();

您的代码中可能是:

  • q.getResultStream() returns 原始 Stream.

    该方法类似于:

    public Stream getResultStream() {
        return Stream.of();
    }
    
  • Return getResultStream 类型不是原始类型,但 q 类型本身就是原始类型。例如:

    public class Page<T> {
        public Stream<T> stream() {
            return Stream.of();
        }
    }
    
    public class Main {
        public static void test(Page q) {
            //                  ^^^^ raw type
            q.stream();
        }
    }
    

尽管原因如此,但问题是:使用原始类型时 one loses:

the ability to use generics in any way for instance members

所以流的任何进一步使用 returns raw StreamEstablishment的方法变成“不可见”,编译失败。

可能的修复:

  1. 显式演员介绍:

    Establishment establishment = ((Stream<?>) q.getResultStream())
            .map(Establishment::new)
            .findFirst()
            .orElseGet(Establishment::new);
    
    • Stream 转换为 Stream<?>,即 unbounded wildcard type
    • map方法中的Function可以看作是一个函数,接受一个Object,返回一个T(Establsihment)
  2. 原始类型消除

    • 原始类型用于向后兼容
    • 它们几乎不存在于现代源代码中(泛型在 2004 年发布的 Java 5 中引入)
    • 高度建议避免它们
      • What is a raw type and why shouldn't we use it?

Can't specify type in any way

 return q.getResultStream()
   .<Establishment>map(Establishment::new)
   .findFirst()
   .orElse(new Establishment())
   .getEstablishment();

is it still possible?

请注意,Intellij IDEA 在那里可能有点误导。

这是 javac 编译的最小示例:

public class WhosebugDemoApplication {
    private static Stream getRawStream() {
        return Stream.of(1, 2, 3);
    }

    public static void test() {
        getRawStream().<Integer>map(it -> it + "")
                .forEach(System.out::println);
    }


    public static void main(String[] args) {
        test();
    }
}

但 intellij 显示错误: