Java - 集合框架(知识梳理)

1、集合概述

存储对象的容器

集合与数组的区别

  • 存储类型

    数组:可以存储任意类型数据,基本数据类型、引用数据类型

    集合:只能存储引用类型,基本数据类型存储时自动装箱

  • 容量

    数组:定长,创建后不可更改

    集合:变长,随存储元素的数量动态改变

Java中集合框架结构
集合框架

集合框架的好处

  1. 容量自增长;
  2. 提供了高性能的数据结构和算法,使编码更轻松,提高了程序速度和质量;
  3. 可以方便地扩展或改写集合,提高代码复用性和可操作性。
  4. 通过使用JDK自带的集合类,可以降低代码维护和学习成本。

2、Iterator接口

Iterator接口,用于遍历集合元素的接口。

在Iterator接口中定义了三个方法

boolean	hasNext() //如果仍有元素可以迭代,则返回true。
E next() //返回迭代的下一个元素,同时移向该元素后一个元素(正向)。
void remove() //从迭代器指向的 collection 中移除迭代器返回的最后一个元素。

每一个集合都有自己的数据结构(容器中存储数据的方式),因此取出元素的方式各不相同。为了便于操作所有的容器,取出元素。JDk提供Iterator接口,使得对容器的遍历操作与其具体的底层实现相隔离,达到解耦的效果。

2.1 迭代器Iterator获取元素

使用方法:

//step1 对要遍历的集合对象,使用.iterator()方法获取迭代器对象
Iterrator<E> it = 集合对象.iterator();
//step2 判断迭代器是否还有元素
while(it.hasNext()) {
    //step3 获取元素
    it.next();
}
  • 迭代器获取元素时,需要先判断是否还存在元素。否则可能抛出NoSuchElementException异常
  • 迭代器工作期间,集合本身不能修改自己的结构,否则会出现意外,安全的删除方法使用接口中的remove()方法

2.1 ListIterator接口

是一个功能更加强大的迭代器, 它继承于Iterator接口,只能用于各种List类型的访问。

通过调用listIterator()方法产生一个指向List开始处的ListIterator对象, 还可以调用listIterator(n)方法创建一个一开始就指向列表索引为n的元素处的ListIterator对象。

特点

  • 可以向前、向后两个方向遍历 List;
  • 在遍历时可以修改 List 中的元素;
  • 遍历时可以获取迭代器当前游标所在位置。

常用方法

//除继承Iterator接口中的方法,还新增以下方法
boolean	hasPrevious() //反向遍历集合时判断其前方是否还有元素
int	nextIndex() //返回调用 next()后返回的元素索引。
E previous() //反向遍历时,获取集合上一个元素,同时光标向前移动。
int	previousIndex() //返回调用previous() 后返回的元素索引 。
void remove() //删除列表中调用next()或previous()的返回最后一个元素。
void set(E e) //用指定元素替换列表中调用next()或previous()的返回最后一个元素。

3 Collection接口

Collection一次存一个元素,是单列集合的根接口

Collection集合主要有List和Set两大接口

  • List:有序(元素存入集合的顺序和取出的顺序一致),元素都有索引。元素可以重复。
  • Set:无序(存入和取出顺序有可能不一致),不可以存储重复元素。必须保证元素唯一性。

主要方法

boolean add(E e)  //添加元素
boolean remove(Object o) //从该集合中删除指定元素(如果存在)
int size() //返回此集合中的元素个数。 
boolean contains(Object o)  //集合中是否包含指定元素
void clear()  //清空集合中元素
Iterator<E> iterator() //集合中的元素的迭代器。  
    
//其他方法
boolean addAll(Collection<? extends E> c) //将指定集合中的所有元素添加到此集合 
boolean removeAll(Collection<?> c) //删除集合中指定集合中的所有元素 底层使用equals方式比较
boolean isEmpty()  //判定集合中是否含有元素
boolean retainAll(Collection<?> c) //仅保留集合中指定集合中的所有元素 底层使用equals方式比较

4、List接口

