a[i] = baseAddress + i *dataTypeSize
即,数组的首地址+索引乘以存储数据的类型大小。
实际上并不是不行。而是如果数组索引从1开始的话,整体性能会变低。
因为寻址公式会变为a[i] = baseAddress + (i-1) *dataTypeSize,也就是说,多了一个减法操作。
数组转List ,使用JDK中java.util.Arrays工具类的asList方法
List转数组,使用List的toArray方法,参数为指定长度的数组实例化对象。如果无参,toArray方法返回 Object数组。
示例代码:
//数组转List
public static void testArray2List(){
String[] strs = {"aaa","bbb","ccc"};
List<String> list = Arrays.asList(strs);
for (String s : list) {
System.out.println(s);
}
}
//List转数组
public static void testList2Array(){
List<String> list = new ArrayList<String>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
String[] array = list.toArray(new String[list.size()]);
for (String s : array) {
System.out.println(s);
}
}
Arrays.asList转换list之后,如果修改了数组的内容,list会受影响,因为它的底层使用的Arrays类中的一个内部类ArrayList来构造的集合,在这个集合的构造器中,把我们传入的这个集合进行了包装而已,最终指向的都是同一个内存地址。
list用了toArray转数组后,如果修改了list内容,数组不会影响,当调用了toArray以后,在底层是它是进行了数组的拷贝,跟原来的元素就没啥关系了,所以即使list修改了以后,数组也不受影响
private static final int DEFAULT_CAPACITY = 10;// 初始容量,默认等于10
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
transient Object[] elementData;//ArrayList的数组(实际存储数据的数组)
private int size; //ArrayList的大小(实际包含的元素)
EMPTY_ELEMENTDATA :
无参构造 ArrayList 对象,且没有指定初始容量时,ArrayList 内部的 elementData 数组将会被初始化为 EMPTY_ELEMENTDATA。
通过这种方式,在初始时节省了内存空间,只有在首次添加元素时才会真正分配内部数组的容量。
代码如下:
import java.util.ArrayList;
public class EmptyElementDataExample {
public static void main(String[] args) {
// 使用无参构造方法创建 ArrayList 对象
ArrayList<String> list = new ArrayList<>();
// 添加元素
list.add("Apple");
list.add("Banana");
}
}
DEFAULTCAPACITY_EMPTY_ELEMENTDATA:
通过带有指定初始容量的构造方法创建 ArrayList 对象,并将初始容量设置为 0时,ArrayList
内部的 elementData 数组会被初始化为 DEFAULTCAPACITY_EMPTY_ELEMENTDATA。
多加一个DEFAULTCAPACITY_EMPTY_ELEMENTDATA是为了区分使用了初始容量为 0 的构造方法和无参构造方法的情况,避免了两种情况下 elementData 指向同一个空数组的问题。
代码如下:
import java.util.ArrayList;
public class DefaultCapacityEmptyElementDataExample {
public static void main(String[] args) {
// 使用带有指定初始容量的构造方法,并设置初始容量为 0
ArrayList<String> list = new ArrayList<>(0);
// 添加元素
list.add("Apple");
list.add("Banana");
}
}
elementData :
使用带有指定初始容量的构造方法时,elementData初始化为长度为指定初始容量的数组。
需要注意的是,elementData被transient关键字修饰,所以不会被默认的序列化机制持久化保存,即,不会转化为字节流,从而节省存储空间和序列化的时间开销。
代码如下:
import java.util.ArrayList;
public class ElementDataExample {
public static void main(String[] args) {
// 使用带有指定初始容量的构造方法,并设置初始容量为 5
ArrayList<String> list = new ArrayList<>(5);
// 添加元素
list.add("Apple");
list.add("Banana");
// 获取内部的 elementData 数组
Object[] elementData = list.toArray();
System.out.println("elementData数组长度:" + elementData.length);
}
}