Java集合主要分为四种类型:
- Set(集):集合中的对象没有重复的对象,并且不安特定方式排序;
- List(列表):集合中的对象按照索引位置排序,可以有重复的对象;
- Queue(队列):集合中的对象按照先进先出的规则来排序.可以有重复的对象;
- Map(映射):集合中的每一个元素包含一对键(Key)对象和值(Value)对象,集合中没有重复的键对象,值对象可以重复;
其中set接口与数学中的集合最接近,两者都不允许包含重复的元素.在Java API中,Collection接口表示集合,Set,List,和Queue都是Collection的子接口.而Map接口没有继承Collection接口.下图显示了Java的主要集合类的类框图.
Collection接口的通用方法
在Collection接口中声明了适用于Java集合的通用方法(只包括Set,List,和Queue)
方法 | 描述 |
---|---|
Int size() | 返回此集合中的元素数 |
Boolean isEmpty() | 判断集合是否为空,如果此collection不包含任何元素,则返回true |
Boolean contains(Object o) | 判断在集合中是否含指定的元素,bao则返回true |
Iterator iterator() | 返回一个Iterator对象,可用它来遍历集合中的元素 |
Object[] toArray() | 返回一个数组,该数组包含集合中的所有元素 |
Boolean add(Object o) | 向集合中添加一个对象的引用 |
Boolean remove(Object o) | 从集合中删除一个对象的引用 |
Iterator iterator() | 返回一个Iterator对象,可用它来遍历集合中的元素 |
Boolean equals(Object o) | 对象比较 |
boolean containsAll(Collection<?> c) | 如果此集合包含所有指定集合中的元素,则返回true |
boolean addAll(Collection<? extends E> c) | 添加所有指定集合中的元素到这个集合(可选操作) |
boolean removeAll(Collection<?> c) | 移除所有包含在指定collection中的元素。 此调用返回后,此集合将不包含与指定集合相同的元素。 |
boolean retainAll(Collection<?> c) | 仅保留此集合中包含在指定集合中的元素 |
Void clear() | 删除集合中的所有对象,即不再持有这些对象的引用 |
以下为Collection的全部方法
Collection 的iterator方法和toArray方法都用于获得集合中的所有元素,前者返回一个Iterator对象,后者返回一个包含集合中所有元素的数组.Iterator接口隐藏底层集合的数据结构,提供了遍历各种类型的集合的统一接口,Iterator接口中声明了如下方法:
方法 | 描述 |
---|---|
hasNext | 判断集合中的元素是否遍历完毕,如果没有,则返回false |
next() | 返回下一个元素 |
remove() | 从集合中删除由next()方法返回的当前元素 |
利用Iterator来遍历集合
package com.company;
import java.util.*;
public class Visitor {
public static void print(Collection<? extends Object> c) {
Iterator<? extends Object> it = c.iterator();
//遍历集合中的所有元素
while (it.hasNext()) {
System.out.println(it.next());
}
}
//同print()方法一样,都用来遍历集合,区别在于printWithForeach)使用foreach语句,简化了代码
public static void printWithForeach(Collection<? extends Object> c) {
for (Object element : c) {
System.out.println(element);
}
}
public static void main(String[] args) {
HashSet<String> set = new HashSet<String>();//创建set
set.add("Tom");
set.add("Marry");
set.add("Jack");
print(set);
ArrayList<String> list = new ArrayList<String>();//创建list
list.add("Linda");
list.add("Mary");
list.add("Rose");
print(list);
ArrayDeque<String> quene = new ArrayDeque<String>();//创建queue
quene.add("Tom");
quene.add("Mike");
quene.add("Jack");
print(quene);
//map.entrySet()方法返回一个集合,该集合中存放Map.Entry元素
//每个Map.Entry元素表示一对键/值
HashMap<String, String> map = new HashMap<String, String>();
map.put("M", "男");
map.put("F", "女");
print(map.entrySet());
printWithForeach(set);
printWithForeach(list);
printWithForeach(quene);
printWithForeach(map.entrySet());
}
}
Tips:如果集合中的元素没有排序.Iterator遍历集合中元素的顺序是任意的,并不一定与集合中加入元素的顺序一直,
当通过Collection集合的iterator()方法得到一个Iterator对象后,如果当前线程或其他线程又通过Collection的一些方法对集合进行了修改操作,接下来访问这个Iterator对象的next()方法会导致java.util.ConcurrentModificationException运行时异常,代码如下
public class ConcurrentTester {
public static void main(String[] args) {
//当前线程
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("d");
arrayList.add("e");
for (String string : arrayList) {
if ("e".equals(string)) {
arrayList.remove(string);
}
}
//其他线程
final int size=1000;
final HashSet<Integer> set = new HashSet<Integer>();
for (int i = 0; i < size; i++) {
set.add(new Integer(i));
}
//负责遍历集合的线程
Thread reader = new Thread(){
public void run(){
for (Integer i : set) {
System.out.println(i);//抛出ConcurrentModificationException异常
yield();//把集合让给别的线程
}
}};
//负责删除集合中元素的线程
Thread remover = new Thread(){
public void run(){
for (int i = 0; i < size; i++) {
set.remove(new Integer(i));//删除集合中的元素
yield();
}
}
};
reader.start();
remover.start();
}
}
错误信息:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at com.company.ConcurrentTester.main(ConcurrentTester.java:23)
总结:
- Iterator对象运用了快速失败机制,一旦监测到集合已被修改,就抛出ConcurrentModificationException运行时异常,而不是显示修改后的当前内容,这可以避免潜在的由于共享资源竞争而导致的并发问题 ;
- 增强for循环用于遍历集合,但不适合对集合进行删除操作;若想在遍历集合时删除元素,可以参阅 https://juejin.im/post/5a992a0d6fb9a028e46e17ef
在本次整理Collection方法时,使用了一个好用API文档工具: Zeal,下载安装参照:https://my.oschina.net/gaoenwei/blog/1793915