java 集合

基础概念

Collection:统计大小、插入或删除数据、清空、是否包含某条数据,等等。而Collection就是对这些常用操作进行提取,只是其很全面、很通用。size(),isEmpty(),contains(),add(),remove,clear(),hashCode()

AbstractCollection:在Collection得基础上,在泛型上实现了一些方法,add抛出一个异常,addAll获得一个迭代器遍历添加,clear获得一个迭代器遍历删除,contains获得一个迭代器遍历查找,tostring集合内容

list:和collection相比,比较针对线性表来设计add,addAll,sort,get,set,indexOf,lastIndexOf,listIterator()返回一个先前遍历得迭代器

AbstractList<e>:iterator方法返回了一个内部类Itr对象,合理的处理hasNext,next,remove方法,还有个ListItr实现了ListIterator接口,equals和hashcode的实现,所以在定义数据元素时,也应该复写这两个方法,以保证程序的正确运行

queue:继承自,collection,有offer(add),poll(remove),peek(element)操作,返回null不抛出异常

AbstractQueue:在泛型上实现了add,remove,element

map接口:put,get,size,remove,clear,希望我们完成hashcode和equal

AbstractMap:在泛型上帮我们实现上面方法

String的方法:
hashcode:hash = 31 * hash+ a[i]
equals:对比是不是同一个引用,对比是不是长度相同,再一个个字母对比
compareTo:实现了Comparable<t>的int compareTo(T t)方法,先对比长度,小的作为循环数,比较到a和b某个字母不相同,返回他们两个相减

数组

  • 创建一个数组,必须声明其长度,以在内存中寻找合适的一段连续存储单元。这也意味着数组的大小是固定的,我们无法动态调整其大小。
  • 想要获取数组中第i个元素,其时间复杂度是 O(1),因为可以根据其地址直接找到它。同理修改也是。
  • 因为地址连续,想要在数组中插入一个元素是复杂的,因为从插入位置起,后边的所有元素都需要向后移动一位。同理删除也是,只是移动方向为向前。并且,当数组存满时,就无法继续插入了。

链表

  • 链表的每个元素都分为数据域和指针域,前者是实际存储的数据,后者则指向下一个元素的地址。和数组相比,每个元素需要占用的内存更大了。
  • 增加与删除一个元素更方便了,因为没有对内存地址的限制,我们只需要在对应节点合理处理下指针域的值,就可以把一个元素插入链表或者从链表删除。
  • 链表对查询表现也一般,需要遍历,时间复杂度为O(n)。

红黑树:红黑树和AVL树的思想是类似的,都是在插入过程中对二叉排序树进行调整,从而提升性能,它的增删改查均可以在O(lg n)内完成。红黑树的插入与删除和AVL树类似,也是每插入一个结点,都检查是否破坏了树的结构,然后进行调整。红黑树每个结点插入时默认都为红色,这样做可以降低黑高,也可以减少调整的次数。


1.Iterator

  • Iterable<E>:collection继承的接口,代表要实现Iterator<T> iterator()接口,有了获得一个迭代器的能力,获得一个迭代器

  • Iterator<E>:Iterator是foreach遍历的主体,有核心next,remove,hasNext

  • ArrayList和linkedList:ListItr增加了hasPrevious,previous,nextIndex,add,set

2.ArrayList

  • 默认是10,添加第一个的时候创建,添加元素时使用 ensureCapacityInternal() 方法来保证容量足够,如果不够时,需要使用 grow() 方法进行扩容,新容量的大小为 oldCapacity + (oldCapacity >> 1),也就是旧容量的 1.5 倍。
  • 扩容操作需要调用 Arrays.copyOf() 把原数组整个复制到新数组中,这个操作代价很高,因此最好在创建 ArrayList 对象时就指定大概的容量大小,减少扩容操作的次数。
  • 需要调用 System.arraycopy() 将 index+1 后面的元素都复制到 index 位置上,该操作的时间复杂度为 O(N),可以看出 ArrayList 删除元素的代价是非常高的。
  • ArrayList 基于数组实现,并且具有动态扩容特性,因此保存元素的数组不一定都会被使用,那么就没必要全部进行序列化。ArrayList 实现了 writeObject() 和 readObject() 来控制只序列化数组中有元素填充那部分内容。
  • Fail-Fast,modCount 用来记录 ArrayList 结构发生变化的次数。结构发生变化是指添加或者删除至少一个元素的所有操作,或者是调整内部数组的大小,仅仅只是设置元素的值不算结构发生变化。
    在进行序列化或者迭代等操作时,需要比较操作前后 modCount 是否改变,如果改变了需要抛出 ConcurrentModificationException。

