如何解决Java 使用流中的重复元素创建多个列表
我正在尝试获取一个列表并返回一个包含原始列表某些方面的 Map<String,List<String>
,其中原始元素可以使用流作为不同键下的值多次出现。例如:
class Employee {
String firstName;
String lastName;
Status status;
}
enum Status {
FULL_TIME,PART_TIME
}
List<Employee> employees = List.of(
new Employee("f1","l1",Status.PART_TIME),new Employee("f2","l2",Status.FULL_TIME),new Employee("f3","l3",new Employee("f4","l4",Status.FULL_TIME));
生成的映射应具有如下键,并且列表必须是不可变的:
fName: ["f1","f2","f3","f4"],lName: ["l1","l4"],fullTime: ["f2 l2","f4 l4"]
对于多个流来说这很容易,但是原始数据非常大,所以我试图一次性完成。如果有另一种我不知道的方法,我也可以使用 Guava 和 Apache Commons。谢谢!
编辑 1:展示我现在的做法
以下是我在三个流中所做的事情,我想将其简化为一个:
var firstName = employees.stream()
.map(e -> e.getFirstName())
.collect(Collectors.toUnmodifiableList());
var lastName = employees.stream()
.map(e -> e.getLastName())
.collect(Collectors.toUnmodifiableList());
var fullTime = employees.stream()
.filter(e -> e.getStatus().equals(Status.FULL_TIME))
.collect(Collectors.toUnmodifiableList());
解决方法
这是一个示例,但您将添加一些额外的行和第三类。
主要
var employees = List.of(
new Employee("f1","l1",Status.PART_TIME),new Employee("f2","l2",Status.FULL_TIME),new Employee("f3","l3",new Employee("f4","l4",Status.FULL_TIME)
);
var maps = employees.stream()
.flatMap(employee -> Stream.of(
new Pair("fName",employee.firstName),new Pair("lName",employee.lastName),new Pair(
employee.status == Status.FULL_TIME ? "fullTime" : "partTime",employee.firstName.concat(" ").concat(employee.lastName)
)
))
.filter(pair -> !pair.name.equals("partTime"))
.collect(Collectors.groupingBy(
pair -> pair.name,Collectors.mapping(pair -> pair.value,Collectors.toUnmodifiableList())
));
相关类
class Employee {
String firstName;
String lastName;
Status status;
//constructors,setters and getters
}
enum Status {
FULL_TIME,PART_TIME
}
class Pair {
String name;
String value;
//constructors,setters and getters
}
,
我建议您将每个生成列表的流放入方法中。像这样:
public static List<String> getListFirstName(List<Employee> employees) {
return employees.stream()
.map(e -> e.getFirstName())
.collect(Collectors.toUnmodifiableList());
}
public static List<String> getListLasttName(List<Employee> employees) {
return employees.stream()
.map(e -> e.getLastName())
.collect(Collectors.toUnmodifiableList());
}
public static List<String> getListFullTime(List<Employee> employees) {
return employees.stream()
.filter(e -> e.getStatus().equals(Status.FULL_TIME))
.map(e -> e.getFirstName()+" "+e.getLastName())
.collect(Collectors.toUnmodifiableList());
}
public static List<String> getListPartTime(List<Employee> employees) {
return employees.stream()
.filter(e ->e.getStatus().equals(Status.PART_TIME))
.map(e -> e.getFirstName()+" "+e.getLastName())
.collect(Collectors.toUnmodifiableList());
}
创建一个返回 Map
public static Map<String,List<String>> getByCriteria(String criteria,List<Employee> employees) {
Map<String,List<String>>map = new HashMap<>();
if("fName".equals(criteria)) {
map.put(criteria,getListFirstName(employees));
}else if("lName".equals(criteria)) {
map.put(criteria,getListFirstName(employees));
}else if("fullTime".equals(criteria)) {
map.put(criteria,getListFullTime(employees));
}else if("partTime".equals(criteria)) {
map.put(criteria,getListPartTime(employees));
}
return Collections.unmodifiableMap(map);
}
创建一个标准列表,例如:
List<String> criterias = List.of("fName","lName","fullTime","partTime");
从标准列表创建流以生成包含您想要的内容的最终地图
Map<String,List<String>> collect = criterias.stream().parallel().map(c -> getByCriteria(c,employees)).flatMap(map -> map.entrySet().stream())
.collect(Collectors.toMap(eM -> eM.getKey(),eM -> eM.getValue()));
这里是完整的课程:
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<Employee> employees = List.of(new Employee("f1",Status.FULL_TIME));
List<String> criterias = List.of("fName","partTime");
Map<String,eM -> eM.getValue()));
System.out.println(collect);
}
public static Map<String,List<Employee> employees) {
Map<String,List<String>>map = new HashMap<>();
if("fName".equals(criteria)) {
map.put(criteria,getListFirstName(employees));
}else if("lName".equals(criteria)) {
map.put(criteria,getListFirstName(employees));
}else if("fullTime".equals(criteria)) {
map.put(criteria,getListFullTime(employees));
}else if("partTime".equals(criteria)) {
map.put(criteria,getListPartTime(employees));
}
return Collections.unmodifiableMap(map);
}
public static List<String> getListFirstName(List<Employee> employees) {
return employees.stream()
.map(e -> e.getFirstName())
.collect(Collectors.toUnmodifiableList());
}
public static List<String> getListLasttName(List<Employee> employees) {
return employees.stream()
.map(e -> e.getLastName())
.collect(Collectors.toUnmodifiableList());
}
public static List<String> getListFullTime(List<Employee> employees) {
return employees.stream()
.filter(e -> e.getStatus().equals(Status.FULL_TIME))
.map(e -> e.getFirstName()+" "+e.getLastName())
.collect(Collectors.toUnmodifiableList());
}
public static List<String> getListPartTime(List<Employee> employees) {
return employees.stream()
.filter(e ->e.getStatus().equals(Status.PART_TIME))
.map(e -> e.getFirstName()+" "+e.getLastName())
.collect(Collectors.toUnmodifiableList());
}
}
,
您可以将员工对象转换为 pairs 列表,其中对键是映射键,对值是列表的单个值。然后您可以通过键对这些对进行“分组”。
Map<String,List<String>> vals = employees.stream()
.map(e -> Arrays.asList(
Pair.of("fname",e.firstName),Pair.of("lname",e.lastName),e.status == Status.FULL_TIME ? Pair.of("fullTime",e.firstName + " " + e.lastName) : null
))
.flatMap(Collection::stream)
.filter(Objects::nonNull)
.collect(Collectors.groupingBy(p -> p.getLeft(),Collectors.mapping(p -> p.getRight(),Collectors.toUnmodifiableList())));
但是这个解决方案的内存消耗比我的previous answer中的要差,特别是在处理大流时。
,既然你说你可以使用apache commons,也许是这样的?
Map<String,List<String>> map = new HashMap<>();
List<Employee> employees = List.of(
new Employee("f1",Status.FULL_TIME));
List<String> firstNames = new ArrayList<>();
List<String> lastNames = new ArrayList<>();
List<String> ftEmployees = new ArrayList<>();
employees.forEach(employee -> {
firstNames.add(employee.firstName);
lastNames.add(employee.lastName);
if (employee.status == Status.FULL_TIME) {
ftEmployees.add(employee.firstName + " " + employee.lastName);
}
});
map.put("fname",ImmutableList.copyOf(firstNames));
map.put("lName",ImmutableList.copyOf(lastNames));
map.put("fullTime",ImmutableList.copyOf(ftEmployees));
,
这是可以执行您想要的操作的示例代码。不需要多个流,一个流就足以遍历对象。
Map<String,List<String>> result = new HashMap<>();
result.put("fname",new ArrayList<String>());
result.put("lname",new ArrayList<String>());
result.put("fullTime",new ArrayList<String>());
List<Employee> employees = List.of(
new Employee("f1",Status.FULL_TIME));
employees.forEach(e -> {
result.get("fname").add(e.firstName);
result.get("lname").add(e.lastName);
result.get("fullTime").add(e.firstName + " " + e.lastName);
});
System.out.println(result);
我会让你把列表转换成不可变列表。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。