JAVA中的部分需要扩容的内容总结如下:
第一部分:

HashMap<String, String> hmap=new HashMap<>();
HashSet<String> hset=new HashSet<>();
Hashtable<String, String> htable=new Hashtable<>();
第二部分:

CopyOnWriteArrayList<String> coarray=new CopyOnWriteArrayList<>();
ArrayList<String> array=new ArrayList<>();
Vector<String> vec=new Vector<>();
第三部分:

StringBuffer sb=new StringBuffer();
StringBuilder sbu=new StringBuilder();
先从以下几个源码方面分析:(JDK1.8)

1、初始容量。
2、扩容机制。
3、同类型之间对比。

1.1 HashMap:
一、初始容量定义:默认为1 << 4(16)。最大容量为1<< 30。
/**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
/**
* The maximum capacity, used if a higher value is implicitly specified
* by either of the constructors with arguments.
* MUST be a power of two <= 1<<30.
*/
static final int MAXIMUM_CAPACITY = 1 << 30;
二、扩容加载因子为(0.75),第一个临界点在当HashMap中元素的数量等于table数组长度*加载因子(16*0.75=12),
如果超出则按oldThr << 1(原长度*2)扩容。
/**
* The load factor used when none specified in constructor.
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;
/**
* Constructs an empty <tt>HashMap</tt> with the default initial capacity
* (16) and the default load factor (0.75).
*/
if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
oldCap >= DEFAULT_INITIAL_CAPACITY)
newThr = oldThr << 1; // double threshold

1.2 HashSet

一、初始容量定义:16。因为构造一个HashSet,其实相当于新建一个HashMap,然后取HashMap的Key。
扩容机制和HashMap一样。
public HashSet(Collection<? extends E> c) {
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}

1.3 Hashtable<String, String> htable=new Hashtable<>();
public class Hashtable<K,V>
extends Dictionary<K,V>
一、初始容量定义:capacity (11)。
/**
* Constructs a new, empty hashtable with a default initial capacity (11)
* and load factor (0.75).
*/
public Hashtable() {
this(11, 0.75f);
}
二、扩容加载因子(0.75),当超出默认长度(int)(11*0.75)=8时,扩容为old*2+1。
int newCapacity = (oldCapacity << 1) + 1;

小结:HashTable和HashMap区别

第一,继承不同。
public class Hashtable extends Dictionary implements Map
public class HashMap extends AbstractMap implements Map
第二:
Hashtable 中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。在多线程并发的环境下,可以直接使用

Hashtable,但是要使用HashMap的话就要自己增加同步处理了。
第三,Hashtable中,key和value都不允许出现null值。

在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,

即可以表示 HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中

是否存在某个键, 而应该用containsKey()方法来判断。

第四,两个遍历方式的内部实现上不同。

Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。

第五,哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。

第六,
Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方

式是 old*2+1。HashMap中hash数组的默认大小是16, 增加的方式是 old*2。

2.1 CopyOnWriteArrayList:
/**
* Creates an empty list.
*/
public CopyOnWriteArrayList() {
setArray(new Object[0]);
}
CopyOnWriteArrayList在做修改操作时,每次都是重新创建一个新的数组,在新数组上操作,最终再将新数组替换掉原数组

。因此,在做修改操作时,仍可以做读取操作,读取直接操作的原数组。读和写操作的对象都不同,因此读操作和写操作互

不干扰。只有写与写之间需要进行同步等待。另外,原数组被声明为volatile,这就保证了,一旦数组发生变化,则结果对

其它线程(读线程和其它写线程)是可见的。

CopyOnWriteArrayList并不像ArrayList一样指定默认的初始容量。它也没有自动扩容的机制,而是添加几个元素,长度就相

应的增长多少。

CopyOnWriteArrayList适用于读多写少,既然是写的情况少,则不需要频繁扩容。并且修改操作每次在生成新的数组时就指

定了新的容量,也就相当于扩容了,所以不需要额外的机制来实现扩容。
2.2 ArrayList<String> array=new ArrayList<>();
一、初始容量定义:10。
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;

二、扩容:oldCapacity + (oldCapacity >> 1),即原集合长度的1.5倍。
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
2.3 Vector<String> vec=new Vector<>();
一、初始容量定义:10。
public Vector() {
this(10);
}
二、扩容:当扩容因子大于0时,新数组长度为原数组长度+扩容因子,否则新数组长度为原数组长度的2倍。
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
小结:
1,ArrayList与Vector初始容量都为10。
2,扩容机制不同,当超出当前长度时ArrayList扩展为原来的1.5倍,而若不考虑扩容因子Vector扩展为原来的2倍。

3,ArrayList为非线程安全的,处理效率上较Vector快,若同时考虑线程安全和效率,可以使用 CopyOnWriteArrayList。

3.1 StringBuffer sb=new StringBuffer();
一、初始容量定义:16。
public StringBuffer() {
super(16);
}
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
二、扩容:因为StringBuffer extends AbstractStringBuilder,所以实际上是用的是AbstractStringBuilder
的扩容方法,当用append(str),添加字符串时,假设字符串中已有字符长度为count的字符串,初始长度value=16,若要添加的

字符串长度(count+str.length())<=(value*2+2)则按value*2+2长度扩容,并且
value=value*2+2,若(count+str.length())>(value*2+2),则按count+str.length()长度扩容,并且
value=count+str.length()。下次超出时再按以上方法与value*2+2比较扩容。

