HashMap

概要

在JDK1.6,JDK1.7中,HashMap采用位桶+链表实现,即使用链表处理冲突,同一hash值的键值对会被放在同一个位桶里,
当桶中元素较多时,通过key值查找的效率较低。

在极端情况下可能会存在某个链表很长,整个时候整个查找效率就变低了,于是有了1.8的改进方式。使用红黑树,提升查询效率。

而JDK1.8中,HashMap采用位桶+链表+红黑树实现,如果哈希表单向链表中元素超过8个,那么单向链表这种数据结构会变成红黑树数据结构。
当红黑树上的节点数量小于6个,会重新把红黑树变成单向链表数据结构。

数组

存储区间是连续,且占用内存严重,空间复杂也很大,时间复杂为O(1)。

Read More

ConcurrentHashMap

ConcurrentHashMap 是一个并发散列映射表的实现,它允许完全并发的读取,并且支持给定数量的并发更新。
相比于 HashTable 和用同步包装器包装的HashMap(Collections.synchronizedMap(new HashMap())),ConcurrentHashMap 拥有更高的并发性。
在 HashTable 和由同步包装器包装的 HashMap 中,使用一个全局的锁来同步不同线程间的并发访问。同一时间点,只能有一个线程持有锁,
也就是说在同一时间点,只能有一个线程能访问容器。这虽然保证多线程间的安全并发访问,但同时也导致对容器的访问变成串行化的了。
在使用锁来协调多线程间并发访问的模式下,减小对锁的竞争可以有效提高并发性。有两种方式可以减小对锁的竞争: 减小请求同一个锁的频率。
减少持有锁的时间。 ConcurrentHashMap 的高并发性主要来自于三个方面:

  1. 用分离锁实现多个线程间的更深层次的共享访问。
  2. 用HashEntery对象的不变性来降低执行读操作的线程在遍历链表期间对加锁的求。
  3. 通过对同一个 volatile 变量的写 / 读访问,协调不同线程间读 / 写操作的内存可见性。 使用分离锁,减小了请求同一个锁的频率。
Read More

反射

反射(Reflection)的作用:

  • 反射让开发人员可以通过外部类的全路径名创建对象,并使用这些类,实现一些扩展的功能。
  • 反射让开发人员可以枚举出类的全部成员,包括构造函数、属性、方法。以帮助开发者写出正确的代码。
  • 测试时可以利用反射API访问类的私有成员,以保证测试代码覆盖率。
Read More

泛型

概述

范型的设计参考了C++中的模版,目的是写出更加通用的代码。泛型将代码安全性检查提前到编译期。添加了范型特性后,解决了Java中容器的类型安全问题。

泛型的本质是参数化类型。也就是说,泛型就是将所操作的数据类型作为参数的一种语法。

Java泛型为了向前兼容,采取运行期类型擦出泛型参数的方式来实现。这就意味着,你在使用泛型的时候,任何具体的类型都已经被擦除。

1
2
3
4
5
public class Paly<T>{ 
T play(){}
}

Play<Integer> playInteger=new Play<>();//这里 T 就会被实例化为 Integer

Read More

引用类型

概要介绍

Java中的几种引用类型:

  • 强引用: 强引用指的是在程序代码之中普遍存在的,类似于”Object obj = new Object()”这类的引用,只要强引用还存在,垃圾回收器永远不会回收掉被引用的对象实例。
  • 软引用: 软引用是用来描述一些还有用但是不是必须的对象。对于软引用关联着的对象,在系统将要发生内存溢出之前,会把这些对象列入回收范围 之中进行第二次回收。
    如果这次回收还是没有足够的内存,才会抛出内存溢 出异常。在 JDK1.2 之后,提供了 SoftReference 类来实现软引用。
  • 弱引用: 弱引用也是用来描述非必需对象的。但是它的强度要弱于软引用。被弱引用关联的对象只能生存到下一次垃圾回收发生之前。当垃圾回收 器开始进行工作时,
    无论当前内容是否够用,都会回收掉只被弱引用关联的 对象。在 JDK1.2 之后提供了 WeakReference 类来实现弱引用。
Read More