如何解决HashMap中同一键对应对象列表的排序失效问题?
按对象名称分组到HashMap的正确实现
我懂你想要做的事儿——把相同名称的对象归到同一个列表里,用HashMap来存,键是名称,值是对应对象的列表对吧?看了你贴的代码片段,我先帮你把坑填上,再给你完整的可运行实现。
首先得说你代码里第一个明显的问题:你用了Java自带的java.lang.Object类来创建实例,但这个系统类根本没有接受String参数的构造方法,new Object("mark")肯定会编译报错!你得自定义一个类来封装对象的名称属性,比如叫CustomObject(当然你可以改成自己喜欢的名字)。
完整实现代码
先定义你的自定义对象类:
class CustomObject { private String name; // 带名称参数的构造方法 public CustomObject(String name) { this.name = name; } // 获取名称的方法,后面分组要用到 public String getName() { return name; } }
然后是分组的核心逻辑,我写了两种方式,你可以根据自己的Java版本选:
方式一:用Java 8+的computeIfAbsent(简洁版)
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Sorter { public static void main(String[] args) { // 创建测试对象 CustomObject obj = new CustomObject("mark"); CustomObject obj1 = new CustomObject("bob"); CustomObject obj2 = new CustomObject("mark"); CustomObject obj3 = new CustomObject("mark"); // 把对象放到列表里统一处理 List<CustomObject> objects = List.of(obj, obj1, obj2, obj3); // 调用分组方法 Map<String, List<CustomObject>> groupedMap = groupObjectsByName(objects); // 打印测试结果(和你示例的格式对齐) groupedMap.forEach((name, objs) -> { System.out.print(name + " = "); for (int i = 0; i < objs.size(); i++) { System.out.print("obj" + (i+1)); if (i != objs.size()-1) System.out.print(", "); } System.out.println(); }); } public static Map<String, List<CustomObject>> groupObjectsByName(List<CustomObject> objects) { Map<String, List<CustomObject>> resultMap = new HashMap<>(); for (CustomObject obj : objects) { String name = obj.getName(); // 关键:如果当前名称不在Map里,就新建一个空列表,然后把对象加进去 resultMap.computeIfAbsent(name, k -> new ArrayList<>()).add(obj); } return resultMap; } }
方式二:传统判断方式(兼容Java 8之前的版本)
如果你的项目还在用老版本Java,就用这个:
public static Map<String, List<CustomObject>> groupObjectsByName(List<CustomObject> objects) { Map<String, List<CustomObject>> resultMap = new HashMap<>(); for (CustomObject obj : objects) { String name = obj.getName(); // 先拿当前名称对应的列表 List<CustomObject> objList = resultMap.get(name); // 如果列表不存在,就新建一个并放到Map里 if (objList == null) { objList = new ArrayList<>(); resultMap.put(name, objList); } // 把当前对象加入列表 objList.add(obj); } return resultMap; }
你原来的代码可能踩的坑
- 误用系统Object类:Java自带的
Object没有new Object(String)构造方法,必须自定义类来封装名称属性。 - 未正确初始化列表:如果第一次遇到某个名称时,直接往Map里的列表add对象,会因为列表为null抛出
NullPointerException,必须先判断并初始化。 - 返回值类型不明确:你的方法如果返回
Object,后续使用会非常麻烦,应该明确返回Map<String, List<CustomObject>>这种具体类型,保证类型安全。
运行上面的代码,就能得到你想要的结果:
bob = obj2 mark = obj1, obj3, obj4
内容的提问来源于stack exchange,提问作者user9489163
相关产品推荐
相关产品推荐

