Java核心编程六:集合与泛型算法

来源:互联网 发布:windows优化大师v7.99 编辑:程序博客网 时间:2024/06/11 06:35
1 集合接口
Java中将集合的接口和实现进行了分离,这样当你希望变更设计时,只需要调整构造器地方即可。如果希望自行实现相关的集合,即只需要扩展自以Abstract开头的类即可。

Collection<T>是所有集合类的根接口,下面继承了Set,List,Map,Queue,SortedSet,SortedMap等一系列的接口。其声明了各种实用的方法,实现类都必须实现这些方法。如isEmpty(),contains(obj),add(),remove(),clear()等等。
Iterator<T>实现了遍历集合的方式,通过hasNext()及next()可以访问集合的各个元素。应该将迭代器看成是位于元素之间的,当调用next方法时,迭代器越过一个元素,并返回这个元素的引用。在jdk5之后,可以通过foreach的方法方便的遍历集合。

util.Collection<T>接口:
Iterator<T> iterator() 返回访问的迭代器
int size()             返回容器大小
bool isEmpty()         返回是否空
bool contains(Object o)
bool containsAll(Collection<?> other)
bool add(object o)/remove()
bool addAll(Collection<? extends E> other)/removeAll()
bool clear()
bool retainAll(Collection<?> other) 集合交集运算
Object[] toArray()

util.Iterator<T>类:
bool hasNext()
T next()
void remove()


2 具体集合

2.1 LinkedList
Java的LinkedList实际上是双重链表。

为了配合List的使用,标准库提供了ListIterator类,其对象可以通过在集合容器上调用listIterator()方法来获取。然后通过功能增加的迭代器来实现更多的操作。
util.List<T>类:
void add(int i,T item) 在指定位置添加新元素
void addAll(int i,Collection<? extends E> c)
T remove(int i)  删除指定位置元素
T set(int i,T item)  设置指定位置元素
int indexOf(Object item) 返回元素的索引位置
ListIterator<T> listIterator() 返回一个List迭代器。

util.ListIterator<T>类
void add(T item)  在当前位置插入元素
void set(T item)  设置当前位置的元素值
bool hasPrevious()
T previous()  前身遍历元素

util.LinkedList<T>类:
void addFirst(T item)
void addLast(T item)
T getFirst()
T getLast()
T removeFirst()
T removeLast()

2.2 ArrayList
一种采用了顺序存储的数据结构,实现了List的接口,它封装了一个动态再分配的对象数据。
Java中的Vector也封装了动态数组,但其接口是synchronized,支持多线程访问,因此如果代码不需要同步,则使用ArrayList可获得更好的性能。

2.3 HashSet
如果不关注存储位置,且关注快速查找,则可以使用Set,HashSet实现了Set的接口。
其结构如下:

如果散列中放的太满,就需要进行再散列,而原始散列将被弃用。加载因子将决定何时会对散列表进行再散列。通常让加载因子保持在0.75左右。其构造函数如下:
Hashset(Collection<? extends T> elements)
HashSet(int initCapacity)
HashSet(int initCapacity,float loadFactor)
2.4 TreeSet
TreeSet实现了SortedMap接口,比HashSet增加了排序的功能,当从此集合进行迭代时,将从中读出顺序的结果。插入到其中的元素需要实现Comparable<T>接口,类似于C++必须重载==运算符。当然也可以给TreeSet传递一个比较器Comparator,用来比较其中的元素。
2.5 PriorityQueue
采用堆的数据结构,只保持堆顶是最值,并不关注所有元素的排序。其比较方法和TreeSet相同。
2.6 Map
Java提供了HashMap和TreeMap,前者都实现了Map的接口,后者实现了SortedMap的接口。其使用和C++都类似。Map<K,V>其接口如下:
V get(K key)
V put(K key,V value)
bool containsKey(obj)/containsValue(obj)
Set<Entry<K,V>> entrySet() 返回Map中的K/V集合
Set<K> keySet() 返回键集
Collection<V> values() 返回值集

