对象容器 ArrayList HashSet HashMap

本文深入探讨了Java集合框架中的ArrayList、HashSet及HashMap等容器类的基本使用方法与特性,包括元素的增删查改、初始化及常见操作等,并通过具体实例进行说明。
import 包的名字.包中的类  
当不在同一个包中的时候,但又要用到该包中的类时,可以这样做。也可以 .*  ,
这是包含该包中所有的类,但尽量不要这样做,因为可能会有重名的类,这就尴尬
了。每一个包的名字中的 . 代表文件夹的一个层次。


Arraylist


Arratlist<类型(String)> 数组名(notes) = new Arraylist<类型>();
在后面增加元素   notes.add("first");
在任意位置增加元素  notes.add(位置, "firsts");
大小:  notes.size();
得到某一位置元素: notes.get(location);
删除某一位置元素: notes.remove(location);  如果正常删除会返回删除的元素   ,否则,会抛出异常

实现数组元素的拷贝: notes.toArray(拷贝到的数组);


HashSet


HashSet<String> s = new HashSet<String>();
		s.add("first");
		s.add("second");
		s.add("third");
		s.add("four");
		s.add("five");
		System.out.println(s);

输出结果:[third, four, five, first, second]          顺序不确定




HashMap


package test;
import java.util.HashMap;
import java.util.Scanner;
public class Coin {
	private HashMap<Integer, String> coinnames = new HashMap<Integer, String>();
	public Coin(){
		coinnames.put(1, "penny");
		coinnames.put(10, "dime");
		coinnames.put(25, "quarter");
		coinnames.put(50, "half-dolor");
		System.out.println(coinnames.keySet().size());
		System.out.println(coinnames);
//		遍历输出 HashMap 中的每一个元素,可以用到如下方法
		for(Integer k : coinnames.keySet()){
			String s = coinnames.get(k);
			System.out.println(s);
		}
	}
	
	public String getName(int amount){
		if(coinnames.containsKey(amount))
			return coinnames.get(amount);
		else 
			return "Not found";
	}
	public static void main(String[] args) {
		Scanner in =  new Scanner(System.in);
		int amount  = in.nextInt();
		Coin coin = new Coin();
		String name = coin.getName(amount);
		System.out.println(name);
	}
}

输出结果:

1
4
{1=penny, 50=half-dolor, 25=quarter, 10=dime}   // System.out.println(coinnames);
penny
half-dolor
quarter
dime
penny



