时间: 2020-09-18|47次围观|0 条评论

一张图诠释Java集合插图
注:蓝色背景都是接口,非蓝色背景实现类

Collection 和 Collections的区别

Collection
是java.util包下的一个集合接口,它是各种集合结构的父接口。
它提供了对集合对象进行基本操作的通用接口方法
Collection接口在Java 类库中有很多具体的实现
Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。

Collections
是java.util包下的一个包装类,它包含有各种有关集合操作的静态方法。
此类不能实例化,是一个服务于Java的Collection框架的工具类。

Collections类的常见方法

addAll(Collection<? super T> c, T... elements)  将所有指定元素添加到指定 collection 中。
binarySearch    使用二分搜索法搜索指定列表,以获得指定对象。
max     根据元素的自然顺序,返回给定 collection 的最大元素。
min     根据元素的自然顺序 返回给定 collection 的最小元素。
reverse(List<?> list)   反转指定列表中元素的顺序。
shuffle(List<?> list)   使用默认随机源对指定列表进行置换。
shuffle(List<?> list, Random rnd)   使用指定的随机源对指定列表进行置换。
sort(List<T> list)  根据元素的自然顺序 对指定列表按升序进行排序。 
sort(List<T> list, Comparator<? super T> c)     根据指定比较器产生的顺序对指定列表进行排序。 
swap(List<?> list, int i, int j)    在指定列表的指定位置处交换元素。 

List, Set, Map是否继承自Collection接口?

List,Set是
Map不是

public interface Map<K,V> {}

什么类不需要实例化?

完全用来提供静态工具方法的类型,不需要被实例化。在JDK中,有几个典型。比如java.util.Arrays,java.util.Collections,java.lang.Math。

通过私有构造方法来加强化不可实例化的性质。

public class Arrays {  
    // Suppresses default constructor, ensuring non-instantiability. 
    private Arrays() {  
    }  
}  

public class Collections {  
    // Suppresses default constructor, ensuring non-instantiability. 
    private Collections() {  
    } 
}  

public final class Math {  
    /** * Don't let anyone instantiate this class. */  
    private Math() {
    }  
}

List

一元操作,有序可重复。

ArrayList 底层实现是数组,线程不安全,效率高
LinkedList 底层实现是双向链表,线程不安全,效率高
Vector 底层实现是数组,线程安全,效率低

Stack 底层实现是数组,线程安全

public class Stack<E> extends Vector<E> {
    public E push(E item) {
    }
    public synchronized E pop() {
    }
    public synchronized E peek() {
    }
    public synchronized int search(Object o) {
    }   
}

注:push方法并没有同步,而其他方法,如pop,peek,search方法,使用了同步。

Map

二元操作,存放<key,value>对。
底层实现是数组+链表。

HashMap 底层实现是哈希表
Hashtable 底层实现是哈希表
ConcurrentHashMap 底层实现是散列表
TreeMap 底层实现是红黑树
ConcurrentSkipListMap 底层实现是跳表
WeakHashMap 底层是以弱键实现的基于哈希表的Map

Hashmap的扩容机制

底层默认的数组大小是16,负载因子为0.75。
当达到16*0.75=12时,数组容量扩大一倍,就会重新hash。

HashMap与Hashtable区别

HashMap:线程不安全,效率高。key可以有一个null,value可以有多个null。
Hashtable:线程安全,效率低。key,value都不能为null。
Hashtable有个子类Properties(资源配置文件,相对路径获取文件。)

Hashtable与ConcurrentHashMap的区别

相同点:它们都是线程安全的。
不同点:
Hashtable是将整个结构都锁住,安全的同时,也带来了巨大的开销。而ConcurrentHashMap是将整个结构进行分桶,底层源码默认的是16个桶,然后对桶进行锁定。这样的话,并发性更高。

TreeMap与ConcurrentSkipListMap的区别

1、跳表是随机化的数据结构:
空间复杂度:O(n)
查找、插入和删除操作的时间复杂度都为: O(logn)
红黑树这样的平衡数据结构查找的时间复杂度也是O(logn)。

