Javaの学習:Javaコンテナ--listインターフェース(アナログ下層のコード実装のArrayListとLinkedListのクラス)

Javaコンテナ--listインタフェース

1、の概念

データインタフェースリストは、繰り返し命じています。Collectionインタフェースを継承。
3実装クラスのArrayList、LinkedListは、Vectorがあります。

ArrayListの:
基本的な実装は配列です。高速クエリ、挿入、削除が遅いです。スレッドセーフな、高効率。
LinkedListのは:
基本的な実装は、リンクされたリストです。スロークエリ、挿入、削除速いです。スレッドセーフな、高効率。
ベクター:
基本的な実装は配列です。スレッドセーフ、効率が低いです。複数のスレッドの共有を使用して、一般的にはローカル変数であるとき、一般的に、それは一般的に使用されていません。
スタック:
Vectorクラスを継承しています。

2、ArrayListの基礎となるアナログ(下地アレイ)

高速クエリは:ターゲットストレージアレイで直接オブジェクトを返します。
挿入は、削除遅い:アレイの拡張は、操作を必要とします。そして新しい配列、オブジェクト・低効率に配列をコピーするための挿入や削除が必要に移動。
膨張機構:デフォルトの長さの10が自動的に1.5倍体積膨張に拡張されたアレイ)

/**
 * 自己实现一个ArrayList,帮助理解其底层实现;笔试一般写get,add,remove 底层通过数组实现。
 */
public class MyArrayList {
	private Object[] elementDate;//底层是数组
	private int size;//对象的个数
	public int size() {
		return size;
	}
	public MyArrayList() {
		this(10);//初始数组长度设为固定值
	}
	public MyArrayList(int initialCapacity) {//也可以在初始化ArrayList时就指定数组长度
		if (initialCapacity < 0) {
			try {
				throw new Exception();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		elementDate = new Object[initialCapacity];
	}
	/**
	 * 扩容
	 */
	private void extendCap() {
		if (size + 1 > elementDate.length) {//如果size+1超过数组长度
			Object[] newArray = new Object[size * 2 + 1];//先建立一个新的数组,昌都市现在size的两倍+1
			System.arraycopy(elementDate, 0, newArray, 0, elementDate.length);// 数组拷贝
			elementDate = newArray;//使源数组等于新建数组
		}
	}
/**
 * index处存放obj,数组后移
 * @param index
 * @param obj
 */
	public void add(int index, Object obj) {
		checkIndex(index);//检查index
		extendCap();//扩容
		System.arraycopy(elementDate, index, elementDate, index + 1, size
				- index );
		elementDate[index] = obj;
		size++;
	}

	public void add(Object obj) {
		// 应当先扩容
		extendCap();
		// 赋值
		elementDate[size] = obj;
		// 自增
		size++;

	}

	/**
	 * 判断是否为空
	 * @return
	 */
	public boolean isEmpty() {
		return size == 0;
	}

	public Object get(int index) {
		checkIndex(index);
		return elementDate[index];
	}

	public void set(int index, Object obj) {
		elementDate[index] = obj;
	}

	private void checkIndex(int index) {
		if (index <= size - 1 && index >= 0) {
		} else {
			throw new IndexOutOfBoundsException("index:" + index + "  size:"
					+ size);
		}

	}

	public void remove(Object obj) {
		for (int i = 0; i < size; i++) {
			if (get(i).equals(obj)) {// 注意底层调用的是equals方法而不是==
				remove(i);// 底层是只删除第一个
			}
		}
	}

	public void print() {
		for (int i = 0; i < size; i++) {
			System.out.print("  " + elementDate[i]);
		}
	}

	public void remove(int index) {
		checkIndex(index);
		int numMoved = size - index - 1;
		if (numMoved > 0) {
			System.arraycopy(elementDate, index + 1, elementDate, index,
					numMoved);
			elementDate[--size] = null;
		}
	}
}

3、LinkedListのアナログ底(底のリスト)

スロークエリ:クエリノードは、最初からクエリオブジェクト指定されたノードを通るループを開始する必要があります。
速い、削除、追加データを移動することなく、すぐに前と変更後のノードの接続点:。

(1)リンクリストノード構造クラス

/**
 * 构造节点类
 * @author Linlin Zhao
 * 
 */
public class Node {

	Node previous;//前一个节点
	Object obj;//对象
	Node next;//下一个节点

	/**
	 * 构造器
	 * 
	 * @param previous
	 * @param obj
	 * @param next
	 */
	public Node(Node previous, Object obj, Node next) {
		super();
		this.previous = previous;
		this.obj = obj;
		this.next = next;
	}

	/**
	 * 构造器
	 */
	public Node() {

	}

}

(2)LinkedListのリストを達成

/**
 * 自己实现一个MyLinkedList,帮助理解其底层实现;一般考add和remove
 * 
 * @author Linlin Zhao
 * 
 */
public class MyLinkedList {
	private Node first;//头结点
	private Node last;//尾结点
	private int size;//节点个数

	public void add(Object obj) {
		Node n = new Node();
		if (first == null) {//若没有头结点,直接将对象放在头结点
			n.previous = null;
			n.obj = obj;
			n.next = null;
			first = n;
			last = n;
		} else {
			// 直接往last结点后加新的结点
			n.previous = last;
			n.next = null;
			n.obj = obj;
			last.next = n;
			last = n;
		}
		size++;
	}

	public int size() {
		return this.size;
	}

	public Object get(int index) {
		checkIndex(index);
		Node tempNode = node(index);
		return tempNode.obj;
	}

	private void checkIndex(int index) {
		if (index < size && index >= 0) {
		} else {
			throw new IndexOutOfBoundsException("index:" + index + "  size:"
					+ size);
		}

	}

	public void remove(int index) {
		checkIndex(index);
		Node tempNode = node(index);
		if (tempNode != null) {
			Node upNode = tempNode.previous;
			Node downNode = tempNode.next;
			upNode.next = downNode;
			downNode.previous = upNode;
		}
		size--;
	}

	/**
	 * 即通过节点遍历实现索引的功能
	 * 
	 * @param index
	 * @return
	 */
	private Node node(int index) {
		Node tempNode = null;
		if (first != null) {
			tempNode = first;
			for (int i = 0; i < index; i++) {
				tempNode = tempNode.next;
			}
		}
		return tempNode;
	}

	public void add(int index, Object obj) {
		checkIndex(index);
		Node tempNode = node(index);
		if (tempNode != null) {
			Node upNode = tempNode.previous;
			Node downNode = tempNode.next;
			Node add = new Node();
			add.next = downNode;
			add.obj = obj;
			add.previous = upNode;
			size++;
		}
	}
}

4、ベクトル基本的な実装

ベクターおよびArrayListの実装が非常に似ていますが、また、配列を達成するために。最大の違いは、ベクターは、スレッドセーフであることを、ほとんどのメソッドは同期化によって変更されています。

公開された57元の記事 ウォン称賛13 ビュー1125

おすすめ

転載: blog.csdn.net/weixin_42924812/article/details/105128912