List集合的进一步学习:性能优化

embedded/2024/11/30 3:34:25/

================================

||        持续分享系列教程,关注一下不迷路     ||

||                B站视频教程:墨轩大楼               ||

||                知识星球:墨轩编程自习室           ||

================================

        在Java集合框架中,选择合适的集合类型和使用正确的操作方法可以显著提高程序的性能。以下是一些常见的性能优化技巧,并附有详细的代码示例。

1. 选择合适的集合类型

根据具体的需求选择合适的集合类型是性能优化的第一步。例如:

  • 随机访问:如果需要频繁进行随机访问操作,应选择ArrayList
  • 频繁插入/删除:如果需要频繁进行插入和删除操作,应选择LinkedList
  • 线程安全:如果需要在多线程环境下使用,可以考虑Vector或使用Collections.synchronizedList包装ArrayList
2. 批量操作

批量操作通常比单个操作更高效。例如,使用addAll方法一次添加多个元素比多次调用add方法更高效。

示例代码
import java.util.ArrayList;
import java.util.List;public class BatchOperationExample {public static void main(String[] args) {List<String> list = new ArrayList<>();// 单个添加操作long startTime = System.nanoTime();for (int i = 0; i < 1000000; i++) {list.add("Element" + i);}long endTime = System.nanoTime();System.out.println("Single add operations: " + (endTime - startTime) + " ns");// 清空列表list.clear();// 批量添加操作List<String> elements = new ArrayList<>();for (int i = 0; i < 1000000; i++) {elements.add("Element" + i);}startTime = System.nanoTime();list.addAll(elements);endTime = System.nanoTime();System.out.println("Batch add operations: " + (endTime - startTime) + " ns");}
}
3. 避免不必要的扩容

ArrayListVector在内部使用数组来存储元素。当数组容量不足时,会创建一个新的更大的数组,并将旧数组中的元素复制到新数组中。这个过程可能会导致性能下降。可以通过预分配足够的初始容量来避免这种情况。

示例代码
import java.util.ArrayList;
import java.util.List;public class InitialCapacityExample {public static void main(String[] args) {// 默认初始容量List<String> list1 = new ArrayList<>();long startTime = System.nanoTime();for (int i = 0; i < 1000000; i++) {list1.add("Element" + i);}long endTime = System.nanoTime();System.out.println("Default initial capacity: " + (endTime - startTime) + " ns");// 预分配初始容量List<String> list2 = new ArrayList<>(1000000);startTime = System.nanoTime();for (int i = 0; i < 1000000; i++) {list2.add("Element" + i);}endTime = System.nanoTime();System.out.println("Pre-allocated initial capacity: " + (endTime - startTime) + " ns");}
}
4. 使用迭代器进行批量删除

在遍历集合并删除元素时,使用迭代器比直接调用remove方法更高效。直接调用remove方法会导致集合重新计算索引,而使用迭代器则不会。

示例代码
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class IteratorRemoveExample {public static void main(String[] args) {List<Integer> list = new ArrayList<>();for (int i = 0; i < 1000000; i++) {list.add(i);}// 使用迭代器删除long startTime = System.nanoTime();Iterator<Integer> iterator = list.iterator();while (iterator.hasNext()) {if (iterator.next() % 2 == 0) {iterator.remove();}}long endTime = System.nanoTime();System.out.println("Using iterator remove: " + (endTime - startTime) + " ns");// 重置列表list.clear();for (int i = 0; i < 1000000; i++) {list.add(i);}// 直接调用remove方法startTime = System.nanoTime();for (int i = 0; i < list.size(); i++) {if (list.get(i) % 2 == 0) {list.remove(i--); // 注意索引调整}}endTime = System.nanoTime();System.out.println("Direct remove: " + (endTime - startTime) + " ns");}
}
5. 减少同步开销

在多线程环境下,尽量减少同步开销。例如,使用CopyOnWriteArrayList代替VectorCollections.synchronizedList包装的ArrayList

示例代码
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;public class SynchronizationExample {private static final int NUM_THREADS = 10;private static final int NUM_OPERATIONS = 10000;public static void main(String[] args) throws InterruptedException {testSynchronization(new ArrayList<>(), "ArrayList with Collections.synchronizedList");testSynchronization(new CopyOnWriteArrayList<>(), "CopyOnWriteArrayList");}private static void testSynchronization(List<Integer> list, String name) throws InterruptedException {if (list instanceof ArrayList) {list = Collections.synchronizedList(list);}ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);long startTime = System.nanoTime();for (int i = 0; i < NUM_THREADS; i++) {executor.submit(() -> {for (int j = 0; j < NUM_OPERATIONS; j++) {list.add(j);}});}executor.shutdown();executor.awaitTermination(1, TimeUnit.MINUTES);long endTime = System.nanoTime();System.out.println(name + ": " + (endTime - startTime) + " ns");}
}
6. 使用缓存

对于频繁访问的数据,可以考虑使用缓存来提高性能。例如,使用ConcurrentHashMap来存储和检索数据。

示例代码
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;public class CacheExample {private static final ConcurrentMap<Integer, String> cache = new ConcurrentHashMap<>();public static void main(String[] args) {// 初始化缓存for (int i = 0; i < 1000000; i++) {cache.put(i, "Value" + i);}// 从缓存中获取数据long startTime = System.nanoTime();for (int i = 0; i < 1000000; i++) {String value = cache.get(i);}long endTime = System.nanoTime();System.out.println("Cache lookup: " + (endTime - startTime) + " ns");}
}

总结

通过选择合适的集合类型、批量操作、预分配初始容量、使用迭代器进行批量删除、减少同步开销以及使用缓存等方法,可以显著提高Java集合框架的性能。希望这些示例代码能够帮助您更好地理解和应用这些性能优化技巧。如果您有任何问题或需要进一步的帮助,请随时提问。


http://www.ppmy.cn/embedded/141640.html

相关文章

迅为rk3568开发板定制扩展分区SDK源码编译-编译 Ubuntu-全自动编译图形化界面

首先在 linux 源码目录下输入以下命令进入编译的 UI 界面&#xff0c;进入之后如下所示&#xff1a; ./build.sh 然后选择第四个 all&#xff0c;就会进入到文件系统类型选择页面&#xff0c;如下所示&#xff1a; 由于本小节全自动编译的是 ubuntu 系统&#xff0c;所以这…

【es6】原生js在页面上画矩形层级等问题的优化(二)

接上篇的业务&#xff0c;实现了基础的画图&#xff0c;选中与拖动的效果&#xff0c;还有点细节问题&#xff0c;多个元素重叠在一起&#xff0c;选中的不能在最上面显示&#xff0c;以及最后绘制的元素要能覆盖前面绘制的&#xff0c; 优化如下 优化后效果 在后面绘制的矩形…

Vue源码巧妙设计

Vue.js的源码中蕴含了许多巧妙的设计&#xff0c;这些设计使得Vue成为一个高效、灵活且易于使用的前端框架。以下是对Vue源码中一些巧妙设计的详细讲解&#xff1a; 1. 响应式系统 Vue的响应式系统是其核心特性之一&#xff0c;它允许Vue追踪数据的变化&#xff0c;并在数据变…

(STM32)ADC驱动配置

1.ADC驱动&#xff08;STM32&#xff09; ADC模块中&#xff0c;**常规模式&#xff08;Regular Mode&#xff09;和注入模式&#xff08;Injected Mode&#xff09;**是两种不同的ADC工作模式 常规模式&#xff1a;用于普通的ADC转换&#xff0c;是默认的ADC工作模式。 注入…

windows C#-迭代器(下)

对泛型列表使用迭代器 在以下示例中&#xff0c;Stack<T> 泛型类实现 IEnumerable<T> 泛型接口。 Push 方法将值分配给类型为 T 的数组。 GetEnumerator 方法通过使用 yield return 语句返回数组值。 除了泛型 GetEnumerator 方法&#xff0c;还必须实现非泛型 G…

std库锁机制的使用

在多线程编程中,关键资源的读写访问是程序员需要非常重视的部分。而控制好读写主要靠的就是锁机制,在各个编程框架中都提供了锁的实现机制。这一篇就简单列举一下std标准库中提供的一些锁机制。 锁是干什么用的 这里稍微啰嗦一句,用通俗的话解释一下锁是干什么用的。其实我…

2024年第十三届”认证杯“数学中国数学建模国际赛(小美赛)

↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓

【JavaEE初阶 — 网络编程】TCP流套接字编程

TCP流套接字编程 1. TCP &#xff06; UDP 的区别 TCP 的核心特点是面向字节流&#xff0c;读写数据的基本单位是字节 byte 2 API介绍 2.1 ServerSocket 定义 ServerSocket 是创建 TCP 服务端 Socket 的API。 构造方法 方法签名 方法说明 ServerS…