List, Set and Map are all interfaces: they define how these respective types
work, but they don’t provide implementation code
overview
1. List(列表):
(1) 创建、访问和操作列表:ArrayList 和 LinkedList。
Creating, accessing, and manipulating a list (两种实现List接口的具体类)
(2) 在方法中使用列表,或作为类的实例变量使用。
Using lists in methods and as instance variables in a class.
2. Set 和 Map(集合与映射): 它们的特性 (Characteristics)及操作方法(operations),并用于解决实际问题。
一、Array Deficiencies
数组的局限性
静态大小:数组需要在声明时定义大小(size),无法动态扩展(grow arbitrarily)。
二、Java Collections Framework
Java 集合框架
集合框架(Collections Framework)是Java编程语言中一个库,它提供了一套接口和类,用于存储和操作对象集合。通过集合框架,程序员可以更方便地处理数据集合
提供更强大灵活的工具管理对象集合(object collections),包括:
List(列表):有序集合,允许重复元素。
Set(集合):无序集合,元素唯一。
Map(映射):键值对集合,用于快速查找。
三、 列表(List)
1. 特点
• 列表是一种有序集合(collection of objects),允许重复元素。
• 大小可以动态增减,无需提前定义大小。
grow or shrink dynamically to accommodate their contents
都是 List 接口的实现,提供相同的操作,但底层机制不同:
ArrayList:基于数组实现,适合频繁读取。 quick access and random reads.
LinkedList:基于链表实现,适合频繁插入和删除操作。frequent insertions and deletions.
2. Creating Lists
创建方式
泛型类型(Generic Type):
• 列表可以通过泛型 <Type> 来定义存储的数据类型。
泛型类型在尖括号 < > 中声明,确保类型安全。
List<String> list1 = new ArrayList<>();
List<String> list2 = new LinkedList<>();
如果左侧和右侧泛型类型相同,右侧的泛型声明可以省略。
List<String> list1 = new ArrayList<>();
List<String> list2 = new LinkedList<>();
将 ArrayList 替换为 LinkedList 不会导致代码出错。
List<String> list1 = new ArrayList<>();
// Later, replace it with:
List<String> list1 = new LinkedList<>();
3. List Operations
4. List 与 ArrayList
List 是接口(Interface):
• 定义了一组操作(specifies the operationsthat a List must provide),但不能直接通过 new 实例化。
• 需要通过实现该接口的具体类(如 ArrayList 或 LinkedList)来创建实例。
5. Object type / generic type parameter
Object 类型与泛型参数
(1) 泛型限制
• List 是为对象类型(object types)设计的,不能直接存储基本数据类型(primitive types)
primitive types (lowercase, abbreviated) has an
equivalent object type (capitalized, fully spelled out)
• 需要使用包装类(Wrapper Class)来替代基本数据类型:
• int → Integer
• double → Double
(2)自动装箱(Autoboxing)
• Java 会自动将基本类型转换为其对应的包装类。
List<Integer> list = new ArrayList<>();
list.add(10); // 自动将 int 类型的 10 转为 Integer
(3)自动拆箱(Unboxing)
• Java 会自动将包装类转换回基本类型。
int value = list.get(0); // 自动将 Integer 转为 int
(4)泛型的作用
• 确保类型安全,避免运行时类型转换错误。
• 泛型通过(angle brackets)尖括号 <> 定义类型。
6. ArrayList 与 LinkedList 比较
(1)ArrayList(动态数组)
• 底层基于动态数组,适合频繁访问元素。
• 插入和删除元素较慢(需要移动其他元素)。
(2) LinkedList(双向链表)
• 底层基于链表,适合频繁插入和删除操作。
• 访问元素较慢(需要从头开始遍历)。
7. Iterate through List
(1)enhanced for loops
• 用于遍历集合中的每个元素
for (int x : list) {
System.out.print(x + " ");
}
(2)Demo examples
• 找出列表中的最大值:
int max = Integer.MIN_VALUE;
for (int x : list) {
if (x > max) {
max = x;
}
}
System.out.println(max);
• 操作文件:
• 读取文件内容,并将结果存储到 List 中。
takes a file name and returns
a List of Student objects generated from the file!
the file contains names of the Student
public static List<Student> readFile(String fileName) {
File file = new File(fileName);\\创建了一个指向名为 fileName 的文件的 File 对象
List<Student> list = new ArrayList<>();
try {
Scanner input = new Scanner(file);
while (input.hasNextLine()) {
String name = input.nextLine();
Student student = new Student(name);
list.add(student);
}
input.close();
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
return list;
}
创建 File 对象
1. 封装文件的路径和引用,告诉程序要读取哪个文件。
2. 配合 Scanner 类读取文件内容,因为 Scanner 需要一个具体的文件对象。
• 存储对象:
• 使用 List 存储对象(如游戏中的角色、学生列表等)。
二、Set and Map
1. Characteristics and Operations of Set
(1) 特性:元素无序且唯一。
(2) 实现:HashSet 和 TreeSet。
• 操作包括:添加(add)、移除(remove)、联合(addAll)、交集(retainAll)和差集(removeAll)。
2. Iterate through Set
enhanced for loops/for each loop to iterate through a Set
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("B");
set.add("C");
set.add("A");
System.out.println(set);
for (String string : set) {
System.out.println(string);
}
}
3. Set Operations
(1)Creating set from list or other set, union, test containment, intersection:
如果直接对 set1 调用 retainAll,set1 中的元素会被修改成与 set3 的交集
addAll 将列表中的元素逐一添加到集合 set1:
• addAll 方法不会将整个列表作为单一对象添加,而是把列表中的每个元素(这里是 1 和 3)逐一添加到 set1 中。
addAll 方法不能直接传入数组,因为它期望的参数是一个实现了 Collection 接口的对象,而数组是 Java 的基本类型结构,不是 Collection 的子类。
Arrays.asList(1, 3);
Arrays.asList(new Integer[] {1, 3});• 当你写 Arrays.asList(1, 3) 时:
• Java 会自动把 1 和 3 作为变长参数处理,并创建一个数组。
• 然后,Arrays.asList() 会基于这个数组返回一个 List 对象。
new ArrayList<>() 本质是构造一个空列表,不能直接传元素。如果你需要直接初始化带有元素的列表,推荐使用 Arrays.asList()
List<Integer> list = new ArrayList<>();
list.add(1); // 手动添加元素
list.add(2);
System.out.println(list); // 输出: [1, 2]
List<Integer> list = new ArrayList<>(10); // 初始容量为10
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3)); // 初始化带有元素
System.out.println(list); // 输出: [1, 2, 3]
(2)Set difference and remove an element
2. Map 的特性和操作
Characteristics and Operations of Map
• 特性:以键值对(key-value pairs)形式存储,键唯一。
Map 的别名:
• 在其他编程语言中,Map 也称为字典 (dictionary) 或符号表 (symbol table)。
Map 的实现类型:
• TreeMap:基于红黑树实现,键按自然顺序或比较器排序。
• HashMap:基于哈希表实现,提供快速的插入和查找(无序)。
• LinkedHashMap:有序哈希表,保持插入顺序。
3. Map Operations
操作包括:添加映射(put)、获取值(get)、移除键值对(remove)、检查键或值(containsKey/containsValue)。
4. Map 应用:统计单词频率
Suppose we have a list of strings of multiple duplicate words, such as
["a", "b", "a", "c", "b", "word", "a", "word"]
We want to find out which words appear in the list and how many times each one
appears
import java.util.HashMap;
import java.util.Map;
public class NumWords {
public Map<String, Integer> wordCount(List<String> list) {
Map<String, Integer> map = new HashMap<>();
int num;
for (String word : list) {
if (!map.containsKey(word)) {
map.put(word, 1);
}
else {
num = map.get(word);
map.put(word, num + 1);
}
}
return map;
}
}
1. 遍历到 "a",map 不包含 "a",添加:{"a": 1}。
2. 遍历到 "b",map 不包含 "b",添加:{"a": 1, "b": 1}。
3. 遍历到第二个 "a",map 包含 "a",更新计数:{"a": 2, "b": 1}。
4. 遍历到 "c",map 不包含 "c",添加:{"a": 2, "b": 1, "c": 1}。
{"a": 3, "b": 2, "c": 1, "word": 2}