Java集合框架

亡梦爱人 提交于 2019-11-29 21:59:09

集合框架体系图

Java集合框架位于java.util包下

短虚线框表示接口,长虚线框表示抽象类,实线框表示类

带三角箭头的实线表示继承关系,由子类指向父类

带三角箭头的虚线表示实现,由类指向接口

带实箭头的虚线表示依赖关系

右下角的Collections和Arrays是工具类

Iterable

Iterable是一个接口,实现该接口表明自身可迭代,核心在于实现接口方法iterator()返回一个迭代器

接口方法

default void forEach(Consumer<? super T> action)  //对 Iterable的每个元素执行给定的操作,直到所有元素都被处理或动作引发异常。   Iterator<T> iterator()  //返回类型为 T元素的迭代器。   default Spliterator<T> spliterator()  //在Iterable描述的元素上创建一个Iterable 。 

Iterator

Iterator是一个接口,定义了遍历集合类的基本方法(由方法可以看出只能支持简单的单向遍历)

由图中可以看出Collection依赖于Iterator,也就是说实现了接口Collection的类都是可迭代对象

接口方法

default void forEachRemaining(Consumer<? super E> action)  //对每个剩余元素执行给定的操作,直到所有元素都被处理或动作引发异常。   boolean hasNext()  //如果迭代具有更多元素,则返回 true 。   E next()  //返回迭代中的下一个元素。   default void remove()  //从底层集合中删除此迭代器返回的最后一个元素(少用)。  

ListIterator

ListIterator是Iterator的子接口,在Iterator的基础上允许任意方向的遍历,并且可以获取迭代位置和添加对象

由图中可以看出List依赖于ListIterator,也就是说实现接口List的类都是可进行上述迭代的对象

接口方法

void add(E e)  //将指定的元素插入列表。   boolean hasNext()  //返回 true如果遍历正向列表,列表迭代器有多个元素。   boolean hasPrevious()  //返回 true如果遍历反向列表,列表迭代器有多个元素。   E next()  //返回列表中的下一个元素,并且前进光标位置。   int nextIndex()  //返回随后调用 next()返回的元素的索引。   E previous()  //返回列表中的上一个元素,并向后移动光标位置。   int previousIndex()  //返回由后续调用 previous()返回的元素的索引。   void remove()  //从列表中删除由 next()或 previous()返回的最后一个元素(可选操作)。   void set(E e)  //用 指定的元素替换由 next()或 previous()返回的最后一个元素(可选操作)。  

集合框架为什么选择实现Interable接口

  • 如果实现Interator接口
    • Interator接口核心方法next()和hasNext()依赖于迭代器的迭代位置,为了解决这个问题在集合对象中势必要包含迭代位置,
    • 迭代后迭代位置是未知的,那么有需要一个reset()方法来重置迭代位置
    • 除此之外这种方法不支持多个迭代器并行迭代(不得不说这种解决方法缺陷很大)
  • 如果实现Interable接口
    • 集合对象不包含迭代位置,降低了耦合度
    • 集合对象的迭代依赖于iterator()返回的迭代器,多个迭代器互不干扰,也就是说解决了迭代位置的未知性和不可并行迭代的问题

Collection

public interface Collection<E> extends Iterable<E>

集合Collection是一个接口,高度抽象了集合应该有的共性方法,实现了Iterable接口

部分接口方法

boolean add(E e)  //先集合中添加一个元素     void clear()  //删除集合中所有元素   boolean contains(Object o)  //判断集合中是否包含元素o     boolean equals(Object o)  //将指定的对象与此集合进行比较以获得相等性。   int hashCode()  //返回此集合的哈希码值。   boolean isEmpty()  //如果此集合不包含元素,则返回 true 。   Iterator<E> iterator()  //返回此集合中的元素的迭代器。  。   boolean remove(Object o)  //从该集合中删除指定元素的单个实例(如果存在)(可选操作)。     int size()  //返回此集合中的元素数。   Object[] toArray()  //返回一个包含此集合中所有元素的数组。

AbstractCollection

public abstract class AbstractCollection<E> extends Object implements Collection<E>

AbstractCollection是一个抽象类,实现了Collection的许多常见方法,继承起来更为方便(不用一一实现Collection中的方法)

抽象方法

abstract Iterator<E> iterator()  //返回包含在该集合中的元素的迭代器。    abstract int size()  //返回此集合中的元素数。  

List

public interface List<E> extends Collection<E>

List接口也称为有序序列,用户可以通过整数索引操作元素

由图中可以看出List依赖于ListIterator,也就是说实现接口List的类支持ListIterator的迭代方法

特有方法

E get(int index)  //返回此列表中指定位置的元素。 int indexOf(Object o)  //返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。 ListIterator<E> listIterator()  //返回列表中的列表迭代器。 ListIterator<E> listIterator(int index)  //表中的指定位置开始,返回列表中的元素(按正确顺序)的列表迭代器。  E remove(int index)  //该列表中指定位置的元素(可选操作)。  E set(int index, E element)  //定的元素替换此列表中指定位置的元素。  List<E> subList(int fromIndex, int toIndex)  //此列表中指定的 fromIndex (含)和 toIndex之间的视图。 

