Collectors.toMap生成错误键:期望以查找表键为最终Map键
问题分析与解决方案
看起来你是把数据源搞混啦!你的目标是基于getLookup()返回的查找表(键是dat1/dat2,值是类全名)来构建最终Map,但你当前的代码用的是handlerMap的entry流——如果handlerMap的键本身就是类全名,那最终Map的键自然会变成类全名,这就和你的预期不符了。
修正后的核心代码
直接从getLookup()返回的查找表入手,这样就能保证最终Map的键是你想要的dat1/dat2:
// 获取目标查找表:键为dat1/dat2,值为对应类的全名 Map<String, String> lookupMap = getLookup(); // 构建最终Map,键保留dat1/dat2,值为加载后的DataMap对象 Map<String, DataMap> handlers = lookupMap.entrySet() .stream() .peek(entry -> System.out.println("Key is " + entry.getKey() + " | Class Name: " + entry.getValue())) .collect(Collectors.toMap( Map.Entry::getKey, // 直接复用查找表的键(dat1/dat2) entry -> createDataMap(entry.getValue()) // 用类全名生成DataMap .orElse(new NullDataMapper()) ));
关键点说明
- 数据源选对:直接遍历
lookupMap的entry集合,每个entry的key就是你需要的dat1/dat2,从根源上保证键的正确性。 - 映射逻辑明确:
toMap的第一个参数指定用原查找表的键作为最终Map的键,第二个参数用查找表中的类全名去调用createDataMap生成对应的值对象。
如果必须用handlerMap怎么办?
要是你的handlerMap是按类全名作为键存储的(比如Map<String, HandlerObj>,键是类全名),那需要通过查找表建立dat1/dat2和类全名的关联:
Map<String, String> lookupMap = getLookup(); Map<String, HandlerObj> handlerMap = ...; // 你的handlerMap,键为类全名 Map<String, DataMap> handlers = lookupMap.entrySet() .stream() .peek(entry -> System.out.println("Key is " + entry.getKey() + " | Class Name: " + entry.getValue())) .collect(Collectors.toMap( Map.Entry::getKey, entry -> { String className = entry.getValue(); HandlerObj handler = handlerMap.get(className); // 处理handler不存在的情况 return handler != null ? createDataMap(handler).orElse(new NullDataMapper()) : new NullDataMapper(); } ));
另外你可以再仔细核对下之前peek的输出——如果输出的key是dat1,但最终Map的键却是类全名,那大概率是你对handlerMap的结构理解错了,比如它的value才是dat1,键是类全名,这时候就得反过来调整映射逻辑啦。
内容的提问来源于stack exchange,提问作者BreenDeen
相关产品推荐
相关产品推荐

