我有类Employee
和Address
如下:
public static class Employee {
private List<Address> address;
// getters, etc.
}
public static class Address {
private String city;
// getters, etc.
}
我正在学习流,我正在尝试从列表列表中迭代对象并创建一组唯一值。我能够通过使用嵌套的 for 循环来让它工作。如何将以下代码转换为流?
public static Set<String> getCityUniquName(List<Employee> emp){
Set<String> cityUniquName = new HashSet<>();
for(Employee e: emp){
List<Address> addList = e.getAddress();
for(Address add: addList){
cityUniquName.add(add.getCity());
}
}
return cityUniquName;
}
由于每个Employee
都与Address
实例的集合相关联,因此您需要应用允许平展数据的流操作,即flatMap()
或mapMulty()
。
请注意,flatMap()
期望一个产生Stream
的函数,而不是另一个答案中显示的集合。
流平面地图
要在映射器函数中将Employee
流转换为Address
流flatMap()
我们需要提取地址集合并在其上创建一个流。
剩下的唯一事情就是获取城市名称并将结果收集到一组中。
public static Set<String> getCityUniqueName(List<Employee> emp) {
return emp.stream()
.flatMap(e -> e.getAddress().stream())
.map(Address::getCity)
.collect(Collectors.toSet());
}
Stream.mapMulti
mapMulti()
期望一个BiConsumer
,而又需要两个参数:流元素(具有初始类型)和结果类型的Consumer
。提供给使用者的每个对象都将出现在生成的流中。
public static Set<String> getCityUniqueName1(List<Employee> emp) {
return emp.stream()
.<Address>mapMulti((e, c) -> e.getAddress().forEach(c))
.map(Address::getCity)
.collect(Collectors.toSet());
}
使用flatMap 展平Address
列表,然后使用map
从每个Address
对象获取城市,然后收集到Set
Set<String> cityUniquName = emp.stream()
.map(Employee::getAddress)
.flatMap(List::stream)
.map(Address::getCity)
.collect(Collectors.toSet());