Collection集合
List 有序集合,允许重复的元素
ArrayList:底层用Object数组实现,特点是查询效率高,增删效率低,线程不安全
LinkedList:底层使用双向循环链表实现,特点是查询效率低,增删效率高,线程不安全,因为线程不同步
Vector:底层用长度可以动态增长的对象数组实现,它的相关方法用 Synchronized 进行了线程同步,所以线程安全,效率低
Stack:栈。特点是:先进后出。继承于Vector
Set 无序集合,不允许重复的元素
HashSet:底层用HashMap实现,本质是一个简化版的HashMap,因此查询效率和增删效率都比较高。其add方法就是在map中增加一个键值对,键对象就是这个元素,值对象是PRESENT的对象
LinkedHashSet:继承自HashSet,内部使用的是LinkHashMap。这样做的意义或者好处就是LinkedHashSet中的元素顺序是可以保证的,也就是说遍历序和插入序是一致的。
TreeSet:底层用TreeMap实现,底层是一种二叉查找树(红黑树),需要对元素做内部排序。内部维持了一个简化版的TreeMap,并通过key来存储Set元素。使用时,要对放入的类实现Comparable接口,且不能放入null
Map集合
HashMap:采用散列算法来实现,底层用哈希表来存储数据,因此要求键不能重复。线程不安全,HashMap在查找、删除、修改方面效率都非常高。允许key或value为null
HashTable:与HashMap类似,只是其中的方法添加了synchronized关键字以确保线程同步检查,线程安全,但效率较低。不允许key或value为null
TreeMap:红黑树的典型实现。TreeMap和HashMap实现了同样的接口Map。在需要Map中Key按照自然排序时才选用TreeMap
ConcurrentHashMap
Collection是一个集合接口,它提供了对集合对象进行基本操作的通用接口方法,所有集合都是它的的子类,比如List,Set等
Collections是一个包装类,包含了很多静态方法,不能被实例化,就像一个工具类,比如提供的排序方法,Collections.sort(list)
List,Set,Map之间的区别主要体现在两个方面:元素是否有序,是否允许元素重复
存储:HashMap允许key和value为null,HashTable不允许
线程安全:HashMap线程不安全,HashTable安全
推荐使用:在 Hashtable 的类注释可以看到,Hashtable 是保留类不建议使用,推荐在单线程环境下使用 HashMap 替代,如果需要多线程使用则用 ConcurrentHashMap 替代。
对于在Map中插入,删除,定位一个元素这类操作,HashMap是最好的选择,因而相对而言HashMap插入会更快,但是如果要对一个key集合进行有序的遍历,那TreeMap是更好的选择
HashMap是基于Hash算法实现的,我们通过put(key,value)存储,get(key)来获取。当传入key值时,HashMap通过 key. hashCode() 计算出 hash 值,根据 hash 值将 value 保存在 bucket 里。当计算出的 hash 值相同时,我们称之为 hash 冲突,HashMap 的做法是用链表和红黑树存储相同 hash 值的 value。当 hash 冲突的个数比较少时,使用链表否则使用红黑树。
HashSet 是基于 HashMap 实现的,HashSet 底层使用 HashMap 来保存所有元素,因此 HashSet 的实现比较简单,相关 HashSet 的操作,基本上都是直接调用底层 HashMap 的相关方法来完成,HashSet 不允许重复的值
数据结构实现:ArrayList是动态数组的数据结构实现,而LinkedList是双向链表的数据结构实现
随机访问效率:ArrayList在随机访问时的效率要比Linkedlist高,因为LinkedList是线性的数据存储方式,因此访问时需要从前往后的依此查找
增加和删除效率:在非首尾的增加和删除操作,LinkedList要比ArrayList效率高,因为ArrayList的增删操作会影响数组中其他数据的下标
综上来说,在需要频繁读取集合中的数据时,更推荐使用ArrayList,而在插入和删除操作较多时,更推荐LinkedList
数组转List:使用Arrays.asList(array)进行转换
List转数组:使用List自带的toArray( )方法
代码示例
//array to list
String[] array = new String[]{"马文成","的博客"};
Arrays.asList(str);
//list to array
List<String> list = new ArrayList<String>();
list.add("马文成");
list.add("的博客");
list.toArray();
线程安全:Vector使用了Synchronized来实现线程同步,是线程安全的,而ArrayList是线程不安全的
性能:ArrayList在性能方面要强于Vector
扩容:ArrayList和Vector都会根据实际的需求动态的调整容量。只不过Vector每次扩容会增加1倍,而ArrayList每次只会增加50%
Array可以存储基本数据类型和对象,而ArrayList只能存储对象
Array是指定固定大小的,而ArrayList大小是自动扩展的
Array内置方法比ArrayList多,比如addAll,removeAll,iteration等方法
相同点:都是返回第一个元素,并在队列中删除返回的对象
不同点:如果没有元素poll()会返回null,而remove()会直接抛出NoSuchElementException 异常。
代码示例:
Queue<String> queue = new LinkedList<String>();
queue. offer("string"); // add
System. out. println(queue. poll());
System. out. println(queue. remove());
System. out. println(queue. size());
Vector,Stack,HashTable都是线程安全的,而像 HashMap 则是非线程安全的,不过在 JDK 1.5 之后随着 Java. util. concurrent 并发包的出现,它们也有了自己对应的线程安全类,比如 HashMap 对应的线程安全类就是 ConcurrentHashMap。
Iterator提供遍历所有Collection的接口,我们可以从Collection中使用迭代器方法获取迭代器实例,迭代器取代了Java集合框架中的Enumeration,迭代器允许调用者在迭代过程中移除元素。
Iterator使用代码如下:
List<String> list = new ArrayList<String>();
Iterator iterator = list.Iteractor();
while(iterator.hasNext){
String obj = iterator.next();
System.out.println(obj);
}
Iterator的特点是更加安全,因为它可以确保,当前遍历的集合元素被更改的时候,就会抛出 ConcurrentModificationException 异常。
Iterator可以遍历List和Set,而ListIterator只能遍历List
Iterator只能单向遍历,而ListIterator可以双向遍历
ListIterator从Iterator接口继承,然后添加了一些额外的功能,比如添加一个元素,替换一个元素,获取前面或后面元素的索引位置
可以使用 Collections. unmodifiableCollection(Collection c) 方法来创建一个只读集合,这样改变集合的任何操作都会抛出 Java. lang. UnsupportedOperationException 异常。
示例代码如下:
List<String> list = new ArrayList<>();
list. add("x");
Collection<String> clist = Collections. unmodifiableCollection(list);
clist. add("y"); // 运行时此行报错
System. out. println(list. size());
java
List list = new ArrayList<>();
list. add(“x”);
Collection clist = Collections. unmodifiableCollection(list);
clist. add(“y”); // 运行时此行报错
System. out. println(list. size());