这是CompletionStage的类定义
public interface CompletionStage<T> {
...
}
这是方法thenApply
public <U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn);
我的问题是:为什么要服用? super T 作为函数的第一个参数......不应该是吗?扩展T ,因为T的任何子类都可以转换为T?并且任何超级T都不能被强制转换为T ??
答案 0 :(得分:2)
我通过询问哪个签名最有意义来解决这个问题?有三种选择:
Function<T, ? extends U>
Function<? super T, ? extends U>
? extends T
首先,T
不包含Function<T, U>
。因此,您无法将CompletionStage<T>
传递给? extends T
,这可能会出乎意料。所以T
不是最好的选择。
这使我们只需? super T
或T
。
简单Function<T, U>
适用于? super T
,就像? super T
一样。但哪个更好? T
允许您应用参数T
或超级T
的函数。与简单CompletionStage<Integer>.thenApply(Function<Number, String>)
相比,这更灵活,因为您可以使用更多通用函数。例如,您可以使用简单的T
执行? super T
。 ? super T
似乎也没有任何缺点,至少我没有看到任何缺点。
所以从我的观点来看,data <- read.table(text="Company Tag
CompanyA TagA
CompanyA TagB
CompanyA TagC
CompanyB TagA
CompanyB TagB
CompanyB TagC
CompanyB TagD
CompanyB TagE
CompanyB TagF
CompanyC TagA
CompanyC TagB
CompanyC TagC
CompanyC TagD
",header=TRUE)
library(reshape2)
d = dcast(data,Company~Tag,value.var = "Tag")
names(d)[grep("^Tag", names(d))] = paste("Tag", 1:(ncol(d)-1), sep = "" )
显然是更好的选择。