Java Stream中thenComparing用法问题:Map<Character,String>排序与拼接
Hey there! Let's work through this problem step by step. The issue you're hitting with thenComparing is almost certainly because you're not properly accessing the String value from the Map entry before trying to call length(). Let's break down the fix and build the solution from the ground up.
Step-by-Step Solution
First, remember that a Map itself can't be sorted directly—we need to work with its entrySet() (the collection of key-value pairs) as a stream. Here's how to implement your desired sorting logic and concatenate the final string:
import java.util.Comparator; import java.util.Map; import java.util.stream.Collectors; public class SortedMapValueConcatenator { public static void main(String[] args) { // Example input map Map<Character, String> myMap = Map.of( 'x', "zebra", 'a', "apple", 'b', "bee", 'c', "cat", 'd', "elephant" ); // Sort and concatenate String sortedConcatenatedString = myMap.entrySet() .stream() // 1. First sort by length of the string value .sorted(Comparator.comparingInt((Map.Entry<Character, String> entry) -> entry.getValue().length()) // 2. Then sort alphabetically when lengths are equal .thenComparing(Map.Entry::getValue)) // Extract just the string values from the sorted entries .map(Map.Entry::getValue) // Join all sorted strings into one (use ", " instead of "" for separated output) .collect(Collectors.joining()); System.out.println(sortedConcatenatedString); // Output: beecatapplezebraelphant } }
Why Your Original thenComparing Call Failed
Chances are you tried something like .thenComparing(e -> e.length())—but e here refers to a Map.Entry<Character, String>, not the String value itself! You need to first call entry.getValue() to get the String, then call length() or rely on String's natural alphabetical sorting.
Customization Tips
- Reverse sorting: If you want longer strings first, add
.reversed()after the length comparator:.sorted(Comparator.comparingInt((Map.Entry<Character, String> entry) -> entry.getValue().length()) .reversed() .thenComparing(Map.Entry::getValue)) - Case-insensitive alphabetical sort: Use
thenComparing(entry -> entry.getValue().toLowerCase())instead ofMap.Entry::getValueto ignore uppercase/lowercase differences. - Add separators: Change
Collectors.joining()toCollectors.joining(", ")if you want commas between sorted strings.
内容的提问来源于stack exchange,提问作者Anton Barinov

