View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.trinidad.component;
20  
21  import java.util.Iterator;
22  
23  /** not thread safe, though it could be as thread-safe as the underlying Iterators at a slight cost to performance and size */
24  public final class CompositeIterator<T> implements Iterator<T>
25  {
26    public CompositeIterator(Iterator<T> firstIterator, Iterator<T> secondIterator)
27    {
28      if (firstIterator == null)
29        throw new NullPointerException();
30  
31      if (secondIterator == null)
32        throw new NullPointerException();
33  
34      // determine whether we have another element aggressively
35      _hasNext = firstIterator.hasNext();
36  
37      if (_hasNext)
38      {
39        _firstIterator = firstIterator;
40        _secondIterator = secondIterator;
41      }
42      else
43      {
44        // first iterator is empty so shift up the second iterator
45        _firstIterator = secondIterator;
46        _secondIterator = null;
47        _hasNext = secondIterator.hasNext();
48      }
49    }
50  
51    public boolean hasNext()
52    {
53      // return cached value
54      return _hasNext;
55    }
56  
57    public T next()
58    {
59      // remove is only valid after next(), so assign it here.
60      // This also deals with issue where next() is called on the
61      // last element of the firstIterator and then remove is called
62      // this way the removeIterator correctly lags shifting from the
63      // old _firstIterator to the _secondIterator
64      _removeIterator = _firstIterator;
65  
66      T nextValue = _firstIterator.next();
67      
68      _hasNext = _firstIterator.hasNext();
69  
70      if (!_hasNext && (_secondIterator != null))
71      {
72        // firsIterator is done, so shift up the secondIterator
73        _firstIterator = _secondIterator;
74        _secondIterator = null;
75        _hasNext = _firstIterator.hasNext();
76      }
77  
78      return nextValue;
79    }
80  
81    public void remove()
82    {
83      if (_removeIterator == null)
84        throw new IllegalStateException();
85  
86      _removeIterator.remove();
87    }
88  
89    private Iterator<T> _firstIterator;
90    private Iterator<T> _secondIterator;
91    private Iterator<T> _removeIterator;
92    private boolean _hasNext;
93  }