AbstractList

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>

AbstractList是一个抽象类,在AbstractCollection的基础上又实现了一些List的方法

抽象方法

abstract E get(int index)  //返回此列表中指定位置的元素。  

AbstractSequentialList

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>

AbstractSequentialList也是抽象类,顾名思义底层是链表

抽象方法

abstract E get(int index)  //返回此列表中指定位置的元素。 

List子类对比

List子类 底层 线程安全
ArrayList 数组
Vector 数组
LinkedList 链表
  • 查询多用ArrayList
  • 增删多用LinkedList
  • 如果都多ArrayList

Map

public interface Map<K,V>

Map也就是键值对,该接口定义了所有map的共性方法

Map值可以重复,但键不可以重复.

部分接口方法

void clear()  //从该地图中删除所有的映射。   boolean containsKey(Object key)  //如果此映射包含指定键的映射,则返回 true 。   boolean containsValue(Object value)  //如果此地图将一个或多个键映射到指定的值,则返回 true 。   Set<Map.Entry<K,V>> entrySet()  //返回此地图中包含的映射的Set视图。   boolean equals(Object o)  //将指定的对象与此映射进行比较以获得相等性。   V get(Object key)  //返回到指定键所映射的值,或 null如果此映射包含该键的映射。     int hashCode()  //返回此地图的哈希码值。   boolean isEmpty()  //如果此地图不包含键值映射,则返回 true 。   Set<K> keySet()  //返回此地图中包含的键的Set视图。   V remove(Object key)  //如果存在,从该地图中删除一个键的映射。   int size()  //返回此地图中键值映射的数量。   Collection<V> values()  //返回此地图中包含的值的Collection视图。 

AbstractMap

public abstract class AbstractMap<K,V> extends Object implements Map<K,V>

AbstractMap是一个抽象类,实现了许多Map接口的方法

抽象方法

abstract Set<Map.Entry<K,V>> entrySet()  //返回此地图中包含的映射的Set视图。

SortedMap

public interface SortedMap<K,V> extends Map<K,V>

SortedMap接口在Map基础之上进行排序,要实现此功能必须实现Comparable接口

部分接口方法

Comparator<? super K> comparator()  //返回用于订购此地图中的键的比较器,或null如果此地图使用其键的natural ordering 。   K firstKey()  //返回此地图中当前的第一个(最低)键。   SortedMap<K,V> headMap(K toKey)  //返回该地图的部分密钥严格小于 toKey 。   Set<K> keySet()  //返回此地图中包含的键的Set视图。   K lastKey()  //返回当前在此地图中的最后(最高)键。   SortedMap<K,V> subMap(K fromKey, K toKey)  //返回此地图部分的视图,其关键字范围为 fromKey (含),不 toKey toKey。   SortedMap<K,V> tailMap(K fromKey)  //返回此地图部分的视图,其键大于或等于 fromKey 。  

Map子类对比

Map子类 线程安全 迭代顺序 存取效率
HashMap 规律 O(1)
TreeMap 自然顺序 Olog(n)
LinkedhashMap 插入顺序 O(1)

可以用 Collections的synchronizedMap方法使HashMap具有同步的能力,或者使用ConcurrentHashMap。

Hashtable是线程安全的,但效率低

Set

public interface Set<E> extends Collection<E>

Set不包含重复元素,也不存在索引,元素的插入顺序可能和实际顺序无关

其实Set很大一部分依赖于Map,Map去掉值就是Map

//HashSet的构造函数 public HashSet() {         map = new HashMap<>(); }

部分接口方法

boolean add(E e)  //如果指定的元素不存在,则将其指定的元素添加.   void clear()  //从此集合中删除所有元素(可选操作)。   boolean contains(Object o)  //如果此集合包含指定的元素,则返回 true 。     boolean equals(Object o)  //将指定的对象与此集合进行比较以实现相等。   int hashCode()  //返回此集合的哈希码值。   boolean isEmpty()  //如果此集合不包含元素,则返回 true 。   Iterator<E> iterator()  //返回此集合中元素的迭代器。   boolean remove(Object o)  //如果存在,则从该集合中删除指定的元素(可选操作)。     int size()  //返回此集合中的元素数(其基数)。   Object[] toArray()  //返回一个包含此集合中所有元素的数组。  

AbstractSet

public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E>

AbstractSet抽象类继承了AbstractCollection,构成了Set的最小骨干

SortedSet

public interface SortedMap<K,V> extends Map<K,V>

SortedSet接口在Set基础之上进行排序,要实现此功能必须实现Comparable接口

部分接口方法