类似于C++的pair<K,V>,Entry<K,V>的接口如下:
K getKey()
V getValue()
V setValue(V val)
2.7 特殊容器
2.7.1 WeakHashMap
对于上面介绍到的集合类,其中的元素必须由程序员来关注进行资源回收,垃圾回收器不支持自动处理其中的元素。除非对整个集合的引用计数为0。
WeakHashMap可以解决这个问题,当其中的元素只存在本集合唯一引用时,将启用垃圾回收器进行资源的回收。
WeakHampMap(int initCapacity,float loadFactor)

2.7.2 LinkedHashSet与LinkedHashMap
这两个Hash容器可以记住你插入元素项的顺序。

我们可以在构造时,设定容器支持按访问顺序进行排序,这样在每次访问时,将最近访问的元素放到链表的尾部,此此可方便实现缓存局部化的应用。
LinkedHashMap(int initCapacity,float loadFactor,bool accessOrder)
2.7.3 EnumSet与EnumMap
EnumSet是一个包含枚举类型元素的集合,内部使用位序列来实现的。它没有公共构造器,只能用静态工厂方法来构建。
allOf(Class enumT)
range(enumT.start,enumT.end)

EnumMap是键类型为枚举类型的映射表。

3 集合框架
接口继承关系图

Collection提供集合操作的接口,如add(),get()等,Map提供了<k,v>的操作接口,必须按k来获取元素。
RandomAccess提供了一个可随机访问的集合接口,但其没有任何接口。像ArrayList或Vector等会实现此接口,它提供了判断一个集合是否可支持随机高性能访问的能力instanceof。

实现类关系图


3.1 视图和包装器
3.1.1 视图
例如Map接口的keySet()方法返回一个Set接口的类的对象,同时此类的方法将对源Map对象数据进行操作,这种集合称为视图。
而Array类,有一个asList方法,它返回一个包装Java数组一List包装器,其也是一个视图对象,可以通过List接口来访问底层的数组数据,这个方法可以让你将数组传递给期望得到列表或集合参数的方法。
3.1.2 范围视图
集合也支持部分范围的视图,如List的subList(),Set的subSet(),Map的subMap()接口可以只返回部分元素的视图。
3.1.3 只读视图
集合也可返回一个只读的视图,unmodifiableCollection/List/Set/SortedSet/Map/SortedMap,如果在返回的对象上调用了修改器,则会返回异常。
需要注意的是,视图只是包装了接口,所以只能访问接口中的方法。
3.1.4 同步视图
Collection的静态方法,synchronizedMap()可将Map转换为具有同步方法的Map。支持多线程上访问,但最好使用util.concurrent中定义的集合来实现并发。
3.1.5 检测视图
Collection.checkedList()可以返回一个类型绑定的列表,当插入类型不满足时将抛出异常。
3.1.6 接口
Collections类提供了一系统的静态方法用来返回相关的视图。
以下接口返回一个只读集合
static <T> Collection unmodifiableCollection(Collection<T> c) 
static <T> List unmodifiableList(List<T> c) 
static <T> Set unmodifiableSet(Set<T> c) 
static <T> SortedSet unmodifiableSortedSet(SortedSet<T> c) 
static <k,v> Map unmodifiableMap(Map<K,V> c)
static <k,v> SortedMap unmodifiableSortedMap(SortedMap<K,V> c)
以下接口返回一个同步集合
static <T> Collection<T> synchronizedCollection(Collection<T> c)
static <T> List synchronizedList(List<T> c)
static <T> Set  synchronizedSet(Set<T> c) 
static <T> SortedSet  synchronizedSortedSet(SortedSet<T> c) 
static <k,v> Map  synchronizedMap(Map<K,V> c)
static <k,v> SortedMap  synchronizedSortedMap(SortedMap<K,V> c)
以下接口返回一个检查的集合
static <T> Collection<T> checkedCollection(Collection<T> c)
static <T> List  checkedList(List<T> c)
static <T> Set   checkedSet(Set<T> c) 
static <T> SortedSet   checkedSortedSet(SortedSet<T> c) 
static <k,v> Map   checkedMap(Map<K,V> c)
static <k,v> SortedMap  checkedSortedMap(SortedMap<K,V> c)

