《Java集合深入阐述(二)》

一:Vector 深入理解

1.1 Vector 基本介绍与注意事项‘

基本介绍:

1) Vector 类的定义说明:

public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable{ }

2) Vector 底层也是一个对象数组, protected Object[ ] elementData;

3) Vector 是线程同步的,即线程安全, Vector 类的操作方法带有 synchronized

例如我们常用的 get 方法

public synchronized E get(int index) {
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);

        return elementData(index);
    }

4) 在开发过程中,需要线程同步安全时, 考虑使用 Vector。

1.2 Vector 底层结构与 ArrayList 的比较:

在这里插入图片描述

        1. new Vector() 底层
        
            public Vector() {
                this(10);
            }
         补充:如果是  Vector vector = new Vector(8);
            走的方法:
            public Vector(int initialCapacity) {
                this(initialCapacity, 0);
            }
         2. vector.add(i)
         2.1  //下面这个方法就添加数据到vector集合
            public synchronized boolean add(E e) {
                modCount++;
                ensureCapacityHelper(elementCount + 1);
                elementData[elementCount++] = e;
                return true;
            }
          2.2  //确定是否需要扩容 条件 : minCapacity - elementData.length>0
            private void ensureCapacityHelper(int minCapacity) {
                // overflow-conscious code
                if (minCapacity - elementData.length > 0)
                    grow(minCapacity);
            }
          2.3 //如果 需要的数组大小 不够用,就扩容 , 扩容的算法
              //newCapacity = oldCapacity + ((capacityIncrement > 0) ?
              //                             capacityIncrement : oldCapacity);
              //就是扩容两倍.
            private void grow(int minCapacity) {
                // overflow-conscious code
                int oldCapacity = elementData.length;
                int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                                 capacityIncrement : oldCapacity);
                if (newCapacity - minCapacity < 0)
                    newCapacity = minCapacity;
                if (newCapacity - MAX_ARRAY_SIZE > 0)
                    newCapacity = hugeCapacity(minCapacity);
                elementData = Arrays.copyOf(elementData, newCapacity);
            }
       

注意: capacityIncrement 默认为 0 ,newCapacity 默认扩容两倍。

Vector 构造器追入,源码展示:

 二:LinkedList 的深入理解:

2.1 LinkedList 的全面说明:

1) LinkedList 底层实现了双向链表和双端队列的特点。

2) 可以添加任何元素(元素可以重复),包括 null

3) 线程不安全,没有实现同步。

2.2 LinkedList 的底层操作机制:

1) LinkedList 底层维护了一个双向链表。

2) LinkedList 中维护了两个属性 first 和 last,分别指向 首节点 和 尾节点。

3) 每个节点(Node 对象),里面维护了prev,next,item三个属性,其中通过 prev 指向前一个,通过 next 指向后一个 节点,最终实现双向链表。

4) 所以 LinkedList 的元素的添加与删除,不是通过数组完成的,相对来说效率比较高。

5) 模拟一个简单的双向链表,见下面代码。

public class LinkedList01 {
    public static void main(String[] args) {
        // 模拟一个简单的双向链表

        Node jack = new Node("jack");
        Node tom = new Node("tom");
        Node mary = new Node("mary");

        // 连接三个节点
        // jack -> tom -> mary
        jack.next = tom;
        tom.next = mary;
        //mary -> tom -> jack
        mary.prev = tom;
        tom.prev = jack;

        Node first = jack; // 让first 引用指向jack,就是双向链表的头节点
        Node last = mary; // 让last 引用指向 mary ,就是双向链表的尾节点

        // 演示从头到尾遍历
        while (true){
            if(first == null){
                break;
            }
            // 输出 first 的信息
            System.out.println(first);
            first = first.next;
        }

        // 演示从尾到头遍历
        while (true){
            if(last == null){
                break;
            }
            System.out.println(last);
            last = last.prev;
        }

        // 演示双向链表添加对象 , 要求在tom 与 mary 之间
        Node bob = new Node("Bob");
        bob.next = mary;
        bob.prev = tom;
        mary.prev = bob;
        tom.next = bob;
        
    }
}

// 定义一个Node类,Node 对象,表示我们双向链表的一个节点
class Node{
    public Object item;  // 真正存放数据的地方
    public Node next;    // 指向下一个节点
    public Node prev;    // 指向前一个节点

    public Node(Object item) {
        this.item = item;
    }

    @Override
    public String toString() {
        return "Node name = " + item;
    }
}

2.3 LinkedList 的底层结构:

1) LinkedList 的创建分析

          语句: LinkedList linkedList = new LinkedList();
          调用: public LinkedList() {}
          这时 linkeList 的属性 first = null  last = null

2)LinkedList 的 add 分析

添加
第一步执行的方法
               public boolean add(E e) {
                    linkLast(e);
                    return true;
                }
第二步执行的方法,将新的结点,加入到双向链表的最后
             void linkLast(E e) {
                final Node<E> l = last;
                final Node<E> newNode = new Node<>(l, e, null);
                last = newNode;
                if (l == null)
                    first = newNode;
                else
                    l.next = newNode;
                size++;
                modCount++;
            }

3)LinkedList 的remove()分析

linkedList.remove(); 这里默认删除的是第一个结点
 1. 执行 removeFirst
            public E remove() {
                return removeFirst();
            }
 2. 执行
            public E removeFirst() {
                final Node<E> f = first;
                if (f == null)
                    throw new NoSuchElementException();
                return unlinkFirst(f);
            }
 3. 执行 unlinkFirst, 将 f 指向的双向链表的第一个结点拿掉
            private E unlinkFirst(Node<E> f) {
                final E element = f.item;
                final Node<E> next = f.next;
                f.item = null;
                f.next = null; // help GC
                first = next;
                if (next == null)
                    last = null;
                else
                    next.prev = null;
                size--;
                modCount++;
                return element;
            }

4) linkedList.set(int index,Object obj)  : 修改某个节点对象。

5)   linkedList.get(int index) :  获取index索引位置的节点对象。

6)LinkedList 实现了 List 接口,遍历方法可以是 迭代器 和 增强for循环。

2.4 LinkedList 与 ArrayList 的比较

注意:ArrayList 与 LinkedList 都是线程不安全的,所以在使用的时候最好是单线程的情况下。

在这里插入图片描述

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值