在Java中创建一个数组,Java对这个数组只提供了下面的一些方法;数组一旦声明,其存储的数据类型和数组的容量大小就一定;且不提供对数组的增删改查操作,需要自己实现;
下面是对静态数组的改进,实现存储任意类型、提供增删改查操作、可扩容:
package com.itheima.array;
/**
* @author GuoBaoYu
* 使用泛型,可以存放任意类型的数据;
*/
public class Array<E> {
private E[] data; //内部是静态数组
private int size;
public Array(int capacity) {
data =(E[]) new Object[capacity];
size = 0;
}
/**
* 默认构造一个容量为10的数组
*/
public Array() {
this(10);
}
public int getCapacity(){
return data.length;
}
public boolean isEmpty(){
return size==0 ;
}
public int getSize(){
return size;
}
public void addLast(E element){
add(size, element);
}
public void addFirst(E element){
add(0,element);
}
//动态数组进行自动扩容和减少容量
private void resize(int newCapacity){
E[] newData = (E[]) new Object[newCapacity];
for(int i = 0; i < size;i++){
newData[i] = data[i];
}
data = newData;
}
/**
* @param index
* @param element
* 向指定的位置插入元素
*/
public void add(int index,E element){
if(size == getCapacity()){
// throw new IllegalArgumentException("AddLast is failed. Array is full.");
// 之前如果数组空间满了,抛出异常;现在进行扩容
int newCapacity = getCapacity()*2;
resize(newCapacity);
}
if(index < 0 || index > size){
throw new IllegalArgumentException("Argument index is illegal.index is required index >=0 and index <= size. ");
}
for(int i = size-1; i>=index; i--){
data[i+1] = data[i];
}
data[index] = element;
size++;
}
@Override
public String toString(){
StringBuilder builder = new StringBuilder();
builder.append(String.format("size = %d,capacity = %d\t", size,getCapacity()));
builder.append("[");
for(int i = 0; i < size; i++){
builder.append(data[i]);
if(i<size-1){
builder.append(",");
}
}
builder.append("]");
return builder.toString();
}
public E get(int index){
if(index >=size || index <0){
throw new IllegalArgumentException("Argument index is illegal.");
}
return data[index];
}
public void set(int index, E element){
if(index >=size || index <0){
throw new IllegalArgumentException("Argument index is illegal.");
}
data[index] = element;
}
public boolean contains(E element){
for(int i =0; i <size;i++){
if(data[i].equals(element)){
return true;
}
}
return false;
}
public int find(E element){
for(int i=0 ; i < size; i++){
if(data[i].equals(element)){
return i;
}
}
return -1;
}
//删除index位置的元素,并返回删除的元素的值
public E remove(int index){
if(index < 0 || index >= size){
throw new IllegalArgumentException("Remove failed.index is an illegal argument.");
}
E element = data[index];
for(int i = index+1; i < size; i++){
data[i-1] = data[i];
}
size--;
//改善算法性能;进行懒缩容;
if(size <= getCapacity() /4 && data.length/2 !=0){
resize(getCapacity()/2);
}
return element;
}
//删除第一个元素
public E removeFirst(){
return remove(0);
}
//删除最后一个元素
public E removeLast(){
return remove(size-1);
}
/**
* @param element
* @return
* 删除指定的数据
*/
public boolean removeElement(E element){
int find = find(element);
if(find!=-1){
remove(find);
return true;
}
return false;
}
}
思路:
1.使用泛型,使得可以存储任意类型的数据
2.在进行添加操作时,如果数组存储数据的个数size已经等于数组创建时声明的容量capacity,则进行自动扩容:创建一个2倍容量的新临时数组newData,将原来的数组data中的数据复制到newData中,再更改data的指向;相当于对data进行了扩容;
类似的,当数组中的数据很少时,可以自动缩容: