当前位置: 首页 > news >正文

网站怎么放到服务器西安seo服务培训

网站怎么放到服务器,西安seo服务培训,三只松鼠网站怎样做,北京造价员变更在哪个网站做一、结论先行ArrayList在JDK1.8与JDK1.7底层区别JDK1.7:ArrayList像饿汉式,直接创建一个初始容量为10的数组,当数组的长度不能容下所添加的内容时候,数组会扩容至原大小的1.5倍JDK1.8:ArrayList像懒汉式,一…

一、结论先行

ArrayList在JDK1.8与JDK1.7底层区别

JDK1.7:ArrayList像饿汉式,直接创建一个初始容量为10的数组,当数组的长度不能容下所添加的内容时候,数组会扩容至原大小的1.5倍

JDK1.8:ArrayList像懒汉式,一开始创建一个长度为0的数组,当添加第一个元素时再创建一个始容量为10的数组,当数组的长度不能容下所添加的内容时候,数组会扩容至原大小的1.5倍

二、JDK1.8 ArrayList源码分析

1、ArrayList 属性

/**

* 默认容量的大小

*/

private static final int DEFAULT_CAPACITY = 10;

/**

* 空数组常量

*/

private static final Object[] EMPTY_ELEMENTDATA = {};

/**

* 默认的空数组常量,我们将其与EMPTY_ELEMENTDATA区分开来,

* 以便知道添加第一个元素时需要膨胀多少

*/

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

/**

* 存放元素的数组,从这可以发现ArrayList的底层实现就是一个Object数组

*/

transient Object[] elementData;

/**

* 数组中包含元素的个数

*/

private int size;

/**

*数组的最大上限,超过上限可能导致OutOfMemoryError错误

*/

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

2、构造方法

/**

* 指定大小的时候,elementData就变成了我们所指定的初始化大小了

*/

public ArrayList(int initialCapacity) {

if (initialCapacity > 0) {

this.elementData = new Object[initialCapacity];

} else if (initialCapacity == 0) {

this.elementData = EMPTY_ELEMENTDATA;

} else {

throw new IllegalArgumentException("Illegal Capacity: "+

initialCapacity);

}

}

/**

* 根据上面的属性可知,DEFAULTCAPACITY_EMPTY_ELEMENTDATA={},所以默认创建的是 一个大小为0的空数组

*/

public ArrayList() {

this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;

}

从上面我可以知道,jkd1.8中默认的是大小为0空数组,这个和jdk1.7之前都是不一样的,这和设计模式的懒汉式很有相似之处

3、add 方法,底层扩容机制

/**

* 在指定的位置插入指定的元素

*/

public void add(int index, E element) {

rangeCheckForAdd(index);

ensureCapacityInternal(size + 1); // Increments modCount!!

System.arraycopy(elementData, index, elementData, index + 1,

size - index);

elementData[index] = element;

size++;

}

/**

* 将指定的参数添加到列表的末尾,其中size是数组中包含元素的个数

* @param e 以附加到此列表中

*/

public boolean add(E e) {

ensureCapacityInternal(size + 1);

// 数组的下标从0开始,所以size++保证elementData每次添加完一个元素,元素个数也随之加1

elementData[size++] = e;

return true;

}

// 参数minCapacity 表达的意思是所需数组的最小容量,也就是size+1, 上面传的值

private void ensureCapacityInternal(int minCapacity) {

ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));

}

/**

* 计算容量的方法,

*/

private static int calculateCapacity(Object[] elementData, int minCapacity) {

// 如果是一个空数组,

if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {

// DEFAULT_CAPACITY从属性可知默认是10,minCapactity为数组的大小

// 由此可以看出他是在添加第一个元素的时候,才创建了长度为10的数组

return Math.max(DEFAULT_CAPACITY, minCapacity);

}

return minCapacity;

}

private void ensureExplicitCapacity(int minCapacity) {

modCount++;

// 如果此时所需要的最小的长度大于原数组的长度,则需要进行扩容

if (minCapacity - elementData.length > 0)

grow(minCapacity);

}

/**

* 增加容量,以确保它至少可以容纳minCapacity指定的元素数量。

* @param minCapacity 表示所需要的扩容的量

*/

private void grow(int minCapacity) {

int oldCapacity = elementData.length; // 原数组的长度

//原数组的长度+原数组的长度/2,表示扩容了原来大小的1.5倍,newCapacity :表示需要扩容的量

int newCapacity = oldCapacity + (oldCapacity >> 1);

if (newCapacity - minCapacity < 0)

newCapacity = minCapacity;

// 如果需要的扩容量大于了本类中定义的最大扩容限制,则扩容到 int 类型最大长度

if (newCapacity - MAX_ARRAY_SIZE > 0)

newCapacity = hugeCapacity(minCapacity);

// 调用的是数组的复制方法,实现扩容

elementData = Arrays.copyOf(elementData, newCapacity);

}

private static int hugeCapacity(int minCapacity) {

if (minCapacity < 0) // overflow

throw new OutOfMemoryError();

// 如若需要扩容的量大于最大限制,则扩容量改为 int 最大限制量:2147483647,否则为本类中所限制长度:2147483647-8

return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;

}

解释:int newCapacity = oldCapacity + (oldCapacity >> 1);

这个>>1 表示的是右移一位,转为二进制我们应该一下就明白了:比如16,转为2进制为

10000,右移一位则成为01000,换为十进制就是8,扩容的大小也就相当于oldCapacity +oldCapacity /2了

4、总结

jdk1.8中:

add方法总结起来就是在插入数据之前,会先检查是否需要扩容,通过无参构造方法来创建 ArrayList 时,它的大小其实是为 0 的,只有在使用到 的时候,才会通过 grow 方法去创建一个大小为 10 的数组。

