java实现ArrayList和LinkedList[包含接口List和抽象类AbstractList]
图解
首先我们需要定义一个MyList的接口,将ArrayList和LinkedList共同的方法进行定义
package com. bingym. list. mylist;
public interface MyList < E> {
int size ( ) ;
boolean isEmpty ( ) ;
boolean contains ( E element) ;
boolean add ( E element) ;
E get ( int index) ;
E set ( int index, E element) ;
void add ( int index, E element) ;
E remove ( int index) ;
int indexOf ( E element) ;
void clear ( ) ;
String toString ( ) ;
}
定义抽象类MyAbstractList:实现共性的方法
package com. bingym. list. myabstractlist;
import com. bingym. list. mylist. MyList;
public abstract class MyAbstractList < E> implements MyList < E> {
protected int size;
@Override
public int size ( ) {
return size;
}
@Override
public boolean isEmpty ( ) {
return size == 0 ;
}
@Override
public boolean contains ( E element) {
return indexOf ( element) != - 1 ;
}
}
实现MyArrayList类
package com. bingym. list. myarraylist;
import com. bingym. list. myabstractlist. MyAbstractList;
public class MyArrayList < E> extends MyAbstractList < E> {
private Object[ ] elementData;
private Object[ ] emptyArray = { } ;
private final int DEFAULT_CAPACITY = 10 ;
public MyArrayList ( ) {
elementData = emptyArray;
}
public boolean add ( E e) {
grow ( ) ;
elementData[ size++ ] = e;
return true ;
}
private void grow ( ) {
if ( elementData == emptyArray) {
elementData = new Object [ DEFAULT_CAPACITY] ;
}
if ( size == elementData. length) {
int oldCapacity = elementData. length;
int newCapacity = oldCapacity + ( oldCapacity >> 1 ) ;
Object[ ] obj = new Object [ newCapacity] ;
System. arraycopy ( elementData, 0 , obj, 0 , elementData. length) ;
elementData = obj;
}
}
private void checkIndex ( int index) {
if ( index < 0 || index > size) {
throw new IndexOutOfBoundsException ( "索引越界" ) ;
}
}
public E get ( int index) {
checkIndex ( index) ;
return ( E) elementData[ index] ;
}
public E set ( int index, E element) {
checkIndex ( index) ;
E value = ( E) elementData[ index] ;
elementData[ index] = element;
return value;
}
@Override
public void add ( int index, E element) {
checkIndex ( index) ;
grow ( ) ;
for ( int i = size - 1 ; i >= index; i-- ) {
elementData[ i + 1 ] = elementData[ i] ;
}
elementData[ index] = element;
size++ ;
}
public E remove ( int index) {
checkIndex ( index) ;
E value = ( E) elementData[ index] ;
int numMoved = size - index - 1 ;
if ( numMoved > 0 ) {
System. arraycopy ( elementData, index+ 1 , elementData, index, numMoved) ;
}
elementData[ -- size] = null;
return value;
}
@Override
public int indexOf ( E element) {
if ( element == null) {
for ( int i = 0 ; i < size; i++ ) {
if ( elementData[ i] == element) return i;
}
} else {
for ( int i = 0 ; i < size; i++ ) {
if ( element. equals ( elementData[ i] ) ) return i;
}
}
return - 1 ;
}
@Override
public void clear ( ) {
for ( int i = 0 ; i < size; i++ ) {
elementData[ i] = null;
}
size = 0 ;
}
public String toString ( ) {
if ( size == 0 ) {
return "[]" ;
}
StringBuilder sb = new StringBuilder ( ) ;
sb. append ( "[" ) ;
for ( int i = 0 ; i < size; i++ ) {
if ( i == size- 1 ) {
sb. append ( elementData[ i] ) . append ( "]" ) ;
} else {
sb. append ( elementData[ i] ) . append ( "," ) . append ( " " ) ;
}
}
return sb. toString ( ) ;
}
}
实现单向链表类
package com. bingym. list. mylinkedlist;
import com. bingym. list. myabstractlist. MyAbstractList;
public class MySingleLinkedList < E> extends MyAbstractList < E> {
private Node first;
private static class Node < E> {
E element;
Node< E> next;
public Node ( E element, Node< E> next) {
this . element = element;
this . next = next;
}
}
@Override
public boolean add ( E element) {
Node< E> x = first;
Node< E> node = new Node < > ( element, null) ;
if ( isEmpty ( ) ) {
first = new Node ( element, first) ;
size++ ;
return true ;
}
while ( true ) {
if ( x. next == null) {
break ;
}
x = x. next;
}
x. next = node;
size++ ;
return true ;
}
@Override
public E get ( int index) {
checkIndex ( index) ;
return node ( index) . element;
}
private Node< E> node ( int index) {
Node< E> x = first;
for ( int i = 0 ; i < index; i++ ) {
x = x. next;
}
return x;
}
@Override
public E set ( int index, E element) {
checkIndex ( index) ;
Node< E> node = node ( index) ;
E oldElement = node. element;
node. element = element;
return oldElement;
}
@Override
public void add ( int index, E element) {
checkPostionIndex ( index) ;
if ( index == 0 ) {
first = new Node ( element, first) ;
} else {
Node< E> pre = node ( index - 1 ) ;
Node< E> next = node ( index) ;
Node< E> node = new Node < > ( element, next) ;
pre. next = node;
}
size++ ;
}
@Override
public E remove ( int index) {
checkPostionIndex ( index) ;
Node< E> oldNode = first;
if ( index == 0 ) {
first = first. next;
} else {
Node< E> pre = node ( index - 1 ) ;
oldNode = pre. next;
pre. next = oldNode. next;
}
size-- ;
return oldNode. element;
}
@Override
public int indexOf ( E element) {
Node< E> x = first;
int index = 0 ;
if ( element == null) {
for ( Node i = x; i != null; i = i. next) {
if ( element == i. element) {
return index;
}
index++ ;
}
} else {
for ( Node i = x; i != null; i = i. next) {
if ( element. equals ( i. element) ) {
return index;
}
index++ ;
}
}
return - 1 ;
}
@Override
public void clear ( ) {
first = null;
size = 0 ;
}
private void checkIndex ( int index) {
if ( index < 0 || index > size) {
throw new IndexOutOfBoundsException ( "索引越界" ) ;
}
}
private void checkPostionIndex ( int index) {
if ( ! isPostionIndex ( index) ) {
throw new IndexOutOfBoundsException ( ": Index: " + index + ", Size: " + size) ;
}
}
private boolean isPostionIndex ( int index) {
return index >= 0 && index <= size;
}
public String toString ( ) {
if ( size == 0 ) {
return "[]" ;
}
StringBuilder sb = new StringBuilder ( ) . append ( "[" ) ;
Node x = first;
for ( Node i = x; i != null ; i = i. next) {
sb. append ( i. element) ;
if ( i. next == null) {
return sb. append ( "]" ) . toString ( ) ;
}
sb. append ( "," ) ;
}
return sb. toString ( ) ;
}
}
实现双向链表类
package com. bingym. list. mylinkedlist;
import com. bingym. list. myabstractlist. MyAbstractList;
public class MyDoubleLinkedList < E> extends MyAbstractList < E> {
private Node< E> first;
private Node< E> last;
private static class Node < E> {
E element;
Node< E> pre;
Node< E> next;
public Node ( E element, Node< E> pre, Node< E> next) {
this . element = element;
this . pre = pre;
this . next = next;
}
}
@Override
public boolean add ( E element) {
add ( size, element) ;
return true ;
}
@Override
public E get ( int index) {
checkElementIndex ( index) ;
return node ( index) . element;
}
private Node< E> node ( int index) {
Node x = first;
if ( index > size >> 1 ) {
x = last;
for ( int i = size - 1 ; i > index; i-- ) {
x = x. pre;
}
} else {
for ( int i = 0 ; i < index; i++ ) {
x = x. next;
}
}
return x;
}
@Override
public E set ( int index, E element) {
checkIndex ( index) ;
Node< E> node = node ( index) ;
E oldElement = node. element;
node. element = element;
return oldElement;
}
@Override
public void add ( int index, E element) {
checkPostionIndex ( index) ;
if ( index == size) {
linkLast ( element) ;
} else {
linkBefore ( element, node ( index) ) ;
}
size++ ;
}
private void linkBefore ( E element, Node< E> node) {
Node< E> pre = node. pre;
Node< E> newNode = new Node < > ( element, pre, node) ;
node. pre = newNode;
if ( pre == null) {
first = newNode;
} else {
pre. next = newNode;
}
}
private void linkLast ( E element) {
Node< E> lastNode = last;
Node< E> newNode = new Node < > ( element, lastNode, null) ;
last = newNode;
if ( lastNode == null) {
first = newNode;
} else {
lastNode. next = newNode;
}
}
@Override
public E remove ( int index) {
checkElementIndex ( index) ;
Node< E> node = node ( index) ;
Node< E> pre = node. pre;
Node< E> next = node. next;
if ( pre == null) {
first = next;
next. pre = null;
} else {
pre. next = next;
}
if ( next == null) {
last = pre;
pre. next = null;
} else {
next. pre = pre;
}
size-- ;
return node. element;
}
@Override
public int indexOf ( E element) {
Node x = first;
int index = 0 ;
if ( element == null) {
for ( Node i = x; i != null; i = i. next) {
if ( element == i. element) {
return index;
}
index++ ;
}
} else {
for ( Node i = x; i != null; i = i. next) {
if ( element. equals ( i. element) ) {
return index;
}
index++ ;
}
}
return - 1 ;
}
@Override
public void clear ( ) {
size = 0 ;
first = null;
last = null;
}
private void checkIndex ( int index) {
if ( index < 0 || index > size) {
throw new IndexOutOfBoundsException ( "索引越界" ) ;
}
}
private void checkPostionIndex ( int index) {
if ( ! isPostionIndex ( index) ) {
throw new IndexOutOfBoundsException ( ": Index: " + index + ", Size: " + size) ;
}
}
private boolean isPostionIndex ( int index) {
return index >= 0 && index <= size;
}
private void checkElementIndex ( int index) {
if ( ! isElementIndex ( index) ) {
throw new IndexOutOfBoundsException ( ": Index: " + index + ", Size: " + size) ;
}
}
private boolean isElementIndex ( int index) {
return index >= 0 && index < size;
}
public String toString ( ) {
if ( size == 0 ) {
return "[]" ;
}
StringBuilder sb = new StringBuilder ( ) . append ( "[" ) ;
Node x = first;
for ( Node i = x; i != null; i = i. next) {
sb. append ( i. element) ;
if ( i. next == null) {
return sb. append ( "]" ) . toString ( ) ;
}
sb. append ( "," ) ;
}
return sb. toString ( ) ;
}
}