List是元素有序(存在下标)且允许元素重复的集合,Collection的一个字接口

List的主要实现类 – ArrayList 、 linkedList、Vector

继承结构

List继承结构

主要方法

//除继承自collection中方法外,新增加方法均与下标相关
void add(int index, E element) // 在指定位置插入元素
boolean addAll(int index, Collection<? extends E> c) //在指定位置插入集合中所有元素
E remove(int index) //删除指定位置的元素 
E set(int index, E element)  //将指定位置的元素替换为目标元素
E get(int index)  //获取指定位置元素
List<E> subList(int fromIndex, int toIndex)  //获取[formIndex,toIndex)间的元素子集合
int indexOf(Object o) //返回集合指定元素的第一次出现的索引,如果集合不包含该元素,则返回-1。 

遍历元素方法

  • for-each,增强for循环
  • Iterator迭代器
  • 普通for循环,结合get(index)方法

4.1 ArrayList实现类

是List的一个实现类,底层使用数组实现,相当于一个动态数组

ArrayList继承结构

它还实现了三个标识型接口,这几个接口都没有任何方法,仅作为标识表示实现类具备某项功能。RandomAccess表示实现类支持快速随机访问,Cloneable表示实现类支持克隆,Serializable则表示支持序列化。

特点

  • 基于数组实现
  • 可以动态调整容量
  • 有序且元素允许重复,元素可以为null
  • 不同步,线程不安全,效率高
  • 查询快,增删慢
  • 对比LinkedList占用空间更小

常用方法

直接实现List接口中的方法,无新增。同List常用方法

4.2 LinkedList实现类

List的一个实现类,基于双向链表实现

继承关系

LinkedList继承结构

LinkedList,同时又实现了 List 和 Deque(双端队列 Double-End Queue) 接口中的方法

特点

  • 基于双向链表实现
  • 有序,允许null与重复值
  • 不同步,线程不安全,效率高
  • 由于LinkedLIst需要额外存储元素前驱与后继的引用,相对ArrayList更占空间

主要方法

//除继承自List集合的中的方法外,还新增的有
//模拟栈结构
void push(E e) // 将元素推送到由此集合表示的堆栈上(入栈)。  
E pop() // 从此集合表示的堆栈中弹出一个元素(出栈)。  

//模拟队列结构
boolean offer(E e) // 将指定的元素添加为此集合的尾部(入列)。  
E poll() // 获取并删除此集合的头元素(出列)。  
    
//其他操作
void addFirst(E e) //在该集合开头插入指定的元素。 
void addLast(E e) //将指定的元素追加到此集合的末尾。  
E element() //获取但不删除此集合的元素 
E getFirst() //返回此集合中的第一个元素。  
E getLast() //返回此集合中的最后一个元素。 
E peek() //获取但不删除此集合的头元素。  
E peekFirst() //获取但不删除此集合的第一个元素,如果此集合为空,则返回 null 。  
E peekLast() //获取但不删除此集合的最后一个元素,如果此集合为空,则返回 null 。 

4.3 Vector实现类(已过时)

List的一个实现类,底层由数组实现。已过时被ArrayList替代

方法同ArrayList中方法。

​ 迭代元素时,还可以使用elements()获取Enumeration对象

  • hasMoreElements() 同 hasNext()
  • nextElement() 同 next()

4.4 ArrayList、LinkedList、Vector比较

ArrayListLinkedListVector
底层实现数组双向链表数组
同步性及效率不同步,非线程安全,效率高,支持随机访问不同步,非线程安全,效率高同步,线程安全,效率低
特点查询快,增删慢查询慢,增删快查询快,增删慢
默认容量10/10
扩容机制int newCapacity = oldCapacity + (oldCapacity >> 1);//1.5 倍/2 倍

5、Set接口

Collection子接口 元素无序,且不能重复

常用方法:继承自Collection中的方法,无新增

5.1 HashSet实现类

Set接口的实现类,底层是HashMap的一个实例,元素无序、不能重复

去重方法:使用元素的HashCode()与equals()方法,需要重写两个方法

