layout: post title: "Java8新特性之Lambda表达式" categories: Java tags: Java8 Lambda
new Thread(new Runnable(){
public void run(){
System.out.println("帅比辉");
}
};
).start();
如上,用到了匿名内部类,但这样做会造成代码重复率多,且臃肿,不易阅读,我们通过Lambda表达式改进一下:
new Thread(() -> {
System.out.println("傻比罗");
}).start();
想要用Lambda表达式需要满足方法参数需要是一个接口类型的参数,比如Thread的构造方法的参数就是一个Runnable接口,且接口只能有一个需要实现的方法,Runnable接口只有一个实现方法run(),Java8本身提供了很多这种函数式接口,如:
// 源码
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
Predicate<String> p = (s) -> s.length() > 0;
// 源码
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
Function<String, Integer> toInteger = (s) -> Integer.valueOf(s);
Function<String, String> backToString = toInteger.andThen((i) -> String.valueOf(i));
backToString.apply("123");
// 源码
@FunctionalInterface
public interface Supplier<T> {
T get();
}
Supplier<String> supplier = () -> "帅比辉";
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
Consumer<Person> greeter = (p) -> System.out.println("Hello, " + p.firstName);
greeter.accept(new Person("傻狗", "罗小狗"));
Java8自带还有很多这样的函数式接口,这里就不一一介绍了。
我们也可以自定以一个函数式接口:
@FunctionalInterface
public interface MyFunction<T> {
T get(T t);
}
MyFunction<Integer> function = (t) -> 100 * t;
从上面例子中可看到,Lambda表达式的基本语法:
(parameters) -> expression
或者是语句块:
(parameters) -> { statements; }
lambda表达式的语法由参数列表、箭头符号->
和函数体组成,而函数体可以是表达式也可以是语句块,其中,parameters表示接口方法的参数,如果没有指定类型,会根据上下文自动推断其类型:
现在我们知道了其实Lambda表达式就是简便了我们实现接口(该接口只能有一个抽象方法)的写法而已。
其实把Function那个实例改成方法引用更为恰当:
Function<String, Integer> toInteger = Integer::valueOf;
Function<String, String> backToString = toInteger.andThen(String::valueOf);
backToString.apply("123");
方法引用又是Lambda表达式的一种简化写法,其基本写法是左边是类名称,右边是方法,主要分为:
ClassName::methodName
Class::new