我正在执行一系列流操作来展平有效的二维数组。
Arrays.stream(attributes)
.map(Attribute::getCommand)
.filter(Optional::isPresent)
.map(Optional::get)
.flatMap((array) -> (Arrays.stream((String[]) array)))
.toArray(String[]::new)
哪里Attribute
符合以下接口(interface):
public interface Attribute<T> {
Optional<String[]> getCommand();
}
然而,最终flatMap()
调用未按预期运行。
.flatMap((array) -> (Arrays.stream((String[]) array)))
工作得很好。.flatMap((array) -> (Arrays.stream(array)))
编译失败java: no suitable method found for stream(java.lang.Object)
..flatMap(Arrays::stream)
编译失败java: incompatible types: cannot infer type-variable(s) T (argument mismatch; java.lang.Object cannot be converted to T[])
.
在我看来,类型应该可以很好地推断出来。 IntelliJ 同意并将强制转换标记为冗余,并且三种实现中的任何一种都没有显示编译错误。 为什么 Java 需要这种明显多余的类型转换?
我还尝试了以下极简实现:
import java.util.Arrays;
import java.util.Optional;
public class Streaming {
public static void main(String[] args) {
Optional<String[]>[] myarray = new Optional[]{Optional.of(new String[]{"Hello", "world"}),
Optional.empty(), Optional.of(new String[]{"Foo"})};
System.out.println(Arrays.toString(Arrays.stream(myarray).filter(Optional::isPresent).map
(Optional::get).flatMap(Arrays::stream).toArray(String[]::new)));
}
}
它在所有三种实现中都能正常工作,输出预期的 [Hello, world, Foo]
.
编辑:
这被标记为 this question 的重复项。我可能是错的,但似乎存在区别,因为类型是以更明确的方式指定的。值得注意的是,IntelliJ 同意在上述帖子提供的示例中强制转换是必要的,但对于我的代码则不然。如果我错了,请告诉我。
编辑:
根据请求,声明attributes
是 Attribute[] attributes = new Attribute[]{...}
哪里...
是Attribute的多种实现。
请您参考如下方法:
Attribute
是一个泛型类(我想知道为什么不使用 T
)。
如果出现此错误,则意味着您声明了原始类型,例如:
Attribute[] attributes = ...;
对于原始类型,返回类型为 getCommand()
声明为 Optional<String[]>
变成 Optional
.
声明Attribute
作为泛型类型,例如:Attribute<String>[] attributes = ...;
这应该在不进行强制转换的情况下进行编译,或者仅删除参数化类型 T
如果不需要。