/* * Hibernate OGM, Domain model persistence for NoSQL datastores * * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.ogm.util.impl; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.hibernate.ogm.dialect.query.spi.ClosableIterator; /** * Provides commonly used functionality around collections. * * @author Gunnar Morling * @author Guillaume Smet */ public class CollectionHelper { private CollectionHelper() { } /** * Returns an unmodifiable set containing the given elements. * * @param ts the elements from which to create a set * @param <T> the type of the element in the set * @return an unmodifiable set containing the given elements or {@code null} in case the given element array is * {@code null}. */ @SafeVarargs public static <T> Set<T> asSet(T... ts) { if ( ts == null ) { return null; } else if ( ts.length == 0 ) { return Collections.emptySet(); } else { Set<T> set = new HashSet<T>( getInitialCapacityFromExpectedSize( ts.length ) ); Collections.addAll( set, ts ); return Collections.unmodifiableSet( set ); } } public static <T> LinkedHashSet<T> newLinkedHashSet() { return new LinkedHashSet<T>(); } public static <T> LinkedHashSet<T> newLinkedHashSet(int initialCapacity) { return new LinkedHashSet<T>( getInitialCapacityFromExpectedSize( initialCapacity ) ); } public static <K, V> HashMap<K, V> newHashMap() { return new HashMap<K, V>(); } public static <K, V> HashMap<K, V> newHashMap(int initialCapacity) { return new HashMap<K, V>( getInitialCapacityFromExpectedSize( initialCapacity ) ); } public static <K, V> HashMap<K, V> newHashMap(Map<? extends K, ? extends V> other) { return new HashMap<K, V>( other ); } public static <K, V> LinkedHashMap<K, V> newLinkedHashMap() { return new LinkedHashMap<K, V>(); } public static <K, V> LinkedHashMap<K, V> newLinkedHashMap(int initialCapacity) { return new LinkedHashMap<K, V>( getInitialCapacityFromExpectedSize( initialCapacity ) ); } public static <K, V> LinkedHashMap<K, V> newLinkedHashMap(Map<? extends K, ? extends V> other) { return new LinkedHashMap<K, V>( other ); } public static <K, V> ConcurrentHashMap<K, V> newConcurrentHashMap() { return new ConcurrentHashMap<K, V>(); } public static <K, V> ConcurrentHashMap<K, V> newConcurrentHashMap(int initialCapacity) { return new ConcurrentHashMap<K, V>( initialCapacity ); } public static <K, V> ConcurrentHashMap<K, V> newConcurrentHashMap(Map<? extends K, ? extends V> other) { return new ConcurrentHashMap<K, V>( other ); } public static <T> ClosableIterator<T> newClosableIterator(Iterable<T> iterable) { return new ClosableIteratorWrapper<T>( iterable.iterator() ); } public static boolean isEmptyOrContainsOnlyNull(Object[] objects) { for ( Object object : objects ) { if ( object != null ) { return false; } } return true; } /** * As the default loadFactor is of 0.75, we need to calculate the initial capacity from the expected size to avoid * resizing the collection when we populate the collection with all the initial elements. We use a calculation * similar to what is done in {@link HashMap#putAll(Map)}. * * @param expectedSize the expected size of the collection * @return the initial capacity of the collection */ private static int getInitialCapacityFromExpectedSize(int expectedSize) { if ( expectedSize < 3 ) { return expectedSize + 1; } return (int) ( (float) expectedSize / 0.75f + 1.0f ); } private static class ClosableIteratorWrapper<T> implements ClosableIterator<T> { private final Iterator<T> iterator; private ClosableIteratorWrapper(Iterator<T> iterator) { this.iterator = iterator; } @Override public boolean hasNext() { return iterator.hasNext(); } @Override public T next() { return iterator.next(); } @Override public void remove() { iterator.remove(); } @Override public void close() { //Nothing to do } } }