我有一个像这样的对象结构
class Person{ String userId; String firstName; String lastName; Set<Courses> courses = new HashSet<Courses>(); }
数据库记录是这样的(实际上用户firstName和lastName来自另一个表,但为了简单起见,我将如下所示):
user1 John Smith course1 user1 John Smith course2 user1 John Smith course3 user2 Jack Smith course1 user2 Jack Smith course2
从数据库中检索结果到List< Map< String,Object>>结果集.
现在我需要按userId进行分组,然后将课程映射到Set并创建一个List< Person>对象.
现在我能够通过userId进行分组并将课程收集到集合中但不能映射firstName和lastName.
Map<Object,Set<Object>> userList = resultSet.stream().collect() .Collectors.groupingBy( usr -> usr.get("user_id"),Collectors.mapping( usr -> usr.get("courses"),Collectors.toSet()) )); // Result {user1=[course1,course2,course3]}
然后我正在创建Person Object
List<Person> = userList.entrySet.stream(). .map( usr -> new Person(usr.getKey().toString(),(Set<Courses)(Set<?>)usr.getValue())) .collect(Collectors.toList())
解决方法
您还可以尝试将作为下游函数传递的自定义收集器定义到Collectors.groupingBy().考虑以下示例:
import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collector; import java.util.stream.Collectors; public class PersonGroupByExample { public static void main(String[] args) { final List<Map<String,Object>> input = Arrays.asList( new HashMap<String,Object>(){{ put("userId","user1"); put("firstName","John"); put("lastName","Smith"); put("courses","course1"); }},new HashMap<String,"course2"); }},"course3"); }},"user2"); put("firstName","Jack"); put("lastName","course2"); }} ); final Collection<Person> result = input.stream() .parallel() .collect(Collectors.groupingBy(it -> it.get("userId"),Collector.of( // Start with an empty Person object Person::new,// Collect a list of map objects grouped by the same userId into a single Person object (person,map) -> { // Override common properties person.setUserId(map.getorDefault("userId","").toString()); person.setFirstName(map.getorDefault("firstName","").toString()); person.setLastName(map.getorDefault("lastName","").toString()); // Add person's course to a courses set person.getCourses().add(new Course(map.getorDefault("courses","").toString())); },// Combiner function that join partials results (for parallel execution) (person,person2) -> { person.getCourses().addAll(person2.getCourses()); return person; } ))).values(); result.forEach(System.out::println); } static class Person { String userId; String firstName; String lastName; Set<Course> courses = new HashSet<>(); public Person() {} public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public Set<Course> getCourses() { return courses; } public void setCourses(Set<Course> courses) { this.courses = courses; } @Override public String toString() { return "Person{" + "userId='" + userId + '\'' + ",firstName='" + firstName + '\'' + ",lastName='" + lastName + '\'' + ",courses=" + courses + '}'; } } static class Course { String id; public Course(String id) { this.id = id; } public String getId() { return id; } public void setId(String id) { this.id = id; } @Override public String toString() { return "Course{" + "id='" + id + '\'' + '}'; } } }
Collectors.groupingBy()按userId字段对所有条目进行分组,然后使用自定义收集器的下游函数减少Map< String,Object>的列表.由同一userId分组的条目包含所有课程的单个Person实例.我使用Person和Course POJO来说明流程,也输入List< Map< String,Object>>用于说明转换过程.
最后,我们调用Map.values()方法返回Collection< Person>而不是Map< String,Person>.
运行此示例将创建以下输出:
Person{userId='user1',firstName='John',lastName='Smith',courses=[Course{id='course1'},Course{id='course3'},Course{id='course2'}]} Person{userId='user2',firstName='Jack',courses=[Course{id='course2'},Course{id='course1'}]}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。