集合与数组的区别?
数组定长,集合可变长
数组可以是基本类型,也可以是引用类型
数组只能存储同一种数据类型,集合可以存储多种数据类型
collection常用的方法?
遍历集合(Collection)的元素都可以使⽤Iterator
iterator
Iterator也是⼀个接⼝,它只有三个⽅法:
- hasNext()
- next()
- remove()
- iterator在ArrayList()是以内部类的方式实现,
list的特点,可重复,有序,按照存储顺序保存
-
arraylist 非安全,底层是数组,遍历快
如果指定了初始容量,就初始为对应的容量,否则为10 动态扩容 add的实现就是先添加,如果发现容量不够就扩大为原来的1.5倍 remove⽅法步骤:检查⻆标删除元素计算出需要移动的个数,并移动 设置为null,让Gc回收 删除元素时不会减少容量 增删时候,需要数组的拷⻉复制(navite ⽅法由C/C++实现)copyof() 可以存放null
-
vector 安全,底层是数组,遍历快
是jdk1.2的类,用synchronized实现了线程安全, 他在容量不够时扩大为原来的2倍,相⽐于ArrayList更多消耗内存 所有都是用同步,有性能损失
-
linkedlist 非安全,底层是双向链表。增删改快,可以通过push形成栈的形式
LinkedList实现了Deque接⼝,因此,我们可以操作LinkedList像操作队列和栈⼀样
set的特点,不可重复,无序
- hashset 底层是hashmap,初始容量⾮常影响迭代性能
- treeset 底层是红黑树
- linkedhashset 底层是哈希表与双向链表
map集合的特点。成对出现
-
hashmap
初始容量为16,默认装载因子为0.75,当存储元素大于容量*装载因子时,扩容两倍 ⽆序,允许为null,⾮同步 底层由散列表(哈希表)+红黑树实现 初始容量和装载因⼦对HashMap影响挺⼤的,设置⼩了不好,设置⼤了也不好
-
hashtable
不允许null,同步
-
concurrentmap
散列表+红⿊树
ConCurrentHashMap⽀持⾼并发的访问和更新,它是线程安全的
检索操作不⽤加锁
引入cas操作
CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内 存值V相同时,将内存值V修改为B,否则什么都不做
-treemap
TreeMap实现了NavigableMap接⼝,
⽽NavigableMap接⼝继承着SortedMap接⼝,使得其是有序的
当时无法排序类型时,需要实现compareable接口来保证其可以排序
底层是红黑树
key不能为null,为null为抛出NullPointException的
TreeMap⾮同步的,想要同步可以使⽤Collections来进⾏封装
map与collection的区别
- map集合的数据结构针对键,与值无关,collection的数据结构针对的是元素
- map集合的特点。成对出现,一个键对应一个值。
- mao集合键唯一,值可以重复,collection中存储元素是单独出现,set是唯一,list是可重复
提升
vector的代替者 copyonwritearraylist
copyonwritearraylist底层就是数组,加锁就交由ReentrantLock来完成。
线程安全
在添加的时候就上锁,并复制⼀个新数组,增加操作在新数组上完成,将
array指向到新数组中,最后解锁。
数据⼀致性:CopyOnWrite容器只能保证数据的最终⼀致性,不能保证数据的实时⼀致性。
hashset的底层是hashmap是如何实现的?
他的值就是一个object
listitrator与itorator的区别?
ListIterator继承了Iterator接⼝,它⽤于遍历List集合的元素。
ListIterator可以实现双向遍历,添加元素,设置元素
hashmap与hashset获取hashcode方式的不同?
hashmap是对键使用hashcode方法
hashset是对成员对象使用hashcode方法
*HashMap* *HashSet*
HashMap实现了Map接口 HashSet实现了Set接口
HashMap储存键值对 HashSet仅仅存储对象
使用put()方法将元素放入map中 使用add()方法将元素放入set中
HashMap中使用键对象来计算hashcode值 HashSet使用成员对象来计算hashcode值,
对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,
如果两个对象不同的话,那么返回false
HashMap比较快,因为是使用唯一的键来获取对象 HashSet较HashMap来说比较慢
hashmap的两个hashcode相同时,如何找到对象?
通过hashcode找到bucket的位置。
找到bucket位置之后,会调用keys.equals()方法去找到链表中正确的节点,最终找到要找的值对象。
hashmap的工作原理?
HashMap是基于hashing的原理,我们使用put(key, value)存储对象到HashMap中
,使用get(key)从HashMap中获取对象。当我们给put()方法传递键和值时,
我们先对键调用hashCode()方法,
返回的hashCode用于找到bucket位置来储存Entry对象。
hashmap存在的问题? (非安全的集合存在的问题)
在多线程的情况下,因为如果两个线程都发现HashMap需要重新调整大小了,
它们会同时试着调整大小。在调整大小的过程中,存储在链表中的元素的次序会反过来,
因为移动到新的bucket位置的时候,HashMap并不会将元素放在链表的尾部,而是放在头部
,这是为了避免尾部遍历(tail traversing)。如果条件竞争发生了,那么就死循环了。
为什么string适合做集合的键?
string最常用,因为其不可变,而且已经重写了hashcode和equals方法。
concurrentmap可以代替hashtable吗?
从性能的角度上来说可以,concurrentmap是分段索,只在部分地方上锁,提高了其性能。但是hashtable提供更高级的安全性。