Javaのコレクション(案)

コレクションの詳細については、推奨されるJavaコレクションシリーズを、以下では、トップのブログの概要はありません


  • リンクリストのセット、キュー、スタック、配列、マッピング:Javaは、キットであって、共通のデータ構造を提供するJavaのコレクションです
  • Javaの各セットは、配列要素と容器の性質と同じであるが、固定長の配列は、可変長のセット
  • セットの要素が記憶されなければならない参照データ型を、データ型がプリミティブにすることはできません

Javaのコレクションフレームワークツールキットマップ:
画像

簡略化した図:
画像

コレクション(インタフェース)

画像
コレクションは、基本的な操作とプロパティのセットを含むインターフェース、高度に抽象的集合です。

基本的なAPIのコレクションインタフェース

abstract boolean         add(E object)
abstract boolean         addAll(Collection<? extends E> collection)
abstract void            clear()
abstract boolean         contains(Object object)
abstract boolean         containsAll(Collection<?> collection)
abstract boolean         equals(Object object)
abstract int             hashCode()
abstract boolean         isEmpty()
abstract Iterator<E>     iterator()
abstract boolean         remove(Object object)
abstract boolean         removeAll(Collection<?> collection)
abstract boolean         retainAll(Collection<?> collection)
abstract int             size()
abstract <T> T[]         toArray(T[] array)
abstract Object[]        toArray()

便宜上、Collectionインタフェースのメソッドのほとんどを実装AbstractCollection抽象クラスを抽象化。
したがって、コレクションの実装クラスは、反復符号化によって分配抽象クラスを継承することができます

その2本の主要な枝は、次のとおりです。リスト設定は、ここでも、これら2つのインターフェイスが、独自の抽象クラスを持っています




一覧(インタフェース)

キューが注文され、Collectionインタフェースを継承、また配列としても知られています。

各要素はインデックス0及び1で始まり昇順でインデックスを持つリスト、それが正確に制御され、リストの各要素にアクセスすることができます。

そして、リストの要素が重複することができ、異なるセット

既存のAPIに加えて、コレクション、追加は以下のとおりです。

abstract void                add(int location, E object)
abstract boolean             addAll(int location, Collection<? extends E> collection)
abstract E                   get(int location)
abstract int                 indexOf(Object object)
abstract int                 lastIndexOf(Object object)
abstract ListIterator<E>     listIterator(int location)
abstract ListIterator<E>     listIterator()
abstract E                   remove(int location)
abstract E                   set(int location, E object)
abstract List<E>             subList(int start, int end)


配列リスト

ArrayListのは、キューの配列に対応する、ダイナミックアレイ配列内のJavaと比較して、その容量を動的に成長することができます。

それは、AbstractListを継承するインタフェースである実装しています。

  1. ランダムアクセスを提供RandmoAccessインターフェース
  2. Cloneableインタフェース、クローニングされ
  3. Serializable接口,支持序列化,能序列化传输

ArrayList的API

boolean             add(E object)
boolean             addAll(Collection<? extends E> collection)
void                clear()
boolean             contains(Object object)
boolean             containsAll(Collection<?> collection)
boolean             equals(Object object)
int                 hashCode()
boolean             isEmpty()
Iterator<E>         iterator()
boolean             remove(Object object)
boolean             removeAll(Collection<?> collection)
boolean             retainAll(Collection<?> collection)
int                 size()
<T> T[]             toArray(T[] array)
Object[]            toArray()
void                add(int location, E object)
boolean             addAll(int location, Collection<? extends E> collection)
E                   get(int location)
int                 indexOf(Object object)
int                 lastIndexOf(Object object)
ListIterator<E>     listIterator(int location)
ListIterator<E>     listIterator()
E                   remove(int location)
E                   set(int location, E object)
List<E>             subList(int start, int end)
Object              clone()
void                ensureCapacity(int minimumCapacity)
void                trimToSize()
void                removeRange(int fromIndex, int toIndex)

ArrayList数据结构是数组结构,默认容量大小是10,当容量不够的时候会自动扩容,新的容量=(原始容量*3)/2 + 1

ArrayList最大的特点:查找快增删慢

ArrayList遍历方式
  1. 通过迭代器遍历
Integer value = null;
Iterator iter = list.iterator();
while (iter.hasNext()) {
    value = (Integer)iter.next();
}
  1. 通过for循环遍历
Integer value = null;
for (Integer integ:list) {
    value = integ;
}
  1. 通过随机访问索引值遍历
Integer value = null;
int size = list.size();
for (int i=0; i<size; i++) {
    value = (Integer)list.get(i);        
}

遍历ArrayList时,使用随机访问遍历效率最高,其次是for遍历,使用迭代器效率最低


Vector

Vector 是矢量队列,有相关增删改查等功能

和ArrayList不同,Vector中的操作是线程安全

它继承于AbstractList,实现了的接口有:

  1. RandmoAccess,提供了随机访问功能
  2. Cloneable接口,能被克隆
  3. Serializable接口,支持序列化,能序列化传输

Vector的API

synchronized boolean        add(E object)
             void           add(int location, E object)
synchronized boolean        addAll(Collection<? extends E> collection)
synchronized boolean        addAll(int location, Collection<? extends E> collection)
synchronized void           addElement(E object)
synchronized int            capacity()
             void           clear()
synchronized Object         clone()
             boolean        contains(Object object)
synchronized boolean        containsAll(Collection<?> collection)
synchronized void           copyInto(Object[] elements)
synchronized E              elementAt(int location)
             Enumeration<E> elements()
synchronized void           ensureCapacity(int minimumCapacity)
synchronized boolean        equals(Object object)
synchronized E              firstElement()
             E              get(int location)
synchronized int            hashCode()
synchronized int            indexOf(Object object, int location)
             int            indexOf(Object object)
synchronized void           insertElementAt(E object, int location)
synchronized boolean        isEmpty()
synchronized E              lastElement()
synchronized int            lastIndexOf(Object object, int location)
synchronized int            lastIndexOf(Object object)
synchronized E              remove(int location)
             boolean        remove(Object object)
synchronized boolean        removeAll(Collection<?> collection)
synchronized void           removeAllElements()
synchronized boolean        removeElement(Object object)
synchronized void           removeElementAt(int location)
synchronized boolean        retainAll(Collection<?> collection)
synchronized E              set(int location, E object)
synchronized void           setElementAt(E object, int location)
synchronized void           setSize(int length)
synchronized int            size()
synchronized List<E>        subList(int start, int end)
synchronized <T> T[]        toArray(T[] contents)
synchronized Object[]       toArray()
synchronized String         toString()
synchronized void           trimToSize()

Vector的数据结构和ArrayList差不多,默认容量大小是10,当容量不够的时候会自动扩容,若容量增加系数 >0,则将容量的值增加“容量增加系数”;否则,将容量大小增加一倍

Vector遍历方式
  1. 通过随机访问遍历
Integer value = null;
int size = vec.size();
for (int i=0; i<size; i++) {
    value = (Integer)vec.get(i);        
}
  1. 通过Enumeration遍历
Integer value = null;
Enumeration enu = vec.elements();
while (enu.hasMoreElements()) {
    value = (Integer)enu.nextElement();
}
  1. 通过for循环遍历
Integer value = null;
for (Integer integ:vec) {
    value = integ;
}
  1. 通过迭代器循环遍历
Integer value = null;
int size = vec.size();
for (int i=0; i<size; i++) {
    value = (Integer)vec.get(i);        
}

遍历Vector时,使用随机访问遍历效率最高,使用迭代器效率最低


LinkedList

LinkedList 是一个双向链表,也可以被当作堆栈队列双端队列

它继承于AbstractSequentialList,实现了的接口有:

  1. List接口,能进行队列操作
  2. Deque接口,既能当作双端队列使用
  3. Cloneable接口,能被克隆
  4. Serializable接口,支持序列化,能序列化传输

LinkedList的API

