Home > Back-end >  Java Streams - Sort element in each List while using Collector groupingBy
Java Streams - Sort element in each List while using Collector groupingBy

Time:10-07

I have the following code, which makes use of the collector groupingBy()

Stream<String> stream = Stream.of("lions", "tigers", "bears", "toads", "tarantullas");

Map<Integer, ?> map7 = stream.collect(
    Collectors.groupingBy(
        String::length,
        Collectors.mapping(s -> s.charAt(0),
            Collectors.toList()
        )
    ));

System.out.println("map7: "   map7);
System.out.println("value type: "   map7.get(5).getClass());

Output:

map7: {5=[l, b, t], 6=[t], 11=[t]}
value type: java.util.ArrayList

How can I sort letters in each list, and what should be the appropriate type of map's value?

CodePudding user response:

The proper type of map according to the downstream collector of groupingBy should be Map<Integer,List<Character>>.

To sort each list of characters, you can make use of the collector collectingAndThen().

Map<Integer, List<Character>> charactersByLength = Stream.of("lions", "tigers", "bears", "toads", "tarantullas")
    .collect(Collectors.groupingBy(
        String::length,
        Collectors.collectingAndThen(
            Collectors.mapping(s -> s.charAt(0), Collectors.toList()),
            list -> { list.sort(null); return list; }
        )
    ));

Sidenote: try to use more meaningful names than map7. When your code base is larger than a couple of tiny classes, it helps a lot in debugging and maintaining the code.

CodePudding user response:

You can use Collectors.toCollection(TreeSet::new) to get a sorted Set and accordingly you can replace ? with SortedSet<Character>.

Map<Integer, SortedSet<Character>> map7 = ohMy.collect(
                Collectors.groupingBy(
                        String::length,
                        Collectors.mapping(s -> s.charAt(0),
                                Collectors.toCollection(TreeSet::new))));

Output:

map7:{5=[b, l, t], 6=[t], 11=[t]}
  • Related