常用方法:Collection中的常用方法

5.1.1 LinkedHashSet实现类

HashSet的一个子类,底层是LinkedHashMap的一个实例。保证了元素可预测迭代顺序(存入顺序),且元素去重

常用方法:Collection中的常用方法

5.2 比较器

5.2.1 Comparable接口

标记该类的实例可以实现自然排序,排序依据为调用compareTo()方法

java.lang.Comparable使用方法

//元素对象所属类实现了Comparable接口
class Person implements Comparable {
    @override
    int compareTo(T o) //将此对象与指定的对象进行比较以进行排序。
} 

排序规则(根据返回值)

  • 正数 :this > o 将this排在o之后
  • 负数:this < o 将this排在o之前
  • 零: this = o this与o相同,去重依据
5.2.2 Comparator接口

自定义比较器接口,用以对象的排序

java.util.Comparator使用方法

class Person {}
//创建接口的实现类
class PersonCompara implements Comparator {
    //实现比较方法
    int compara(T o1, T o2) {}
}
//new集合时传入的接口实现类
TreeSet<Person> set = new TreeSet<>(PersonCompara);

//创建集合时,直接使用匿名内部类
TreeSet<Person> set = new TreeSet<>(new Comparator() {
    //实现比较方法
    int compara(T o1, T o2) {}
});

排序规则(根据返回值)

  • 正数:o1 > o2 o1排在o2后面
  • 负数:o1 < o2 o1排在o2前面
  • 零:o1 = o2 o1与o2相同,去重依据

5.3 TreeSet实现类

Set接口的一个实现类,同时还实现了SortedSet接口。底层是TreeMap的一个实例,元素有序(自然排序或者定制排序),无重复元素

去重方法:元素已经实现Comparable接口自然排序去重或者集合创建时传入Comparator接口实现类定制排序去重

常用方法

//继承自Set接口中的方法,即Collection中方法
E ceiling(E e) //返回此集合中大于或等于给定元素的最小元素,如果没有此元素,则返回 null。例如集合[aaa,bbb,ccc,ddd] ceiling("bbc") --> ccc
E floor(E e) //返回此集合中小于或等于给定元素的最大元素,如果没有这样的元素,则返回 null。例如集合[aaa,bbb,ccc,ddd] floor("bbc") --> bbb
E higher(E e) //返回大于给定元素的该集合中的最小元素,如果没有此元素则返回 null  例如集合[aaa,bbb,ccc,ddd] higher("ccc") --> ddd
E lower(E e) //返回这个集合中最大的元素严格小于给定的元素,如果没有这样的元素,则返回 null 。 例如集合[aaa,bbb,ccc,ddd] lower("ccc") --> bbb 
E first() //返回此集合中排序第一个元素。  
E last() //返回此集合中排序最后一个元素。  
SortedSet<E> headSet(E toElement) //小于toElement的部分集合 。 例如集合[aaa,bbb,ccc,ddd] headSet("ccc") --> [aaa,bbb]
NavigableSet<E> tailSet(E fromElement)  //大于或等于fromElement的部分集合。 例如集合[aaa,bbb,ccc,ddd] tailSet("ccc") --> [ccc,ddd]
SortedSet<E> subSet(E fromElement, E toElement) //获取[fromElement, toElement)间的子集合

5.4 HashSet、TreeSet、LinkedHashSet比较

HashSetTreeSetLinkedHashSet
底层实现HashMapTreeMapLinkedHashMap
元素重复性不允许重复不允许重复不允许重复
元素有无序无序有序,支持两种排序方式,自然排序和定制排序,其中自然排序为默认的排序方式。有序,即元素插入的顺序
同步性不同步,线程不安全不同步,线程不安全不同步,线程不安全
null值允许null值不支持null值,会抛出 java.lang.NullPointerException 异常允许null值
去重方法HashCode()、equals()compareTo()与compare()HashCode()、equals()

6、Map接口

Map是一种把键对象和值对象映射的集合。是双列集合(一次存储两个数据)

Map中的元素,总是成对存在。分为键(K Key)与值(V Value),他们是映射关系。