public boolean add(E e) 方法的复杂度为O(1),涉及到扩容的操作是非常少的,可以忽略不计,它的本质是添加元素到数组中最后一个元素的后面。

public void add(int index, E element) 这个是带指定下标的add 方法,复杂度为O(n),因为涉及到数组中元素的移动,这一操作非常耗时,由此可见ArrayList不适合插入和删除操作。

三、ArrayList与Vector的区别

现在Vector已经很少有人用了,这里只是简单的记录下二者区别:

1、ArrayList线程不安全,Vector是线程安全的

通过Vector源码我们可以知道很多方法都是加了synchronized关键字,所以Vector是线程安全的。

2、ArrayList创建的默认大小为0,Vector创建时的默认大小是10。

3、ArrayList 每次扩容都以当前数组大小的 1.5 倍去扩容, Vector 每次扩容都以当前数组大小的 2 倍去扩容。当指定了 capacityIncrement 之 后,每次扩容仅在原先基础上增加 capacityIncrement 个单位空间。

补充知识:ArrayList详解,底层是数组,实现Serializable接口

一、对于ArrayList需要掌握的七点内容

ArrayList的创建:即构造器

往ArrayList中添加对象:即add(E)方法

获取ArrayList中的单个对象:即get(int index)方法

删除ArrayList中的对象:即remove(E)方法

遍历ArrayList中的对象:即iterator,在实际中更常用的是增强型的for循环去做遍历

判断对象是否存在于ArrayList中:contain(E)

ArrayList中对象的排序:主要取决于所采取的排序算法(以后讲)

二、源码分析

2.1、ArrayList的创建(常见的两种方式)

List strList = new ArrayList();

List strList2 = new ArrayList(2);

ArrayList源代码:

基本属性:

//对象数组:ArrayList的底层数据结构

private transient Object[] elementData;

//elementData中已存放的元素的个数,注意:不是elementData的容量

private int size;

注意:

transient关键字的作用:在采用Java默认的序列化机制的时候,被该关键字修饰的属性不会被序列化。

ArrayList类实现了java.io.Serializable接口,即采用了Java默认的序列化机制

上面的elementData属性采用了transient来修饰,表明其不使用Java默认的序列化机制来实例化,但是该属性是ArrayList的底层数据结构,在网络传输中一定需要将其序列化,之后使用的时候还需要反序列化,那不采用Java默认的序列化机制,那采用什么呢?直接翻到源码的最下边有两个方法,发现ArrayList自己实现了序列化和反序列化的方法

View Code

构造器:

/**

* 创建一个容量为initialCapacity的空的(size==0)对象数组

*/

public ArrayList(int initialCapacity) {

super();//即父类protected AbstractList() {}

if (initialCapacity < 0)

throw new IllegalArgumentException("Illegal Capacity:" + initialCapacity);

this.elementData = new Object[initialCapacity];

}

/**

* 默认初始化一个容量为10的对象数组

*/

public ArrayList() {

this(10);//即上边的public ArrayList(int initialCapacity){}构造器

}

在我们执行new ArrayList()时,会调用上边的无参构造器,创造一个容量为10的对象数组。

在我们执行new ArrayList(2)时,会调用上边的public ArrayList(int initialCapacity),创造一个容量为2的对象数组。

注意:

上边有参构造器的super()方法是ArrayList父类AbstractList的构造方法,这个构造方法如下,是一个空构造方法:

protected AbstractList() {

}

在实际使用中,如果我们能对所需的ArrayList的大小进行判断,有两个好处:

节省内存空间(eg.我们只需要放置两个元素到数组,new ArrayList(2))

避免数组扩容(下边会讲)引起的效率下降(eg.我们只需要放置大约37个元素到数组,new ArrayList(40))

2.2、往ArrayList中添加对象(常见的两个方法add(E)和addAll(Collection extends E> c))

以上这篇聊一聊jdk1.8中的ArrayList 底层数组是如何扩容的就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

http://www.wooajung.com/news/35305.html

相关文章:

  • 商务网站建设与维护 ppt最经典最常用的网站推广方式
  • 宝山网站建设 网站外包湖南正规seo优化报价
  • 细胞医疗 网站模版深度搜索
  • 建设信用卡在网站挂失块吗网络推广是指什么
  • 这样做的网站微博营销
  • 手机端网站开发教程临沂百度代理公司有几个
  • 抓好党建网站联盟建设专业seo网络推广
  • 做淘宝有没有店小秘类型的网站网店怎么运营和推广
  • 岳阳做网站 公司电话怎样做网站推广
  • 网站建设公司需要具备销售平台有哪些
  • 东莞网站关键排名优秀营销软文100篇
  • 自己做网站 需要会什么6百度在线入口
  • 网站怎样优化关键词好十大免费cms建站系统介绍
  • phpstudy做正式网站获客
  • 网站摄影设计西安百度代运营
  • 云南住房建设厅网站制作网页代码大全
  • 做采集网站难不关键词优化步骤简短
  • 深圳建设网站费用明细推广app赚钱的平台
  • 优秀平面设计网站公关
  • 企业展示建设网站营销型公司网站建设
  • 比较好的网页设计网站怎么接广告赚钱
  • 万网域名管理控制台百度竞价是seo还是sem
  • 新乡专业做淘宝网站2023搜索最多的关键词
  • 山西两学一做登录网站百度推广客户端怎么登陆
  • 用KEGG网站做通路富集分析热门关键词
  • 做网站需要的合同温州seo结算
  • 企业网站排名优化价格刷seo排名
  • 专业做制作网站信息发布推广方法
  • 广州 营销型网站建设广点通推广登录入口
  • 个人博客网站制作论文武汉百度百科