static <T> List<T> asList(T... array)  返回普通数组的集合视图,只可修改,不可改变大小
以下接口返回各集合的范围视图
List<T> subList(int fist,int end) 
SortedSet<T> subSet(T first,T end)
SortedSet<T> headSet(T first)
SortedSet<T> tailSet(T first)

SortedMap<K,V> subMap(T first,T end)
SortedMap<K,V> headMap(T first)
SortedMap<K,V> tailMap(T first)

3.2 批操作
retainAll()  求交集
removeAll()  求差集
addAll       求并集

3.3 集合与数组转换
集合提供了一个接口,可以返回指定类型的数组
<T> T[] toArray(T[] array) 检查数组参数,如果容量足够,则将集合元素加到数组中,并加一个null结束符。如果数组没有足够的空间,则创建一个新数组,其类型与输入数组相同,并将集合的各元素填入数组。
4 泛型算法
泛型集合接口具体一个很大的优点,即算法只需要实现一次。例如一个排序算法,可以作用于不同类型的可比较的集合。C++标准库算法比较强大,Java中暂时还没有那么多的算法。
util.Collections算法API如下
排序算法:
static <T extends Comparable<? super T>> void sort(List<T> s)
static <T> void sort(List<T> elements,Comparator<? super T> c)
混合算法:
static void shuffle(List<?> elements)
static void shuffle<List<?> elements,Random r)
查找算法:
static <T extends Comparable<? super T>> int binarySearch(List<T> elements,T key)
static <T> int binarySearch(List<T> elements , T key, Comparator<? super T> c)
其他算法:
static <T extends Comparable<? super T>> T min(Collection<T> elements);
static <T extends Comparable<? super T>> T max(Collection<T> elements);
static <T> min(Collection<T> elements,Comparator<? super T> c)
static <T> max(Collection<T> elements,Comparator<? super T> c)
static <T> void copy(List<? super T> to,List<T> from) 元素复制
static <T> void fill(List<? super T> lst, T value)
static <T> bool addAll(Collection<? super T> c,T...values)
static <T> bool replaceAll(List<?> lst,T old,T newV)
static int indexOfSubList(List<?> lst,List<?> s)
static int lastIndexOfSubList(List<?> lst,List<?> s)
static void swap(List<?> lst,int i ,int j)
static void reverse(List<?> lst)
static int frequency(Collection<?> lst,Object o)
这里得到的启示是,如果你编写了一个返回集合的方法,返回一个接口而不是一个类可以获得更好的灵活性。

5 遗留集合
下面这些类是Java出现后就存在的容器。

5.1 Hashtable
Hashtable与HashMap拥有同样的接口。不再详细说明。
遗留集合使用Enumeration接口来遍历元素序列。
下面两个Hashtable的接口返回两个Enum对象,以供遍历。
Enumeration<K> keys()   
Enumeration<V> elements()

Enumeration有两个方法,可像迭代器一样访问元素
bool hasMoreElements()
T nextElement()

5.2 Vector
Enumeration<T> elements();

5.3 Properties
属性集是一个映射表,其主要用于处理KV形式的配置文件。
其k和v都是字符串,可以方便的序列化和反序列化。
Properties()
String getProperty(String key)
void load(InputStream in)
void store(OutputStream out,String comment)

5.4 Stack
T push(T item)
T pop()
T peek()

5.5 BitSet
int length()
bool get(int idx)
void set(int idx)
void clear(int idx)
void and(BitSet o)
void or(BitSet o)
void xor(BitSet o)

原创粉丝点击