给定人员列表,如何在一行代码中遍历所有名称而不在java8中使用forEach? 请参阅下面代码中注释中的问题。
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<ArrayList<Person>> llist = new ArrayList<ArrayList<Person>>();
ArrayList<Person> list1 = new ArrayList<>();
list1.add(new Person("aaa"));
list1.add(new Person("bbb"));
ArrayList<Person> list2 = new ArrayList<>();
list2.add(new Person("ccc"));
list2.add(new Person("ddd"));
llist.add(list1);
llist.add(list2);
// how to change this part into one line in java 8?
llist.forEach(l -> {
l.forEach(p -> {
System.out.println(p.getName());
});
});
}
static class Person {
String name;
Person(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public String toString() {
return "" + this.name;
}
}
}
"一行"代码,不使用 forEach:
llist.stream().flatMap(Collection::stream).peek(System.out::println).collect(Collectors.toList());
在这种特殊情况下,您可以将其简化为
llist.forEach(l -> l.forEach(System.out::println));
(因为toString()
Person
类的方法返回与getName()
基本相同(。
没有 forEach,所以像这样?
llist.stream().filter(ll -> {
ll.stream().filter(l -> {
System.out.println("do something on " + l);
return true;
}).toArray();
return true;
}).collect(Collectors.toList());
不是完全有用,但根据要求没有 forEach:
Iterator<String> iterator = llist.stream().flatMap(Collection::stream).map(Person::getName).iterator(); while(iterator.hasNext());
甚至没有一个衬里,因为将while
放在同一条线上是作弊的。
这里的重点是使用flatMap(Collection::stream)
将List<List<Person>>
展平为List<Person>
,然后使用map
将name
从Person
中取出。从那时起,这几乎取决于迭代过程中会发生什么,如果它真的System.out.println
那么没有什么比forEach
更胜一筹了。事实上,forEach
是唯一正确的做法。那将是那时
llist.stream().flatMap(Collection::stream).map(Person::getName).forEach(System.out::println);