JAVA基础:Collections 工具类实战指南-从排序到线程安全

在 Java 开发中,集合类几乎贯穿每一个项目,而Collections工具类提供了一系列强大的方法,用于操作和增强集合的功能。无论是排序、查找还是线程安全的封装,Collections工具类都是提升代码效率和质量的重要工具。

一、Collections 工具类概述

java.util.Collections是 Java 提供的一个工具类,主要用于操作集合类(如 List、Set 和 Map)。其核心方法包括:

1.排序操作:如sort()和reverseOrder()。

2.查找与填充:如binarySearch()和fill()。

3.其他操作:如shuffle()、swap()等。

4.线程安全包装:如synchronizedList()和synchronizedMap()。

5.不可变集合:如unmodifiableList()。

二、排序操作:让数据更有序

Collections.sort()是最常用的方法之一,可对 List 进行自然排序或自定义排序。

示例 1:自然排序

import java.util.*;public class CollectionsSortExample {public static void main(String[] args) {List<String> list = new ArrayList<>(Arrays.asList("banana", "apple", "cherry"));// 自然排序Collections.sort(list);System.out.println("自然排序后: " + list);  // 输出: [apple, banana, cherry]}
}

示例 2:自定义排序

Collections.sort(list, Comparator.reverseOrder());
System.out.println("降序排序后: " + list);  // 输出: [cherry, banana, apple]

实战场景:商品价格排序

假设有一个商品列表,需要按价格从低到高排序:

List<Product> products = Arrays.asList(new Product("Apple", 100),new Product("Banana", 60),new Product("Cherry", 120)
);Collections.sort(products, Comparator.comparingInt(Product::getPrice));
System.out.println("按价格排序后的商品: " + products);

三、查找与填充

1. Collections.binarySearch()

binarySearch()用于在排序后的列表中快速查找元素的位置。

import java.util.*;public class CollectionsBinarySearchExample {public static void main(String[] args) {List<Integer> list = Arrays.asList(1, 3, 5, 7, 9);// 必须先排序Collections.sort(list);int index = Collections.binarySearch(list, 5);System.out.println("元素 5 的索引位置: " + index);  // 输出: 2}
}

注意:

binarySearch()的前提是列表必须是有序的,否则结果不可预测。

2. Collections.fill()

fill()可将集合中的所有元素替换为指定值。

import java.util.*;
public class CollectionsFillExample {public static void main(String[] args) {List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));Collections.fill(list, "X");System.out.println("填充后的集合: " + list);  // 输出: [X, X, X]}
}

四、其他操作

1. Collections.shuffle()

shuffle()用于将集合中的元素随机排列,适合打乱顺序的场景,如洗牌程序或抽奖工具。

Collections.shuffle(list);
System.out.println("打乱顺序后的集合: " + list);

实战场景:洗牌功能实现

List<String> deck = new ArrayList<>(Arrays.asList("♥A", "♥2", "♥3", "♠A", "♠2", "♠3"
));
Collections.shuffle(deck);
System.out.println("洗牌后的结果: " + deck);

2. Collections.swap()

swap()方法可交换集合中两个元素的位置。

import java.util.*;public class SwapExample {public static void main(String[] args) {List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));Collections.swap(list, 0, 2);System.out.println("交换后的列表: " + list);  // 输出: [C, B, A]}
}

实战场景:数组中最小值和最大值交换

List<Integer> list = Arrays.asList(3, 5, 1, 9, 7);
int minIndex = list.indexOf(Collections.min(list));
int maxIndex = list.indexOf(Collections.max(list));
Collections.swap(list, minIndex, maxIndex);
System.out.println("交换后: " + list);  // 示例输出: [9, 5, 1, 3, 7]

五、线程安全包装

在多线程环境中,原生集合类如ArrayList并不是线程安全的,可以通过Collections.synchronizedXXX()方法生成线程安全的集合。

示例 1:线程安全的集合包装