boolean             add(E object)
void                add(int location, E object)
boolean             addAll(Collection<? extends E> collection)
boolean             addAll(int location, Collection<? extends E> collection)
void                addFirst(E object)
void                addLast(E object)
void                clear()
Object              clone()
boolean             contains(Object object)
Iterator<E>         descendingIterator()
E                   element()
E                   get(int location)
E                   getFirst()
E                   getLast()
int                 indexOf(Object object)
int                 lastIndexOf(Object object)
ListIterator<E>     listIterator(int location)
boolean             offer(E o)
boolean             offerFirst(E e)
boolean             offerLast(E e)
E                   peek()
E                   peekFirst()
E                   peekLast()
E                   poll()
E                   pollFirst()
E                   pollLast()
E                   pop()
void                push(E e)
E                   remove()
E                   remove(int location)
boolean             remove(Object object)
E                   removeFirst()
boolean             removeFirstOccurrence(Object o)
E                   removeLast()
boolean             removeLastOccurrence(Object o)
E                   set(int location, E object)
int                 size()
<T> T[]             toArray(T[] contents)
Object[]            toArray()

LinkedList数据结构是双向链表结构,没有初始大小,也没有扩容的机制,只在前面或后面新增就行

ArrayList最大的特点:增删快查找慢

LinkedList遍历方式:
  1. 通过for循环遍历
for (Integer integ:list) {
    value = integ;
}
  1. 通过remove遍历
try {
    while(list.removeLast() != null);
    
    while(list.removeFirst() != null);
} catch (NoSuchElementException e) {
}
  1. 通过poll遍历
while(list.pollLast() != null);
或
while(list.pollFirst() != null);
  1. 通过迭代器遍历
Integer value = null;
Iterator iter = list.iterator();
while (iter.hasNext()) {
    value = (Integer)iter.next();
}
  1. 通过快速随机遍历
int size = list.size();
for (int i=0; i<size; i++) {
    list.get(i);        
}

遍历LinkedList时,使用remove效率最高,但是会删除原始数据,只读取遍历应该使用for循环遍历,使用随机访问效率最低




Set(接口)

Set 是继承于Collection的接口。它是一个不允许有重复元素的集合

AbstractSet 是一个抽象类,它继承于AbstractCollection,AbstractCollection实现了Set中的绝大部分函数,为Set的实现类提供了便利

HashSet

  • HashSet是一个没有重复元素的集合,但是也是非同步的

    如果多个线程同时访问一个哈希 set,而其中至少一个线程修改了该 set,那么它必须 保持外部同步。这通常是通过对自然封装该 set 的对象执行同步操作来完成的。如果不存在这样的对象,则应该使用 Collections.synchronizedSet 方法来“包装” set。最好在创建时完成这一操作,以防止对该 set 进行意外的不同步访问

  • 本质是由HashMap实现,其中的操作函数实际上都是通过map实现的
  • 不保证元素的存储顺序,而且HashSet允许使用null元素。

HashSet的主要API

boolean         add(E object)
void            clear()
Object          clone()
boolean         contains(Object object)
boolean         isEmpty()
Iterator<E>     iterator()
boolean         remove(Object object)
int             size()
HashSet遍历方式:
  1. 通过迭代器循环遍历
