一、Java集合框架图
上述类图中,实线边框的是实现类,比如ArrayList,LinkedList,HashMap等,折线边框的是抽象类,比如AbstractCollection,AbstractList,AbstractMap等,而点线边框的是接口,比如Collection,Iterator,List等。
发现一个特点,上述所有的集合类,都实现了Iterator接口,这是一个用于遍历集合中元素的接口,主要包含hashNext(),next(),remove()三种方法。
它的一个子接口LinkedIterator在它的基础上又添加了三种方法,分别是add(),previous(),hasPrevious()。也就是说如果实现Iterator接口,那么在遍历集合中元素的时候,只能往后遍历,被遍历后的元素不会在遍历到,通常无序集合实现的都是这个接口,比如HashSet,HashMap;而那些元素有序的集合,实现的一般都是LinkedIterator接口,实现这个接口的集合可以双向遍历,既可以通过next()访问下一个元素,又可以通过previous()访问前一个元素,比如ArrayList。
还有一个特点就是抽象类的使用。如果要自己实现一个集合类,去实现那些抽象的接口会非常麻烦,工作量很大。这个时候就可以使用抽象类,这些抽象类中给我们提供了许多现成的实现,我们只需要根据自己的需求重写一些方法或者添加一些方法就可以实现自己需要的集合类,工作流昂大大降低。
二、详解
2.1HashSet
HashSet是Set接口的一个子类,主要的特点是:里面不能存放重复元素,而且采用散列的存储方法,所以没有顺序。这里所说的没有顺序是指:元素插入的顺序与输出的顺序不一致。
代码示例:HashSetDemo
package edu.sjtu.erplab.collection;View Code
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class HashSetDemo {
public static void main(String[] args) {
Set<String> set=new HashSet<String>();
set.add("a");
set.add("b");
set.add("c");
set.add("c");
set.add("d");
//使用Iterator输出集合
Iterator<String> iter=set.iterator();
while(iter.hasNext())
{
System.out.print(iter.next()+" ");
}
System.out.println();
//使用For Each输出结合
for(String e:set)
{
System.out.print(e+" ");
}
System.out.println();
//使用toString输出集合
System.out.println(set);
}
}
代码示例:SetTest
package edu.sjtu.erplab.collection;View Code
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;
public class SetTest {
public static void main(String[] args) throws FileNotFoundException {
Set<String> words=new HashSet<String>();
//通过输入流代开文献
//方法1:这个方法不需要抛出异常
InputStream inStream=SetTest.class.getResourceAsStream("Alice.txt");
//方法2:这个方法需要抛出异常
//InputStream inStream = new FileInputStream("D:\\Documents\\workspace\\JAVAStudy\\src\\edu\\sjtu\\erplab\\collection\\Alice.txt");
Scanner in=new Scanner(inStream);
while(in.hasNext())
{
words.add(in.next());
}
Iterator<String> iter=words.iterator();
for(int i=0;i<5;i++)
{
if(iter.hasNext())
System.out.println(iter.next());
}
System.out.println(words.size());
}
}
2.2ArrayList
ArrayList是List的子类,它和HashSet相反,允许存放重复元素,因此有序。集合中元素被访问的顺序取决于集合的类型。
如果对ArrayList进行访问,迭代器将从索引0开始,每迭代一次,索引值加1。然而,如果访问HashSet中的元素,每个元素将会按照某种随机的次序出现。虽然可以确定在迭代过程中能够遍历到集合中的所有元素,但却无法预知元素被访问的次序。
代码示例:ArrayListDemo
package edu.sjtu.erplab.collection;View Code
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ArrayListDemo {
public static void main(String[] args) {
List<String> arrList=new ArrayList<String>();
arrList.add("a");
arrList.add("b");
arrList.add("c");
arrList.add("c");
arrList.add("d");
//使用Iterator输出集合
Iterator<String> iter=arrList.iterator();
while(iter.hasNext())
{
System.out.print(iter.next()+" ");
}
System.out.println();
//使用For Each输出结合
for(String e:arrList)
{
System.out.print(e+" ");
}
System.out.println();
//使用toString输出集合
System.out.println(arrList);
}
}
2.3 ListIterator
ListIterator是一个继承于Iterator的接口,它是队列迭代器。专门用于便利List,能提供向前/向后遍历。相比于Iterator,它新增了添加、是否存在上一个元素、获取上一个元素等等API接口。
代码示例:LinkedListTest(使用ListIterator遍历)
package edu.sjtu.erplab.collection;View Code
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class LinkedListTest {
public static void main(String[] args) {
List<String> a=new ArrayList<String>();
a.add("a");
a.add("b");
a.add("c");
System.out.println(a);
List<String> b=new ArrayList<String>();
b.add("d");
b.add("e");
b.add("f");
b.add("g");
System.out.println(b);
//ListIterator在Iterator基础上添加了add(),previous()和hasPrevious()方法
ListIterator<String> aIter=a.listIterator();
//普通的Iterator只有三个方法,hasNext(),next()和remove()
Iterator<String> bIter=b.iterator();
//b归并入a当中,间隔交叉得插入b中的元素
while(bIter.hasNext())
{
if(aIter.hasNext())
aIter.next();
aIter.add(bIter.next());
}
System.out.println(a);
//在b中每隔两个元素删除一个
bIter=b.iterator();
while(bIter.hasNext())
{
bIter.next();
if(bIter.hasNext())
{
bIter.next();//remove跟next是成对出现的,remove总是删除前序
bIter.remove();
}
}
System.out.println(b);
//删除a中所有的b中的元素
a.removeAll(b);
System.out.println(a);
}
}
2.4HashMap
参考下一篇博客:HashMap实现原理
三、比较分析
集合名称 | 具体集合名称 | 是否有序 | 是否允许元素重复 |
Collection | 否 | 是 | |
List | 是 | 是 | |
Set | AbstractSet | 否 | 否 |
HashSet | |||
TreeSet | 是 | ||
Map | AbstractMap | 否 |
使用key-value来映射和存储数据 key必须唯一,value可以重复 |
HashMap | |||
TreeMap | 是 |