Java集合--对比的视角

单线程类集合

List

继承自Conllection
元素以线性方式存储,集合中可以存放重复对象。

  • ArrayList:底层基于动态数组,多用于随机访问。
  • LinkedList:底层基于链表,多适用于插入删除操作。

Map

元素以键值对的形式存储
基本同样接口Map,但是行为、效率、排序策略、保存对象的生命周期和判定“键”等价的策略等各不相同。标准Java类库定义了HashMap, TreeMap, LinkedHashMap, WeakHashMap, IdentityHashMap。

  • HashMap:底层基于散列表实现
  • LinkedHashMap:类似于HashMap,但是迭代遍历它时,取得“键值对”的顺序是其插入次序,或者是最近最少使用(LRU)的次序。只比HashMap慢一点。而在迭代访问时发而更快,因为它使用链表维护内部次序。
  • TreeMap:基于红黑树数据结构(二叉查找树)的实现。查看“键”或“键值对”时,它们会被排序(次序由Comparabel或Comparator决定)。主要特点在于,得到的结果是经过排序的。TreeMap是唯一的带有subMap()方法的Map,它可以返回一个子树。
  • WeakHashMap:弱键(weak key)Map,Map中使用的对象也被允许释放: 这是为解决特殊问题设计的。如果没有map之外的引用指向某个“键”,则此“键”可以被垃圾收集器回收。适用于构建缓存场景。
  • IdentityHashMap:使用==代替equals()对“键”作比较的hash map

Set

继承自Conllection
真正数学意义上的集合抽象,不包含重复元素,更准确的说是不满足e1.equals(e2)的元素。
从实现方式上来看,Set很像Map的马甲。

  • HashSet:基于HashMap的Set实现。底层基于散列表,为实现快速查找
  • LinkedHashSet:基于LinkHashMap实现,具有与HashSet同样的查询速度,内部使用链表维护元素的插入的次序。
  • TreeSet:类似于TreeMap,底层基于树型结构,保存次序的Set
  • EnumSet:值为枚举类型的Set。
  • BitSet:值为比特类型的Set。

Queue/Deques

  • ArrayDeque:Deque是基于有首尾指针的数组(环形缓冲区)实现的。和LinkedList
    不同,这个类没有实现List接口。因此,如果没有首尾元素的话就不能取出任何元素。这个类比LinkedList要好一些,因为它产生的垃圾数量较少(在扩展的时候旧的数组会被丢弃)。
  • Stack:一种后进先出的队列。不要在生产代码中使用,使用别的Deque来代替(ArrayDeque比较好)。
  • PriorityQueue:一个基于优先级的队列。使用自然顺序或者制定的比较器来排序。他的主要属性——poll/peek/remove/element会返回一个队列的最小值。同样PriorityQueue还实现了Iterable接口,队列迭代时不进行排序(或者其他顺序)。在需要排序的集合中,使用这个队列会比TreeSet等其他队列要方便。

并发类线程类集合

List

  • CopyOnWriteArrayList:list的实现每一次更新都会产生一个新的隐含数组副本,所以这个操作成本很高。通常用在遍历操作比更新操作多的集合,比如listeners/observers
    集合。

Queues/deques

  • ArrayBlockingQueue:基于数组实现的一个有界阻塞队,大小不能重新定义。所以当你试图向一个满的队列添加元素的时候,就会受到阻塞,直到另一个方法从队列中取出元素。
  • ConcurrentLinkedDeque / ConcurrentLinkedQueue:基于链表实现的无界队列,添加元素不会堵塞。但是这就要求这个集合的消费者工作速度至少要和生产这一样快,不然内存就会耗尽。严重依赖于CAS(compare-and-set)操作。
  • DelayQueue:无界的保存Delayed
    元素的集合。元素只有在延时已经过期的时候才能被取出。队列的第一个元素延期最小(包含负值——延时已经过期)。当你要实现一个延期任务的队列的时候使用(不要自己手动实现——使用ScheduledThreadPoolExecutor)
  • LinkedBlockingDeque / LinkedBlockingQueue:可选择有界或者无界基于链表的实现。在队列为空或者满的情况下使用ReentrantLock-s
  • LinkedTransferQueue:基于链表的无界队列。除了通常的队列操作,它还有一系列的transfer
    方法,可以让生产者直接给等待的消费者传递信息,这样就不用将元素存储到队列中了。这是一个基于CAS操作的无锁集合。
  • PriorityBlockingQueue:PriorityQueue的无界的版本。
  • SynchronousQueue:一个有界队列,其中没有任何内存容量。这就意味着任何插入操作必须等到响应的取出操作才能执行,反之亦反。如果不需要Queue接口的话,通过Exchanger类也能完成响应的功能。

