选择合适的数据结构不仅能够优化内存使用,还能提升应用的性能。例如,在处理大量数据时,使用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支持全源码交付,完全支持根据公司、项目需求、业务需求进行二次改造开发或内网部署,具备多角色门户、登录认证、组织管理、角色授权、表单设计、流程设计、页面配置、报表设计、门户配置、代码生成工具等开箱即用的在线服务。