0

Can you please help me sort a map like this

Map<Object, List<Object>> halls = new HashMap()<>;

where the key Object has one of his parameters to be numberOfSeats and the whole map should be sorted by the most number of seats in reverse order. I tried doing it with streamAPI but i can't seem to make it work.

Something like:

 halls.entrySet().stream().sorted((h1, h2) -> h1.getSeatsNumber.compareTo(h2.getSeatsNumber));

3 Answers 3

3

Instead of using HashMap, create a TreeMap which is sorted by key and provide a custom comparator:

Map<MyObject, List<MyObject>> halls = new TreeMap<>(
        Comparator.comparingInt(MyObject::getSeatsNumber).reversed()
);

If you have a collection of MyObject that needs to be collected into map, this can be done using Collectors.groupingBy with a supplier of the TreeMap:

List<MyObject> list = new ArrayList<>(); // input list of MyObject

Map<MyObject, List<MyObject>> halls2 = list
        .stream()
        .collect(Collectors.groupingBy(
            x -> x,
            () -> new TreeMap<>(
                Comparator.comparingInt(MyObject::getSeatsNumber).reversed()
            ),
            Collectors.toList()
        ));
Sign up to request clarification or add additional context in comments.

Comments

1

you can use comparing by key for example:

halls.entrySet().stream()
            .sorted(Map.Entry.comparingByKey(Comparator.comparing(YourObject::numberOfSeats).reversed()))
            .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (s1, s2) -> s1, LinkedHashMap::new));

And if you want to sort map you should use LinkedHashMap for example.

Comments

0

Since you specifically said that you had a Map<Object,List<Object>>, I will limit this to that scenario.

First, create some test data.

Map<Object, List<Object>> halls = Map.of(new MyClass(1),
        List.of("G", "H"), new MyClass(4), List.of("C", "D"),
        new MyClass(7), List.of("A", "B"), new MyClass(3),
        List.of("E", "F"));

Now sort the existing map. To preserve the sort you can used a LinkedHashMap which will maintain the insertion order. However, newly added items will not be sorted but simply added to the end.

In this case you must cast the key to your actual class name to obtain the seats as Object knows nothing about that method. To reverse the sort, just reverse the order of e1 and e2 in the Integer.compare method. Had you used MyClass as the key and not Object, this could have been somewhat easier.

Map<Object, List<Object>> result = halls.entrySet().stream()
        .sorted((e1, e2) -> Integer.compare(
                ((MyClass) e2.getKey()).getSeatsNumber(),
                ((MyClass) e1.getKey()).getSeatsNumber()))
        .collect(Collectors.toMap(Entry::getKey,
                Entry::getValue, (a, b) -> a,
                LinkedHashMap::new));

result.entrySet().forEach(System.out::println);

The above prints.

seats:7=[A, B]
seats:4=[C, D]
seats:3=[E, F]
seats:1=[G, H]

And here is the test class with a toString override included.

class MyClass {
    int seats = 0;
    
    public MyClass(int seats) {
        this.seats = seats;
    }
    
    public int getSeatsNumber() {
        return seats;
    }
    
    public String toString() {
        return "seats:"+seats;
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.