继承结构

在这里插入图片描述

特点

  • 键(k)不允许重复,当存入数据键重复时,新值覆盖旧值
  • 值(V)允许重复

常用方法

//增
V put(K key, V value) //将指定的键值对存入Map。V 被替换的值 没有替换返回null
void putAll(Map<? extends K,? extends V> m)  //存入Map对象

//删
V remove(Object key)  //删除指定键的键值对映射
void clear() // 从该Map中删除所有的映射 

//获取
int size() //返回此Map中键值映射的数量。  
V get(Object key) //获取指定键所映射的值,不存在返回null
Set<K> keySet() // 获取此Map中包含的所有键的Set集合。  
Set<Map.Entry<K,V>> entrySet()  // 获取Map中包含的所有键值映射的Set集合。 
Collection<V> values() //获取Map包含的所有值的Collection集合。  

//判断
boolean isEmpty()  // 判断集合是否为空
boolean containsKey(Object key) //判断Map中是否含有指定键 
boolean containsValue(Object value)  //判断Map中是否含有指定值

6.1 Map.Entry

定义在Map接口中的一个内部接口,他表示一个映射项(包含有Map中的key与value)

Map接口中的entrySet()返回一个包含有Entry类型元素的Set集合,通过Entry中的方法getKey()与getValue()方法,即能遍历出Map中的每一个键值对值

使用方法

//1. 获取Set(Map.Entry<K,v>)集合
Set<Entry<String, String>> set = map.entrySet();
//2. 遍历Set集合,获取Entry对象
Entry<String, String> entry = set.iterator();
//3. 获取键值
entry.getKey();
entry.getValue();

6.2 HashMap实现类

Map的一个实现类,基于哈希表实现(JDk1.7为数组链表,JDK1.8为数组链表加红黑树)

继承结构

在这里插入图片描述

HashMap继承抽象类AbstractMap,实现Map接口

Key去重原理同HashSet去重

常用方法:实现的Map中方法

6.2.1 HashMap在JDk1.7与1.8区别
不同JDk1.7JDk1.8
存储结构数组 + 链表数组 + 链表 + 红黑树
初始化方式单独函数:inflateTable()集成到扩容函数resize()
hash值计算方式扰动处理 :9次扰动 (4次位运算 + 5次异或运算)扰动处理 :2次扰动(1次位运算 + 1次异或运算)
存放数据的规则无冲突时,存放数组;冲突时,存放链表无冲突时,存放数组;冲突 & 链表长度 < 8:存放单链表;冲突 & 链表长度 > 8:树化并存放红黑树
插入数据方式头插法(先将原位置的数据后移1位,再插入数据到该位置)尾插法(直接插入到链表尾部/红黑树)
6.2.2 LinkedHashMap实现类

HashMap的子类,基于链表和哈希表实现。可以保证元素的存入顺序

去重原理:同HashMap(使用元素的HashCode()与equals()方法)

常用方法:同HashMap

6.3 Hashtable实现类(已过时)

Map的实现类,底层基于哈希表实现。已过时被HashMap代替

HashMap与Hashtable比较

  • 都是Map的实现类(HashMap代替Hashtable)
  • HashMap继承自AbstractMap,Hashtable继承自Dictionary
  • Hashtable同步、线程安全。HashMap不同步,线程不安全
  • HashMap允许存入null值,Hashtable不允许存入null值
6.3.1 Properties类

Hashtable的一个子类,表示一个持久的属性集

主要用于存储一些配置信息,可以从流中加载、也可以保存到流中,泛型K与V均为String类型

常用方法

String getProperty(String key) //使用此属性集合中指定的键搜索属性。  
Object setProperty(String key, String value) //同 Hashtable方法 put 。  
void load(InputStream inStream) //从输入字节流读取属性集合(键值对)。
void load(Reader reader) //以简单的线性格式从输入字符流读取属性集合(键值对)。
void store(OutputStream out, String comments) //使用字节输出流将此属性集合(键值对)保存
void store(Writer writer, String comments) //使用字符输出流将此属性集合(键值对)保存

