相同点
都是容器,可以存储多个数据
不同点
数组的长度是不可变的,集合的长度是可变的
数组可以存基本数据类型和引用数据类型
集合只能存引用数据类型,如果要存基本数据类型,需要存对应的包装类
public static void main(String[] args) {
int[] arr1={1,2,3};
String[] arr2={"a","b","c"};
System.out.println(Arrays.toString(arr1));
System.out.println(Arrays.toString(arr2));
System.out.println("----------------------");
ArrayList<String> list1 = new ArrayList<>();
list1.add("a");list1.add("b");list1.add("c");
System.out.println(list1);
//ArrayList<int> list2 = new ArrayList<>();//报错 只能存储引用数据类型 不能存储基本数据类型
ArrayList<Integer> list2 = new ArrayList<>();
list2.add(1);list2.add(2);list2.add(3);
System.out.println(list2);
}


蓝色外框都是接口、红色外框都是具体实现类
Collection集合概述
创建Collection集合的对象
| 方法名 | 说明 |
|---|---|
| boolean add(E e) | 添加元素 |
| boolean remove(Object o) | 从集合中移除指定的元素(第一次出现的那一个 且 成功返回true 失败返回false) |
| boolean removeIf(Object o) | 根据条件进行移除 |
| void clear() | 清空集合中的元素 |
| boolean contains(Object o) | 判断集合中是否存在指定的元素 |
| boolean isEmpty() | 判断集合是否为空 |
| int size() | 集合的长度,也就是集合中元素的个数 |
代码1:add&remove
public static void main(String[] args) {
Collection<String> c =new ArrayList<>();//只能new实现类 不能new接口
// boolean add(E e) | 添加元素
c.add("aaa");c.add("bbb");c.add("ccc");
System.out.println(c);//[aaa, bbb, ccc]
//boolean remove(Object o) | 从集合中移除指定的元素(成功返回true 失败返回false)
print("remove");
System.out.println(c.remove("aaa"));//true
System.out.println(c.remove("ddd"));//false
System.out.println(c);//[bbb, ccc]
}
public static void print(String s){
System.out.println("-----------"+s+"-----------");
}
代码2:removeIf
public static void main(String[] args) {
Collection<String> c =new ArrayList<>();//只能new实现类 不能new接口
c.add("aaa");c.add("bbb");c.add("ccc");c.add("dddd");
//boolean removeIf(Object o) | 根据条件进行删除
/*removeIf底层会遍历集合,得到集合中的每一个元素
s依次表示集合中的每一个元素
就会把这每一个元素都到lambda表达式中去判断一下
如果返回的是true,则删除
如果返回的是false,则保留不删除.*/
c.removeIf( (String s)->{return s.length()==3;}/*删除长度为3的*/ );//传入lambda表达式 条件删除
System.out.println(c);//[dddd]
}
代码3:清空集合中的元素
public static void main(String[] args) {
Collection<String> c =new ArrayList<>();//只能new实现类 不能new接口
c.add("aaa");c.add("bbb");c.add("ccc");c.add("dddd");
// void clear() | 清空集合中的元素
System.out.println(c);//[aaa, bbb, ccc, dddd]
c.clear();
System.out.println(c);//[]
}
代码4:判断集合中是否存在指定元素
public static void main(String[] args) {
Collection<String> c =new ArrayList<>();//只能new实现类 不能new接口
c.add("aaa");c.add("bbb");c.add("ccc");c.add("dddd");
//boolean contains(Object o) | 判断集合中是否存在指定的元素
System.out.println(c.contains("aaa"));//true
System.out.println(c.contains("cccc"));//false
}
代码5:集合判空、集合长度
public static void main(String[] args) {
Collection<String> c =new ArrayList<>();//只能new实现类 不能new接口
c.add("aaa");c.add("bbb");c.add("ccc");c.add("dddd");
// boolean isEmpty() | 判断集合是否为空
System.out.println(c.isEmpty());//false
// int size() | 集合的长度,也就是集合中元素的个数
System.out.println(c.size());//4
}
迭代器介绍
Iterator中的常用方法
boolean hasNext(): 判断当前位置是否有元素可以被取出
E next(): 获取当前位置的元素,将迭代器对象移向下一个索引位置
Collection集合的遍历
public static void main(String[] args) {
Collection<String> list=new ArrayList<>();
list.add("a");list.add("b");list.add("c");list.add("d");
//1.获取迭代器对象
//迭代器对象一旦被创建出来,默认指向集合的0索引处
Iterator<String> it = list.iterator();
while (it.hasNext()){//当前位置是否有元素可以被取出
System.out.println(it.next());//取出当前位置的元素 + 将迭代器往后移动一个索引的位置
}
}


