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

io.github.selcukes.collections.Streams Maven / Gradle / Ivy

There is a newer version: 2.3.12
Show newest version
/*
 *  Copyright (c) Ramesh Babu Prudhvi.
 *
 *  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.
 */

package io.github.selcukes.collections;

import lombok.experimental.UtilityClass;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.BiFunction;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

@UtilityClass
public class Streams {
    /**
     * It takes an iterator and returns a stream.
     *
     * @param  iterator The iterator to convert to a stream.
     * @return          A stream of the iterator.
     */
    public  Stream of(final Iterator iterator) {
        return StreamSupport
                .stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false);
    }

    /**
     * Returns an OptionalInt that contains the index of the first element in
     * the list that matches the given predicate, or an empty OptionalInt if no
     * such element exists.
     * 

* This method converts the input list to a Stream using the of() method, * filters the stream using the provided predicate, and returns the index of * the first element that matches the predicate using the findFirst() * method. If no element matches the predicate, an empty OptionalInt is * returned. * * @param elements the list of elements to search through * @param predicate the predicate to apply to the elements * @return an OptionalInt containing the index of the first * matching element, or an empty OptionalInt if no such * element exists */ public OptionalInt indexOf(List elements, Predicate predicate) { return of(elements).parallel() .filter(i -> predicate.test(elements.get(i))) .findFirst(); } /** * Returns an {@code Optional} describing the first element of this list * that matches the given predicate, or an empty {@code Optional} if no such * element is found. * * @param elements the list of elements to search for a * matching element * @param predicate the predicate to apply to each element in * the list * @param the type of the elements in the list * @return an {@code Optional} describing the first * matching element, or an empty * {@code Optional} if no such element is found * @throws NullPointerException if the specified list or predicate is null */ public Optional findFirst(List elements, Predicate predicate) { return elements.parallelStream() .filter(predicate) .findFirst(); } /** * It returns an IntStream of the indices of the elements in the given list. * * @param elements The list of elements to iterate over. * @return An IntStream of the indexes of the elements in the list. */ public IntStream of(List elements) { return of(0, elements.size()); } /** * Returns an IntStream of the numbers between start and end, inclusive. * * @param start The starting value of the range. * @param end The end value (exclusive) for the range to be created * @return IntStream */ public IntStream of(int start, int end) { return IntStream.range(start, end); } /** * Merges two lists by applying a specified function to corresponding * elements of the two lists. The resulting stream contains the results of * these function applications in order. The length of the resulting stream * is equal to the length of the shorter of the two input lists. * * @param first the first list to be zipped * @param second the second list to be zipped * @param zipper a function that combines the elements of the two lists * @param the type of elements in the first list * @param the type of elements in the second list * @param the type of elements in the resulting stream * @return a stream of the results of applying the given function to * corresponding elements of the two lists */ public static Stream zip(List first, List second, BiFunction zipper) { return IntStream.range(0, Math.min(first.size(), second.size())) .mapToObj(i -> { var firstValue = i < first.size() ? first.get(i) : null; var secondValue = i < second.size() ? second.get(i) : null; return zipper.apply(firstValue, secondValue); }); } /** * Converts a list of lists of values into a {@link DataTable}, using the * first row as headers. *

* This method transforms a nested list structure into a structured * {@link DataTable}, facilitating data manipulation and analysis with * tabular data. It handles missing values gracefully by using empty strings * as defaults. * * @param cells the list of lists of values to convert * @return the resulting {@code DataTable} */ public DataTable toTable(List> cells) { var headers = Lists.toString(cells.get(0)); return cells.stream() .skip(1) .map(row -> Maps.of(headers, Lists.toString(row), "")) .collect(Collectors.toCollection(DataTable::new)); } /** * Converts a List of Maps into a Map of Lists, where keys from the input * Maps are grouped together, and their corresponding values are aggregated * into Lists. * * @param listMap A List of Maps to be converted into a Map of Lists. * @return A Map of Lists where each key is mapped to a List of * values from the input List. */ public Map> toMapOfList(List> listMap) { return listMap.stream() .flatMap(map -> map.entrySet().stream()) .collect(Collectors.groupingBy( Map.Entry::getKey, Collectors.mapping( Map.Entry::getValue, Collectors.toList()))); } /** * Converts a list of lists of strings into a 2D array of strings. * * @param cells The list of lists of strings to convert to a 2D array. * @return A 2D array of Strings */ public String[][] toArray(final List> cells) { return cells.stream() .map(row -> row.toArray(String[]::new)) .toArray(String[][]::new); } /** * Return a list of trimmed strings from the given list of strings. * * @param list The list to trim. * @return A list of strings that have been trimmed. */ public List trim(final List list) { return list.stream() .map(String::trim) .toList(); } /** * Returns a stream of string representations for the constants of the given * enum class. * * @param enumData The enum class whose constants are to be streamed. * @return A stream of string. */ public Stream of(final Class> enumData) { return Stream.of(enumData.getEnumConstants()).map(Enum::toString); } }