import java.util.*;public class SynchronizedCollectionsExample {public static void main(String[] args) {List<String> list = new ArrayList<>();// 转换为线程安全的 ListList<String> synchronizedList = Collections.synchronizedList(list);synchronizedList.add("Thread-safe");System.out.println("线程安全的集合: " + synchronizedList);}
}

实战场景:多线程统计数据

List<Integer> scores = Collections.synchronizedList(new ArrayList<>());Runnable task = () -> {for (int i = 0; i < 1000; i++) {scores.add(i);}
};Thread t1 = new Thread(task);
Thread t2 = new Thread(task);t1.start();
t2.start();try {t1.join();t2.join();
} catch (InterruptedException e) {e.printStackTrace();
}System.out.println("线程安全的集合大小: " + scores.size());

六、不可变集合:安全共享数据

不可变集合是指在创建后无法修改的集合类型,适合在多线程环境下共享数据。

示例 1: 创建不可变集合

 unmodifiableList
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
List<String> unmodifiableList = Collections.unmodifiableList(list);// 尝试修改会抛出 UnsupportedOperationException
try {unmodifiableList.add("D");
} catch (UnsupportedOperationException e) {System.out.println("Cannot modify immutable list!");
}

实战场景:配置文件的共享

Map<String, String> config = new HashMap<>();
config.put("host", "localhost");
config.put("port", "8080");Map<String, String> unmodifiableConfig = Collections.unmodifiableMap(config);// 多个线程可以安全地读取配置
Runnable task = () -> {System.out.println("Host: " + unmodifiableConfig.get("host"));
};Thread t1 = new Thread(task);
Thread t2 = new Thread(task);t1.start();
t2.start();

七、性能优化建议

1.避免频繁排序

对于动态数据的排序,建议使用TreeSet或PriorityQueue。

2.选择合适的线程安全集合

在频繁读写场景中,优先考虑ConcurrentHash-Map或CopyOnWriteArrayList。

3.减少锁竞争

使用synchronizedList时,尽量避免在循环中频繁调用修改操作。

八、综合实战:线程安全排行榜

以下案例展示如何结合Collections工具类创建线程安全的排行榜:

import java.util.*;public class LeaderboardExample {public static void main(String[] args) {// 创建线程安全的排行榜(List)List<Integer> scores = Collections.synchronizedList(new ArrayList<>());// 添加分数scores.addAll(Arrays.asList(85, 90, 75, 95, 88));// 排序Collections.sort(scores, Collections.reverseOrder());System.out.println("排行榜: " + scores);  // 输出: [95, 90, 88, 85, 75]// 查找某个分数的排名int rank = Collections.binarySearch(scores, 90, Collections.reverseOrder());System.out.println("分数 90 的排名: 第 " + (rank + 1) + " 名");}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/79433.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ReLU函数及其Python实现

ReLU函数及其Python实现 文章目录 ReLU函数及其Python实现1. ReLU函数定义2. Python实现3. 在深度学习中的应用总结 1. ReLU函数定义 ReLU&#xff08;Rectified Linear Unit&#xff0c;修正线性单元&#xff09;函数是深度学习中常用的激活函数之一。它的定义非常简单&#…

2505ahk,wmi学习

检索每个服务的状态和启动类型 wbemServices : ComObjGet("winmgmts:\\.") //.代表本地计算机. wbemObjectSet : wbemServices.InstancesOf("Win32_Service")For wbemObject In wbemObjectSetMsgBox, % "Display Name: " wbemObject.DisplayNam…

大语言模型能力评定探讨

有标准答案的评估&#xff08;选择题&#xff09; 评估语言模型能力的基本思路是准备输入和标准答案&#xff0c;比较不同模型对相同输入的输出 由于AI答题有各种各样答案&#xff0c;因此现在是利用选择题考察。 有一个知名的选择题的基准叫做Massive Multitask Language Und…

数字智慧方案5874丨智慧交通收费稽核管理体系的构建与思考(44页PPT)(文末有下载方式)

资料解读&#xff1a;智慧交通收费稽核管理体系的构建与思考 详细资料请看本解读文章的最后内容。 随着高速公路收费系统的不断升级&#xff0c;特别是撤站后的新形势&#xff0c;收费稽核管理体系的构建显得尤为重要。本文将对辽宁省在联网收费新形势下的收费稽核管理体系进…

3.Java转义字符

Java转义字符 转义字符以\开头&#xff0c;常见的转义字符&#xff1a; 转义字符作用\t &#x1f31f;水平制表符&#xff08;Tab&#xff09;\r &#x1f31f;“回车&#xff08;Carriage Return&#xff09;”\n换行&#xff08;New Line&#xff09;\\输出一个反斜杠 \\&q…

【凑修电脑的小记录】vscode打不开

想把vscode的数据和环境从c盘移到d盘 大概操作和这篇里差不多 修改『Visual Studio Code&#xff08;VS Code&#xff09;』插件默认安装路径的方法 - 且行且思 - 博客园 在原地址保留了个指向新地址的链接文件。 重新安装vscode后双击 管理员身份运行均无法打开&#xff0…

MSP430G2553驱动0.96英寸OLED(硬件iic)

1.前言 最近需要用MSP430单片机做一个大作业,需要用到OLED模块&#xff0c;在这里记录一下 本篇文章主要讲解MSP430硬件iic的配置和OLED函数的调用&#xff0c;不会详细讲解OLED显示原理(其实就是江科大的OLED模块如何移植到msp430上).OLED显示原理以及底层函数讲解请参考其他…

SEO长尾词精准优化实战

内容概要 在搜索引擎优化领域&#xff0c;长尾关键词的精准挖掘与优化已成为突破流量瓶颈的核心策略。相较于通用词汇&#xff0c;长尾词具备更强的用户意图指向性与竞争分散特征&#xff0c;能够有效触达细分需求场景下的高价值受众。本部分将从长尾词的核心价值出发&#xf…

计算机组成原理实验(6) 微程序控制单元实验

实验六 微程序控制单元实验 一、实验目的 1、熟悉微程序控制器的原理 2、掌握微程序编制、写入并观察运行状态 二、实验要求 按照实验步骤完成实验项目&#xff0c;掌握设置微地址、微指令输出的方法 三、实验说明 3.1 微程序控制单元的构成&#xff1a;&#xff08;…

ECMAScript 2(ES2):标准化的微调与巩固

1. 版本背景与发布 发布时间&#xff1a;1998 年 6 月&#xff0c;由 ECMA International 正式发布&#xff0c;标准编号为 ECMA-262 Edition 2。核心定位&#xff1a;作为 ECMAScript 标准的第二次修订版&#xff0c;ES2 的核心目标是修正 ES1 中的错误、完善规范定义&#x…

基于蒙特卡洛模拟的电路容差分析与设计优化

蒙特卡洛模拟在电路设计中的应用 背景知识&#xff1a; 蒙特卡洛模拟是一种通过随机抽样来解决问题的数值方法。在电路设计中&#xff0c;它通过在元件参数的公差范围内随机生成大量样本值&#xff0c;模拟电路在不同参数组合下的行为&#xff0c;从而评估和优化电路设计&…

node.js 实战——mongoDB

MongoDB MongoDB 简介 MongoDB 是一种基于文档型 (document-oriented) 的 NoSQL 数据库&#xff0c;使用类 JSON 的 BSON 格式存储数据&#xff0c;自然支持复杂数据结构。它特别适合需要快速变化、大量数据处理和高应用扩展性的场景。 MongoDB 特性&#xff1a; 无法表、无…

如何掌握 Lustre/Scade 同步数据流语言

从 KPN 的萌芽开始&#xff0c;到 Lustre/Scade 的发展&#xff0c;再到 Velus/Zelus/Swan 在形式化编译、连续时间建模、MBD 平权等各方面的边界拓展&#xff0c;同步数据流语言已经历许多。现在&#xff0c;我们讨论如何掌握 Lustre/Scade 这类法式技术&#xff0c;从语言基础…

神州趣味地名-基于天地图和LeafLet的趣味地名探索

目录 前言 一、搜索API据介绍 1、官方API 2、Leaflet集成 二、成果介绍 1、令人忍俊不禁的地名 2、黑地名 3、数字地名 4、文艺地名 三、总结 前言 在华夏大地广袤的土地上&#xff0c;地名承载着深厚的历史文化底蕴&#xff0c;它们如同一颗颗璀璨的明珠&#xff0c;…

第6篇:EggJS数据库操作与ORM实践

在Web应用开发中&#xff0c;数据库操作是核心环节之一。EggJS通过集成Sequelize ORM框架&#xff0c;提供了高效、安全的数据库操作方案。本文将深入讲解如何在EggJS中配置MySQL数据库、定义数据模型、优化复杂查询&#xff0c;以及管理数据库迁移与种子数据。 一、MySQL基础配…

法线纹理采样+可视化Shader编辑器

法线贴图&#xff0c;对主纹理凹凸显示 建模原理 法线贴图&#xff1a;切线空间&#xff0c;存储xy切线&#xff0c;映射法线&#xff0c;法线信息存储在切线空间中。 模型是否凹凸&#xff0c;是由模型顶点决定的&#xff0c;现在实现的法线贴图&#xff0c;控制凹凸,实际上是…

OID是什么?

什么是 OID? OID 是 Object Identifier(对象标识符) 的缩写,是SNMP(Simple Network Management Protocol,简单网络管理协议)中用来唯一标识被管理对象(比如设备的某项信息)的一串数字。

STM32 ZIBEE DL-20 无线串口模块

一.配置方法 二.串口中断 u8 i; u16 buf[20],res; u8 receiving_flag 0; // 新增一个标志&#xff0c;用于标记是否开始接收数组 void USART1_IRQHandler(void) {if(USART_GetITStatus(USART1, USART_IT_RXNE) ! RESET) //接收中断{res USART_ReceiveData(USART1);if(receiv…

全感官交互革命:当 AI 大模型学会 “看、听、说、创”

引言&#xff1a;从 “文字对话” 到 “全感官体验”&#xff0c;AI 正在重塑人类认知边界 当 AI 不再局限于文本对话&#xff0c;而是能 “看懂” 图像、“听懂” 语音、“生成” 视频&#xff0c;并将这些模态无缝融合时&#xff0c;一场关于人机交互的革命已然开启。DeepSe…

C++模板知识

目录 引言 一、非类型模板参数 二、类模板的特化 &#xff08;一&#xff09;概念 &#xff08;二&#xff09;函数模板特化 &#xff08;三&#xff09;类模板特化 1. 全特化 2. 偏特化 &#xff08;四&#xff09;类模板特化应用示例 三、模板的分离编译 …