All Downloads are FREE. Search and download functionalities are using the official Maven repository.

xapi.collect.impl.AbstractLinkedList Maven / Gradle / Ivy

Go to download

Everything needed to run a comprehensive dev environment. Just type X_ and pick a service from autocomplete; new dev modules will be added as they are built. The only dev service not included in the uber jar is xapi-dev-maven, as it includes all runtime dependencies of maven, adding ~4 seconds to build time, and 6 megabytes to the final output jar size (without xapi-dev-maven, it's ~1MB).

The newest version!
/**
 *
 */
package xapi.collect.impl;

import java.util.Iterator;

/**
 * A simple base class for implementing linked lists. The default implementation
 * is uni-directional (a {@link SimpleStack}), but it leaves room to be extended
 * into a doubly-linked list ({@link SimpleLinkedList}).
 *
 * @author "James X. Nelson ([email protected])"
 *
 */
public abstract class AbstractLinkedList, L extends AbstractLinkedList>
  implements Iterable {

  protected static class Node> {
    protected N next;
    protected T value;

    @Override
    public String toString() {
      return "Node [" + value + "]";
    }

  }

  protected final class NodeIterator implements Iterator {
    private N next = head.next;

    @Override
    public boolean hasNext() {
      return next != null;
    }

    @Override
    public T next() {
      try {
        return next.value;
      } finally {
        next = next.next;
      }
    }

    @Override
    public void remove() {
      throw new UnsupportedOperationException();
    }

  }
  N tail;
  final N head = tail = newNode(null);

  @SuppressWarnings("unchecked")
  public synchronized L add(final T item) {
    final N node = newNode(item);
    node.value = item;
    tail.next = node;
    onAdd(tail, node);
    tail = node;
    return (L) this;
  }

  public synchronized void clear() {
    (tail = head).next = null;
  }

  /**
   * Forcibly takes all elements from one stack and attaches them to this.
   * 

* This method destroys the stack you send to it. *

* Note that it is threadsafe with respect to the stack consuming, but not so * with the stack being consumed (deadlock's no fun). *

* Since you are destroying it anyway, chances are the stack is getting gc'd * as soon as it pops off the, well... [execution] stack! *

* This method is destructive because you _really_ don't want to allow cyclic * references when two stacks reference each other. * * @return */ @SuppressWarnings("unchecked") public synchronized L consume( final L other) { onAdd(tail, other.head); if ((tail.next = other.head.next) != null) { tail = other.tail; } (other.tail = other.head).next = null; return (L) this; } public T head() { return head.next == null ? null : head.next.value; } public boolean isEmpty() { return head == tail; } @Override public Iterator iterator() { return new NodeIterator(); } /** * toStrings the items in the stack with the specified separator */ public String join(final String separator) { final StringBuilder b = new StringBuilder(); final Iterator iter = iterator(); if (iter.hasNext()) { b.append(iter.next()); } while (iter.hasNext()) { b.append(separator).append(iter.next()); } return b.toString(); } public T tail() { return tail.value; } @Override public String toString() { return getClass().getName() + " [ " + join(", ") + " ]"; } /** * Called whenever a node is created, including the {@link #head} node. * * @param item * -> The item that will become the value for this node. Expect a * null for the head node. */ protected abstract N newNode(T item); protected void onAdd(final N previous, final N next) { } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy