集合

来源:互联网 发布:北京亿都川女装淘宝店 编辑:程序博客网 时间:2024/06/09 14:24

2. 集合 -core java 7 第2卷

2.1 集合接口

Java类库中的 接口Collection是一种基本的接口. 如下:

public interface Collection<E> {
    boolean add(E element); //添加元素. 添加成功返回true
    Iterator<E> iterator(); //返回迭代器. 该方法来自接口Iterable.
    ... //其它方法
}

其中方法iterator()返回的是迭代器类型. 注意Java中的迭代器和c++容器中的迭代器不同. 它的迭代器
没有"当前元素"这样的概念. 而是"指向元素之间".所以当有3个元素的时候可以有4个迭代器位置.

Iterator接口如下:

public interface Iterator<E> {
    E next();  //返回下一个元素.并后移迭代器. 没有元素时抛出 NoSuchElementException异常
    boolean hasNext();  //是否有下一个元素.
    void remove();  //移除元素. 注意: 这里移除的是上次做next()调用时返回的元素.
                    //例如要remove第一个元素.则要先要iter.next()再iter.remove().
}

使用迭代器遍历容器的例子:
Collection<String> c = ....;
Iterator<String> iter = c.iterator();
while (iter.hasNext())
{
    String s = iter.next();
    //...
}
不过从Java1.5开始. 为遍历容器提供了一种"for each"缩写形式:
for (String s : c)  //要求c是实现了Iterable接口(即有iterator()方法)的对象
{
    //...
}


Collection接口还声明了下边的方法:
    boolean add(E o) //添加失败时返回false
    boolean addAll(Collection<? extends E> c)
    void clear()  //移除所有元素
    boolean contains(Object o) //包含指定的元素o则返回 true
    boolean containsAll(Collection<?> c) 
    boolean equals(Object o) //比较此 collection 与指定对象是否相等
    int hashCode() //返回此 collection 的哈希码值
    boolean isEmpty() //如果此 collection 不包含元素则返回 true
    Iterator<E> iterator() //返回迭代器
    boolean remove(Object o) //移除指定元素的单个实例, 移除失败则返回false
    boolean removeAll(Collection<?> c)
    boolean retainAll(Collection<?> c) //只保留它与c的交集.
    int size() //返回个数.
    Object[] toArray() //返回包含此 collection 中所有元素的数组
    <T> T[] toArray(T[] a) //返回的数组的运行时类型与指定数组的运行时类型相同

这个接口的方法比较多. 所以提供了一个抽象类 AbstractCollection. 具体的集合类可以从该类继承.

2.2 具体的集合

2.2.1 链表

List接口
public interface List<E> extends Collection<E>
实现该接口的类包括 LindedList, ArrayList, Stack, Vector
它从Collection接口增加的方法有:
    void add(int index, E element) //指定位置插入element
    boolean addAll(int index, Collection<? extends E> c)  //指定位置上插入c所有元素
    E get(int index) //返回指定位置的元素
    int indexOf(Object o) //返回首次出现指定元素的索引,找不到则返回 -1
    int lastIndexOf(Object o) //返回最后出现指定元素的索引找不到则返回 -1
    ListIterator<E> listIterator()  //返回ListIterator
    ListIterator<E> listIterator(int index) //返回起始位置为index的ListIterator
    E remove(int index) //移除指定位置的元素(可选操作)。
    boolean remove(Object o) //移除元素o的首次出现
    boolean removeAll(Collection<?> c) //移除c中包含的所有元素
    boolean retainAll(Collection<?> c) //仅保留c中所包含的元素
    E set(int index, E element) //用element替换指定位置的元素
    List<E> subList(int fromIndex, int toIndex) //返回子序列

