所谓数组,是有序的元素序列。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式。这些有序排列的同类数据元素的集合称为数组。
数组是用于储存多个相同类型数据的集合。数组本身是静态的,在创建的时候,就必须要指定它的大小。
代码演示:
package com.ldc.datastructures.array;
public class Main {
public static void main(String[] args) {
//第一种声明的方式
int[] arr = new int[20];
for (int i = 0; i < arr.length; i++) {
arr[i] = i;
}
//第二种声明的方式
int[] scores = new int[]{100, 99, 66};
for (int i = 0; i < scores.length; i++) {
System.out.println(scores[i]);
}
scores[0] = 98;
for (int score : scores) {
System.out.println(score);
}
}
}
package com.ldc.datastructures.array;
/**
* @author lengdongcheng
* @date 2020-05-03 12:02
*/
public class Array {
/**
* 数组存放的元素
*/
private int[] data;
/**
* 在数组中元素的个数,也即跟下标索引相对应
*/
private int size;
/**
* 默认的构造函数,调用public Array(int capacity){...}来进行构造
* 默认数组的容量capacity=10
*/
public Array() {
this(10);
}
/**
* 构造函数,用传入参数capacity作为数组的容量来构造数组
* @param capacity 容量
*/
public Array(int capacity) {
data = new int[capacity];
size = 0;
}
/**
* 获取数组中元素的个数
* @return
*/
public int getSize(){
return size;
}
/**
* 获取数组的容量
* @return
*/
public int getCapacity(){
return data.length;
}
/**
* 返回数组是否为空
* @return
*/
public boolean isEmpty(){
return size == 0;
}
}
图解
我们只需要在数组的末尾添加元素,然后维护一下size即可
代码演示
/**
* 在数组的末尾添加元素
* @param e
*/
public void addLast(int e) {
//如果数组的个数已经等于数组的容量,那么需要抛出异常
if (size == data.length) {
throw new IllegalArgumentException("AddLast failed.Array is full.");
}
data[size] = e;
size++;
}
图解
将索引为1以及索引为1后面的元素整体向后移,并且是将元素从最后面的元素开始移,不然会将数据覆盖:
将元素66插入到索引为1的位置
维护size,将size向后移一位
代码演示
这个时候,也可以把在末尾添加元素的方法进行修改,直接调用add方法
/**
* 在数组的末尾添加元素
*
* @param e
*/
public void addLast(int e) {
//如果数组的个数已经等于数组的容量,那么需要抛出异常
add(size, e);
}
/**
* 在数组中第index的位置添加元素
* @param e
*/
public void add(int index, int e) {
//如果数组的个数已经等于数组的容量,那么需要抛出异常
if (size == data.length) {
throw new IllegalArgumentException("Add failed.Array is full.");
}
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed.index < 0 || index > size.");
}
//从要插入的位置到最后一个元素,都要向后挪一个位置,并且是从最后一个元素开始挪
for (int i = size - 1; i >= index; i--) {
//将后一个位置赋上前一个位置的元素
data[i + 1] = data[i];
}
//实际上index这个位置还是有元素的,只不过是将e元素把之前的元素给覆盖了
data[index] = e;
size++;
}
}
/**
* 在数组的头部添加元素
*
* @param e
*/
public void addFirst(int e) {
add(0, e);
}
/**
* 在数组中第index的位置添加元素
* @param e
*/
public void add(int index, int e) {
//如果数组的个数已经等于数组的容量,那么需要抛出异常
if (size == data.length) {
throw new IllegalArgumentException("Add failed.Array is full.");
}
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed.index < 0 || index > size.");
}
//从要插入的位置到最后一个元素,都要向后挪一个位置,并且是从最后一个元素开始挪
for (int i = size - 1; i >= index; i--) {
//将后一个位置赋上前一个位置的元素
data[i + 1] = data[i];
}
//实际上index这个位置还是有元素的,只不过是将e元素把之前的元素给覆盖了
data[index] = e;
size++;
}
}
向数组中查询元素和修改元素以及重写了toString方法
/**
* 获取index索引位置的元素
* @param index
* @return
*/
public int get(int index) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("get failed.index is illegal.");
}
return data[index];
}
/**
* 修改index索引位置的元素
* @param index
* @return
*/
public void set(int index,int e) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("set failed.index is illegal.");
}
data[index] = e;
}
/**
* 重写toString方法
* @return
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(String.format("Array: size = %d , capacity = %d \n", size, data.length));
sb.append('[');
for (int i = 0; i < size; i++) {
sb.append(data[i]);
if (i != size - 1) {
sb.append(", ");
}
}
sb.append(']');
return sb.toString();
}
}
/**
* 查找数组中是否包含元素e
* @param e
* @return
*/
public boolean contains(int e) {
for (int i = 0; i < size; i++) {
if (data[i] == e) {
return true;
}
}
return false;
}
/**
* 查找数组中元素e所在的位置,如果不存在元素e,则返回-1
* @param e
* @return
*/
public int find(int e) {
for (int i = 0; i < size; i++) {
if (data[i] == e) {
return i;
}
}
return -1;
}
图解
将指定位置后面的元素都向前挪一位
这样size就指向了删除前最后一个元素,这样并不会有什么问题,
代码演示
/**
* 从数组中删除index位置的元素,并返回被删除的元素
* @param index
* @return
*/
public int remove(int index) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("remove failed.index is illegal.");
}
int ret = data[index];
//index后面的元素都向前挪一位
for (int i = index+1; i < size; i++) {
data[i - 1] = data[i];
}
//维护一下size
size--;
return ret;
}
/**
* 从数组中删除第一个元素,并返回
* @return
*/
public int removeFirst() {
return remove(0);
}
/**
* 从数组中删除最后一个元素,并返回
* @return
*/
public int removeLast() {
return remove(size - 1);
}
/**
* 从数组中删除元素e
* @param e
*/
public void removeElement(int e) {
int index = find(e);
if (index != -1) {
remove(index);
}
}
package com.ldc.datastructures.array;
/**
* @author lengdongcheng
* @date 2020-05-03 12:02
*/
public class Array {
/**
* 数组存放的元素
*/
private int[] data;
/**
* 在数组中元素的个数,也即跟下标索引相对应
*/
private int size;
/**
* 默认的构造函数,调用public Array(int capacity){...}来进行构造
* 默认数组的容量capacity=10
*/
public Array() {
this(10);
}
/**
* 构造函数,用传入参数capacity作为数组的容量来构造数组
*
* @param capacity 容量
*/
public Array(int capacity) {
data = new int[capacity];
size = 0;
}
/**
* 查找数组中是否包含元素e
* @param e
* @return
*/
public boolean contains(int e) {
for (int i = 0; i < size; i++) {
if (data[i] == e) {
return true;
}
}
return false;
}
/**
* 从数组中删除index位置的元素,并返回被删除的元素
* @param index
* @return
*/
public int remove(int index) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("remove failed.index is illegal.");
}
int ret = data[index];
//index后面的元素都向前挪一位
for (int i = index+1; i < size; i++) {
data[i - 1] = data[i];
}
//维护一下size
size--;
return ret;
}
/**
* 从数组中删除元素e
* @param e
*/
public void removeElement(int e) {
int index = find(e);
if (index != -1) {
remove(index);
}
}
/**
* 从数组中删除第一个元素,并返回
* @return
*/
public int removeFirst() {
return remove(0);
}
/**
* 从数组中删除最后一个元素,并返回
* @return
*/
public int removeLast() {
return remove(size - 1);
}
/**
* 查找数组中元素e所在的位置,如果不存在元素e,则返回-1
* @param e
* @return
*/
public int find(int e) {
for (int i = 0; i < size; i++) {
if (data[i] == e) {
return i;
}
}
return -1;
}
/**
* 获取数组中元素的个数
*
* @return
*/
public int getSize() {
return size;
}
/**
* 获取数组的容量
*
* @return
*/
public int getCapacity() {
return data.length;
}
/**
* 返回数组是否为空
*
* @return
*/
public boolean isEmpty() {
return size == 0;
}
/**
* 在数组的末尾添加元素
*
* @param e
*/
public void addLast(int e) {
add(size, e);
}
/**
* 在数组的头部添加元素
*
* @param e
*/
public void addFirst(int e) {
add(0, e);
}
/**
* 在数组中第index的位置添加元素
*
* @param e
*/
public void add(int index, int e) {
//如果数组的个数已经等于数组的容量,那么需要抛出异常
if (size == data.length) {
throw new IllegalArgumentException("Add failed.Array is full.");
}
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed.index < 0 || index > size.");
}
//从要插入的位置到最后一个元素,都要向后挪一个位置,并且是从最后一个元素开始挪
for (int i = size - 1; i >= index; i--) {
//将后一个位置赋上前一个位置的元素
data[i + 1] = data[i];
}
//实际上index这个位置还是有元素的,只不过是将e元素把之前的元素给覆盖了
data[index] = e;
size++;
}
/**
* 获取index索引位置的元素
* @param index
* @return
*/
public int get(int index) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("get failed.index is illegal.");
}
return data[index];
}
/**
* 修改index索引位置的元素
* @param index
* @return
*/
public void set(int index,int e) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("set failed.index is illegal.");
}
data[index] = e;
}
/**
* 重写toString方法
* @return
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(String.format("Array: size = %d , capacity = %d \n", size, data.length));
sb.append('[');
for (int i = 0; i < size; i++) {
sb.append(data[i]);
if (i != size - 1) {
sb.append(", ");
}
}
sb.append(']');
return sb.toString();
}
}
使用泛型让我们的数据结构可以放置"任意"的数据类型(泛型是不支持基本的数据类型,只能是类对象)
package com.ldc.datastructures.array;
/**
* @author lengdongcheng
* @date 2020-05-03 12:02
*/
public class Array {
/**
* 数组存放的元素
*/
private E[] data;
/**
* 在数组中元素的个数,也即跟下标索引相对应
*/
private int size;
/**
* 默认的构造函数,调用public Array(int capacity){...}来进行构造
* 默认数组的容量capacity=10
*/
public Array() {
this(10);
}
/**
* 构造函数,用传入参数capacity作为数组的容量来构造数组
*
* @param capacity 容量
*/
public Array(int capacity) {
data = (E[]) new Object[capacity];
size = 0;
}
/**
* 查找数组中是否包含元素e
* @param e
* @return
*/
public boolean contains(E e) {
for (int i = 0; i < size; i++) {
if (data[i].equals(e)) {
return true;
}
}
return false;
}
/**
* 从数组中删除index位置的元素,并返回被删除的元素
* @param index
* @return
*/
public E remove(int index) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("remove failed.index is illegal.");
}
E ret = data[index];
//index后面的元素都向前挪一位
for (int i = index+1; i < size; i++) {
data[i - 1] = data[i];
}
//维护一下size
size--;
//loitering Object
data[size] = null;
return ret;
}
/**
* 从数组中删除元素e
* @param e
*/
public void removeElement(E e) {
int index = find(e);
if (index != -1) {
remove(index);
}
}
/**
* 从数组中删除第一个元素,并返回
* @return
*/
public E removeFirst() {
return remove(0);
}
/**
* 从数组中删除最后一个元素,并返回
* @return
*/
public E removeLast() {
return remove(size - 1);
}
/**
* 查找数组中元素e所在的位置,如果不存在元素e,则返回-1
* @param e
* @return
*/
public int find(E e) {
for (int i = 0; i < size; i++) {
if (data[i].equals(e)) {
return i;
}
}
return -1;
}
/**
* 获取数组中元素的个数
*
* @return
*/
public int getSize() {
return size;
}
/**
* 获取数组的容量
*
* @return
*/
public int getCapacity() {
return data.length;
}
/**
* 返回数组是否为空
*
* @return
*/
public boolean isEmpty() {
return size == 0;
}
/**
* 在数组的末尾添加元素
*
* @param e
*/
public void addLast(E e) {
add(size, e);
}
/**
* 在数组的头部添加元素
*
* @param e
*/
public void addFirst(E e) {
add(0, e);
}
/**
* 在数组中第index的位置添加元素
*
* @param e
*/
public void add(int index, E e) {
//如果数组的个数已经等于数组的容量,那么需要抛出异常
if (size == data.length) {
throw new IllegalArgumentException("Add failed.Array is full.");
}
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed.index < 0 || index > size.");
}
//从要插入的位置到最后一个元素,都要向后挪一个位置,并且是从最后一个元素开始挪
for (int i = size - 1; i >= index; i--) {
//将后一个位置赋上前一个位置的元素
data[i + 1] = data[i];
}
//实际上index这个位置还是有元素的,只不过是将e元素把之前的元素给覆盖了
data[index] = e;
size++;
}
/**
* 获取index索引位置的元素
* @param index
* @return
*/
public E get(int index) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("get failed.index is illegal.");
}
return data[index];
}
/**
* 修改index索引位置的元素
* @param index
* @return
*/
public void set(int index,E e) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("set failed.index is illegal.");
}
data[index] = e;
}
/**
* 重写toString方法
* @return
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(String.format("Array: size = %d , capacity = %d \n", size, data.length));
sb.append('[');
for (int i = 0; i < size; i++) {
sb.append(data[i]);
if (i != size - 1) {
sb.append(", ");
}
}
sb.append(']');
return sb.toString();
}
}
这样,就相当于进行了扩容
/**
* 在数组中第index的位置添加元素
*
* @param e
*/
public void add(int index, E e) {
//如果数组的个数已经等于数组的容量,那么需要抛出异常
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed.index < 0 || index > size.");
}
//扩容
if (size == data.length) {
resize(2 * data.length);
}
//从要插入的位置到最后一个元素,都要向后挪一个位置,并且是从最后一个元素开始挪
for (int i = size - 1; i >= index; i--) {
//将后一个位置赋上前一个位置的元素
data[i + 1] = data[i];
}
//实际上index这个位置还是有元素的,只不过是将e元素把之前的元素给覆盖了
data[index] = e;
size++;
}
/**
* 进行扩容
* @param newCapacity
*/
private void resize(int newCapacity) {
E[] newData = (E[]) new Object[newCapacity];
for (int i = 0; i < size; i++) {
newData[i] = data[i];
}
data = newData;
}
/**
* 从数组中删除index位置的元素,并返回被删除的元素
* @param index
* @return
*/
public E remove(int index) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("remove failed.index is illegal.");
}
E ret = data[index];
//index后面的元素都向前挪一位
for (int i = index+1; i < size; i++) {
data[i - 1] = data[i];
}
//维护一下size
size--;
//loitering Object
data[size] = null;
//缩容
if (size == data.length / 2) {
resize(data.length / 2);
}
return ret;
}
package com.ldc.datastructures.array;
/**
* @author lengdongcheng
* @date 2020-05-03 12:02
*/
public class Array {
/**
* 数组存放的元素
*/
private E[] data;
/**
* 在数组中元素的个数,也即跟下标索引相对应
*/
private int size;
/**
* 默认的构造函数,调用public Array(int capacity){...}来进行构造
* 默认数组的容量capacity=10
*/
public Array() {
this(10);
}
/**
* 构造函数,用传入参数capacity作为数组的容量来构造数组
*
* @param capacity 容量
*/
public Array(int capacity) {
data = (E[]) new Object[capacity];
size = 0;
}
/**
* 查找数组中是否包含元素e
* @param e
* @return
*/
public boolean contains(E e) {
for (int i = 0; i < size; i++) {
if (data[i].equals(e)) {
return true;
}
}
return false;
}
/**
* 从数组中删除index位置的元素,并返回被删除的元素
* @param index
* @return
*/
public E remove(int index) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("remove failed.index is illegal.");
}
E ret = data[index];
//index后面的元素都向前挪一位
for (int i = index+1; i < size; i++) {
data[i - 1] = data[i];
}
//维护一下size
size--;
//loitering Object
data[size] = null;
//缩容
if (size == data.length / 2) {
resize(data.length / 2);
}
return ret;
}
/**
* 从数组中删除元素e
* @param e
*/
public void removeElement(E e) {
int index = find(e);
if (index != -1) {
remove(index);
}
}
/**
* 从数组中删除第一个元素,并返回
* @return
*/
public E removeFirst() {
return remove(0);
}
/**
* 从数组中删除最后一个元素,并返回
* @return
*/
public E removeLast() {
return remove(size - 1);
}
/**
* 查找数组中元素e所在的位置,如果不存在元素e,则返回-1
* @param e
* @return
*/
public int find(E e) {
for (int i = 0; i < size; i++) {
if (data[i].equals(e)) {
return i;
}
}
return -1;
}
/**
* 获取数组中元素的个数
*
* @return
*/
public int getSize() {
return size;
}
/**
* 获取数组的容量
*
* @return
*/
public int getCapacity() {
return data.length;
}
/**
* 返回数组是否为空
*
* @return
*/
public boolean isEmpty() {
return size == 0;
}
/**
* 在数组的末尾添加元素
*
* @param e
*/
public void addLast(E e) {
add(size, e);
}
/**
* 在数组的头部添加元素
*
* @param e
*/
public void addFirst(E e) {
add(0, e);
}
/**
* 在数组中第index的位置添加元素
*
* @param e
*/
public void add(int index, E e) {
//如果数组的个数已经等于数组的容量,那么需要抛出异常
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed.index < 0 || index > size.");
}
//扩容
if (size == data.length) {
resize(2 * data.length);
}
//从要插入的位置到最后一个元素,都要向后挪一个位置,并且是从最后一个元素开始挪
for (int i = size - 1; i >= index; i--) {
//将后一个位置赋上前一个位置的元素
data[i + 1] = data[i];
}
//实际上index这个位置还是有元素的,只不过是将e元素把之前的元素给覆盖了
data[index] = e;
size++;
}
/**
* 进行扩容
* @param newCapacity
*/
private void resize(int newCapacity) {
E[] newData = (E[]) new Object[newCapacity];
for (int i = 0; i < size; i++) {
newData[i] = data[i];
}
data = newData;
}
/**
* 获取index索引位置的元素
* @param index
* @return
*/
public E get(int index) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("get failed.index is illegal.");
}
return data[index];
}
/**
* 修改index索引位置的元素
* @param index
* @return
*/
public void set(int index,E e) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("set failed.index is illegal.");
}
data[index] = e;
}
/**
* 重写toString方法
* @return
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(String.format("Array: size = %d , capacity = %d \n", size, data.length));
sb.append('[');
for (int i = 0; i < size; i++) {
sb.append(data[i]);
if (i != size - 1) {
sb.append(", ");
}
}
sb.append(']');
return sb.toString();
}
}
package com.ldc.datastructures.array;
public class Main {
public static void main(String[] args) {
Array arr = new Array<>(10);
for (int i = 0; i < 15; i++) {
arr.addLast(i);
}
System.out.println(arr);
arr.add(1,100);
System.out.println(arr);
arr.remove(2);
System.out.println(arr);
}
}
运行结果如下:可以看出已经实现了扩容
“Array: size = 15 , capacity = 20 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] Array: size = 16 , capacity = 20 [0, 100, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] Array: size = 15 , capacity = 20 [0, 100, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]