3.linked list

  • LinkedList既继承了List,又继承了Deque,那它必然有一堆add、remove、addFirst、addLast等方法。
  • Node<e>作为她的内部类,有e数据域,和上下节点的指针
    因为链表没有长度方面的问题,所以也不会涉及到扩容等问题,其构造函数也十分简洁了。
  • 果要遍历,也最好使用foreach,也就是Iterator提供的方式。
  • 非常适合大量数据的插入与删除,但其对处于中间位置的元素,无论是增删还是改查都需要折半遍历,这在数据量大时会十分影响性能。

4.treemap

  • TreeMap是根据key进行排序的,它的排序和定位需要依赖比较器或覆写Comparable接口,也因此不需要key覆写hashCode方法和equals方法,就可以排除掉重复的key,而HashMap的key则需要通过覆写hashCode方法和equals方法来确保没有重复的key。
  • TreeMap的查询、插入、删除效率均没有HashMap高,一般只有要对key排序时才使用TreeMap。
  • TreeMap的key不能为null,而HashMap的key可以为null。
  • TreeMap不是同步的。如果多个线程同时访问一个映射,并且其中至少一个线程从结构上修改了该映射,则其必须 外部同步。

5.hashmap

  • 初始化没有设定值的时候,初始值1《《4=16,最大为1《《30,负载因为0.75的时候扩容,也是2次幂
  • 链表长度为8的时候变成红黑树,小于6的时候变回链表
  • 设计的key对象一定要实现hashCode方法
  • 如果可以预先估计数量级,可以指定initial capacity,以减少rehash的过程。
  • JDK 1.8 使用了 CAS 操作来支持更高的并发度,在 CAS 操作失败时使用内置锁 synchronized。


    image

6.Collections.sort(list,comparator<User>),默认升序

 Collections.sort(userList, new Comparator<User>() {
    public int compare(User u1, User u2) {
       return new Double(u1.getSalary()).compareTo(new Double(u2.getSalary())); 升序
       return new Double(u2.getSalary()).compareTo(new Double(u2.getSalary())); 降序
      }
  });

int[] intArray = new int[] { 4, 1, 3, -23 };
        Arrays.sort(intArray);

7.集合和数组转化

list转数组
List<String> list = new ArrayList<String> ();
        list.add("str1");
        list.add("str2");
        int size = list.size();
        String[] arr = (String[]) list.toArray(new String[size]);

数组转集合
List<String> list = new ArrayList<>(arr.length);
        Collections.addAll(list, arr);

8.数组和list复制

数组复制
System.arraycopy(a1, 1, a2, 3, 3);
        System.out.println(Arrays.toString(a1)); // [1, 2, 3, 4, 5]
        System.out.println(Arrays.toString(a2)); // [0, 0, 0, 2, 3, 4, 0, 0, 0, 0]
list复制
1、遍历循环复制
List<Person> destList=new ArrayList<Person>(srcList.size());  
for(Person p : srcList){  
    destList.add(p);  
}  

2、使用List实现类的构造方法
List<Person> destList=new ArrayList<Person>(srcList);  

3、使用list.addAll()方法
List<Person> destList=new ArrayList<Person>();  
destList.addAll(srcList);

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

推荐阅读更多精彩内容

  • Java集合类可用于存储数量不等的对象,并可以实现常用的数据结构如栈,队列等,Java集合还可以用于保存具有映射关...
    小徐andorid阅读 1,915评论 0 13
  • 原文地址 Java集合 Java集合框架:是一种工具类,就像是一个容器可以存储任意数量的具有共同属性的对象。 Ja...
    gyl_coder阅读 973评论 0 8
  • Java集合详解 [if !supportLists]一、[endif]集合的由来 通常,我们的程序需要根据程序运...
    秋刀鱼茶泡饭QAQ阅读 465评论 1 2
  • 本文取自工匠若水的qq群里的Java基础题目,把里面有关Java集合放在一起。全文github地址 35.Arra...
    蝉翅的空响阅读 235评论 0 0
  • 3.3 集合 一方面, 面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储。另...
    闫子扬阅读 715评论 0 1