容器的概念
-
之前我们使用过数组,数组是一个存放固定长度的1相同类型的有序集合,这对于某些方面的是用是很好的,但是在一些需要灵活添加数据的时候使用起来效率就会很低,这时候我们就需要使用容器,容器时一种灵活的,容量可以随时扩充的容器来装载我们的对象。
容器的上层接口
-
Collection 接口是一组允许重复的对象。
-
Set 接口继承 Collection,无序不允许重复,使用自己内部的一个排列机制。
-
List 接口继承 Collection,有序允许重复,以元素安插的次序来放置元素, 不会重新排列。
-
-
Map 接口是一组成对的键值对象,即所持有的是 key-value pairs。Map 中不能有重 复的 key。拥有自己的内 部排列机制。
-
容器中的元素类型都为引用类型,不能放置原生数据类型(使用装箱即可),使用泛 型保留类型
Collection 表示一组对象,它是集中,收集的意思,就是把一些数据收集起来,Collection 接口的两个子接口:
-
Set 中的数据没有顺序,不可重复
-
List 中的数据有顺序,可重复
方法 返回值 作用 CRUD add(E e) boolean 添加元素 C size() int 返回容器大小 R contains(Object o) boolean 包含(引用类型重写equals) isEmpty() boolean 容器是否为空 equals(Object o) boolean 比较两个容器内容是否相同 remove(Object o) boolean 删除元素 D clear() void 清空容器 toArray() Object[] 所有元素存放在数组中 其他 toArray(T[] a) <T> t[] retainAll(Collection<> c) boolean 求交集 iterator iterator 遍历 遍历 示例
package Demo10;
import java.util.ArrayList;
import java.util.Collection;
public class Demo11 {
public static void main(String[] args) {
Collection col = new ArrayList();
// 添加
col.add("张三");
// 打印容量
System.out.println("容器的大小为:" + col.size());
col.add("李四");
System.out.println("容器的大小为:" + col.size());
col.add("王五");
System.out.println("容器的大小为:" + col.size());
}
}结果
容器的大小为:1
容器的大小为:2
容器的大小为:3说明容器的大小时随着数据的增加而更改的
泛型<>
把类型明确的工作推迟到创建对象或调用方法的时候才去明确的特殊的类型
为什么需要泛型?
JDK1.4 以前类型不明确:
装入集合的类型都被当作 Object 对待,从而失去自己的实际类型。
从集合中取出时往往需要转型,效率低,容易产生错误。
泛型的好处:
增强程序的可读性和稳定性。
使用泛型,保留了容器中元素的类型,安全省心的使用容器。注意:没有必要引入泛型 的复杂性。
package Demo10;
import java.util.ArrayList;
import java.util.Collection;
public class Demo12 {
public static void main(String[] args) {
Collection<String> col = new ArrayList<String>();
col.add("钢铁侠");
col.add("蜘蛛侠");
col.add("蚁人");
col.add("惊奇队长");
System.out.println("容器大小为:" + col.size());
// 遍历容器
for (String str : col) {
System.out.println(str);
}
}
}
Iterator 接口
所有实现了Collection接口的容器类都有一个iterator方法用以返回一个实现了Iterator接口的对象Iterator对象 称作迭代器,用以方便的实现对容器内元素的遍历操作。
//接口定义了如下方法
boolean hasNext(); //判断是否有元素没有被遍历
Object next(); //返回游标当前位置的元素并将游标移动到下一个位置
void remove(); //删除游标左面的元
使用迭代器时,分三步走策略:
-
第一步,获取对象
-
第二步,判断是否存在下一个
-
第三步,获取元素、
//迭代器
//1.获取容器的迭代器
Iterator it = coll2.iterator();
//2.循环判断是否存在下一个元素
while(it.hasNext()) {
//3.获取
System.out.println(it.next());
}
List接口
List接口,位置有序允许元素重复。多了一些关于位置(顺序)的方法
方法 | 返回值 | 作用 | CRUD |
---|---|---|---|
add(int index,E element) | void | 指定位置添加元素 | C |
get(int index) | E | 获取指定位置元素(for遍历) | R |
indexOf(Object o) | int | 元素第一次出现的索引 | |
lasrIndexOf(Object o) | int | 元素最后一次出现的索引 | |
set(int,E) | E | 覆盖元素,返回覆盖前的元素 | U |
remove(int,int) | E | 删除指定索引的元素,返回该元素 | D |
subList(int int) | List | 获取子集合 | 其他 |
listlterator() | Lisriterator | 可以反向输出 | 遍历 |
ArrayList
ArrayList 是 List 的子类,它和 HashSet 想法,允许存放重复元素,因此有序。集合中元 素被访问的顺序取决于集 合的类型。如果对 ArrayList 进行访问,迭代器将从索引 0 开始, 每迭代一次,索引值加 1。然而,如果访问 HashSet 中的元素,每个元素将会按照某种随机 的次序出 现。虽然可以确定在迭代过程中能够遍历到集合中的所 有元素,但却无法预知元 素被访问的次序。
ArrayList,Vector,LinkedList三者区别
AarryList :
-
底层实现: 可变数组实现的,内部 通过数组拷贝实现根据内容可变长
-
优点 : 根据索引查询效率高
-
缺点 :错增加删除时效率低,因为要通过数组拷贝实现
-
应用场景: 存储耽搁数据,有序可以重复-->大量做查询,少量增删,推荐使用ArrayList
-
扩容: 在第一次添加数据时候初始容量10 , 通过Arrays.copyof方法进行动态扩容,每次扩容原容量的1.5倍
-
int newCapacity = oldCapacity + (oldCapacity >> 1);
Vector:
-
底层实现: 可变数组实现的,
-
扩容:: 在第一次添加数据时候初始容量10 , 每次扩容原容量的2倍
-
与ArrayList不同点:
-
1)AarryList线程不安全 ,vector线程安全
-
2)扩容问题: ArrayList1.5倍增长 vector2倍增长 ArrayList更有利于节省内存
-
LinkedList:
-
底层实现: 双向链表实现的
-
优点:增删效率高
-
缺点: 查询效率低
-