private int newCapacity(int minCapacity) {
// overflow-conscious code
int newCapacity = (value.length << 1) + 2;
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;

3.2 StringBuilder sbu=new StringBuilder();
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
public StringBuilder() {
super(16);
}
private int newCapacity(int minCapacity) {
// overflow-conscious code
int newCapacity = (value.length << 1) + 2;
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
小结:
1.StringBuilder是jdk1.5引进的,而StringBuffer在1.0就有了;
2.StringBuilder和StringBuffer都是可变的字符串。能够通过append或者insert等方法改动串的内容;
3.StringBuffer是线程安全的而StringBuilder不是,因而在多线程的环境下优先使用StringBuffer,而其它情况下推荐使用

StringBuilder,由于它更快。
4.StringBuilder和StringBuffer都继承自AbstractStringBuilder类,AbStractStringBuilder主要实现了扩容、append、

insert方法。StrngBuilder和StringBuffer的相关方法都直接调用的父类。
5.StringBuilder和StringBuffer的初始容量都是16,程序猿尽量手动设置初始值。以避免多次扩容所带来的性能问题;
6.StringBuilder和StringBuffer的扩容机制是这种:首先试着将当前数组容量扩充为原数组容量的2倍加上2,假设这个新容

量仍然小于预定的最小值(minimumCapacity),那么就将新容量定为(minimumCapacity),最后推断是否溢出,若溢出,

则将容量定为整型的最大值0x7fffffff。

浅谈JAVA中HashMap、ArrayList、StringBuilder等的扩容机制的更多相关文章

  1. 浅谈Java中set.map.List的区别

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

  2. Java基础学习总结(29)——浅谈Java中的Set、List、Map的区别

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

  3. 【转】浅谈Java中的hashcode方法(这个demo可以多看看)

    浅谈Java中的hashcode方法 哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native i ...

  4. 【转】浅谈Java中的hashcode方法

    哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native int hashCode(); 根据这个 ...

  5. 浅谈Java中的hashcode方法(转)

    原文链接:http://www.cnblogs.com/dolphin0520/p/3681042.html 浅谈Java中的hashcode方法 哈希表这个数据结构想必大多数人都不陌生,而且在很多地 ...

  6. 浅谈Java中的equals和==(转)

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...

  7. 浅谈Java中的对象和引用

    浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...

  8. 浅谈Java中的equals和==

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: String str1 = new String("hello"); String str2 = ...

  9. 浅谈Java中的深拷贝和浅拷贝(转载)

    浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...

随机推荐

  1. [Go] 开发 go web 项目,踩到的一些“坑”

    注意:这些“坑”不是bug,只是自己当时没搞明白. 用到的框架为 Beego 1.字典 map 是“引用类型”,本身就是指针,作为参数传递时,直接传 map 变量名即可(不要传 map 变量指针). ...

  2. app v1界面

         

  3. Android典型界面设计(7) ——DrawerLayout+Fragement+ViewPager+PagerTabStrip实现双导航

    一.问题描述 在Android典型界面设计(3)的我们实现了双导航效果,即外层底部导航和内部区域的头部导航,如网易新闻等很多应用采用了这种导航,但Google提供DrawerLayout可实现抽屉式导 ...

  4. 郑晔谈 Java 开发:新工具、新框架、新思维【转载】【整理】

    原文地址 导语:"我很惊讶地发现,现在许多程序员讨论的内容几乎和我十多年前刚开始做 Java 时几乎完全一样.要知道,我们生存的这个行业号称是变化飞快的.其实,这十几年时间,在开发领域已经有 ...

  5. 微软BI 之SSAS 系列 - 多维数据集维度用法之二 事实维度(退化维度 Degenerate Dimension)

    这篇文章是基于上一篇 SSAS 系列 - 多维数据集维度用法之一 引用维度 Referenced Dimension 继续讲解多维数据集维度用法中的事实维度. 事实维度,顾名思义就是把事实表 Fact ...

  6. 基于CentOS体验万象优图鉴黄服务

    系统要求:CentOS 7.2 64 位操作系统 初始化配置 使用万象优图图片鉴黄 API 接口,我们需要先完成以下步骤: 获取腾讯云账号 APP ID 配置云 API 公钥/密钥 配置优图 buck ...

  7. 【Android】解析Android的路径

    目录结构: contents structure [+] 内部路径 外部路径 Assets目录 Android中的路径主要分为内部路径和外部路径. 一.内部路径 常见的内部存储路径有: File f1 ...

  8. aaronyang的百度地图API之LBS云与.NET开发 Javascript API 2.0【把数据存到LBS云2/2】

    中国的IT 需要无私分享和贡献的人,一起努力 本篇博客来自地址:http://www.cnblogs.com/AaronYang/p/3672898.html,请支持原创,未经允许不许转载 1.新建一 ...

  9. SNF快速开发平台--规则引擎整体介绍及使用说明书

    一.设计目标 a)规则引擎语法能够满足分单,计费,WMS策略的配置要求.语法是一致和统一的 b)能够在不修改规则引擎模块的情况下,加入任意一个新的规则:实现上述需求之外的规则配置需求 c)运算速度快 ...

  10. 使用Nginx实现灰度发布(转)

    灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式.AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B ...