注意listIterator()方法返回的是ListIterator类型的迭代器.
ListIterator是接口. 如下:
public interface ListIterator<E> extends Iterator<E>
它扩展了Iterator接口. 增加了下边几个方法:
    boolean hasPrevious()  //是否有前一个元素.
    E previous()  //返回前一个元素.
    int nextIndex()  //返回下一次next()返回的元素的索引.
    int previousIndex()  //返回下一次previousIndex()返回的元素的索引.
    void remove()   //移除上次调用next()或previousIndex()返回的元素.
    void set(E o)  //用o替换上次调用next()或previousIndex()返回的元素
注意其中的remove()和set()方法, 它们删除或替换的元素根据迭代器上次是前进还是后退而不同.

LinkedList类
public class LinkedList<E> extends AbstractSequentialList<E>
         implements List<E>, Queue<E>, Cloneable, Serializable
它除了实现接口List中的方法外还提供了:
    void addFirst(E o) //插入o到表头
    void addLast(E o) //插入o到表尾
    E getFirst() //返回表尾
    E getLast()  //返回表头
    此外还有Queue(队列)接口声明的几个方法:
    E element()  //返回队列的头
    boolean offer(E o) //插入队列尾部
    E peek()  //返回队列的头, 若队列为空则返回null
    E poll() //返回并移除队列的头,若队列为空则返回null
    E remove()  //返回并移除队列的头


2.2.2 数组列表 ArrayList类

该类也实现了List接口, 它封装了一个大小可变的对象数组. 所以可以高效的随机访问.
让它扩展RandomAccess接口(该接口没有方法而只是用来标识)来表明它可以快速随机访问.
用ArrayList代替Vector的原因是.Vector的所有方法都是同步的(效率低一些). 而ArrayList不是.

class ArrayList<E> extends AbstractList<E>
     implements List<E>, RandomAccess, Cloneable, Serializable

它的方法除了List接口声明的那些方法外还有:
void ensureCapacity(int minCapacity)   //指定容量的最小值.(容量也可以在构造方法中指定.)
void trimToSize()   //将容量调整为当前size()的大小.

2.2.3 Set

Set是没有重复元素的一种集合.
常见的. set有两种实现. 一种是哈希表实现的(元素是无序的). 一种是2叉树实现的(要求元素可比较大小).
它们在Java.util库中对应 HashSet 和 TreeSet 两个类. 两个类都实现了接口Set.

Set 接口
interface Set<E> extends Collection<E>
该接口并没有从Collection中添加新的方法.
虽然没有添加新方法. 但它们是不同的接口. 例如有方法
void fun(Set<int> s)
这就清楚的说明参数要一个Set对象而不是其它的Collection对象.


HashSet类
在需要快速搜索的时候需要使用散列表. 散列表为每个对象计算一个整数(散列码).
计算散列码的方法是hashCode(). 如果a.equals(b)为true, 则a和b的散列码要相同.

class HashSet<E>extends AbstractSet<E>
     implements Set<E>, Cloneable, Serializable
构造方法:
    HashSet() //空集合,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75。
              // 加载因子决定当其中的元素越来越多时.何时对散列表进行再散列.
    HashSet(Collection<? extends E> c) //构造的集合包含c的元素.
    HashSet(int initialCapacity) //指定初始容量. 加载因子为默认的(0.75)。
    HashSet(int initialCapacity, float loadFactor) //指定初始容量和加载因子.
其它方法:
    Set接口中声明的那些方法.


2.2.4 TreeSet类

TreeSet是用红黑树实现的Set.
class TreeSet<E> extends AbstractSet<E>
     implements SortedSet<E>, Cloneable, Serializable

它的构造方法:
    TreeSet() //构造一个set, 其元素按元素的自然顺序排序(即要求元素的类实现了Comparable接口).
    TreeSet(Collection<? extends E> c) //构造的set包含 c 中的元素
                          //元素的排序用的也是自然顺序(即要求元素的类实现了Comparable接口).
    TreeSet(Comparator<? super E> c) // 构造TreeSet时指定了排序时用的比较器.
                                     // 比较器实现了Comparator接口.该接口声明了方法
                                     //   int compare(T a, T b).
    TreeSet(SortedSet<E> s) //让新set包含的元素与指定的已排序 set 包含的元素相同
                        //并按照相同的顺序对元素进行排序
