概述
集合是java中提供的一种容器,可以用来存储多个数据。集合和数组既然都是容器,它们有啥区别呢?
数组的长度是固定的。集合的长度是可变的。数组中可以存储基本数据类型值,也可以存储对象,而集合中只能存储对象,如果集合想存储基本类型数据需要存储对应的包装类类型。
集合主要分为两大系列:Collection和Map,Collection 表示一组对象,Map表示一组映射关系或键值对。
单列集合常用类的继承体系
Collection:是单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两个重要的子接口,分别是 java.util.List 和 java.util.Set 。子类拥有父类中所有的特点,而且他们还有各自的特点。下面我们就来简单学习一下吧。
List接口特点:元素可重复,元素有索引,元素存取有序。主要实现类如下所示:
ArrayList:查询快,增删慢 linkedList:查询慢,增删快Set接口特点:元素不可重复(唯一),元素无索引。主要实现类如下所示:
HashSet:元素存取无序linkedHashSet:元素存取有序TreeSet:可以对集合中的元素进行排序
注意:上面只是我们常用的集合有这些,不是说就只有这些集合。
Collection类Collection
添加元素
public boolean add(E obj):添加元素对象到当前集合中public boolean addAll(Collection extends E> other):添加other集合中的所有元素对象到当前集合中
import java.util.ArrayList;
import java.util.Collection;
public class Test {
public static void main(String[] args) {
// 创建Collection集合对象,限制集合中元素的类型为String
Collection c1 = new ArrayList<>();
Collection c2 = new ArrayList<>();
// 往c1集合中添加元素
c1.add("张三");
c1.add("李四");
// 往c2集合中添加元素
c2.add("王五");
c2.add("赵六");
System.out.println("c1集合中的元素: "+c1);// c1集合中的元素: [张三, 李四]
System.out.println("c2集合中的元素: "+c2);// c2集合中的元素: [王五, 赵六]
//把c2中的元素添加到c1中
c1.addAll(c2);
System.out.println("c1集合中的元素: "+c1);// c1集合中的元素: [张三, 李四, 王五, 赵六]
System.out.println("c2集合中的元素: "+c2);// c2集合中的元素: [王五, 赵六]
}
}
删除元素
public boolean remove(Object obj) :从当前集合中删除第一个找到的与obj对象equals返回true的元素。public boolean removeAll(Collection> coll):从当前集合中删除所有与coll集合中相同的元素。
import java.util.ArrayList;
import java.util.Collection;
public class Test {
public static void main(String[] args) {
// 创建Collection集合对象,限制集合中元素的类型为String
Collection c1 = new ArrayList<>();
Collection c2 = new ArrayList<>();
// 往c1集合中添加元素
c1.add("张三");
c1.add("李四");
c1.add("王五");
c1.add("赵六");
// 往c2集合中添加元素
c2.add("王五");
c2.add("赵六");
//删除c1集合中的第一个出现 名字叫张三的元素
c1.remove("张三");
System.out.println("c1集合中的元素: "+c1);// c1集合中的元素: [李四, 王五, 赵六]
System.out.println("c2集合中的元素: "+c2);// c2集合中的元素: [王五, 赵六]
//删除c1集合中与c2集合中相同的元素。
c1.removeAll(c2);
System.out.println("c1集合中的元素: "+c1);// c1集合中的元素: [李四]
}
}
判断相关的方法
public boolean isEmpty( ):判断当前集合是否为空集合。public boolean contains(Object obj):判断当前集合中是否存在一个与obj对象equals返回true的元素。public boolean containsAll(Collection> c):判断c集合中的元素是否在当前集合中都存在。即c集合是否是当前集合的“子集”。
import java.util.ArrayList;
import java.util.Collection;
public class Test {
public static void main(String[] args) {
// 创建Collection集合对象,限制集合中元素的类型为String
Collection c1 = new ArrayList<>();
Collection c2 = new ArrayList<>();
// 往c1集合中添加元素
c1.add("张三");
c1.add("李四");
c1.add("王五");
c1.add("赵六");
// 往c2集合中添加元素
c2.add("王五");
c2.add("赵六");
System.out.println("c1集合中的元素: " + c1);// c1集合中的元素: [李四, 王五, 赵六]
System.out.println("c2集合中的元素: " + c2);// c2集合中的元素: [王五, 赵六]
//判断c1集合中是否为空
System.out.println("c1集合中为空: " + c1.isEmpty());// c1集合中为空: false
// 判断c1集合中是否包含张三这个元素
System.out.println("c1集合中是否包含张三: " + c1.contains("张三"));// c1集合中是否包含张三: true
//c2集合是否为c1集合的子集
System.out.println("c2集合中的元素是否在c1集合中都存在: " + c1.containsAll(c2));//c2集合中的元素是否在c1集合中都存在: true
}
}
获取元素个数
public int size():获取当前集合中实际存储的元素个数
import java.util.ArrayList;
import java.util.Collection;
public class Test {
public static void main(String[] args) {
// 创建Collection集合对象,限制集合中元素的类型为String
Collection c1 = new ArrayList<>();
// 往c1集合中添加元素
c1.add("张三");
c1.add("李四");
c1.add("王五");
c1.add("赵六");
System.out.println("c1中的元素个数是:" + c1.size());// c1中的元素个数是:4
}
}
转为数组
public Object[ ] toArray():把集合中的元素,存储到数组中
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class Test {
public static void main(String[] args) {
// 创建Collection集合对象,限制集合中元素的类型为String
Collection c1 = new ArrayList<>();
// 往c1集合中添加元素
c1.add("张三");
c1.add("李四");
c1.add("王五");
c1.add("赵六");
// 把集合中的元素,存储到数组中
Object[] objects = c1.toArray();
System.out.println(Arrays.toString(objects));// [张三, 李四, 王五, 赵六]
}
}
交集
public boolean retainAll(Collection> coll):当前集合仅保留与c集合中的元素相同的元素,即当前集合中仅保留两个集合的交集。
import java.util.ArrayList;
import java.util.Collection;
public class Test {
public static void main(String[] args) {
// 创建Collection集合对象,限制集合中元素的类型为String
Collection c1 = new ArrayList<>();
Collection c2 = new ArrayList<>();
// 往c1集合中添加元素
c1.add("张三");
c1.add("李四");
c1.add("王五");
c1.add("赵六");
// 往c2集合中添加元素
c2.add("王五");
c2.add("赵六");
c2.add("田七");
System.out.println("c1集合中的元素: " + c1);// c1集合中的元素: [李四, 王五, 赵六]
System.out.println("c2集合中的元素: " + c2);// c2集合中的元素: [王五, 赵六, 田七]
//保留2个集合中的交集
c1.retainAll(c2);
System.out.println("c1集合中的元素: " + c1); //c1集合中的元素: [王五, 赵六]
}
}
Iterator迭代器
概述
在程序开发中,经常需要遍历集合中的所有元素。针对这种需求,JDK专门提供了一个接口java.util.Iterator。Iterator接口也是Java集合中的一员,但它与Collection、Map接口有所不同,Collection接口与Map接口主要用于存储元素,而Iterator主要用于迭代访问(即遍历)Collection中的元素,因此Iterator对象也被称为迭代器。
想要遍历Collection集合,那么就要获取该集合迭代器完成迭代操作,下面介绍一下获取迭代器的方法:
public Iterator iterator( ): 获取集合对应的迭代器,用来遍历集合中的元素的。
下面介绍一下迭代的概念:
迭代:即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。
Iterator接口的常用方法如下:
public E next( ):返回迭代的下一个元素。public boolean hasNext( ):如果仍有元素可以迭代,则返回 true。
代码示例
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Demo01 {
public static void main(String[] args) {
// 创建Collection集合对象,限制集合中元素的类型为String
Collection col = new ArrayList<>();
// 往col集合中添加元素
col.add("张三");
col.add("李四");
col.add("王五");
col.add("赵六");
// 获取迭代器对象
Iterator it = col.iterator();
// 循环判断集合中是否有元素可以迭代
while (it.hasNext()) {
// 说明有元素可以迭代
String e = it.next();
System.out.println(e);
}
}
}
迭代器的常见问题
问题一:在进行集合元素获取时,如果集合中已经没有元素可以迭代了,还继续使用迭代器的next方法,将会抛出java.util.NoSuchElementException没有集合元素异常。解决办法: 如果还需要重新迭代,那么就重新获取一个新的迭代器对象进行操作问题二:在进行集合元素迭代时,如果使用集合中的方法添加或移除集合中的元素 , 将无法继续迭代 , 将会抛出ConcurrentModificationException并发修改异常.
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Demo02 {
public static void main(String[] args) {
// 创建Collection集合对象,限制集合中元素的类型为String
Collection col = new ArrayList<>();
// 往col集合中添加元素
col.add("a");
col.add("b");
col.add("c");
col.add("d");
Iterator it = col.iterator();
// 循环判断集合中是否有元素可以迭代
while (it.hasNext()){
// 获取可以迭代的元素
String e = it.next();
System.out.println(e);
// 集合中的方法添加元素到集合中
//col.add("高圆圆");// 报异常
// 集合中的方法 删除元素
//col.remove(e); 报异常
// 我们可以使用迭代器中方法删除
if (e.equals("d")){
it.remove();
}
}
System.out.println("col中的元素"+col);// col中的元素[a, b, c]
// 再获取集合中的元素
// String next = it.next(); //NoSuchElementException
}
}
迭代器的实现原理
我们在之前案例已经完成了Iterator遍历集合的整个过程。当遍历集合时,首先通过调用t集合的iterator()方法获得迭代器对象,然后使用hashNext()方法判断集合中是否存在下一个元素,如果存在,则调用next()方法将元素取出,否则说明已到达了集合末尾,停止遍历元素。Iterator迭代器对象在遍历集合时,内部采用指针的方式来跟踪集合中的元素。
在调用Iterator的next方法之前,迭代器的索引位于第一个元素之前,指向第一个元素,当第一次调用迭代器的next方法时,返回第一个元素,然后迭代器的索引会向后移动一位,指向第二个元素,当再次调用next方法时,返回第二个元素,然后迭代器的索引会再向后移动一位,指向第三个元素,依此类推,直到hasNext方法返回false,表示到达了集合的末尾,终止对元素的遍历。
增强for增强for循环(也称for each循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原理其实是个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。
格式:
遍历数组
通常只进行遍历元素,不要在遍历的过程中对数组元素进行修改。
public class NBForDemo1 {
public static void main(String[] args) {
int[] arr = {3,5,6,87};
//使用增强for遍历数组
for(int a : arr){//a代表数组中的每个元素
System.out.println(a);
}
}
}
遍历集合
通常只进行遍历元素,不要在遍历的过程中对集合元素进行增加、删除、替换操作。
public class NBFor {
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add("小河神");
coll.add("老河神");
coll.add("神婆");
//使用增强for遍历
for(String s :coll){//接收变量s代表 代表被遍历到的集合元素
System.out.println(s);
}
}
}



