Java容器类包含List、ArrayList、Vector及map、HashTable、HashMap、Hashset
ArrayList和HashMap是异步的,Vector和HashTable是同步的,所以Vector和HashTable是线程安全的,而 ArrayList和HashMap并不是线程安全的。因为同步需要花费机器时间,所以Vector和HashTable的执行效率要低于 ArrayList和HashMap。
由Collection接口派生的两个接口是List和Set。
List是有序、重复的集合,set是无需不可重复的集合。
Java中的“STL”可以从C++中进行衍生理解,Java拥有了C++的STL功能,这些功能类被封装在java.util包内,以下简称这些类的统称为J-STL。
util定义了如下接口,J-STL主要实现了以下几个接口——斜体字表示
Collection (Java 2) List (Java 2) Observer Comparator (Java 2) ListIterator (Java 2) Set (Java 2) Enumeration Map (Java 2) SortedMap (Java 2) EventListener Map.Entry (Java 2) SortedSet (Java 2) Iterator (Java 2)
我们所使用的J-STL类都是这些接口的某个实现。下面是简单的部分介绍。
Collection接口
Collection 能使你操作对象组,它位于类集层次结构的顶层。Collection接口是构造类集框架的基础。它声明所有类集都将拥有的核心方法。
一个类集不能直接存储类型int,char,double等的值,如果要使用这些类型,则使用对象,比如new Integer(1)。
常用的使用方法如下:
boolean add(Object obj) 将obj加入到调用类集中。如果obj被加入到类集中了,则返回true;如果obj已经是类集中的一个成员或类集不能被复制时,则返回false boolean addAll(Collection c) 将c中的所有元素都加入到调用类集中,如果操作成功(也就是说元素被加入了),则返回true;否则返回false void clear( ) 从调用类集中删除所有元素 boolean contains(Object obj) 如果obj是调用类集的一个元素,则返回true,否则,返回false boolean containsAll(Collection c) 如果调用类集包含了c中的所有元素,则返回true;否则,返回false boolean equals(Object obj) 如果调用类集与obj相等,则返回true;否则返回false int hashCode( ) 返回调用类集的散列码 boolean isEmpty( ) 如果调用类集是空的,则返回true;否则返回false Iterator iterator( ) 返回调用类集的迭代程序 Boolean remove(Object obj) 从调用类集中删除obj的一个实例。如果这个元素被删除了,则返回true;否则返回false Boolean removeAll(Collection c) 从调用类集中删除c的所有元素。如果类集被改变了(也就是说元素被删除了),则返回true;否则返回false Boolean retainAll(Collection c) 删除调用类集中除了包含在c中的元素之外的全部元素。如果类集被改变了(也就是说元素被删除了),则返回true,否则返回false int size( ) 返回调用类集中元素的个数
List接口
List接口相当于链表,无序、可重复。
ArrayList类
ArrayList类扩展AbstractList并执行List接口。ArrayList支持可随需要而增长的动态数
组。在Java中,标准数组是定长的。在数组创建之后,它们不能被加长或缩短,这也就意
味着你必须事先知道数组可以容纳多少元素。但是,你直到运行时才能知道需要多大的数
组。为了解决这个问题,类集框架定义了ArrayList。本质上,ArrayList是对象引用的一个
变长数组。也就是说,ArrayList能够动态地增加或减小其大小。数组列表以一个原始大小
被创建。当超过了它的大小,类集自动增大。当对象被删除后,数组就可以缩小。
Vector类
Vector实现动态数组。这与ArrayList相似,但两者不同的是:Vector是同步的,并且它
包含了许多不属于类集框架的从以前版本遗留下来的方法。随着Java 2的公布,Vector被重
新设计来扩展AbstractList和实现List接口。如果没有指定增量,在每个分配周期,矢量的大小增一倍。
Stack类
Stack是Vector的一个子类,它实现标准的后进先出堆栈
LinkedList类
LinkedList类扩展AbstractSequentialList并执行List接口。它提供了一个链接列表数据结
构。
显然要理解ArrayList和LinkedList这两种数据结构,可以类比到链表和数组的异同。
前者插入到中间的元素对后面的元素造成了移位,效率低,而后者不需要。例子:
private static void testArrayListandLinkedList(){ long start = System.currentTimeMillis(); List<String> list1 = new ArrayList<String>(); for(int i=0;i<10000;i++){ list1.add(0,"hello"); } long end = System.currentTimeMillis(); System.out.println("start:"+ start + " end:"+end+" time use :"+ (end-start)+"ms"); start = System.currentTimeMillis(); List<String> list2 = new LinkedList<String>(); for(int i=0;i<10000;i++){ list2.add(0,"hello"); } end = System.currentTimeMillis(); System.out.println("start:"+ start + " end:"+end+" time use :"+ (end-start)+"ms"); }
同样都插入到第一个元素,LinkedList的效率高的多:
start:1358144834832 end:1358144834874 time use :42ms
start:1358144834875 end:1358144834877 time use :2ms
Set接口
Set接口相当于集合,无序、不可重复。
SortedSet接口相当于有序的集合,有序、不可重复。SortedSet接口扩展了Set并说明了按升序排列的集合的特性。
J-STL迭代器
1. 通过调用类集的iterator( )方法获得对类集头的迭代函数。
2. 建立一个调用hasNext( )方法的循环,只要hasNext( )返回true,就进行循环迭代。
3. 在循环内部,通过调用next( )方法来得到每一个元素。
boolean hasNext( ) 如果存在更多的元素,则返回true,否则返回false Object next( ) 返回下一个元素。如果没有下一个元素,则引发NoSuchElementException异常 void remove( ) 删除当前元素,如果试图在调用next( )方法之后,调用remove( )方法,则引发IllegalStateException异常 void add(Object obj) 将obj插入列表中的一个元素之前,该元素在下一次调用next( )方法时,被返回 boolean hasNext( ) 如果存在下一个元素,则返回true;否则返回false boolean hasPrevious( ) 如果存在前一个元素,则返回true;否则返回false Object next( ) 返回下一个元素,如果不存在下一个元素,则引发一个NoSuchElementException异常 int nextIndex( ) 返回下一个元素的下标,如果不存在下一个元素,则返回列表的大小 Object previous( ) 返回前一个元素,如果前一个元素不存在,则引发一个NoSuchElementException异常 int previousIndex( ) 返回前一个元素的下标,如果前一个元素不存在,则返回-1 void remove( ) 从列表中删除当前元素。如果remove( )方法在next( )方法或previous( )方法调用之前被调用,则引发一个IllegalStateException异常 void set(Object obj) 将obj赋给当前元素。这是上一次调用next( )方法或previous( )方法最后返回的元素 和C++STL有一个很明显的不同,J-STL不用++和--来移动,而是用next和previous。 Iterator it = l.iterator(); // 获得一个迭代子 while (it.hasNext()) { String s = (String) it.next(); System.out.println(s); }
Map接口
Map接口
映射循环使用两个基本操作:get( )和put( )。使用put( )方法可以将一个指定了关键字和
值的值加入映射。为了得到值,可以通过将关键字作为参数来调用get( )方法。调用返回该
值。正如前面谈到的,映射不是类集,但可以获得映射的类集“视图”。为了实现这种功
能,可以使用entrySet( )方法,它返回一个包含了映射中元素的集合(Set)。为了得到关键
字的类集“视图”,可以使用keySet( )方法。为了得到值的类集“视图”,可以使用values( )
方法。类集“视图”是将映射集成到类集框架内的手段。
SortedMap接口
SortedMap接口扩展了Map,它确保了各项按关键字升序排序。由SortedMap说明的方法总结在表15-7中。当调用映射中没有的项时,其中的几种方法引发一个NoSuchElementException异常。当对象与映射中的元素不兼容时,则引发一个ClassCastException异常。当试图使用映射不允许使用的null对象时,则引发一个NullPointerException异常。
字典(Dictionary)是一个表示关键字/值存储库的抽象类,同时它的操作也很像映射(Map),散列表(Hashtable)是原始java.util中的一部分同时也是Dictionary的一个具体实现。
TreeMap 类
TreeMap类通过使用树实现Map接口。TreeMap提供了按排序顺序存储关键字/值对的有
效手段,同时允许快速检索。应该注意的是,不像散列映射,树映射保证它的元素按照关
键字升序排序。显然,TreeMap类显示出很好的排序优异。
注意对关键字进行了排序。然而,在这种情况下,它们用名字而不是用姓进行了排序。
可以通过在创建映射时,指定一个比较函数来改变这种排序
比较函数
TreeSet和TreeMap都按排序顺序存储元素。然而,精确定义采用何种“排序顺序”的
是比较函数。通常在默认的情况下,这些类通过使用被Java称之为“自然顺序”的顺序存
储它们的元素,而这种顺序通常也是你所需要的(A在B的前面,1在2的前面,等等)。如
果需要用不同的方法对元素进行排序,可以在构造集合或映射时,指定一个Comparator对
象。这样做为你提供了一种精确控制如何将元素储存到排序类集和映射中的能力。
Comparator接口定义了两个方法:compare( )和equals( )。
class MyComp implements Comparator<Object> { public int compare(Object a, Object b) { //String aStr, bStr; //aStr = (String) a; //bStr = (String) b; //return bStr.compareTo(aStr); Integer ai, bi; ai = (Integer) a; bi = (Integer) b; return bi.compareTo(ai); } // no need to override equals } Map<Integer, String> treemap = new TreeMap<Integer, String>(new MyComp());
HashMap 类
HashMap类使用散列表实现Map接口。这允许一些基本操作如get( )和put( )的运行时间
保持恒定,即便对大型集合,也是这样的。