其它方法:
    包括Set接口中声明的: add() / addAll() / clear() / contains() / isEmpty() /
                       iterator() / remove() / size() 
    以及SortedSet接口(它扩展Set接口)所添加的下列方法:
    Comparator<? super E> comparator()  //返回排序用的比较器.
                                        //若没指定比较器则返回null(即按自然顺序排序).
    E first()  //返回SortedSet中第一个(即最小的)元素
    E last()   //返回SortedSet中最后一个(即最大的)元素
    SortedSet<E> headSet(E toElement) //返回子集. 此子集Set的元素都小于参数toElement.
    SortedSet<E> tailSet(E fromElement)//返回子集. 此子集Set的元素都大于等于fromElement
    SortedSet<E> subSet(E fromElement, E toElement) //返回子集.
                 //此子集Set的元素大于等于fromElement, 小于toElement.


2.2.5 优先级队列 PriorityQueue

优先级队列是用最小堆实现的集合. 用来方便的找到其中最小的元素.
因为要比较元素之间的大小.所以其中的元素的类需要实现Comparable接口.或者构造集合时指定一个比较器.
class PriorityQueue<E> extends AbstractQueue<E> implements Serializable

构造方法:
    PriorityQueue() //用默认的初始容量(11)构造,
                    //比较大小时用自然顺序(要求元素的类实现Comparable接口)
    PriorityQueue(Collection<? extends E> c) //创建的新的优先级队列中包含c的元素.
    PriorityQueue(PriorityQueue<? extends E> c) //同上
    PriorityQueue(SortedSet<? extends E> c)  //同上
    PriorityQueue(int initialCapacity) //指定初始的容量
    PriorityQueue(int initialCapacity, Comparator<? super E> comparator)
                             //指定了初始容量和比较器
其它方法:
    boolean add(E o) 
    void clear()
    int size()
    Iterator<E> iterator()
    boolean remove(Object o) //移除指定元素的单个实例(若其存在)
    Comparator<? super E> comparator() //返回比较器.若没有指定比较器则返回null.
    boolean offer(E o) //插入o
    E peek() //查看(但不会移除)队列的头,如果此队列为空则返回 null
    E poll() //查看并移除此队列的头,如果此队列为空则返回 null
 

2.2.6 映射表 Map

映射表 Map 用来表示键值对的集合. 通常有两种实现: HashMap 类和 TreeMap 类. 它们扩展自Map接口.
而Map接口却没有扩展自Collection接口. 因为Collection接口不适合操作键值对.

先看看Map接口:
interface Map<K,V>
其中有一个嵌套接口:
    static interface Map.Entry<K,V>
    这个接口描述的是键值对.方法有getKey() / getValue() / setValue()

Map接口的方法如下:
    void clear() 
    boolean isEmpty()
    int size()
    int hashCode()
    boolean equals(Object o)
    V get(Object key) //返回此映射中映射到指定键的值。
    V put(K key, V value) //插入一个键值对(key, value)
    V remove(Object key) //移除key键对应的键值对
    void putAll(Map<? extends K,? extends V> t) //插入t中包含的所有键值对
    boolean containsKey(Object key) //是否包含键key
    boolean containsValue(Object value) //是否包含值value(一个value值可以对应多个键)
    Set<K> keySet() //返回此映射中包含的键的 set 视图。
    Collection<V> values() //返回map中值的 collection 视图。
    Set<Map.Entry<K,V>> entrySet() //返回map中包含的键值对的 set 视图。


HashMap 类
它用一个散列表来实现. 根据键的hash()值来确定元素的位置.
class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable

