您的位置:首页 > 编程语言 > Java开发

用java实现动态的数组结构

2019-03-27 11:03 127 查看

java中的数组在被开始创建的时候就必须要初始化,这点与我们的list或者collection就会有很大的区别。而如果我们来进行封装的话,就可以实现一个(伪)动态数组。

在个人维护的数组中,内部可以封装其中私有变量的数组,不对外部提供,从而实现保密。对外提供的只有构造方法以及增删盖查的方法,而通过Capacity(数组初始容量)可以动态的来增加或者减少数组的长度,从而节省内存。

当然对于一些特殊需求的数组,这种自动增加数组的不能满足要求。其实我们可以实现一个resCapacity这种方法,来实现数组的动态减少,这就可以把这个当成一个缓存,或者说是容器,来存放一下不停更换的值。

对于重写equals方法,则是分别比较其中每个值是否相等来判断他们这个数组是否相等。 代码注释写的不是很详细,不过正常使用应该还是可以的。

对于传统的数组来说,是没有增删改查的功能的,我们只能通过他们的角标来进行操作或者是遍历,而增强的数组类,就可以用他来进行数组的一系列增删改查。

  • 构造函数

    Array ():创建默认为长度为16的一维数组
  • Array(int capacity):创建指定长度的一位数组
  • Array(T[]):将指定的数组转为Array对象
    • add (int index,T t):在指定角标添加元素
    • addFirst (T t):在开头添加元素
    • addLast(T t):在末尾添加元素
    • delete(int index):删除指定角标的元素
    • delFirst():删除数组中角标位0的元素
    • remove():删除数组中最后一个元素
    • set(int index,):删除数组中角标位0的元素
    • replace(T t,newT newt) :使用newT来替换数组中所有的t(感觉太耗内存,没有实现)
    • get(int index) : 获得指定角标位置的元素
    • find(T t):返回第一个存放指定元素的角标

    当然除了这些功能,还复写了equals方法,hashcode方法。缺少一个toString方法的实现。

    内部维护了一个自增数组,可以在数组容量满的时候,增加一倍,防止数组溢出,这样就不会出现数组容量不够的情况了。

    package com.it.data;
    
    public class Array<T> {
    //内部维护的私有数组
    private T[] data;
    //定义现有大小
    private int size;
    
    public int getSize(){
    return size;
    }
    
    public int getCapacity(){
    return data.length;
    }
    
    /**
    * 构造方法,传入容量即可。
    * @param capacity
    */
    public Array(int capacity){
    data =(T[]) new Object[capacity];
    size = 0;
    }
    
    /**
    * 空参构造方法,默认生成数组容量为16的数组
    */
    public Array(){
    this(16);
    }
    
    /**
    * 直接传入数组的构造方法
    * @param arr
    */
    public Array(T[] arr){
    data = arr;
    }
    
    /**
    * 查看数组是否为空
    * @return
    */
    public  boolean isEmpty(){
    return size==0;
    }
    
    /**
    * 在数组末尾添加一个元素
    * @param t
    * @throws Exception
    */
    public void addLast(T t){
    add(size,t);
    }
    
    /**
    * 在数组开始处添加一个元素
    * @param t
    * @throws Exception
    */
    public void addFirst(T t){
    add(0,t);
    }
    
    /**
    * @Description: 根据指定角标来添加一个元素
    * @Param: [index, t]
    * @return: void
    */
    public void add(int index,T t){
    if(index>size || index<0)
    throw new IllegalArgumentException("插入角标违法,请检查后再输入");
    
    if (this.getCapacity() == this.getSize()) {
    capactyInc(this.getCapacity()*2);
    }
    for (int i = index; i < size ; i++) {
    data[i+1]  = data[i];
    }
    data[index] = t;
    size++;
    }
    
    /**
    * @Description: 根据角标删除元素
    * @Param: [index]
    * @return: T
    */
    public T delete(int index){
    if(index>= size|| index<0) {
    throw new IllegalArgumentException("角标位置不存在元素");
    }
    T t = data[index];
    for (int i = index; i < size ; i++) {
    data[i] = data[i+1];
    }
    size--;
    return  t;
    }
    
    /**
    * @Description: 删除第一个元素
    * @Param: []
    * @return: T
    */
    public T delFirst() {
    return delete(0);
    }
    
    /**
    * 移除最后一个元素,remove方法默认为移除最后的一个元素
    * @return
    * @throws Exception
    */
    public T remove(){
    return  delete(size-1);
    }
    
    /**
    * 修改相应角标的元素
    * @param index
    * @param t
    * @return
    * @throws Exception
    */
    public T set(int index,T t){
    if(index>= size|| index<0) {
    throw new IllegalArgumentException("角标位置不存在元素");
    }
    T temp = data[index];
    data[index] = t;
    return temp;
    }
    
    /**
    * 根据角标来查询元素
    * @param index
    * @return
    * @throws Exception
    */
    public T get(int index){
    if(index>= size|| index<0) {
    throw new IllegalArgumentException("角标位置不存在元素");
    }
    return  data[index];
    }
    
    /**
    * 截取一个相应的集合
    * @param index
    * @param length
    * @return
    * @throws Exception
    */
    public T[] getArray(int index,int length){
    if(index>= size|| index<0) {
    throw new IllegalArgumentException("角标位置不存在元素");
    }
    if (length<0 || index+length>=size){
    throw  new IllegalArgumentException("需要的长度不存在,请重新确认长度");
    }
    T[] temp = (T[]) new Object[length];
    for (int i = 0; i < length; i++,index++) {
    temp[i] = data[index];
    }
    return  temp;
    }
    
    /**
    * @
    */
    public int getIndex(T t){
    //本想使用forEach循环,但包含结果也需要返回角标,所以使用for循环才能拿到他的角标
    for (int i = 0; i < size ; i++) {
    if(data[i].equals(t)){
    return  i;
    }
    }
    return -1;
    }
    
    /**
    * 判断是否包含某个元素
    * @param t
    * @return
    */
    public boolean contains(T t){
    for (int i = 0; i < size; i++) {
    if (data[i].equals(t)){
    return true;
    }
    }
    return  false;
    }
    
    /**
    * 在输入容量不够的情况下,自增容量
    * @param capacity
    */
    private void capactyInc(int capacity){
    T[] newData = (T[])new Object[capacity];
    for (int i = 0; i < size; i++) {
    newData[i] = data[i];
    }
    data = newData;
    }
    
    @Override
    public int hashCode() {
    return super.hashCode();
    }
    
    @Override
    public boolean equals(Object obj) {
    if(obj instanceof Array){
    Array arr = (Array) obj;
    for (int i = 0; i < arr.getSize(); i++) {
    try {
    if (data[i].equals(arr.get(i)))
    continue;
    return false;
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    return true;
    }
    return false;
    }
    }
  • 内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: