1.特点
- 相同数据类型
- 序列(顺序性)
- 有限
2.逻辑结构
3.存储结构
- 链式表 (节点=值+地址)
- 优点 插入和删除方便,空间利用率高
- 缺点 存储密度小( <1 ),查找和修改需要遍历整个链表
- 顺序表(数组)
- 优点 存储密度大( =1 ),易于查找和修改
- 缺点 插入和删除不方便,存储空间利用率低
4.实现
- 顺序结构实现
1. 自定义线性表接口(List)和存储结构无关
/**
* 自定义线性表接口
* 和存储结构无关
* @author Administrator
*/
public interface List {
/**
* 定义size方法,应返回size大小,最大值为Integer.MAX_VALUE
* @return
*/
int size();
/**
* List要求,定义get方法,获取指定index的值
* @param index
* @return
*/
Object get(int index);
/**
* 定义isEmpty方法,用于返回是否为空
* 如果不包含元素,则返回true
* @return
*/
boolean isEmpty();
/**
* 定义contains方法,判断一个e是否属于此集合
* 如不是集合,则返回true
* @param e
* @return
*/
boolean contains(Object e);
/**
*
* 获取查询元素的index,若备查元素为null,则寻找空元素,返回index
* 若备查元素不为null,则使用equal判断该元素是否存在,并返回index
* 不存在则返回-1
* 被contains调用
* @param e
* @return
*/
int indexOf(Object e);
/**
* 定义add方法,添加一个元素e,并返回添加成功标志
* @param e
* @return
*/
boolean add(Object e);
/**
* 在指定位置插入指定元素在这个列表(可选操作)。变化的元素目前位置(如果有的话)和任何后续元素向右(添加一个索引)。
* @param index 指数要插入指定的元素
* @param e 元素被插入
*/
void add(int index, Object e);
/**
* 将元素e插入到元素object之前
* @param object 目标元素
* @param e 元素被插入
* @return
*/
boolean addBefore(Object object,Object e);
/**
* 将元素e插入到元素object之后
* @param object 目标元素
* @param e 元素被插入
* @return
*/
boolean addAfter(Object object,Object e);
/**
* 这个列表中删除指定位置的元素(可选操作)。任何后续元素转移到左(减去一个来自他们的指标)。返回的元素从列表中删除。
* @param index 删除元素的索引
* @return
*/
Object remove(int index);
/**
* 定义remove方法,移除一个元素e,并返回移除元素成功标志
* @param e
* @return
*/
boolean remove(Object e);
/**
* 替换序号为index的元素为e 返回原元素
* @param index 序号
* @param e 替换元素
* @return 原元素
*/
Object replace(int index,Object e);
}
2.顺序结构的实现类(ArrayList)
import java.util.Arrays;
/**
* 顺序结构的实现
* @author Administrator
*/
public class ArrayList implements List {
/**
* 底层是一个数组
*/
private Object[] elementData;
/**
* 不是数组分配的空间,而是元素的个数
*/
private int size;
/**
* @param initialCapacity 数组初始长度
*/
public ArrayList(int initialCapacity){
//给数组分配指定的空间
elementData = new Object[initialCapacity];
//指定顺序表元素个数
// size = 0; int初始值是0
}
public ArrayList(){
//没有指定长度,默认长度是5
this(10);
//没有指定长度,长度是0
// elementData = new Object[]{};
}
/**
* 定义size方法,应返回size大小,最大值为Integer.MAX_VALUE
*
* @return
*/
@Override
public int size() {
return size;
}
/**
* List要求,定义get方法,获取指定index的值
*
* @param index
* @return
*/
@Override
public Object get(int index) {
if (index < 0 || index >= size){
throw new MyArrayIndexOutOfBoundsException("数组索引越界异常:"+index);
}
return elementData[index];
}
/**
* 定义isEmpty方法,用于返回是否为空
* 如果不包含元素,则返回true
*
* @return
*/
@Override
public boolean isEmpty() {
return size==0;
}
/**
* 定义contains方法,判断一个e是否属于此集合
* 如不是集合,则返回true
*
* @param e
* @return
*/
@Override
public boolean contains(Object e) {
return indexOf(e)>=0;
}
/**
* 获取查询元素的index,若备查元素为null,则寻找空元素,返回index
* 若备查元素不为null,则使用equal判断该元素是否存在,并返回index
* 不存在则返回-1
* 被contains调用
*
* @param e
* @return
*/
@Override
public int indexOf(Object e) {
if (e == null) {
for (int i = 0; i < size; i++) {
if (elementData[i] == null)
{
return i;
}
}
} else {
for (int i = 0; i < size; i++) {
if (e.equals(elementData[i])) {
return i;
}
}
}
return -1;
}
/**
* 定义add方法,添加一个元素e,并返回添加成功标志
*
* @param e
* @return
*/
@Override
public boolean add(Object e) {
this.add(size,e);
// //数组扩容
// if (size == elementData.length){
// grow();
// }
//
// //添加
// elementData[size] = e;
// //元素个数+1
// size++;
elementData[size++] = e;
System.out.println("length="+elementData.length);
return true;
}
/**
* 在指定位置插入指定元素在这个列表(可选操作)。变化的元素目前位置(如果有的话)和任何后续元素向右(添加一个索引)。
*
* @param index 指数要插入指定的元素
* @param e 元素被插入
*/
@Override
public void add(int index, Object e) {
//判断index的位置要正确
if (index<0 || index>size){
throw new MyArrayIndexOutOfBoundsException("数组索引越界异常:"+index);
}
//数组扩容
if (size == elementData.length){
grow();
}
//后移index及其后面元素,从最后一个元素开始
for (int j = size; j>index ;j--){
elementData[j] = elementData[j-1];
}
//添加
elementData[index] = e;
//元素个数+1
size++;
}
/**
* 数组扩容
*/
private void grow(){
// //新创建一个新的数组,长度是旧的数组2倍
// Object[] newArr = new Object[elementData.length*2];
// //将旧数组的数据拷贝到新的数组中
// for (int i = 0;i<size;i++){
// newArr[i] = elementData[i];
// }
// //让elementData指向新数组
// elementData = newArr;
elementData = Arrays.copyOf(elementData,elementData.length*2);
}
/**
* 将元素e插入到元素object之前
*
* @param object 目标元素
* @param e 元素被插入
* @return
*/
@Override
public boolean addBefore(Object object, Object e) {
//目标元素的索引序号 -1说明无此元素
int i = indexOf(object);
if (i==-1){
return false;
}
//添加操作
add(i,e);
return true;
}
/**
* 将元素e插入到元素object之后
*
* @param object 目标元素
* @param e 元素被插入
* @return
*/
@Override
public boolean addAfter(Object object, Object e) {
//目标元素的索引序号 -1说明无此元素
int i = indexOf(object);
if (i==-1){
return false;
}
//添加操作
add(i+1,e);
return true;
}
/**
* 这个列表中删除指定位置的元素(可选操作)。任何后续元素转移到左(减去一个来自他们的指标)。返回的元素从列表中删除。
*
* @param index 删除元素的索引
* @return
*/
@Override
public Object remove(int index) {
//判断index的位置要正确
if (index<0 || index>size-1){
throw new MyArrayIndexOutOfBoundsException("数组索引越界异常:"+index);
}
//要删除的元素
Object elementDatum = elementData[index];
//要移动的长度
fastRemove(index);
return elementDatum;
}
/**
* 定义remove方法,移除一个元素e,并返回移除元素成功标志
*
* @param e
* @return
*/
@Override
public boolean remove(Object e) {
//当前元素的索引序号 -1说明无此元素
int i = indexOf(e);
if (i==-1){
return false;
}
fastRemove(i);
return true;
// if (e == null) {
// for (int index = 0; index < size; index++){
// if (elementData[index] == null) {
// fastRemove(index);
// return true;
// }
// }
//
// } else {
// for (int index = 0; index < size; index++){
// if (e.equals(elementData[index])) {
// fastRemove(index);
// return true;
// }
// }
//
// }
// return false;
}
/**
* 要移动的长度
* @param index
*/
private void fastRemove(int index) {
for (; index<size;index++){
elementData[index] = elementData[index+1];
}
elementData[size]=null;
size--;
}
/**
* 替换序号为index的元素为e 返回原元素
*
* @param index 序号
* @param e 替换元素
* @return 原元素
*/
@Override
public Object replace(int index, Object e) {
if (index < 0 || index >= size){
throw new MyArrayIndexOutOfBoundsException("数组索引越界异常:"+index);
}
Object object = elementData[index];
elementData[index] = e;
return object;
}
//[0,1,2,3,4,5]
@Override
public String toString() {
if (size == 0){
return "[]";
}
StringBuilder builder = new StringBuilder("[");
for (int i = 0;i<size;i++){
if (i!=size-1){
builder.append(elementData[i]+",");
}else {
builder.append(elementData[i]);
}
}
builder.append("]");
return builder.toString() ;
}
}
3.自定义异常(MyArrayIndexOutOfBoundsException)
/**
* 自定义异常类
* @author Administrator
*/
public class MyArrayIndexOutOfBoundsException extends RuntimeException{
public MyArrayIndexOutOfBoundsException(){
super();
}
public MyArrayIndexOutOfBoundsException(String message){
super(message);
}
}
4.测试类(ArrayListTest)
/**
* 测试
* @author Administrator
*/
public class ArrayListTest {
private List list;
@Before
public void setUp() throws Exception {
list = new ArrayList();
list.add(0);
list.add(null);
list.add(2);
list.add(3);
}
@Test
public void add() {
list.add(1,151515151);
int size = list.size();
System.out.println("元素个数="+size);
System.out.println(list);
}
@Test
public void get(){
Object o = list.get(1);
System.out.println(o);
System.out.println(list);
}
@Test
public void indexOf(){
add();
int i = list.indexOf(3);
System.out.println(i);
}
@Test
public void remove(){
Object remove = list.remove(4);
System.out.println(remove);
System.out.println(list.toString());
}
@Test
public void remove1(){
System.out.println("操作前线性表:"+list);
boolean remove = list.remove(Integer.valueOf(1));
System.out.println(remove);
System.out.println("操作后线性表:"+list);
}
@Test
public void replace(){
Object o = list.replace(3, 1);
System.out.println(o);
System.out.println(list.toString());
}
@Test
public void addAfter() {
System.out.println("操作前线性表:"+list);
boolean b = list.addAfter(4, 99999);
System.out.println(b);
int size = list.size();
System.out.println("元素个数="+size);
System.out.println("操作后线性表:"+list);
}
@Test
public void addBefore() {
System.out.println("操作前线性表:"+list);
boolean b = list.addBefore(null, 99999);
System.out.println(b);
int size = list.size();
System.out.println("元素个数="+size);
System.out.println("操作后线性表:"+list);
}
@Test
public void contains() {
boolean contains = list.contains(0);
System.out.println(contains);
}
}