集合和数组比较
- 相似点: 都可以存储多个对象,对外作为一个整体存在
- 数组缺点:
- 长度必须在初始化时指定,且固定不变
- 数组采用连续存储空间,删除和添加效率低下
- 数组无法直接保存映射关系
- 数组缺乏封装,操作繁琐
集合架构
下面的“唯一”可理解为“不重复”,“不唯一”即为“可重复”
- Collection:接口存储一组不唯一,无序的对象
- List:接口存储一组不唯一,有序(索引顺序)的对象【即可以有重复元素,有序】
- Set:接口存储一组唯一,无序的对象【即没有重复元素,无序,类似于数学中的集合】
- Map接口存储一组键值对象,提供key到value的映射:
- key:唯一、无序
- value:不唯一,无序
List集合
- List集合的主要实现类有ArrayList和LinkedList,分别是数据结构中顺序表和链表的实现。另外还包括栈和队列的实现类:Deque和Queue
- ArrayList:
- 在内存中分配连续的空间,实现了长度可变的数组
- 优点:(顺序表的优点)遍历元素和随机访问元素的效率比较高
- 缺点:添加和删除需大量移动元素效率低,按照内容查询效率低
- LinkedList:
- 采用双向链表存储方式
- 缺点:遍历和随机访问元素效率低下
- 优点:(链表的优点)插入、删除元素效率比较高(但是前提也是必须先低效率查询才可,如果插入删除发生在头尾可以减少查询次数)
ArrayList
-
ArrayList底层是一个长度可以动态增长的Object数组,每次默认增长50%(即每次变为原来的1.5倍)
-
ArrayList中提供了一个内部类Itr(可直接访问外部类中的元素),实现了Iterator接口,实现对集合元素的遍历
-
使用案例1:
package com.bjsxt.list;
import java.util.ArrayList;
import java.util.Iterator;
/**
* 数组中既可以放基本数据类型,也可以放引用数据类型,比如int[] arr, Computer[] arr2
* 集合中只能放引用数据类型,不能放基本数据类型(基本数据类型需要使用包装类来包装,然后再放入集合)
*/
public class TestArrayList01 {
public static void main(String[] args) {
// 创建一个集合对象
ArrayList<Integer> arrayList = new ArrayList<>();
// 添加元素
arrayList.add(80); // 自动装箱 int--->Integer
arrayList.add(90);
arrayList.add(80); // 向末尾添加元素
arrayList.add(1, 100); // 向指定索引添加元素
// 添加元素底层发生了大量数据后移操作,并且可能发生数组的扩容
// 元素的数量
System.out.println("------元素的数量------");
System.out.println(arrayList.size());
System.out.println("--------------------");
// 获取指定索引的元素
int elem = arrayList.get(1);
System.out.println("------索引为1的元素为------" + elem);
// 遍历元素
System.out.println(arrayList);
System.out.println("遍历方法一:for循环");
for (int i = 0; i < arrayList.size(); i++) {
System.out.println(arrayList.get(i));
}
System.out.println("遍历方法二:for-each循环");
for (Integer element : arrayList) {
System.out.println(element);
}
System.out.println("遍历方法三:Iterator");
Iterator<Integer> it = arrayList.iterator();
while (it.hasNext()) { // 是否还有元素
System.out.println(it.next());
}
System.out.println("遍历方式四:Lambda表达式+流式编程");
arrayList.forEach(System.out::println);
}
}
运行结果
- 使用案例2:
package com.bjsxt.list;
import java.util.ArrayList;
public class TestArrayList02 {
public static void main(String[] args) {
ArrayList<Integer> arrayList1 = new ArrayList<>();
arrayList1.add(10);
arrayList1.add(20);
arrayList1.add(30);
ArrayList<Integer> arrayList2 = new ArrayList<>();
arrayList2.add(30);
arrayList2.add(40);
arrayList2.add(50);
arrayList2.add(60);
System.out.println(arrayList1);
System.out.println(arrayList2);
System.out.println("------两个集合addAll------");
// 将两个集合中的元素添加到一个集合中
arrayList1.addAll(arrayList2);
System.out.println(arrayList1);
System.out.println("------两个集合removeAll------");
System.out.println(arrayList1);
System.out.println(arrayList2);
System.out.println(arrayList1.removeAll(arrayList2));
// 删除两个集合共有的元素
System.out.println(arrayList1);
System.out.println("------两个集合retainAll------");
arrayList1.add(30);
System.out.println(arrayList1);
System.out.println(arrayList2);
// 保留两个集合中相同的元素
System.out.println(arrayList1.retainAll(arrayList2));
System.out.println(arrayList1);
System.out.println(arrayList2);
// 判断集合中是否包含某元素
System.out.println("------contains------");
System.out.println(arrayList2.contains(50));
// 获取某元素对应的索引
System.out.println("------indexOf------");
System.out.println(arrayList2.indexOf(60));
System.out.println("------isEmpty() & clear()------");
// 判断集合是否为空
System.out.println(arrayList1.isEmpty());
// 移除集合中所有元素
arrayList1.clear();
System.out.println(arrayList1.isEmpty());
}
}
运行结果
LinkedList
- 代码示例
package com.bjsxt.list2;
import java.util.LinkedList;
/**
* 将ArrayList替换为LinkedList之后,执行结果没有变,底层的数据结构发生了变化:数组--->双向链表
* 具体的操作方式变化了 list.remove(2);
* <p>
* LinkedList提供了更多的方法,可以作为线性表、栈、队列来使用
* <p>
* 使用场景:
* ArrayList: 按照索引随机访问,遍历集合
* LinkedList: 添加、删除操作多
*/
public class TestLinkedList01 {
public static void main(String[] args) {
LinkedList<Integer> list = new LinkedList<>();
list.add(80);
list.add(70);
list.add(90);
list.add(0, 100);
System.out.println(list.size());
System.out.println(list.isEmpty());
System.out.println(list.indexOf(70));
System.out.println(list.indexOf(70));
System.out.println(list.contains(80));
int elem = list.get(2);
System.out.println(elem);
}
}