Comparator<? super E> comparator()  //返回用于对该集合中的元素进行排序的比较器,或null,如果此集合使用其元素的natural ordering 。   E first()  //返回此集合中当前的第一个(最低)元素。   SortedSet<E> headSet(E toElement)  //返回该集合的部分的视图,其元素严格小于 toElement 。   E last()  //返回此集合中当前的最后(最高)元素。   default Spliterator<E> spliterator()  //在此排序集中的元素上创建一个 Spliterator 。   SortedSet<E> subSet(E fromElement, E toElement)  //返回该集合的部分的视图,其元素的范围为 fromElement (含),为 toElement ,独占。   SortedSet<E> tailSet(E fromElement)  //返回此组件的元素大于或等于 fromElement的部分的视图。 

Set子类对比

Set子类 线程安全 迭代顺序 存取效率
HashSet 规律 O(1)
TreeSet 自然顺序 Olog(n)
LinkedhashSet 插入顺序 O(1)

HashMap和HashSet

Map的键不可以重复,Set的元素不可以重复,这个特点是通过equals方法来判断的,而在HashMap和HashSet中重复判断稍稍不同

在HashMap和HashSet中每添加一个新元素会先调用hashCode()查看集合中是否有和新元素一样哈希值的元素,如果没有就将其添加;如果有再调用equals()来判断两者是否相同,相同则不添加,反之添加.因为哈希值不同对象一定不同,哈希值相同对象可能不同)

必要时重写equals()和hashCode()

st=>start: 新元素 t=>operation: 添加 d=>operation: 丢弃 cond1=>condition: 哈希值相同 cond2=>condition: 内容相同 e=>end  st->cond1 cond1(yes)->cond2(yes)->d cond1(yes)->cond2(no)->t cond1(no)->t
import java.util.*; class Cat{     public int no;     public String name;     Cat(int no,String name){         this.no=no;         this.name=name;     }     Cat(){}     @Override     public String toString() {         return "no:"+no+",name:"+name;     }      @Override     public boolean equals(Object o) {         if (this == o) return true;         if (o == null || getClass() != o.getClass()) return false;         Cat cat = (Cat) o;         return no == cat.no &&                 Objects.equals(name, cat.name);     }      @Override     public int hashCode() {         return Objects.hash(no, name);     } } public class Demo {     public static void main(String args[]){         HashSet<Cat> hc=new HashSet<>();         hc.add(new Cat(1,"花花"));         hc.add(new Cat(2,"小黑"));         for(Cat c:hc)             System.out.println(c);     } }

TreeMap和TreeSet

TreeMap和TreeSet会对添加的元素进行排序,这依赖于Comparable接口的实现,或者在构造TreeMap或TreeSet时传递Comparator对象

后者是为了解决某些类(final 类)不能实现Comparable接口

import java.util.*; class Cat implements Comparable<Cat>{     public int no;     public String name;     Cat(int no,String name){         this.no=no;         this.name=name;     }     Cat(){}     @Override     public String toString() {         return "no:"+no+",name:"+name;     }      @Override     public boolean equals(Object o) {         if (this == o) return true;         if (o == null || getClass() != o.getClass()) return false;         Cat cat = (Cat) o;         return no == cat.no &&                 Objects.equals(name, cat.name);     }      @Override     public int compareTo(Cat c) {         //返回正数表示该对象大于c,返回0表示二者相等,返回负数表述该对象小于c         return no-c.no;     } } public class Demo {     public static void main(String args[]){         TreeSet<Cat> hc=new TreeSet<>();         hc.add(new Cat(1,"花花"));         hc.add(new Cat(3,"大米"));         hc.add(new Cat(2,"小黑"));         for(Cat c:hc)             System.out.println(c);     } }

Collections工具类

void reverse(List list)//反转 void shuffle(List list)//随机排序 void sort(List list)//按自然排序的升序排序 void sort(List list, Comparator c)//定制排序,由Comparator控制排序逻辑 void swap(List list, int i , int j)//交换两个索引位置的元素 void rotate(List list, int distance)//旋转。当distance为正数时,将list后distance个元素整体移到前面。当distance为负数时,将 list的前distance个元素整体移到后面。 int binarySearch(List list, Object key)//对List进行二分查找,返回索引,注意List必须是有序的 int max(Collection coll)//根据元素的自然顺序,返回最大的元素。 类比int min(Collection coll) int max(Collection coll, Comparator c)//根据定制排序,返回最大元素,排序规则由Comparatator类控制。类比int min(Collection coll, Comparator c) void fill(List list, Object obj)//用指定的元素代替指定list中的所有元素。  int frequency(Collection c, Object o)//统计元素出现次数 int indexOfSubList(List list, List target)//统计target在list中第一次出现的索引,找不到则返回-1,类比int lastIndexOfSubList(List source, list target). boolean replaceAll(List list, Object oldVal, Object newVal)//用新元素替换旧元素

Arrays工具类

sort()//排序 binarySearch()//二叉查找 equals()//比较 fill()//填充 static <T> List<T> asList(T... a) //返回由指定数组支持的固定大小的列表。  toString()//转字符串
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!