2

I need to have a resultset converted into a Map of Maps. The reason why I'm not using a List of Maps is because I don't want to iterate through the entire List to get a specific row.

The problem I am facing now is that the HashMap's entries aren't ordered anymore if the index is greater than 16.

Now I tried the following for a simple test:

    public static void main(String[] args) {

    Map<Integer, String> map = new HashMap<Integer, String>();

    //creating 20 rows from 1 to 20
    for (int i = 1; i <= 20; i++){
        map.put(i, "ROW "+i);   
    }


    //returning all the rows the map contains. Look at position 16.
    for(int key : map.keySet()){
        System.out.println(key);    
    }
}

And the output is the following (look at position 16 to 20. They are totally unordered):

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17 16 19 18 20

I would really appreciate it, if someone can explain why that happens.

And by the way:

i cant use something like this:

for (int i = 0; i < map.size; i++){
    map.get(i) //...and so on

}

because I don't know if the index exists. It may be that that the index from 200 to 800 doesnt exist. So it would be better only to iterate through exisiting entries of the map.

6 Answers 6

7

A HashMap is not ordered or sorted. If you need an insertion ordered Mapuse java.util.LinkedHashMap. If you need a Mapsorted by the key, use a SortedMapsuch as java.util.TreeMap

Sign up to request clarification or add additional context in comments.

Comments

4

You should use either a TreeMap or a LinkedHashMap instead of a HashMap depending on if you want elements sorted by their natural order or insertion order respectively.

A HashMap makes no guarantees about the ordering of keys. The other two Map implementations I referenced do.

A TreeMap will sort keys based on their natural order which means the keys must implement Comparable or you have to provide your own comparator in order to determine the ordering.

A LinkedHashMap will keep the keys ordered based on when they are inserted.

Since they behavior you're looking for is for the keys to be naturally ordered and you happen to be inserting the keys in order yourself, either implementation would work for this case.

Comments

3

You can use a LinkedHashMap to keep order of insertion instead since basic maps do not guarantee the order of keys.

Comments

3

How about using TreeMap? Instead of HashMap. You can provide even your own ordering.

1 Comment

TreeMap wastes more resources, it doesn't sound like the OP needs custom sorting, just keeping insertion order.
2

The reason why I'm not using a List of Maps is because I don't want to iterate through the entire List to get a specific row.

So make it an ArrayList instead of a LinkedList. That way, list.get(1234) will go straight to that entry -- it won't iterate over the 1234 entries before it.

Comments

1

I think the problem you are facing is because of the default size of HashMap.

According to standard java documentation,

/**
 * The default initial capacity - MUST be a power of two.
 */
static final int DEFAULT_INITIAL_CAPACITY = 16;
/**
 * The load factor used when none specified in constructor.
 */
static final float DEFAULT_LOAD_FACTOR = 0.75f;

/**
 * Constructs an empty <tt>HashMap</tt> with the default initial capacity
 * (16) and the default load factor (0.75).
 */
public HashMap() {
    this.loadFactor = DEFAULT_LOAD_FACTOR;
    threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
    table = new Entry[DEFAULT_INITIAL_CAPACITY];
    init();
}

So, you are not getting proper output after 16th element.

According to JavaDoc,

/**
 * Constructs an empty <tt>HashMap</tt> with the specified initial
 * capacity and the default load factor (0.75).
 *
 * @param  initialCapacity the initial capacity.
 * @throws IllegalArgumentException if the initial capacity is negative.
 */
public HashMap(int initialCapacity) {
    this(initialCapacity, DEFAULT_LOAD_FACTOR);
}

try the following (Parameterized constructor with initial capacity),

Map<Integer, String> map = new HashMap<Integer, String>(32);

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.