LinkedList源码系列(2)

int indexOF(T e):

   /**
     * Returns the index of the first occurrence of the specified element
     * in this list, or -1 if this list does not contain the element.
     * More formally, returns the lowest index {@code i} such that
     * (o==null?get(i)==null:o.equals(get(i))),
     * or -1 if there is no such index.
     *
     * @param o element to search for
     * @return the index of the first occurrence of the specified element in
     *         this list, or -1 if this list does not contain the element
     */
	public int indexOf(T e){
		int index = 0;
		if(e == null){
			for(Node<T> x = first;x != null;x = x.next){
				if(x.data == null)
					return index;
				index++;
			}
		}
		else{
			for(Node<T> x = first;x != null;x = x.next){
				if(e.equals(x.data))
					return index;
				index++;
			}
		}
		return -1;
	}
indexOf()是找到第一个Node.data = e的节点,e == null  || e == Object两种情况都要考虑。。。 找不到返回-1

int lastIndexOf():

   /**
     * Returns the index of the last occurrence of the specified element
     * in this list, or -1 if this list does not contain the element.
     * More formally, returns the highest index {@code i} such that
     * (o==null?get(i)==null:o.equals(get(i))),
     * or -1 if there is no such index.
     *
     * @param o element to search for
     * @return the index of the last occurrence of the specified element in
     *         this list, or -1 if this list does not contain the element
     */
	public int lastIndexOf(T e){
		int index = size;
		if(e == null){
			for(Node<T> x = last; x != null; x = x.next){
				if(x.data == null)
					return index;
				index--;
			}
		}else{
			for(Node<T> x = last; x != null; x= x.next){
				if(e.equals(x.data))
					return index;
				index--;
			}
		}
		return -1;
	}
这个是最后出现的Node.data == e的结点,原理同上

// Queue Operations
   /**
     * Retrieves(找回), but does not remove, the head (first element) of this list.
     *
     * @return the head of this list, or {@code null} if this list is empty
     * @since 1.5
     */
	public T peek(){
		final Node<T> f = first;
		return (f == null)? null:f.data;
	}
	
   /**
     * Retrieves, but does not remove, the head (first element) of this list.
     *
     * @return the head of this list
     * @throws NoSuchElementException if this list is empty
     * @since 1.5
     */
	public T Element(){
		return getFirst();
	}
	
	/**
     * Retrieves and removes the head (first element) of this list.
     *
     * @return the head of this list, or {@code null} if this list is empty
     * @since 1.5
     */
	public T poll(){
		final Node<T> f = first;
		return (f == null)? null:unlinkFirst(f);
	}
	
   /**
     * Retrieves and removes the head (first element) of this list.
     *
     * @return the head of this list
     * @throws NoSuchElementException if this list is empty
     * @since 1.5
     */
	public T remove(){
		return removeFirst();
	}
	
   /**
     * Adds the specified element as the tail (last element) of this list.
     *
     * @param e the element to add
     * @return {@code true} (as specified by {@link Queue#offer})
     * @since 1.5
     */
	public boolean offer(T e){
		return add(e);
	}
看吧,其实源代码大家也是可以写出来的。。  不难,都是前面方法的封装~~~

下面就直接来看List迭代器的设计学习一下它的思想,我们才能更好的使用:

	private class LinkedListIterator implements java.util.ListIterator<T>{
		private Node<T> lastReturned = null;
		private Node<T> next ;
		private int nextIndex; 
		private int expectedModCount = modCount;
		
		public LinkedListIterator(){
			
		}
		
		public LinkedListIterator(int index){
			// assert checkPositionIndex(index)
			next = (index==size)?null:getNode(index);
			nextIndex = index;
		}
		
		@Override
		public boolean hasNext() {
			return nextIndex < size;
		}
		
		public T next(){
			checkForModification();
			if(!hasNext())
				throw new java.util.NoSuchElementException();
			lastReturned = next;
			next = next.next;
			nextIndex++;
			return lastReturned.data;
		}
		
		 public boolean hasPrevious(){
	            return nextIndex > 0;
	     }
		
		 public T previous() {
			 checkForModification();
			 if(!hasPrevious())
				 throw new java.util.NoSuchElementException();
			 lastReturned = next = (next == null)?last:next.prev;
			 nextIndex--;
			 //因为next移动的位置已经在当前迭代元素的下一个位置,所以不用next = next.prev
			 return lastReturned.data;
		 }
		 
		 public int nextIndex(){
			 return nextIndex;
		 }
		 
		 public int previousIndex(){
			 return nextIndex - 1;
		 }
		 
		 public void remove(){
			 checkForModification();
			 if(lastReturned == null)
				 throw new IllegalStateException();
			<span style="font-family: Arial, Helvetica, sans-serif;">Node<T> lastNode = lastReturned.next;</span><pre name="code" class="java">			 unlink(lastReturned);
			 if(next == lastReturned){
				 //当只调用了一次previous()方法next == lastReturn,其他时候lastReturn = next.prev
				 next = lastNode;
			 }else{
				 nextIndex--;
			 }
				 lastReturned = null;
				 expectedModCount++;
} public void set(T e){ if(lastReturned == null) throw new IllegalStateException(); checkForModification(); lastReturned.data = e; } public void add(T e){ checkForModification(); lastReturned = null; if(next == null) linkLast(e); else linkBefore(e,next); nextIndex++; expectedModCount++; } final void checkForModification(){if(expectedModCount != modCount){throw new java.util.ConcurrentModificationException();}}}
} public void set(T e){ if(lastReturned == null) throw new IllegalStateException(); checkForModification(); lastReturned.data = e; } public void add(T e){ checkForModification(); lastReturned = null; if(next == null) linkLast(e); else linkBefore(e,next); nextIndex++; expectedModCount++; } final void checkForModification(){if(expectedModCount != modCount){throw new java.util.ConcurrentModificationException();}}}

 首先,当我们声明一个LinkedListIterator内部类时,编译器将添加一个外部类对象的的一个隐式引用,该对象引起内部类的构造。在这个LinkedListIterator的设计中 private int expectedModCount = MyLinkedList.this.modCount这里就是一个内部类应用的实例,类与类之间的关联可以是is-a,也可以是inner-outer 、nested总之我们需要灵活运用。我们可以知道在api中构造listIterator时,必须传入一个index,也就是从当前结点开始的迭代器,在new LinkedListIterator(index)时,先在堆内LinkedListiterator对象分配足够的空间,这块存储空间会被清零,这就自动的将LinkedListIterato对象中的所有基本类型设置成默认值,引用类型置null,接着执行所有出现在字段定义处的初始化动作,然后执行构造器。这时每个LinkedListIterato对象expectedModCount都被赋上LinkedList中的modCount(List结构修改次数),next ->currrentNode ,nextInt = currentIndex ,lastReturned = null(它的作用就是用来判断拿到Data) 

