文档章节

SparseArray介绍

似水流年0_0
 似水流年0_0
发布于 2016/01/11 14:31
字数 753
阅读 4430
收藏 34
点赞 5
评论 4

首先说一下SparseArray是什么东西,在java中我们也没见过这个API啊,哦,原来是android中定义的一个类,按字面意思来说是一个稀疏数组,但通过源码注释我们发现它和数组有很大的区别:

 SparseArrays map integers to Objects.  Unlike a normal array of Objects,
* there can be gaps in the indices.  It is intended to be more memory efficient
* than using a HashMap to map Integers to Objects, both because it avoids
* auto-boxing keys and its data structure doesn't rely on an extra entry object
* for each mapping.

我们通过这段注释大体知道,android希望我们用SparseArray在一些情况下代替HashMap来使用,因为它有更好的性能,大家都知道内存是非常宝贵的,尤其是在手机上。

再看一下它的两个构造函数:

/**
 * Creates a new SparseArray containing no mappings.
 */
public SparseArray() {
    this(10);
}

/**
 * Creates a new SparseArray containing no mappings that will not
 * require any additional memory allocation to store the specified
 * number of mappings.  If you supply an initial capacity of 0, the
 * sparse array will be initialized with a light-weight representation
 * not requiring any additional array allocations.
 */
public SparseArray(int initialCapacity) {
    if (initialCapacity == 0) {
        mKeys = EmptyArray.INT;
        mValues = EmptyArray.OBJECT;
    } else {
        mValues = ArrayUtils.newUnpaddedObjectArray(initialCapacity);
        mKeys = new int[mValues.length];
    }
    mSize = 0;
}

发现其默认的key-value数组大小是10,当然也可以是自定义的。

SparseArray中有一些和HashMap中相似的实用方法,比如:

put(int key, E value)
get(int key)
get(int key, E valueIfKeyNotFound)
delete(int key)
removeAt(int index)
keyAt(int index)
valueAt(int index)
等等。

随便分析一个方法,比如put(int key,E value):

/**
 * Adds a mapping from the specified key to the specified value,
 * replacing the previous mapping from the specified key if there
 * was one.
 */
public void put(int key, E value) {
    int i = ContainerHelpers.binarySearch(mKeys, mSize, key);

    if (i >= 0) {
        mValues[i] = value;
    } else {
        i = ~i;

        if (i < mSize && mValues[i] == DELETED) {
            mKeys[i] = key;
            mValues[i] = value;
            return;
        }

        if (mGarbage && mSize >= mKeys.length) {
            gc();

            // Search again because indices may have changed.
            i = ~ContainerHelpers.binarySearch(mKeys, mSize, key);
        }

        mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
        mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);
        mSize++;
    }
}

代码中首先查询该key在SparseArray中是否已经存在,若存在,替换掉,若不存在,把对应的key和value插入到对应的数组中,然后mSize++。大家注意到在查询key时使用的折半查找,看源码:

class ContainerHelpers {

    // This is Arrays.binarySearch(), but doesn't do any argument validation.
    static int binarySearch(int[] array, int size, int value) {
        int lo = 0;
        int hi = size - 1;

        while (lo <= hi) {
            final int mid = (lo + hi) >>> 1;
            final int midVal = array[mid];

            if (midVal < value) {
                lo = mid + 1;
            } else if (midVal > value) {
                hi = mid - 1;
            } else {
                return mid;  // value found
            }
        }
        return ~lo;  // value not present
    }

    static int binarySearch(long[] array, int size, long value) {
        int lo = 0;
        int hi = size - 1;

        while (lo <= hi) {
            final int mid = (lo + hi) >>> 1;
            final long midVal = array[mid];

            if (midVal < value) {
                lo = mid + 1;
            } else if (midVal > value) {
                hi = mid - 1;
            } else {
                return mid;  // value found
            }
        }
        return ~lo;  // value not present
    }
}

哇哦,是不是我们在java中常用的一种查找方式。

知道了这些之后,我们以后就可以使用SparseArray来代替HashMap了,但是要注意SparseArray中的key是int类型,若实际中不是int类型,还得乖乖的使用map,另外,根据key-value中的value类型不同,android又给封装了SparseIntArray,SparseBooleanArray,SparseLongArray等等,使用方法和SparseArray都大同小异,只要你会使用Map,那么你就会使用SparseArray。

© 著作权归作者所有

共有 人打赏支持
似水流年0_0
粉丝 55
博文 79
码字总数 51471
作品 0
长宁
高级程序员
加载中

评论(4)

J
Johnnyan
还有simplearraymap
J
Johnnyan
已经使用了
似水流年0_0
似水流年0_0

引用来自“meng0823”的评论

:stuck_out_tongue_winking_eye::stuck_out_tongue_winking_eye:
meng0823
meng0823
:stuck_out_tongue_winking_eye::stuck_out_tongue_winking_eye:
Android内存优化(使用SparseArray和ArrayMap代替HashMap)

在Android开发时,我们使用的大部分都是Java的api,比如HashMap这个api,使用率非常高,但是对于Android这种对内存非常敏感的移动平台,很多时候使用一些java的api并不能达到更好的性能,相反...

u010687392
2015/08/20
0
0
Save State

Save State Activity: PhoneWindow: View: ViewGroup:

lightUp
2016/09/27
1
0
Android性能优化之SparseArray源码分析

