Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get sorted a TreeMap from list using streams

I have a class say Level (its just a dummy class for understanding). I want a sorted TreeMap<Level,Set<String>> based on levelId. Please find below code

import java.util.*;
import java.util.stream.Collectors;

    public class Level {
        int levelId;

        public Level(int levelId) {
            this.levelId = levelId;
        }

        public static Level getLevel(String name){
            return new Level(name.length());
        }

        public static void main(String[]args){
            Set<String> names=new HashSet<>();
            names.add("Mahesh");
            names.add("Ram");
            names.add("Rita");

            Map<Level, Set<String>> map = names.stream().collect(
                    Collectors.groupingBy(name->Level.getLevel(name),
                    Collectors.mapping(name->name,Collectors.toSet())));

        }
    }

I have also tried with Collectors.collectingAndThen().

Any help is appreciated.

Thanks in advance.

like image 416
Nidhi257 Avatar asked Oct 12 '17 06:10

Nidhi257


People also ask

Is a TreeMap automatically sorted?

Default Sorting in TreeMapBy default, TreeMap sorts all its entries according to their natural ordering. For an integer, this would mean ascending order and for strings, alphabetical order.

How do I sort a list in streams?

Stream sorted() in Java Stream sorted() returns a stream consisting of the elements of this stream, sorted according to natural order. For ordered streams, the sort method is stable but for unordered streams, no stability is guaranteed.

Can we sort TreeMap based on values?

You can't have the TreeMap itself sort on the values, since that defies the SortedMap specification: A Map that further provides a total ordering on its keys. However, using an external collection, you can always sort Map.

Is TreeMap keyset sorted?

The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used. This implementation provides guaranteed log(n) time cost for the containsKey , get , put and remove operations.


1 Answers

If you don’t want to let Level implement Comparable, you need a Comparator. Then, you have to pass a lambda expression creating a TreeMap using this separator as map factory to the groupingBy collector:

public class Level {
    int levelId;

    public Level(int levelId) {
        this.levelId = levelId;
    }

    public static Level getLevel(String name){
        return new Level(name.length());
    }

    public int getLevelId() {
        return levelId;
    }

    public static void main(String[]args){
        Set<String> names=new HashSet<>();
        names.add("Mahesh");
        names.add("Ram");
        names.add("Rita");

        Comparator<Level> c = Comparator.comparingInt(Level::getLevelId);
        Map<Level, Set<String>> map = names.stream()
            .collect(Collectors.groupingBy(
                         Level::getLevel, () -> new TreeMap<>(c), Collectors.toSet()));
    }
}
like image 125
Holger Avatar answered Oct 05 '22 13:10

Holger