常用容器(Collection)实现类总结(二)——LinkedList

LinkedList简略说明:

List 接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括 null)。除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 getremoveinsert 元素提供了统一的命名方法。这些操作允许将链接列表用作堆栈、队列双端队列

(Doubly-linked list implementation of the List and Deque interfaces. Implements all optional list operations, and permits all elements (including null).All of the operations perform as could be expected for a doubly-linked list. Operations that index into the list will traverse the list from the beginning or the end, whichever is closer to the specified index. )

所有操作都是按照双重链接列表(doubly-linked list)的需要执行的。在列表中编索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端)。

(All of the operations perform as could be expected for a doubly-linked list. Operations that index into the list will traverse the list from the beginning or the end, whichever is closer to the specified index. )

 

LinkedList的优、缺点分析:

优点:

  • 操作的是数据指针,相对ArrayList大大增强了增、删速率

缺点:

  • 查找速率较低
  • 线程不安全

 双向链表示意:

 

链表与泛型集合有一个重要区别:链表是一个有序集合,每个对象的位置很重要.

LinkedList.add方法是将元素添加到列表的最后,但是有时我们需要在列表中插入一个元素,这时这时使用迭代器就很必要.

 

图例:

相关代码:

List<String> staff = new LinkedList<>();
staff.add("Amy");
staff.add("Bob");
staff.add("Carl");
ListIterator<String> iter = staff.listIterator();
iter.next(); // skip past first element
iter.add("Juliet");

注意:

这里有个调用remove方法的小细节------迭代器的删除和backspace工作方式有区别,在调用了next后,remove确实是删除了迭代后左侧的元素,但是在调用了previous之后,remove的是迭代后右侧的元素,并且不能连续调用两次remove.

add只依赖于迭代器的位置,而remove注重迭代器的状态.

    public static void main(String[] args) {
        List<String> l = new LinkedList<>();
        l.add("a");
        l.add("b");
        l.add("c");
        ListIterator<String> it = l.listIterator();
        it.next();
        it.add("some"); //在a后插入some
        it.previous();
        it.remove();
        System.out.println(l);  //输出[a, b, c],删除的是some而非a
    }

 

基本实现:

  • Node类的实现:

由于在链表中,出现了节点(Node)的概念,所以我们先写如一个节点类,来操控指针:

 1 public class Node {
 2     private Node previous;
 3     private Node next;
 4     private Object obj;
 5     
 6     public Node(){}
 7     
 8     public Node(Node previous, Node next, Object obj) {
 9         super();
10         this.previous = previous;
11         this.next = next;
12         this.obj = obj;
13     }
14     
15     public Node getPrevious() {
16         return previous;
17     }
18     public void setPrevious(Node previous) {
19         this.previous = previous;
20     }
21     public Node getNext() {
22         return next;
23     }
24     public void setNext(Node next) {
25         this.next = next;
26     }
27     public Object getObj() {
28         return obj;
29     }
30     public void setObj(Object obj) {
31         this.obj = obj;
32     }
33     
34     
35 }

我们所实现的是双向链表,因此我定义了next和previous两个变量,顾名思义,目的就是为了对一个数据进行前后操作,后面定义了一系列getter/setter方法以达到增、删的操作;object变量显然就是储存的数据了

  • LinkedList类的实现:

    public class LinkList {
        private Node first;
        private Node last;
        
        private int size;
        
        public void add(Object obj) {
            Node n = new Node();
            if(first == null) {
                n.setPrevious(null);
                n.setObj(obj);
                n.setNext(null);
                
                first = n;
                last = n;
            }else {
                n.setPrevious(last);
                n.setObj(obj);
                n.setNext(null);
                
                last.setNext(n);
                last = n;
            }
            size++;
        }
        
        public void add(int index, Object obj) {
            rangeCheck(index);
            Node temp = (Node) find(index);
            Node newNode = new Node();
            Node prev = temp.getPrevious();
            if(temp != null) {
                newNode.setObj(obj);
                prev.setNext(newNode);
                newNode.setNext(temp);
                newNode.setPrevious(prev);
                temp.setPrevious(newNode);
            }
        }
        
        public void rangeCheck(int index) {
            if(index < 0 || index >= this.size) {   
                try {
                    throw new Exception();
                }catch(Exception e) {
                    e.printStackTrace();
                }
            }
        }
        
        public Object get(int index) {
            rangeCheck(index);
            Node temp = find(index);
            if(temp != null) {
                return temp.getObj();
            }
            return null;
        }
        
        public void remove(int index) {
            Node temp = find(index);
            if (temp != null) {
                Node prev = temp.getPrevious();
                Node next = temp.getNext();
                prev.setNext(next);
                next.setPrevious(prev);
                size--;
            }
        }
            
        public Node find(int index) {
            Node temp = first;
            if(first != null) {
                for(int i = 0;i < index; i++) {
                    temp = first;
                    temp = temp.getNext();
                }
            }
            return temp;
        }
        
        public int getSize() {
            return size;
        }

     

 

转载于:https://www.cnblogs.com/nothingAJ/p/6618427.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值