商务网站的建设与管理,做百度推广一定要有自已网站,好的网站推荐一个,wordpress 下一篇插件本节将介绍如何使用Lambda表达式简化匿名内部类的书写#xff0c;但Lambda表达式并不能取代所有的匿名内部类#xff0c;只能用来取代函数接口#xff08;Functional Interface#xff09;的简写。先别在乎细节#xff0c;看几个例子再说。
例子1#xff1a;无参函数的简…本节将介绍如何使用Lambda表达式简化匿名内部类的书写但Lambda表达式并不能取代所有的匿名内部类只能用来取代函数接口Functional Interface的简写。先别在乎细节看几个例子再说。
例子1无参函数的简写
如果需要新建一个线程一种常见的写法是这样
// JDK7 匿名内部类写法
new Thread(new Runnable(){// 接口名Overridepublic void run(){// 方法名System.out.println(Thread run());}
}).start();
上述代码给Tread类传递了一个匿名的Runnable对象重载Runnable接口的run()方法来实现相应逻辑。这是JDK7以及之前的常见写法。匿名内部类省去了为类起名字的烦恼但还是不够简化在Java 8中可以简化为如下形式
// JDK8 Lambda表达式写法
new Thread(() - System.out.println(Thread run())// 省略接口名和方法名
).start();
上述代码跟匿名内部类的作用是一样的但比匿名内部类更进一步。这里连接口名和函数名都一同省掉了写起来更加神清气爽。如果函数体有多行可以用大括号括起来就像这样
// JDK8 Lambda表达式代码块写法
new Thread(() - {System.out.print(Hello);System.out.println( Hoolee);}
).start();
例子2带参函数的简写
如果要给一个字符串列表通过自定义比较器按照字符串长度进行排序Java 7的书写形式如下
// JDK7 匿名内部类写法
ListString list Arrays.asList(I, love, you, too);
Collections.sort(list, new ComparatorString(){// 接口名Overridepublic int compare(String s1, String s2){// 方法名if(s1 null)return -1;if(s2 null)return 1;return s1.length()-s2.length();}
});
上述代码通过内部类重载了Comparator接口的compare()方法实现比较逻辑。采用Lambda表达式可简写如下
// JDK8 Lambda表达式写法
ListString list Arrays.asList(I, love, you, too);
Collections.sort(list, (s1, s2) -{// 省略参数表的类型if(s1 null)return -1;if(s2 null)return 1;return s1.length()-s2.length();
});
上述代码跟匿名内部类的作用是一样的。除了省略了接口名和方法名代码中把参数表的类型也省略了。这得益于javac的类型推断机制编译器能够根据上下文信息推断出参数的类型当然也有推断失败的时候这时就需要手动指明参数类型了。注意Java是强类型语言每个变量和对象都必需有明确的类型。 简写的依据
也许你已经想到了能够使用Lambda的依据是必须有相应的函数接口函数接口是指内部只有一个抽象方法的接口。这一点跟Java是强类型语言吻合也就是说你并不能在代码的任何地方任性的写Lambda表达式。实际上Lambda的类型就是对应函数接口的类型。Lambda表达式另一个依据是类型推断机制在上下文信息足够的情况下编译器可以推断出参数表的类型而不需要显式指名。Lambda表达更多合法的书写形式如下
// Lambda表达式的书写形式
Runnable run () - System.out.println(Hello World);// 1
ActionListener listener event - System.out.println(button clicked);// 2
Runnable multiLine () - {// 3 代码块System.out.print(Hello);System.out.println( Hoolee);
};
BinaryOperatorLong add (Long x, Long y) - x y;// 4
BinaryOperatorLong addImplicit (x, y) - x y;// 5 类型推断
上述代码中1展示了无参函数的简写2处展示了有参函数的简写以及类型推断机制3是代码块的写法4和5再次展示了类型推断机制。 自定义函数接口
自定义函数接口很容易只需要编写一个只有一个抽象方法的接口即可。
// 自定义函数接口
FunctionalInterface
public interface ConsumerInterfaceT{void accept(T t);
}
上面代码中的FunctionalInterface是可选的但加上该标注编译器会帮你检查接口是否符合函数接口规范。就像加入Override标注会检查是否重载了函数一样。
有了上述接口定义就可以写出类似如下的代码
ConsumerInterfaceString consumer str - System.out.println(str);
进一步的还可以这样使用
class MyStreamT{private ListT list;...public void myForEach(ConsumerInterfaceT consumer){// 1for(T t : list){consumer.accept(t);}}
}
MyStreamString stream new MyStreamString();
stream.myForEach(str - System.out.println(str));// 使用自定义函数接口书写Lambda表达式