简体   繁体   English

Java地图 <Integer, HashMap<String, String> &gt;

[英]Java Map<Integer, HashMap<String, String>>

I need to have a resultset converted into a Map of Maps. 我需要将结果集转换为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. 我现在面临的问题是,如果索引大于16,则HashMap的条目不再排序。

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): 输出是以下内容(查看位置16到20。它们完全是无序的):

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17 16 19 18 20 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. 从200到800的索引可能不存在。 So it would be better only to iterate through exisiting entries of the map. 因此,最好仅通过现有地图条目进行迭代。

A HashMap is not ordered or sorted. HashMap没有排序或排序。 If you need an insertion ordered Map use java.util.LinkedHashMap . 如果需要插入顺序的Map使用java.util.LinkedHashMap If you need a Map sorted by the key, use a SortedMap such as java.util.TreeMap 如果需要按键排序的Map ,请使用SortedMap例如java.util.TreeMap

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. 您应该使用TreeMapLinkedHashMap代替HashMap,具体取决于您是否希望元素分别按其自然顺序或插入顺序进行排序。

A HashMap makes no guarantees about the ordering of keys. HashMap不保证键的顺序。 The other two Map implementations I referenced do. 我引用的其他两个Map实现。

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. TreeMap将根据键的自然顺序对键进行排序,这意味着键必须实现Comparable,或者您必须提供自己的比较器才能确定顺序。

A LinkedHashMap will keep the keys ordered based on when they are inserted. LinkedHashMap将根据插入密钥的顺序来对其进行排序。

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. 由于您要查找的行为是自然地对键进行排序,并且碰巧自己按顺序插入了键,因此在这种情况下,任何一种实现都可以使用。

您可以使用LinkedHashMap来保持插入顺序,因为基本映射不能保证键的顺序。

How about using TreeMap? 如何使用TreeMap? Instead of HashMap. 而不是HashMap。 You can provide even your own ordering. 您甚至可以提供自己的订购。

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 . 因此,使其成为ArrayList而不是LinkedList That way, list.get(1234) will go straight to that entry -- it won't iterate over the 1234 entries before it. 这样, list.get(1234)会直接转到该条目-它不会迭代之前的1234个条目。

I think the problem you are facing is because of the default size of HashMap. 我认为您面临的问题是由于HashMap的默认大小。

According to standard java documentation, 根据标准的Java文档,

/**
 * 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. 因此,在第16个元素之后,您将无法获得正确的输出。

According to JavaDoc, 根据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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM