0

How can I iterate over a Map in a specific desired order? I currently have a HashMap and want to be able to define a specific iteration order. The order should be able to get changed by the user.

My first thought was to use a LinkedHashMap since that one will give me an order of entries, but sadly the implementation only orders them by order of insertion or by order of access. Other than manipulating the insertion order with deletes, I dont see the LinkedHashMap fit for the task. Imo the implementation kind of falls short of what the docs say about it.

I also found the SortedMap, but that one uses a comparator, so I needs to evaluate that every time I want to iterate over the entries. This could be a solution, but is kind of expensive: O(n*log(n)).

So far Andreas comment seems to be the best solution, which is having both a HashMap and a ArrayList.

Tigerware
  • 3,196
  • 2
  • 23
  • 39
  • 1
    *"Is there an easier way?"* No, except perhaps building a new list, eliminating the need to individually remove items from the old list. – Andreas Jun 02 '19 at 19:52
  • 4
    If you want control of the order, use a separate `List` (array, linked, whatever) and a straight `HashMap`. Might be good to wrap them in a class that keeps them in sync. – Andreas Jun 02 '19 at 19:54
  • Yeah, a `LinkHashMap` is perhaps not what you need. – Maurice Perry Jun 03 '19 at 06:10
  • You know they are *always* put in there in the order of insertion. No 'usually' about it. – user207421 Jun 03 '19 at 06:45
  • @user207421 Well but isnt that an implementation detail? The main goal of the LinkedHashMap is "a predictable iteration order" for a Map. Btw if you pass the bool for accessOrder the resulting order can actually get changed. If you know a different map implementation which also lets me decide the order of entries when iterating, please let me know. – Tigerware Jun 03 '19 at 12:19
  • @Andreas Thank you for your comment, so far that seems to be the best solution. If you write it as solution, I'll probably accept that if nothing better comes up. – Tigerware Jun 03 '19 at 12:41
  • @user207421 It even says so in the docs for the LinkedHashMap: "Hash table and linked list implementation of the Map interface, with predictable iteration order. [...] This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order)." Well they use the word normally instead of usually. https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html – Tigerware Jun 03 '19 at 12:45
  • 1
    *To clarify:* The "predictable iteration order" phrasing is because [`LinkedHashMap`](https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html) supports 2 (and only 2) iteration orderings. The default (aka most commonly used, aka "normally" used) order is *insertion-order*, the other is *access-order*. The class does not support any other iteration orderings. – Andreas Jun 03 '19 at 16:38

3 Answers3

1

Convert the LinkedHashMap to an ArrayList and then switch the value. Then convert back to LinkedHashMap. O(n) for both space and time complexity.

Gawain
  • 1,017
  • 8
  • 17
  • This could work, but is overly complicated in my opinion. – Tigerware Jun 03 '19 at 12:48
  • Because LinkedHashMap use LinkedList internally, it is not a good idea to switch items by index. I think if possible, you can implement a HashMap with ArrayList of keys to do this. – Gawain Jun 04 '19 at 01:31
  • And if you want to use a custom order of entries, I think SortedMap will be your solution, TreeMap is an implementation of SortedMap which can write you own comparator. – Gawain Jun 06 '19 at 03:21
0

The correct answer for this question is you use incorrect data structure in cease you have to reorder it.

Oleg Cherednik
  • 17,377
  • 4
  • 21
  • 35
  • What would be the correct data structure? I need a Map, which also lets me iterate over the entries in the order I want. – Tigerware Jun 03 '19 at 12:20
0

If you want a key value pair and you want it to have properties of ArrayList then can you try

List<Pair<String, String>> ?
Hari Rao
  • 2,990
  • 3
  • 21
  • 34