List 接口
public interface List<E>{
int size();
boolean isEmpty();
void add(E element);
void add(int index,E element);
E remove(int index);
E set(int index,E element);
boolean contains(E element);
E get(int index);
int valueof(E element);
void clear();
String toString();
}
AbstractList 抽象类
public abstract class AbstractList<E> implements List<E> {
protected int size;
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public boolean contains(E element) {
return valueof(element) != -1;
}
@Override
public void add(E element) {
add(size,element);
}
}
单向链表
public class MyLinkedList<E> extends AbstractList<E> {
private Node<E> first;
private static class Node<E> {
Node<E> next;
E element;
public Node(Node next, E element) {
this.next = next;
this.element = element;
}
}
@Override
public void add(int index, E element) {
checkPositionIndex(index);
if (index == 0) {
first = new Node<>(first, element);
} else {
Node<E> pre = node(index - 1);
Node<E> next = pre.next;
pre.next = new Node<>(next, element);
}
size++;
}
private void checkPositionIndex(int index) {
if (!isPositionIndex(index)) {
throw new IndexOutOfBoundsException("IndexOutOfBoundsException:index " + index + ", size " + size);
}
}
private boolean isPositionIndex(int index) {
return index >= 0 && index <= size;
}
@Override
public E remove(int index) {
checkElementIndex(index);
Node<E> oldNode= first;
if(index==0){
first=first.next;
size--;
return oldNode.element;
}else {
Node<E> pre = node(index - 1);
oldNode = pre.next;
pre.next = oldNode.next;
size--;
return oldNode.element;
}
}
@Override
public E set(int index, E element) {
checkElementIndex(index);
Node<E> node = node(index);
E oldElement = node.element;
node.element = element;
return oldElement;
}
@Override
public E get(int index) {
checkElementIndex(index);
return node(index).element;
}
private void checkElementIndex(int index) {
if (!isElementIndex(index)) {
throw new IndexOutOfBoundsException("IndexOutOfBoundsException:index " + index + ", size " + size);
}
}
private boolean isElementIndex(int index) {
return index >= 0 && index < size;
}
private Node<E> node(int index) {
Node<E> x = first;
for (int i = 0; i < index; i++) {
x = x.next;
}
return x;
}
@Override
public int valueof(E element) {
Node x = first;
int index = 0;
if (element == null) {
while (x != null)
if (x.element == element) return index;
x = x.next;
index++;
} else {
while (x != null) {
if (element.equals(x.element)) return index;
x = x.next;
index++;
}
}
return -1;
}
@Override
public void clear() {
size = 0;
first = null;
}
@Override
public String toString() {
if (size == 0) {
return "[]";
}
StringBuilder sb = new StringBuilder();
sb.append("[");
Node x = first;
for (Node i = x; i!=null ; i=i.next) {
sb.append(i.element);
if(i.next==null){
sb.append("]");
}
sb.append(", ");
}
return sb.toString();
}
}
双向链表
public class MyLinkedList2<E> extends AbstractList<E> {
private Node<E> first;
private Node<E> last;
private static class Node<E> {
Node<E> pre;
Node<E> next;
E element;
public Node(Node pre, Node next, E element) {
this.pre = pre;
this.next = next;
this.element = element;
}
}
@Override
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size) {
linkLast(element);
} else {
linkBefore(element, node(index));
}
size++;
}
private void linkLast(E element) {
Node<E> l = last;
Node<E> newNode = new Node<>(l, null, element);
last = newNode;
if (l == null) {
first = newNode;
} else {
l.next = newNode;
}
}
private void linkBefore(E element, Node<E> node) {
Node<E> pre = node.pre;
Node<E> newNode = new Node<>(pre, node, element);
node.pre = newNode;
if (pre == null) {
first = newNode;
} else {
pre.next = newNode;
}
}
private void checkPositionIndex(int index) {
if (!isPositionIndex(index)) {
throw new IndexOutOfBoundsException("IndexOutOfBoundsException:index " + index + ", size " + size);
}
}
private boolean isPositionIndex(int index) {
return index >= 0 && index <= size;
}
@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){
next.pre=null;
first=next;
}else {
pre.next=next;
}
if(next==null){
last=pre;
}else {
next.pre=pre;
}
size--;
return node.element;
}
@Override
public E set(int index, E element) {
checkElementIndex(index);
Node<E> node = node(index);
E oldElement = node.element;
node.element = element;
return oldElement;
}
@Override
public E get(int index) {
checkElementIndex(index);
return node(index).element;
}
private void checkElementIndex(int index) {
if (!isElementIndex(index)) {
throw new IndexOutOfBoundsException("IndexOutOfBoundsException:index " + index + ", size " + size);
}
}
private boolean isElementIndex(int index) {
return index >= 0 && index < size;
}
private Node<E> node(int index) {
Node<E> x = first;
if (index <= size >> 1) {
for (int i = 0; i < index; i++) {
x = x.next;
}
} else {
x = last;
for (int i = size - 1; i > index; i--) {
x = x.pre;
}
}
return x;
}
@Override
public int valueof(E element) {
Node x = first;
int index = 0;
if (element == null) {
while (x != null)
if (x.element == element) return index;
x = x.next;
index++;
} else {
while (x != null) {
if (element.equals(x.element)) return index;
x = x.next;
index++;
}
}
return -1;
}
@Override
public void clear() {
size = 0;
first = null;
last = null;
}
@Override
public String toString() {
if (size == 0) {
return "[]";
}
StringBuilder sb = new StringBuilder();
sb.append("[");
Node x = first;
for (Node i = x; i != null; i = i.next) {
sb.append(i.element);
if (i.next == null) {
sb.append("]");
}
sb.append(", ");
}
return sb.toString();
}
}