for(Iterator iterator = Iterator<String> it = set.iterator();
while (it.hasNext()) {
  String str = it.next();
}
  1. 通过for循环遍历
for (String str : set) {
    System.out.println(str);
}
HashSet保证不重复的原理

equalshashcode
hashcode能根据对象,计算出并返回一个整数结果,如果对象相同,结果也会相同。
HashSet的底层是用HashMap存储数据的,它会先计算出这个元素存储在map的位置。
如果位置为空就会添加进去,
如果不为空,则用equals方法比较元素是否相等,相等就不添加,不等则找个空位添加


LinkedHashSet

属于HashSet的子类,是链表和哈希表相组合的数据存储结构

链表同时保证顺序一致


TreeSet

TreeSet是一个有序的集合,从创建或插入的时候就已经排好序。

TreeSet基于TreeMap实现,元素支持2种排序方式:

  • 自然排序

    构造时使用API自带方法排序

  • Comparator比较器排序

    自定义类中实现Comparator接口,重写compare方法

  • 自定义实体类

    实体类实现comparable接口,重写compareTo方法

比较规则:
return 小于0时,放左边
return 大于0时,放右边
return 等于0时,放一个

关于Comparator与Comparable

able是排序接口,若一个类实现该接口,则代表该类支持排序(相当于内部比较器)
tor是比较器,若一个类实现该接口,则一定要重写compareTo方法来支持排序

当自定义排序写好之后,可以用sort进行排序

Collections.sort(list)

它会根据集合类型选择comparTo方法

当需要再倒序的时候,可以用reverseOrder()方法

Comparator<Student> c = Collections.reverseOrder();
Collections.sort(list,c);

TreeSet继承于AbstractSet,实现了的接口有:

  1. NavigableSet接口,能进行队列操作
  2. Cloneable接口,能被克隆
  3. Serializable接口,支持序列化,能序列化传输

TreeSet的主要API

boolean                   add(E object)
boolean                   addAll(Collection<? extends E> collection)
void                      clear()
Object                    clone()
boolean                   contains(Object object)
E                         first()
boolean                   isEmpty()
E                         last()
E                         pollFirst()
E                         pollLast()
E                         lower(E e)
E                         floor(E e)
E                         ceiling(E e)
E                         higher(E e)
boolean                   remove(Object object)
int                       size()
Comparator<? super E>     comparator()
Iterator<E>               iterator()
Iterator<E>               descendingIterator()
SortedSet<E>              headSet(E end)
NavigableSet<E>           descendingSet()
NavigableSet<E>           headSet(E end, boolean endInclusive)
SortedSet<E>              subSet(E start, E end)
NavigableSet<E>           subSet(E start, boolean startInclusive, E end, boolean endInclusive)
NavigableSet<E>           tailSet(E start, boolean startInclusive)
SortedSet<E>              tailSet(E start)
TreeSet遍历方式:
  1. 通过迭代器循环遍历
for(Iterator iterator = Iterator<String> it = set.iterator();
while (it.hasNext()) {
  String str = it.next();
}
  1. 通过for循环遍历
for (String str : set) {
    System.out.println(str);
}
TreeSet保证不重复的原理

compareTo
一般只需要实现Comparable接口或compareTo()方法就可以了
但是自定义类的话推荐重写equals方法,可能compare结果为0,但equals却是false结果




Map(接口)

画像
Map是一个键值对映射接口,每个元素都由键与值两部分组成
在映射中不能包含重复的键,一个键只能映射一个值

Collection接口的基本API

abstract void                 clear()
abstract boolean              containsKey(Object key)
abstract boolean              containsValue(Object value)
abstract Set<Entry<K, V>>     entrySet()
abstract boolean              equals(Object object)
abstract V                    get(Object key)
abstract int                  hashCode()
abstract boolean              isEmpty()
abstract Set<K>               keySet()
abstract V                    put(K key, V value)
abstract void                 putAll(Map<? extends K, ? extends V> map)
abstract V                    remove(Object key)
abstract int                  size()
abstract Collection<V>        values()

entrySet()用于返回键-值集的Set集合
keySet()用于返回键集的Set集合
values()用户返回值集的Collection集合
因为Map中不能包含重复的键;每个键最多只能映射到一个值。所以,键-值集、键集都是Set,值集时Collection。

同样,Map接口有一个骨干实现:AbstractMap类,以最大限度地减少实现此接口所需的工作

遍历set的方式
Map 接口提供三种collection 视图,允许以键集、值集或键-值映射关系集的形式查看某个映射的内容。

  • 键集:获取集合中所有的键,通过迭代集合用get()方法获得对应值
Set< E > sets = maps.keySet();
//遍历
Iterator<String> it = sets.iterator();
while(it.hasNext()){
    String key = it.next();//得到每一个key
    String value = map.get(key);//通过key获取对应的value
    System.out.println(key+"="+value);
}
  • 值集:获取集合中所有的值
    (没有键和映射关系)
Collection< E > collections =  maps.values();
  • 键值映射关系集:获取映射关系的set视图,通过迭代集合用getKey()、getValue()获得键和值
Set< Map.Entry<K,V> > entries = maps.entrySet();
//遍历
Iterator< Map.Entry<K,V> > it = entries.iterator();
while(it.hasNext()){
    //得到每一对对应关系
    Map.Entry<K,V> entry = it.next();
    //通过对应关系获取对应的key
    String key = entry.getKey();
    //通过对应关系获取对应的value
    String value = entry.getValue();
    
    System.out.println(key+"="+value);
}

虽然keySet和entrySet进行遍历能取得相同的结果,但是entrySet的性能明显比keySet要好,遍历速度也是最快的

其中,大部分适用的entrySet的遍历方式为:

Map<Integer, Integer> map = new HashMap<Integer, Integer>(); 
for (Map.Entry<Integer, Integer> entry : map.entrySet()) { 
    System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); 
}


HashMap

HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。

HashMap 继承于AbstractMap,实现了:Map、Cloneable、erializable接口。

HashMap 的实现不是同步的,这意味着它不是线程安全的。它的key、value都可以为null。
此外,HashMap中的映射是无序的。

HashMap的API

void                 clear()
Object               clone()
boolean              containsKey(Object key)
boolean              containsValue(Object value)
Set<Entry<K, V>>     entrySet()
V                    get(Object key)
boolean              isEmpty()
Set<K>               keySet()
V                    put(K key, V value)
void                 putAll(Map<? extends K, ? extends V> map)
V                    remove(Object key)
int                  size()
Collection<V>        values()

HashMap 的实例有两个参数影响其性能:“初始容量”“加载因子”
容量:是哈希表中桶的数量,初始容量 只是哈希表在创建时的容量。
加载因子:是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行 rehash 操作(即重建内部数据结构),从而哈希表将具有大约两倍的桶数。

通常,默认加载因子是 0.75 , 这是在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查询成本(在大多数 HashMap 类的操作中,包括 get 和 put 操作,都反映了这一点)。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地减少 rehash 操作次数。如果初始容量大于最大条目数除以加载因子,则不会发生 rehash 操作。


LinkedHashMap

属于HashMap的子类,是链表哈希表相组合的数据存储结构

保证顺序一致


TreeMap

TreeMap 是一个有序的key-value集合,它是通过红黑树实现的。

天然のソートキーのそれらのマッピングのため、または使用される構成方法に応じて、マップ作成時に提供されたコンパレータに従ってソート。
TreeMapの基本的な操作のcontainsKey、時間の複雑さは、(n)は、ログを入れて、削除します。
さらに、TreeMapの非同期化。
それiteratorメソッドは反復子がフェイルfastlで返します。

TreeMapのの的のAPI

Entry<K, V>                ceilingEntry(K key)
K                          ceilingKey(K key)
void                       clear()
Object                     clone()
Comparator<? super K>      comparator()
boolean                    containsKey(Object key)
NavigableSet<K>            descendingKeySet()
NavigableMap<K, V>         descendingMap()
Set<Entry<K, V>>           entrySet()
Entry<K, V>                firstEntry()
K                          firstKey()
Entry<K, V>                floorEntry(K key)
K                          floorKey(K key)
V                          get(Object key)
NavigableMap<K, V>         headMap(K to, boolean inclusive)
SortedMap<K, V>            headMap(K toExclusive)
Entry<K, V>                higherEntry(K key)
K                          higherKey(K key)
boolean                    isEmpty()
Set<K>                     keySet()
Entry<K, V>                lastEntry()
K                          lastKey()
Entry<K, V>                lowerEntry(K key)
K                          lowerKey(K key)
NavigableSet<K>            navigableKeySet()
Entry<K, V>                pollFirstEntry()
Entry<K, V>                pollLastEntry()
V                          put(K key, V value)
V                          remove(Object key)
int                        size()
SortedMap<K, V>            subMap(K fromInclusive, K toExclusive)
NavigableMap<K, V>         subMap(K from, boolean fromInclusive, K to, boolean toInclusive)
NavigableMap<K, V>         tailMap(K from, boolean inclusive)
SortedMap<K, V>            tailMap(K fromInclusive)




拡張概要

コレクション 初期 複数の拡張 リマーク
配列リスト 10 1.5倍 あなたは、新しい拡張のサイズ、必要な最小容量の容量よりも多くしたい場合
LinkedListの デフォルトの容量ません あなたは拡張を必要としません これは拡張せずに、リンクリスト構造であります
ベクター 10 2倍 膨張あまりにも費用がかかり、低い初期膨張効率、しばしばメモリの断片の過剰増殖をもたらします
HashSetの 16 2倍 負荷係数は0.75、すなわち数拡張のための0.75倍の容量を超えてしまうです
HashMapの 16 2倍 負荷係数は0.75であります
StringBufferの/ビルダー 16の文字 2倍 +2




おすすめ

転載: www.cnblogs.com/zohnn/p/11260671.html