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

apoc.util.collection.Iterables Maven / Gradle / Ivy

There is a newer version: 5.25.1
Show newest version
/*
 * Copyright (c) "Neo4j"
 * Neo4j Sweden AB [http://neo4j.com]
 *
 * This file is part of Neo4j.
 *
 * 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 apoc.util.collection;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Stream;
import org.neo4j.graphdb.Resource;
import org.neo4j.graphdb.ResourceIterable;
import org.neo4j.graphdb.ResourceIterator;

/**
 * Utility methods for processing iterables. Where possible, If the iterable implements
 * {@link Resource}, it will be {@link Resource#close() closed} when the processing
 * has been completed.
 */
public final class Iterables {

    /**
     * Collect all the elements available in {@code iterable} and add them to the
     * provided {@code collection}.
     * 

* If the {@code iterable} implements {@link Resource} it will be * {@link Resource#close() closed} in a {@code finally} block after all * the items have been added. * * @param collection the collection to add items to. * @param iterable the iterable from which items will be collected * @param the type of elements in {@code iterable}. * @param the type of the collection to add the items to. * @return the {@code collection} that has been updated. */ public static > C addAll(C collection, Iterable iterable) { try { Iterator iterator = iterable.iterator(); try { while (iterator.hasNext()) { collection.add(iterator.next()); } } finally { Iterators.tryCloseResource(iterator); } } finally { tryCloseResource(iterable); } return collection; } @SafeVarargs public static Iterable iterable(C... items) { return Arrays.asList(items); } @SuppressWarnings("unchecked") public static T[] asArray(Class componentType, Iterable iterable) { if (iterable == null) { return null; } List list = asList(iterable); return list.toArray((T[]) Array.newInstance(componentType, list.size())); } public static ResourceIterable asResourceIterable(final Iterable iterable) { if (iterable instanceof ResourceIterable) { return (ResourceIterable) iterable; } return new AbstractResourceIterable<>() { @Override protected ResourceIterator newIterator() { return Iterators.asResourceIterator(iterable.iterator()); } @Override protected void onClosed() { tryCloseResource(iterable); } }; } /** * Returns the given iterable's first element or {@code null} if no * element found. *

* If the {@code iterable} implements {@link Resource}, then it will be closed in a {@code finally} block * after the first item has been retrieved, or failed to be retrieved. *

* If the {@link Iterable#iterator() iterator} created by the {@code iterable} implements {@link Resource} * it will be {@link Resource#close() closed} in a {@code finally} block after the single item * has been retrieved, or failed to be retrieved. * * @param the type of elements in {@code iterable}. * @param iterable the {@link Iterable} to get elements from. * @return the first element in the {@code iterable}, or {@code null} if no * element found. */ public static T firstOrNull(Iterable iterable) { try { return Iterators.firstOrNull(iterable.iterator()); } finally { tryCloseResource(iterable); } } /** * Returns the given iterable's first element. If no element is found a * {@link NoSuchElementException} is thrown. *

* If the {@code iterable} implements {@link Resource}, then it will be closed in a {@code finally} block * after the first item has been retrieved, or failed to be retrieved. * * @param the type of elements in {@code iterable}. * @param iterable the {@link Iterable} to get elements from. * @return the first element in the {@code iterable}. * @throws NoSuchElementException if no element found. */ public static T first(Iterable iterable) { try { return Iterators.first(iterable.iterator()); } finally { tryCloseResource(iterable); } } /** * Returns the given iterable's single element. If there are no elements * or more than one element in the iterable a {@link NoSuchElementException} * will be thrown. *

* If the {@code iterable} implements {@link Resource}, then it will be closed in a {@code finally} block * after the single item has been retrieved, or failed to be retrieved. *

* If the {@link Iterable#iterator() iterator} created by the {@code iterable} implements {@link Resource} * it will be {@link Resource#close() closed} in a {@code finally} block after the single item * has been retrieved, or failed to be retrieved. * * @param the type of elements in {@code iterable}. * @param iterable the {@link Iterable} to get elements from. * @return the single element in the {@code iterable}. * @throws NoSuchElementException if there isn't exactly one element. */ public static T single(Iterable iterable) { try { return Iterators.single(iterable.iterator()); } finally { tryCloseResource(iterable); } } /** * Counts the number of items in the {@code iterable} by looping through it. *

* If the {@code iterable} implements {@link Resource}, then it will be closed in a {@code finally} block * after all its items have been counted. *

* If the {@link Iterable#iterator() iterator} created by the {@code iterable} implements {@link Resource} * it will be {@link Resource#close() closed} in a {@code finally} block after the items have been counted. * * @param the type of items in the iterator. * @param iterable the {@link Iterable} to count items in. * @return the number of items found in {@code iterable}. */ public static long count(Iterable iterable) { try { return Iterators.count(iterable.iterator()); } finally { tryCloseResource(iterable); } } /** * Creates a list from an iterable. *

* If the {@code iterable} implements {@link Resource}, then it will be closed in a {@code finally} block * after all its items have been added. *

* If the {@link Iterable#iterator() iterator} created by the {@code iterable} implements {@link Resource} * it will be {@link Resource#close() closed} in a {@code finally} block after all the items have been added. * * @param iterable The iterable to create the list from. * @param The generic type of both the iterable and the list. * @return a list containing all items from the iterable. */ public static List asList(Iterable iterable) { return addAll(new ArrayList<>(), iterable); } /** * Creates a {@link Set} from an {@link Iterable}. *

* If the {@code iterable} implements {@link Resource}, then it will be closed in a {@code finally} block * after all its items have been added. *

* If the {@link Iterable#iterator() iterator} created by the {@code iterable} implements {@link Resource} * it will be {@link Resource#close() closed} in a {@code finally} block after all the items have been added. * * @param iterable The items to create the set from. * @param The generic type of items. * @return a set containing all items from the {@link Iterable}. */ public static Set asSet(Iterable iterable) { return addAll(new HashSet<>(), iterable); } /** * Create a stream from the given iterable. *

* Note: returned stream needs to be closed via {@link Stream#close()} if the given iterable implements * {@link Resource}. * * @param iterable the iterable to convert to stream * @param the type of elements in the given iterable * @return stream over the iterable elements * @throws NullPointerException when the given iterable is {@code null} */ public static Stream stream(Iterable iterable) { Objects.requireNonNull(iterable); return Iterators.stream(iterable.iterator()).onClose(() -> tryCloseResource(iterable)); } /** * Close the provided {@code iterable} if it implements {@link Resource}. * * @param iterable the iterable to check for closing */ private static void tryCloseResource(Iterable iterable) { if (iterable instanceof Resource closeable) { closeable.close(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy