From 56ddaa91320eedb9539460c118e2929d718e3b88 Mon Sep 17 00:00:00 2001 From: John Blum Date: Mon, 30 Mar 2020 17:05:02 -0700 Subject: [PATCH] DATAGEODE-302 - Add nullSafeIsEmpty(:Iterable) and nullSafeSize(:Iterable) methods. --- .../data/gemfire/util/CollectionUtils.java | 26 +++++++ .../util/CollectionUtilsUnitTests.java | 69 +++++++++++++++++-- 2 files changed, 91 insertions(+), 4 deletions(-) diff --git a/spring-data-geode/src/main/java/org/springframework/data/gemfire/util/CollectionUtils.java b/spring-data-geode/src/main/java/org/springframework/data/gemfire/util/CollectionUtils.java index 362fead5..770c6ed4 100644 --- a/spring-data-geode/src/main/java/org/springframework/data/gemfire/util/CollectionUtils.java +++ b/spring-data-geode/src/main/java/org/springframework/data/gemfire/util/CollectionUtils.java @@ -32,6 +32,7 @@ import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.StreamSupport; import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; @@ -284,6 +285,18 @@ public abstract class CollectionUtils extends org.springframework.util.Collectio return nullSafeCollection(collection).isEmpty(); } + /** + * Determines whether the given {@link Iterable} is empty. + * + * @param iterable {@link Iterable} to evaluate. + * @return a boolean value indicating whether the given {@link Iterable} is empty. + * @see java.lang.Iterable + * @see #nullSafeIterable(Iterable) + */ + public static boolean nullSafeIsEmpty(@Nullable Iterable iterable) { + return !nullSafeIterable(iterable).iterator().hasNext(); + } + /** * Determines whether the given {@link Map} is {@link Map#isEmpty() empty}. * @@ -308,6 +321,19 @@ public abstract class CollectionUtils extends org.springframework.util.Collectio return nullSafeCollection(collection).size(); } + /** + * Determines the {@link Long size} of the give {@link Iterable}. + * + * @param iterable {@link Iterable} to evaluate. + * @return the {@link Long size} indicating the number of elements contained by the given {@link Iterable}. + * If {@link Iterable} is {@literal null}, then returns {@literal 0}. + * @see java.lang.Iterable + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static long nullSafeSize(@Nullable Iterable iterable) { + return StreamSupport.stream(nullSafeIterable(iterable).spliterator(), false).count(); + } + /** * Determines the {@link Map#size()} of the given {@link Map}. * diff --git a/spring-data-geode/src/test/java/org/springframework/data/gemfire/util/CollectionUtilsUnitTests.java b/spring-data-geode/src/test/java/org/springframework/data/gemfire/util/CollectionUtilsUnitTests.java index 8a0077c1..52e062a8 100644 --- a/spring-data-geode/src/test/java/org/springframework/data/gemfire/util/CollectionUtilsUnitTests.java +++ b/spring-data-geode/src/test/java/org/springframework/data/gemfire/util/CollectionUtilsUnitTests.java @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.gemfire.util; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import java.util.ArrayList; @@ -41,7 +41,7 @@ import org.junit.Test; import org.springframework.data.gemfire.test.support.MapBuilder; /** - * Unit tests for {@link CollectionUtils}. + * Unit Tests for {@link CollectionUtils}. * * @author John Blum * @see java.lang.Iterable @@ -245,7 +245,6 @@ public class CollectionUtilsUnitTests { } @Test - @SuppressWarnings("unchecked") public void iterableOfNullEnumeration() { Iterable iterable = CollectionUtils.iterable((Enumeration) null); @@ -323,7 +322,7 @@ public class CollectionUtilsUnitTests { @Test public void nullSafeCollectionWithNullCollection() { - Collection collection = CollectionUtils.nullSafeCollection(null); + Collection collection = CollectionUtils.nullSafeCollection(null); assertThat(collection).isNotNull(); assertThat(collection.isEmpty()).isTrue(); @@ -507,6 +506,39 @@ public class CollectionUtilsUnitTests { assertThat(CollectionUtils.isEmpty((Collection) null)).isTrue(); } + @Test + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void nullSafeIsEmptyIterableWithNonNullNonEmptyIterableReturnsFalse() { + + Iterator mockIterator = mock(Iterator.class); + + when(mockIterator.hasNext()).thenReturn(true); + + assertThat(CollectionUtils.nullSafeIsEmpty(() -> mockIterator)).isFalse(); + + verify(mockIterator, times(1)).hasNext(); + verifyNoMoreInteractions(mockIterator); + } + + @Test + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void nullSafeIsEmptyIterableWithEmptyIterableReturnsTrue() { + + Iterator mockIterator = mock(Iterator.class); + + when(mockIterator.hasNext()).thenReturn(false); + + assertThat(CollectionUtils.nullSafeIsEmpty(() -> mockIterator)).isTrue(); + + verify(mockIterator, times(1)).hasNext(); + verifyNoMoreInteractions(mockIterator); + } + + @Test + public void nullSafeIsEmptyWithNullIterableReturnsTrue() { + assertThat(CollectionUtils.nullSafeIsEmpty((Iterable) null)).isTrue(); + } + @Test public void nullSafeIsEmptyMapWithNonNullNonEmptyMapReturnsFalse() { assertThat(CollectionUtils.isEmpty(Collections.singletonMap("key", "value"))).isFalse(); @@ -539,6 +571,35 @@ public class CollectionUtilsUnitTests { assertThat(CollectionUtils.nullSafeSize((Collection) null)).isZero(); } + @Test + public void nullSafeIterableSizeWithNonNullNonEmptyIterable() { + + Iterable iterable = () -> Arrays.asList("test", "testing", "tested").iterator(); + + assertThat(CollectionUtils.nullSafeSize(iterable)).isEqualTo(3); + } + + @Test + public void nullSafeIterableSizeWithSingleElementIterable() { + + Iterable iterable = () -> Collections.singleton("mock").iterator(); + + assertThat(CollectionUtils.nullSafeSize(iterable)).isOne(); + } + + @Test + public void nullSafeIterableSizeWithEmptyIterable() { + + Iterable iterable = () -> Collections.emptyIterator(); + + assertThat(CollectionUtils.nullSafeSize(iterable)).isZero(); + } + + @Test + public void nullSafeIterableSizeWithNullIterable() { + assertThat(CollectionUtils.nullSafeSize((Iterable) null)).isZero(); + } + @Test public void nullSafeMapSizeWithNonNullNonEmptyMapReturnsSize() { assertThat(CollectionUtils.nullSafeSize(Collections.singletonMap("key", "value"))).isEqualTo(1);