Android开发中常用高效数据结构

选择合适的数据结构不仅能够优化内存使用,还能提升应用的性能。例如,在处理大量数据时,使用SparseArray代替HashMap可以有效减少内存开销;而在需要频繁插入和删除操作的情况下,LinkedList则是更好的选择。

在Android开发中,性能优化是一个永恒的话题。无论是减少内存占用、提高应用响应速度,还是优化用户体验,选择合适的数据结构都是至关重要的一步。Android SDK和Java标准库中早已提供了许多隐藏款数据结构------它们专为特定场景设计,能显著减少内存开销、提升运行效率。

SparseArray

替代了传统的HashMap,避免了自动装箱带来的内存开销。适用于键为整数且数据量较小的场景。

复制

ini 复制代码
SparseArray<String> sparseArray = new SparseArray<>();
sparseArray.put(1, "One");
sparseArray.put(2, "Two");
String value = sparseArray.get(1); // 获取键为1的值1.2.3.4.

ArrayMap

相比HashMap,ArrayMap的内存占用更小,适合小规模数据。它同样适用于键值对数量较少的情况。

复制

ini 复制代码
ArrayMap<String, Integer> arrayMap = new ArrayMap<>();
arrayMap.put("One", 1);
arrayMap.put("Two", 2);
int value = arrayMap.get("One"); // 获取键为"One"的值1.2.3.4.

LongSparseArray

类似于SparseArray,但键为long类型。适用于键为长整数的场景。

复制

ini 复制代码
LongSparseArray<String> longSparseArray = new LongSparseArray<>();
longSparseArray.put(1L, "One");
longSparseArray.put(2L, "Two");
String value = longSparseArray.get(1L); // 获取键为1L的值1.2.3.4.

SparseXXXXArray

用于存储boolean、int、long等类型的值,避免了装箱操作,提高了性能。

复制

ini 复制代码
SparseBooleanArray sparseBooleanArray = new SparseBooleanArray();
sparseBooleanArray.put(1, true);
sparseBooleanArray.put(2, false);
boolean value = sparseBooleanArray.get(1); // 获取键为1的值

SparseIntArray sparseIntArray = new SparseIntArray();
sparseIntArray.put(1, 10);
sparseIntArray.put(2, 20);
int intValue = sparseIntArray.get(1); // 获取键为1的值

SparseLongArray sparseLongArray = new SparseLongArray();
sparseLongArray.put(1, 100L);
sparseLongArray.put(2, 200L);
long longValue = sparseLongArray.get(1); // 获取键为1的值1.2.3.4.5.6.7.8.9.10.11.12.13.14.

LinkedList

插入和删除操作效率高,但随机访问较慢。适用于频繁插入和删除的场景。

复制

csharp 复制代码
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("One");
linkedList.add("Two");
linkedList.addFirst("Zero"); // 在头部插入
linkedList.remove("One"); // 删除元素1.2.3.4.5.

HashSet

基于HashMap,存储唯一元素,查找速度快。适用于需要快速查找且元素唯一的场景。

复制

csharp 复制代码
HashSet<String> hashSet = new HashSet<>();
hashSet.add("One");
hashSet.add("Two");
hashSet.add("One"); // 重复元素不会被添加1.2.3.4.

TreeSet

基于TreeMap,元素有序,查找和插入的时间复杂度为O(log n)。适用于需要有序且唯一元素的场景。

复制

csharp 复制代码
TreeSet<String> treeSet = new TreeSet<>();
treeSet.add("One");
treeSet.add("Two");
treeSet.add("Three");1.2.3.4.

EnumSet

专为枚举类型设计,内存占用小,性能高。适用于存储枚举类型。

复制

css 复制代码
enum Color { RED, GREEN, BLUE }
EnumSet<Color> enumSet = EnumSet.of(Color.RED, Color.GREEN);1.2.

Circular Buffer(环形缓冲区)

固定大小,循环覆盖旧数据,适合流式数据。适用于需要固定大小缓冲区的场景。

复制

ini 复制代码
ArrayDeque<Integer> circularBuffer = new ArrayDeque<>(5);
circularBuffer.add(1);
circularBuffer.add(2);
circularBuffer.add(3);
circularBuffer.add(4);
circularBuffer.add(5);
circularBuffer.add(6); // 6进入,1被移除1.2.3.4.5.6.7.

LruCache

基于LRU算法,自动移除最近最少使用的数据。适用于缓存数据。

复制

ini 复制代码
import android.util.LruCache;

LruCache<String, Bitmap> lruCache = new LruCache<>(1024 * 1024 * 5); // 5MB缓存
lruCache.put("key1", bitmap1);
lruCache.put("key2", bitmap2);
Bitmap bitmap = lruCache.get("key1"); // 获取键为"key1"的值1.2.3.4.5.6.

ConcurrentHashMap

线程安全,适合高并发场景。适用于多线程环境下的键值对存储。

复制

ini 复制代码
import java.util.concurrent.ConcurrentHashMap;

ConcurrentHashMap<String, Integer> concurrentHashMap = new ConcurrentHashMap<>();
concurrentHashMap.put("One", 1);
concurrentHashMap.put("Two", 2);
int value = concurrentHashMap.get("One"); // 获取键为"One"的值1.2.3.4.5.6.

CopyOnWriteArrayList

线程安全,写操作时复制整个列表。适用于读多写少的并发场景。

复制

csharp 复制代码
import java.util.concurrent.CopyOnWriteArrayList;

