在集合、Stream中都出现了forEach()方法实现对其中元素的遍历。
首先看集合中ArrayList中重写的forEach()方法的代码。
@Override
public void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action);
final int expectedModCount = modCount;
@SuppressWarnings("unchecked")
final E[] elementData = (E[]) this.elementData;
final int size = this.size;
for (int i=0; modCount == expectedModCount && i < size; i++) {
action.accept(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
输入的参数是Consumer类型,通过for循环将集合中的元素依次传给action对象的accept()方法,则accept()方法要实现将元素输出。
Consumer是java.util.function包下基础的函数式接口(只声明了一个抽象方法),且方法为accept()。现在需要创建接口实现类的对象,并重写抽象方法,再把对象传给forEach()方法。
//1 创建Consumer接口的实现类对象
Consumer<String> consumer = new Consumer<String>(){
@Override
public void accept(String str) {
System.out.println(str);
}
};
list.forEach(consumer);
或者创建接口匿名实现类对象
//2 创建Consumer接口的匿名实现类对象
list.forEach(new Consumer<String>() {
@Override
public void accept(String str) {
System.out.println(str);
}
});
一般函数式接口的实现是利用lambda表达式完成的,所以可以改写为
//3 lambda表达式
list.forEach(str -> System.out.println(str));
在lambda表达式的基础上由于满足使用条件,可以用方法引用来进一步简化forEach()方法的使用
//4 方法引用
list.forEach(System.out::println);
lambda表达式和方法引用时jdk8中增加的语法,能够帮助更加高效简洁地表达。
如果有ArrayList
ArrayList<String> list = new ArrayList<>();
list.add("aa");
list.add("bb");
list.add("cc");
输出结果为
aa
bb
cc