提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:
集合类是Java数据结构的实现。Java的集合类是java.util包中的重要内容,它允许以各种方式将元素分组,并定义了各种使这些元素更容易操作的方法。Java集合类是Java将一些基本的和使用频率极高的基础类进行封装和增强后再以一个类的形式提供。集合类是可以往里面保存多个对象的类,存放的是对象,不同的集合类有不同的功能和特点,适合不同的场合,用以解决一些实际问题。
集合体系内容 :
Collection接口:
它是List和Set的父级接口,Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)。
一、List
List接口:有序可重复。
遍历方式:迭代器,增强for循环,通过索引值遍历
ArrayList:
ArrayList是在JDK1.2版本的时候推的,它可以存放为 null 的元素,底层是由数组来实现数据的存储,基本等同于vector,并且它线程不安全,多线程的时候不建议使用。
底层源码:
1.ArrayList底层维护的是一个Object类型的数组 elementData 。
2.当创建ArrayList对象时,使用无参构造器,初始容量为0,第一次添加元素时会先将数组扩容至10,如需再次扩容,则扩容为elementData当前长度的1.5倍。
3.如果使用的是指定大小的构造器,则初始element容量为指定的大小,如果需要再次扩容,则直接扩容为当前长度的1.5倍。
注意:
elementData是被transient修饰的,表示不可被序列化。
LinkedList:
1.底层实现了双向链表和双端队列特点,添加和删除效率高。
2.可以添加任意元素,元素可以重复。
3.线程不安全,没有实现同步机制。
双向链表:
Node对象中维护了三个属性:prev,next,item
prev:指向frist。item:数据。next:指向last。
Vector:
1.继承了AbstractList,实现了List<E>接口
2.底层也是一个对象数组。protected Object[] elementData;
3.Vector是线程同步的,即线程安全,Vector类的操作方法带有Synchronize。
4.扩容机制:如果是无参,默认为10,满后按2倍扩容,如果指定大小则按指定大小的2倍扩容。
ArrayList和LinkedList最主要区别:
ArrayList:底层是数组,增删效率低,查询效率高。
LinkedList:底层是双向链表,增删效率高,查询效率低。
二、Set
set接口:无序,不可重复,最多只能有1个null。
遍历方式:迭代器,增强for循环。
注意:Set的底层用到了Map,所以也是<K-V>,但是只用到了key,没用到value(默认值填充)HashSet:
HashSet:
1.HashSet实现了Set接口,可以存放一个null值,不能有重复的值。
2.HashSet不保证元素是有序的,取决于Hash后在确定索引的结果。
3.HashSet底层用的是HashMap。
4.它的底层是数组+单链表+红黑树。
添加元素:
1.添加元素时会通过Hash算法算出一个Hash值,然后再通过Hash/当前链表长度=索引值。
2.然后再判断当前位置是否有元素存在,没有就直接插入。
3.如果有,再调用equals进行比较,如果相同,就放弃添加,如果不同,则添加至当前链表末尾(拉链法)。
4.在JDK1.8中,如果一条链表元素个数大于8(包括8),那么这条链表就会进行红黑树化。
注意:只有当前table数组个数大于等于64且一条链表长度大于8的时候当前链表才会红黑树化。如果链表大于等于8,而数组个数不够64,会先进行数组扩容。
LinkedHashSet:
1.LinkedHashSet是HashSet的子类。
2.LinkedHashSet底层是一个LinkedHashMap,底层维护了一个数组+双向链表。
3.LinkedHashSet根据元素的HashCode值来决定元素的存储位置,同时使用链表维护元素的次序,使得元素看起来插入顺序是保存的。
注意:LinkedHashSet在内存中存储的时候是打乱的,但是因为它是双向链表的结构,所以呈现的时候是按顺序呈现。
TreeSet:
TreeSet底层是二叉树,可以对对象元素进行排序,但是自定义类需要实现comparable接口,重写comparaTo() 方法。可以保存对象元素的唯一性(并不是一定保证唯一性,需要根据重写的compaaTo方法来确定。
TreeSet是一个有序的集合,它继承于java.util.AbstractSet抽象类,实现了NavigableSet接口,Cloneable接口,Serializable接口等。
TreeSet继承于AbstractSet,它具有Set的属性和方法。
它还是实现了NavigableSet接口,支持它一系列的导航方法,如查找与指定目标最匹配项。
实现了Serializable接口,它支持序列化。
TreeSet是基于TreeMap实现的,TreeSet里面的元素支持2种排序方式:第一种是自然排序,第二种是根据TreeSet时提供的Comparator进行排序。
TreeSet是非同步的哦,它的iterator方法返回的迭代器是fail-fast的。
三、Map
Map接口:
1.Map接口与Collection并列存在,用于保存具有映射关系的数据key-value。
2.Map中的key和value可以是任何引用类型数据,会封装到HashMap的Node对象中。
3.Map中的Key不允许重复,本质和HashSet一样(HashSet添加元素)。
4.value的值可以重复,Map中的Key可以为null,value也可以为null,但是key只能有一个为null,value可以有多个null。
5.通常用String类作为Map的Key。
6.key和value之间存在单向一对一关系,即通过一个key可以找到一个对应的value
7.Map存放数据的key-value是放在一个Node中(Node是HashMap的一个内部类)因为Node实现了Entry接口,(这里的Node除了Key,Value还有一个hash和next属性,因为它是链表的形式存储的)
注意:Entry是一个接口,Entry里放的是<set,collection>,Entry中的Set类型的Key指向Node中的Key。Entry中collection类型的value指向Node中的Key。
HashMap:
1.HashMap底层维护了Node类型的数组table,默认为null。
2.当创建对象时,将加载因子初始化为0.75
3.添加方式与HashSet完全一致(key转成Hash值。。。。)
4.第一次添加,则需要扩容table容量为16,临界值为12(16*0.75)
5.以后再扩容,则需要扩容table容量为原来的2倍
6.在JDK1.8中,如果一条链表的元素个数超过或等于默认值8,并且table的大小>=默认值64,就会进行红黑树化。
注意:临界值是指当table中元素到了12之后就要扩容。
HashTable:
1.键和值都不能为null。
2.使用方法和HashMap基本一致
3.HashTable是线程安全的,因为HashTable加了Synchronize关键字,HashMap是线程不安全的。
4.底层有一个数组:Hashtable$Entry[],初始化大小为11,threshold(临界值):8
ConcurrentHashMap:
ConcurrentHashMap内部数据结构是hashTable,但是与hashTable不同的是CurrentHashMap使用了锁分离技术,即:使用多个不同的锁来控制对HashTable的不同部分进行修改,其内部的不同部分使用Segment来表示。这样一个大的HashTable就会被分为多个小的HahTable,每个锁作用在不同的小HashTable上。当多个操作发生在不同的Segment上,就可以进行并发操作了。
但是有些操作例如:size(),需要将整个表锁定,先按顺序锁定每个段的,然后进行操作,操作完后再按顺序释放所有段的锁。
ConcurrentHashMap实际上就是将一个大HashTable分割成多个小的HashTable,然后在每个小的HashTable上加锁,实现锁分离。
ConcurrentHashMap的实现方式:
ConcurrentHashMap主要有三个实体类:ConcurrentHashMap(整个Hash表),Segment(桶),HashEntry(节点)
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。