Maps

  • ConcurrentHashMap:get操作全并发访问,put操作可配置并发操作的哈希表。并发的级别可以通过构造函数中concurrencyLevel参数设置(默认级别16)。该参数会在Map内部划分一些分区。在put操作的时候只有更新的分区是锁住的。这种Map不是代替HashMap的线程安全版本——任何 get-then-put的操作都需要在外部进行同步。
  • ConcurrentSkipListMap:基于跳跃列表(Skip List)的ConcurrentNavigableMap实现。本质上这种集合可以当做一种TreeMap的线程安全版本来使用。

Sets

  • ConcurrentSkipListSet:存储线程安全的Set。
  • CopyOnWriteArraySet:存储线程安全的Set。

集合工具

Arrays:Java中专门用来处理数组的工具

  • Arrays.asList:可以从 Array 转换成 List。可以作为其他集合类型构造器的参数。
  • Arrays.sort:对整个数组或者数组的一部分进行排序。也可以使用此方法用给定的比较器对对象数组进行排序。
  • Arrays.toString:打印数组的内容。

Collections:Java中专门用来处理集合的工具

  • Collections.addAll:添加一些元素或者一个数组的内容到集合中。
  • Collections.disjoint:检查两个集合是不是没有相同的元素。
  • Collections.fill:用一个指定的值代替集合中的所有元素。
  • Collections.frequency:集合中有多少元素是和给定元素相同的。
  • Collections.replaceAll:将集合中的某一元素替换成另一个元素。
  • Collections.reverse:颠倒排列元素在集合中的顺序。如果你要在排序之后使用这个方法的话,在列表排序时,最好使用Collections.reverseOrder
    比较器。
  • Collections.rotate:根据给定的距离旋转元素。
  • Collections.sort:将集合按照自然顺序或者给定的顺序排序。
  • Collections.swap:交换集合中两个元素的位置(多数开发者都是自己实现这个操作的)。

集合相关的面试题

请简单介绍些Java 集合

List、Set、Map是这个集合体系中最主要的三个接口。其中List和Set继承自Collection接口。Set不允许元素重复。HashSet和TreeSet是两个主要的实现类。List有序且允许元素重复。ArrayList、LinkedList和Vector是三个主要的实现类。Map和Collection接口不同。Map是key对value的映射集合,其中key列就是一个集合。key不能重复,但是value可以重复。HashMap、TreeMap和Hashtable是三个主要的实现类。

Comparable和Comparator区别

  • Comparable:可以认为内部比较器,实现了Comparable接口的类有一个特点,就是这些类是可以和自己比较的,至于具体和另一个实现了Comparable接口的类如何比较,则依赖compareTo方法的实现,compareTo方法也被称为自然比较方法。如果开发者add进入一个Collection的对象想要Collections的sort方法帮你自动进行排序的话,那么这个对象必须实现Comparable接口。compareTo方法的返回值是int,
  • Comparator:可以认为外比较器,在这两种情况下:
  • 一个对象不支持自己和自己比较(没有实现Comparable接口),但是又想对两个对象进行比较
  • 一个对象实现了Comparable接口,但是开发者认为compareTo方法中的比较方式并不是自己想要的那种比较方式
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容

  • 1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:V...
    Oneisall_81a5阅读 899评论 0 11
  • 1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:V...
    独念白阅读 761评论 0 2
  • java笔记第一天 == 和 equals ==比较的比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量...
    jmychou阅读 1,490评论 0 3
  • 1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:V...
    hutuxiaogui阅读 677评论 0 10
  • 雪..冬 你问我,我为什么喜欢冬日。我说:因为我喜欢雪,我喜欢一个人站在雪地里,感触那一刻的静谧,我喜欢让飘舞的绒...
    小汐丫头阅读 217评论 0 0