当我在 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&lt;String&gt;

【问题讨论】:

【参考方案1】:

改用新的SparseArray&lt;String&gt;(...) 以获得更好的性能

由于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&lt;Integer,String&gt; 一样使用。

【讨论】:

+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>)的主要内容,如果未能解决你的问题,请参考以下文章

动态禁用控件时显示警告消息 angular2

Android:关闭软键盘时显示空白

如果单击按钮时显示警告消息,则不显示更新的搜索结果列表

为啥 Xcode 在 appdelegate.h 文件中使用 AVAudioPlayer Delegate 协议时显示警告?

当我尝试在我的 Android 设备上预览我的应用程序时显示错误

如何在适用于 Android 和 cordova 的项目中单击通知时显示特定页面?