collection里面有什么子类?(list和set是实现了collection接口的。) 

List:

1.可以允许重复的对象(可重复,有序集合)。
2.可以插入多个null元素。
3.常用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行,它提供了使用索引的随意访问,而 LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适。

list去重:方法一:使用java8新特性stream进行List去重 。方法二:双重for循环去重 。方法三:set集合判断去重。方法四:遍历后判断赋给另一个list集合 。方法五:set和list转换去重 
————————————————

Set:

1.不允许重复对象(不可重复,无序集合)。
2 只允许一个 null 元素
3.Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序集合。而且可以重复。
————————————————
Map:

1.Map不是collection的子接口或者实现类。Map是一个接口。
2.不允许重复元素。
3. Map 里你可以拥有随意个 null 值但只能有一个 null (key)键。
4. Map 接口最流行的几个实现类是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。(HashMap、TreeMap最常用)
————————————————

List 的实现类有 ArrayList,Vector 和 LinkedList:

ArrayList 和 Vector 内部是数组结构,线程不安全,在查询效率上会高很多。 Vector 是线程安全的,性能会稍慢一些。

LinkedList:是双向链表的数据结构,在做查询时会按照序号索引数据进行前向或后向遍历,查询效率偏低,插入速度较快。

Set 的实现类有 HashSet 和 TreeSet:

HashSet:内部是由哈希表(实际上是一个 HashMap 实例)支持的。集合元素可以是null,但只能放入一个null。无序的。

TreeSet:是二叉树实现的,有序的,或者根据创建 set 时提供的 Comparator 进行排序。

LinkedHashSet:是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。有序的,查询快,插入慢。当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好,但是插入时性能稍微逊色于HashSet。

Map 的实现类有 HashMap,Hashtable、TreeMap和 LinkedHashMap:

Hashtable:存储的键值对是无序的是按照哈希算法进行排序,与 HashMap 最大的区别就是线程安全(用synchronized)。键或者值不能为 null,为 null 就会抛出空指针异常。

HashMap: 继承Map接口,实现了哈希表,允许null,线程不安全。哈希表结构其实就是数组+链表;在JDK1.8中规定:当链表长度大于8时,链表长度就转换为红黑树,大大                        提高了查找效率。

TreeMap:基于红黑树 (二叉树) 数据结构实现,按 key 排序,默认的排序方式是升序。

LinkedHashMap:有序的 Map 集合实现类,通过插入排序,相当于一个栈,先 put 进去的最后出来,先进后出。

————————————————-------------------------------------------------------------------------------------------------------------------

HashMap: 线程不安全,链表结构,效率高;

Hashtable : 线程安全,但效率低,因为是Hashtable是使用synchronized的,所有线程竞争同一把锁;

Synchronized   Map: 线程安全,但效率低,一次性锁住整张表来保证线程安全,所以每次只能有一个线程来访问map。

ConcurrentHashMap:线程安全而且效率高,因为它包含一个segment数组,将数据分段存储,给每一段数据配一把锁。

          在理想状态下,ConcurrentHashMap 可支持16个线程执行并发写操作,及任意数量线程的读操作。

jdk1.7中采用Segment + HashEntry的方式进行实现。

jdk1.8中放弃了Segment臃肿的设计,取而代之的是采用Node + CAS Synchronized来保证并发安全进行实现。(HashEntry在1.8中称为Node)

Segment :  Segment 类继承于 ReentrantLock 类,从而使得 Segment 对象能充当锁的角色。

HashEntry : 主要存储键值对,可以叫节点、用来封装散列映射表中的键值对。  https://blog.csdn.net/dfsaggsd/article/details/50572958

如何线程安全的使用HashMap

  以下三种方式:用Hashtable、ConcurrentHashMap、或者Synchronized Map。

ConCurrentHashMap与HashTable区别?

两者都是线程安全的,但是hashTable锁住的是整个map,效率低下。而ConcurrentHashMap使用的是cas+synchronized机制,不会锁定整个map,而是锁定table数组位置对应的链表。
一般不要使用hashTable,推荐使用ConCurrentHashMap。

