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;
}
}