关于集合的详细介绍,推荐Java集合系列,以下是上面博客做的总结


  • Java集合是Java提供的工具包,包含了常用的数据结构:集合、链表、队列、栈、数组、映射等
  • Java各个集合也是和数组一样性质的元素容器,但是数组长度固定,集合长度可变
  • 集合存储的元素必须是引用数据类型,不能是基本数据类型

Java集合工具包框架图:

简化图:

Collection(接口)


Collection是一个接口,是高度抽象出来的集合,它包含了集合的基本操作和属性;

Collection接口的基本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()

为了方便,抽象出了AbstractCollection抽象类,它实现了Collection接口中绝大部分方法。
因此在Collection的实现类中,可以通过继承这个抽象类省去重复编码

它的主要两个分支是: ListSet ,同样,这两个接口也有着自己的抽象类


List(接口)

继承了Collection接口,是有序的一个队列,也称为序列。

List中的每一个元素都有一个索引,索引从0开始然后依次递增1,因此可以对列表中每个元素进行精确控制和访问。

和Set不同,List允许有重复的元素

除了Collection中已有的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

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();//得到每一个keyString value = map.get(key);//通过key获取对应的valueSystem.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();//通过对应关系获取对应的keyString key = entry.getKey();//通过对应关系获取对应的valueString 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集合,它是通过红黑树实现的。

该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。
TreeMap的基本操作 containsKey、get、put 和 remove 的时间复杂度是 log(n) 。
另外,TreeMap是非同步的。
它的iterator 方法返回的迭代器是fail-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)

扩容总结

Collection 初始 扩容倍数 备注
ArrayList 10 1.5x 新增的如果超过要扩容的大小,则容量为所需的最小容量
LinkedList 无默认容量 不需要扩容 这是个链表结构,无需扩容
Vector 10 2x 扩容方式代价太大,初始扩容效率低,频繁增长造成过多内存碎片
HashSet 16 2x 加载因子是0.75,即当个数超过容量的0.75倍时会进行扩容
HashMap 16 2x 加载因子也是0.75
StringBuffer/Builder 16字符 2x +2

转载于:https://www.cnblogs.com/zohnn/p/11260671.html

Java 集合(初稿)相关推荐

  1. java 集合 接口_Java集合之Collection接口

    1 - Java集合介绍 /* 1. 一方面, 面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象 的操作,就要对对象进行存储. 2. 另一方面,使用Array存储对象方面具有一些弊 端,而 ...

  2. java 头尾 队列_超详细的java集合讲解

    1 集合 1.1 为什么会出现集合框架 [1] 之前的数组作为容器时,不能自动拓容 [2] 数值在进行添加和删除操作时,需要开发者自己实现添加和删除. 1.2 Collection接口 1.2.1 C ...

  3. java集合总结_Java中集合总结

    Java数组的长度是固定的,为了使程序能够方便地存储和操作数目不固定的一组数据,JDK类库提供了Java集合,这些集合类都位于java.util包中,但是与数组不同的是,集合中不能存放基本类型数据,而 ...

  4. 考考基础部分,谈谈Java集合中HashSet的原理及常用方法

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:工匠初心 cnblogs.com/LiaHon/p/1125 ...

  5. Java集合框架综述,这篇让你吃透!

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:平凡希 cnblogs.com/xiaoxi/p/60899 ...

  6. 【Java集合框架】ArrayList类方法简明解析(举例说明)

    本文目录 1.API与Java集合框架 2.ArrayList类方法解析 2.1 add() 2.2 addAll() 2.3 clear() 2.4 clone() 2.5 contains() 2 ...

  7. Java基础篇:Java集合

    文章目录 1.概述 2.Collection接口 2.1 Collection接口方法 2.2 Iterator迭代器接口 2.3 Collection子接口之:List接口 2.4 Collecti ...

  8. java奇怪的问题_一个奇怪的Java集合问题

    int size = list.size(); Integer existIndex = -1; for (int index = 0; index < size; index++) { Pho ...

  9. Java集合框架的知识总结(1)

    Java集合框架的知识总结(1) 所有集合类都位于java.util包下.集合中只能保存对象(保存对象的引用变量). Java的集合类主要由两个接口派生而出:Collection和Map,Collec ...

最新文章

  1. Spring Data JPA 五分钟快速入门和实践
  2. 影像组学视频学习笔记(43)-标准差、标准误及95%置信区间CI、Li‘s have a solution and plan.
  3. python2与python3之间的主要区别
  4. 德国政府发布新网络安全战略
  5. ShellExecute, WinExec, CreateProcess区别
  6. react 遍历对象_探索:跟随《Build your own React》实现一个简易React
  7. 关系型数据库,第一!
  8. 防火墙对nginx服务器有影响
  9. 交叉编译器arm-linux-gcc
  10. C/C++语言函数参数里的“...”作用,va_list的使用(stdarg.h)
  11. MAVEN自定义项目骨架
  12. mysqld_exporter报错Error 1146: Table 'my2.status' doesn't exist
  13. Android实践--监測网络状态
  14. NYOJ1 - A+B Problem
  15. Jupyter Notebook 作图显示中文
  16. 怎么找网页源文件位置_无法查看网页的源文件该怎么办?
  17. hdu 5211 Mutiple
  18. 2021字节秋招算法岗面经——抖音推荐
  19. html语言设置图片位置,HTML中如何设置图片位置
  20. microLED应该会取代OLED的

热门文章

  1. python入门程序异常_Python 入门 之 异常处理
  2. linux mysql 数据类型_MySQL的数据类型和建库策略(转)
  3. java tcp聊天程序_java实现基于Tcp的socket聊天程序
  4. swagger OAuth认证
  5. Oracle索引状态查询与索引重建
  6. axios中get与post方式传参区别
  7. Android5.0和6.0之后新增的控件说明
  8. 如何转换并压缩png格式图片
  9. 玩转iOS开发:iOS 8 新特性《UIVisualEffect》
  10. sql server生成不重复的时间字符串