数组被定义以后不能再将length重新增大,但我们可以是有拷贝的方法进行扩容。
主要使用的函数——
System.arraycopy(arr3, insertedIndex, arr3, insertedIndex + 1, elementCounts - insertedIndex);
//把索引为insertedIndex位置开始的elementCounts个元素数据复制到arr3的insertedIndex + 1的位置上。
扩容实现Array类:
resourceObjs = Arrays.copyOf(resourceObjs, _zoomSize);// 可以按_zoomSize倍数进行扩容
下面是一个具体的实现方法,ArrayList的实现,扩容是当中的一个重要内容。
import java.util.Arrays;
public class VariableArray {
private static final int DEFALUT_LENGTH = 5;
private Object[] resourceObjs;
private int count = 0;
public VariableArray(){
resourceObjs = new Object[DEFALUT_LENGTH];
}
public void appendNewObject(Object obj){// 每次扩容1,并做新对象的添加
int oldLength = resourceObjs.length;
if (oldLength - 1 < count){
int _zoomSize = oldLength + 1;
ensureCapacity(_zoomSize);
}
resourceObjs[count] = obj;
count++;
System.out.println(Arrays.toString(resourceObjs));
}
private void ensureCapacity(int _zoomSize){
resourceObjs = Arrays.copyOf(resourceObjs, _zoomSize);// 可以按_zoomSize倍数进行扩容
}
public void testSystemArrayCopy(){
int[] arr0 = {1, 3, 5, 7, 9};
int[] arr2 = {2, 4, 6, 8, 10, 12, 14};
int insertedIndex = 4;
int insertedData = 999;
System.arraycopy(arr0, 0, arr2, 0, arr0.length);
System.out.println(Arrays.toString(arr2));// [1, 3, 5, 7, 9, 12, 14]
Integer[] arr1 = {2, 4, 6, 8, 10, 12, 14};
System.out.println(Arrays.toString(arr1));
int _zoomSize = arr1.length + 1;
Integer[] arr3 = Arrays.copyOf(arr1, _zoomSize);
int elementCounts = arr3.length - 1;
//把索引为insertedIndex位置开始的elementCounts个元素数据复制到arr3的insertedIndex + 1的位置上。
System.arraycopy(arr3, insertedIndex, arr3, insertedIndex + 1, elementCounts - insertedIndex);
arr3[insertedIndex] = insertedData;
System.out.println(Arrays.toString(arr3));
}
}
下面给出关于ArrayList解读的一些内容点
Iterator接口:
public interface Iterator<E> {
public boolean hasNext();
public E next();
public void remove();
}
RandomAccess接口说明:
JDK中推荐的是对List集合尽量要实现RandomAccess接口
如果集合类是RandomAccess的实现,则尽量用for(int i = 0; i < size; i++) 来遍历而不要用Iterator迭代器来遍历,
在效率上要差一些。反过来,如果List是Sequence List,则最好用迭代器来进行迭代。
在对List的遍历算法中,要尽量来判断是属于RandomAccess(如ArrayList) 还是Sequence List (如LinkedList),因为适合RandomAccess List的遍历算法,用在Sequence List上就差别很大,常用的作法就是:
if (list instance of RandomAccess) {
for(int m = 0; m < list.size(); m++){}
}else{
Iterator iter = list.iterator();
while(iter.hasNext()){}
}
ArrayList类中使用transient定义成员属性,因为ArrayList继承了Serializable接口,做了持久化,transient的目的就是不希望所定义的常量不被进行持久化
transient Object[] array;
————————————————————————————————————————————————————————————
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {...}
public abstract class AbstractCollection<E> implements Collection<E> {...}
public interface Collection<E> extends Iterable<E> {
public boolean add(E object);
public boolean addAll(Collection<? extends E> collection);
public void clear();
public boolean contains(Object object);
public boolean containsAll(Collection<?> collection);
public boolean equals(Object object);
public int hashCode();
public boolean isEmpty();
public Iterator<E> iterator();
public boolean remove(Object object);
public boolean removeAll(Collection<?> collection);
public boolean retainAll(Collection<?> collection);
public int size();
public Object[] toArray();
public <T> T[] toArray(T[] array);
}
public interface Iterable<T> {
/**
* Returns an {@link Iterator} for the elements in this object.
*
* @return An {@code Iterator} instance.
*/
Iterator<T> iterator();
}
public interface List<E> extends Collection<E> {...}
当中定义有public ListIterator<E> listIterator();故而可以有前一个和后一个元素的判断:
void add(E object);
ListIterator接口方法:
/**
* Returns whether there are more elements to iterate.
*
* @return {@code true} if there are more elements, {@code false} otherwise.
* @see #next
*/
public boolean hasNext();
/**
* Returns whether there are previous elements to iterate.
*
* @return {@code true} if there are previous elements, {@code false}
* otherwise.
* @see #previous
*/
public boolean hasPrevious();
/**
* Returns the next object in the iteration.
*
* @return the next object.
* @throws NoSuchElementException
* if there are no more elements.
* @see #hasNext
*/
public E next();
/**
* Returns the index of the next object in the iteration.
*
* @return the index of the next object, or the size of the list if the
* iterator is at the end.
* @throws NoSuchElementException
* if there are no more elements.
* @see #next
*/
public int nextIndex();
/**
* Returns the previous object in the iteration.
*
* @return the previous object.
* @throws NoSuchElementException
* if there are no previous elements.
* @see #hasPrevious
*/
public E previous();
/**
* Returns the index of the previous object in the iteration.
*
* @return the index of the previous object, or -1 if the iterator is at the
* beginning.
* @throws NoSuchElementException
* if there are no previous elements.
* @see #previous
*/
public int previousIndex();
/**
* Removes the last object returned by {@code next} or {@code previous} from
* the list.
*
* @throws UnsupportedOperationException
* if removing is not supported by the list being iterated.
* @throws IllegalStateException
* if {@code next} or {@code previous} have not been called, or
* {@code remove} or {@code add} have already been called after
* the last call to {@code next} or {@code previous}.
*/
public void remove();
/**
* Replaces the last object returned by {@code next} or {@code previous}
* with the specified object.
*
* @param object
* the object to set.
* @throws UnsupportedOperationException
* if setting is not supported by the list being iterated
* @throws ClassCastException
* if the class of the object is inappropriate for the list.
* @throws IllegalArgumentException
* if the object cannot be added to the list.
* @throws IllegalStateException
* if {@code next} or {@code previous} have not been called, or
* {@code remove} or {@code add} have already been called after
* the last call to {@code next} or {@code previous}.
*/
void set(E object);
ArrayList接口构造函数
public ArrayList(int capacity) {
if (capacity < 0) {
throw new IllegalArgumentException("capacity < 0: " + capacity);
}
array = (capacity == 0 ? EmptyArray.OBJECT : new Object[capacity]);
}// 构造含有容量大小的对象
public ArrayList() {
array = EmptyArray.OBJECT;
}// 构造具有初始化大小的对象
_________________________________________________________________________________________________________
@Override
public boolean add(E object) {
Object[] a = array;
int s = size;
if (s == a.length) {// 扩容逻辑
Object[] newArray = new Object[s +
(s < (MIN_CAPACITY_INCREMENT / 2) ?
MIN_CAPACITY_INCREMENT : s >> 1)];
System.arraycopy(a, 0, newArray, 0, s);
array = a = newArray;
}
a[s] = object;// 将数组中的最后一个位置进行赋值,完成添加
size = s + 1;
modCount++;
return true;
}
_________________________________________________________________________________________________________
插入数据到具体某个位置,有扩容和移位的逻辑处理
@Override public void add(int index, E object) {
Object[] a = array;
int s = size;
if (index > s || index < 0) {
throwIndexOutOfBoundsException(index, s);
} if (s < a.length) {
System.arraycopy(a, index, a, index + 1, s - index);
} else {
// assert s == a.length;
Object[] newArray = new Object[newCapacity(s)];
System.arraycopy(a, 0, newArray, 0, index);
System.arraycopy(a, index, newArray, index + 1, s - index);
array = a = newArray;
}
a[index] = object;
size = s + 1;
modCount++;
}