前言 迟到一年的HashMap解读 文章中讲述了常用Java编程的数据结合HashMap的一些知识点。但如果在Android编程中出现HashMap的时候,编译器就会提示用SparseArray代替HashMap。为什么呢?众所周...

静默加载
2017/10/30
0
0
关于Android中 SparseArray和HashMap的讨论笔记

SparseArray结构比HashMap简单(SparseArray内部主要使用两个一维数组来保存数据,一个用来存key,一个用来存value)不需要额外的额外的数据结构(主要是针对HashMap中的HashMapEntry而言的)...

SuShine
2015/08/02
0
3
谈谈源码中的SparseArray

谈谈源码中的SparseArray 在Andorid的源码和第三方库中,偶尔能看到该类,我们先来看一下官方文档的说明如下: SparseArray map integers to Objects. Unlike a normal array of Objects,th...

程序猿骆二胖
2015/12/04
36
0
SparseArray替代HashMap来提高性能

SparseArray是 Android框架独有的类,在标准的JDK中不存在这个类。它要比 HashMap 节省内存,某些情况下比HashMap性能更好,按照官方问答的解释,主要是因为SparseArray不需要对key和value进...

Jerikc
2014/06/03
0
0
数据结构HashMap(Android SparseArray 和ArrayMap)

HashMap也是我们使用非常多的Collection,它是基于哈希表的 Map 接口的实现,以key-value的形式存在。在HashMap中,key-value总是会当做一个整体来处理,系统会根据hash算法来来计算key-val...

codeGoogle
06/20
0
0
Android基础学习:Android App性能提升

最近我在进行Android App的性能提升,在使用Android Studio的Code Inspect功能的过程中,发现系统提醒我进行如下操作: 系统提醒我把HashMap替换成相应的SparseIntArray和SparseArray。 之前...

Android开发
2017/12/19
0
0
Android SparseArray用法详解

传统的通过定义对象,运用面向对象的封装特性,实现视图的缓存,这里使用一种快速而便捷的缓存方式——SparseArray,此数据结构是通过Key和Value的index实现的,无论查询和插入效率,比HashM...

IamOkay
2014/10/25
0
0
Android碎碎念 -- 稀疏数组:SparseArray

在一般情况下,使用HashMap<K, V>,如果K整数类型的话,使用SparseArray效率会更高。 和HashMap类似,SparseArray建立整数索引和对象的关系。和简单的对象数组相比,SparseArray允许索引之间...

淡定的米哥
2015/12/16
80
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

SpringBoot | 第十章:Swagger2的集成和使用

前言 前一章节介绍了mybatisPlus的集成和简单使用,本章节开始接着上一章节的用户表,进行Swagger2的集成。现在都奉行前后端分离开发和微服务大行其道,分微服务及前后端分离后,前后端开发的...

oKong
今天
2
0
Python 最小二乘法 拟合 二次曲线

Python 二次拟合 随机生成数据,并且加上噪声干扰 构造需要拟合的函数形式,使用最小二乘法进行拟合 输出拟合后的参数 将拟合后的函数与原始数据绘图后进行对比 import numpy as npimport...

阿豪boy
今天
1
0
云拿 无人便利店

附近(上海市-航南路)开了家无人便利店.特意进去体验了一下.下面把自己看到的跟大家分享下. 经得现场工作人员同意后拍了几张照片.从外面看是这样.店门口的指导里强调:不要一次扫码多个人进入....

周翔
昨天
1
0
Java设计模式学习之工厂模式

在Java(或者叫做面向对象语言)的世界中,工厂模式被广泛应用于项目中,也许你并没有听说过,不过也许你已经在使用了。 简单来说,工厂模式的出现源于增加程序序的可扩展性,降低耦合度。之...

路小磊
昨天
156
1
npm profile 新功能介绍

转载地址 npm profile 新功能介绍 npm新版本新推来一个功能,npm profile,这个可以更改自己简介信息的命令,以后可以不用去登录网站来修改自己的简介了 具体的这个功能的支持大概是在6这个版...

durban
昨天
1
0
Serial2Ethernet Bi-redirection

Serial Tool Serial Tool is a utility for developing serial communications, custom protocols or device testing. You can set up bytes to send accordingly to your protocol and save......

zungyiu
昨天
1
0
python里求解物理学上的双弹簧质能系统

物理的模型如下: 在这个系统里有两个物体,它们的质量分别是m1和m2,被两个弹簧连接在一起,伸缩系统为k1和k2,左端固定。假定没有外力时,两个弹簧的长度为L1和L2。 由于两物体有重力,那么...

wangxuwei
昨天
0
0
apolloxlua 介绍

##项目介绍 apolloxlua 目前支持javascript到lua的翻译。可以在openresty和luajit里使用。这个工具分为两种模式, 一种是web模式,可以通过网页使用。另外一种是tool模式, 通常作为大规模翻...

钟元OSS
昨天
2
0
Mybatis入门

简介: 定义:Mybatis是一个支持普通SQL查询、存储过程和高级映射的持久层框架。 途径:MyBatis通过XML文件或者注解的形式配置映射,实现数据库查询。 特性:动态SQL语句。 文件结构:Mybat...

霍淇滨
昨天
2
0
开发技术瓶颈期,如何突破

前言 读书、学习的那些事情,以前我也陆续叨叨了不少,但总觉得 “学习方法” 就是一个永远在路上的话题。个人的能力、经验积累与习惯方法不尽相同,而且一篇文章甚至一本书都很难将学习方法...

_小迷糊
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部