Java 8 Lambda 表达式

Lambda 表达式,它是推动 Java 8 发布的最重要新特性。

Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。

使用 Lambda 表达式可以使代码变的更加简洁紧凑。

1、语法

lambda 表达式的语法格式如下:

(parameters) -> expression
或
(parameters) ->{ statements; }

2、lambda表达式特征

 1.可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
 2.可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
 3.可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
 4.可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。

示例:

//入参为空
TestDemo no_param = () -> "hi, no param";
TestDemo no_param2 = () -> { return "hi, no param"; };
System.out.println(no_param.hi());

//单个参数
TestDemo2 param = name -> name;
TestDemo2 param2 = name -> { return name;};
System.out.println(param.hei("hei, grils"));

//多个参数
TestDemo3 multiple = (String hello, String name) -> hello + " " + name;
//一条返回语句,可以省略大括号和return
TestDemo3 multiple2 = (hello, name) -> hello + name;
//多条处理语句,需要大括号和return
TestDemo3 multiple3 = (hello, name) -> {
    System.out.println("进入内部");
    return hello + name;
};
System.out.println(multiple.greet("hello", "lambda"));

3、方法引用

有以下几种类型

3.1 对象::实例方法,将 lambda 的参数当做方法的参数使用

objectName::instanceMethod

示例:

Consumer<String> sc = System.out::println;
//等效
Consumer<String> sc2 = (x) -> System.out.println(x);
sc.accept("618, 狂欢happy");

3.2 类::静态方法,将lambda的参数当做方法的参数使用

ClassName::staticMethod

示例:

//ClassName::staticMethod  类的静态方法:把表达式的参数值作为staticMethod方法的参数
Function<Integer, String> sf = String::valueOf;
//等效
Function<Integer, String> sf2 = (x) -> String.valueOf(x);
String apply1 = sf.apply(61888);

3.3 类::实例方法,将lambda的第一个参数当做方法的调用者,其他的参数作为方法的参数。开发中尽量少些此类写法,减少后续维护成本。

ClassName::instanceMethod

示例:

//ClassName::instanceMethod  类的实例方法:把表达式的第一个参数当成instanceMethod的调用者,其他参数作为该方法的参数
BiPredicate<String, String> sbp = String::equals;
//等效
BiPredicate<String, String> sbp2 = (x, y) -> x.equals(y);
boolean test = sbp.test("a", "A");

4、构造函数

无参的构造方法就是类::实例方法模型,如:

Supplier<User> us = User::new;
//等效
Supplier<User> us2 = () -> new User();
//获取对象
User user = us.get();

当有参数时:

//一个参数,参数类型不同则会编译出错
Function<Integer, User> uf = id -> new User(id);
//或加括号
Function<Integer, User> uf2 = (id) -> new User(id);
//等效
Function<Integer, User> uf3 = (Integer id) -> new User(id);
User apply = uf.apply(61888);

//两个参数
BiFunction<Integer, String, User> ubf = (id, name) -> new User(id, name);
User 狂欢happy = ubf.apply(618, "狂欢happy");

5、继承及实现具有相同默认方法的父类或接口问题

接口A:

public interface A {
    String hi();
    String greet();
    default void hello() {
        System.out.println("A.hello");
    }
}

接口B:

public interface B {
    String hi();
    String hh();
    default void hello() {
        System.out.println("B.hello");
    }
}

类C实现A,B:

public class C implements A, B{

    @Override
    public String hi() {
        return "C.hi";
    }

    @Override
    public String greet() {
        return "C.greet";
    }

    @Override
    public String hh() {
        return "C.hh";
    }

    /**
     * 子类优先继承父类的方法, 如果父类没有相同签名的方法,才继承接口的默认方法。
     * 编译报错解决1:覆盖法
     */
    @Override
    public void hello() {
        System.out.println("C.hello");
    }

    /**
     * 编译报错解决2:指定实现的父接口
     */
//    @Override
//    public void hello() {
//        A.super.hello();
        B.super.hello();
//    }

}

此时若不处理hello方法时,类C将编译出错,解决方式要么覆盖,要么指定实现父接口的该方法。

进一步测试继承具有相同方法的父类:

类D:

public class D {
    public void hello() {
        System.out.println("D.hello");
    }
}

类 C 继承类 D:

public class C extends D implements A, B{

    @Override
    public String hi() {
        return "C.hi";
    }

    @Override
    public String greet() {
        return "C.greet";
    }

    @Override
    public String hh() {
        return "C.hh";
    }

}

此时若不覆盖或指定父接口的方法时,类C将继承类D的hello方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值