赞
踩
此类继承了 AbstractList 类。 AbstractList 是 List 接口的子类。 AbstractList 是个抽象类, 适配器设计模式。
采用数组结构存储,增加删除慢,查找快
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable
ArrayList<Integer> data = new ArrayList<>();
源码如下,DEFAULTCAPACITY_EMPTY_ELEMENTDATA={},所以构造新数组时实际长度是为0的,但文档中初始容量为何为10,这与扩容算法有关
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
public boolean add(E e)
将指定的元素追加到此列表的末尾。public void add(int index, E element)
将指定元素插入此列表中的指定位置。 将当前位置的元素(如果有)和任何后续元素向右移动(将其添加到索引中)。public boolean addAll(int index, Collection<? extends E> c)
从指定位置开始,将指定集合中的所有元素插入此列表。 将当前位置的元素(如果有)和任何后续元素向右移动(增加其索引)。public boolean addAll(Collection<? extends E> c)
add(E e)源码分析:
public boolean add(E e) { modCount++; //add(插入元素,数组数据,有效数据的长度) add(e, elementData, size); //无论成功失败都会返回true!!! return true; } private void add(E e, Object[] elementData, int s) { //如果已有数据量达到数组最大长度,调用grow()扩容算法 if (s == elementData.length) elementData = grow(); //如果还有空间,直接加到末尾,有效数据长度加1 elementData[s] = e; size = s + 1; } private Object[] grow() { //至少要加1长度 return grow(size + 1); } private Object[] grow(int minCapacity) { //Arrays.copyof()把新长度数组拷贝到原数组 return elementData = Arrays.copyOf(elementData, newCapacity(minCapacity)); } private int newCapacity(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; //oldCapacity >> 1,二进制数右移一位,减小一半,即扩容1.5倍。注意:空数组和1元素的数组扩容无效 int newCapacity = oldCapacity + (oldCapacity >> 1); //扩容后空间仍然小于最小需要的空间,即不够存 if (newCapacity - minCapacity <= 0) { //如果原数组为空(即第一次存储),DEFAULTCAPACITY_EMPTY_ELEMENTDATA={},返回DEFAULT_CAPACITY=10和需求的空间的最大值 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) return Math.max(DEFAULT_CAPACITY, minCapacity); //最小长度超过int最大值,溢出变成负数,抛出内存溢出异常 if (minCapacity < 0) // overflow throw new OutOfMemoryError(); //如果既不是第一次添加数据也没有溢出,即添加一组数据时,如果扩容1.5倍无法满足,则返回最小需要的长度 return minCapacity; } //扩容后的新长度够用,且如果小于MAX_ARRAY_SIZE=int最大值-8,返回新长度,不然跳转到hugeCapacity(minCapacity) return (newCapacity - MAX_ARRAY_SIZE <= 0) ? newCapacity : hugeCapacity(minCapacity); } private static int hugeCapacity(int minCapacity) { //首先没有溢出 if (minCapacity < 0) // overflow throw new OutOfMemoryError(); //如果所需长度大于int最大值-8 return (minCapacity > MAX_ARRAY_SIZE) //返回int最大值 ? Integer.MAX_VALUE //不然返回int最大值-8 : MAX_ARRAY_SIZE; }
使用:
ArrayList<Integer> data = new ArrayList<>(); data.add(100); data.add(99); data.add(98); System.out.println(data.toString()); //[100, 99, 98] data.add(2,44); System.out.println(data.toString()); //[100, 99, 44, 98] ArrayList<Integer> data1 = new ArrayList<>(); data1.add(23); data1.add(43); data1.add(56); data.addAll(2, data1); System.out.println(data.toString()); //[100, 99, 23, 43, 56, 44, 98]
public E remove(int index)
删除此列表中指定位置的元素,并返回该元素。 将任何后续元素向左移位(从索引中减去一个元素)。public boolean remove(Object o)
从该列表中删除指定元素的第一个匹配项(如果存在)。 如果列表不包含该元素,则不会更改。System.out.println(names.remove(2));
//王五
System.out.println(names);
//[张三, 李四]
System.out.println(names.remove("赵六"));
//false
System.out.println(names.remove("李四"));
//true
System.out.println(names);
//[张三]
public boolean removeIf(Predicate<? super E> filter)
删除此集合中满足给定过滤条件的所有元素。ArrayList<String> names = new ArrayList<>(3); names.add("张三"); names.add("李四"); names.add("王五"); System.out.println("Names:"+names); //Names:[张三, 李四, 王五] names.removeIf(s -> s.contains("李")); System.out.println(names); //[张三, 王五] ArrayList<Integer> data = new ArrayList<>(); data.add(100); data.add(99); data.add(98); data.add(97); data.add(96); data.add(95); System.out.println(data); //[100, 99, 98, 97, 96, 95] //是偶数则删除 data.removeIf(integer -> (integer % 2) == 0); System.out.println("Odd numbers:" + data); //Odd numbers:[99, 97, 95]
public boolean removeAll(Collection<?> c)
从此列表中删除指定集合中包含的所有元素。//data = [100, 99, 98, 97, 96, 95]
//删除指定的数组中的元素
data.removeAll(data);
System.out.println(data);
//[]
protected void removeRange(int fromIndex, int toIndex)
从此列表中删除索引介于fromIndex (含)和toIndex (独占)之间的所有元素。 将任何后续元素向左移动(降低其索引)。 此调用通过(toIndex - fromIndex)元素缩短列表。 (如果toIndex==fromIndex ,此操作无效。)
ArrayList.subList(int fromIndex, int toIndex).clear()
更方便public class Demo3 extends ArrayList<Integer>{ public static void main(String[] args) { Demo3 data = new Demo3(); data.add(100); data.add(99); data.add(98); data.add(97); data.add(96); data.add(95); System.out.println(data); //[100, 99, 98, 97, 96, 95] data.removeRange(1, 3); System.out.println(data); //[100, 97, 96, 95] } }
public boolean retainAll(Collection<?> c)
仅保留此列表中包含在指定集合中的元素。 换句话说,从该列表中删除未包含在指定集合中的所有元素。//data = [100, 99, 98, 97, 96, 95]
//只保留索引为[2,4)的元素
data.retainAll(data.subList(2,4));
System.out.println(data);
//[98, 97]
public void clear()
//接上
data.clear();
System.out.println(data.toString());
//[]
public Object clone()
浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存, 所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
浅拷贝对应的就是深拷贝,深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。
data1 = (ArrayList<Integer>)data.clone();
System.out.println(data.clone());
//[100, 99, 23, 43, 56, 44, 98]
System.out.println(data1.toString());
//[100, 99, 23, 43, 56, 44, 98]
这里clone()的返回值是Object,所以需要ArrayList)进行类型转换为整数型的动态数组
参考来源 http://www.w3school.me/java/java-arraylist-clone.html
public boolean contains(Object o)
Integer i = 100;
System.out.println(data.contains(i));
//true
public void ensureCapacity(int minCapacity)
ArrayList<String> names = new ArrayList<>();
names.ensureCapacity(3);
names.add("张三");
names.add("李四");
names.add("王五");
System.out.println("Names:"+names);
//Names:[张三, 李四, 王五]
public void forEach(Consumer<? super E> action)
//将lamda表达式传递给forEach
names.forEach((e)->{
e = e + "是傻子";
System.out.println(e);
});
// 张三是傻子
// 李四是傻子
// 王五是傻子
public E get(int index)
System.out.println(names.get(2));
//王五
public int indexOf(Object o)
System.out.println(names.indexOf("王五"));
//2
System.out.println(names.indexOf("赵六"));
//-1
public int lastIndexOf(Object o)
public boolean isEmpty()
ArrayList<String> names1 = new ArrayList<>();
System.out.println(names1.isEmpty());
//true
public Iterator<E> iterator()
Iterator<String> iterator = names.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
public E set(int index, E element)
//data = [100, 99, 98, 97, 96, 95]
data.set(2,250);
System.out.println(data);
//[100, 99, 250, 97, 96, 95]
public int size()
System.out.println(data.size());
public List<E> subList(int fromIndex, int toIndex)
//data = [100, 99, 98, 97, 96, 95]
List<Integer> data1 = data.subList(2, data.size());
System.out.println(data1);
//[98, 97, 96, 95]
public Object[] toArray()
//data = [100, 99, 98, 97, 96, 95]
Object[] it = data.toArray();
System.out.println(Arrays.toString(it));
//[100, 99, 98, 97, 96, 95]
public <T> T[] toArray(T[] a)
Integer[] it = new Integer[(data.size())];
data.toArray(it);
System.out.println(Arrays.toString(it));
//[100, 99, 98, 97, 96, 95]
public void trimToSize()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。