java_集合与泛型
- 格式:doc
- 大小:176.00 KB
- 文档页数:29
Collection 接口及实现类Java 语言的Collection 接口及实现类是在java.util 包中定义的,其中定义了多个接口和类,它们统称为Java 集合框架(Java Collection Framework )。
Java 集合框架由两种类型构成,一个是Collection ,另一个是Map 。
Collection 对象用于存放一组对象,Map 对象用于存放一组关键字/值的对象。
Collection 和Map 是最基本的接口,它们又有子接口,这些接口的层次关系如图1所示。
图1 Java 集合框架的接口继承关系1.1 Collection 接口及操作Collection 接口是所有集合类型的根接口,它有三个子接口:Set 接口、List 接口和Queue 接口。
Collection 接口的定义如下:public interface Collection<E> extends Iterable<E> {// 基本操作int size();boolean isEmpty();boolean contains(Object element);boolean add(E element);boolean remove(Object element);Iterator iterator();// 批量操作boolean containsAll(Collection<?> c);boolean addAll(Collection<? extends E> c);boolean removeAll(Collection<?> c);boolean retainAll(Collection<?> c);void clear();// 数组操作Object[] toArray();<T> T[] toArray(T[] a);}说明 从JDK 1.5开始,Java 开始支持范型(generics )的概念。
在Collection 接口的声明中,<E>就表示该接口支持范型,它指的是集合中的对象类型。
这样,当我们声明一个Collection 实例时,应该使用这种方式指明包含在集合中的对象类型。
这可以使编译器在编译时检查存入集合的对象类型是否正确,从而减少运行时错误。
Collection 接口中定义的方法主要包括三类:集合操作、批量操作和数组操作。
1. 基本操作实现基本操作的方法有size(),它返回集合中元素的个数;isEmpty()方法返回集合是否为空;contains()方法返回集合中是否包含指定的对象;add()方法和remove()方法实现向集合中添加元素和删除元素的功能;iterator()方法用来返回Iterator对象。
通过基本操作可以检索集合中的元素。
检索集合中的元素有两种方法:使用增强的for 循环和使用Iterator迭代对象。
(1)使用增强的for循环使用增强的for循环不但可以遍历数组的每个元素,还可以遍历集合的每个元素。
下面的代码打印集合的每个元素:for (Object o : collection)System.out.println(o);(2)使用迭代器迭代器是一个可以遍历集合中每个元素的对象。
通过调用集合对象的iterator()方法可以得到Iterator对象,再调用Iterator对象的方法就可以遍历集合中的每个元素。
Iterator接口的定义如下:public interface Iterator<E> {boolean hasNext();E next();void remove();}该接口的hasNext()方法返回迭代器中是否还有对象;next()方法返回迭代器中下一个对象;remove()方法删除迭代器中的对象,该方法同时从集合中删除对象。
假设c为一个Collection对象,要访问c中的每个元素,可以按下列方法实现:Iterator it = c.iterator();while (it.hasNext()){System.out.println(it.next());}2. 批量操作实现批量操作的方法有containsAll(),它返回集合中是否包含指定集合中的所有元素;addAll()方法和removeAll()方法将指定集合中的元素添加到集合中和从集合中删除指定的集合元素;retainAll()方法删除集合中不属于指定集合中的元素;clear()方法删除集合中所有元素。
3. 数组操作toArray()方法可以实现集合与数组的转换。
该方法可以实现将集合元素转换成数组元素。
无参数的toArray()方法实现将集合转换成Object类型的数组。
有参数的toArray()方法将集合转换成指定类型的对象数组。
例如,假设c是一个Collection对象,下面的代码将c中的对象转换成一个新的Object 数组,数组的长度与集合c中的元素个数相同。
Object[] a = c.toArray();假设我们知道c中只包含String对象,可以使用下面代码将其转换成String数组,它的长度与c中元素个数相同:String[] a = c.toArray(new String[0]);1.2 Set接口及实现类Set接口是Collection的子接口,Set接口对象类似于数学上的集合概念,其中不允许有重复的元素。
Set接口没有定义新的方法,只包含从Collection接口继承的方法。
Set接口有几个常用的实现类,它们的层次关系如图2所示:图2 Set接口及实现类的层次结构Set接口的常用的实现类有:HashSet类、TreeSet类和LinkedHashSet类。
1. HashSet类与LinkedHashSet类HashSet类是抽象类AbstractSet的子类,它实现了Set接口,HashSet使用哈希方法存储元素,具有最好的性能,但元素没有顺序。
HashSet类的构造方法有:∙HashSet() 创建一个空的哈希集合,装填因子(load factor)是0.75。
∙HashSet(Collection c) 用指定的集合c的元素创建一个哈希集合。
∙HashSet(int initialCapacity) 创建一个哈希集合,并指定的集合初始容量。
∙HashSet(int initialCapacity, float loadFactor) 创建一个哈希集合,并指定的集合初始容量和装填因子。
LinkedHashSet类是HashSet类的子类。
该实现与HashSet的不同之处是它对所有元素维护一个双向链表,该链表定义了元素的迭代顺序,这个顺序是元素插入集合的顺序。
下面的程序从命令行输入若干英文单词,输出每个重复的单词,不同单词的个数及消除重复单词后的列表。
程序FindDups.javaimport java.util.*;public class FindDups {public static void main(String args[]) {Set<String> hs = new HashSet<String>();for (String a : args)if (!hs.add(a))System.out.println("Duplicate: " + a);System.out.println(hs.size()+" distinct words: "+hs);}}_____________________________________________________________________________▃如果使用下面命令运行程序:C:\>java FindDups i came i saw i left会得到下面结果:Duplicate: iDuplicate: i4 distinct words: [i, left, saw, came]由于上面程序中使用的实现类为HashSet,它并不保证集合中元素的顺序。
注意该程序对集合的声明中使用了泛型的方法,即加上了<String>,如果去掉<String>,该程序在JDK 5.0下也能成功编译,但会显示下面的提示:Note: D:\java\FindDups.java uses unchecked or unsafe operations.Note: Recompile with -Xlint:unchecked for details.该提示说明程序中使用了未检查的或不安全的操作,如果要知道详细细节,可以带-Xlint:unchecked参数重新编译该程序。
2. 用集合对象实现集合运算对于Set对象的批量操作方法,可以实现标准集合代数运算。
假设s1和s2是Set对象,下面的操作可实现相关的集合运算。
s1.containAll(s2):如果s2是s1的子集,该方法返回true;s1.addAll(s2):实现集合s1与s2的并运算;s1.retainAll(s2):实现集合s1与s2的交运算;s1.removeAll(s2):实现集合s1与s2的差运算。
为了计算两个集合的并、交、差运算而又不破坏原来的集合,可以通过下面代码实现:Set<Type> union = new HashSet<Type>(s1);union.addAll(s2);Set<Type> intersection = new HashSet<Type>(s1);intersection.retainAll(s2);Set<Type> difference = new HashSet<Type>(s1);difference.removeAll(s2);下面的程序实现了两个集合的并、交、差运算:程序SetDemo.javaimport java.util.*;public class SetDemo {public static void main(String args[]) {Set<String> s1 = new HashSet<String>();Set<String> s2 = new HashSet<String>();s1.add(new String("one"));s1.add(new String("two"));s1.add(new String("three"));s2.add(new String("two"));s2.add(new String("three"));s2.add(new String("four"));Set<String> union = new HashSet<String>(s1);union.addAll(s2);Set<String> intersection = new HashSet<String>(s1);intersection.retainAll(s2);Set<String> difference = new HashSet<String>(s1);difference.removeAll(s2);System.out.println(union);System.out.println(intersection);System.out.println(difference);}}_____________________________________________________________________________▃程序输出结果为:[one,two,foue,three][two,three][one]3. SortedSet接口与TreeSet类SortedSet接口对象是有序对象的集合,其中的元素排序规则按照元素的自然顺序排列。