构造方法:
    HashMap() //默认初始容量(即桶)(16) 和默认加载因子(0.75)
    HashMap(int initialCapacity) //指定初始容量
    HashMap(int initialCapacity, float loadFactor) //指定初始容量和加载因子
    HashMap(Map<? extends K,? extends V> m) //构造一个映射关系与指定 Map 相同的 HashMap
其它方法:
    实现Map接口所声明的方法.


TreeMap类
它用红黑树来实现. 它的插入等操作要求键之间可以比较大小. 所以键要实现 Comparable 接口. 或者
被指定的比较器所接受(如 comparator.compare(k1, k2) ).
class TreeMap<K,V> extends AbstractMap<K,V>
       implements SortedMap<K,V>, Cloneable, Serializable

其中 SortedMap接口 为:
    interface SortedMap<K,V> extends Map<K,V>
它比Map接口添加了下边几个方法:
    Comparator<? super K> comparator() //返回比较器,若无则返回 null。
    K firstKey() //返回当前第一个(最小的)键
    K lastKey()  //返回当前最后一个(最大的)键
    SortedMap<K,V> headMap(K toKey) //返回部分视图,其键值小于 toKey
    SortedMap<K,V> tailMap(K fromKey) //返回部分视图,其键大于等于 fromKey
    SortedMap<K,V> subMap(K fromKey, K toKey) //返回部分视图,
                     //其键值大于等于fromKey 小于toKey

所以 TreeMap类 的方法就是 Map接口 和 SortedMap接口 声明的那些方法.
此外TreeMap的构造方法有:
    TreeMap() 
    TreeMap(Comparator<? super K> c) //指定比较器
    TreeMap(Map<? extends K,? extends V> m) //新TreeMap中包含m的所有元素(即键值对)
                                            //排序则是按自然顺序进行排序
    TreeMap(SortedMap<K,? extends V> m) //新TreeMap中包含m的所有元素(即键值对)
                                        //排序和m的排序方式一样
 

2.3.3 集合和数组的转换

要将一个数组转换为集合. 使用java.util.Arrays类的静态方法:
    static <T> List<T> asList(T... a)
    //它返回的是数组a的List视图. 所以返回的list的长度是不可以改变的(改变则抛异常).
    //有时想创建固定长度的 List 对象. 则可以用该方法简便的来实现:
    //  List<String> l = Arrays.asList("abc" , "de", "f");
    // 另外. Arrays类还提供了其它静态方法.用来支持数组的排序 / 填充 / 2叉搜索 / 比较相等 .

要将集合转换为一个Java数组. 使用 Collection接口 中声明的方法:
    <T> T[] toArray(T[] a)
    //其中返回的数组类型和参数a的类型一样. 
    //若参数a的数组大小能够容纳该Collection的所有元素.
    //则将集合的所有元素放入a. 若a还有剩余空间. 则再多放一个null. 再返回a.
    //否则若参数a的大小小于集合的元素数. 将会分配一个新的数组并放入元素后返回.


2.4 算法

对于数组. Arrays类中提供了一些静态方法来支持 排序 / 填充 / 2叉搜索 等.
对于集合. Collections类也提供了一些静态方法来支持各种算法.

static <T> boolean addAll(Collection<? super T> c, T... a) //将a的元素添加c中
static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key)
          //2分搜索. 要求list已排序. 而且list的元素要实现Coparable接口.
          //若list不是"随机访问"的. 则本算法如何?
static <T> int binarySearch(List<? extends T> list,T key,Comparator<? super T> c)
          //2分搜索. 要求list已排序. 比较时将使用参数中指定的比较器c来比较元素.
static <T> void copy(List<? super T> dest, List<? extends T> src)
          //复制. 将src的所有元素复制到dest. 要求dest有足够的长度容纳这些元素.
static boolean disjoint(Collection<?> c1, Collection<?> c2)
          //是否c1和c2没有相同的元素