2、要实现像红黑树这样的数据结构并非易事,
但是只要你熟悉链表的基本操作,再加之对跳表原理的理解,实现一个跳表数据结构相对更加简单。

3、跳跃表在并发环境下有优势。
在并发环境下,如果要更新数据,跳跃表需要更新的部分就比较少,锁的东西也就比较少,所以不同线程争锁的代价就相对少了,
而红黑树有个平衡的过程,牵涉到大量的节点,争锁的代价也就相对较高了。性能也就不如前者了。

HashMap与WeakHashMap的区别

HashMap、WeakHashMap允许键和值是null。
HashMap、WeakHashMap都没有同步机制,线程不安全。
WeakHashMap会检查各元素是否“常用”,如果“不常用”会自动从WeakHashMap对象中删除,而HashMap没有这种自动检查、删除机制;

WeakHashMap实现了Map接口,是HashMap的一种实现,他使用弱引用作为内部数据的存储方案,WeakHashMap可以作为简单缓存表的解决方案,当系统内存不够的时候,垃圾收集器会自动的清除没有在其他任何地方被引用的键值对。
如果需要用一张很大的HashMap作为缓存表,那么可以考虑使用WeakHashMap,当键值不存在的时候添加到表中,存在即取出其值。

Set

一元操作,无序不可重复。
Set的底层实现是Map,Set的不可重复性正是利用了Map的key不可重复。

Queue与Deque

Queue 单向队列,先进先出。
Deque 双向队列

PriorityQueue 底层实现是小顶堆。默认是每次最小值出队列,如果想最大值出队列,可以通过Comparator接口进行控制。
ArrayDeque 底层实现是数组。

ArrayBlockingQueue和LinkedBlockingQueue的区别

ArrayBlockingQueue 定长的缓冲队列
LinkedBlockingQueue 无界的缓冲队列
1、 队列中锁的实现不同
ArrayBlockingQueue实现的队列中的锁是没有分离的,即生产和消费用的是同一个锁;
LinkedBlockingQueue实现的队列中的锁是分离的,即生产用的是putLock,消费是takeLock

2、 在生产或消费时操作不同
ArrayBlockingQueue实现的队列中在生产和消费的时候,是直接将枚举对象插入或移除的;
LinkedBlockingQueue实现的队列中在生产和消费的时候,需要把枚举对象转换为Node<E>进行插入或移除,会影响性能。

3、队列大小初始化方式不同
ArrayBlockingQueue实现的队列中必须指定队列的大小;
LinkedBlockingQueue实现的队列中可以不指定队列的大小,但是默认是Integer.MAX_VALUE

注意:
1、在使用LinkedBlockingQueue时,若用默认大小且当生产速度大于消费速度时候,有可能会内存溢出。
2、在使用ArrayBlockingQueue和LinkedBlockingQueue分别对1000000个简单字符做入队操作时,LinkedBlockingQueue的消耗是ArrayBlockingQueue消耗的10倍左右,
即LinkedBlockingQueue消耗在1500毫秒左右,ArrayBlockingQueue只需150毫秒左右。

PriorityBlockingQueue

它是无界阻塞队列,容量是无限的,它使用与类PriorityQueue相同的顺序规则。
它是线程安全的,是阻塞的
不允许使用 null 元素。
对于put(E o)和offer(E o, long timeout, TimeUnit unit),由于该队列是无界的,所以此方法永远不会阻塞。
因此参数timeout和unit没意义,会被忽略掉。
iterator() 方法中所提供的迭代器并不保证以特定的顺序遍历 PriorityBlockingQueue 的元素。如果需要有序地遍历,则应考虑使用 Arrays.sort(pq.toArray())。

原文链接:https://blog.csdn.net/scgaliguodong123_/article/details/48862263

本站声明:网站内容来源于网络,如有侵权,请联系我们,我们将及时处理。

本博客所有文章如无特别注明均为原创。
复制或转载请以超链接形式注明转自起风了,原文地址《一张图诠释Java集合
   

还没有人抢沙发呢~