联系人算法优化

2018-05-04  本文已影响0人  满满满的日落

        先说下功能需求,上传联系人,因为联系人可能过多,不上传联系人头像,只上传联系人姓名,号码,但是UI上展示已经上传的联系人的时候又需要展示头像,这时候,只能是从服务器获取到联系人,然后去匹配本机的联系人,找到头像,然后展示。

        有的同学说了,那简单啊,两层for循环嵌套下,找到本地的联系人头像展示就完事了,代码大致是这种:

无脑循环法

        上面这种,的确没有BUG,但却是一种很烂的算法,复杂度达到了O(N²),如果别人联系人非常多的情况下,这种写法,效率会低到不行。这种时候我们就要考虑进行算法优化,经过思考,选择利用散列来将复杂度从 N² 降低到 N,散列的话,读取的复杂度是常量阶(如果不了解散列数据结构的同学可以自行去学习一把),在这种需求下,对于Java已经封装好的散列结构我认为HashMap最适合。

        思路就是,首先,让后台拿到的Contact对象与本地拿到的Contact对象在 姓名 与 号码一致的情况下 hashcode一致,这样才能产生碰撞(对象放到散列数组里的位置是其hashCode值与散列大小决定的),然后就是覆盖equals方法,当 姓名 和 号码一致,就认为其是同一个对象。这样就可以以本地联系人来覆盖服务器拿到的联系人,话不多说,上代码:

Contact对象的equals与hashCode方法

        然后我们就可以建立一个以Contact对象为KEY,Contact的头像Uri为value的HashMap

1.把后台获取到的Contact全部放到hashmap里,此时value全为null,因为后台根本没有头像地址

2.把本地获取到的Contact全部放到hashmap里,value对应为本地获取到的头像Uri,此时,如果姓名 号码 都一致,后台获取的Contact对象与本地的Contact对象就会产生碰撞,碰撞之后HashMap会判断两个对象是否 equal,如果不equal,就把其插入到对应散列位置的链表里,但是我们已经覆盖了equal方法,所以肯定是相等的,hashmap就会直接用新插入的值覆盖掉之前的值。此时我们就得到了一个带有本地联系人头像URI的hashmap.

3.遍历服务器获取到的联系人,一一去hashmap取到头像URI,塞入到服务器获取到的联系人对象里。大功告成,上代码:

运用散列将算法优化

总结:代码很简单,只要思路对了,实现起来很快。PS:之前获取本地联系人的时候,闷头网上找一段拿来复制粘贴,结果就进了坑,复制了一份双层循环的查询语句,后来仔细看的时候大概是先查询到所有的contactId然后通过contactId去aw_contacts表中读取raw_contact_id,再用raw_contact_id到data表读取所有信息,导致测试的时候,大概多于1000个联系人的时候,APP直接ANR,蛮尴尬。复制代码需谨慎,哈哈。

上一篇下一篇

猜你喜欢

热点阅读