How to parse a map (foreach) in the same order that I created (JAVA)

So, I have a map that I created (inserted data) in the order I wanted. When parsing a map, the 1st key returned to foreach is not the first key I entered. Is there any way to do this?

Also, sorting my map is quite complicated, it needs to be sorted by value and in a specific field within the value. Ty

+6
java sorting foreach map
source share
3 answers

We'll see. Your requirements are as follows:

  • You have a set of key / value pairs where the keys are unique.
  • You want to be able to quickly find the value for a given key.
  • You want to be able to iterate over keys (or pairs) in insertion order.
  • You want to be able to iterate over the values โ€‹โ€‹in the order of some field of type value.

There is no single standard Java collection class that satisfies all these requirements. And I don't think Commons collections or Google collections will either ...

If you selected requirement 3, then work TreeSet (created using custom Comparator ). If you selected requirement 4, then LinkedHashMap will do the job.

To satisfy all requirements, you need to do one of the following:

  • Use LinkedHashMap , and if you want to iterate in a specific order depending on the values, extract the map values collection, sort it using your own comparator, and return the iterator for the sorted collection.

  • Use both LinkedHashMap and TreeMap , and update them in parallel.

  • Create a custom fasade class for LinkedHashMap and TreeMap . This is necessary to update both data structures when calling put , remove etcetera, and also provide additional methods for obtaining sorted values.

+4
source share

Check http://java.sun.com/j2se/1.4.2/docs/api/java/util/LinkedHashMap.html to implement a map with a predictable iteration order. You may also consider using a list if you are not performing a key search.

+5
source share

If you can sort the items up by the value attribute, you can use LinkedListHashMap , as this preserves the order you specify. However, this seems a little fragile and not suitable if you need to add a few more elements to the map.

An alternative is to store values โ€‹โ€‹in a list sorted as needed, and use a binary search to retrieve items and search for insertion points for new items.

You can even wrap it all up and put it in the Map interface.

The Collections class provides binarySearch . Here is the diagram:

  • Place the Value class on the list, List<Value> values .
  • Introduce the Comparable<Value> class, which compares values โ€‹โ€‹using the attribute you want to sort.
  • Use Comparator<Value> to sort the list.
  • Now that the list is sorted, you can use Collections.binarySearch(values, aValue, Comparator<Value>) to find the index of the actual value. Note that aValue is not a real value - it is a value with attributes set to provide the key, but the rest is not unenalized. AValue is used only to store the sort key.

In code

 List<Value> values = new ArrayList<Values>(); // .. add values values.add(new Value(key, data1, data2, etc..)); Comparator<Value> compValue = new Comparator<Value>() { public int compare(Value v1, Value v2) { return v1.getKey()>v2.getKey(); } } Collections.sort(values, compValue); // now we can search on key int index = Collections.binarySearch(values, new Value(keyTofind), valueComp); Value foundValue = null; // value with the key may not be in the list if (index>=0) foundValue = values.get(index); // we can also update the list Value newValue = new Value(key, data, data2, etc...); int insert = Collections.binarySearch(values, newValue, valueComp); // insert will be negative values.add((-insert)-1, newValue); 

EDIT: if you wrap this in a map interface, for example. Extending AbstractMap, it will be serializable.

0
source share

All Articles