/*******************************************************************************
* Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.tracecompass.common.core;
import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
import java.util.Iterator;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Function;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
/**
* Common utilities for {@link Stream}.
*
* @author Alexandre Montplaisir
* @since 2.0
*/
public final class StreamUtils {
private StreamUtils() {}
/**
* Get a sequential {@link Stream} from an {@link Iterable}.
*
* @param iterable
* Any iterable
* @return The stream on the elements of the iterable
*/
public static <T> Stream<T> getStream(Iterable<T> iterable) {
return StreamSupport.stream(iterable.spliterator(), false);
}
/**
* Get a {@link Stream} from a generic {@link Iterator}.
*
* Depending on the type of terminal operation used on the stream, the
* iterator may or may not have some elements remaining. Be wary if you
* re-use the same iterator afterwards.
*
* @param iterator
* The iterator to wrap
* @return A stream containing the iterator's elements
* @since 2.2
*/
public static <T> Stream<T> getStream(Iterator<T> iterator) {
Spliterator<T> spliterator = Spliterators.spliteratorUnknownSize(iterator, 0);
return StreamSupport.stream(spliterator, false);
}
/**
* Generic utility class to "flatten" a data structure using the
* {@link Stream} API.
*
* @param <T>
* The type of container, or "node" in the tree
*/
public static class StreamFlattener<T> {
private final Function<T, Stream<T>> fGetChildrenFunction;
/**
* Constructor
*
* @param getChildrenFunction
* The function to use to get each element's children. Should
* return a {@link Stream} of those children.
*/
public StreamFlattener(Function<T, Stream<T>> getChildrenFunction) {
fGetChildrenFunction = getChildrenFunction;
}
/**
* Do an in-order flattening of the data structure, starting at the given
* element (or node).
*
* @param element
* The tree node or similar from which to start
* @return A unified Stream of all the children that were found,
* recursively.
*/
public Stream<T> flatten(T element) {
Stream<T> ret = Stream.concat(
Stream.of(element),
fGetChildrenFunction.apply(element).flatMap(this::flatten));
return checkNotNull(ret);
}
}
}