如何将Spring MVC分组Map的Key改为LectureHall的Name属性?
问题:如何将分组后的Map键从LectureHall对象改为其Name属性?
我现在有两个实体类LectureHall和TimeTable,定义如下:
@Entity @Table (name = "lectureHall_details") public class LectureHall { @Id @GeneratedValue(strategy = GenerationType.IDENTITY ) private int id; private String Name; private String code; private String description; private int capacity; // 省略其他代码 }
@Entity @Table(name = "timeTable_details") public class TimeTable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY ) private int id; @ManyToOne private LectureHall lectureHall; @ManyToOne private Department department; // 省略其他代码 }
在Spring MVC的Controller里,我通过Stream把TimeTable列表按LectureHall对象分组,得到了Map<LectureHall, List<TimeTable>>:
@RequestMapping(value = {"view/{day}/lecturehalls"}) public ModelAndView viewLectureHalls(@PathVariable("day") String day) { List<TimeTable> lectureHalls = timeTableDao.getLectureHallsList(day); Map<LectureHall, List<TimeTable>> byHall = lectureHalls.stream() .collect(Collectors.groupingBy(TimeTable::getLectureHall)); ModelAndView mv = new ModelAndView("page"); mv.addObject("title","TimeTable"); mv.addObject("mondayTime",byHall); mv.addObject("userclickviewlecturehallarrangements",true); return mv; }
现在我想把这个Map的Key改成LectureHall类的Name属性,该怎么实现?
解决方案
其实很简单,只需要修改Collectors.groupingBy的参数,不要直接传递TimeTable::getLectureHall,而是改成提取LectureHall的Name属性就行。不过要注意一点:如果有多个LectureHall的Name是重复的,分组的时候会把对应的TimeTable列表合并到同一个Key下。
修改后的代码如下:
@RequestMapping(value = {"view/{day}/lecturehalls"}) public ModelAndView viewLectureHalls(@PathVariable("day") String day) { List<TimeTable> lectureHalls = timeTableDao.getLectureHallsList(day); // 这里把分组的Key改成LectureHall的Name属性 Map<String, List<TimeTable>> byHallName = lectureHalls.stream() .collect(Collectors.groupingBy(t -> t.getLectureHall().getName())); ModelAndView mv = new ModelAndView("page"); mv.addObject("title","TimeTable"); mv.addObject("mondayTime",byHallName); // 同步修改变量名,逻辑更清晰 mv.addObject("userclickviewlecturehallarrangements",true); return mv; }
另外提个小细节:你LectureHall类里的Name属性首字母大写了,按照Java命名规范,成员变量应该用小驼峰格式(比如name),对应的getter方法是getName()。如果你的getter方法是符合规范的,那上面的代码没问题;如果因为属性命名特殊导致getter方法不是getName(),记得调整lambda表达式里的调用,确保能正确拿到Name属性的值。
如果担心出现重名的LectureHall(比如不同场馆名字相同),可以考虑用Name + code的组合作为Key来保证唯一性,示例代码如下:
Map<String, List<TimeTable>> byHallNameAndCode = lectureHalls.stream() .collect(Collectors.groupingBy(t -> t.getLectureHall().getName() + "-" + t.getLectureHall().getCode()));
这样就能避免不同场馆因为Name相同被合并到同一分组里的问题啦。
内容的提问来源于stack exchange,提问作者user8212013
相关产品推荐
相关产品推荐

