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

com.mchange.util.impl.CircularList Maven / Gradle / Ivy

There is a newer version: 0.3.1
Show newest version
/*
 * Distributed as part of mchange-commons-java v.0.2.3
 *
 * Copyright (C) 2012 Machinery For Change, Inc.
 *
 * Author: Steve Waldman 
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 2.1, as 
 * published by the Free Software Foundation.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this software; see the file LICENSE.  If not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */


/*
 * This class modified from swaldman.util.CircularList,
 * originally written by Steve Waldman at the MIT Media Lab
 */
package com.mchange.util.impl;

import java.util.*;
import com.mchange.util.*;


/**
 * 

CircularList is a list class. Objects can be added * at the beginning or end; they may be enumerated through * forwards or backwards; they may be retrieved directly or * by index from the front or rear. CircularLists can also * be enumerated endlessly. If the list contains any elements at * all, an "unterminated" Enumeration will always claim to have * more elements... when it's done enumerating, it will start * over again. The default Enumeration is of the usual, * terminated variety, however.

* *

This class is a completely UNSYNCHRONIZED implementation * class. Synchronize on calls where necessary.

* */ public class CircularList extends Object implements Cloneable { CircularListRecord firstRecord; int size; public CircularList() { this.firstRecord = null; this.size = 0; } private void addElement(Object object, boolean first) { if (firstRecord == null) firstRecord = new CircularListRecord(object); else { CircularListRecord newRecord = new CircularListRecord(object, firstRecord.prev, firstRecord); firstRecord.prev.next = newRecord; firstRecord.prev = newRecord; if (first) firstRecord = newRecord; } ++size; } private void removeElement(boolean first) { if (size == 1) firstRecord = null; else { if (first) firstRecord = firstRecord.next; zap(firstRecord.prev); } --size; } private void zap(CircularListRecord record) { record.next.prev = record.prev; record.prev.next = record.next; } public void appendElement(Object object) {addElement(object, false);} public void addElementToFront(Object object) {addElement(object, true);} public void removeFirstElement() {removeElement(true);} public void removeLastElement() {removeElement(false);} public void removeFromFront(int count) { if (count > size) throw new IndexOutOfBoundsException(count + ">" + size); else for(int i = 0; i < count; ++i) removeElement(true); } public void removeFromBack(int count) { if (count > size) throw new IndexOutOfBoundsException(count + ">" + size); else for(int i = 0; i < count; ++i) removeElement(false); } public void removeAllElements() { size = 0; firstRecord = null; } public Object getElementFromFront(int index) { if (index >= size) throw new IndexOutOfBoundsException(index + ">=" + size); else { CircularListRecord finger = firstRecord; for (int i = 0; i < index; ++i) finger = finger.next; return finger.object; } } public Object getElementFromBack(int index) { if (index >= size) throw new IndexOutOfBoundsException(index + ">=" + size); else { CircularListRecord finger = firstRecord.prev; for (int i = 0; i < index; ++i) finger = finger.prev; return finger.object; } } public Object getFirstElement() { try {return firstRecord.object;} catch (NullPointerException e) {throw new IndexOutOfBoundsException("CircularList is empty.");} } public Object getLastElement() { try {return firstRecord.prev.object;} catch (NullPointerException e) {throw new IndexOutOfBoundsException("CircularList is empty.");} } public Enumeration elements(boolean forward, boolean terminated) {return new CircularListEnumeration(this, forward, terminated);} public Enumeration elements(boolean forward) {return elements(forward, true);} public Enumeration elements() {return elements(true, true);} public int size() {return size;} /** * Returns a shallow copy. The list is * cloned, but not the elements within it. */ public Object clone() { //this could be much more effeicient... CircularList out = new CircularList(); int len = this.size(); for (int i = 0; i < len; ++i) out.appendElement(this.getElementFromFront(i)); return out; } public static void main(String[] argv) { CircularList list = new CircularList(); list.appendElement("Hello"); list.appendElement("There"); list.appendElement("Joe."); for (Enumeration e = list.elements(); e.hasMoreElements();) System.out.println("x " + e.nextElement()); } } class CircularListEnumeration extends Object implements Enumeration { boolean forward; boolean terminated; boolean done; CircularListRecord startRecord; CircularListRecord lastRecord; CircularListEnumeration(CircularList list, boolean forward, boolean terminated) { if (list.firstRecord == null) this.done = true; else { this.done = false; this.forward = forward; this.terminated = terminated; this.startRecord = (forward ? list.firstRecord : list.firstRecord.prev); this.lastRecord = (forward ? startRecord.prev : startRecord); } } public boolean hasMoreElements() {return !done;} public Object nextElement() { if (done) throw new NoSuchElementException(); else { lastRecord = (forward ? lastRecord.next : lastRecord.prev); if (terminated && lastRecord == (forward ? startRecord.prev : startRecord)) done = true; return lastRecord.object; } } } class CircularListRecord { Object object; CircularListRecord next; CircularListRecord prev; CircularListRecord(Object object, CircularListRecord prev, CircularListRecord next) { this.object = object; this.prev = prev; this.next = next; } CircularListRecord(Object object) //for first record { this.object = object; this.prev = this; this.next = this; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy