快速随机访问和可删除的数组

    我们知道ArrayList是基于Array的,所以它拥有Array的优点,适用于按索引取值的场合,但是它不适合插入数据和删除数据,因为每插入或删 除一次就会产生一次大量数组内容Copy的操作。而LinkedList正好与ArrayList相反,它比较适合与插入删除操作,不适合于索引取值,因 为它不可以像数组一样根据索引值直接就可以定位元素的地址,而需要从头至尾一个一个的来数位置。
    那么有没有一种数据结构既拥有数据索引取值快速的特性,又拥有快速删除元素的优点呢?当然有,下面我介绍的就是其中的一种方式,我称之为无序数组(概念可 能与数组的概念有些冲突,因为数组本身是有序的),这种数组包装方法是基于数组的,所以拥有数组快速索引取值的特点;并且在删除元素的时候并不移动 (Copy)数组内部元素,所以删除元素的时候速度很快。缺点就是损失了数组的有序性,同时因为该数组是无序的,所以没有必要提供数据中间插入操作,只可 以向数据的末尾添加数据。
    这个数据结构的设计是基于效率的,所以它只适合于对数组的按索引取值和随机删除元素的效率要求都比较高,同时对数组的有序性(这里的有序性不是指数组元素的排序顺序,而是指数组元素的索引顺序)没有任何要求的场合。
     这个数据结构的一个使用示例场合就是随机取数据。可以用该数组存储数据源,然后随机生成一个索引,并将该索引对应的元素remove掉。而且还能保证数据不被重复读取。
    下面提供的示例代码抽取了这个数组的最基本功能,很清晰,没有什么需要解释的地方。导致数组无序和快速删除的根源就在于 remove(int index) 方法中,大家自己看吧。
public   class  NoOrderArray
{
  
private Object[] values = null;

  
private int size = 0;

  
/**
   * 数组 NoOrderArray 的构造函数。 <br>
   * 
   * 
@param capacity int - 数组的初始容量。
   
*/

  
public NoOrderArray(int capacity)
  
{
    
if (capacity < 0)
      
throw new IllegalArgumentException("Illegal Capacity: " + capacity);

    values 
= new Object[capacity];
  }


  
/**
   * 数组 NoOrderArray 的构造函数,初始容量为 8.<br>
   
*/

  
public NoOrderArray()
  
{
    
this(10);
  }


  
/**
   * 设定数组的容量大小,使其至少满足 minCapacity 所指的大小。 <br>
   * 
   * 
@param minCapacity int - 新的容量值。
   
*/

  
public void ensureCapacity(int minCapacity)
  
{
    
int oldCapacity = values.length;

    
if (minCapacity > oldCapacity)
    
{
      Object[] oldValues 
= values;

      
int newCapacity = (oldCapacity * 3/ 2 + 1;

      
if (newCapacity < minCapacity)
        newCapacity 
= minCapacity;

      values 
= new Object[newCapacity];

      System.arraycopy(oldValues, 
0, values, 0, size);
    }

  }


  
/**
   * 向数组 NoOrderArray 中添加元素内容。 <br>
   * 
   * 
@param value - 添加的内容。
   
*/

  
public void add(Object value)
  
{
    ensureCapacity(size 
+ 1);

    values[size] 
= value;

    size 
++;
  }


  
/**
   * 清除数组 NoOrderArray 中的全部元素。 <br>
   
*/

  
public void clear()
  
{
    
// 释放内存
    for (int i = 0; i < size; i ++)
      values[i] 
= null;

    size 
= 0;
  }


  
/**
   * 返回数组 NoOrderArray 中指定索引的元素。 <br>
   * 
   * 
@param index int - 索引值。
   * 
   * 
@return Object - 对应的元素。
   
*/

  
public Object get(int index)
  
{
    
if (index >= size || index < 0)
      
throw new IndexOutOfBoundsException("Index out of bounds.");

    
return values[index];
  }


  
/**
   * 判断当前 NoOrderArray 数组是否为空。 <br>
   * 
   * 
@return boolean - 如果为空返回 <code>true</code>.
   
*/

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


  
/**
   * 移除 NoOrderArray 数组中指定位置的元素。 <br>
   * 
   * 
@param index int - 索引值。
   * 
   * 
@return Object - 被移除的元素。
   
*/

  
public Object remove(int index)
  
{
    
if (index >= size || index < 0)
      
throw new IndexOutOfBoundsException("Index out of bounds.");

    Object value 
= values[index];

    
if (index != size - 1)
    
{
      
// 将数组最后一个值补充到被移除的位置。
      values[index] = values[size - 1];
      values[size 
- 1= null// 防止该位置永久持有对象的引用
    }


    size 
--;

    
return value;
  }


  
/**
   * 判断指定的数据是否在 NoOrderArray 数组中。 <br>
   * 
   * 
@param value Object - 需要判断的数据。
   * 
   * 
@return boolean - 如果包含返回 <code>true</code>.
   
*/

  
public boolean contains(Object value)
  
{
    
if (value == null)
    
{
      
for (int i = 0; i < size; i ++)
        
if (values[i] == null)
          
return true;
    }

    
else
    
{
      
for (int i = 0; i < size; i ++)
        
if (value.equals(values[i]))
          
return true;
    }


    
return false;
  }


  
/**
   * 返回当前数组的大小。 <br>
   * 
   * 
@return int - 当前数组的大小。
   
*/

  
public int size()
  
{
    
return size;
  }


  
/*
   * (non-Javadoc)
   * 
   * @see java.lang.Object#toString()
   
*/

  
public String toString()
  
{
    StringBuffer buffer 
= new StringBuffer();

    buffer.append(
'[');

    
for (int index = 0; index < size; index ++)
    
{
      Object value 
= values[index];

      
if (index > 0)
        buffer.append(
',');

      buffer.append(value);
    }


    buffer.append(
']');

    
return buffer.toString();
  }


  
/**
   * 
@param args
   
*/

  
public static void main(String[] args)
  
{
    
// TODO 自动生成方法存根
  }

}

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值