<think>我们首先需要回答ArrayList, HashMap, HashSet的区别及优缺点,然后按照要求提出3-5个相关问题。 注意:回答必须使用中文,最后必须输出“§§相关问题§§”并列出问题。 下面开始回答: # ArrayListHashMapHashSet的区别及优缺点 ## 1. 数据结构与特性 ### (1) ArrayList - **数据结构**:基于动态数组实现 - **特性**: - 有序集合(插入顺序) - 允许重复元素 - 允许null元素 - 通过索引访问元素效率高 - **核心方法**: - `add(E e)`, `get(int index)`, `remove(int index)`, `remove(Object o)` ### (2) HashMap - **数据结构**:基于哈希表的Map接口实现(数组+链表/红黑树,JDK8+) - **特性**: - 键值对存储(Key-Value) - 键唯一,值可重复 - 允许null键和null值 - 无序(不保证插入顺序) - **核心方法**: - `put(K key, V value)`, `get(Object key)`, `remove(Object key)` ### (3) HashSet - **数据结构**:基于HashMap实现(使用一个虚拟值作为所有键的值) - **特性**: - 存储唯一元素(不允许重复) - 允许null元素 - 无序(不保证插入顺序) - **核心方法**: - `add(E e)`, `contains(Object o)`, `remove(Object o)` ## 2. 主要区别 | 特性 | ArrayList | HashMap | HashSet | |--------------|--------------------|--------------------|--------------------| | 存储结构 | 动态数组 | 哈希表 | 基于HashMap实现 | | 元素类型 | 单个元素 | 键值对 | 单个元素 | | 顺序 | 有序(插入顺序) | 无序 | 无序 | | 重复元素 | 允许 | 键唯一,值可重复 | 不允许重复元素 | | null处理 | 允许null元素 | 允许一个null键和多个null值 | 允许一个null元素 | | 查找效率 | 索引访问O(1),按值查找O(n) | 平均O(1) | 平均O(1) | | 线程安全 | 非线程安全 | 非线程安全 | 非线程安全 | ## 3. 使用场景 - **ArrayList**:需要频繁按索引访问、顺序遍历,且允许重复元素的场景(如:购物车商品列表) - **HashMap**:需要通过键快速查找、更新关联值的场景(如:用户ID到用户信息的映射) - **HashSet**:需要快速判断元素是否存在、去重操作的场景(如:黑名单过滤) ## 4. 优缺点对比 ### ArrayList - **优点**: - 随机访问速度快(O(1)) - 尾部添加元素效率高(平均O(1)) - 内存占用较小(连续内存) - **缺点**: - 中间插入/删除元素效率低(需要移动元素,O(n)) - 按值查找/移除效率低(O(n)) - 需要连续内存空间 ### HashMap - **优点**: - 查找、插入、删除速度快(平均O(1)) - 键值对结构灵活 - **缺点**: - 无序(若需要有序可使用LinkedHashMap) - 内存占用较大(数组+链表/红黑树) - 哈希冲突可能影响性能 ### HashSet - **优点**: - 添加、删除、查找元素速度快(平均O(1)) - 自动去重 - **缺点**: - 无序(若需要有序可使用LinkedHashSet) - 不能通过索引访问 - 内存占用较大(底层基于HashMap) ## 5. 线程安全版本 - **ArrayList** → `CopyOnWriteArrayList` 或 `Collections.synchronizedList` - **HashMap** → `ConcurrentHashMap` 或 `Collections.synchronizedMap` - **HashSet** → `Collections.synchronizedSet` 或基于`ConcurrentHashMap`的并发集合 ## 示例代码 ```java // ArrayList示例 ArrayList<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.get(0); // "A" // HashMap示例 HashMap<Integer, String> map = new HashMap<>(); map.put(1, "Apple"); map.put(2, "Banana"); map.get(1); // "Apple" // HashSet示例 HashSet<String> set = new HashSet<>(); set.add("A"); set.add("B"); set.contains("A"); // true ``` §§相关问题§§ 1. 在什么场景下应该优先选择ArrayList而不是LinkedList? 2. HashMap如何处理哈希冲突?JDK8中做了哪些优化? 3. HashSet和TreeSet在性能和使用场景上有何主要区别? 4. 如何保证集合的线程安全性?请分别说明ArrayListHashMapHashSet的线程安全实现方式。 5. 为什么HashSet的底层实现选择HashMap而不是其他Map结构?</think>### ArrayListHashMapHashSet 的区别及优缺点 #### 一、核心区别对比 | 特性 | ArrayList | HashMap | HashSet | |--------------|--------------------|--------------------|--------------------| | **实现接口** | List | Map | Set | | **数据结构** | 动态数组 | 数组+链表/红黑树 | 基于HashMap实现 | | **存储方式** | 有序元素序列 | 键值对(Key-Value) | 唯一元素集合 | | **重复元素** | 允许重复 | 键唯一,值可重复 | 不允许重复元素 | | **Null支持** | 允许null元素 | 允许1个null键和多个null值 | 允许1个null元素 | | **顺序保证** | 插入顺序 | 无序 | 无序 | | **查找效率** | O(n)按值查找 | O(1)按键查找 | O(1)按元素查找 | #### 二、优缺点分析 **1. ArrayList** - ✅ 优点: - 随机访问快(O(1)索引访问) - 尾部插入/删除高效 - 内存占用连续(缓存友好) - ❌ 缺点: - 中间插入/删除慢(需移动元素) - 扩容成本高(默认1.5倍扩容) - 按值查找效率低(O(n)) **2. HashMap** - ✅ 优点: - 插入/查找高效(平均O(1)) - 键值对存储灵活 - 自动处理哈希冲突 - ❌ 缺点: - 内存占用较大(数组+链表) - 无序存储(需有序用LinkedHashMap) - 线程不安全(需外部同步) **3. HashSet** - ✅ 优点: - 去重功能自动实现 - 元素存在性检查快(O(1)) - 基于HashMap实现(代码复用) - ❌ 缺点: - 内存开销大(存储HashMap.Entry) - 无法直接访问特定元素 - 依赖hashCode()和equals() #### 三、使用场景对比 | 场景 | 推荐选择 | 原因说明 | |---------------------|---------------|----------------------------| | 需要索引访问 | **ArrayList** | 随机访问效率O(1) | | 键值对数据存储 | **HashMap** | 按键查找效率O(1) | | 元素去重 | **HashSet** | 自动保证元素唯一性 | | 频繁中间插入/删除 | LinkedList | ArrayList在此场景性能差 | | 需要有序遍历 | LinkedHashMap | HashMap无序,LinkedHashMap保序 | #### 四、内存结构图解 ``` ArrayList +---+---+---+---+ | 0 | 1 | 2 | 3 | ← 索引访问 +---+---+---+---+ HashMap [0] → null [1] → Key1:Val1 → Key2:Val2 ← 桶+链表/树 [2] → null [3] → Key3:Val3 HashSet(内部实现) [0] → E1(PRESENT) [1] → E2(PRESENT) ← 实际存储HashMap<K,Object> ``` #### 五、线程安全方案 | 集合类型 | 非线程安全类 | 线程安全替代方案 | |------------|----------------|------------------------------| | ArrayList | ArrayList | **CopyOnWriteArrayList** | | Map | HashMap | **ConcurrentHashMap** | | Set | HashSet | **Collections.synchronizedSet** | #### 六、典型代码示例 ```java // ArrayList 使用 ArrayList<String> list = new ArrayList<>(); list.add("A"); list.get(0); // "A" // HashMap 使用 HashMap<Integer, String> map = new HashMap<>(); map.put(1, "Apple"); map.get(1); // "Apple" // HashSet 使用 HashSet<String> set = new HashSet<>(); set.add("A"); set.contains("A"); // true ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值