HashMap的ArrayList或LinkedHashMap的按索引获取项目

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HashMap的ArrayList或LinkedHashMap的按索引获取项目相关的知识,希望对你有一定的参考价值。

我需要以键值形式存储大量数据。另外,我有两个要求

  1. 通过索引查询数据,例如从数组中查询数据。
  2. 因此必须保留数据结构中的顺序。

对于要求2-我可以使用LinkedHashMap

对于要求1-我有两个选择:

  • 1.1 |实现HashMap的ArrayList。 [ArrayList<HashMap<String,String>>]
  • 1.2 |要实现LinkedHashMap并使用类似以下内容的索引来查询项目
    • -> new ArrayList(hashMapObject.entrySet()).get(0);

问题是1.11.2中哪个更好?

更好,我的意思是-在内存和空间方面很有效。

[假设数据量在50到100个键值对之间,并且具有平均大小的字符串-假设每个键是10-30个字符,值是30-50个字符。

答案

尝试使用SortedMap。

例如:

SortedMap<Key, Value> map = new TreeMap<Key, Value>();

通过这种方式,您可以通过密钥获得快速的查找时间,但它们仍然保持有序。

然后您可以像这样遍历数据:

for(Key k : map.keySet()) { 
    process(map.get(k)); 
}

我最近使用它们来分析千万条推文,其中键是日期,而值是计数器。我想保持日期的顺序。

update如果仅通过迭代数据就可以解决问题,那么我的方法就足够了。也许您可以举一个小例子?如果绝对需要您也可以按索引引用数据,则似乎您只想维护提到的@Jim这样的两个数据结构。我以前必须这样做。

另一答案

请记住,集合不包含对象,仅references包含对象。

使用两个集合:

  1. ArrayList存储引用以供按索引访问
  2. A HashMap存储引用以供密钥访问

例如:

List<MyValue> list = new ArrayList<MyValue>(100000);
Map<MyKey,MyValue> map = new HashMap<MyKey,MyValue>(100000);

while(moreItems) {
    // read input
    MyKey key = ...
    MyValue value = ...
    list.add(value);
    map.put(key,value);
}

// lookup by index
MyValue v1 = list.get(11241);
// lookup by key
MyValue v2 = map.get(someKey);

如果您需要交叉引用(即给定值对象,请找到其索引或键),您可以选择以下选项:

  1. 将索引和键保存在值对象本身中
  2. 将值包装在包含键和索引的“句柄”中。

例如

class Wrapper {
    MyKey   key;
    MyValue value;
    int     index;
    // constructor, getters and setters
}

int index=0;
while(moreItems) {
    // read input
    MyKey key = ...
    MyValue value = ...
    Wrapper w = new Wrapper(key,value,index++);
    list.add(w);
    map.put(key,w);
}
...
Wrapper w = list.get(23410);
MyKey k = w.getKey();
MyValue v = w.getValue();
int i = w.getIndex();
...
另一答案

我认为LinkedHashMap是最好的解决方案,但是要获得该项目,您可以使用

hashMapObject.values().toArray()[index]

但是,对于大量数据,toArray方法将很慢。但这是您必须测试的。

如果速度确实是一个问题,则可以维护HashMap ArrayList。

另一答案

我自己进行了实验。事实证明,创建HashMaps的ArrayList的方法大约用1000个元素快40倍。

public class HashMapVsArrayOfHashMap {

    public static void main(String[] args){
        ArrayList<HashMap<String, String>> listOfMaps=new ArrayList<HashMap<String,String>>();
        for( int i=0;i<1000;i++){
            final int finalI=i;
        listOfMaps.add(new HashMap<String, String>(){{put("asdfasdfasdfasdfadsf"+finalI,"asdfsdafasdfsadfasdf"+finalI);}});
        }
        LinkedHashMap<String, String> map=new LinkedHashMap<String, String>();
        for(int i=0;i<1000;i++)
            map.put("asdfasdfasdfasdfadsf"+i,"asdfsdafasdfsadfasdf"+i);     
        int position=700;
        testArrayList("Method1:ArrayListOfHashMaps",position,listOfMaps);
        testHashMap("Method2:LinkedHashMap",position,map);
    }

    private static void testArrayList(String string, int position,
            ArrayList<HashMap<String, String>> listOfMaps) {
        long start, end;
        start=System.nanoTime();
        listOfMaps.get(position).get("asdfasdfasdfasdfadsf"+position);
        end=System.nanoTime();
        System.out.println(string+"|Difference = "+(end-start));        
    }
    private static void testHashMap(String string, int position,
            LinkedHashMap<String, String> map) {
        long start, end;
        start=System.nanoTime();

        String s= new ArrayList<String>(map.keySet()).get(position);

        end=System.nanoTime();
        System.out.println(string+"|Difference = "+(end-start));        
    }
}

“在此处输入图像描述”

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9xYTZnSy5wbmcifQ==” alt =“在此处输入图像说明”>

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS8zS3RhRC5wbmcifQ==” alt =“在此处输入图像说明”>

当您将大小增加到30,000个元素时-差异很大。

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9WcUZERi5wbmcifQ==” alt =“在此处输入图像描述”>

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS93S1lSci5wbmcifQ==” alt =“在此处输入图像描述”>“ >>

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9Uc3RZMS5wbmcifQ==” alt =“在此处输入图像描述”>

以上是关于HashMap的ArrayList或LinkedHashMap的按索引获取项目的主要内容,如果未能解决你的问题,请参考以下文章

包含不同片段的HashMap(或ArrayList)

哪个更有效:使用 removeAll() 或使用以下 HashMap 技术仅保留 ArrayList 中的更改记录

彻底理解HashMap及LinkedHashMap

ArrayList 和 HashMap 使用指令

ArrayList 和 HashMap 使用指令

Java ArrayList:从包含 HashMap 的 ArrayList 中获取不同的值