Hashmap的数据结构是什么样子的?自己如何实现一个hashmap?

主要数据结构即为数组+链表。默认长度是16。

Hashmap的底层数据结构是由数组+链表组成的,是线程不安全,允许key和value为null。

底层结构,数组叫哈希桶,而桶内则是链表,链表中的节点Node存放着实际的元素。

HashMap底层(原理)是如何实现的?

  HashMap先得到key的散列值,在通过扰动函数(减少碰撞次数)得到Hash值,接着通过hash & (n -1 ),n位table的长度,运算后得到数组的索引值。如果当前节点存在元素,则通过比较hash值和key值是否相等,相等则替换,不相等则通过拉链法查找元素,直到找到相等或者下个节点为null时。

HashMap是如何put元素的?

HashMap在put方法中,调用内部方法putVal。它使用hashCode()和equals()方法。当我们通过传递key-value对调用put方法的时候,HashMap使用Key hashCode()和哈希算法来找出存储key-value对的索引。如果索引处为空,则直接插入到对应的数组中,否则哈希冲突,要判断是否是红黑树,若是,则红黑树插入,否则遍历链表,若长度超过8,则将链表转为红黑树,转成功之后 再插入。

什么是Hash(哈希)、什么是Hash算法、什么是哈希表

  hash的定义:Hash译为散列,哈希是指一个过程,这个过程就是把任意长度的输入,通过散列算法,变换成固定长度的输出,所输出的称为哈希值(散列值)。

  Hash(哈希)算法:   即散列函数。它是一种单向密码体制,即它是一个从明文到密文的不可逆的映射,只有加密过程,没有解密过程。

  哈希表:   是根据设定的哈希函数(key)将一组关键字映射到一个有限的地址区间上,并以关键字在地址区间中的象作为记录在表中的存储位置,这种表称为哈希表或散列,所得存储位置称为哈希地址或散列地址。

Hash的计算规则(算法)?

第一步:调用key.hashCode()。

第二步:用hashCode值高16位异或低16位(右移16位然后与原先的hashCode值异或,即自己的高半区与低半区做异或,这样混合后的低位掺杂了高位的部分信息):

    return (key==null)?0:h=key.hashCode()^h>>>16;

第三步:取模运算:h&(length-1) 其中length为table数组长度。h&(length-1) 等价于h%length。

Hashmap的哈希怎么求出下标位置?

1、进行哈希散列 hash();
      int h=key.hashCode();
2、这里得到的是二进制数:比如:
      h=key.hashCode(); //得到的是32位二进制数

3、转换成二进制后 >>>右移16位和hahsCode值进行位异或.

4、然后index=(16-1)&&hash; 转换成二进制后index=2就是存储在数组中的下标位置。

HashMap的长度为什么是2的倍数?

  在HashMap的操作流程中,首先会对key进行hash算法得到一个索引值,这个索引值就是对应哈希桶数组的索引。为了得到这个索引值必须对扰动后的数跟数组长度进行取余运算。即 hash % n (n为hashmap的长度),又因为&比%运算快。n如果为2的倍数,就可以将%转换为&,结果就是 hash & (n-1)。所以这就解释了为什么HashMap长度是2的倍数。

哈希碰撞(冲突)是什么,怎么解决? https://www.cnblogs.com/williamjie/p/9377028.html

  两个不同的原始值在经过哈希运算后得到同样的结果,这样就是哈希碰撞。
解决方法:

开放定址法:   原理是在HashMap中,把同样哈希值的位置以一串链表存储起来数据,把多个原始值不同而哈希结果相同的数据以链表存储起来。
拉链法(链表法): 当发生地址冲突时,按照某种方法继续探测哈希表中的其他存储单元,直到找到空位置为止。

在哈希法:   当发生冲突时,使用第二个、第三个、哈希函数计算地址,直到无冲突时。缺点:计算时间增加。

谈一下hashMap中什么时候需要进行扩容,扩容resize()又是如何实现的?

调用场景:

