安卓SparseArray的indexOfValue方法遇到的坑
来源:互联网 发布:centos7下安装mysql 编辑:程序博客网 时间:2024/06/08 00:23
在数据量比较少的情况下使用SparseArray可以提高效率,最近一个项目利用它存储int型数据,利用indexOfValue去获取value的索引,本以为value大小范围可以是int的范围大小,结果不是,数据可以存储但是利用indexOfValue方法得到的索引就是不对返回-1检索不到,特别坑,当value范围是-128到127,indexOfValue才能得到正确的索引,查阅官方文档也没有找到原因,如果有大佬发现原因麻烦指出了,一起交流。解决这个问题可以用SparseIntArray代替,value的值是int的范围通过indexOfValue方法也能获得正确的索引。实验代码如下:
SparseArray<Integer> abc = new SparseArray<Integer>();int gpuIndex = 0;abc.put(gpuIndex++, 127);abc.put(gpuIndex++, 128);abc.put(gpuIndex++, -128); int a, a1, a2; a = a1 = a2 = Integer.MIN_VALUE; a = abc.indexOfValue(127); a1 = abc.indexOfValue(128); a2 = abc.indexOfValue(-128); Log.i("SparseArray", "SparseArrayIndex127: " + a); Log.i("SparseArray", "SparseArrayIndex128: " + a1); Log.i("SparseArray", "SparseArrayIndex-128: " + a2); SparseIntArray def = new SparseIntArray(); int index = 0; def.put(index++, 2147483647); int b = def.indexOfValue(2147483647); Log.i("SparseIntArray", "SparseIntArrayIndex: " + b);输出的log日志为:
07-20 16:53:45.611: I/SparseArray(13173): SparseArrayIndex127: 007-20 16:53:45.611: I/SparseArray(13173): SparseArrayIndex128: -107-20 16:53:45.611: I/SparseArray(13173): SparseArrayIndex-128: 207-20 16:53:45.611: I/SparseIntArray(13173): SparseIntArrayIndex: 0
如果大佬知道原因还希望指出来一起讨论!
------------------------------------------------------------------2017.8.9更新----------------------------------------------------------------------------------------------
查看java的int的自动装箱机制发现了问题的原因,是由于自动装箱机制和“==”比较引起的
首先看一下SparseArray的indexOfValue方法源码
/** * Returns an index for which {@link #valueAt} would return the * specified key, or a negative number if no keys map to the * specified value. * <p>Beware that this is a linear search, unlike lookups by key, * and that multiple keys can map to the same value and this will * find only one of them. * <p>Note also that unlike most collections' {@code indexOf} methods, * this method compares values using {@code ==} rather than {@code equals}. */ public int indexOfValue(E value) { if (mGarbage) { gc(); } for (int i = 0; i < mSize; i++) if (mValues[i] == value) return i; return -1; }注释已经提示了是利用“==”来进行比较,比较的是对象引用的地址,而传进来的类型E是是Integer的对象,我们知道在-128至127的数自动装箱时,获得的是同一个对象,而不在这个范围的自动装箱获得的是不同的对象,例子如下:
Integer num1 = 666; Integer num2 = 666; Integer num3 = 88; Integer num4 = 88;
System.out.println("num1==num2: "+(num1==num2));
System.out.println("num3==num4: "+(num3==num4));
输出结果:num1==num2: false num3==num4: true
所以indexOfValue(128)时,128自动装箱成Integer对象,利用“==”与原来put进去的128是不同的对象,所以检索不到,返回-1;
再看SparseIntArray的indexOfValue源码:
/** * Returns an index for which {@link #valueAt} would return the * specified key, or a negative number if no keys map to the * specified value. * Beware that this is a linear search, unlike lookups by key, * and that multiple keys can map to the same value and this will * find only one of them. */ public int indexOfValue(int value) { for (int i = 0; i < mSize; i++) if (mValues[i] == value) return i; return -1; }用的也是“==”,但是比较的类型是基本数据类型int,而不是Integer对象,所以能够检索到之前的数据。问题根源解决!
------------------------------------------------------------------------------------------------------------------------------------------------
后记:细节决定成败啊
- 安卓SparseArray的indexOfValue方法遇到的坑
- SparseArray中的indexOfValue与ArrayList中indexOf的区别
- 发布安卓版本遇到的坑。
- 安卓修改颜色遇到的坑
- 安卓打包时遇到方法过多的问题
- 安卓高效开发的SparseArray替代HashMap用法的个人总结
- 安卓开发中遇到的Intent的startActivityForResult方法回调后不执行onActivityResult方法
- 安卓游戏接入的时候遇到的找不到V4包的方法checkSelfPermission
- Android SparseArray的用法
- android的SparseArray
- sparseArray的应用原理
- SparseArray的用法
- 安卓开发遇到的坑(一)
- 安卓位置服务locationManager使用时候遇到的坑
- 安卓NDK开发中遇到的坑
- 安卓开发中遇到的一些坑
- ionic 部署安卓系统android遇到的坑
- 安卓编译环境遇到的问题
- Java开发中的23种设计模式详解
- java enum 枚举类型用例
- 浅析C++的结构体与容器
- sphinx/coreseek配置说明
- MySQL必知必会笔记(一)基础知识和基本操作
- 安卓SparseArray的indexOfValue方法遇到的坑
- 统计第一个只出现两次的字符
- 题目1451:不容易系列之一
- idea使用问题集合
- 腾讯2017秋招笔试编程题--geohash编码
- jquery选择器,dom操作
- spring-boot-starter-security
- 微信token验证失败Java解决办法
- 前端在线编程题5