All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.jenetics.ext.internal.util.ConcatSpliterator Maven / Gradle / Ivy

The newest version!
/*
 * Java Genetic Algorithm Library (jenetics-8.1.0).
 * Copyright (c) 2007-2024 Franz Wilhelmstötter
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author:
 *    Franz Wilhelmstötter ([email protected])
 */
package io.jenetics.ext.internal.util;

import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Deque;
import java.util.List;
import java.util.Objects;
import java.util.Spliterator;
import java.util.function.Consumer;

/**
 * This {@code Spliterator} takes a list of other spliterators which are
 * concatenated and a limiting predicate.
 *
 * @author Franz Wilhelmstötter
 * @version 6.3
 * @since 4.1
 */
public class ConcatSpliterator implements Spliterator {

	private final Deque> _spliterators;
	private final int _characteristics;
	private final long _size;

	/**
	 * Create a new concatenating spliterator with the given arguments.
	 *
	 * @param spliterators the spliterators which are concatenated
	 * @throws NullPointerException if one of the arguments are {@code null}
	 */
	public ConcatSpliterator(final Collection> spliterators) {
		_spliterators = new ArrayDeque<>(spliterators);


		int characteristics = (ORDERED | SIZED | SUBSIZED);
		long size = 0;
		for (var spliterator : spliterators) {
			characteristics &= spliterator.characteristics();
			size += spliterator.estimateSize();
		}
		if (size < 0) {
			size = Long.MAX_VALUE;
			characteristics &= (~SIZED) & (~SUBSIZED);
		}

		_characteristics = characteristics;
		_size = size;
	}

	@Override
	public boolean tryAdvance(final Consumer action) {
		boolean advance = true;
		if (!_spliterators.isEmpty()) {
			final Spliterator spliterator = _spliterators.peek();
			assert spliterator != null;

			if (!spliterator.tryAdvance(action)) {
				_spliterators.removeFirst();
				advance = !_spliterators.isEmpty();
			}
		} else {
			advance = false;
		}

		return advance;
	}

	@Override
	public Spliterator trySplit() {
		final List> split = _spliterators.stream()
			.map(Spliterator::trySplit)
			.toList();

		return split.stream().noneMatch(Objects::isNull)
			? new ConcatSpliterator<>(split)
			: null;
	}

	@Override
	public long estimateSize() {
		return _size;
	}

	@Override
	public int characteristics() {
		return _characteristics;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy