theGreenCabbage
theGreenCabbage

Reputation: 4845

HashMap/TreeMap sorting my keys

Using JSoup I am scraping some data from a website that gives me pollen data. They do not have an API access, so scraping was my last resort.

Using a HashMap, I am storing the date and the pollenIndex, which is how high pollen levels are that day on a scale of 0.0 - 10.0.

private static Map<String, String> pollenMap = new HashMap<String, String>();

This is part of the constructor of my Pollen class.

for(int i = 0; i < 4; i++)
{
    Element dates = doc.select("td.text-center.even-four").get(i);
    Element levels = doc.select("td.levels").get(i);

    System.out.println(dates.text() + ", " + levels.text());

    pollenMap.put(dates.text(), levels.text());
}

One issue is that HashMap sorts the data for me. The output of the pollenMap is this:

 : [Monday May 26, 2014, Wednesday May 28, 2014, Sunday May 25, 2014, Tuesday May 27, 2014]
 : [7.90, 6.60, 7.60, 8.80]

As you can see, HashMap sorts my dates keys, resulting in Monday coming first, and Tuesday last.

I may be using the HashMap incorrectly, so my friend suggested I use TreeMap, however, the result of that was this:

 : [Monday May 26, 2014, Wednesday May 28, 2014, Sunday May 25, 2014, Tuesday May 27, 2014]
 : [7.90, 6.60, 7.60, 8.80]

How do I use this key-value structure without it being sorted?

Apologies for the novice question on this data structure. I could use two String lists but I want to learn these new data structures.

Upvotes: 0

Views: 592

Answers (3)

Paul Draper
Paul Draper

Reputation: 83421

(1) java.util.HashMap makes no guarantees about order.

(2) java.util.SortedMap, such as java.util.TreeMap sorts by key. (In your case, sorting the String keys lexicographically.)


How do I use this key-value structure without it being sorted?

If you want to iterate over the key-values in the order in which you inserted them, you need java.util.LinkedHashMap.

This implementation differs from HashMap in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order).


OP doesn't want to preserve insertion order. He/she wants date order.

If you want to iterate over the key-values in the order of the dates, use a java.util.TreeMap, but parse the Strings to Dates.

SimpleDateFormat format = new SimpleDateFormat("EEEEE MMMM d, yyyy");
for(int i = 0; i < 4; i++)
{
    Element dates = doc.select("td.text-center.even-four").get(i);
    Element levels = doc.select("td.levels").get(i);

    System.out.println(dates.text() + ", " + levels.text());

    pollenMap.put(format.parse(dates.text()), levels.text());
}

Incidentally, you may want to do the same for your measurements, and store them as longs or java.math.BigDecimals.

Upvotes: 4

Dawood ibn Kareem
Dawood ibn Kareem

Reputation: 79875

Your problem is that you are using String values to store both dates, and decimals. When you sort, your dates are getting sorted alphabetically, which in this case is putting Monday before Saturday, and so on.

Since you're storing date data and decimal data in your map, you should make it a TreeMap<Date,BigDecimal> instead of a TreeMap<String,String>. Parse your dates and your decimals before putting them into the map. The TreeMap code will then sort them correctly.

Upvotes: 0

Elliott Frisch
Elliott Frisch

Reputation: 201537

HashMap does not sort the data; it hashes the keys to assign the data to buckets! You can create a Key-Value type and store your data in a List or a Stack. They will preserve your insertion order.

Upvotes: 2

Related Questions