import java.util.Iterator; /** * A list of massive objects implemented as a linked list. * The number of elements of the list is not limited. */ public class MassiveLinkedList implements MassiveIterable { private int size = 0; private Item first; private Item last; /** * Initializes 'this' as an empty list. */ public MassiveLinkedList() { first = null; last = null; } /** * Initializes 'this' as an independent copy of the specified list 'list'. * Calling methods of this list will not affect the specified list 'list' * and vice versa. * Precondition: list != null. */ public MassiveLinkedList(BodyLinkedList list) { this.size = 0; for (Body b : list) { this.addLast(b); } } /** * Inserts the specified element 'body' at the beginning of this list. */ public void addFirst(Massive body) { if (first == null) { first = new Item(body); last = first; } else { first.setPrev(new Item(body)); first = first.prev; } size++; } /** * Appends the specified element 'body' to the end of this list. */ public void addLast(Massive body) { if (last == null) { last = new Item(body); first = last; } else { last.setNext(new Item(body)); last = last.next; } size++; } /** * Returns the last element in this list. * Returns 'null' if the list is empty. */ public Massive getLast() { return (last != null) ? last.body : null; } /** * Returns the first element in this list. * Returns 'null' if the list is empty. */ public Massive getFirst() { return (first != null) ? first.body : null; } /** * Retrieves and removes the first element in this list. * Returns 'null' if the list is empty. */ public Massive pollFirst() { if (first == null) { return null; } Massive m = first.body; first = first.next; if (first != null) first.setPrev(null); size--; return m; } /** * Retrieves and removes the last element in this list. * Returns 'null' if the list is empty. */ public Massive pollLast() { if (last == null) { return null; } Massive m = last.body; last = last.prev; if (last != null) last.setNext(null); size--; return m; } /** * Inserts the specified element at the specified position in this list. * Precondition: i >= 0 && i <= size(). */ public void add(int i, Massive m) { if (first == null || i == 0) { addFirst(m); return; } else if (i == size) { addLast(m); return; } Item item = first; for (int j = 0; j < i; j++) { item = item.next; } item.prev.setNext(new Item(m)); item.setPrev(item.prev.next); size++; } /** * Returns the element at the specified position in this list. * Precondition: i >= 0 && i < size(). */ public Massive get(int i) { Item item; if (i < size / 2) { item = first; for (int j = 0; j < i; j++) { item = item.next; } } else { item = last; for (int j = size - 1; j > i; j--) { item = item.prev; } } return item.body; } /** * Returns 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(Massive m) { if (first == null) { return -1; } Item item = first; for (int i = 0; i < size; i++, item = item.next) { if (item.body.equals(m)) return i; } return -1; } /** * Returns the number of elements in this list. */ public int size() { return size; } @Override public MassiveIterator iterator() { return new MassiveIterator() { Item ptr = first; boolean yieldedFirst = false; @Override public boolean hasNext() { return ptr != null && (!yieldedFirst || ptr.next != null); } @Override public Massive next() { if (!yieldedFirst) { yieldedFirst = true; } else { ptr = ptr.next; } return ptr.body; } }; } private static class Item { private final Massive body; private Item prev; private Item next; public Item(Massive body) { this.body = body; this.prev = null; this.next = null; } public void setPrev(Item prev) { this.prev = prev; if (prev != null) prev.next = this; } public void setNext(Item next) { this.next = next; if (next != null) next.prev = this; } } }