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

org.killbill.commons.utils.collect.Iterables Maven / Gradle / Ivy

/*
 * Copyright (C) 2007 The Guava Authors
 * Copyright 2020-2022 Equinix, Inc
 * Copyright 2014-2022 The Billing Project, LLC
 *
 * The Billing Project licenses this file to you 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 org.killbill.commons.utils.collect;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.RandomAccess;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import org.killbill.commons.utils.Preconditions;

/**
 * Contains subset of Guava's {@code com.google.common.collect.Iterables} functionality.
 */
public final class Iterables {

    /**
     * 

Verbatim copy of {@code com.google.common.collect.Iterables#getLast(Iterable)}. Guava's suggestion on javadoc * to use stream's {@code .stream().findFirst()} sometimes not working if {@code findFirst()} * return null.

* *

Returns the first element in {@code iterable} or {@code defaultValue} if the iterable is empty. * The {@link Iterators} analog to this method is {@link Iterators#getNext}.

*/ public static T getFirst(final Iterable iterable, final T defaultValue) { return Iterators.getNext(iterable.iterator(), defaultValue); } /** * Verbatim copy of {@code com.google.common.collect.Iterables#getLast(Iterable)}. * * Returns the last element of {@code iterable}. If {@code iterable} is a {@link List} with {@link RandomAccess} * support, then this operation is guaranteed to be {@code O(1)}. * * @return the last element of {@code iterable} * @throws NoSuchElementException if the iterable is empty */ public static T getLast(final Iterable iterable) { if (iterable instanceof List) { final List list = (List) iterable; if (list.isEmpty()) { throw new NoSuchElementException("Cannot Iterables#getLast(iterable) on empty list"); } return list.get(list.size() - 1); } return Iterators.getLast(iterable.iterator()); } /** * Verbatim copy of {@code com.google.common.collect.Iterables#getLast(Iterable, Object)}. * * Returns the last element of {@code iterable} or {@code defaultValue} if the iterable is empty. * If {@code iterable} is a {@link List} with {@link RandomAccess} support, then this operation is * guaranteed to be {@code O(1)}. * * @param defaultValue the value to return if {@code iterable} is empty * @return the last element of {@code iterable} or the default value */ public static T getLast(final Iterable iterable, final T defaultValue) { if (iterable instanceof Collection) { final Collection c = (Collection) iterable; if (c.isEmpty()) { return defaultValue; } else if (iterable instanceof List) { final List list = (List) iterable; return list.get(list.size() - 1); } } return Iterators.getLast(iterable.iterator(), defaultValue); } /** * Concat two or more iterable into single {@link Iterable}. * * @param iterables two or more iterable to concat * @param the iterable element * @return combined iterable */ public static Iterable concat(final Iterable... iterables) { Preconditions.checkNotNull(iterables); final List result = new ArrayList<>(); for (final Iterable iterable : iterables) { Preconditions.checkNotNull(iterable, "One of iterable in Iterables#concat() is null"); iterable.forEach(result::add); } return result; } /** * Convert {@link Iterable} to immutable {@link Set}. If any stream operation need to applied to iterable, use * {@link #toStream(Iterable)} instead. * * @param iterable to convert * @param iterable element * @return immutable {@link Set} */ public static Set toUnmodifiableSet(final Iterable iterable) { return toStream(iterable).collect(Collectors.toUnmodifiableSet()); } /** * Convert {@link Iterable} to immutable {@link List}. If any stream operation needed, use {@link #toStream(Iterable)} * instead of this method. * * @param iterable to convert * @param iterable element * @return converted iterable as immutable {@link List} */ public static List toUnmodifiableList(final Iterable iterable) { return toStream(iterable).collect(Collectors.toUnmodifiableList()); } /** * Convert {@link Iterable} to {@link List}. If any stream operation needed, use {@link #toStream(Iterable)} instead. * * @param iterable to convert * @param iterable element * @return converted iterable as {@link List} */ public static List toList(final Iterable iterable) { return toStream(iterable).collect(Collectors.toList()); } /** * Convert {@link Iterable} to non-parallel {@link Stream} for further processing. * @param iterable iterable to convert * @param iterable element * @return java {@link Stream} , for further processing */ public static Stream toStream(final Iterable iterable) { Preconditions.checkNotNull(iterable); return StreamSupport.stream(iterable.spliterator(), false); } /** * Verbatim copy of {@code com.google.common.collect.Iterables#isEmpty(Iterable)}. * * Determines if the given iterable contains no elements. * *

There is no precise {@link Iterator} equivalent to this method, since one can only ask an iterator whether it * has any elements remaining (which one does using {@link Iterator#hasNext}). * * @return {@code true} if the iterable contains no elements */ public static boolean isEmpty(final Iterable iterable) { if (iterable instanceof Collection) { return ((Collection) iterable).isEmpty(); } return !iterable.iterator().hasNext(); } /** Returns the number of elements in {@code iterable}. */ public static int size(final Iterable iterable) { return (iterable instanceof Collection) ? ((Collection) iterable).size() : Iterators.size(iterable.iterator()); } /** * Returns {@code true} if {@code iterable} contains any element {@code o} for which {@code * Objects.equals(o, element)} would return {@code true}. Otherwise returns {@code false}, even in * cases where {@link Collection#contains} might throw {@link NullPointerException} or {@link * ClassCastException}. */ public static boolean contains(final Iterable iterable, final Object element) { if (iterable instanceof Collection) { final Collection collection = (Collection) iterable; return safeContains(collection, element); } return Iterators.contains(iterable.iterator(), element); } /** * Delegates to {@link Collection#contains}. Returns {@code false} if the {@code contains} method * throws a {@code ClassCastException} or {@code NullPointerException}. */ private static boolean safeContains(final Collection collection, final Object object) { Preconditions.checkNotNull(collection); Preconditions.checkNotNull(object); try { return collection.contains(object); } catch (final ClassCastException e) { return false; } } /** * Returns the single element contained in {@code iterable}. * *

Java 8 users: the {@code Stream} equivalent to this method is {@code * stream.collect(MoreCollectors.onlyElement())}. * * @throws NoSuchElementException if the iterable is empty * @throws IllegalArgumentException if the iterable contains multiple elements */ public static T getOnlyElement(final Iterable iterable) { return Iterators.getOnlyElement(iterable.iterator()); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy