java集合框架小札

ArrayList与LinkedList异同

  • 线程安全
    • ArrayList和LinkedList都是不同步,不保证线程安全
  • 底层数据结构
    • Arraylist 底层使用的是Object数组
    • LinkedList 底层使用的是双向链表数据结构
  • 插入和删除是否受元素位置的影响
    • ArrayList 采用数组存储(顺序存储),插入和删除时间复杂度受影响
    • LinkedList 采用链表存储,不受影响
  • 是否支持快速随机访问
    • LinkedList不支持高效的随机元素访问,而ArrayList支持
  • 内存空间占用
    • ArrayList的空 间浪费主要体现在在list列表的结尾会预留一定的容量空间
    • LinkedList每一个元素都需要消耗比ArrayList更多的空间(存放直接后继和前驱以及自身的数据)
  • list遍历方式选择
    • 实现了RandomAccess接口的list,优先选择普通for循环,其次foreach
    • 未实现的,优先先选择iterator遍历

ArrayList与Vector区别

  • Vector类的所有方法都是同步的(同步在多线程编程才有意义)。
  • ArrayList非同步,在不需要保证线程安全时通常使用它。

HashMap底层实现

  • 该类的hash方法也就是扰动函数是为了防止一些实现比较差的 hashCode() 方法,减少碰撞。
  • 拉链法,将链表和数组相结合。
    • 创建一个链表数组,数组中每一格就是一个链表。若遇到哈希冲突,则将冲突的值加到链表中即可。

HashMap和Hashtable的区别

  • 线程是否安全
    • HashMap是非线程安全
    • HashTable是线程安全,其内部方法基本都经过synchronized修饰
  • 效率 HashMap比HashTable高
  • 对Null key 和 Null value的支持
    • HashMap中null可以作为键,可有多个值为null
    • HashTable中的put键值均不可为null
  • 初始容量大小和每次扩容量大小的不同
    • 创建时如果不指定容量初始值,Hashtable 默认的初始大小为11,之后每次扩充,容量变为原来的2n+1
    • HashMap 默认的初始化大小为16。之后每次扩充,容量变为原来的2倍
    • 创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为2的幂次方大小
  • 底层数据结构
    • JDK1.8 以后的 HashMap 当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间

HashMap 多线程操作导致死循环问题

  • 原因在于 HashMap 的扩容 resize()方法
    • 扩容是新建一个数组,复制原数据到数组
    • 由于数组下标挂有链表,所以需要复制链表,但是多线程操作有可能导致环形链表。

HashSet 和 HashMap 区别

  • HashSet 底层就是基于 HashMap 实现的

ConcurrentHashMap 和 Hashtable 的区别

ConcurrentHashMap 和 Hashtable 的区别主要体现在实现线程安全的方式上不同

  • 底层数据结构
    • JDK1.7的 ConcurrentHashMap 底层采用 分段的数组+链表 实现
    • JDK1.8 采用的数据结构跟HashMap1.8的结构一样,数组+链表/红黑二叉树
    • JDK1.8之前 数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的
  • 实现线程安全的方式
    • 在JDK1.7的时候,ConcurrentHashMap(分段锁),由 Segment 数组结构和 HashEntry 数组结构组成。
    • JDK1.8直接用 Node 数组+链表+红黑树的数据结构来实现,并发控制使用 synchronized 和 CAS 来操作。
    • Hashtable(同一把锁)

Collection底层数据结构总结

  • List
    • Arraylist: Object数组
    • Vector: Object数组
    • LinkedList: 双向链表(JDK1.6之前为循环链表,JDK1.7取消了循环)
  • Set
    • HashSet(无序,唯一): 基于 HashMap 实现的,底层采用 HashMap 来保存元素
    • LinkedHashSet: LinkedHashSet 继承与 HashSet,并且其内部是通过 LinkedHashMap 来实现的
    • TreeSet(有序,唯一): 红黑树(自平衡的排序二叉树。)
  • Map
    • HashMap jdk1.8+ 当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间
    • LinkedHashMap
      • 在上面结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序
      • 同时通过对链表进行相应的操作,实现了访问顺序相关逻辑
    • HashTable: 数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的
    • TreeMap: 红黑树(自平衡的排序二叉树)

反射机制

  • 定义:动态获取信息及动态调用对象的方法功能
  • 编译
    • 静态编译:
      • 在编译时确定类型,绑定对象
    • 动态编译:
      • 运行时确定类型,绑定对象
  • 反射特点
    • 优点:运行期类型的判断,动态加载类,提高代码灵活度
    • 缺点:性能瓶颈,相当于一系列解释操作
  • 应用场景
    • 通过反射去调用对应的字节码
    • 通过反射机制实现动态代理设计模式
    • 应用框架
      • Spring/Hibernate
      • JDBC连接数据库用Class.forName()通过反射加载数据库的驱动程序
      • Spring经典的xml配置模式,装载Bean过程
        1. 将程序内所有 XML 或 Properties 配置文件加载入内存中
        2. Java类里面解析xml或properties里面的内容,得到对应实体类的字节码字符串以及相关的属性信息
        3. 使用反射机制,根据这个字符串获得某个类的Class实例
        4. 动态配置实例的属性

List,Set,Map之比较

  • List 该接口存储一组不唯一的有序对象
  • Set 不允许重复的对象集合
  • Map 使用键值对存储,key不允许重复,可以是字符串,也可以是任意对象

comparable 和 comparator

  • comparable接口实际上是出自java.lang包 它有一个 compareTo(Object obj)方法用来排序
  • comparator接口实际上是出自 java.util 包它有一个compare(Object obj1, Object obj2)方法用来定制排序
  • 对objects数组排序,用Arrays.sort()
  • 对objects集合进行排序,用Collections.sort()

数组与List转换

  • List转数组 toArray(arraylist.size())
  • 数组转List Arrays的asList(a)方法
  • ArrayList操作接口方法
    • addAll(Collection<? extends E> c) 并集
    • retainAll(Collection<?> c) 交集
    • removeAll(Collection<?> c) 差集
    • 无重复并集
      • list2.removeAll(list1);list1.addAll(list2);

猜你喜欢

转载自blog.csdn.net/u011584949/article/details/86511799