package com.test.tmp; public interface IList<E> { boolean add(E e); int getSize(); E get(int index); E getFirst(); E getLast(); boolean remove(int index); boolean remove(E e); boolean contains(E e); void reverse(); }
Implementation class
package com.test.tmp; import java.util.function.Consumer; /** * Doubly linked list, not thread safe * @author yq * * @param <E> */ public class LinkedList<E> implements IList<E>{ /** * The first element of the linked list */ private Node first; /** * last element */ private Node last; /** * number of elements */ private int size; /** * Doubly linked list node structure, used to construct node elements */ private class Node { //node element value E item; //The predecessor node of the node Node pre; //The back straight node of the node Node next; /** * Node constructor, used to construct nodes */ public Node(Node pre, E item, Node next) { this.pre = pre; this.item = item; this.next = next; } } /** * */ @Override public boolean add(E e) { final Node copyLast = last; //The added element is always at the end, and the last next is always null final Node newNode = new Node(copyLast, e, null); //The newly added element must be the last element last = newNode; /* * If the last element is null, the linked list is empty, add the first element. */ if(copyLast == null) { first = newNode; } else { copyLast.next = newNode; } //Add an element, add 1 to the length of the linked list size++; return true; } @Override public int getSize() { return size; } @Override public E get(int index) { final Node indexNode = indexOf(index); return indexNode.item; } @Override public E getFirst() { return first.item; } @Override public E getLast() { return last.item; } /** * Return the corresponding element value according to the subscript index of the array element * @param index index number, the minimum is 0, the maximum is size-1 */ @Override public boolean remove(int index) { if(index < 0) { throw new IllegalArgumentException(); } if(index == 0) { first = first.next; first.pre = null; size--; return true; } if(index == size -1) { last = last.pre; last.next = null; size--; return true; } final Node indexNode = indexOf(index); final Node indexPre = indexNode.pre; final Node indexNext = indexNode.next; indexPre.next = indexNext; indexNext.pre = indexPre; size--; return true; } private Node indexOf(int index) { Node next = first; for(int i = 0 ; i < index; i++) { next = next.next; } return next; } @Override public boolean remove(E e) { if(first == null || last == null) { return false; } final Node find = find(e); if(find == null) { return false; } Node findPre = find.pre; Node findNext = find.next; if(findNext != null) { findPre.next = findNext; findNext.pre = findPre; } else { last = findPre; last.next = null; } size--; return true; } private Node find(E e) { Node findNode = null; Node next = first; for(int i = 0 ; i < size ; i++) { if(next == null) { return next; } if(next.item != null && next.item.equals(e)) { findNode = next; break; } else if(next.item == null && e == null){ findNode = next; break; } next = next.next; } return findNode; } @Override public boolean contains(E e) { boolean founded = false; if(size < 1) { return false; } Node next = first; for(int i = 0 ; i < size; i++) { if(next == null) { return false; } if(next.item != null && next.item.equals(e)) { founded = true; break; } else if(next.item == null && e == null){ founded = true; break; } next = next.next; } return founded; } @Override public void reverse() { first = reverse(first); } /** * Reverse the linked list recursively * @param first * @return */ private Node reverse(Node first) { if(first == null) { return null; } if(first.next == null) { return first; } Node second = first.next; Node rest = reverse(second); second.next = first; first.next = null; return rest; } class Iterator implements java.util.Iterator<E> { @Override public boolean hasNext() { return false; } @Override public E next() { return null; } @Override public void remove() { } @Override public void forEachRemaining(Consumer<? super E> action) { } } }