一、概述
- 本质上是一个存储一组数据大小不定的容器 ---- 顶级 接口Collection
二、集合的声明
- 集合的声明 Collection<String> c; 表示一个存储String类型数据的集合。
- <E> : 泛型,在声明一个集合时使用泛型临时代替具体类型,由于泛型的限制,集合中只能存储对象。
三、Collection中的方法:
- add() : 添加元素。
- remove() : 删除元素 。在删除之前会首先判断元素是否存在,若存在则删除;若不存在,则跳过。不会报错
- contains() : 判断集合中是否包含指定元素。
- clear() ; 清空集合
- isEmpty() : 判断集合是否为空。
- size() : 获取集合中元素的个数。
- toArray() : 将集合转换为数组,返回值是Object[ ] 。 返回的Object[] 不能转换成其他类型的数组。原因:集合底层实际上是以Object存储内容
- toArray(new String[]) : 将集合转换为指定类型的数组。底层会判断数组的大小是否等于元素的个数。如果大于元素的个数,则直接使用参数数组存储元素;如果小于元素个数底层只会根据数组类型来创建一个与元素个数等大的数组存储数据。
public static void main(String[] args) {
// 表示元素类型是String类型
Collection<String> c = new ArrayList<String>();
// 添加元素
c.add("adf");
c.add("rth");
c.add("lmn");
c.add("jkl");
// 将集合转化为Object类型的数组
// Object[] os = c.toArray();
// 集合底层在存储元素的时候实际上是以Object类型存储
// Oject[] os = new Object[c.size()];
// String[] os = (String[]) c.toArray();
// for (String object : os) {
// System.out.println(object);
// }
// 将集合转化为对应类型的数组
/*
* 在底层会判断传入的数组的大小是否大于等于元素的个数
* 如果大于等于了元素个数,则直接使用传入的数组来存储元素,最后返回传入的数组。
* 如果小于元素个数,底层只会根据传入对的类型来创建一个和元素个数等大的数组
*/
String[] ss = c.toArray(new String[0]);
for (String s : ss) {
System.out.println(s);
}
// 获取元素个数---集合中元素的个数和集合的大小是两个概念
// System.out.println(c.size());
// 清空集合
// c.clear();
// 判断是否一个空集合
// System.out.println(c.isEmpty());
// 遍历集合
// for (String s : c) {
// System.out.println(s);
// }
// 删除元素---在删除这个元素之前会首先判断这个元素是否存在。
// c.remove("adg");
// 判断指定的元素是否存在
// System.out.println(c.contains("jkl"));
// 集合中toString做过重写
System.out.println(c);
}
四、List<E>
- List<E> 是Collection的子接口 ,所以Collection中的方法都可以用。
- List<E> 中的元素是有序的,存在List中的元素会被自动编号。从0开始。
- 可以有重复的元素
List<E>中的方法:
- add() : 添加元素
- add(int index ,arg) : 在指定下标的位置添加指定元素
- equals(List<E>) : 判断两个列表内容是否一致(包括顺序)。 底层实现: 实际上是依次调用对应位置的元素的equals方法 比较是否一致。
- get(int index) : 获取指定下标位置的元素。
- indexOf() ; 获取指定元素在列表中第一次出现的位置。若果元素不在列表中,则返回-1.
- lastIndexOf() : 获取指定元素在列表中最后一次出现的位置。
- removeIndexOf() : 移除制定下标位置上的元素。
- set(int index,arg) : 替换指定下标位置的元素。
- subList() : 获取子列表。
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
// 添加元素
list.add("abc");
list.add("def");
list.add("ghi");
list.add("jkl");
list.add("abc");
// list.add(10, "xyz");
// 移除指定下标位置上的元素
// list.remove(2);
// 替换指定下标上的元素
// list.set(1, "opq");
// 获取指定下标位置上的元素
// System.out.println(list.get(3));
// 获取指定元素在列表中第一次出现的位置
// 如果元素不存在,则返回-1
// System.out.println(list.indexOf("ad"));
// 向列表的指定下标上插入指定的元素
// list.add(1, "mno");
// 判断两个列表是否一致
// List<String> list2 = new ArrayList<String>();
// list2.add(new String("abc"));
// list2.add("def");
// list2.add("ghi");
// list2.add("jkl");
// list2.add("abc");
// 在比较两个集合是否一致的时候,实际上依次调用对应位置上的元素的equals来比较两个元素是否一致。
// System.out.println(list.equals(list2));
System.out.println(list);
}
五、 ArrayList<E>
- 是List<E>的实现类
- 是基于数组的
- 初始容量为10.如果容量不够用,则自动扩容,在上一次的基础上累加一半。 10 -> 15 ->22 ....
- 内存空间连续。查询较快,增删较慢。
练习: 1. 用数组实现一个简易版的ArrayList 存储String,有add\remove\set\get\indexOf\contains\isEmpty\size\toString等方法
import java.util.Arrays;
public class ListExer {
// 存储元素
private String[] data;
// 记录已经存储的元素个数
private int size = 0;
public ListExer() {
data = new String[10];
}
public ListExer(int capacity) {
// 需要判断容量是否符合事实
if (capacity < 0) {
capacity = 10;
}
data = new String[capacity];
}
private void grow() {
if (data.length <= 1) {
data = Arrays.copyOf(data, data.length + 1);
return;
}
data = Arrays.copyOf(data, data.length + (data.length >> 1));
}
public void add(String s) {
// 判断是否需要扩容
if (size >= data.length) {
this.grow();
}
data[size] = s;
size++;
}
public void add(int index, String s) {
// 判断下标是否越界
if (index > size) {
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
// 判断是否需要扩容
if (size >= data.length) {
this.grow();
}
// 插入元素
// for (int i = size - 1; i >= index; i--) {
// data[i + 1] = data[i];
// }
System.arraycopy(data, index, data, index + 1, size - index);
data[index] = s;
size++;
}
public void remove(String s) {
// 获取这个元素第一次出现的下标
int index = this.indexOf(s);
// 判断这个下标是否存在
if (index != -1) {
this.remove(index);
}
}
private void out(int index) {
// 判断下标越界
if (index >= size) {
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
}
public void remove(int index) {
this.out(index);
// for (int i = index; i < size - 1; i++) {
// data[i] = data[i + 1];
// }
System.arraycopy(data, index + 1, data, index, size - index - 1);
size--;
}
public void set(int index, String s) {
this.out(index);
data[index] = s;
}
public String get(int index) {
this.out(index);
return data[index];
}
public boolean contains(String s) {
return this.indexOf(s) != -1;
}
public boolean isEmpty() {
return size <= 0;
}
public int indexOf(String s) {
for (int i = 0; i < size; i++) {
if (s == data[i] || s != null && s.equals(data[i])) {
return i;
}
}
return -1;
}
public int size() {
return size;
}
public String toString() {
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < size; i++) {
sb.append(data[i]).append(", ");
}
String str = sb.toString();
if (str.length() > 1) {
str = str.substring(0, str.length() - 2);
}
return str += "]";
}
public static void main(String[] args) {
ListExer le = new ListExer(3);
le.add("a");
le.add("b");
le.add("c");
le.add(0,"e");
le.remove(0);
System.out.println(le);
}
}