为什么 - 在Java 1.8中 - 使用函数<V,R>而不是函数<R,V>?

Pau*_*aul 6 java generics functional-programming java-8

顺序似乎很奇怪,因为在常规Java中,始终首先指定返回类型.如:

public static double sum(Iterable<Number> nums) { ... }
Run Code Online (Sandbox Code Playgroud)

那么为什么在Function和BiFunction类中可以选择以相反的方式指定它们呢?如:

interface Function<T,R>
interface BiFunction<T,U,R>
Run Code Online (Sandbox Code Playgroud)

我不是在这里询问关于哪个更好的意见,但具体来说:

a)优先考虑一个订单而不是另一个订单是否有任何技术或其他(非风格)好处?或者它是一个随意的选择?

b)是否有人知道任何文件说明或权威来源的任何陈述的理由,为什么选择了另一个?

旁白:如果延伸到更高的城市,这个命令似乎更奇怪.例如,一个假设的QuadFunction:

interface QuadFunction<A,B,C,D,R> { ... }
Run Code Online (Sandbox Code Playgroud)

(在撰写本文时,图书馆中的最高权力是2 - 即BiFunction.)

请参阅:http://download.java.net/jdk8/docs/api/java/util/function/package-summary.html

Lan*_*Lan 13

它与先前存在的符号一致.

数学整数除法函数扩展为有理数:

(\): I x I -> Q
Run Code Online (Sandbox Code Playgroud)

上面的函数式编程版本(如Haskell,Ocaml)

division :: Integer -> (Integer -> Rational)

or

division :: Integer -> Integer -> Rational
Run Code Online (Sandbox Code Playgroud)

这三个人都说"分割函数需要两个整数并返回一个有理数".在功能范例中,它首先要说明你的回报.C告诉我们"我们在除法函数中返回一个有理数,它取两个整数"(ex float division(int a,int b){}).

在Java中,返回类型位于方法的左侧,因为Java想要看起来像C. C的设计者认为"int main(int argv,char*argv [])"看起来比"main(int argv,char*)好" argv [])int".在编写代码时,至少对我而言,在知道它需要什么之前,我经常会知道什么方法会返回.(编辑1:我们写了像String s = removeSpaces(textLine)这样的行,所以左边的返回符合左边的变量)

在C#中,func看起来与Java 8 Function相同.

  • 我认为杀手论证(我在答案中也提到)是它是数学和函数式编程中的既定符号.Java程序员对于`void doSomething()`是无用的,毫无意义和不赞成的领域是相当新的,因此他们更好地学习关于函数的先前约定. (2认同)

And*_*hev 6

我的猜测是方法链更直观,这可能是lambdas的典型用例,即

IntStream.range(1, 10).map(Ints::random).filter(x -> x % 2 == 0)
Run Code Online (Sandbox Code Playgroud)

因此,这里的方法序列从左到右读取,lambdas从左到右.那么为什么不使用类型参数从左到右?

进一步升级 - 原因可能是英语从左到右阅读.:-)

UPDATE

我很惊讶地发现这是数学现代阿拉伯语符号的发生:

拉丁文复数

拉丁复数

阿拉伯文复数

阿拉伯语复数

在这个例子中,每个char中的阿拉伯符号表示拉丁语.人们可以通过角度符号和i(imagenary unit)char 来跟踪它 - 在这两种情况下它都有一个点.在链接的wiki文章中,还有一个反向lim箭头的示例(与Java 8 lamda的箭头方向相比).这可能意味着阿拉伯语Java,如果它被开发出来,会看起来有点不同.:-)

免责声明:我有数学背景,但在回答这个问题时我不知道阿拉伯语符号.