public static void main(String[] args) {
ArrayList<String> list=new ArrayList<>();
list.add("a");list.add("b");list.add("b");list.add("c");list.add("d");
Iterator<String> it = list.iterator();
while (it.hasNext()){
String s = it.next();
if("b".equals(s)){
it.remove();
//迭代器不会因为删除而导致指针混乱(应该自动帮你实现了it--啥的 或者it一起左移了)
}
}
System.out.println(list);//[a, c, d]
}
普通根据下标删除的弊端
public static void main(String[] args) {
ArrayList<String> list=new ArrayList<>();
list.add("a");list.add("b");list.add("b");list.add("c");list.add("d");
for (int i = 0; i < list.size(); i++) {
if("b".equals(list.get(i))){//ArrayList 才有get方法 Collection没有
list.remove(i);
i--;//必须i-- 否则bug list.remove(i);会自动将后面元素整体后移动(标准顺序表)然后表长-1
//System.out.println(list.size());
}
}
System.out.println(list);//[a, c, d]
//remove后不加 i--; 输出[a, b, c, d] 原因,每次remove后集合元素会整体前移,然后i++,正好错过了相邻的b
list.add("e");list.add("e");
System.out.println(list);
while (list.contains("e")) //结合api删除 多快 不过可能时间效率太慢了 不提倡
list.remove("e");//一次remove只能删除一个
System.out.println(list);
}
介绍
格式
for(集合/数组中元素的数据类型 变量名 : 集合/数组名) {
// 已经将当前遍历到的元素封装到变量中了,直接使用变量即可
}
代码
public static void main(String[] args) {
ArrayList<String> list=new ArrayList<>();
list.add("a");list.add("b");list.add("b");list.add("c");list.add("d");
//只能是数组或者Collection(单列集合) Map不能用(需要自己实现Iterable接口后才可以用)
for (String s : list) {
System.out.print(s+" ");//a b b c d
}
}
注意:增强for无法修改集合
public static void main(String[] args) {
ArrayList<String> list=new ArrayList<>();
list.add("a");list.add("b");list.add("b");list.add("c");list.add("d");
//只能是数组或者Collection(单列集合) Map不能用(需要自己实现Iterable接口后才可以用)
for (String s : list) {
s="q";//s只是list元素(新地址下)的一个副本 不要妄想通过增强for修改集合
}
System.out.println(list);//[a, b, b, c, d]
}

List接口就有的
| 方法名 | 描述 |
|---|---|
| void add(int index,E element) | 在此集合中的指定位置 插入指定的元素 |
| E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
| E set(int index,E element) | 修改指定索引处的元素,返回被修改的元素 |
| E get(int index) | 返回指定索引处的元素 |
public static void main(String[] args) {
List<String> list = new ArrayList<>();//类型采用List接口类型
list.add("aaa");list.add("bbb");list.add("bbb");
Iterator<String> it = list.iterator();
while (it.hasNext()){
String s = it.next();
System.out.println(s);
}
System.out.println("---------------");
for (String s : list) {
System.out.println(s);
}
}

public static void main(String[] args) {
List<String> list = new ArrayList<>();//类型采用List接口类型
list.add("aaa");list.add("bbb");list.add("ccc");
// void add(int index,E element) 在此集合中的指定位置插入指定的元素
// 原来位置上的元素往后挪一个索引.
list.add(0,"qqq");
System.out.println(list);//[qqq, aaa, bbb, ccc]
}

public static void main(String[] args) {
List<String> list = new ArrayList<>();//类型采用List接口类型
list.add("aaa");list.add("bbb");list.add("ccc");
// E remove(int index) 删除指定索引处的元素,返回被删除的元素
//在List集合中有两个删除的方法
//第一个 删除指定的元素,返回值表示当前元素是否删除成功
//第二个 删除指定索引的元素,返回值表示实际删除的元素
String s = list.remove(0);
System.out.println(s);//aaa
System.out.println(list);//[bbb, ccc]
/* boolean remove(Object o) //Collection就有,继承下来的
从此列表中移除第一次出现的指定元素(如果存在)(可选操作)。 */
}
public static void main(String[] args) {
List<String> list = new ArrayList<>();//类型采用List接口类型
list.add("aaa");list.add("bbb");list.add("ccc");
// E set(int index,E element) 修改指定索引处的元素,返回被修改的元素
//被替换的那个元素,在集合中就不存在了.
String s = list.set(0, "qqq");
System.out.println(s);//aaa (返回被修改消失的元素)
System.out.println(list);//[qqq, bbb, ccc]
// E get(int index) 返回指定索引处的元素
String s1 = list.get(0);
System.out.println(s1);//qqq
}
栈结构
先进后出
队列结构
先进先出
数组结构
查询快、增删慢
队列结构
查询慢、增删快
ArrayList集合
底层是数组结构实现,查询快、增删慢 (add、remove、get…算法完全就是顺序表的那些操作,需要知道)
[ArrayList.get(i) 数组当然可以随机访问(查看源码也确实有个数组)]
ArrayList.java源码里面一句话: private static final int DEFAULT_CAPACITY = 10;
则:初试数组容量0,第一次申请数组容量10 (以后再满了应该是1.5倍地增长 还带有原来数组元素的复制)

LinkedList集合
底层是链表结构实现,查询慢、增删快(add、remove、get…算法完全就是链表的那些操作,需要知道)
LinkedList也有get(i)方法,只不过效率很低罢了 [List接口继承下来的嘛]
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<>();
list.add("aaa");list.add("bbb");list.add("ccc");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));//链表的get(i)方法,效率很低
}
System.out.println("----------------------------");
Iterator<String> it = list.iterator();
while (it.hasNext()){
String s = it.next();
System.out.println(s);
}
System.out.println("----------------------------");
for (String s : list) {
System.out.println(s);
}
}

特有方法
| 方法名 | 说明 |
|---|---|
| public void addFirst(E e) | 在该列表开头插入指定的元素 |
| public void addLast(E e) | 将指定的元素追加到此列表的末尾 |
| public E getFirst() | 返回此列表中的第一个元素 |
| public E getLast() | 返回此列表中的最后一个元素 |
| public E removeFirst() | 从此列表中删除并返回第一个元素 |
| public E removeLast() | 从此列表中删除并返回最后一个元素 |