Java 8中用Function接口与Lambda实现Set转HashMap的问题求助
解决Java 8 Function结合HashMap的Lambda实现问题
嘿,我来帮你揪出代码里的问题,再给你正确的实现方式~
你的代码问题分析
你当前的Lambda表达式犯了两个关键错误:
- 返回值错误:
new HashMap().put(s2,s2)返回的是put方法的结果(该键之前关联的值,第一次存入就是null),而不是你新建的HashMap对象。所以最后setToMap.apply(hs)返回的是null,自然打印出null。 - 逻辑错误:你把整个
Set对象当作键和值存入Map了,而不是遍历Set里的每个单词,用单词首字母大写作为键、单词本身作为值。
正确的实现代码
下面是符合你需求的代码,我还做了泛型优化避免原始类型警告:
import java.util.*; import java.util.function.Function; public class FunctionTest { public static void main(String[] args) { HashSet<String> hs = new HashSet<>(); hs.add("ciao"); hs.add("hello"); hs.add("hallo"); hs.add("bonjour"); // 定义正确的Function,将Set<String>转换为Map<Character, String> Function<Set<String>, Map<Character, String>> setToMap = inputSet -> { Map<Character, String> resultMap = new HashMap<>(); // 遍历输入的Set,逐个处理每个单词 for (String word : inputSet) { // 提取首字母并转为大写(这里假设所有单词都非空,若有空字符串需额外处理) char firstUpperCase = Character.toUpperCase(word.charAt(0)); resultMap.put(firstUpperCase, word); } // 返回构建完成的Map对象 return resultMap; }; System.out.println(setToMap.apply(hs)); } }
这段代码运行后会输出符合你预期的结果(注意:HashSet是无序的,若"hallo"在"hello"之后被遍历,H对应的value会是"hallo",你可以用LinkedHashSet来保证插入顺序)。
更简洁的Stream API写法
如果你想用上Java 8的Stream API简化代码,可以这样写:
import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; public class FunctionTest { public static void main(String[] args) { HashSet<String> hs = new HashSet<>(); hs.add("ciao"); hs.add("hello"); hs.add("hallo"); hs.add("bonjour"); Function<Set<String>, Map<Character, String>> setToMap = inputSet -> inputSet.stream() .collect(Collectors.toMap( // 键:单词首字母大写 word -> Character.toUpperCase(word.charAt(0)), // 值:单词本身 word -> word, // 键冲突时的处理:保留后面的单词,和循环写法行为一致 (oldValue, newValue) -> newValue )); System.out.println(setToMap.apply(hs)); } }
补充说明
如果你的场景中存在多个首字母相同的单词,且需要保留所有单词,可以把Map的value类型改成List<String>,用Collectors.groupingBy来实现,不过根据你的预期结果,当前的单值Map就足够啦。
内容的提问来源于stack exchange,提问作者Giacomo Brunetta
相关产品推荐
相关产品推荐

