Sort Map<String, Map<String, Map<String, Long>>

Asked

Viewed 207 times

-2

Hi, I did a search but I couldn’t find this sort of sorting by the last value of this Map.

I need to order a Map<String, Map<String, Map<String, Long>>> for the last Long value, to return in JSON.

The structure is like this:

  "Map": {
            "Info A": {
                "SubInfo A": {
                    "X": 0,
                    "Y": 0,
                    "Z": 2,
                    "Total": 2
                }
            },
            "Info B": {
                "SubInfo B": {
                    "X": 2,
                    "Y": 2,
                    "Z": 4,
                    "Total": 8
                }
            }, 
            "Info C": {
                "SubInfo C": {
                    "X": 4,
                    "Y": 0,
                    "Z": 1,
                    "Total": 5
                }
            } 

She must stay like this:

 "Map": {
            "Info B": {
                "SubInfo B": {
                    "X": 2,
                    "Y": 2,
                    "Z": 4,
                    "Total": 8
                }
            },
            "Info C": {
                "SubInfo C": {
                    "X": 4,
                    "Y": 0,
                    "Z": 1,
                    "Total": 5
                }
            }, 
            "Info A": {
                "SubInfo A": {
                    "X": 0,
                    "Y": 0,
                    "Z": 2,
                    "Total": 2
                }
            }

With the Ordination of the decreasing "Total".

I only found simple ordering. Ex: Map<String, Long>.

Does anyone have any ideas that can help me?

Thanks in advance.

  • Map maps are starting to be a confusing solution for code maintenance. You can make your 'value' which is a Map<String, Map<String, Long>> is actually a Class and, in this class, you would have to compare these values using a comparable Map<String,SuaClasse>. About ordering, remember that Map is just an interface that can be implemented in several ways. That answer can help you.

  • Okay @Tobo, I’m going to take a look at this Post. .

  • I tried this time with java.util.Treemap, Sortedmap but unfortunately it didn’t work. With Linkedhashmap I had already tried, unsuccessfully in my case of Map’s Map. I’m checking to see if I can apply your suggestion to create a Class. Thank you @Tobo

  • Dude you can not order before, create an ordered list before and when to play on the maps will be ordered. In this case it is not yet a map but a list.

  • Map<String, Map<String, Long>>result = items.stream(). Collect( Collectors.groupingBy(Class::String), Collectors.groupingBy(Class::String) Collectors.groupingBy(Class::Long));

  • Map<String, Map<String, Long>>result = items.stream() . Sorted(Comparator.Comparing(p -> p.long())). Collect( Collectors.groupingBy(Class::String), Collectors.groupingBy(Class::String) Collectors.groupingBy(Class::Long));

  • TreeMap and SortedMap order by the keys, but in your case the Long is the value (the key is String). Already LinkedHashMap maintains the order in which the elements were inserted and will not serve. Anyway, it would be interesting [Dit] the question and put some examples of what you want to do. Do you just want to show (print to screen, save to file, etc) the map data in some specific order? Or do you want the structure to always keep the elements in order? Anyway, I think the structure is too complex and it would be better to review it, as already suggested...

  • @Eduardorodrigues, unfortunately in my case it does not work to create a list and order it before mapping. Still, thanks for the tip.

  • Hi @hkotsubo, I need to sort this Map to return in a Restfull API. The data comes from the Database and will always be dynamic, it is very complex, there is a relation of 6 tables and some filters applied in Java. I will edit with examples. Thank you very much.

  • One detail is that a JSON Object (delimited by { }, how it seems to be the answer you want) does not guarantee the order of the keys, so even if you create an ordered structure in Java, nothing prevents the JSON API from generating the result in another order (since the order doesn’t matter, according to the definition of a JSON). Maybe you should review the structure and return an array, for example (something like [ { infoa }, {infob}, etc... ]), for then order is guaranteed

  • So @hkotsubo as JSON does not guarantee the ordering, in my Response I put a 'Linkedhashmap<>()' that should receive my Map in an orderly way, because an Array in my case does not solve the problem, unfortunately.

  • Matthew, depending on the API you use, it may not generate JSON in the same order as LinkedHashMap. I tested with org.json.JSONObject it changes the order (even using a LinkedHashMap), and the google Gson keeps order (but do not know it was coincidence or if it always respects the order). And anyway, a JSON Object, by definition, does not guarantee the order (nor in maps the order should matter), so returning an Object in which the order is important is already wrong. If you can fix something, start there...

  • @Matthew, write to SOLUTION in the answer box and accept it as correct. Additionally, you do not need to mark the question as "Solved".

  • Thanks for the info @neves. Hug.

  • @hkotsubo Thank you so much for the tips.

Show 10 more comments

1 answer

0


After several attempts, I was able to find a way to solve my problem. As I did not find a way to sort (by the value) my Map of Maps a little complex and also by the fact that I should return a similar Map in Response, I did the following:

I created a VO containing a Map of the same complexity and a Long that receives my Total contained in the last Map of each Map;

public class minhaVO {
    private Long total;
    private Map<String,Map<String, Map<String, Long>>> map;
}

Then I created a LinkedList<>() of that VO List<minhaVO> voListOrdenar = new LinkedList<>(); populated it with all keys and values of my Map and using the Collections.sort I ordered downward as needed.

That way all the items on my VO list are ordered by Total and consequently my Map too.

Done that, I created a For Loop in this List, incrementing a Map LinkedMap<>() identical to my Response, but in an orderly fashion and finally passed it to my answer that JSON returns.

I thank the people who suggested some tips and tried to help me.

A hug to all of the community.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.