001/* 002 * Java Genetic Algorithm Library (jenetics-7.2.0). 003 * Copyright (c) 2007-2023 Franz Wilhelmstötter 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 * Author: 018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com) 019 */ 020package io.jenetics.internal.util; 021 022import static java.util.Objects.requireNonNull; 023 024import java.util.Comparator; 025import java.util.Spliterator; 026import java.util.function.Consumer; 027import java.util.function.Predicate; 028 029/** 030 * Extends the {@link Spliterator} interface by an additional {@code proceed} 031 * predicate. 032 * 033 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a> 034 * @version 4.1 035 * @since 4.1 036 */ 037public final class LimitSpliterator<T> implements Spliterator<T> { 038 039 private final Spliterator<T> _spliterator; 040 private final Predicate<? super T> _proceed; 041 042 private boolean _limited = false; 043 044 private LimitSpliterator( 045 final Spliterator<T> spliterator, 046 final Predicate<? super T> proceed 047 ) { 048 _spliterator = requireNonNull(spliterator); 049 _proceed = requireNonNull(proceed); 050 } 051 052 @Override 053 public boolean tryAdvance(final Consumer<? super T> action) { 054 final boolean hasNext = _spliterator.tryAdvance(element -> { 055 if (_proceed.test(element)) { 056 action.accept(element); 057 } else { 058 _limited = true; 059 } 060 }); 061 062 return hasNext && !_limited; 063 } 064 065 @Override 066 public Spliterator<T> trySplit() { 067 final Spliterator<T> split = _spliterator.trySplit(); 068 return split == null ? null : new LimitSpliterator<>(split, _proceed); 069 } 070 071 @Override 072 public long estimateSize() { 073 return 0; 074 } 075 076 @Override 077 public int characteristics() { 078 return _spliterator.characteristics() & ~SIZED & ~SUBSIZED; 079 } 080 081 @Override 082 public Comparator<? super T> getComparator() { 083 return _spliterator.getComparator(); 084 } 085 086 087 public static <T> LimitSpliterator<T> of( 088 final Spliterator<T> spliterator, 089 final Predicate<? super T> proceed 090 ) { 091 return new LimitSpliterator<>(spliterator, proceed); 092 } 093 094}