集合:集合是java中提供的一种容器,可以用来存储多个数据。
这和我们之前学的数组作用是一样的,那他们有什么区别呢?
既然数组已经可以当作一个容器来存储多个值,那集合有什么用呢?
—从上面的区别,我们知道数组的长度不可变,不够灵活,需要我们自己去扩容,比较麻烦。而集合就不需要考虑这个了,并且里面封装了查找,新增,修改,删除元素等方法,用起来很方便,就不需要我们自己手动去写这些方法了。
集合类的体系图
(单列指输入一个数据,双列需要输入两个数据)
1.Collection集合概述
是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
JDK 不提供此接口的任何直接实现,它提供更具体的子接口(如Set和List)实现
1.1Collection提供的一些方法
public boolean add(E e)
: 把给定的对象添加到当前集合中 。public void clear()
:清空集合中所有的元素。public boolean remove(E e)
: 把给定的对象在当前集合中删除。public boolean contains(Object obj)
: 判断当前集合中是否包含给定的对象。public boolean isEmpty()
: 判断当前集合是否为空。public int size()
: 返回集合中元素的个数。public Object[] toArray()
: 把集合中的元素,存储到数组中#2.Set和List
Set和List都是子接口,没有具体实现,需要依赖子类来实现。
区别:
(图片来源于网络)
注意:Set集合没有索引,所以不能用for循环来遍历元素。只能通过增强for循环和迭代器来遍历元素。
介绍:用来遍历集合中的所有元素,并且不需要知道它的底层结构,提供了以下常用方法。
public boolean hasNext():如果仍有元素可以迭代,则返回 true。
public E next():返回迭代的下一个元素。
public void remove():删除元素
注意:
- 在进行集合元素获取时,如果集合中已经没有元素了,还继续使用迭代器的next方法,将会抛出java.util.NoSuchElementException没有集合元素异常。
- 在进行集合元素获取时,如果添加或移除集合中的元素 , 将无法继续迭代 , 将会抛出ConcurrentModificationException并发修改异常.
Iterable 是Collection的父接口,并且提供了Iterator iterator()方法来获取一个迭代器对象,这样所有的Collection子类都能进行迭代
我们来看一下源码:
举例:
public class test04 {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();//创建集合对象
arrayList.add("123");//给集合里面添加数据
arrayList.add("456");
//调用父类提供的iterator()方法,来获取一个迭代器对象
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()){//判断集合中是否还有元素,如果有才能继续循环
//返回迭代的下一个元素。
Object next = iterator.next();
System.out.println(next);
}
}
}
注意:
Iterator是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出java.util.ConcurrentModificationException异常
增强for循环
增强for循环就是for循环的增强版,专门用来遍历集合和数组的。因为有些集合没有索引,普通for循环就没法遍历了。增强for循环的底层其实就是迭代器
举例:
ublic class test04 {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
arrayList.add("123");
arrayList.add("456");
for (Object o : arrayList) {
System.out.println(o);
}
}
}
我们查看它生成的class文件
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.Frank.Test2;
import java.util.ArrayList;
import java.util.Iterator;
public class test04 {
public test04() {
}
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
arrayList.add("123");
arrayList.add("456");
Iterator var2 = arrayList.iterator();
while(var2.hasNext()) {
Object o = var2.next();
System.out.println(o);
}
}
}
可以看出,其实它最后还是转换成了迭代器来遍历集合。
既然增强for循环的底层是迭代器,那增强for循环也就有迭代器的特性
举例:(用迭代器遍历的时候不能修改集合,只能用迭代器提供的方法来修改)
public class test04 {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
arrayList.add("123");
arrayList.add("456");
for (Object o : arrayList) {
System.out.println(o);
arrayList.add("789");//不能用集合的add()方法,要用迭代器的
}
}
}