手写容器java、新手一学就会

手写容器

1、不使用类型参数的容器类

1.1、设计 Container 类

创建 Container 类并声明相关的 实例变量 :

public class Container {    private Object[] elements ;       private int counter ;       private float loadFactor ;  }

其中:

  • elements 变量用来引用 存放数据的 Object 数组

    • 每次调用 add( Object ) 方法时,都将新添加的 对象 添加到 elements 数组中

  • counter 变量充当一个计数器

    • 既用来统计容器中存放的元素个数

    • 又用来确定下次添加元素时(再次调用add(Object)方法时)元素的存放位置

  • loadFactor 用来表示扩容的时机,也被称作加载因子

    • 就是 当 容器中有效元素的个数( counter 变量的值 ) 超过 elements 数组的长度的指定比例时,就需要 为 容器 扩容

    • 所谓 为容器扩容,就是 换一个 更大的数组来存放元素

1.2、构造方法

首先添加一个带有两个参数的构造方法:

public Container( int initialCapacity , float loadFactor ) {        if( initialCapacity <= 0 ) {            initialCapacity = 10 ;        }        this.elements = new Object[ initialCapacity ];                if( loadFactor <= 0 || loadFactor >= 1 ) {            loadFactor = 0.75F ;        }         this.loadFactor = loadFactor ;    }

其中

  • 第一个参数 initialCapacity 用来指定容器的初始容量

  • 第二个参数 loadFactor 用来指定 加载因子

随后就可以添加 带有一个参数的构造方法 和 无参构造方法了:

public Container( int initialCapacity ) {        this( initialCapacity , 0.75F );    }?    public Container() {        this( 10 , 0.75F );    }

1.3、搞定扩容方法

private void ensureCapacity() {        // 当达到某个条件时,就对容器进行扩容        if( counter > elements.length * loadFactor ) {            // 将 原来的数组 的地址 暂存到 temp 变量中            final Object[] temp = this.elements ;            // 创建新数组 ( 创建一个新的、更大的数组 ) 并将新数组地址赋值到 elements 变量            this.elements = new Object[ temp.length * 3 / 2 + 1 ];            // 将原数组中的[ 0 , counter ) 之间的元素拷贝到新数组中            System.arraycopy( temp ,  0 ,  elements ,  0 , counter );            // 后续就使用新数组 (放弃老数组) 了 ( 因为 elements 变量中存储了 新数组的地址 )        }    }

1.4、搞定添加元素

public boolean add( Object element ) {                this.ensureCapacity();                // 将 element 添加到 elements 数组的 counter 处        elements[ counter ] = element ;        // 对 counter 执行 自增操作 ( 增加 1 )        counter++ ; // 自增之后的值既表示元素个数又表示下次添加元素时的存放位置                return true ;    }

1.5、搞定 toString

@Override    public String toString() {        StringBuilder builder = new StringBuilder();        builder.append( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );        builder.append( "\n" );        builder.append( "容器的当前容量是: " + elements.length );        builder.append( "\n" );        builder.append( "容器的元素个数是: " + counter );        builder.append( "\n" );                if( counter > 0 ) {            builder.append( "容器中的元素有: " );            for( int i = 0 ; i < counter ; i++ ) {                builder.append( elements[ i ] );                builder.append( i < counter -1 ? " , " : "\n" );            }        } else {            builder.append( "容器中尚未添加有效元素" );            builder.append( "\n" );        }                builder.append( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );        String s = builder.toString();        return  s ;    }

1.6、获取元素个数

public int size() {        return  this.counter ;    }

1.7、判断容器是否为空

public boolean isEmpty() {        return counter == 0  ;    }

1.8、清空容器

public void clear() {        this.counter = 0 ;        Arrays.fill( elements ,  null );    }
import java.util.Arrays;

public class Container {
    
    //elements用来引用 存放数据的 Object 数组
    //每次调用 add( Object ) 方法时,都将新添加的 对象 添加到 elements 数组中
    private Object[] elements ; 
    
    //counter充当一个计数器
    //既用来统计容器中存放的元素个数
    //又用来确定下次添加元素时(再次调用add(Object)方法时)元素的存放位置
    private int counter ; 
  
    //loadFactor用来表示扩容的时机,也被称作加载因子
    //一般情况是0.75
    private float loadFactor ;
    
    //带参构造
    //第一个参数 `initialCapacity` 用来指定容器的初始容量
    //第二个参数 `loadFactor` 用来指定 加载因子
    public Container(int initialCapacity , float d) {
        if( initialCapacity <= 0 ) {
            initialCapacity = 10 ;
        }
        this.elements = new Object[ initialCapacity ];//创建一个新的数组
        
        if( d <= 0 || d >= 1 ) {
            d = 0.75F ;
        } 
        this.loadFactor = d ;
    }
    
    //扩容方法
    private void ensureCapacity() {
        // 当达到某个条件时,就对容器进行扩容
        if( counter > elements.length * loadFactor ) {
            
            // 将 原来的数组 的地址 暂存到 temp 变量中
            final Object[] temp = this.elements ;
            
            // 创建新数组 ( 创建一个新的、更大的数组 ) 并将新数组地址赋值到 elements 变量
            this.elements = new Object[ temp.length * 3 / 2 + 1 ];
            
            // 将原数组中的[ 0 , counter ) 之间的元素拷贝到新数组中
            System.arraycopy( temp ,  0 ,  elements ,  0 , counter );
            
            // 后续就使用新数组 (放弃老数组) 了 ( 因为 elements 变量中存储了 新数组的地址 )
        }
    }
    //增加集合元素的方法
    public boolean add(Object element) {
        this.ensureCapacity();
        elements[counter++]=elements;
        return true;
    }
    
    //判断是否有元素
    public boolean isEmpty() {
        return counter==0;
    }
    
    @Override
    public String toString() {
        StringBuilder builder=new StringBuilder();
        builder.append( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
        builder.append( "\n" );
        builder.append( "容器的当前容量是: " + elements.length );
        builder.append( "\n" );
        builder.append( "容器的元素个数是: " + counter );
        builder.append( "\n" );
        builder.append( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
        if(counter>0)
        {
            builder.append("容器的元素有:");
            builder.append( "\n" );
            for(int i=0;i<counter;i++)
            {
                builder.append(elements[i]+"   ");
            }
        }else
            builder.append("该容器暂时无元素");
        builder.append( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
        
        return builder.toString();
    }
    
    //获取元素个数
    public int size() {
        return  this.counter ;
    }
    
    //清空元素
    public void clear() {
        this.counter = 0 ;
        Arrays.fill( elements ,  null );
    }
}

相关推荐