next()方法就是返回lastReturned.data,同时向后更新next,preivous()则恰好相反~

remove方法这里还有点需要注意:

<span style="white-space:pre">			</span> Node<T> lastNode = lastReturned.next;
			 unlink(lastReturned);
			 if(next == lastReturned){
				 //当只调用了一次previous()方法next == lastReturn,其他时候lastReturn = next.prev
				 next = lastNode;
			 }else{
				 nextIndex--;
			 }
				 lastReturned = null;
				 expectedModCount++;
这里有可能出现这种情况,拿到迭代器后先执行一次previous()方法, lastReturned = next = (next == null)?last : last.prev ;  这时候就有  next == lastReturned的情况,next = lastNode 更新next指针。而先执行next方法,在remove的时候就只需要更新nextInt索引(减一,因为在next方法中已经将nextInt移动到lastReturned的下一个结点的索引)

最后需要注意的是:lastReturned的使用,当没有用previous和next迭代时,lastReturned == null,这时使用remove,set是会抛出IllegalStateException.

java api文档中还提供了逆序的迭代器     Iterator<T> descendingIterator():

           /**
	     * Adapter to provide descending iterators via ListItr.previous
	     */
	  private class DescendingIterator implements Iterator<T>{
		  final LinkedListIterator itr = new LinkedListIterator(size());
		  
		@Override
		public boolean hasNext() {
			return itr.hasPrevious();
		}

		@Override
		public T next() {
			return itr.previous();
		}
		  
		@Override
		public void remove() {
			itr.remove();
		}
		
		 @SuppressWarnings({  "unchecked" })
		private MyLinkedList<T> superClone() {
		        try {
		            return (MyLinkedList<T>) super.clone();
		        } catch (CloneNotSupportedException e) {
		        	//该异常指示 Java 虚拟机中出现一些意外的内部错误
		        	throw new InternalError();
		        }
		    }
		 
		 /**
	           * Returns a shallow copy of this {@code LinkedList}. (The elements
		   * themselves are not cloned.)
		   *
		   * @return a shallow copy of this {@code LinkedList} instance
		   */
		 public Object clone(){
			 MyLinkedList<T> clone = superClone();
			 
			 // Put clone into "virgin" state
			 clone.first = clone.last = null;
			 clone.modCount = 0;
			 clone.size = 0;
			 
			// Initialize clone with our elements
			 for(Node<T> x = first;x != null; x=x.next ){
				 clone.add(x.data);
			 }
			 	return clone;
		 }
		 
		   /**
		     * Returns an array containing all of the elements in this list
		     * in proper sequence (from first to last element).
		     *
		     * <p>The returned array will be "safe" in that no references to it are
		     * maintained by this list.  (In other words, this method must allocate
		     * a new array).  The caller is thus free to modify the returned array.
		     *
		     * <p>This method acts as bridge between array-based and collection-based
		     * APIs.
		     *
		     * @return an array containing all of the elements in this list
		     *         in proper sequence
		     */
			 @SuppressWarnings("unused")
			public Object[] toArray(){
				 Object[] result = new Object[size];
				 int i = 0;
				 for(Node<T> x = first; x != null;x = x.next)
					 result[i++] = x.data;
				 return result;
			 }
	  }
这里大家其实可以看出DescendingIterator其实还是使用LinkedListIterator里面的方法,本质上还是一样的,至于其他的方法大家可以看看。。


最后,作为一个合格的程序员,我想说下上面的代码是最基础也是最重要的,希望大家能熟悉熟悉再熟悉~~~~      

                                                                                                                               ---愿与诸君共进步,Judy  



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值