JAVA集合之List

概述


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();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值