概述
list是java集合中的4大接口之一,list是一个有序的集合,list中的元素可以重复,在平时编程使用频率也非常的高。
list的常用实现类
- ArrayList
- 底层是数组实现;
- 查询速度快;
- 线程不安全,效率高 ;
- LinkedList
- 底层链表实现;
- 增删改的速度快;
- 线程不安全,效率高;
- Vector
- 底层是数组实现
- 线程安全,效率低。
手写ArrayList
这里简单的实现了一个ArrayList,类似于JDK中实现的ArrayList,包含了一些常用的方法,如:size(),isEmpty(),add(int index,Object object),add(Object object),remove(Object object),remove(int index),get(int index),set(int index,Object object),
等,主要对数组的深入和集合的理解加透彻。了解list的一些底层的实现。
package com.bai.cn.Collection;
/**
* 手写ArrayList
* @author 白
*
*/
public class MyArrayList {
//相关的属性
private transient Object[] elementData;
private int size;
//不带参数的构造器
public MyArrayList(){}
//带参数的构造器
public MyArrayList(int initialcapacity){
if(initialcapacity<0){
try {
throw new Exception();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
elementData=new Object[initialcapacity];
}
//目前的大小,存放对象的个数
public int size(){
return size;
}
//该容器是否为空
public boolean isEmpty(){
return size==0;
}
//添加对象
public void add(Object object){
ensureCapacity();
elementData[size++]=object;
//size++;
}
//根据对象名称移除对象
public void remove(Object object){
for(int i=0;i<size;i++){
if(elementData[i]. equals(object)){
remove(i);
}
}
}
//根据索引移除对象
public void remove(int index){
rangeCheck(index);
for(int i=index;i<elementData.length;i++){
if(i+1<=elementData.length-1){
elementData[i]=elementData[i+1];
}
}
size--;
}
//根据索引获取对象
public Object get(int index){
rangeCheck(index);
return elementData[index];
}
//修改指定索引位置的对象
public void set(int index,Object object){
rangeCheck(index);
elementData[index]=object;
}
//在指定索引位置插入对象
public void add(int index,Object object){
rangeCheck(index);
ensureCapacity();
System.arraycopy(elementData, index, elementData, index+1, size-index);
elementData[index]=object;
size++;
}
//索引越界判断
private void rangeCheck(int index){
if(index>=size||index<0){
throw new ArrayIndexOutOfBoundsException();
}
}
//确保容量(扩容)
private void ensureCapacity(){
if(size==elementData.length){
Object[] newArray=new Object[size*2+2];
for(int i=0;i<elementData.length;i++){
newArray[i]=elementData[i];
}
elementData=newArray;
}
}
}
class Test{
private String teString;
@Override
public boolean equals(Object arg0) {
// TODO Auto-generated method stub
if(arg0 instanceof Test){
if(((Test) arg0).teString.equals(this.teString)){
return true;
}
}
return false;
}
public Test(String string){
this.teString=string;
}
}
手写LinkedList
这里简单的实现了一个LinkedList,类似于JDK中实现的LinkedList,包含了一些常用的方法,如:size(),isEmpty(),add(int index,Object object),add(Object object),remove(int index),get(int index)
等,主要对帮助链表的深入和对集合的理解,了解list的一些底层的实现。
package com.bai.cn.Collection;
/**
* 手写LinkedList
* @author 白
*
*/
public class MylLinkedList {
//相关属性
private Node first;
private Node last;
private int size;
//目前容纳对象的数量
public int size(){
return size;
}
//判断是否为空
public boolean isEmpty(){
return size==0;
}
//添加元素,追加到末尾
public void add(Object object){
Node node=new Node();
if(first==null){
node.setPrevious(null);
node.setObject(object);
node.setNext(null);
first=node;
last=node;
}else{
//往last后增加新的节点
node.setPrevious(last);
node.setObject(object);
node.setNext(null);
last.setNext(node);
last=node;
}
size++;
}
//根据索引获取元素
public Object get(int index){
rangeCheck(index);
Node temp=null;
if(first!=null){
temp=first;
for(int i=0;i<index;i++){
temp=temp.getNext();
}
}
return temp.getObject();
}
//根据索引删除元素
public Object remove(int index){
rangeCheck(index);
Node temp=null;
if(first!=null){
temp=first;
for(int i=0;i<index;i++){
temp=temp.getNext();
}
Node temp_P=temp.getPrevious();
Node temp_N=temp.getNext();
temp_P.next=temp_N;
temp_N.previous=temp_P;
size--;
return temp.getObject();
}
return null;
}
//根据索引插入元素
public boolean add(int index,Object object){
rangeCheck(index);
Node temp=new Node();
Node newNode=new Node();
newNode.setObject(object);
if(first!=null){
temp=first;
for(int i=0;i<index;i++){
temp=temp.getNext();
}
Node temp_P=temp.previous;
temp_P.next=newNode;
newNode.previous=temp_P;
newNode.next=temp;
temp.previous=newNode;
size++;
return true;
}
return false;
}
//索引越界判断
private void rangeCheck(int index){
if(index>=size||index<0){
try {
throw new Exception();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//节点类
class Node{
Node previous;//上一个节点
private Object object;//要存放的内容
Node next;//下一个节点
public Node(){}
public Node(Node previous, Object object, Node next) {
super();
this.previous = previous;
this.object = object;
this.next = next;
}
public Node getPrevious() {
return previous;
}
public void setPrevious(Node previous) {
this.previous = previous;
}
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
测试
注意Test类equals()
方法的重写,实现以对象属性作为参数的比较从而移除对象。
package com.bai.cn.Collection;
public class ListTest {
//手写ArrayList测试
public static void arrayListDemo(){
Test test=new Test("FFF");
/**
* 测试对象为String
*/
MyArrayList myArrayList=new MyArrayList(2);
//添加
myArrayList.add("aaa");
myArrayList.add("bbb");
myArrayList.add("ccc");
myArrayList.add("ddd");
myArrayList.add("eee");
myArrayList.add("FFF");
//移除
myArrayList.remove(1);
myArrayList.remove("FFF");
System.out.println(myArrayList.size());
//获取
for(int i=0;i<myArrayList.size();i++){
System.out.println(myArrayList.get(i));
}
/**
* 测试对象为任意的类
*/
MyArrayList myArrayList2=new MyArrayList(2);
//添加
myArrayList2.add(new Test("aaa"));
myArrayList2.add(new Test("bbb"));
myArrayList2.add(new Test("ccc"));
myArrayList2.add(new Test("ddd"));
myArrayList2.add(new Test("eee"));
myArrayList2.add(test);
//移除
myArrayList2.remove(1);
/**
* 根据对象的相关属性移除对象
*
* 例:根据名称,
* 这里以Test对象为例,
* 需要重写它的equals方法(具体实现在Test类中)。
*
*
* 因为Object类的equals方法比较的是对象的地址,
* 对于一个类,new了一个对象就会在堆空间分配一个地址,
* 因此new Test("FFF")再new Test("FFF"),
* 这两个对象是不同的对象,所以需要重写equals方法。
*
* 以上测试对象为String,而String对象本身就重写了equals方法
*/
myArrayList2.remove(new Test("ccc"));
System.out.println(myArrayList2.size());
//获取
for(int i=0;i<myArrayList2.size();i++){
System.out.println(myArrayList2.get(i));
}
}
//手写LinkedList测试
public static void linkedListDemo(){
MylLinkedList mylLinkedList=new MylLinkedList();
//添加,追加到末尾
mylLinkedList.add("a");
mylLinkedList.add("b");
mylLinkedList.add("c");
mylLinkedList.add("d");
//移除指定索引位置的元素
System.out.println(mylLinkedList.remove(2));
//添加,插入
System.out.println(mylLinkedList.add(1, "New"));
//获取元素
System.out.println(mylLinkedList.get(1));
}
public static void main(String[] args) {
arrayListDemo();
System.out.println("----------------------------------------------------------------");
linkedListDemo();
}
}