这三段代码其实是一致的
//生成随机数流
Stream<Double> randoms = Stream.generate(Math::random);
Stream<Double> randoms2 = Stream.generate(() -> Math.random());
Stream<Double> randoms3 = Stream.generate(new Supplier<Double>() {
@Override
public Double get() {
return Math.random();
}
});
后面两段我都能理解,第一段为什么 Math 的静态方法也算是可以当做 Supplier 接口的实现者,我有点想不通
1
passerbytiny 2021-07-23 00:46:10 +08:00 via Android
第一,Math::random 是 () -> Math.random() 的等价简写。
第二,Math::random 是 lambda 表达式,不是静态方法。 |
2
0576coder OP |
3
zhady009 2021-07-23 09:47:43 +08:00
因为 Supplier 是没有入参有返回值的方法, Math.random 也是一样 所以可以用静态方法引用
其他的还有构造器和实例方法 |
4
ztcaoll222 2021-07-23 10:54:08 +08:00
第一个就是个语法糖,等价于第二个
|
5
unco020511 2021-07-23 11:20:06 +08:00
第一个和第二个你都可以理解为是语法糖,第三个是原始写法
|
6
mijazz 2021-07-23 14:24:55 +08:00
上面讲的都蛮清晰暴力了,我来凑个热闹。[functional interface]( https://mijazz.icu/posts/Functional-Interface-and-its-Underlying-Pattern/#:~:text=Supplier%3CT%3E,LocalDate%3A%3Anow)
第一个写法是用 double colon(`::`)表示的 Method Declaration,它既可以作用在静态方法也能作用在实例方法上,且用`::new`也能作为 Constructor 的 Method Declaration 。 至于`Supplier`,只是`java.util.function`下面的众多函数式接口的一类,只要符合不接参数但又返回一个参数的方法,都能被 method declaration 看作是 supplier 类型的函数式接口。 且鉴于第三种写法我感觉我像在 Effective Java 里看过,不建议,因为你的返回类是基本类型是 int,double,long 里的一种,在上述包内有提供上述三个原始类作为返回值的特殊 functional interface,在这个情况下是 DoubleSupplier,你就不用使用包装类来增加多一轮装箱拆箱了。 题外话,为什么不用`ThreadLocalRandom`的`DoubleStream`呢 :-) 有错的请加以指正。 |
7
ikas 2021-07-25 11:00:22 +08:00
第一种是方法引用,第二种 lambda 表达式
另外第一种与第二种不完全等价,他们具体的实现,是根据不同情况有区别的 |