1.当hashmap中的元素个数超过当前数组的长度 乘以 loadFactor(加载因子的值)时,就会进行数组扩容(loadFactor:默认值为0.75)

扩容resize()实现过程:

resize:原数组中的数据必须重新计算其在新数组中的位置,并放进去。

1.通过判断旧数组的容量是否大于0来判断数组是否初始化过

2、否:进行初始化。

3、是,进行扩容,扩容成两倍(小于最大值的情况下),之后在进行将元素重新进行与运算复制到新的散列表中

概括的讲:扩容需要重新分配一个新数组,新数组是老数组的2倍长,然后遍历整个老结构,把所有的元素挨个重新hash分配到新结构中去。

JDK 1.7 HashMap扩容导致死循环的主要原因?
  HashMap扩容导致死循环的主要原因在于扩容后链表中的节点在新的hash桶使用头插法插入。(链表倒置以及链表过长。)

新的hash桶会倒置原hash桶中的单链表,那么在多个线程同时扩容的情况下就可能导致产生一个存在闭环的单链表,从而导致死循环。

JDK 1.8 HashMap扩容不会造成死循环的原因?

  使用的是尾插法,不会导致单链表的倒置,所以扩容的时候不会导致死循环。

谈一下hashMap中get是如何实现的?

对key的hashCode进行hashing,与运算计算下标获取bucket位置,如果在桶的首位上就可以找到就直接返回,否则在树中找或者链表中遍历找,如果有hash冲突,则利用equals方法去遍历链表查找节点。

谈一下HashMap中hash函数是怎么实现的?还有哪些hash函数的实现方式?

对key的hashCode做hash操作,与高16位做异或运算

还有平方取中法,除留余数法,伪随机数法

为什么不直接将key作为哈希值而是与高16位做异或运算?

  因为数组位置的确定用的是与运算,仅仅最后四位有效,设计者将key的哈希值与高16为做异或运算使得在做&运算确定数组的插入位置时,此时的低位实际是高位与低位的结合,增加了随机性,减少了哈希碰撞的次数。

为什么是16?为什么必须是2的幂?如果输入值不是2的幂比如10会怎么样?

https://blog.csdn.net/sidihuo/article/details/78489820

https://blog.csdn.net/eaphyy/article/details/84386313

1.为了数据的均匀分布,减少哈希碰撞。因为确定数组位置是用的位运算,若数据不是2的次幂则会增加哈希碰撞的次数和浪费数组空间。(PS:其实若不考虑效率,求余也可以就不用位运算了也不用长度必需为2的幂次)

2.输入数据若不是2的幂,HashMap通过一通位移运算和或运算得到的肯定是2的幂次数,并且是离那个数最近的数字

谈一下当两个对象的hashCode相等时会怎么样?

  会产生哈希碰撞,若key值相同则替换旧值,不然链接到链表后面,链表长度超过阙值8就转为红黑树存储

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

  HashCode相同,通过equals比较内容获取值对象

1. java语言CAS底层如何实现?

  CAS是compare and swap的缩写,即我们所说的比较交换。cas是一种基于锁的操作,而且是乐观锁。

通过某种方式不加锁来处理资源,比如通过给记录加version来获取数据,性能较悲观锁有很大的提高。

具体:利用java(unsafe)提供的原子性操作方法。原子操作类,指的是java.util.concurrent.atomic包下,一系列以Atomic开头的包装类(AutoInteger)。

2.什么事ABA问题?怎么解决?

  当一个值从A变成B,又更新回A,普通CAS机制会误判通过检测。

  利用加上version版本号比较可以有效解决ABA问题。每次跟新version+1。

