Java Collections框架


Java Collections框架中包含了大量集合接口以及这些接口的实现类和操作它们的算法(例如排序、查找、反转、替换、复制、取最小元素、去最大元素),主要提供了List(列表)、Queue(队列)、Set(集合)、Stack(栈)和Map(映射表,用于存放键值对)等数据结构。其中,List、Queue、Set、Stack都继承自Collection接口。

  • Set表示数学意义上的集合概念。其最主要的特点是集合中的元素不能重复,一次存入Set的每个元素都必须定义equals()方法来确保对象的唯一性。该接口有两个实现类:HashSet和TreeSet。TreeSet实现了SortedSet接口,因此TreeSet容器中的元素是有序的。
  • List又称为有序的Collection。它按对象进入的顺序保存对象,所以它能对列表中的每个的插入和删除位置进行精确的控制,同时可以保存重复的对象。LinkedList、ArrayList和Vector都实现了List接口。
  • Map提供了一个从键映射到值得数据结构。它用于保存键值对,其中值可以重复,但是键是唯一的,不能重复。Java类库中有多个实现该接口的类:HashMap、TreeMap、LinkedHashMap、WeakHashMap和IdentityHashMap。HashMap是基于散列表实现的,采用对象的HashCode可以进行快速查询。LinkedHashMap是采用列表来维护内部顺序。TreeMap基于红黑树的数据结构来实现的,内部元素是按需排列的。
Collection框架.png

迭代器(Iterator)
迭代器(Iterator)是一个对象,它的工作室遍历并选择序列中的对象,它提供了一种访问一个容器(container)对象的各个元素,而又不必暴露该对象内部细节的方法。通过迭代器,开发人员不需要了解容器底层的结构,就可以实现对容器的遍历。
迭代器的是由主要有以下3个方面注意事项:

  • 使用容器的iterator()方法返回一个Iterator,然后通过Iterator的next()方法返回第一个元素。
  • 使用Iterator的hasNext()方法判断容器是否还有元素,如果有,可以使用next()方法获取下一个元素。
  • 可以通过remove()方法删除迭代器返回的元素。
    示例:
public class IteratorTest{
    public static void main(String []args){
        List<String> ll = new LinkedList<String>();
        ll.add("first");
        ll.add("second");
        ll.add("third");
        for(Iterator<String> iter = ll.iterator();iter.hasNext();){
             String str = iter.next();
             System.out.println(str);
        }
    }
}

注:

  • 单线程中,在遍历的过程中把需要删除的对象保存到一个集合中,等遍历结束后调用removeAll()方法来删除,或者使用iter.remove()方法。
  • 使用ConcurrentHashMap和CopyOnWriteArrayList等线程安全的容器来代替非线程安全的容器。
  • 在使用迭代器遍历容器时对容器的操作放到synchronized代码块中,但是当引用程序并发程度高时,这会严重影响程序的性能。

ArrayList、Vector和LinkedList的区别

  • ArrayList和Vector都是基于存储元素的Object[] array来实现的,它们在内存中开辟一块连续的空间来存储,由于数据存储室连续的,因此,它们支持用序号(下标)来访问元素,同时索引数据的速度比较快。但是在插入元素时需要移动容器中的元素,所以对数据的插入操作执行比较慢。当它们的容量所存储的元素超过这个大小时就需要动态地扩充它们的存储空间。它们的区别是synchroonization(同步)的使用,没有一个ArrayList的方法是同步的,而Vector的绝大多数方法(add、insert、remove、set、equals、hascode等)都是直接或间接同步的,所以Vector是线程安全的,ArrayList不是线程安全的。
  • LinkedList是采用双向列表来实现的,对数据的索引需要从列表头开始遍历,因此用于随机访问则效率比较低,但是插入元素时不需要对数据进行移动,因此插入的效率高,是非线程安全的容器。
  • 当对数据的主要操作是索引或志在集合的末端增加、删除元素时,使用ArrayList和Vector效率比较高;当对数据的操作主要为指定位置的插入和删除操作时,使用LinkedList效率比较高;当在多线程中使用容器时(即多个线程会同时访问该容器),选用Vector较为安全。

HashMap、HashTable、TreeMap和WeakHashMap区别
Map是用来存储键值对的数据结构,通过对象进行索引,用来索引的对象叫做key,其对应的对象叫做value。
Hash是一个最常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问数据。区别:

  • HashMap是HashTable的轻量级实现(非线程安全),HashMap允许一条记录的键值(key)为空(null),HashTable不允许。
  • HashMap把HashTable的contains方法去掉了,改成containsvalue和containsvalueKey。
  • HashTable的方法是线程安全的,HashMap不支持线程的同步,所以不是线程安全的。在多线程访问HashTable时,不需要开发人员对它进行同步,而对于HashMap,需要提供额外的同步机制。
  • HashTable使用Enumeration,HashMap使用Iterator。
  • hash值得使用不同,HashTable直接使用对象的hashCode。

HashMap里面存入的键值对取出时没有固定顺序,随机的。在Map中插入、删除和定位元素,HashMap是最好的选择。由于TreeMap实现了SortMap接口,能够把它保存的记录根据根据键排序,取出来是排序后的键值对,如果需要按自然顺序或自定义顺序遍历键,使用TreeMap。

WeakHashMap与HashMap类似,二者不同之处在于WeakHashMap中的key采用的是“弱引用”的方式,只要WeakHashMap中的key不再被外部引用,它就可以被垃圾回收器回收。而HashMap中key采用的是“强引用的方式”,当HashMap中的key没有被外部引用时,只有在这个key从HashMap中删除后,才可以被垃圾回收器回收。
注:

  • 在HashMap上下文中,同步意味着在一个时间点只能有一个线程可以修改hash表,任何线程在执行HashTable的更新操作前都需要获取对象锁,其他线程则等待锁的释放。
  • HashMap可以通过Map m = Collections.synchronizedMap(new HashMap())来达到同步的效果。即,该方法返回一个同步的Map,该Map封住了底层的HashMap的所有方法,使得底层的HashMap即使是在多线程的环境中也是安全的。

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

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,602评论 18 399
  • Java SE 基础: 封装、继承、多态 封装: 概念:就是把对象的属性和操作(或服务)结合为一个独立的整体,并尽...
    Jayden_Cao阅读 2,103评论 0 8
  • 终于定下来了,房主最终还是涨了四万,看来这次必须要筹钱了,还有十五万的首付缺口,加油吧!或许可以考虑一下小额贷款,...
    OO碰到OO阅读 243评论 0 0
  • 上午在中心听课,幼儿小班的两个娃娃虽然只有三岁多,而且只是第三次课,却发现他们已经可以两遍闪卡过后就能找到老师随机...
    喻青阅读 661评论 2 2
  • 你是不是时常壮怀激烈,想到未来总觉得自己可以大有一番作为? 你是不是又时常觉得无聊,不知道该干些什么,不希望时间被...
    不再写诗阅读 484评论 0 1