CopyOnWriteArrayList<String> copyOnWriteArrayList = new CopyOnWriteArrayList<>();
copyOnWriteArrayList.add("One");
copyOnWriteArrayList.add("Two");
copyOnWriteArrayList.add("Three");1.2.3.4.5.6.

PriorityQueue

基于优先级堆,元素按优先级排序。适用于需要优先级排序的场景。

复制

ini 复制代码
import java.util.PriorityQueue;

PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
priorityQueue.add(3);
priorityQueue.add(1);
priorityQueue.add(2);
int top = priorityQueue.poll(); // 获取并移除优先级最高的元素1.2.3.4.5.6.7.

WeakHashMap

键为弱引用,适合缓存。避免内存泄漏,适用于缓存数据。

复制

ini 复制代码
import java.util.WeakHashMap;

WeakHashMap<String, Bitmap> weakHashMap = new WeakHashMap<>();
weakHashMap.put("key1", bitmap1);
weakHashMap.put("key2", bitmap2);
Bitmap bitmap = weakHashMap.get("key1"); // 获取键为"key1"的值1.2.3.4.5.6.

LinkedHashMap

保持插入顺序或访问顺序。适用于需要有序键值对的场景。

复制

ini 复制代码
import java.util.LinkedHashMap;

LinkedHashMap<String, Integer> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("One", 1);
linkedHashMap.put("Two", 2);
linkedHashMap.put("Three", 3);1.2.3.4.5.6.

ArrayDeque

双端队列,高效插入和删除。适用于需要双端操作的场景。

复制

java 复制代码
import java.util.ArrayDeque;

ArrayDeque<String> arrayDeque = new ArrayDeque<>();
arrayDeque.add("One");
arrayDeque.add("Two");
arrayDeque.addFirst("Zero"); // 在头部插入
arrayDeque.removeLast(); // 删除尾部元素1.2.3.4.5.6.7.

BitSet

高效存储布尔值,节省内存。适用于需要存储大量布尔值的场景。

复制

ini 复制代码
import java.util.BitSet;

BitSet bitSet = new BitSet(10);
bitSet.set(1);
bitSet.set(2);
boolean value = bitSet.get(1); // 获取索引为1的值1.2.3.4.5.6.

Atomic Classes

线程安全,适合高并发场景。适用于多线程环境下的原子操作。

复制

java 复制代码
import java.util.concurrent.atomic.AtomicInteger;

AtomicInteger atomicInteger = new AtomicInteger(0);
atomicInteger.incrementAndGet(); // 原子性增加1.2.3.4.

Collections.unmodifiableXXXX

创建不可变集合,防止意外修改。适用于需要不可变集合的场景。

复制

ini 复制代码
import java.util.Collections;
import java.util.ArrayList;

ArrayList<String> list = new ArrayList<>();
list.add("One");
list.add("Two");
List<String> unmodifiableList = Collections.unmodifiableList(list);1.2.3.4.5.6.7.

实际应用场景

  • 缓存机制:使用LruCache可以有效地管理缓存,自动移除最近最少使用的数据,确保缓存不会占用过多内存。
  • 多线程环境:在多线程环境中,ConcurrentHashMap和CopyOnWriteArrayList提供了线程安全的解决方案,避免了锁的竞争。
  • 布尔值存储:如果需要存储大量的布尔值,BitSet是一个非常好的选择,它能够大大节省内存空间。

选择合适的数据结构不仅能够优化内存使用,还能提升应用的性能。例如,在处理大量数据时,使用SparseArray代替HashMap可以有效减少内存开销;而在需要频繁插入和删除操作的情况下,LinkedList则是更好的选择。

行业拓展

分享一个面向研发人群使用的前后端分离的低代码软件------JNPF

基于 Java Boot/.Net Core双引擎,它适配国产化,支持主流数据库和操作系统,提供五十几种高频预制组件,内置了常用的后台管理系统使用场景和实用模版,通过简单的拖拉拽操作,开发者能够高效完成软件开发,提高开发效率,减少代码编写工作。

JNPF基于SpringBoot+Vue.js,提供了一个适合所有水平用户的低代码学习平台,无论是有经验的开发者还是编程新手,都可以在这里找到适合自己的学习路径。

此外,JNPF支持全源码交付,完全支持根据公司、项目需求、业务需求进行二次改造开发或内网部署,具备多角色门户、登录认证、组织管理、角色授权、表单设计、流程设计、页面配置、报表设计、门户配置、代码生成工具等开箱即用的在线服务。

相关推荐
三小河1 分钟前
Agent Skill与Rules的区别——以Cursor为例
前端·javascript·后端
Hilaku8 分钟前
不要在简历上写精通 Vue3?来自面试官的真实劝退
前端·javascript·vue.js
三小河15 分钟前
前端视角详解 Agent Skill
前端·javascript·后端
牛奔23 分钟前
Go 是如何做抢占式调度的?
开发语言·后端·golang
Aniugel28 分钟前
单点登录(SSO)系统
前端
颜酱28 分钟前
二叉树遍历思维实战
javascript·后端·算法
鹏多多31 分钟前
移动端H5项目,还需要react-fastclick解决300ms点击延迟吗?
前端·javascript·react.js
serioyaoyao32 分钟前
上万级文件一起可视化,怎么办?答案是基于 ParaView 的远程可视化
前端
万少38 分钟前
端云一体 一天开发的元服务-奇趣故事匣经验分享
前端·ai编程·harmonyos
WindrunnerMax40 分钟前
从零实现富文本编辑器#11-Immutable状态维护与增量渲染
前端·架构·前端框架