关于ArrayList扩容的疑问

丿任飘渺 2018-09-12 09:51:35
package cn.itheima.arraylist;

import java.util.ArrayList;

public class Demo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("a");
list.add("a");
list.add("a");
list.add("a");
list.add("a");
list.add("a");
list.add("a");
list.add("a");
list.add("a");
ArrayList<String>list1=list;
list.add("a");
System.out.println(list==list1);//true
}
}

ArrayList扩容后在底层产生新的数组,地址是不变吗??
...全文
1155 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
sjlzcj 2018-10-16
  • 打赏
  • 举报
回复
我认为你这个问题 跟 深浅拷贝 没什么关系 整段代码 两行 重点 1. ArrayList<String> list = new ArrayList<>(); 可以理解为 开辟了一个空间 并且用 list 指向这个空间 2. ArrayList<String>list1=list; 将 list 指向的空间地址赋值给 list1 所以 list1 与 list 指向同一块空间 然后 无论你是 操作 list 还是 list1 其实都是在 一个地址空间内操作 并且没用 使用 = 或 new 等方法来改变 list 或 list1 指向的地址 所以 你 list== list1 是true 根本原因是 == 在java 中比较的仅仅是地址
01世界历险记 2018-10-15
  • 打赏
  • 举报
回复
@SunsetFeng 你这里的hashCode值并不是list的地址,这里是AbstractList里重写的hashCode方法,是元素哈希值的累加值,所以你每次添加一个元素得到的hashcode都是会变的
引用 7 楼 qq_27368993 的回复:
首先吧,list和list1的实例对象是同一个,所以不管你怎么扩,这两个比肯定是一样的。我做了个测试 结果如下: 第一个元素的hashCode没变,其余元素的hashCode应该也不会变,虽然hashCode不是对象地址,但确是根据地址得出来得一个值,不同对象相同hashCode得概率估计小得可以买彩票,可以看出元素地址应该是没变的,但list对象一直在变,讲道理扩容是按1.5倍容量扩的,又不是添一个扩一下,为什么一直会变就很迷茫
lemon小白 2018-09-25
  • 打赏
  • 举报
回复
只要不新建数组,没有new,数组的地址值不会改变
zoujiawei6 2018-09-19
  • 打赏
  • 举报
回复
ArralyList默认大小是10,在源码中是这个字段:

/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;

每次大小达到临界值之后,都是增加一半的容量(通过位运算符取中间值:oldCapacity >> 1)

/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}

java的数组,每次扩容都会产生新数组。在源码中通过Arrays.copyOf(elementData, newCapacity);复制到新数组。
你看下这篇文章,有介绍数据结构的扩容原理的。
初尘19 2018-09-19
  • 打赏
  • 举报
回复
楼主展示的代码和扩容没啥关系吧,只是两个对象指向同一个堆内存地址而已
yu终ren未归 2018-09-18
  • 打赏
  • 举报
回复
这。。。。是同一个对象吧,这跟扩容是没有关系的
SunsetFeng 2018-09-15
  • 打赏
  • 举报
回复
首先吧,list和list1的实例对象是同一个,所以不管你怎么扩,这两个比肯定是一样的。我做了个测试

结果如下:

第一个元素的hashCode没变,其余元素的hashCode应该也不会变,虽然hashCode不是对象地址,但确是根据地址得出来得一个值,不同对象相同hashCode得概率估计小得可以买彩票,可以看出元素地址应该是没变的,但list对象一直在变,讲道理扩容是按1.5倍容量扩的,又不是添一个扩一下,为什么一直会变就很迷茫
verejava 2018-09-14
  • 打赏
  • 举报
回复
ArrayList 扩容原理 数据结构算法 之 线性表(一维数组) 添加,插入,修改,删除

http://www.verejava.com/?id=17285863679575
lx_six_satr 2018-09-13
  • 打赏
  • 举报
回复
666,明白了
木秀林 2018-09-13
  • 打赏
  • 举报
回复
一步一步调试
4-5-610
进入add方法 看序号都是不变的


然后判断


grow 调用静态方法


最后其实就是调用了System.arraycopy 的浅复制

这有详解浅复制的方法详解
nayi_224 2018-09-13
  • 打赏
  • 举报
回复
list,list1是一个地址,就是相等的,跟内部扩不扩容无关
ArrayList通过System.arraycopy扩容,产生新数组,数组地址变化。数组内容是浅拷贝。
HinanaiTenshi 2018-09-13
  • 打赏
  • 举报
回复 1
你比较的是集合类的地址,而不是ArrayList内部values数组的地址。
无论集合内部怎么扩容,你通过 ArrayList<String>list1= list; 申明了两个集合变量指向同一个集合的实例,那么list==list1比较的结果就一定是true。
Surrin1999 2018-09-13
  • 打赏
  • 举报
回复
补充一下咯 浅拷贝内存地址不变 深拷贝才会改变 这里的arraycopy是本地方法 是一个浅拷贝

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