文章目录
一、数组基础
数组就是把数据码成一排进行存放。
Java中,数组的每个元素类型必须相同,可以都为int类型,string类型,甚至是自定义类型。
数组的命名要语义化,例如,如果数组用来存放学生的成绩,那么命名为scores就比较合适。
索引(index)是数组中的一个重要概念,它是我们给数组中的每个元素分配的编号,从0开始,依次递增。如果数组中存放了n个元素,第一个元素的索引是0,最后一个元素的索引是n-1。
通过索引,我们可以对数组中的元素进行快速访问,例如,我们访问索引为2的元素也就是数组中的第3个元素,就可以通过scores[2]这种形式。
1、在Java中声明一个简单的数组:
/*
创建线性表List的顺序存储结构实现类ArrayList
*/
public class ArrayList<E> implements List<E>{
//创建E类型的一维数组
private E[] data;
//维护元素个数
private int size;
//默认最大容量为10
private static int DEFAULT_CAPACITY=10;
//创建一个默认大小的顺序表
public ArrayList(){
this(DEFAULT_CAPACITY);
}
//创建一个容量由用户指定的顺序表
public ArrayList(int capacity){
if(capacity<=0){
throw new IllegalArgumentException("容量>0:"+capacity);
}
data=(E[])(new Object[capacity]);
size=0;
}
//用户传入一个数组 将该数组封装成一个顺序表
public ArrayList(E[] data){
if(data==null){
throw new IllegalArgumentException("数组不能为空");
}
this.data=(E[])(new Object[data.length]);
for (int i = 0; i <data.length ; i++) {
this.data[i]=data[i];
}
size=data.length;
}
2、实现自定义数组类Array所包含的基本方法
首先,写一个接口包含ArrayList的基本方法(如下)
public interface List<E> extends Iterable<E>{
//获取线性表中元素的有效个数
int getSize();
//判断线性表是否为空表
boolean isEmpty();
//在线性表指定的index角标处插入元素e
void add(int index,E e);
//在线性表的表头处插入元素e
void addFirst(E e);
//在线性表的表尾处插入元素e
void addLast(E e);
//获取线性表中指定角标index处的元素
E get(int index);
//获取表头元素
E getFirst();
//获取表尾元素
E getLast();
//修改线性表中指定角标index处的元素为新元素e
void set(int index,E e);
//判断线性表中是否包含元素e
boolean contains(E e);
//查找元素e的角标(从左到又默认第一个出现的元素角标)
int find(E e);
//删除并返回线性表中指定角标index处的元素
E remove(int index);
//删除并返回表头元素
E removeFirst();
//删除并返回表尾元素
E removeLast();
//删除指定元素e
void removeElement(E e);
//清空线性表
void clear();
3、实现接口的功能
获取有效个数和判空
@Override
public int getSize() {
return size;
}
@Override
public boolean isEmpty() {
return size==0;
}
在指定位置插入元素
//指定位置添加元素
@Override
public void add(int index, E e) {
if(index<0||index>size){
throw new IllegalArgumentException("角标越界");
}
if(size==data.length){
//扩容
resize(data.length*2);
}
for (int i = size; i >index ; i--) {
data[i]=data[i-1];
}
data[index]=e;
size++;
}
//扩容、缩容
private void resize(int newLength) {
E[] newData=(E[])(new Object[newLength]);
for (int i = 0; i < size; i++) {
newData[i]=data[i];
}
data=newData;
}
//头插入
@Override
public void addFirst(E e) {
add(0,e);
}
//尾插入
@Override
public void addLast(E e) {
add(size,e);
}
获取线性表中指定角标index处的元素
//获取线性表中指定角标index处的元素
@Override
public E get(int index) {
if(isEmpty()){
throw new IllegalArgumentException("线性表为空");
}
if(index<0||index>=size){
throw new IllegalArgumentException("角标越界");
}
return data[index];
}
//获取表头元素
@Override
public E getFirst() {
return get(0);
}
//获取表尾元素
@Override
public E getLast() {
return get(size-1);
}
修改指定角标处元素
@Override
public void set(int index, E e) {
if(isEmpty()){
throw new IllegalArgumentException("线性表为空");
}
if(index<0||index>=size){
throw new IllegalArgumentException("角标越界");
}
data[index]=e;
}
判断线性表中是否包含元素e
@Override
public boolean contains(E e) {
return find(e)!=-1;
}
查找元素
@Override
public int find(E e) {
if(isEmpty()){
throw new IllegalArgumentException("线性表为空");
}
for (int i = 0; i < size; i++) {
if(data[i].equals(e)){
return i;
}
}
return -1;
}
删除元素
//删除并返回线性表中指定角标index处的元素
@Override
public E remove(int index) {
if(isEmpty()){
throw new IllegalArgumentException("线性表为空");
}
if(index<0||index>=size){
throw new IllegalArgumentException("角标越界");
}
E ret=data[index];
for(int i=index+1;i<size;i++){
data[i-1]=data[i];
}
size--;
if(size<=data.length/4&&data.length/2>=10){
resize(data.length/2);
}
return ret;
}
//删除并返回表头元素
@Override
public E removeFirst() {
return remove(0);
}
//删除并返回表尾元素
@Override
public E removeLast() {
return remove(size-1);
}
//删除指定元素e
@Override
public void removeElement(E e) {
int index=find(e);
if(index!=-1){
remove(index);
}else{
throw new IllegalArgumentException("元素不存在");
}
}
清空顺序表和获取容量
//清空
@Override
public void clear() {
size=0;
data=(E[])(new Object[DEFAULT_CAPACITY]);
}
//获取容量
public int getCapacity(){
return data.length;
}
实现自定义打印数组格式
@Override
public String toString() {
StringBuilder sb=new StringBuilder();
sb.append(String.format("ArrayList: %d/%d \n",size,data.length));
sb.append('[');
if(isEmpty()){
sb.append(']');
}else{
for (int i = 0; i < size; i++) {
sb.append(data[i]);
if(i == size - 1){
sb.append(']');
}else{
sb.append(',');
}
}
}
return sb.toString();
}
返回当前数据结构的一个迭代器对象
//迭代器用于在没有角标支持的环境下遍历元素
@Override
public Iterator<E> iterator() {
return new ArrayListIterator();
}
private class ArrayListIterator implements Iterator{
private int index=-1;
@Override
public boolean hasNext() {
return index<size-1;
}
@Override
public E next() {
index++;
return data[index];
}
}