Collectors.toMap()错误报告是否异常?重复键提示与实际不符
Let's break down what's happening here—this isn't a bug in the error reporting, but rather a quirk of how the default Collectors.toMap implementation handles duplicate keys.
First, let's look at your code again:
List<String> strings = Arrays.asList("3","55","3"); Map<String,Integer> map = strings.stream().collect(Collectors.toMap(s -> s, s -> s.length()));
You're using toMap with two core functions:
- The key mapper:
s -> s(so keys are the strings themselves: "3", "55", "3") - The value mapper:
s -> s.length()(so values are 1, 2, 1)
When toMap hits a duplicate key (the second "3"), it relies on the default merge function to resolve the conflict. That default function, throwingMerger(), throws an IllegalStateException with the message "Duplicate key X".
Here's the critical detail: the X in that message isn't the duplicate key—it's the second value that tried to be paired with the duplicate key. In your case, the second "3" maps to the value 1, so the error reads "Duplicate key 1".
How to Get the "Duplicate key 3" Error You Expect
The default merge function only has access to the conflicting values, not the key itself. So if you want your error message to include the actual duplicate key, you need to implement custom duplicate checking.
A straightforward workaround is to first group elements by their key, then explicitly check for duplicates:
// Group all values by their corresponding key Map<String, List<Integer>> grouped = strings.stream() .collect(Collectors.groupingBy( s -> s, Collectors.mapping(s -> s.length(), Collectors.toList()) )); // Scan for duplicate keys and throw a meaningful error for (Map.Entry<String, List<Integer>> entry : grouped.entrySet()) { if (entry.getValue().size() > 1) { throw new IllegalStateException("Duplicate key: " + entry.getKey()); } } // Convert to your desired map (we've already validated no duplicates exist) Map<String, Integer> map = grouped.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().get(0)));
With this setup, when a duplicate key like "3" is found, you'll get the exact error message you expected: IllegalStateException: Duplicate key: 3.
To Sum Up
The default error message from Collectors.toMap isn't broken—it's just designed to highlight conflicting values rather than duplicate keys. If you need the key in your error output, you'll have to add custom validation logic like the example above.
内容的提问来源于stack exchange,提问作者Paul Janssens