static <T> List<T> emptyList() //返回空的列表(不可变的)。
static <K,V> Map<K,V>  emptyMap() //返回空的映射(不可变的)。
static <T> Set<T>  emptySet() //返回空的 set(不可变的)。
static <T> Enumeration<T> enumeration(Collection<T> c) //返回参数c 上的枚举。
static <T> void fill(List<? super T> list, T obj) //用obj填充(替换)list上的所有元素.
static int frequency(Collection<?> c, Object o) //统计c中有多少个o?
static int indexOfSubList(List<?> source, List<?> target)
          //返回子序列target在序列source中的第一次出现的位置.若无则返回-1
static int lastIndexOfSubList(List<?> source, List<?> target)
          //返回子序列target在序列source中的最后一次出现的位置.若无则返回-1
static <T> ArrayList<T> list(Enumeration<T> e)
          //将一个Enumeration转换为一个ArrayList.
static <T extends Object & Comparable<? super T>> T
       max(Collection<? extends T> coll) //返回集合coll中的最大元素. 
static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp)
          // 返回集合coll中的最大元素. 比较时使用参数提供的比较器comp
static <T extends Object & Comparable<? super T>> T
       min(Collection<? extends T> coll)   //返回集合coll中的最小元素.
static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp)
          // 返回集合coll中的最小元素. 比较时使用参数提供的比较器comp
static <T> List<T> nCopies(int n, T o) //返回一个不可修改的List. 元素由n个o组成.
static <T> boolean replaceAll(List<T> list, T oldVal, T newVal)
          //用newVal替换list中的oldVal
static void reverse(List<?> list) //反转
static <T> Comparator<T> reverseOrder()
          //返回一个相反的比较器. 使用它比较时的结果和用compareTo()方法比较的结果相反.
          //例如若有 String[] a = ... 要对a进行反序排序. 可以:
          // Arrays.sort(a, Collections.reverseOrder());
static <T> Comparator<T> reverseOrder(Comparator<T> cmp)
          //返回一个比较器,用它比较时的结果和用参数cmp比较的结果相反.
static void rotate(List<?> list, int distance)
          //list的所有元素循环移动distance个位置(最后的将移动到开头).
static void shuffle(List<?> list) //对list洗牌.
                   //若list不是随机访问的则会先复制到一个数组中来洗牌.
static void shuffle(List<?> list, Random rnd) //洗牌. rnd为指定的随机源.
static <T> Set<T> singleton(T o) //返回的set对象不可改变. 且只包含唯一的元素o.
static <T> List<T> singletonList(T o) //返回的list对象不可改变.且只包含唯一的元素o.
static <K,V> Map<K,V> singletonMap(K key, V value)
            //返回的Map对象不可改变. 且只包含唯一的一组映射(key, value).
static <T extends Comparable<? super T>> void sort(List<T> list) //升序排序
static <T> void sort(List<T> list, Comparator<? super T> c)
          //排序. 指定了比较器.
static void swap(List<?> list, int i, int j) //交换list中位置i和位置j上的元素.
static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c)
          //返回 c 的不可修改视图
static <T> List<T> unmodifiableList(List<? extends T> list)
          //返回 list 的不可修改视图
static <K,V> Map<K,V> unmodifiableMap(Map<? extends K,? extends V> m)
          //返回 m 的不可修改视图
static <T> Set<T> unmodifiableSet(Set<? extends T> s)
          //返回 s 的不可修改视图
static <K,V> SortedMap<K,V> unmodifiableSortedMap(SortedMap<K,? extends V> m)
          // 返回 m 的不可修改视图
static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s)
          //返回 s 的不可修改视图


2.5 遗留下来的集合

Hashtable类. 作用和HashMap一样. 接口也一样. 但它的方法是同步的.
Enumeration 接口. 它的作用和现在用的Iterator接口类似.
Vector类. 和ArrayList类的区别是它的方法是同步的.
Stack类. 继承自Vector类.
BitSet类. 用来方便的位操作.

 

原创粉丝点击