List/Set/Map是什么
数据容器
先从计算机逻辑上来讲「List」「Set」「Map」三个都属于数据容器,这个容器的概念和Web容器是不一样的,但是总体来讲复合「什么叫做容器」这篇文章里我主张的容器的概念。
数据容器的主要特征是
- 有增删功能
- 内存空间是可变的
接口Interface
然后从定义上来讲,这三个都属于接口,也就是说是一个抽象表达,并不是具体的Class,每一个都有多种可能的实现,并且可以对实现了该接口的实例进行指向。可以参考另一片文章「Java和OC中Interface/Implement/Protocol」
List/Set
Collection接口
List和Set均间接实现了「Collection」「Iterable」接口
public interface Collection<E> extends Iterable<E> {}
public interface List<E> extends Collection<E> {}
public interface Set<E> extends Collection<E> {}
List的实现
根据查询源代码implements了List协议的Class有以下三个
- @see ArrayList
- @see LinkedList
- @see Vector
查看定义
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, Serializable {}
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable {}
public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable {}
其中「AbstractList」「AbstractSequentialList」是作为它们的基类,而这两个是抽象类,抽象类和接口的关系同样可以参考「Java和OC中抽象类接口和协议」。
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {}
public abstract class AbstractSequentialList<E> extends AbstractList<E> {}
所以说在使用List的时候,List可以当作通用指针,指向不同的new
List array = new ArrayList<>();
List linked = new LinkedList();
List vector = new Vector();
Set的实现
根据源代码「直接或间接」implements了Set协议的Class有以下两个
- @see HashSet
- @see TreeSet
定义
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, Serializable {}
public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, Serializable {}
之所以说是间接,是因为NavigableSet继承于Set
public interface SortedSet<E> extends Set<E> {}
public interface NavigableSet<E> extends SortedSet<E> {}
而它们的基类全部继承于一个抽象类「AbstractSet」
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {}
同List一样我们可以通过Set作为通用指针指向不同的new
Set hashSet = new HashSet();
Set treeSet = new TreeSet();
Map
Map没有实现Collection接口
通过Map的接口定义可以看到其和List/Set最大的不同是没有实现Collection接口
public interface Map<K,V> {}
Map的实现
根据源代码「直接或间接」implements了Map协议的Class有以下三个
public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>, Cloneable, Serializable {}
public class TreeMap<K, V> extends AbstractMap<K, V> implements NavigableMap<K, V>, Cloneable, Serializable {}
public class Hashtable<K, V> extends Dictionary<K, V> implements Map<K, V>, Cloneable, Serializable {}
同Set一样,间接的原因是
public interface NavigableMap<K,V> extends SortedMap<K,V> {}
public interface SortedMap<K,V> extends Map<K,V> {}
而它们的基类全部继承于两个不同的抽象类「AbstractMap」「Dictionary」
public abstract class AbstractMap<K, V> implements Map<K, V> {}
public abstract class Dictionary<K,V> {}
可以使用Map作为通用指针指向任意一个new
Map hashMap = new HashMap();
Map treeMap = new TreeMap();
Map hashTable = new Hashtable();
HashMap和Hashtable的区别
为什么会有两个不同的抽象类呢,与List不管哪个类都继承于「AbstractList」抽象类不一样,「AbstractMap」和「Dictionary」没有任何关系。
通过查询资料得知Dictionary是比较老的版本提出的的,但是凭不是说其过时了
HashMap | Hashtable | |
---|---|---|
基类 | AbstractMap | Dictionary |
是否同步 | 否 | 是 |
K/V是否可为null | 是 | 否 |
通过以上表格可以知道,由于Dictionary是同步的,所以是线程安全的。