001: /******************************************************************
002: * File: UniqueExtendedIterator.java
003: * Created by: Dave Reynolds
004: * Created on: 28-Jan-2003
005: *
006: * (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
007: * [See end of file]
008: * $Id: UniqueExtendedIterator.java,v 1.16 2008/01/02 12:07:36 andy_seaborne Exp $
009: *****************************************************************/package com.hp.hpl.jena.util.iterator;
010:
011: import java.util.*;
012:
013: /**
014: * A variant on the closable/extended iterator that filters out
015: * duplicate values. There is one complication that the value
016: * which filtering is done on might not be the actual value
017: * to be returned by the iterator.
018: *
019: * @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
020: * @version $Revision: 1.16 $ on $Date: 2008/01/02 12:07:36 $
021: */
022: public class UniqueExtendedIterator extends WrappedIterator {
023:
024: /** The set of objects already seen */
025: protected HashSet seen = new HashSet();
026:
027: /** One level lookahead */
028: protected Object next = null;
029:
030: /**
031: * Constructor. Note the use of {@link #create} as reliable means of
032: * creating a unique iterator without double-wrapping iterators that
033: * are already unique iterators.
034: */
035: public UniqueExtendedIterator(Iterator underlying) {
036: super (underlying, true);
037: }
038:
039: /**
040: * Factory method for generating an iterator that is guaranteed
041: * only to return one instance of every result from the wrapped
042: * iterator <code>it</code>.
043: * @param it An iterator to wrap
044: * @return A iterator that returns the elements of the wrapped
045: * iterator exactly once. If <code>it</code> is already a unique
046: * extended iteator, it is not further wrapped.
047: */
048: public static ExtendedIterator create(Iterator it) {
049: return (it instanceof UniqueExtendedIterator) ? ((UniqueExtendedIterator) it)
050: : new UniqueExtendedIterator(it);
051: }
052:
053: /**
054: * Fetch the next object to be returned, only if not already seen.
055: * Subclasses which need to filter on different objects than the
056: * return values should override this method.
057: * @return the object to be returned or null if the object has been filtered.
058: */
059: protected Object nextIfNew() {
060: Object value = super .next();
061: return seen.add(value) ? value : null;
062: }
063:
064: /**
065: * @see Iterator#hasNext()
066: */
067: public boolean hasNext() {
068: while (next == null && super .hasNext())
069: next = nextIfNew();
070: return next != null;
071: }
072:
073: /**
074: * @see Iterator#next()
075: */
076: public Object next() {
077: ensureHasNext();
078: Object result = next;
079: next = null;
080: return result;
081: }
082: }
083:
084: /*
085: * (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
086: * All rights reserved.
087: *
088: * Redistribution and use in source and binary forms, with or without
089: * modification, are permitted provided that the following conditions
090: * are met:
091: * 1. Redistributions of source code must retain the above copyright
092: * notice, this list of conditions and the following disclaimer.
093: * 2. Redistributions in binary form must reproduce the above copyright
094: * notice, this list of conditions and the following disclaimer in the
095: * documentation and/or other materials provided with the distribution.
096: * 3. The name of the author may not be used to endorse or promote products
097: * derived from this software without specific prior written permission.
098: *
099: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
100: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
101: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
102: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
103: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
104: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
105: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
106: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
107: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
108: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
109: */
|