JAVA学习-07-韩顺平老师
JAVA-集合Collection之List篇
目录:
01-为什么要使用集合?
02-Collection接口
03-List接口
为什么要使用集合?
原因: 之前保存多个数据使用的都是数组,但是数组存在很多的缺陷,所以出现了集合。
数组的缺陷:
1.长度定义时必须只当,而且一旦指定,就不能更改。
2.保存的数据必须是同一数据类型。
3.使用数组增加元素非常的麻烦。
集合的优点:
1)可以动态保存任意多个对象,使用比较方便。
2)提供了一系列的方便操作对象的方法:add、remove、set、get。
3)使用集合添加和删除操作更加简单。
Collection接口
Collection接口特点: public interface Collection extends Iterable
1.Collection实现的子类可以存放多个元素,每个元素的类型都是Object
2.有些Collection的实现类,可以存放重复元素,有些不可以。
3.有些Collection的实现类,有些是有序的(List),有些不是有序的(Set)。
4..Collection接口没有直接实现的子类,是通过它的子接口Set和List实现的。
Collection结构体系图:
Collection接口常用方法: 使用ArrayList演示
1)add : 添加单个元素
2)remove : 删除指定元素
3)contains : 查找元素是否存在
4)size : 获取元素个数
5)isEmpty : 判断是否为空
6)clear : 清空
7)addAll : 添加多个元素
8)contains : 查询多个元素是否存在
9)removeAll : 删除多个元素
演示代码:
import java.util.ArrayList;
import java.util.List;
@SuppressWarnings({"all"})
public class Collction_ {
public static void main(String[] args) {
List list = new ArrayList();
// add
list.add("10"); // 在添加的时候,会对这个元素先进行装箱
list.add("100");
list.add("1000");
System.out.println(list); // [10,100,1000]
// remove
list.remove("10");
System.out.println(list);// [100, 1000]
// contains
System.out.println(list.contains("100")); // true
// size
System.out.println(list.size()); // 2
// isEmpty
System.out.println(list.isEmpty()); // false
// clear
list.clear();
System.out.println(list); // []
// addAll
ArrayList list2 = new ArrayList(); // 新建一个集合
list2.add("水浒传");
list2.add("西游记");
list.addAll(list2);
System.out.println(list); // [水浒传, 西游记]
// containsAll
System.out.println(list.containsAll(list2)); // true
// removeAll()
list.removeAll(list2);
System.out.println(list); // []
}
}
集合遍历:
1.使用迭代器(Iterator)遍历
public class traverse {
public static void main(String[] args) {
List list = new ArrayList();
list.add("10");
list.add("100");
list.add("1000");
Iterator iterator = list.iterator();
while (true){
// 注意在进行输出next之前,必须要判断next是否存在
if(!iterator.hasNext()){
break;
}
Object obj = iterator.next();
System.out.print(obj + "\t"); // 10 100 1000
}
// 如果需要再次遍历,必须重置迭代器
iterator = list.iterator();
}
}
2.使用for循环增强遍历
public class traverse {
public static void main(String[] args) {
List list = new ArrayList();
list.add("10");
list.add("100");
list.add("1000");
for (Object obj : list) {
System.out.print(obj + "\t"); // 10 100 1000
}
}
}
3.使用普通的for循环遍历
public class traverse {
public static void main(String[] args) {
List list = new ArrayList();
list.add("10");
list.add("100");
list.add("1000");
for (int i = 0; i < list.size(); i++) {
Object obj = list.get(i);
System.out.print(obj + "\t"); // 10 100 1000
}
}
}
List接口
基本概念:
List接口是Collection接口的子接口
1) List集合类种的元素有序(即添加顺序和取出顺序一致)、且可重复。
2)List集合的每个元素都有其对应的顺序索引,即支持索引。
3) List接口实现了很多类,只分析常用的三个 LinkedList、ArrayList,Vector。
常用方法:
1.实现了Collection 的方法,Collection可以使用的方法。
List集合类都可以使用。
2.List集合类中添加了一些根据索引来操作元素的方法。
1) add(int index, Object ele) :在index位置插入元素。
2) get(int index) :获取 index 位置的元素。
3) set(int index, Object ele):替换index位置元素为ele。
4) indexof(Object ele) : 返回 ele 首次出现的位置。
5) lastIndexOf(Object ele) : 返回 ele 最后一次出现的位置。
6) subList(int fromIndex, int toIndex): 返回fromIndex-toIndex的子集合。
演示代码:
public class ListExercise {
public static void main(String[] args) {
List list = new ArrayList();
for (int i = 0; i < 12; i++) {
list.add(i);
}
System.out.println(list);
// 在第二个位置插入 ”小明“
list.add(1,"小明"); // 传入索引,从0开始
System.out.println(list); // [0, 小明, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
// 获得第5个元素
System.out.println(list.get(5)); // 3
// 删除第6个元素
list.remove(6);
System.out.println(list); // [0, 小明, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11]
// 修改第七个元素
list.set(6,"小红");
System.out.println(list); // [0, 小明, 1, 2, 3, 4, 小红, 7, 8, 9, 10, 11]
}
}
ArrayList、Vector: 是实现了接口List的两个类。
ArrayList底层原理:
1.ArrayList中维护了一个Object数组,elementData
transient Object[] elementData; // transient 表示数据不可以序列化
2.如果使用无参构造器构造无参构造器时,则初始化elementData容量为0。
3.当添加元素时,先判断是否需要扩容,如果需要扩容调用grow方法,否则直接添加元素。
4.如果使用无参构造器,第一次添加初始化容量为10,每次扩容,容量增加到原来的1.5倍。
5.如果使用指定容量的构造器,则初始化值为给定的容量,每次扩容增加到原来的1.5倍。
6.实际上底层实现扩容使用的时 copyof 方法。
Vector底层原理:
前面的过曾与ArrayList的原理一致,但是在扩容的时候不一样:
Vector 在每次需要扩容的时候,会将容量扩大到原来的2倍。
ArrayList VS Vector:
底层结构:两个都是可变数组存储。
线程安全(同步)效率:
1.ArrayList 不安全,但效率高。
2.Vector 安全,但是效率不高。
扩容倍数:使用无参构造器,初始化容量都是10,
扩容时ArrayList每次扩容到原来的1.5倍。
Vector扩容到原来的2倍。
LinkedList:
基本介绍:
LinkedList底层实现了双向链表和两端队列的特点,
可以添加任意个元素(元素可以重复),包括null,
线程不安全,没有实现同步。
底层机制:
1.LinkedList底层维护了一个双向链表.
2.LinkList维护两个属性first和last分别指向首结点和尾节点.
3.每个节点就是一个Node对象,里面维护了prev 和 next item 三个属性
其中prev指向前一个,通过next指向下一个.
4.所以LinkedList的元素的添加和删除,不是通过数组删除完成的,相对来说效率更高.
ArrayList VS LinkedList :
底层结构: ArrayList 是可变数组,LinkedList 是双向链表
增删效率: ArrayList是数组扩容,所以效率相对较低
LinkedList是链表追加,效率较高.
改查效率: ArrayList 有索引,较高
LinkedList 遍历链表查找,较低
如何选择 ArrayList 和 LinkList :
1.如果改查多,选择ArrayList
2.如果增删多,选择LinkedList
根据具体情况而定.