6.4 TreeMap实现类

Map的实现类,基于黑红树实现,K有序(排序)

继承结构

在这里插入图片描述

TreeMap继承于AbstractMap,直接实现NavigableMap

去重方法(排序方式):元素已经实现Comparable接口自然排序去重或者集合创建时传入Comparator接口实现类定制排序去重

常用方法

//除继承自Map中的方法还有如下
K ceilingKey(K key) //返回TreeMap中大于或等于指定Key的最小Key值,如果没有返回 null 。 
K floorKey(K key) //返回TreeMap中小于或等于给定Key的最大key值,如果没有返回null 。 
K firstKey()  //返回TreeMap中第一个键。
K lastKey() //返回TreeMap中最后一个键。  
SortedMap<K,V> headMap(K toKey) //返回key小于toKey值得子Map集合。  
SortedMap<K,V> tailMap(K fromKey) //返回key大于等于 fromKey值的子Map集合 。 

6.5 HashMap、Hashtable、TreeMap比较

HashMapHashtableTreeMap
底层实现哈希表(数组+链表)哈希表(数组+链表)红黑树
线程安全性不安全安全不安全
null值允许key与value为null,且只允许一个key为null不允许key、value 是 nullvalue允许为null。
元素hash值使用hash(Object key)扰动函数对 key 的 hashCode 进行扰动后作为 hash 值直接使用 key 的 hashCode() 返回值作为 hash 值/
容量默认容量为 16 且容量一定是 2^n默认容量是11,不一定是 2^n/
扩容两倍2n+1倍/

7、泛型

类型参数化,在定义时不使用具体类型限定,创建时才限定类型。类似于方法中的参数,提高代码的复用性(JDk1.5)

7.1 泛型类

声明的时候使用<>,做限制类型,类中只能存在普通方法与属性。泛型接口使用类基本相同

class 类名<T> {
    // T  type
    // E  element
    //K   key
    //V   value
}

泛型擦除:使用时没有指明泛型具体的类型,则类型自动变为Object类型

7.2 泛型静态方法

静态方法需要使用泛型时,需要在方法声明时同时独立声明泛型,声明泛型应写在static关键字之后,返回类型值之前

//静态方法独立声明泛型,不能使用类声明泛型
public static <T> T test(T t) {
    return t;
}

7.3 泛型限定

  • ?:代表可以使用任意类型
  • ? extends T:限定上限。可以使用T及T的子类
  • ? super T:限定下限。可以使用T及T的父类

7.4 不允许使用泛型的地方

  1. 静态的属性
  2. 创建泛型的实例。 例如:T t = new T()
  3. 自定义异常时,不能使用泛型

8 Collections工具类

提供集合的常用静态操作方法

//获取线程安全的集合
static <T> Collection<T> synchronizedCollection(Collection<T> c) //返回由指定集合支持的同步(线程安全)集合。  
static <T> List<T> synchronizedList(List<T> list) //返回由指定List支持的同步(线程安全)List。  
static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) //返回由指定Map支持的同步(线程安全)Map。  

//向Collection容器中添加元素
static <T> boolean addAll(Collection<? super T> c, T... elements) //将所有指定的元素添加到指定的集合。
    
//对于List操作
//使用二叉搜索算法搜索指定对象的指定列表。 
static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) 
//使用二叉搜索算法搜索指定对象的指定列表。  
static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c)   
static <T extends Comparable<? super T>> void sort(List<T> list) //对List元素进行自然排序。 
static <T> void sort(List<T> list, Comparator<? super T> c) //根据指定的比较器对指定的List进行排序。  
static void reverse(List<?> list)  // 反转指定列表中元素的顺序。 
static void shuffle(List<?> list) // 使用默认的随机源随机排列指定的列表。  
static <T> boolean replaceAll(List<T> list, T oldVal, T newVal) //将列表中一个指定值的所有出现替换为另一个。  
static int frequency(Collection<?> c, Object o) //返回指定集合中与指定对象相等的元素数。  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值