Iterators.java revision 524:dcaa586ab756
1/* 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.xml.internal.xsom.impl.scd; 27 28import java.util.Iterator; 29import java.util.NoSuchElementException; 30import java.util.Set; 31import java.util.HashSet; 32import java.util.Collections; 33 34/** 35 * Various convenient {@link Iterator} implementations. 36 * @author Kohsuke Kawaguchi 37 */ 38public class Iterators { 39 40 static abstract class ReadOnly<T> implements Iterator<T> { 41 public final void remove() { 42 throw new UnsupportedOperationException(); 43 } 44 } 45 46 // we need to run on JDK 1.4 47 private static final Iterator EMPTY = Collections.EMPTY_LIST.iterator(); 48 49 public static <T> Iterator<T> empty() { 50 return EMPTY; 51 } 52 53 public static <T> Iterator<T> singleton(T value) { 54 return new Singleton<T>(value); 55 } 56 57 /** 58 * {@link Iterator} that returns a single (or no) value. 59 */ 60 static final class Singleton<T> extends ReadOnly<T> { 61 private T next; 62 63 Singleton(T next) { 64 this.next = next; 65 } 66 67 public boolean hasNext() { 68 return next!=null; 69 } 70 71 public T next() { 72 T r = next; 73 next = null; 74 return r; 75 } 76 } 77 78 /** 79 * {@link Iterator} that wraps another {@link Iterator} and changes its type. 80 */ 81 public static abstract class Adapter<T,U> extends ReadOnly<T> { 82 private final Iterator<? extends U> core; 83 84 public Adapter(Iterator<? extends U> core) { 85 this.core = core; 86 } 87 88 public boolean hasNext() { 89 return core.hasNext(); 90 } 91 92 public T next() { 93 return filter(core.next()); 94 } 95 96 protected abstract T filter(U u); 97 } 98 99 /** 100 * For each U, apply U->Iterator<T> function and then iterate all 101 * the resulting T. 102 */ 103 public static abstract class Map<T,U> extends ReadOnly<T> { 104 private final Iterator<? extends U> core; 105 106 private Iterator<? extends T> current; 107 108 protected Map(Iterator<? extends U> core) { 109 this.core = core; 110 } 111 112 public boolean hasNext() { 113 while(current==null || !current.hasNext()) { 114 if(!core.hasNext()) 115 return false; // nothing more to enumerate 116 current = apply(core.next()); 117 } 118 return true; 119 } 120 121 public T next() { 122 return current.next(); 123 } 124 125 protected abstract Iterator<? extends T> apply(U u); 126 } 127 128 /** 129 * Filter out objects from another iterator. 130 */ 131 public static abstract class Filter<T> extends ReadOnly<T> { 132 private final Iterator<? extends T> core; 133 private T next; 134 135 protected Filter(Iterator<? extends T> core) { 136 this.core = core; 137 } 138 139 /** 140 * Return true to retain the value. 141 */ 142 protected abstract boolean matches(T value); 143 144 public boolean hasNext() { 145 while(core.hasNext() && next==null) { 146 next = core.next(); 147 if(!matches(next)) 148 next = null; 149 } 150 151 return next!=null; 152 } 153 154 public T next() { 155 if(next==null) throw new NoSuchElementException(); 156 T r = next; 157 next = null; 158 return r; 159 } 160 } 161 162 /** 163 * Only return unique items. 164 */ 165 static final class Unique<T> extends Filter<T> { 166 private Set<T> values = new HashSet<T>(); 167 public Unique(Iterator<? extends T> core) { 168 super(core); 169 } 170 171 protected boolean matches(T value) { 172 return values.add(value); 173 } 174 } 175 176 /** 177 * Union of two iterators. 178 */ 179 public static final class Union<T> extends ReadOnly<T> { 180 private final Iterator<? extends T> first,second; 181 182 public Union(Iterator<? extends T> first, Iterator<? extends T> second) { 183 this.first = first; 184 this.second = second; 185 } 186 187 public boolean hasNext() { 188 return first.hasNext() || second.hasNext(); 189 } 190 191 public T next() { 192 if(first.hasNext()) return first.next(); 193 else return second.next(); 194 } 195 } 196 197 /** 198 * Array iterator. 199 */ 200 public static final class Array<T> extends ReadOnly<T> { 201 private final T[] items; 202 private int index=0; 203 public Array(T[] items) { 204 this.items = items; 205 } 206 207 public boolean hasNext() { 208 return index<items.length; 209 } 210 211 public T next() { 212 return items[index++]; 213 } 214 } 215} 216