HashMap,ConcurrentHashMap原理。Collection(list,set,map集合区别)。和CAS的更多相关文章

  1. collection(list,set,map)集合详解

    一:java集合的体系结构如下: Java集合大致分为Set.List.Queue.Map四个体系 .Collection: List和Set,Queue继承自Collection接口. |--Lis ...

  2. HashTable & HashMap & ConcurrentHashMap 原理与区别

    一.三者的区别     HashTable HashMap ConcurrentHashMap 底层数据结构 数组+链表 数组+链表 数组+链表 key可为空 否 是 否 value可为空 否 是 否 ...

  3. Collection和Map集合

    前言 集合的长度是可变的.集合存储的都是对象.而且对象的类型可以不一致. Collection集合和Map集合是所有集合的父接口. Collection接口定义 体系结构的根接口,代表一组对象,有两个 ...

  4. Map集合。

    Map集合: java.util,Map<k,v> 特点:1.键值对 2.key-value一一对应 3.key不允许重复. Map常用实现类: java.util.HashMap< ...

  5. 有序取出Map集合的元素

    最近写到一个程序,返回了map,但是经过查阅资料,map是没有顺序的,各种查阅资料无果,最后自己写了这个方法.. 1,通过map集合的keySet()方法,获取到一个包含map所有key的Set集合 ...

  6. 浅谈Java中的Set、List、Map的区别(转)

    对JAVA的集合的理解是想对于数组: 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),JAVA集合可以存储和操作数目不固定的一组数据. 所有的JAVA集合都位于 java ...

  7. Java-list,set,map的区别

    jdk中api的定义 Collection ├----List │ ├----LinkedList │ ├----ArrayList │ └----Vector │ └----Stack └----S ...

  8. Java基础知识Set、List、Map的区别

    就学习经验,浅谈Java中的Set,List,Map的区别,对JAVA的集合的理解是相对于数组: 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),JAVA集合可以存储和操 ...

  9. Set,List,Map的区别

    最近在学习struct2中OGNL表达式的过程中,发现自己对set,list,map存在只是欠缺,在百度的过程中发现了此文觉得讲的不错,放到自己博客以便再次查阅,也希望更多地菜鸟看到. java集合的 ...

随机推荐

  1. 【STM32H7教程】第46章 STM32H7的ADC应用之DMA方式多通道采样

    完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第46章       STM32H7的ADC应用之DMA方式多 ...

  2. Java基础之四、字符和字符串 异常处理

    字符和字符串是最常用的信息 1:char表示字符 字符常量-两个单引号中间的字符表示字符常量'A' 2:字符串和String 字符串常量-双引号中间的字符序列"Java" 字符串常 ...

  3. C#连接数据库的方法

    using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...

  4. 基于element-ui 模仿微信聊天页面以及滚动条隐藏在chrome和其他浏览器的处理

    1.效果图 2.代码 <template> <div style=" overflow: hidden;"> <el-row> <el-c ...

  5. export default和export的使用方法

    Node中 向外暴露成员,使用module.exports和exports module.exports = {} Node中导入模块 var 名称 = require('模块标识符') 在ES6中 ...

  6. phpcms抛出的二维数组转移到js,js中for....in遍历数组,用“.”连接来读出一维数组值

    直切正题: 1.phpcms在模版中读出数组有很多中方法,如,{pc:content action="lists"}或{pc:get sql=""},经过{lo ...

  7. 11maven的聚合

    我们都知道项目之间的依赖首先要把被依赖的项目先安装install到maven的本地仓库中,然后在本项目中配置被依赖的仓库坐标,才能进行依赖通信. 例如: A项目 >  B项目 A项目依赖B项目中 ...

  8. Linux 用户命令

    用户管理的命令 添加删除用户,注意的是,涉及到权限的修改,只能用root去操作,其他人基本上没权限 useradd caixukun #创建用户caixukunpasswd   caixukun #给 ...

  9. linux C++ 读取mysql结果保存

    c++读取mysql数据库结果保存 #include <fstream> #include <iomanip> #include <iostream> #inclu ...

  10. [转]从实例谈OOP、工厂模式和重构

    有了翅膀才能飞,欠缺灵活的代码就象冻坏了翅膀的鸟儿.不能飞翔,就少了几许灵动的气韵.我们需要给代码带去温暖的阳光,让僵冷的翅膀重新飞起来.结合实例,通过应用OOP.设计模式和重构,你会看到代码是怎样一 ...