1 19 20 package org.netbeans.modules.java.source.util; 21 22 import java.util.ArrayList ; 23 import java.util.Arrays ; 24 import java.util.BitSet ; 25 import java.util.Collection ; 26 import java.util.Collections ; 27 import java.util.Comparator ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import java.util.NoSuchElementException ; 31 33 38 public final class Iterators { 39 40 private static final String NULL_AS_PARAMETER_MESSAGE = "Iterator(s) passed in as parameter must NOT be null."; 42 43 private Iterators() {} 44 45 public static <T> Iterator <T> empty() { 46 return new EmptyIterator(); 47 } 48 49 public static <T> Iterator <T> unmodifiable( Iterator <T> iterator ) { 50 return new UnmodifiableIterator<T>( iterator ); 51 } 52 53 public static <T> Iterator <T> chained( Iterator <T>... iterators ) { 54 return new ChainedIterator<T>( iterators ); 55 } 56 57 public static <T> Iterator <T> chained( Collection <Iterator <T>> iterators ) { 58 return new ChainedIterator<T>( iterators ); 59 } 60 61 public static <T> Iterator <T> colating( Iterator <? extends T>... iterators ) { 62 return new CollatingIterator<T>( iterators ); 63 } 64 65 public static <T> Iterator <T> colating( Comparator <? super T> comparator, Iterator <? extends T>... iterators ) { 66 return new CollatingIterator<T>( comparator, iterators ); 67 } 68 69 public static <T,P> Iterator <T> translating( Iterator <? extends P> delegate, Factory<? extends T,P> factory ) { 70 return new TranslatingIterator<T,P>( delegate, factory ); 71 } 72 73 76 public static <T> Iterable <T> toIterable( Iterator <T> iterator ) { 77 return new IteratorIterable( iterator ); 78 } 79 80 81 public static <T,P> Iterable <T> translating (final Iterable <? extends P> delegate, final Factory<? extends T,P> factory) { 82 return new TranslatingIterable (delegate, factory); 83 } 84 85 87 88 private static class TranslatingIterable<T,P> implements Iterable <T> { 89 90 final Iterable <? extends P> delegate; 91 final Factory<? extends T,P> factory; 92 93 94 public TranslatingIterable (final Iterable <? extends P> delegate, final Factory<? extends T,P> factory) { 95 assert delegate != null; 96 assert factory != null; 97 this.delegate = delegate; 98 this.factory = factory; 99 } 100 101 public Iterator <T> iterator() { 102 return translating(this.delegate.iterator(),this.factory); 103 } 104 } 105 106 private static class EmptyIterator<T> implements Iterator <T> { 107 108 public void remove() { 109 throw new UnsupportedOperationException ( "Can't remove elements from emptu iterator"); 110 } 111 112 public boolean hasNext() { 113 return false; 114 } 115 116 public T next() { 117 throw new NoSuchElementException ( "Empty Iterator has no elements"); 118 } 119 120 } 121 122 private static class TranslatingIterator<T,P> implements Iterator <T> { 123 124 private Iterator <? extends P> delegate; 125 private Factory<? extends T,P> factory; 126 127 public TranslatingIterator( Iterator <? extends P> delegate, Factory<? extends T,P> factory ) { 128 if ( delegate == null ) { 129 throw new IllegalArgumentException ( NULL_AS_PARAMETER_MESSAGE ); 130 } 131 this.delegate = delegate; 132 this.factory = factory; 133 } 134 135 public void remove() { 136 delegate.remove(); 137 } 138 139 public T next() { 140 return factory.create( delegate.next() ); 141 } 142 143 public boolean hasNext() { 144 return delegate.hasNext(); 145 } 146 147 } 148 149 150 private static class UnmodifiableIterator<T> implements Iterator <T> { 151 152 private Iterator <T> delegate; 153 154 public UnmodifiableIterator( Iterator <T> delegate ) { 155 if ( delegate == null ) { 156 throw new IllegalArgumentException ( NULL_AS_PARAMETER_MESSAGE ); 157 } 158 this.delegate = delegate; 159 } 160 161 public void remove() { 162 throw new UnsupportedOperationException (); 163 } 164 165 public T next() { 166 return delegate.next(); 167 } 168 169 public boolean hasNext() { 170 return delegate.hasNext(); 171 } 172 173 } 174 175 private static class ChainedIterator<E> implements Iterator <E> { 176 177 178 protected final List <Iterator <E>> iteratorChain = 179 new ArrayList <Iterator <E>>(); 180 181 182 protected int currentIteratorIndex = 0; 183 184 185 protected Iterator <E> currentIterator = null; 186 187 192 protected Iterator <E> lastUsedIterator = null; 193 194 198 protected boolean isLocked = false; 199 200 201 210 public ChainedIterator(final Iterator <E>... iterators) { 211 for (Iterator <E> iterator : iterators) { 212 if ( iterator == null ) { 213 throw new IllegalArgumentException ( NULL_AS_PARAMETER_MESSAGE ); 214 } 215 iteratorChain.add(iterator); 216 } 217 } 218 219 228 public ChainedIterator(final Collection <Iterator <E>> iterators) { 229 for (Iterator <E> iterator : iterators) { 230 if ( iterator == null ) { 231 throw new IllegalArgumentException ( NULL_AS_PARAMETER_MESSAGE ); 232 } 233 iteratorChain.add(iterator); 234 } 235 } 236 237 240 246 public int size() { 247 return iteratorChain.size(); 248 } 249 250 254 protected void updateCurrentIterator() { 255 if (currentIterator == null) { 256 if (iteratorChain.isEmpty()) { 257 currentIterator = Collections.<E>emptyList().iterator(); 259 } else { 260 currentIterator = iteratorChain.get(0); 261 } 262 lastUsedIterator = currentIterator; 265 } 266 267 while (currentIterator.hasNext() == false && 268 currentIteratorIndex < iteratorChain.size() - 1) { 269 currentIteratorIndex++; 270 currentIterator = iteratorChain.get(currentIteratorIndex); 271 } 272 } 273 274 277 283 public boolean hasNext() { 284 updateCurrentIterator(); 285 lastUsedIterator = currentIterator; 286 287 return currentIterator.hasNext(); 288 } 289 290 298 public E next() { 299 updateCurrentIterator(); 300 lastUsedIterator = currentIterator; 301 302 return currentIterator.next(); 303 } 304 305 320 public void remove() { 321 updateCurrentIterator(); 322 323 lastUsedIterator.remove(); 324 } 325 326 327 } 328 329 330 331 private static class CollatingIterator<E> implements Iterator <E> { 332 333 336 337 private Comparator <? super E> comparator = null; 338 339 340 private List <Iterator <? extends E>> iterators = null; 341 342 343 private List <E> values = null; 344 345 346 private BitSet valueSet = null; 347 348 352 private int lastReturned = -1; 353 354 357 358 public CollatingIterator( Iterator <? extends E>... iterators) { 359 this.iterators = Arrays.asList( iterators ); 360 } 361 362 public CollatingIterator( Comparator <? super E> comp, 363 Iterator <? extends E>... iterators) { 364 this.iterators = Arrays.asList( iterators ); 365 this.comparator = comp; 366 } 367 368 371 376 public boolean hasNext() { 377 start(); 378 return anyValueSet(valueSet) || anyHasNext(iterators); 379 } 380 381 388 public E next() throws NoSuchElementException { 389 if (hasNext() == false) { 390 throw new NoSuchElementException (); 391 } 392 int leastIndex = least(); 393 if (leastIndex == -1) { 394 throw new NoSuchElementException (); 395 } else { 396 E val = values.get(leastIndex); 397 clear(leastIndex); 398 lastReturned = leastIndex; 399 return val; 400 } 401 } 402 403 410 public void remove() { 411 if (lastReturned == -1) { 412 throw new IllegalStateException ("No value can be removed at present"); 413 } 414 Iterator <? extends E> it = iterators.get(lastReturned); 415 it.remove(); 416 } 417 418 421 424 private void start() { 425 if (values == null) { 426 values = new ArrayList <E>(iterators.size()); 427 valueSet = new BitSet (iterators.size()); 428 for (int i = 0; i < iterators.size(); i++) { 429 values.add(null); 430 valueSet.clear(i); 431 } 432 } 433 } 434 435 444 private boolean set(final int i) { 445 Iterator <? extends E> it = iterators.get(i); 446 if (it.hasNext()) { 447 values.set(i, it.next()); 448 valueSet.set(i); 449 return true; 450 } else { 451 values.set(i, null); 452 valueSet.clear(i); 453 return false; 454 } 455 } 456 457 461 private void clear(final int i) { 462 values.set(i, null); 463 valueSet.clear(i); 464 } 465 466 472 private void checkNotStarted() throws IllegalStateException { 473 if (values != null) { 474 throw new IllegalStateException ( 475 "Can't do that after next or hasNext has been called."); 476 } 477 } 478 479 485 private int least() { 486 int leastIndex = -1; 487 E leastObject = null; 488 for (int i = 0; i < values.size(); i++) { 489 if (valueSet.get(i) == false) { 490 set(i); 491 } 492 if (valueSet.get(i)) { 493 if (leastIndex == -1) { 494 leastIndex = i; 495 leastObject = values.get(i); 496 } else { 497 E curObject = values.get(i); 498 if (comparator.compare(curObject,leastObject) < 0) { 499 leastObject = curObject; 500 leastIndex = i; 501 } 502 } 503 } 504 } 505 return leastIndex; 506 } 507 508 512 private boolean anyValueSet(final BitSet set) { 513 for (int i = 0; i < set.size(); i++) { 514 if (set.get(i)) { 515 return true; 516 } 517 } 518 return false; 519 } 520 521 525 private boolean anyHasNext(final List <Iterator <? extends E>> iters) { 526 for (Iterator <? extends E> it: iters) { 527 if (it.hasNext()) { 528 return true; 529 } 530 } 531 return false; 532 } 533 } 534 535 private static class IteratorIterable<T> implements Iterable <T> { 536 537 private Iterator <T> iterator; 538 539 public IteratorIterable( Iterator <T> iterator ) { 540 if ( iterator == null ) { 541 throw new IllegalArgumentException ( NULL_AS_PARAMETER_MESSAGE ); 542 } 543 this.iterator = iterator; 544 } 545 546 public Iterator <T> iterator() { 547 return iterator; 548 } 549 550 } 551 552 } 553 | Popular Tags |