一、Lambada表达式到底是什么
首先先看一下下面的一段代码!
package cn.org.kingdom.jdk8;
@FunctionalInterface
interface MyInterface {
void test();
String toString();
}
public class Test {
public void test(MyInterface inter) {
System.out.println("*************************");
inter.test();
System.out.println("*************************");
}
public static void main(String[] args) {
Test t = new Test();
t.test(()->{
System.out.println("lambada表达式实现");
});
MyInterface my =()->{};
System.out.println(my);
System.out.println(my.getClass());
System.out.println(my.getClass().getSuperclass());
System.out.println(my.getClass().getInterfaces()[0]);
}
}
打印结果如下
*************************
lambada表达式实现
*************************
cn.org.kingdom.jdk8.Test$$Lambda$2/9195351@18025c
class cn.org.kingdom.jdk8.Test$$Lambda$2/9195351
class java.lang.Object
interface cn.org.kingdom.jdk8.MyInterface
二、下面再次看一下之前的例子
List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
list.forEach(new Consumer() {
@Override
public void accept(Integer t) {
System.out.println(t);
}
});
对于list的foreach方法我们来看一下,这个方法的定义在什么地方
public interface Iterable {
Iterator iterator();
default void forEach(Consumer super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
default Spliterator spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}
对于以上的代码,我们可以看出在jdk1..8中,接口中增加了默认方法(保证了jdk1.8新特性的加入,同时也保证了jdk8与老版本的兼容),下面我们重点研究一下这个foreach方法
/**
* Performs the given action for each element of the {@code Iterable}
* until all elements have been processed or the action throws an
* exception. Unless otherwise specified by the implementing class,
* actions are performed in the order of iteration (if an iteration order
* is specified). Exceptions thrown by the action are relayed to the
* caller.
翻译如下:对于这个接口的每个元素执行给定的参数,直到所有的元素都被处理完毕,或者说操作抛出了一个异常,如果没有被实现类所指定的话,动作会被按照迭代的顺序来执行
是否抛出异常取决于调用者
*/
接下来,在看下Consumer接口的定义
package java.util.function;
import java.util.Objects;
/**
* Represents an operation that accepts a single input argument and returns no
* result. Unlike most other functional interfaces, {@code Consumer} is expected
* to operate via side-effects.
* 代表一个操作,这个操作接受一个单个的输入参数,并且不产生结果,和大多数函数接不同的是,它可能会产生副作用
*
* This is a functional interface
* whose functional method is {@link #accept(Object)}.
*这个函数式接口的函数式方法为accept
* @param the type of the input to the operation
*
* @since 1.8
*/
@FunctionalInterface
public interface Consumer {
/**
* Performs this operation on the given argument.
* @param t the input argument
*/
void accept(T t);
/**
* Returns a composed {@code Consumer} that performs, in sequence, this
* operation followed by the {@code after} operation. If performing either
* operation throws an exception, it is relayed to the caller of the
* composed operation. If performing this operation throws an exception,
* the {@code after} operation will not be performed.
*
* @param after the operation to perform after this operation
* @return a composed {@code Consumer} that performs in sequence this
* operation followed by the {@code after} operation
* @throws NullPointerException if {@code after} is null
*/
default Consumer andThen(Consumer super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
接下来,使用函数式接口的方式来对案例进行重新实现
List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
list.forEach(i->{
System.out.println(i);
});
Lambda表达式为java添加了缺失的函数式编程特性,使我们能将函数当成一等公民看待
在将函数作为一等公民的语言中,Lambda表达式的类型是函数,但在java中,Lambda表达式是对象,他们必须依附一类特别的对象类型-函数式接口
也可以通过以下方式进行实现
List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
//通过方法引用(method references)
list.forEach(System.out::print);
好了,今天就写到这里!关于Lambda表达式的基本使用,相信大家应该有一个基本的认识了