java集合详解

2 篇文章 0 订阅
1 篇文章 0 订阅

集合:

Collection

List---有序,元素可以重复

一些List的常用方法

              Length:查看数组的最大容量,size:查看当前元素个数

              add(下标,元素)-添加、addAll(下标,集合)、add(元素)末尾添加、

              get(下标)获取、set(下标,指定元素)修改、remove(下标)删除、

              removeAll()==clear()全部清除、

              public boolean contains(Object o)list中是否包含某元素

              查看元素中的索引

              正序遍历,第一次找到就返回 public int indexOf(Object o),没有-1

              倒序遍历 第一次找到的元素下标public int lastIndexOf(Object o) -1

              转换:toString、toArray

              截取集合:subList(int fromIndex, int toIndex),左闭右开

 

     ArrayList:

               底层数据结构是动态数组,查询快,增删慢。

              线程不安全,效率高,不同步

              扩容:加上原来长度的一半(即1.5倍)+1(默认初始容量为10)             

     LinkedList

              底层数据结构是双向链表,查询慢,增删快

              线程不安全,效率高,不同步

              add、get方法  支持null值

              扩容:默认是无限大的链表

     Vector:---已经被弃用

             可以用java.util.Concurrent包下的concurrentLinkedDeque或者concurrentQueue来代替

             底层数据结构是动态数组,查询快,增删慢

             线程安全--(同步方法保证安全性),效率低,同步

             扩容:默认增加原来的一倍(或每次增加指定容量)

Set---无序,元素不可重复,只能通过游标来取值

    HashSet

             底层数据结构式哈希表,哈希表依赖俩个方法hashcode()和equals()方法

             俩个方法的执行顺序:

                  先判断hashcode()值是否相同,

                  是---就继续执行equals()方法,查看返回值

                            True:说明元素重复,不添加;false:直接添加元素

                  否---就直接添加元素

    TreeList

             底层数据结构是二叉树

Map---双列集合,键值对存储,key不能重复

    HashMap--底层数据结构是哈希表(子类--LinkedHashMap,其他不再详细写出,不常用)

             非同步,线程不安全的,非synchronized、可接受null为key value

             默认16,0.75因子,扩容*2(位运算)

             让hashMap 同步:Map m = Collections.synchronizeMap(hashMap);

             为什么hashMap不是线程安全的?

                     这里写图片描述

          可以看到输出的序号被打乱了

             底层:

              

             逻辑图:

             这里写图片描述

 

           图片来源: https://blog.csdn.net/LovePluto/article/details/79712473#commentBox

    HashTable--已淘汰

             同步,线程安全的,初始默认大小11,扩容*2+1,不允许null值

             为什么是线程安全的?

             Remove、put、get是同步方法

             每个操作数据的方法都进行同步控制之后,由此带来的问题任何一个时刻只能有一个线程可以操纵Hashtable,所以其                 率比较低。

 

    TreeMap--底层数据结构是二叉树

    ConcurrentHashMap

             默认16个线程同时访问该map,也可以自己设置

             ConcurrentHashMap将Map分段了,每个段进行加锁,而不是想Hashtable,SynchronizedMap是整个map加锁,这样就                 可以多线程访问了

            

Java中集合的选择:

1.单列还是双列

            单列就选Collection类型的,双列选Map类型的

2.选择单列后看元素是否唯一

            是:选择Set集合

            看元素是否排序:

                        是:TreeSet

                        否:HashSet

            否:   选择List集合

            安全线高低:    

                        高:Vector

                        低:ArrayList 或LinkedList '

                                    增删多:LinkedList

                                    查询多:ArrayList

 

在集合中会问到的问题:

1、我们能否使用任何类作为Map的key

我们可以使用任何类作为Map的key,然而在使用它们之前,需要考虑以下几点:

(1)如果类重写了equals()方法,它也应该重写hashCode()方法

(2)类的所有实例需要遵循与equals()和hashCode()相关的规则。请参考之前提到的这些规则。

(3)如果一个类没有使用equals(),你不应该在hashCode()中使用它。

(4)用户自定义key类的最佳实践是使之为不可变的,这样,hashCode()值可以被缓存起来,拥有更好的性能。不可变的类也可以确保hashCode()和equals()在未来不会改变,这样就会解决与可变相关的问题了。

2、HashMap与Hashtable的区别:

HashMap可以接受null键值和值,而Hashtable则不能。

Hashtable是线程安全的,通过synchronized实现线程同步。而HashMap是非线程安全的,但是速度比Hashtable快

3、HashMap的原理

4、如果两个键的hashcode相同,你如何获取值对象

HashMap在链表中存储的是键值对,找到哈希地址位置之后,会调用keys.equals()方法去找到链表中正确的节点,最终找到要找的值对象

5、以上集合的扩容问题

ConcurrentHashMap引入了分割(segmentation),不论它变得多么大,仅仅需要锁定map的某个部分,而其它的线程不需要等到迭代完成才能访问map。简而言之,在迭代的过程中,ConcurrentHashMap仅仅锁定map的某个部分,而Hashtable则会锁定整个map。

6、hash冲突(碰撞)问题

在计算hash地址的过程中会出现对于不同的关键字出现相同的哈希地址的情况,即key1 ≠ key2,但是f(key1) = f(key2),这种情况就是Hash 冲突。具有相同关键字的key1和key2称之为同义词。

通过优化哈希函数可以减少这种冲突的情况(如:均衡哈希函数),但是在通用条件下,考虑到于表格的长度有限及关键值(数据)的无限,这种冲突是不可避免的,所以就需要处理冲突,冲突处理分为以下四种方式:

开放地址又分为: 线性探测再散列 二次探测再散列 伪随机探测再散列

处理冲突的基本原则就是出现冲突后按照一定算法查找一个空位置存放

再哈希:再哈希法,就是出现冲突后采用其他的哈希函数计算,直到不再冲突为止。

链地址:链接地址法不同与前两种方法,他是在出现冲突的地方存储一个链表,所有的同义词记录都存在其中。形象点说就行像是在出现冲突的地方直接把后续的值摞上去

建立公共溢出区:建立公共溢出区的基本思想是:假设哈希函数的值域是[1,m-1],则设向量HashTable[0…m-1]为基本表,每个分量存放一个记录,另外设向量OverTable[0…v]为溢出表,所有关键字和基本表中关键字为同义词的记录,不管它们由哈希函数得到的哈希地址是什么,一旦发生冲突,都填入溢出表。

7、二叉树的遍历:

前:根左右

中:左根右

后:左右根

 

以上内容结合多篇博客大佬内容和我自己的一些理解,此处不再进行详写,我别的博客中也有详写

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值