当我在 android 中使用哈希映射时显示警告(使用新的 SparseArray<String>)
Posted
技术标签:
【中文标题】当我在 android 中使用哈希映射时显示警告(使用新的 SparseArray<String>)【英文标题】:Warning shows when i use Hash Map In android(Use new SparseArray<String>) 【发布时间】:2013-01-25 02:48:31 【问题描述】:我是 android 开发的新手。在我的 android 应用程序中,我使用的是 HashMap
,但我收到了警告:
**"Use new SparseArray<String>(...) instead for better performance"**
这是什么意思,我该如何改用SparseArray<String>
?
【问题讨论】:
【参考方案1】:改用新的
SparseArray<String>(...)
以获得更好的性能
由于here 描述的原因,您收到此警告。
SparseArrays 将整数映射到对象。不同于普通的数组 对象,索引中可能存在间隙。它的目的是更多 比使用 HashMap 将整数映射到对象更有效。
现在
我如何使用 SparseArray ?
您可以通过以下方式进行:
HashMap
方式:
Map<Integer, Bitmap> _bitmapCache = new HashMap<Integer, Bitmap>();
private void fillBitmapCache()
_bitmapCache.put(R.drawable.icon, BitmapFactory.decodeResource(getResources(), R.drawable.icon));
_bitmapCache.put(R.drawable.abstrakt, BitmapFactory.decodeResource(getResources(), R.drawable.abstrakt));
_bitmapCache.put(R.drawable.wallpaper, BitmapFactory.decodeResource(getResources(), R.drawable.wallpaper));
_bitmapCache.put(R.drawable.scissors, BitmapFactory.decodeResource(getResources(),
Bitmap bm = _bitmapCache.get(R.drawable.icon);
SparseArray
方式:
SparseArray<Bitmap> _bitmapCache = new SparseArray<Bitmap>();
private void fillBitmapCache()
_bitmapCache.put(R.drawable.icon, BitmapFactory.decodeResource(getResources(), R.drawable.icon));
_bitmapCache.put(R.drawable.abstrakt, BitmapFactory.decodeResource(getResources(), R.drawable.abstrakt));
_bitmapCache.put(R.drawable.wallpaper, BitmapFactory.decodeResource(getResources(), R.drawable.wallpaper));
_bitmapCache.put(R.drawable.scissors, BitmapFactory.decodeResource(getResources(),
Bitmap bm = _bitmapCache.get(R.drawable.icon);
希望它会有所帮助。
【讨论】:
确保查看链接文档,该文档继续详细说明“实施不适用于可能包含大量项目的数据结构”。 SparseArray 通常比可比较的 HashMap 慢。 我已经阅读了文档,但仍有一些问题并阅读了一些关于 Java 地图的内容。我在 HashMap 上发现的一些东西:如果散列函数“正确”分散,它为 get/put 提供恒定时间性能。 Map 允许一个空键(表不允许)。在稀疏数组上,文档说使用少量数据可以获得更好的性能。什么尺寸? (引用)“对于容纳数百个项目的容器,性能差异小于 50%”——我认为这意味着在使用数百个键:值时稀疏开始输给 map(/table?)。就我而言 - 我想要稀疏的。【参考方案2】:SparseArray
在您使用Integer
作为键时使用。
使用SparseArray
时,键 将始终作为原始变量,而使用HashMap
时需要Object
作为 key 将导致 int 在短时间内成为 Integer
对象,同时将对象放入地图。
通过使用SparseArray
,您将为垃圾收集器节省一些工作。
所以就像Map<Integer,String>
一样使用。
【讨论】:
+1,避免了 HashMap 发生的自动装箱(和关联的对象+GC)。 @cyril-mottier 在这里写道:speakerdeck.com/cyrilmottier/… 从技术上讲,您不是“使用Integer
作为密钥”。您正在使用int
。【参考方案3】:
这暗示了您的代码有更好的数据结构。
该提示来自 Lint。当你有一个HashMap
的整数到别的东西时,你通常会得到它。
它最大的优点是将整数键视为原语。换句话说,它不会转换为Integer
(Java 对象)以将其用作键。
这在使用大型地图时很重要。在这种情况下,HashMap
将导致创建很多很多 Integer
对象。
查看更多信息here。
【讨论】:
developer.android.com/reference/android/util/SparseArray.html 说:“该实现不适用于可能包含大量项目的数据结构。它通常比传统的 HashMap 慢,...” - 这意味着:如果您对速度感兴趣并且想要存储许多值,则必须使用 HashMap。【参考方案4】:对于整数键值对,SparseArray 是比 HashMap 更好的内存效率数据结构。而且它是特定于 Android 的,我相信它不能用于 Java SE。
有时,Linter 警告显示 SparseArray 必须像上面那样使用。这个愚蠢的警告可能是对的,也可能是错的。如果您觉得合适,您需要决定使用 SparseArray 而不是 HashMap,或者您需要使用 @SuppressLint 注释来抑制它。
要决定是否实施,值得进行一些研究并评估您的情况。你可以在这里找到所有有用的链接
https://gunhansancar.com/sparsearray-vs-hashmap/
https://developer.android.com/reference/android/util/SparseIntArray
【讨论】:
以上是关于当我在 android 中使用哈希映射时显示警告(使用新的 SparseArray<String>)的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Xcode 在 appdelegate.h 文件中使用 AVAudioPlayer Delegate 协议时显示警告?