栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JAVA数组和集合-个人笔记

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JAVA数组和集合-个人笔记

数组

一、数组声明了它容纳的元素的类型,而集合不声明。

二、数组是静态的,一个数组实例具有固定的大小,一旦创建了就无法改变容量了。而集合是可以动态扩展容量,
   可以根据需要动态改变大小,集合提供更多的成员方法,能满足更多的需求。
   数组会做边界检查(检查边界会以效率为代价)

三、数组的存放的类型只能是一种(基本类型/引用类型),集合存放的类型可以不是一种(不加泛型时添加的类型是Object)。

四、数组是java语言中内置的数据类型,是线性排列的,执行效率或者类型检查都是最快的

集合

			Collection		             	    Map                      ------->都是接口
				/   					      /  |  
			   /    					   /	 |	   
			(List    Set)          (HashMap   TreeMap    HashTable)

类 Collections中
public static  void sort(List list, Comparator c)根据指定比较器产生的顺序对指定列表进行排序

	长度可以动态改变
	存储不同类型的对象和数据 	
	boolean retainAll(Collection c) 如果此 collection 由于调用而发生更改,则返回 true 

数据结构
 ├栈:先进后出    子弹夹
 ├队列:先进先出    排队买票
 ├数组:查询快,添加删除慢
 ├树:
 └链表:添加删除快,查询慢
  ├单向链表
  ├双向链表
  └循环链表
(加载因子:当元素个数达到集合长度*加载因子的长度后,会触发扩容)
List(有序集合(存和取顺序一致),允许相同元素和null)
 ├ArrayList 初始容量10,加载因子为0.5,扩容增量:0.5倍+1,即第一次扩容:10*1.5+1=16
 │  ├底层是数组
 │  ├线程不安全,不同步
 │  ├查询修改快,插入删除慢
 │  └ListIterator(主要用于List迭代)
 │   ├可以逆向输出,是Iterator的子接口
 │   └ListIterator在遍历时,使用ListIterator类中的add()和remove()方法对List数据进行操作是不会有并发异常;
 │    Iterator在遍历时,对list的进行数据操作会抛出并发异常 ConcurrentModificationException
 ├Vector(基本不使用) 初始容量10,加载因子1,扩容增量为1倍
 │  ├底层是数组,查询修改快,删除增加慢
 │  ├线程安全,同步
 │  ├firstElement()  返回此向量(位于索引0)一个组件
 │  └lastElement()   返回此向量的最后一个组件
 └linkeList
    ├底层是链表,查询修改速度慢,删除增加快
    ├线程不安全,不同步
    ├addFirst()   addLast()   将指定元素插入此列表的开头或结尾
    └gteFirst()   getLast()   获取此列表的开头或结尾元素

Set (无序集合,不允许相同元素,最多有一个null元素)
 ├HashSet  最多有一个null元素;初始容量16,加载因子为0.75,扩容增量为一倍(与HashMap等同)
 │ ├hashCode()和equals()
 │ │ └HashSet底层是hashCode()和equals()进行去重,先比较hashCode()是否相等,如果不相等,返回false(即不重复);
 │ │        如果相等,会在进行equsals()方法比较,如果equals()返回true,则去重,否则不去重。
 │ └遍历
 │   ├foreach
 │   └Iterator
 └TreeSet
   ├不能存null
   ├存入的对象的类必须使用比较器,否则会抛出类转换异常
   └比较器
	 ├实现 comparable   重写compareTo方法
     └TreeSet(Comparator comparator)   自定义裁判类实现Comparator接口,重写compare(),并将此类对象作为参数传入TreeSet()
	
Map (没有实现collection接口,key不能重复,value可以重复,一个key映射一个value,允许null为key和value)
├Hashtable  (实现Map接口,同步,不允许null作为key和value,用自定义的类当作key的话要复写hashCode和eques方法,)
├HashMap     (实现Map接口,非同步,允许null作为key和value,用的多) 初始容量16
└TreeMap    (实现Map接口,根据自然顺序(或指定规则)顺序对key进行排序,非同步,不允许null为key)

哈希算法相关知识点

a. java中的每个对象都有一个“哈希码”, “哈希码”其实就是一个整数(包括正数和负数) 
b. jdk内置的类的对象,哈希码都是根据内容计算出来的,也就说,内容相同的两个对象,哈希码一定相同。
c. 那么我们自定义的类,哈希码是否与内容有关: 无关!! why??
        因为,我们自定义的类,并没有重写Object的hashcode方法,所以调用自定义的类的hashcode方法时,
        会直接调用父类Object的hashcode方法,而父类Object的hashcode方法恰恰返回的是对象在堆内存中的地址!
d. 我们也想让自定义的类的hashcode也是根据内容就算出来的,就需要重写Object的hashcode方法。
        保证自定义的类的hashCode是根据内容计算出来的!
e. 当我们把一个对象加入HashSet的时候,HashSet(内部是HashMap)会根据对象的hashCode来分配对象进入的区域,也就说,
        哈希码相同的2个对象会进入同一片区域,进入同一片区域的对象就会引起比较,而比较的时候,又会回调对象的
   equals. 可惜equals默认是比较内存地址!  所以还要重写equals方法,保证equals方法是在比较内容!
   
f. HashSet利用的就是哈希算法,就是利用空间换取时间!
g. 3句话
	i.   两个对象,哈希码不同,内容一定不同
	ii.  两个对象,哈希码相同,内容不一定相同
	iii. 两个对象,内容相同,哈希码一定相同
        (联想宿舍)

*注:HahsSet 在jdk1.6 jdk1.7中的数据结构. jdk1.8中的数据结构(待补充)

HashMap扩容:

HashMap维护了一个Node(可以形成链表)类型的数组table。

*注:初始容量和扩容,都是针对map维护的table而言的。

1.存放数据时,会先根据元素的key的hash值计算(, 注:这个计算方式可以在散列时减少的hash碰撞)索引位置;
2.如果table该索引位置上已经有node了,需要先对比两个node的key的hash值是否相同
	1).如果相同在进行比对两个node的key内容(equals)是否相同,
		i).如果相同则进行替换
	2).否则在该node下进行追加。
3.table中每个索引上起初存放的都是node链表,如果链表长度超过8,该链表可能会变成红黑树(如果map的size没有超过64,则不会进行类型变更,而是将map进行扩容)
4.当map中存放的元素超过map容量的0.75倍时,table就会进行2倍扩容(选择2幂次扩容,是因为计算元素索引是使用[],为了减少扩容后重新散列元素时的hash碰撞)。

*注:jdk1.8版本前,table中存放的的node链表在扩容后,进行重新散列时,采用的是头插法,即链表倒叙插入。jdk1.8后,变成了正序。   --百度看一下?

ConcurrentHashMap分段锁(补充)

1.jdk1.8之前采用分段锁:ConcurrentHashMap维护了一个segment数组,里面是一个个HashEntry(链表)。而锁是加载segment上的,各segment间相互独立
2.jdk1.8后,ConcurrentHashMap去掉了Segment数组,锁直接加载table中各元素(node/treeify)的第一个元素(node)上,使锁粒度更细
扩容/重散列
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/352305.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号