算法和数据结构

支持泛型类的数组实现

前面一篇文章里,我们实现了一个只支持整型数据的数组,这远远不够。我们接下来将它改造为支持泛型类的数组,即改造后的数组,可以存放任意类型的数据。

那么,我们就得将前面的自定义的Array类改造为支持泛型的。

1 改写Array为支持泛型的类

/**
 * @Author:asher
 * @Date:2021/3/29 09:26
 * @Description:PACKAGE_NAME
 * @Version:1.0
 */
public class Array<E > {
    private E[] data;
    private int size;
​
    public Array(int capacity) {
        data = (E[]) new Object[capacity];
        size = 0;
    }
​
    public Array() {
        this(10);
    }
​
    public int getSize() {
        return size;
    }
​
    public int getCapacity() {
        return data.length;
    }
​
    public boolean isEmpty() {
        return size == 0;
    }
​
    public void addLast(E e) {
  //有了在任意位置添加元素的方法,我们就可以改掉下面的这段代码
  //      if (size >= data.length) {
  //          throw new IllegalArgumentException("addLast failed.data is full");
  //      }
  //      data[size] = e;
  //      size++;
      add(e,size);
    }
​
    public void add(E e, int index) {
        if (index < 0 || index > size) {
            throw new IllegalArgumentException("add failed.index is invalid");
        }
        for (int i = size; i>index; i--) {
            data[i] = data[i - 1];
        }
        data[index] = e;
        size++;
    }
​
    public void addFirst(E e) {
        add(e, 0);
    }
​
    public E get(int index) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("get failed.index is invalid");
        }
        return data[index];
    }
​
    public boolean contains(E e) {
        for (int i = 0; i < size; i++) {
            if (data[i].equals(e)) {
                return true;
            }
        }
        return false;
    }
​
    public int find(E e) {
        for (int i = 0; i < size; i++) {
            if (data[i].equals(e)) {
                return i;
            }
        }
        return -1;
    }
​
    public E removeLast() {
        return remove(size);
    }
​
    public E remove(int index) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("remove failed.index is inavalid");
        }
        E temp = data[index];
  //上限应该是i+1<size。否则,有4个元素的数组,删除最后1个元素。此时,size=4,index=3,到这儿就会报错了!!!
        for (int i = index; i+1 <size ; i++) {
            data[i] = data[i + 1];
        }
        size--;
        return temp;
    }
​
    public E removeFirst() {
        return remove(0);
    }
​
​
    public void modify(E e, E newValue) {
        int temp = find(e);
        if (temp != -1) {
            data[temp] = newValue;
        }
    }
​
    public void removeElement(E e) {
        int temp = find(e);
        if (temp != -1) {
            remove(temp);
        }
    }
​
    public void removeAllElement(E e) {
        while (!isEmpty()) {
            if (find(e) != -1) {
                remove(find(e));
            }
        }
    }
​
    public void set(E e, int index) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("set failed.index is invalid");
        }
        data[index] = e;
    }
​
    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(String.format("Array size: %d ,length: %d\n", size, data.length));
        for (int i = 0; i < size; i++) {
            stringBuilder.append(data[i]);
            if (i != size - 1) {
                stringBuilder.append(" , ");
            }
        }
        stringBuilder.append("]");
        return stringBuilder.toString();
    }
}
​

2 自定义Student类,重写equals()方法

在同一个package下,自定义一个Student类,重写equals()、toString()方法。

/**
 * @Author:asher
 * @Date:2021/3/29 11:03
 * @Description:PACKAGE_NAME
 * @Version:1.0
 */
public class Student {
    private String name;
    private int age;
​
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
​
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
​
        Student student = (Student) o;
​
        if (age != student.age) return false;
        return name != null ? name.equals(student.name) : student.name == null;
    }
​
    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }
​
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
​

3 测试验证

在Array类里,添加main(),这样,我们就可以使用泛型数组来存放Student类,并执行测试验证。

 public static void main(String[] args) {
        Array<Student> studentArray = new Array<Student>();
        studentArray.addLast(new Student("Jim", 10));
        studentArray.addFirst(new Student("Kate", 8));
        studentArray.add(new Student("Jerry", 9), 1);
        System.out.println(studentArray);
        System.out.println(studentArray.contains(new Student("Jerry", 9)));
        studentArray.removeElement(new Student("Jim", 10));
​
        System.out.println(studentArray);
    }
//结果:
Array size: 3 ,length: 10
Student{name='Kate', age=8} , Student{name='Jerry', age=9} , Student{name='Jim', age=10}]
true
Array size: 2 ,length: 10
Student{name='Kate', age=8} , Student{name='Jerry', age=9}]

4 小结

至此,我们已经将前面自定义的数组这种数据结构的Array类,改写为支持泛型类的数组,而不再局限于某一特定数据类型了。但是,该数组依然有容量上的短板,不能自动动态扩容。