既然线性结构可以由顺序存储结构和链式存储结构实现,那么将两者对线性结构共同的操作进行抽取,定义出线性结构的接口。
import java.util.Comparator;
//线性表的接口定义,继承了迭代接口Iterable
public interface List<E> extends Iterable<E> {
public void add(E element);
public void add(int index,E element);
public void remove(E element);
public E remove(int index);
public E get(int index);
public E set(int index, E element);
public int size();
public int indexOf(E element);
public boolean contains(E element);
public boolean isEmpty();
public void clear();
public void sort(Comparator<E> c);
public List<E> subList(int fromIndex,int toIndex);
}
ArrayList就是线性结构顺序存储方式的具体实现,称为线性表。
Iterable–>List–>ArrayList (继承关系)
import shujujiegou_interface.List;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
public class ArrayList<E> implements List<E> {
//线性表的默认容量
private static int DEFAULT_CAPACITY=10;
//线性表存储元素的容器data.length容器的最大容量
private E [] data;
//线性表中元素的有效个数,也表示新来元素默认在尾部添加的角标
//表满条件:size==data.length
//表空条件:size==null
private int size;
//默认创建一个容量为DEFAULT_CAPACITY的线性表
public ArrayList(){
this(DEFAULT_CAPACITY);
}
//创建一个有用户指定容量capacity的线性表
public ArrayList(int capacity){
if(capacity<0){
throw new IllegalArgumentException("inital capacity must>=0");
}
data=(E[])new Object[capacity];
size=0;
}
public ArrayList(E[] arr){
if (arr==null){
throw new IllegalArgumentException("inital arr can not be null ");
}
data=(E[])new Object[arr.length];
for (int i=0;i<arr.length;i++){
data[i]=arr[i];
}
size=arr.length;
}
//在线性表的表尾添加一个元素element O(1)
@Override
public void add(E element) {
add(size,element);
}
//在线性表中指定的index角标处添加一个元素element O(n)
@Override
public void add(int index, E element) {
if(index<0||index>size){
throw new IndexOutOfBoundsException("add index out of bounds");
}
//判断线性表是否已经满了
if(size==data.length){
reszie(data.length*2);
}
for(int i=size-1;i>=index;i--){
data[i+1]=data[i];
}
data[index]=element;
size++;
}
//既实现了数组扩容的操作,也实现了数组缩容的操作,重点就是在这个size身上 O(n)
private void reszie(int newLength) {
//第一步创建一个新数组
E[] newData=(E[])new Object[newLength];
//第二步将原数组data中的元素复制到新数组newData中
for(int i=0;i<size;i++){
newData[i]=data[i];
}
data=newData;
}
//删除线性表中指定元素的位置 O(n)
@Override
public void remove(E element) {
//获取该元素位置
int index=indexOf(element); //O(n)
//判断元素的存在性,如果存在则根据角标删除
if(index!=-1){
remove(index);//O(n)
}
}
//删除线性表中指定角标处index的元素,并返回 O(n)
@Override
public E remove(int index) {
if(index<0||index>=size){
throw new IndexOutOfBoundsException("remove index out of bounds");
}
E ret=data[index];
for(int i=index+1;i<size;i++){
data[i-1]=data[i];
}
size--;
//判断是否需要缩容 不要缩容的太厉害 至少保证一个最小值DEFAULT_CAPACITY
//如果有效元素的个数是容量的1/4、且当前数组的长度是大于10的,则缩容
if(size==data.length/4&&data.length>=DEFAULT_CAPACITY){
reszie(data.length/2);
}
return ret;
}
//获取线性表中指定角标index的元素 O(1)
@Override
public E get(int index) {
if(index<0||index>=size){
throw new IndexOutOfBoundsException("get index out of bounds");
}
return data[index];
}
//在线性表中修改指定角标处的元素为新的值element ,并返回原先的值 O(1)
@Override
public E set(int index, E element) {
if(index<0||index>=size){
throw new IndexOutOfBoundsException("set index out of bounds");
}
E ret=data[index];
data[index]=element;
return ret;
}
//获取线性表中有效元素的个数
@Override
public int size() {
return size;
}
//获取线性表中数组的容量
public int getCapacity(){
return data.length;
}
//在线性表中查找指定元素element的角标并返回 从左到右第一次出现的位置 如果元素不存在则返回-1 O(n)
@Override
public int indexOf(E element) {
for(int i=0;i<size;i++){
if(element.equals(data[i])){
return i;
}
}
return -1;
}
//在线性表中是否包含指定元素element O(n)
@Override
public boolean contains(E element) {
return indexOf(element)!=-1;
}
//判断线性表是否为空 O(1)
@Override
public boolean isEmpty() {
return size==0;
}
//清空线性表 O(1)
@Override
public void clear() {
data= (E[]) new Object[DEFAULT_CAPACITY];
size=0;
}
//根据比较器的规则 来对线性表中的元素进行排序【插入排序】 O(n^2)
@Override
public void sort(Comparator<E> c) {
if(c==null){
throw new IllegalArgumentException("comparator can not be null");
}
int j=0;
E e=null;
for(int i=1;i<size;i++){
e=data[i];
//j-1>=0 j>=1 j>0
for(j=i;j>0&&c.compare(data[j-1],e)>0;j--){
data[j]=data[j-1];
}
data[j]=e;
}
}
//获取从fromIndex到toIndex区间的子线性表 [fromIndex,toIndex]
@Override
public List<E> subList(int fromIndex, int toIndex) {
if (fromIndex<0){
throw new IndexOutOfBoundsException("fromIndex must>0");
}
if(toIndex>=size){
throw new IndexOutOfBoundsException("toIndex must>size");
}
if (fromIndex>toIndex){
throw new IndexOutOfBoundsException("fromIndex must<=toIndex");
}
ArrayList<E> subList=new ArrayList<>();
for (int i=fromIndex;i<=toIndex;i++){
subList.add(data[i]);//默认表尾添加
}
return subList;
}
//比较两个线性表是否相等 长度相等且内容相等
@Override
public boolean equals(Object obj) {
//1、是否比的是自己
if(this==obj){
return true;
}
//判断obj是否为空
if(obj==null){
return false;
}
//判断obj是否和ArrayList是同一个类型
if(getClass()!=obj.getClass()){
return false;
}
//具体比较内容
ArrayList other=(ArrayList)obj;
//比的长度
if(size!=other.size){
return false;
}
//比的数组内容
return Arrays.equals(data,other.data);
}
@Override
public String toString() {
//ArrayList:10/30[x,x,x,x,x]
StringBuilder sb=new StringBuilder(String.format("ArrayList:%d/%d[",size,data.length));
if (isEmpty()){
sb.append("]");//ArrayList:0/10[]
}else {//ArrayList:5/10[1,2,3,4,5]
for (int i=0;i<size;i++){
sb.append(data[i]);
if(i!=size-1){
sb.append(",");
}else{
sb.append("]");
}
}
}
return sb.toString();
}
//获取ArrarList的迭代器 foreach遍历线性表 it.haNext() it.next()
@Override
public Iterator<E> iterator() {
return new ArrayListIterator();
}
class ArrayListIterator implements Iterator<E>{
private int cur=0;
//判断之后是否有元素
@Override
public boolean hasNext() {
return cur<size;
}
//先把元素返回在后移
@Override
public E next() {
return data[cur++];
}
}
}
import shixianClass.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Random;
public class TestArrayList {
public static void main(String[] args) {
ArrayList<Integer> list=new ArrayList<Integer>();
System.out.println(list);
for (int i=1;i<=12;i++){
list.add(i);
}
System.out.println(list);
for (int num:list){
System.out.println(num);
}
System.out.println("====================");
Iterator<Integer> it=list.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
System.out.println(list);
System.out.println(list.remove(0));
System.out.println(list.remove(0));
System.out.println(list.remove(0));
System.out.println(list.remove(0));
System.out.println(list.remove(0));
System.out.println(list.remove(0));
System.out.println(list);
System.out.println(list.remove(0));
System.out.println(list);
Random rand=new Random();
for (int i=0 ;i<12;i++){
list.add(rand.nextInt(30));
}
System.out.println(list);
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
});
System.out.println(list);
ArrayList<Student> list2=new ArrayList<Student>();
list2.add(new Student("muzi",20));
list2.add(new Student("dgfr",21));
list2.add(new Student("kait",25));
list2.add(new Student("diva",10));
System.out.println(list2);
list2.sort(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.name.compareTo(o2.name);
}
});
System.out.println(list2);
list2.sort(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.age-o2.age;
}
});
System.out.println(list2);
}
}
class Student{
public String name;
public int age;
public Student(String name,int age){
this.name=name;
this.age=age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
执行结果
ArrayList:0/10[]
ArrayList:12/20[1,2,3,4,5,6,7,8,9,10,11,12]
1
2
3
4
5
6
7
8
9
10
11
12
====================
1
2
3
4
5
6
7
8
9
10
11
12
ArrayList:12/20[1,2,3,4,5,6,7,8,9,10,11,12]
1
2
3
4
5
6
ArrayList:6/20[7,8,9,10,11,12]
7
ArrayList:5/10[8,9,10,11,12]
ArrayList:12/20[3,11,5,26,5,19,19,23,6,27,0,3]
ArrayList:12/20[0,3,3,5,5,6,11,19,19,23,26,27]
ArrayList:4/10[Student{name='muzi', age=20},Student{name='dgfr', age=21},Student{name='kait', age=25},Student{name='diva', age=10}]
ArrayList:4/10[Student{name='dgfr', age=21},Student{name='diva', age=10},Student{name='kait', age=25},Student{name='muzi', age=20}]
ArrayList:4/10[Student{name='diva', age=10},Student{name='muzi', age=20},Student{name='dgfr', age=21},Student{name='kait', age=25}]