今天看到了类似的代码,我表示一脸懵逼
List<String> list= Arrays.asList("阿里", "华为", "哔哩哔哩");
list.forEach(System.out::println);
执行结果:
阿里
华为
哔哩哔哩
查了很多资料
下面是我自己的一些理解
首先分析list.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.
*
* @implSpec
* <p>The default implementation behaves as if:
* <pre>{@code
* for (T t : this)
* action.accept(t);
* }</pre>
*
* @param action The action to be performed for each element
* @throws NullPointerException if the specified action is null
* @since 1.8
*/
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
我们看到这个方法需要一个Consumer,@FunctionalInterface标记在该接口上, “函数式接口”是指仅仅只包含一个抽象方法的接口。这个仅有一个accept(T t)抽象方法。
那我们就new 一个Consumer传进去
// 1、基本写法
Consumer<Object> consumer = new Consumer<Object>()
{
@Override
public void accept(Object o) {
System.out.println(o);
}
};
list.forEach(consumer);
使用Lambda表达式
// 2、使用lambda表达式
list.forEach(x -> System.out.println(x));
采用缩写形式
// 3、缩写形式
/**
* :: 的作用
* 可以理解为将遍历的元素作为参数传入println方法
*/
list.forEach(System.out::println);
这里可能还是有些不懂,那我们就自己新建一个打印类来进行测试
/**
* 自定义打印类
*
*/
public class MyPrint {
public void addString(String x) {
System.out.println(x);
}
}
// 4、自定义打印类
list.forEach(new MyPrint()::addString);
// 上面等同于
list.forEach(x -> new MyPrint().addString(x));