91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java中數組與鏈表的比較

發布時間:2021-08-20 19:38:32 來源:億速云 閱讀:177 作者:chen 欄目:開發技術

這篇文章主要講解了“java中數組與鏈表的比較”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“java中數組與鏈表的比較”吧!

目錄
  • 數組與鏈表的比較:

  • ArrayList:

  • LinkedList:

  • 總結

數組與鏈表的比較:

  • 數組通過下標訪問的話是O(1)

  • 數組一旦聲明 長度就是固定的

  • 數組的數據是物理邏輯均連續的

  • 鏈表增刪要快一些, 數組遍歷快一些

  • 長度一定的話, 數組的存儲空間比鏈表要小

ArrayList:

ArrayList是List接口的實現類,它是支持根據需要而動態增長的數組;java中標準數組是定長的,在數組被創建之后,它們不能被加長或縮短。這就意味著在創建數組時需要知道數組的所需長度,但有時我們需要動態程序中獲取數組長度。ArrayList就是為此而生的。

擴容機制發生在add()方法調用的時候;

  public boolean add(E e) {
       //擴容
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

該行代碼ensureCapacityInternal()是用來擴用的,形參是最小擴容量,進入該方法后:

private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

通過方法calculateCapacity(elementData, minCapacity)獲取:

   private static int calculateCapacity(Object[] elementData, int minCapacity) {
        //如果傳入的是個空數組則最小容量取默認容量與minCapacity之間的最大值
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }

使用 ensureExplicitCapacity方法可以判斷是否需要擴容:

 private void ensureExplicitCapacity(int minCapacity) {
          modCount++;
          // 如果最小需要空間比elementData的內存空間要大,則需要擴容
          if (minCapacity - elementData.length > 0)
              //擴容
              grow(minCapacity);
      }

需要擴容,進入ArrayList擴容的關鍵方法grow():擴大為原來的1.5倍;

 private void grow(int minCapacity) {
          // 獲取到ArrayList中elementData數組的內存空間長度
          int oldCapacity = elementData.length;
         // 擴容至原來的1.5倍
         int newCapacity = oldCapacity + (oldCapacity >> 1);
         // 再判斷一下新數組的容量夠不夠,夠了就直接使用這個長度創建新數組,
          // 不夠就將數組長度設置為需要的長度
         if (newCapacity - minCapacity < 0)
             newCapacity = minCapacity;
         //若預設值大于默認的最大值檢查是否溢出
         if (newCapacity - MAX_ARRAY_SIZE > 0)
             newCapacity = hugeCapacity(minCapacity);
         // 調用Arrays.copyOf方法將elementData數組指向新的內存空間時newCapacity的連續空間
         // 并將elementData的數據復制到新的內存空間
         elementData = Arrays.copyOf(elementData, newCapacity);
     }

至此得出ArrayList擴容的本質是計算出新的擴容數組的size后實例化,并將原有數組內容復制到新數組中去。

LinkedList:

鏈表實現擴容,直接在尾指針后面加入新的元素即可。

實現LinkedList:LinkedList的底層實現是鏈表。更深理解是一個雙向鏈表。

節點代碼:

//節點
public class Node {
	Node previous;//前繼,指向前一個Node
	Object data;//節點數據
	Node next;//后繼,指向后一個Node
	public Node() {
	}
	public Node(Node previous, Object data, Node next) {
		super();
		this.previous = previous;
		this.data = data;
		this.next = next;
	} 
}

初始化MyLinkedList:

public class MyLinkedList {
	private Node first;//首節點
	private Node last;//尾節點
	private int size;//鏈表大小
	public MyLinkedList() {
		first = null;
		last = null;
		size = 0;
	}
}

尾部添加,實現add(Object obj)方法:

public void add(Object obj){
		Node node = new Node(null,null,null);
		if(first==null){//first=null,說明LinkedList中沒有一個節點
			node.data = obj;
			first = node;
			last = node;//第一個節點和最后一個節點都是node
			size++;
		}else{
			node.data = obj;
			last.next = node;//和最后一個連接起來
			node.previous = last;
			last = node;//當前節點變為末尾節點
			size++;
		}

現get(int index)方法,獲取index處的節點并返回Node:

使用循環,遍歷鏈表:

public Node get(int index) {
		RangeCheck(index);
		Node temp = null;
		if(index < (size>>1)){//改進的遍歷方法,右移運算符的巧用
			temp = first;
			for(int i=0;i<index;i++){
				temp = temp.next;
			}
		}else {
			temp = last;
			for(int i=size-1;i>index;i--){
				temp = temp.previous;
			}
		}
		return temp;
	}

任意位置插入,實現add(int index,Object obj)方法:插入的步驟注意順序,不要產生斷鏈。

public void add(int index,Object obj) {
		RangeCheck(index);//對傳入的索引必須進行檢查,判斷是否越界
		Node node = new Node(null,null,null);
		node.data = obj;
		Node node2=first;
		for(int i=0;i<index-1;i++){
			node2 = node2.next;
		}
		node.next = node2.next;
		node2.next.previous=node;
		node2.next = node;
		node.previous=node2;
		size++;
	}

RangeCheck():

private void RangeCheck(int index) {
		if(index<0||index >= size){
			throw new IndexOutOfBoundsException("IndexOutOfBounds"+index);//不合法則拋出異常
		}
	}

實現remove(Object obj)方法:

public boolean remove(Object obj) {
		Node node = first;
		if(obj==null){
			while(node!=null){
				if(node.data==null){
					removefast(node);
					return true;
				}
				node = node.next;
			}
		}else {
			while(node!=null){
				if(obj.equals(node.data)){
					removefast(node);
					return true;
				}
				node = node.next;
			}
		}
		return false;
	}
	private void removefast(Node node){
		node.previous.next=node.next;
		size--;
		node.data=null;
		node.previous = node.next = null;
	}

實現set(int index,Object obj)方法:

public Object set(int index,Object obj) {
		Node node = get(index);
		Object oldObject=node.data;
		node.data = obj;
		return oldObject;
	}

感謝各位的閱讀,以上就是“java中數組與鏈表的比較”的內容了,經過本文的學習后,相信大家對java中數組與鏈表的比較這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

玉屏| 宿州市| 乐安县| 阜阳市| 渝北区| 宁阳县| 德兴市| 宁晋县| 迁西县| 揭西县| 兴安盟| 昭通市| 鸡西市| 龙州县| 徐水县| 新干县| 龙里县| 中卫市| 彭泽县| 林芝县| 马边| 博客| 遂昌县| 凤阳县| 正蓝旗| 霍州市| 土默特左旗| 长兴县| 临江市| 宝坻区| 甘谷县| 稻城县| 休宁县| 中西区| 喜德县| 上杭县| 威宁| 普宁市| 嵊州市| 墨脱县| 沛县|