001/** 002 * @author Francesco.Kriegel@gmx.de 003 */ 004package conexp.fx.core.collections; 005 006/* 007 * #%L 008 * Concept Explorer FX 009 * %% 010 * Copyright (C) 2010 - 2019 Francesco Kriegel 011 * %% 012 * This program is free software: you can redistribute it and/or modify 013 * it under the terms of the GNU General Public License as 014 * published by the Free Software Foundation, either version 3 of the 015 * License, or (at your option) any later version. 016 * 017 * This program is distributed in the hope that it will be useful, 018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 020 * GNU General Public License for more details. 021 * 022 * You should have received a copy of the GNU General Public 023 * License along with this program. If not, see 024 * <http://www.gnu.org/licenses/gpl-3.0.html>. 025 * #L% 026 */ 027 028import java.util.Iterator; 029import java.util.ListIterator; 030import java.util.NoSuchElementException; 031 032import com.google.common.base.Function; 033import com.google.common.base.Predicate; 034import com.google.common.collect.UnmodifiableIterator; 035import com.google.common.collect.UnmodifiableListIterator; 036 037public final class ListIterators { 038 039 public static final <E> ListIterator<E> empty() { 040 return new UnmodifiableListIterator<E>() { 041 042 public final boolean hasNext() { 043 return false; 044 } 045 046 public final E next() { 047 return null; 048 } 049 050 public final boolean hasPrevious() { 051 return false; 052 } 053 054 public final E previous() { 055 return null; 056 } 057 058 public final int nextIndex() { 059 return 0; 060 } 061 062 public final int previousIndex() { 063 return -1; 064 } 065 }; 066 } 067 068 public static final ListIterator<Integer> integers(final int size) { 069 return integers(0, size); 070 } 071 072 public static final ListIterator<Integer> integers(final int i, final int size) { 073 return new UnmodifiableListIterator<Integer>() { 074 075 private int j = i - 1; 076 077 public synchronized final boolean hasNext() { 078 return j < size - 1; 079 } 080 081 public synchronized final Integer next() { 082 if (!hasNext()) 083 throw new NoSuchElementException(); 084 return ++j; 085 } 086 087 public final boolean hasPrevious() { 088 return j > -1; 089 } 090 091 public final Integer previous() { 092 if (!hasPrevious()) 093 throw new NoSuchElementException(); 094 return j--; 095 } 096 097 public synchronized final int nextIndex() { 098 return j + 1; 099 } 100 101 public final int previousIndex() { 102 return j; 103 } 104 }; 105 } 106 107 public static final <E> UnmodifiableListIterator<E> unmodifiable(final ListIterator<E> it) { 108 if (it instanceof UnmodifiableListIterator) 109 return (UnmodifiableListIterator<E>) it; 110 return new UnmodifiableListIterator<E>() { 111 112 public final boolean hasNext() { 113 return it.hasNext(); 114 } 115 116 public final E next() { 117 return it.next(); 118 } 119 120 public final boolean hasPrevious() { 121 return it.hasPrevious(); 122 } 123 124 public final E previous() { 125 return it.previous(); 126 } 127 128 public final int nextIndex() { 129 return it.nextIndex(); 130 } 131 132 public final int previousIndex() { 133 return it.previousIndex(); 134 } 135 }; 136 } 137 138 public static final <T, E> ListIterator<E> 139 transform(final ListIterator<? extends T> it, final Function<? super T, E> f) { 140 return new UnmodifiableListIterator<E>() { 141 142 public final boolean hasNext() { 143 return it.hasNext(); 144 } 145 146 public final E next() { 147 return f.apply(it.next()); 148 } 149 150 public final boolean hasPrevious() { 151 return it.hasPrevious(); 152 } 153 154 public final E previous() { 155 return f.apply(it.previous()); 156 } 157 158 public final int nextIndex() { 159 return it.nextIndex(); 160 } 161 162 public final int previousIndex() { 163 return it.previousIndex(); 164 } 165 }; 166 } 167 168 public static final <E> ListIterator<E> filter(final ListIterator<? extends E> it, final Predicate<? super E> p) { 169 return filter(it, p, 0); 170 } 171 172 public static final <E> ListIterator<E> 173 filter(final ListIterator<? extends E> it, final Predicate<? super E> p, final int i) { 174 return new SimpleListIterator<E>(i) { 175 176 protected final E createNext() { 177 while (it.hasNext()) { 178 final E next = it.next(); 179 if (p.apply(next)) 180 return next; 181 } 182 return null; 183 } 184 185 protected final E createPrevious() { 186 while (it.hasPrevious()) { 187 final E prev = it.previous(); 188 if (p.apply(prev)) 189 return prev; 190 } 191 return null; 192 } 193 }; 194 } 195 196 public static final <E> ListIterator<E> 197 concat(final ListIterator<? extends E> it1, final ListIterator<? extends E> it2, final int i) { 198 return new SimpleListIterator<E>(i) { 199 200 protected final E createNext() { 201 if (it1.hasNext()) 202 return it1.next(); 203 if (it2.hasNext()) 204 return it2.next(); 205 return null; 206 } 207 208 protected final E createPrevious() { 209 if (it2.hasPrevious()) 210 return it2.previous(); 211 if (it1.hasPrevious()) 212 return it1.previous(); 213 return null; 214 } 215 }; 216 } 217 218 public static final <T, E> ListIterator<Pair<T, E>> 219 disjointUnion(final ListIterator<T> it1, final ListIterator<E> it2, final int i) { 220 return new SimpleListIterator<Pair<T, E>>(i) { 221 222 protected final Pair<T, E> createNext() { 223 if (it1.hasNext()) 224 return new Pair<T, E>(it1.next(), null); 225 if (it2.hasNext()) 226 return new Pair<T, E>(null, it2.next()); 227 return null; 228 } 229 230 protected final Pair<T, E> createPrevious() { 231 if (it2.hasPrevious()) 232 return new Pair<T, E>(null, it2.previous()); 233 if (it1.hasPrevious()) 234 return new Pair<T, E>(it1.previous(), null); 235 return null; 236 } 237 }; 238 } 239 240 public static final <T, E> ListIterator<Pair<T, E>> 241 cartesianProduct(final ListIterator<T> it1, final ListIterator<E> it2, final int i) { 242 return new SimpleListIterator<Pair<T, E>>(true) { 243 244 private T t = it1.hasNext() ? it1.next() : null; 245 { 246 createFirst(i); 247 } 248 249 protected final Pair<T, E> createNext() { 250 if (t != null && it2.hasNext()) 251 return new Pair<T, E>(t, it2.next()); 252 else if (it1.hasNext()) { 253 t = it1.next(); 254 while (it2.hasPrevious()) 255 it2.previous(); 256 if (it2.hasNext()) 257 return new Pair<T, E>(t, it2.next()); 258 } 259 return null; 260 } 261 262 protected final Pair<T, E> createPrevious() { 263 if (t != null && it2.hasPrevious()) 264 return new Pair<T, E>(t, it2.previous()); 265 else if (it1.hasPrevious()) { 266 t = it1.previous(); 267 while (it2.hasNext()) 268 it2.next(); 269 if (it2.hasPrevious()) 270 return new Pair<T, E>(t, it2.previous()); 271 } 272 return null; 273 } 274 }; 275 } 276 277 public static final <E> Iterable<Pair<E, E>> upperCartesianDiagonal(final Iterable<E> it) { 278 return new Iterable<Pair<E, E>>() { 279 280 @Override 281 public final Iterator<Pair<E, E>> iterator() { 282 if (!it.iterator().hasNext()) 283 return empty(); 284// return Iterators.emptyIterator(); 285 return new UnmodifiableIterator<Pair<E, E>>() { 286 287 private final Iterator<E> it1 = it.iterator(); 288 private Iterator<E> it2 = it.iterator(); 289 private E e1 = it1.next(); 290 private int skip2 = 0; 291 292 @Override 293 public final boolean hasNext() { 294 return e1 != null; 295 } 296 297 @Override 298 public final Pair<E, E> next() { 299 if (!it2.hasNext()) { 300 e1 = it1.next(); 301 it2 = it.iterator(); 302 ++skip2; 303 for (int i = 0; i < skip2; i++) 304 it2.next(); 305 } 306 final Pair<E, E> p = Pair.of(e1, it2.next()); 307 if (!it2.hasNext() && !it1.hasNext()) 308 e1 = null; 309 return p; 310 } 311 }; 312 } 313 }; 314 } 315 316 public static final <E> Iterable<Pair<E, E>> upperCartesianDiagonalStrict(final Iterable<E> it) { 317 return new Iterable<Pair<E, E>>() { 318 319 @Override 320 public final Iterator<Pair<E, E>> iterator() { 321 Iterator<E> _it = it.iterator(); 322 if (!_it.hasNext()) 323 return empty(); 324// return Iterators.emptyIterator(); 325 _it.next(); 326 if (!_it.hasNext()) 327 return empty(); 328// return Iterators.emptyIterator(); 329 return new UnmodifiableIterator<Pair<E, E>>() { 330 331 private final Iterator<E> it1 = it.iterator(); 332 private Iterator<E> it2 = it.iterator(); 333 private E e1 = it1.next(); 334 private int skip2 = 1; 335 { 336 it2.next(); 337 } 338 339 @Override 340 public final boolean hasNext() { 341 return e1 != null; 342 } 343 344 @Override 345 public final Pair<E, E> next() { 346 final Pair<E, E> p = Pair.of(e1, it2.next()); 347 if (!it2.hasNext()) { 348 if (it1.hasNext()) { 349 e1 = it1.next(); 350 if (!it1.hasNext()) 351 e1 = null; 352 else { 353 it2 = it.iterator(); 354 ++skip2; 355 for (int i = 0; i < skip2; i++) 356 it2.next(); 357 } 358 } else { 359 e1 = null; 360 } 361 } 362 return p; 363 } 364 }; 365 } 366 }; 367 } 368}