注:我这个只是简单地实现了表层的结构什么的,内部具体的优化什么的都没有关。而且,属于我的合理性猜测。只能说,如果让我简单的实现一个Stream的话,我会去这么做。
// X:一个只接收不返回的接口,基本相当于Consumer
// Y:一个接收并返回布尔值的接口,基本相当于Predicate
interface X {
void print(Object x);
}
interface Y {
boolean isTrue(Object x);
}
public class Main {
private static Main now = new Main();
private int[] a = {1, 2, 3, 4};
private boolean[] b = {true, true, true, true};
public static void main(String[] args) {
// 首先揭秘System.out::println是啥,就像现在这样,System.out是一个静态的类的对象,然后println是他的一个方法。
// 我这里用now和print方法来模拟了一下,写作now::print。
// 然后我们发现,就可以用一个函数式接口来接收它了。(要求参数类型和返回值类型一致!)
X x = now::print;
// x.print()就能输出了,是不是很方便呢?(对使用的人来说。其实可以发现底层还是写了个方法。。。)
x.print("abc"); // abc
// 可是Stram不是这么写的啊,他不是forEach(System.out::println)吗?
// 那么我们再写一个类似的实现,可以看到forEach接收的参数是一个接口X,然后遍历存储的数值,这里用一个静态数组来模拟
Main main1 = new Main();
main1.forEach(now::print);
// 输出了
// 1
// 2
// 3
// 4
// 还没完,我们知道,Stram是可以链式编程的,关键在于,要有返回!
// 我们再简单地写一个filter函数和一个forEach1
System.out.println("链式编程:");
Main main2 = new Main();
main2
.filter(xx -> (int)xx % 2 == 0)
.forEach1(now::print);
// 1
// 3
// 可以发现成功过滤掉了。
// 当然,你也可以先把它写成一个方法,再通过now来调用
System.out.println("过滤也使用两个:的版本:");
Main main3 = new Main();
main3
.filter(now::mod2)
.forEach1(now::print);
// 1
// 3
// 会发现也是正确的
}
private void print(Object x) {
System.out.println(x);
}
private void forEach(X x) {
for (int i = 0; i < a.length; i++) {
x.print(a[i]);
}
}
private Main filter(Y y) {
for (int i = 0; i < b.length; i++) {
b[i] = !y.isTrue(a[i]);
}
return this;
}
private Main forEach1(X x) {
for (int i = 0; i < a.length; i++) {
if(b[i]) x.print(a[i]);
}
return this;
}
private boolean mod2(Object x) {
return (int)x % 2 == 0;
}
}
lambda的确带来了非常多的便利!尤其是对使用者来说~