首页 > 代码库 > Java8学习笔记(二)-函数式接口与方法引用
Java8学习笔记(二)-函数式接口与方法引用
一、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<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8); list.forEach(new Consumer<Integer>() { @Override public void accept(Integer t) { System.out.println(t); } });
对于list的foreach方法我们来看一下,这个方法的定义在什么地方
public interface Iterable<T> { Iterator<T> iterator();
default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } default Spliterator<T> 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.
* 代表一个操作,这个操作接受一个单个的输入参数,并且不产生结果,和大多数函数接不同的是,它可能会产生副作用 * * <p>This is a <a href="http://www.mamicode.com/package-summary.html">functional interface</a> * whose functional method is {@link #accept(Object)}. *这个函数式接口的函数式方法为accept * @param <T> the type of the input to the operation * * @since 1.8 */ @FunctionalInterface public interface Consumer<T> { /** * 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<T> andThen(Consumer<? super T> after) { Objects.requireNonNull(after); return (T t) -> { accept(t); after.accept(t); }; } }
接下来,使用函数式接口的方式来对案例进行重新实现
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8); list.forEach(i->{ System.out.println(i); });
Lambda表达式为java添加了缺失的函数式编程特性,使我们能将函数当成一等公民看待
在将函数作为一等公民的语言中,Lambda表达式的类型是函数,但在java中,Lambda表达式是对象,他们必须依附一类特别的对象类型-函数式接口
也可以通过以下方式进行实现
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8); //通过方法引用(method references) list.forEach(System.out::print);
好了,今天就写到这里!关于Lambda表达式的基本使用,相信大家应该有一个基本的认识了
Java8学习笔记(二)-函数式接口与方法引用