翻看自己的github觉得将之前写的集合写成一篇文章便于以后自己进行查阅,于此同时也提供给需要的coder,java集合可以说是java程序员必须要掌握的一项基本技术点了,我们每天打交道的就是集合了。
之前写过三篇关于集合源码的文章,需要了解集合源码的可以看下链接。
a.java之CopyOnWriteArraySet源码分析
b.java之CopyOnWriteArrayList源码分析
今天要分享的就是关于实现自己的java集合,为以后写基础性文章暂时做下铺垫吧,毕竟现在距离100片篇文章还有一段时间才能编写完。
package com.wpw.springbootmyarraylist;
public interface ISeqList<T> {
/**
* 判断集合是否为空
* @return true/false
*/
boolean isEmpty();
/**
* 获取集合长度
* @return 集合长度
*/
int length();
/**
* 获取元素
* @param index 索引
* @return 指定索引所对应的下标元素值
*/
T get(int index);
/**
* 设置某个元素的值
* @param index 指定索引
* @param data 待设置的元素值
* @return
*/
T set(int index,T data);
/**
* 根据index添加元素
* @param index 索引index
* @param data 待添加的元素
* @return
*/
boolean add(int index,T data);
/**
* 添加元素
* @param data 待添加的元素信息
* @return
*/
boolean add(T data);
/**
* 根据index移除元素
* @param index 索引index
* @return
*/
T remove(int index);
/**
* 根据data移除元素
* @param data 待移除的元素
* @return
*/
boolean remove(T data);
/**
* 根据data移除所有元素
* @param data 待移除的元素
* @return
*/
boolean removeAll(T data);
/**
* 清空集合
*/
void clear();
/**
* 是否包含data元素
* @param data 元素data
* @return
*/
boolean contains(T data);
/**
* 根据值查找下标
* @param data 元素data
* @return
*/
int indexOf(T data);
/**
* 根据data查询最后一个出现在顺序表中的下标
* @param data 元素data
* @return
*/
int lastIndexOf(T data);
/**
* toString()方法
* @return 集合内容
*/
@Override
String toString();
}
上面定义了集合常用的一些方法的接口,这也是我们用jdk集合最常用的一些方法了。
package com.wpw.springbootmyarraylist;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class MyList<T> implements ISeqList<T> {
/**
* 数组声明,用于存储元素
*/
private Object[] table;
/**
* 集合大小
*/
private int length;
public MyList(int capacity) {
/***
* 申请数组存储空间,元素初始化为null
*/
this.table = new Object[Math.abs(capacity)];
this.length = 0;
}
public MyList() {
this(64);
}
public MyList(T[] array) {
Objects.requireNonNull(array, "array can not be not empty");
if (Objects.isNull(array)) {
throw new NullPointerException("array can not be empty");
}
/***
* 创建对应容量的数组
*/
this.table = new Object[array.length];
for (int i = 0; i < array.length; i++) {
this.table[i] = array[i];
}
this.length = array.length;
}
@Override
public boolean isEmpty() {
return this.length == 0;
}
@Override
public int length() {
return this.length;
}
@Override
public T get(int index) {
if (index >= 0 && index < this.length) {
return (T) table[index];
}
return null;
}
@Override
public T set(int index, T data) {
if (index >= 0 && index < this.length && data != null) {
T old = (T) this.table[index];
this.table[index] = data;
return old;
}
return null;
}
@Override
public boolean add(int index, T data) {
if (Objects.isNull(data)) {
return false;
}
/***
* 插入下标的容错判断,插入在最前面
*/
if (index < 0) {
index = 0;
}
/**
* 插入下标的容错判断,插入在最后面
*/
if (index > this.length) {
index = this.length;
}
/***
* 判断内部数组是否已满
*/
if (this.length == table.length) {
Object[] temp = this.table;
/***
* 把原数组赋值给临时数组
*/
/***
* 对原数组进行成倍扩容,并把原数组的元素赋值到新数组
*/
this.table = new Object[temp.length << 1];
/***
* 先把原数组下标从0到index-1(即插入位置的前一个位置复制到新数组
*/
for (int i = 0; i < index; i++) {
this.table[i] = temp[i];
}
}
/***
* 从原数组的最后一个元素开始直到index,都往后一个位置
* 最后腾出来的位置就是新插入元素的位置了
*/
for (int j = this.length - 1; j >= index; j--) {
this.table[j + 1] = this.table[j];
}
/***
* 插入新值
*/
this.table[index] = data;
/***
* 长度加一
*/
this.length++;
/**
* 插入成功
*/
return true;
}
@Override
public boolean add(T data) {
return add(this.length, data);
}
@Override
public T remove(int index) {
if (this.length != 0 && index >= 0 && index < this.length) {
/**
* 记录删除元素的值并返回
*/
T old = (T) this.table[index];
/**
* 从被删除的元素开始,其后的元素都一次往前移动
*/
for (int j = index; j < this.length - 1; j++) {
this.table[j] = this.table[j + 1];
}
/***
* 设置数组元素对象为空
*/
//gc
this.table[this.length - 1] = null;
/***
* 顺序表长度减一
*/
this.length--;
return old;
}
return null;
}
@Override
public boolean remove(T data) {
if (this.length != 0 && data != null) {
return this.remove(this.indexOf(data)) != null;
}
return false;
}
@Override
public boolean removeAll(T data) {
boolean done = false;
if (this.length != 0 && data != null) {
int i = 0;
while (i < this.length) {
if (data.equals(this.table[i])) {
this.remove(i);
done = true;
} else {
i++;
}
}
}
return done;
}
@Override
public void clear() {
this.length = 0;
for (int i = 0; i < this.length; i++) {
//gc
this.table[i] = null;
}
}
@Override
public boolean contains(T data) {
return this.indexOf(data) >= 0;
}
@Override
public int indexOf(T data) {
if (data != null) {
for (int i = 0; i < this.length; i++) {
/**
* 相等则返回下标
*/
if (this.table[i].equals(data)) {
return i;
}
}
}
return -1;
}
@Override
public int lastIndexOf(T data) {
if (data != null) {
for (int i = this.length - 1; i >= 0; i--) {
if (data.equals(this.table[i])) {
return i;
}
}
}
return -1;
}
@Override
public String toString() {
List<String> list=new ArrayList<>();
StringBuilder stringBuilder = new StringBuilder("(");
if (this.length != 0) {
for (int i = 0; i < this.length-1; i++) {
stringBuilder.append(this.table[i].toString() + ",");
}
stringBuilder.append(this.table[this.length - 1].toString());
}
return stringBuilder.append(")").toString();
}
}
由于上面的注释说明很清晰了,可以进行测试了。
package com.wpw.springbootmyarraylist;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Test {
public static void main(String[] args) {
ISeqList myArrayList=new MyList();
myArrayList.add("1");
myArrayList.add("2");
myArrayList.add("3");
log.info("打印集合的元素信息:{}",myArrayList.toString());
log.info("判断集合是否为空:{}",myArrayList.isEmpty());
log.info("集合大小:{}",myArrayList.length());
log.info("集合包含元素1:{}",myArrayList.contains("1"));
log.info("集合元素1的索引位置:{}",myArrayList.indexOf("1"));
log.info("集合元素2的索引位置:{}",myArrayList.indexOf("2"));
log.info("获取集合索引下标为0的元素:{}",myArrayList.get(0));
log.info("删除集合中某个索引下标位置的元素");
myArrayList.remove(2);
log.info("此时集合元素大小:{}",myArrayList.length());
log.info("获取集合元素的索引下标:{}",myArrayList.lastIndexOf("2"));
log.info("打印集合的元素信息:{}",myArrayList.toString());
}
}
整个自定义集合的实现就结束了,喜欢文章的可以关注转发。