Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/rxm.git

Simplified divergent list. Added iterator that allows looking ahead to the next element.

AuthorDave Jarvis <email>
Date2015-03-27 21:30:35 GMT-0700
Commit83e78af3bd7f775ac9faefa89a316156d175d70c
Parent31c2e4e
source/java/com/whitemagicsoftware/rxm/DivergentList.java
package com.whitemagicsoftware.rxm;
-import java.util.LinkedList;
+import java.util.ArrayList;
+import java.util.Iterator;
import static java.lang.System.out;
/**
* Provides the ability to determine the index whereat two lists begin
* to differ in content. Both this list and the list to comapre against
- * must not contain null strings.
+ * must not contain null objects.
*/
-public class DivergentList extends LinkedList<String> {
+public class DivergentList<E> extends ArrayList<E> {
/**
- * Answers the index at which the strings within this list differ from
- * the strings in the given list.
+ * Determines the index at which the objects within this list differ from
+ * the objects in the given list.
*
* @param list The list to compare against.
*
- * @return -1 if the lists have no common strings.
+ * @return -1 if the lists have no equal objects.
*/
- public int diverges( DivergentList list ) {
+ public int diverges( DivergentList<E> list ) {
int index = -1;
+ boolean smaller = list.size() < this.size();
- if( valid( list ) && valid( this ) ) {
- while( equals( list, ++index ) );
- }
+ Iterator<E> iFew = (smaller ? list : this).iterator();
- return index;
- }
+ for( E e : (smaller ? this : list) ) {
+ index++;
- /**
- * Answers whether the element at the given index is the same in both
- * lists. This is not null-safe.
- *
- * @param list The list to compare against this list.
- * @return true The lists have the same string at the given index.
- */
- private boolean equals( DivergentList list, int index ) {
- return (index < size()) && (index < list.size()) &&
- get( index ).equals( list.get( index ) );
- }
+ if( !(iFew.hasNext() && e.equals( iFew.next() )) ) {
+ break;
+ }
+ }
- /**
- * Answers whether the given element path contains at least one
- * string.
- *
- * @param list The list that must have at least one string.
- * @return true The list has at least one element.
- */
- private boolean valid( DivergentList list ) {
- return list != null && list.size() > 0;
+ return index;
}
/**
- * Test the functionality.
+ * Testing.
*/
public static void main( String args[] ) {
- DivergentList list1 = new DivergentList();
- list1.addLast( "name" );
- list1.addLast( "first" );
- list1.addLast( "middle" );
- list1.addLast( "last" );
- list1.addLast( "maiden" );
+ DivergentList<String> list1 = new DivergentList<String>();
+ list1.add( "name" );
+ list1.add( "first" );
+ list1.add( "middle" );
+ list1.add( "last" );
+ list1.add( "maiden" );
- DivergentList list2 = new DivergentList();
- list2.addLast( "name" );
- list2.addLast( "middle" );
- list2.addLast( "last" );
+ DivergentList<String> list2 = new DivergentList<String>();
+ list2.add( "name" );
+ list2.add( "middle" );
+ list2.add( "last" );
// Prints 1
out.println( list2.diverges( list1 ) );
list1.clear();
- list1.addLast( "name" );
- list1.addLast( "middle" );
- list1.addLast( "last" );
+ list1.add( "name" );
+ list1.add( "middle" );
+ list1.add( "last" );
list2.clear();
- list2.addLast( "name" );
- list2.addLast( "middle" );
- list2.addLast( "last" );
- list2.addLast( "maiden" );
- list2.addLast( "honorific" );
+ list2.add( "name" );
+ list2.add( "middle" );
+ list2.add( "last" );
+ list2.add( "maiden" );
+ list2.add( "honorific" );
// Prints 3
out.println( list1.diverges( list2 ) );
- list2.addFirst( "name" );
+ list2.add( 0, "name" );
// Prints 1
+ out.println( list1.diverges( list2 ) );
+
+ list1.clear();
+ list1.add( "name" );
+ list1.add( "middle" );
+ list1.add( "last" );
+ list1.add( "maiden" );
+ list1.add( "honorific" );
+
+ list2.clear();
+ list2.add( "name" );
+ list2.add( "middle" );
+ list2.add( "last" );
+ list2.add( "maiden" );
+ list2.add( "honorific" );
+
+ // Prints 4
out.println( list1.diverges( list2 ) );
}
source/java/com/whitemagicsoftware/rxm/PeekingIterator.java
+package com.whitemagicsoftware.rxm;
+
+import java.util.Iterator;
+
+/**
+ * Provides look-ahead abilities for an iterator.
+ */
+public class PeekingIterator<E> implements Iterator<E> {
+ private final Iterator<? extends E> iterator;
+
+ private boolean peekNext;
+ private E elementNext;
+
+ /**
+ * Constructs an iterator with look-ahead abilities for a given iterator.
+ *
+ * @param iterator The iterator to adorn with look-ahead abilities.
+ */
+ public PeekingIterator( Iterator<? extends E> iterator ) {
+ this.iterator = iterator;
+ }
+
+ /**
+ * Answers whether there are more elements to iterate.
+ *
+ * @return true There is another element to iterate.
+ */
+ @Override
+ public boolean hasNext() {
+ return getPeekedNext() || getIterator().hasNext();
+ }
+
+ /**
+ * Returns the next element in the list. If peek was called before
+ * this method, then this method will return the peeked value.
+ *
+ * @return The next element.
+ */
+ @Override
+ public E next() {
+ return getPeekedNext() ? reset() : iteratorNext();
+ }
+
+ /**
+ * Resets the peeked next state to false and sets the next peeked element
+ * to null.
+ *
+ * @return The peeked next element.
+ */
+ private E reset() {
+ E result = getElementNext();
+ setPeekedNext( false );
+ setElementNext( null );
+
+ return result;
+ }
+
+ /**
+ * Attempts to remove the currently iterated element. This will throw
+ * an exception when trying to remove an element after peeking. This is
+ * because next() has already been called on the underlying iterator.
+ */
+ @Override
+ public void remove() {
+ if( getPeekedNext() ) {
+ throw new UnsupportedOperationException( "No removing after peeking." );
+ }
+
+ getIterator().remove();
+ }
+
+ /**
+ * Returns the next element to iterate. Note that peeking prevents
+ * removal.
+ *
+ * @return The next element in the iterator's list.
+ */
+ public E peek() {
+ if( !getPeekedNext() ) {
+ setElementNext( iteratorNext() );
+ setPeekedNext( true );
+ }
+
+ return getElementNext();
+ }
+
+ private E iteratorNext() {
+ return getIterator().next();
+ }
+
+ private E getElementNext() {
+ return this.elementNext;
+ }
+
+ private void setElementNext( E elementNext ) {
+ this.elementNext = elementNext;
+ }
+
+ private boolean getPeekedNext() {
+ return this.peekNext;
+ }
+
+ private void setPeekedNext( boolean peekNext ) {
+ this.peekNext = peekNext;
+ }
+
+ private Iterator<? extends E> getIterator() {
+ return this.iterator;
+ }
+}
+
source/java/com/whitemagicsoftware/rxm/xml/SelectTree.java
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
+import com.whitemagicsoftware.rxm.PeekingIterator;
import com.whitemagicsoftware.rxm.Tree;
sb.append( indent ).append( start( tree ) );
- for( Tree<Context> branch : tree.getBranches() ) {
+ // Immediately previous column map (if any).
+ ColumnMapContext priorColumnMap = null;
+ List<Tree<Context>> branches = tree.getBranches();
+ PeekingIterator<Tree<Context>> i = createIterator( branches.iterator() );
+
+ while( i.hasNext() ) {
+ Tree<Context> branch = i.next();
Context context = branch.getPayload();
if( context instanceof AttributeMapContext ) {
- AttributeMapContext ctx = (AttributeMapContext)context;
Tree<Context> parent = branch.getParent();
+ AttributeMapContext ctx = (AttributeMapContext)context;
ctx.hasPrecedingPayload( hasPrecedingPayload( parent, ctx ) );
ctx.hasFollowingPayload( hasFollowingPayload( parent, ctx ) );
}
else if( context instanceof ColumnMapContext ) {
- // nothing.
+ if( i.hasNext() ) {
+ Tree<Context> next = i.peek();
+
+ Context nextContext = next.getPayload();
+
+ if( nextContext instanceof ColumnMapContext ) {
+ System.out.println( "NEXT!" + nextContext.toString() );
+ }
+ }
+
+ /*
+ if( priorColumnMap != null ) {
+ ((ColumnMapContext)context).setPrevious( priorColumnMap );
+ }
+
+ priorColumnMap = context;
+ */
}
protected String stop( Context payload ) {
return payload.getStop();
+ }
+
+
+ private PeekingIterator<Tree<Context>> createIterator(
+ Iterator<Tree<Context>> iterator ) {
+ return new PeekingIterator<Tree<Context>>( iterator );
}
Delta198 lines added, 55 lines removed, 143-line increase