Lambda表达式
lambda表达式是java8的新特性。
可以把Lambda表达式理解为简洁的表示可传递的匿名函数的一种方式:它没有名称,但它有参数列表,函数主体,返回类型,可能还有一个可以抛出的异常列表。
java中引入了一个新的操作符’->'称为箭头操作符。
箭头操作符把lambda分成两部分:
- 左边:lambda表达式的参数列表
- 右边:lambda表达式所需要执行的功能,名lambda函数体
lambda表达式语法:
(1)语法一:无参、无返回值
interface Dog{
public void show();
}
//测试类
public class Test{
public static void main(String[] args) {
Dog dog = () ->{
System.out.println("萝莉");
};
Dog dog2 = () -> System.out.println("小萝莉"); //lambda表达式 只有一条语句 可以去掉中括号
dog.show();
dog2.show();
}
}
输出结果:
萝莉
小萝莉
(2)语法二:一个参数
interface Dog{
public void show(String x);
}
//测试类
public class Test{
public static void main(String[] args) {
Dog dog = (x) ->{
System.out.println(x);
};
Dog dog2 = x -> System.out.println(x); //lambda表达式 只有一个参数的时候可以去掉括号
dog.show("小萝莉");
dog2.show("赛高");
}
}
输出结果:
小萝莉
赛高
(3)语法三:多个参数,有返回值
package amazon;
interface Dog{
public int show(int x, int y);
}
//测试类
public class Test{
public static void main(String[] args) {
//Lambda表达有‘类型推断’
Dog dog = (x,y) -> { //忽略数据类型 不用int x,int y
System.out.println(x+"+"+y);
return x+y;
};
System.out.println(dog.show(3,6));
}
}
输出结果:
3+6
9
类型推断:Lambda 表达式中的参数类型都是由编译器推断 得出的。 Lambda 表达式中无需指定类型,程序依然可 以编译,这是因为 javac 根据程序的上下文,在后台 推断出了参数的类型。 Lambda 表达式的类型依赖于上 下文环境,是由编译器推断出来的。这就是所谓的 “类型推断”
方法引用
也是java8引进的新特性
方法引用的操作符是“::”两个冒号
方法引用和lambda表达式类似,lambda表达式是自定义抽象方法的实现方法,而方法引用是直接引用存在的实现方法(参数列表和lambda一样)
方法引用有四种方式
语法:
- 静态方法引用 : ClassName :: staticMethodName
- 构造器引用 : ClassName :: new
- 类的任意对象的实例方法引用: ClassName :: instanceMethodName
- 特定对象的实例方法引用 : object :: instanceMethodName
接下写示例给大家看:
静态方法引用
类名::静态方法
package amazon;
interface Dog{
public String show(String x,String y);
}
class Mog{
public static String show(String x,String y){
return x+y;
}
}
//测试类
public class Test{
public static void main(String[] args) {
Dog dog1 = Mog :: show;
String name1 = dog1.show("萝莉", "赛高");
System.out.println(name1+"--------1");
//效果同上
Dog dog2 = (x,y) -> Mog.show(x, y);
String name2 = dog2.show("萝莉", "赛高");
System.out.println(name2+"--------2");
}
}
输出结果:
萝莉赛高--------1
萝莉赛高--------2
这种方式必须是静态方法,而且方法还要一致才行
构造器引用
Class::new
package amazon;
interface Dog{
Mog show(String x);
}
class Mog{
String name;
public Mog() {
name = "";
}
public Mog(String x){
name = x;
}
}
//测试类
public class Test{
public static void main(String[] args) {
Dog dog1 = Mog :: new;
Mog mog1 = dog1.show("萝莉");
System.out.println(mog1.name+"--------1");
//效果同上
Dog dog2 = (x) -> new Mog("赛高");
Mog mog2 = dog2.show("赛高");
System.out.println(mog2.name+"--------2");
}
}
输出结果:
萝莉--------1
赛高--------2
类的任意对象的实例方法引用
类::实例方法
package amazon;
interface Dog<T>{
String show(T t,String x);
}
class Mog{
String name;
public String getString(String a) {
return this.name + a;
}
public String dogString(Dog<Mog> imTheOne, String str) {
String result = imTheOne.show(this, str);
return result;
}
}
//测试类
public class Test{
public static void main(String[] args) {
Mog mog1 = new Mog();
mog1.name = "萝莉";
String name1 = mog1.dogString(Mog :: getString , "赛高");
System.out.println(name1+"--------1");
//效果同上
Mog mog2 = new Mog();
mog2.name = "萝莉";
Dog dog2 = (x,y) -> mog2.getString(y);
String name2 = mog2.dogString(dog2, "赛高");
System.out.println(name2+"--------2");
}
}
输出结果:
萝莉赛高--------1
萝莉赛高--------2
这种模式下方法引用的方法必须是调用者对象所属类中的对象
特定对象的实例方法引用
package amazon;
interface Dog{
String show(String x,String y);
}
class Mog{
public String show(String x,String y){
return x+y;
}
}
//测试类
public class Test{
public static void main(String[] args) {
Mog mog1 = new Mog();
Dog dog1 = mog1 :: show;
String name1 = dog1.show("大萝莉", "拉姆");
System.out.println(name1+"--------1");
//效果同上
Mog mog2 = new Mog();
Dog dog2 = (x,y) -> mog2.show(x, y);
String name2 = dog2.show("小萝莉","蕾姆");
System.out.println(name2+"--------2");
}
}
输出结果:
大萝莉拉姆--------1
小萝莉蕾姆--------2
内建函数式接口
(1)功能型函数接口(输入一个数据,经过处理后输出一个数据)
interface Dog<T,R>{
R show(T t);
}
//测试类
public class Test{
public static void main(String[] args) {
Dog<Integer,String> dog = String :: valueOf;
System.out.println(dog.show(20).length());
}
}
输出结果:
2
(2)供给型函数式接口
interface Dog<T>{
T show();
}
//测试类
public class Test{
public static void main(String[] args) {
Dog<String> dog = "hello world" :: toUpperCase;
System.out.println(dog.show());
}
}
输出结果:
HELLO WORLD
(3)消费型函数式接口
interface Dog<T>{
void show(T t);
}
//测试类
public class Test{
public static void main(String[] args) {
Dog<String> dog = System.out :: printf;
dog.show("hello world");
}
}
输出结果:
hello world
(4)断言型函数式接口
interface Dog<T>{
boolean show(T t);
}
//测试类
public class Test{
public static void main(String[] args) {
Dog<String> dog = "##hello" :: startsWith;
System.out.println(dog.show("##"));
}
}
输出结果:
true