Java中使用HashMap改进查找性能的步骤
java中,hashmap,其实就是键值对。一个key,对应一个值;写数据时,指定key写对应值;读取时凭key找到相应值。感觉就跟redis差不多。
// 创建 hashmap 对象 sites hashmap<integer, string> sites = new hashmap<integer, string>(); // 添加键值对 sites.put(1, "google"); sites.put(2, "runoob"); sites.put(3, "taobao"); sites.put(4, "zhihu"); //读取 string val = sites.get(1);//得到google
为什么说可以用hashmap来改进性能呢?原因不是说hashmap这种数据结构存储性能就比其他的,比如数组,集合先进多少。我主要看中的,是在知道key的情况下,找到相应值得速度非常快。如果是用数组,最简单的,用循环;讲究一点,排好序,用折半查找(二分查找)。都比不上用key在hashmap里直接读取。不知道为什么hashmap在查找方面为啥这么快,估计是存储结构,使用了啥树,并为key建立了索引。这是另外一个课题,以后再了解。昨天,我只是利用了这个特性,将运行几个小时都没结束的问题,只耗费了十几秒。
问题如下:
有25万条记录,每条记录含经纬度;存在不同记录坐标相同情况。现在想将坐标相同的记录归并在一起。
如果数据是保存在数据库里,那么用sql进行坐标分组,应该能解决问题。然而并没有数据库,数据是从gdb文件里读出来的。
好吧,将数据保存到数组里,再新建一个集合;然后循环数组,与新集合中的记录逐个比较,坐标相同就归并到新集合,不同就插入新集合。最简单了。结果2个小时过去了,还没有结束的迹象。
想想也对,新集合越来越大,比较的次数也越来越多,仿佛棋盘里的大米一样,每格的大米数量是前一格的两倍;最后即使是整个国家粮库的大米都放进去,都填不满整个棋盘。
将25万条记录先排好序再处理?单是排序就忙死了,不行吧。
将25万条记录先保存到数据库里,再分组?应该也可以,但总觉得笨了一些,而且速度应该也是以分钟算的。
最后决定用hashmap来做这个新集合。
如上所述,hashmap按照key来写入或读取值。关键是这个key怎么得来。上面的例子,是写代码的人自己给出了一些字符作为key。而在我们项目中,可以用经纬度之和的哈希值来作为key。哈希值相同的,就认为是经纬度相同,只需要判断新集合中,是否存在这个key对应的元素就可以了,根本无须循环比较。
由于存在两个不同的经纬度加起来,结果是一样的可能性,因此先将经度 乘以1000,再加纬度,这样基本杜绝冲突的机会。
代码如下:
private hashmap<long,simpleitem> recgeo(hashmap<long, simpleitem> map,string geo,int j){ /* 将相同坐标的记录合成一条 hashmap<long, simpleitem> map, 新集合 string geo, 坐标字符串 int j 记录id */ try { point p = (point)reader.read(geo); /* 计算哈希值 因为如果采用循环来比较,数据量太大,速度太慢了 为避免不同坐标出现经度+纬度结果相同的情况,将经度 * 1000再相加 */ //计算key long k = long.valueof(double.doubletolongbits(p.getx() * 1000 + p.gety())).hashcode(); simpleitem si = map.get(k); if(si != null){//新集合中该key对应元素已存在,应该是相同坐标的记录 si.getpointers().add(j);//归并 } else {//否则插入 si = new simpleitem(); si.setgeo(geo); list<integer> pointers = new arraylist(); pointers.add(j); si.setpointers(pointers); map.put(k,si); } } catch (parseexception e) { e.printstacktrace(); } return map; } private static geometryfactory geometryfactory = jtsfactoryfinder.getgeometryfactory( null ); private static wktreader reader = new wktreader( geometryfactory ); class simpleitem{ private point geo; private list<integer> pointers; public point getgeo() { return geo; } public void setgeo(string geo) { try { this.geo = (point)reader.read(geo); } catch (parseexception e) { e.printstacktrace(); } } public list<integer> getpointers() { return pointers; } public void setpointers(list<integer> pointers) { this.pointers = pointers; } }
短短几秒,新集合即得到5万个元素。
以上就是java中使用hashmap改进查找性能的步骤的详细内容,更多关于java hashmap改进查找性能的资料请关注其它相关文章!
上一篇: 张郃忠心耿耿,为何司马懿却要陷害他呢?
推荐阅读
-
Java中使用HashMap改进查找性能的步骤
-
Java日期时间API系列30-----Jdk8中java.time包中的新的日期时间API类,减少时间精度方法性能比较和使用。
-
java 中linq 的使用方式 筛选 查找 去重
-
Java8中的流操作-基本使用&性能测试
-
Java8中的流操作-基本使用&性能测试
-
Java手写简易版HashMap的使用(存储+查找)
-
java中HashMap的7种遍历方式与性能分析
-
Java日期时间API系列30-----Jdk8中java.time包中的新的日期时间API类,减少时间精度方法性能比较和使用。
-
java 中linq 的使用方式 筛选 查找 去重
-
Java中HashMap遍历与使用的示例详解