集合
定义:提供一种存储空间可变的存储模型,存储的数据容量可以发生改变
其特点如下
集合类似于数组,它也是一个容器
集合不需要定义下标,它的容量是根据自己的底层数据结构来决定的
集合只能存储对象,而且类型不限
# 包装类
作用:将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据
常用的操作之一:用于基本数据类型与字符串之间的转换
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
# 案例 - 字符串数据排序
需求:有一个字符串:"91 27 46 38 50",请写程序实现最终输出结果是:"27 38 46 50 91"
public class IntegerTest {
public static void main(String[] args) {
// 定义一个字符串
String s = "91 27 46 38 50";
// 把字符串中的数字数据存储到一个 int 类型的数组中
String[] strArray = s.split(" ");
// for(int i=0; i<strArray.length; i++) {
// System.out.println(strArray[i]);
// }
// 定义一个 int 数组,把 String[] 数组中的每一个元素存储到 int 数组中
int[] arr = new int[strArray.length];
for (int i = 0; i < arr.length; i++) {
arr[i] = Integer.parseInt(strArray[i]);
}
// 对 int 数组进行排序
Arrays.sort(arr);
// 把排序后的 int 数组中的元素进行拼接得到一个字符串,这里拼接采用 StringBuilder 来实现
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
sb.append(arr[i]);
} else {
sb.append(arr[i]).append(" ");
}
}
String result = sb.toString();
// 输出结果
System.out.println(result);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 自动拆箱和自动装箱
自动装箱:把基本数据类型转换为对应的包装类类型
自动拆箱:把包装类类型转换为对应的基本数据类型
Integer i = 100; // 自动装箱
i += 200; // i = i + 200; i + 200 自动拆箱;i = i + 200; 是自动装箱
2
3
4
# List
特点:有序、元素可重复,该接口下常用的实现类
ArrayList
底层的数据结构是数组,当我们不知道使用什么类型的集合时,就使用这个
特点:查询速度快,因为数组中的所有元素都是有索引的,增删速度慢
LinkList
该实现类的底层数据结构是链表
特点:增删速度快,查询速度慢
Vectors
底层数据结构跟 ArrayList 一样
线程安全的,其他的跟 ArrayListy 一样
# ArrayList
ArrayList 类常用方法
方法名 | 说明 |
---|---|
public boolean remove(Object o) | 删除指定的元素,返回删除是否成功 |
public E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
public E set(int index,E element) | 修改指定索引处的元素,返回被修改的元素 |
public E get(int index) | 返回指定索引处的元素 |
public int size() | 返回集合中的元素的个数 |
public boolean add(E e) | 将指定的元素追加到此集合的末尾 |
public void add(int index,E element) | 在此集合中的指定位置插入指定的元素 |
# 案例
需求:针对目前我们的所学内容,完成一个综合案例:学生管理系统!该系统主要功能如下
添加学生:通过键盘录入学生信息,添加到集合中
删除学生:通过键盘录入要删除学生的学号,将该学生对象从集合中删除
修改学生:通过键盘录入要修改学生的学号,将该学生对象其他信息进行修改
查看学生:将集合中的学生对象信息进行展示
退出系统:结束程序
# Set
特点:无序、元素不可重复,该接口下的常用实现类
# 哈希值
定义:JDK 根据对象的地址或者字符串或者数字算出来的 int 类型的数值
Object 类中的 public int hashCode():返回对象的哈希码值
哈希值的特点
同一个对象多次调用 hashCode() 方法返回的哈希值是相同的
默认情况下,不同对象的哈希值是不同的。而重写 hashCode() 方法,可以实现让不同对象的哈希值相同
# HashSet
HashSet 集合的特点
底层数据结构是哈希表
对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致
没有带索引的方法,所以不能使用普通 for 循环遍历
由于是 Set 集合,所以是不包含重复元素的集合
基本使用
public class HashSetDemo01 {
public static void main(String[] args) {
// 创建集合对象
HashSet<String> hs = new HashSet<String>();
// 添加元素
hs.add("hello");
hs.add("world");
hs.add("java");
hs.add("world");
// 遍历
for (String s : hs) {
System.out.println(s);
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
HashSet 集合保证元素唯一性的图解
# LinkedHashSet
哈希表和链表实现的 Set 接口,具有可预测的迭代次序
由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
由哈希表保证元素唯一,也就是说没有重复的元素
基本使用
public class LinkedHashSetDemo {
public static void main(String[] args) {
// 创建集合对象
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>();
// 添加元素
linkedHashSet.add("hello");
linkedHashSet.add("world");
linkedHashSet.add("java");
linkedHashSet.add("world");
// 遍历集合
for (String s : linkedHashSet) {
System.out.println(s);
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# TreeSet
元素有序,可以按照一定的规则进行排序,具体排序方式取决于构造方法
TreeSet():根据其元素的自然排序进行排序
TreeSet(Comparator comparator) :根据指定的比较器进行排序
由于是 Set 集合,所以不包含重复元素的集合
基本使用
public class TreeSetDemo01 {
public static void main(String[] args) {
// 创建集合对象
TreeSet<Integer> ts = new TreeSet<Integer>();
// 添加元素
ts.add(10);
ts.add(40);
ts.add(30);
ts.add(50);
ts.add(20);
ts.add(30);
// 遍历集合
for (Integer i : ts) {
System.out.println(i);
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 比较器
在集合中存在两个比较器,其功能都可以用来实现集合中元素的排序
Comparable
实现了 Comparable 接口的类有一个特点,就是这些类是可以和自己比较的,至于具体和另一个实现了 Comparable 接口的类如何比较,则依赖 compareTo 方法的实现
Comparator
可以认为是是一个外比较器,有两种情况可以使用实现 Comparator 接口的方式
一个对象不支持自己和自己比较(没有实现 Comparable 接口),但是又想对两个对象进行比较
一个对象实现了 Comparable 接口,但是开发者认为 compareTo 方法中的比较方式并不是自己想要的那种比较方式
两者的不同点
comparator | comparable | |
---|---|---|
排序代码实现 | 在调用时实现 | 在需排序对象类中实现被称为自然排序 |
实现 | 实现 comparator 接口的 compare 方法 | 实现 comparator 接口的 compareTo 方法 |
所在包 | java.util | java.lang |
触发排序 | Collections.sort(list,new Comparator(){…}) | Collections.sort(list) |
# 案例
存储学生对象并遍历,创建 TreeSet 集合使用无参构造方法
要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
# Map
和 collection 接口同级,其特点如下
键值对映射关系
一个键对应一个值
键不能重复,值可以重复
元素存取无序
常用方法
方法名 | 说明 |
---|---|
V put(K key,V value) | 添加元素 |
V remove(Object key) | 根据键删除键值对元素 |
void clear() | 移除所有的键值对元素 |
boolean containsKey(Object key) | 判断集合是否包含指定的键 |
boolean containsValue(Object value) | 判断集合是否包含指定的值 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中键值对的个数 |
示例代码
public class MapDemo02 {
public static void main(String[] args) {
// 创建集合对象
Map<String, String> map = new HashMap<String, String>();
// V put(K key,V value):添加元素
map.put("张无忌","赵敏");
map.put("郭靖","黄蓉");
map.put("杨过","小龙女");
// V remove(Object key):根据键删除键值对元素
// System.out.println(map.remove("郭靖"));
// System.out.println(map.remove("郭襄"));
// void clear():移除所有的键值对元素
// map.clear();
// boolean containsKey(Object key):判断集合是否包含指定的键
// System.out.println(map.containsKey("郭靖"));
// System.out.println(map.containsKey("郭襄"));
// boolean isEmpty():判断集合是否为空
// System.out.println(map.isEmpty());
// int size():集合的长度,也就是集合中键值对的个数
System.out.println(map.size());
// 输出集合对象
System.out.println(map);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 案例
创建一个 HashMap 集合,键是学号 (String),值是学生对象 (Student)。存储三个键值对元素,并遍历
# Collections
该类是针对集合操作的工具类,常用 API 如下:
方法名 | 说明 |
---|---|
public static void sort(List list) | 将指定的列表按升序排序 |
public static void reverse(List<?> list) | 反转指定列表中元素的顺序 |
public static void shuffle(List<?> list) | 使用默认的随机源随机排列指定的列表 |
# 案例
ArrayList 存储学生对象,使用 Collections 对 ArrayList 进行排序
要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
public class CollectionsDemo02 {
public static void main(String[] args) {
// 创建 ArrayList 集合对象
ArrayList<Student> array = new ArrayList<Student>();
// 创建学生对象
Student s1 = new Student("linqingxia", 30);
Student s2 = new Student("zhangmanyu", 35);
Student s3 = new Student("wangzuxian", 33);
Student s4 = new Student("liuyan", 33);
// 把学生添加到集合
array.add(s1);
array.add(s2);
array.add(s3);
array.add(s4);
// 使用 Collections 对 ArrayList 集合排序
// sort•(List<T> list, Comparator<? super T> c)
Collections.sort(array, new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
// 按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
int num = s1.getAge() - s2.getAge();
int num2 = num == 0 ? s1.getName().compareTo(s2.getName())
: num;
return num2;
}
});
// 遍历集合
for (Student s : array) {
System.out.println(s.getName() + "," + s.getAge());
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35