diff --git a/pom.xml b/pom.xml index ef7bec18..d838d859 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.cedarsoftware java-util bundle - 2.9.0 + 2.10.0 Java Utilities https://github.com/jdereg/java-util diff --git a/src/main/java/com/cedarsoftware/util/ByteUtilities.java b/src/main/java/com/cedarsoftware/util/ByteUtilities.java index 11dce8a3..3d71fcd8 100644 --- a/src/main/java/com/cedarsoftware/util/ByteUtilities.java +++ b/src/main/java/com/cedarsoftware/util/ByteUtilities.java @@ -82,7 +82,7 @@ public static String encode(final byte[] bytes) * * @param value * to be converted - * @return '0'..'F' in char format. + * @return '0'...'F' in char format. */ private static char convertDigit(final int value) { diff --git a/src/main/java/com/cedarsoftware/util/CollectionUtilities.java b/src/main/java/com/cedarsoftware/util/CollectionUtilities.java index 1267f710..b1692119 100644 --- a/src/main/java/com/cedarsoftware/util/CollectionUtilities.java +++ b/src/main/java/com/cedarsoftware/util/CollectionUtilities.java @@ -1,27 +1,73 @@ package com.cedarsoftware.util; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +/** + * @author John DeRegnaucourt (jdereg@gmail.com) + *
+ * Copyright (c) Cedar Software LLC + *

+ * 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 + *

+ * License + *

+ * 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. + */ public class CollectionUtilities { private static final Set unmodifiableEmptySet = Collections.unmodifiableSet(new HashSet<>()); private static final List unmodifiableEmptyList = Collections.unmodifiableList(new ArrayList<>()); + /** + * This is a null-safe isEmpty check. + * + * @param col Collection to check + * @return true if empty or null + */ + public static boolean isEmpty(Collection col) { + return col == null || col.isEmpty(); + } + + /** + * This is a null-safe isEmpty check. + * + * @param col Collection to check + * @return true if empty or null + */ + public static boolean hasContent(Collection col) { + return col != null && !col.isEmpty(); + } + + /** + * This is a null-safe size check. + * + * @param col Collection to check + * @return true if empty or null + */ + public static int size(Collection col) { + return col == null ? 0 : col.size(); + } + /** * For JDK1.8 support. Remove this and change to List.of() for JDK11+ */ @SafeVarargs - public static List listOf(T... items) - { - if (items == null || items.length ==0) - { - return (List)unmodifiableEmptyList; + public static List listOf(T... items) { + if (items == null || items.length == 0) { + return (List) unmodifiableEmptyList; } List list = new ArrayList<>(); Collections.addAll(list, items); @@ -32,10 +78,8 @@ public static List listOf(T... items) * For JDK1.8 support. Remove this and change to Set.of() for JDK11+ */ @SafeVarargs - public static Set setOf(T... items) - { - if (items == null || items.length ==0) - { + public static Set setOf(T... items) { + if (items == null || items.length == 0) { return (Set) unmodifiableEmptySet; } Set set = new LinkedHashSet<>(); diff --git a/src/main/java/com/cedarsoftware/util/EncryptionUtilities.java b/src/main/java/com/cedarsoftware/util/EncryptionUtilities.java index 5c7776d1..00b0d7f2 100644 --- a/src/main/java/com/cedarsoftware/util/EncryptionUtilities.java +++ b/src/main/java/com/cedarsoftware/util/EncryptionUtilities.java @@ -36,9 +36,7 @@ */ public class EncryptionUtilities { - private EncryptionUtilities() - { - } + private EncryptionUtilities() { } /** * Super-fast MD5 calculation from entire file. Uses FileChannel and diff --git a/src/main/java/com/cedarsoftware/util/MathUtilities.java b/src/main/java/com/cedarsoftware/util/MathUtilities.java index 584c7f79..2fbf659f 100644 --- a/src/main/java/com/cedarsoftware/util/MathUtilities.java +++ b/src/main/java/com/cedarsoftware/util/MathUtilities.java @@ -2,6 +2,9 @@ import java.math.BigDecimal; import java.math.BigInteger; +import java.util.List; + +import static java.util.Collections.swap; /** * Useful Math utilities @@ -292,4 +295,30 @@ public static Number parseToMinimalNumericType(String numStr) { } } } -} + + /** + * Utility method for generating the "next" permutation. + * @param list List of integers, longs, etc. Typically, something like [1, 2, 3, 4] and it + * will generate the next permutation [1, 2, 4, 3]. It will override the passed in + * list. This way, each call to nextPermutation(list) works, until it returns false, + * much like an Iterator. + */ + static > boolean nextPermutation(List list) { + int k = list.size() - 2; + while (k >= 0 && list.get(k).compareTo(list.get(k + 1)) >= 0) { + k--; + } + if (k < 0) { + return false; // No more permutations + } + int l = list.size() - 1; + while (list.get(k).compareTo(list.get(l)) >= 0) { + l--; + } + swap(list, k, l); + for (int i = k + 1, j = list.size() - 1; i < j; i++, j--) { + swap(list, i, j); + } + return true; + } +} \ No newline at end of file diff --git a/src/main/java/com/cedarsoftware/util/SealableList.java b/src/main/java/com/cedarsoftware/util/SealableList.java index 595b6951..847fa42a 100644 --- a/src/main/java/com/cedarsoftware/util/SealableList.java +++ b/src/main/java/com/cedarsoftware/util/SealableList.java @@ -9,7 +9,7 @@ /** * SealableList provides a List or List wrapper that can be 'sealed' and 'unsealed.' When - * sealed, the List is mutable, when unsealed it is immutable (read-only). The iterator(), + * sealed, the List is immutable, when unsealed it is mutable. The iterator(), * listIterator(), and subList() return views that honor the Supplier's sealed state. * The sealed state can be changed as often as needed. *

diff --git a/src/main/java/com/cedarsoftware/util/StringUtilities.java b/src/main/java/com/cedarsoftware/util/StringUtilities.java index 423cc17c..d4173c3a 100644 --- a/src/main/java/com/cedarsoftware/util/StringUtilities.java +++ b/src/main/java/com/cedarsoftware/util/StringUtilities.java @@ -4,6 +4,8 @@ import java.util.Optional; import java.util.Random; +import static java.lang.Character.toLowerCase; + /** * Useful String utilities for common tasks * @@ -165,7 +167,7 @@ static boolean regionMatches(CharSequence cs, boolean ignoreCase, int thisStart, // The real same check as in String.regionMatches(): char u1 = Character.toUpperCase(c1); char u2 = Character.toUpperCase(c2); - if (u1 != u2 && Character.toLowerCase(u1) != Character.toLowerCase(u2)) { + if (u1 != u2 && toLowerCase(u1) != toLowerCase(u2)) { return false; } } @@ -623,10 +625,10 @@ public static int hashCodeIgnoreCase(String s) { if (s == null) { return 0; } - int len = s.length(); + final int len = s.length(); int hash = 0; for (int i = 0; i < len; i++) { - hash = 31 * hash + Character.toLowerCase((int) s.charAt(i)); + hash = 31 * hash + toLowerCase(s.charAt(i)); } return hash; } diff --git a/src/test/java/com/cedarsoftware/util/CollectionUtilitiesTests.java b/src/test/java/com/cedarsoftware/util/CollectionUtilitiesTests.java index bbc1fe6f..0248c350 100644 --- a/src/test/java/com/cedarsoftware/util/CollectionUtilitiesTests.java +++ b/src/test/java/com/cedarsoftware/util/CollectionUtilitiesTests.java @@ -1,15 +1,40 @@ package com.cedarsoftware.util; +import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.junit.jupiter.api.Test; +import static com.cedarsoftware.util.CollectionUtilities.hasContent; +import static com.cedarsoftware.util.CollectionUtilities.isEmpty; +import static com.cedarsoftware.util.CollectionUtilities.listOf; +import static com.cedarsoftware.util.CollectionUtilities.setOf; +import static com.cedarsoftware.util.CollectionUtilities.size; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * @author John DeRegnaucourt (jdereg@gmail.com) + *
+ * Copyright (c) Cedar Software LLC + *

+ * 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 + *

+ * License + *

+ * 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. + */ class CollectionUtilitiesTests { static class Rec { final String s; @@ -28,27 +53,27 @@ static class Rec { @Test void testListOf() { - final List list = CollectionUtilities.listOf(); + final List list = listOf(); assertEquals(0, list.size()); } @Test void testListOf_producesImmutableList() { - final List list = CollectionUtilities.listOf(); + final List list = listOf(); assertThatExceptionOfType(UnsupportedOperationException.class) .isThrownBy(() -> list.add("One")); } @Test void testListOfOne() { - final List list = CollectionUtilities.listOf("One"); + final List list = listOf("One"); assertEquals(1, list.size()); assertEquals("One", list.get(0)); } @Test void testListOfTwo() { - final List list = CollectionUtilities.listOf("One", "Two"); + final List list = listOf("One", "Two"); assertEquals(2, list.size()); assertEquals("One", list.get(0)); assertEquals("Two", list.get(1)); @@ -56,7 +81,7 @@ void testListOfTwo() { @Test void testListOfThree() { - final List list = CollectionUtilities.listOf("One", "Two", "Three"); + final List list = listOf("One", "Two", "Three"); assertEquals(3, list.size()); assertEquals("One", list.get(0)); assertEquals("Two", list.get(1)); @@ -65,13 +90,13 @@ void testListOfThree() { @Test void testSetOf() { - final Set set = CollectionUtilities.setOf(); + final Set set = setOf(); assertEquals(0, set.size()); } @Test void testSetOf_producesImmutableSet() { - final Set set = CollectionUtilities.setOf(); + final Set set = setOf(); assertThatExceptionOfType(UnsupportedOperationException.class) .isThrownBy(() -> set.add("One")); } @@ -79,25 +104,54 @@ void testSetOf_producesImmutableSet() { @Test void testSetOfOne() { - final Set set = CollectionUtilities.setOf("One"); + final Set set = setOf("One"); assertEquals(1, set.size()); assertTrue(set.contains("One")); } @Test - public void testSetOfTwo() { - final Set set = CollectionUtilities.setOf("One", "Two"); + void testSetOfTwo() { + final Set set = setOf("One", "Two"); assertEquals(2, set.size()); assertTrue(set.contains("One")); assertTrue(set.contains("Two")); } @Test - public void testSetOfThree() { - final Set set = CollectionUtilities.setOf("One", "Two", "Three"); + void testSetOfThree() { + final Set set = setOf("One", "Two", "Three"); assertEquals(3, set.size()); assertTrue(set.contains("One")); assertTrue(set.contains("Two")); assertTrue(set.contains("Three")); } + + @Test + void testIsEmpty() { + assertTrue(isEmpty(null)); + assertTrue(isEmpty(new ArrayList<>())); + assertTrue(isEmpty(new HashSet<>())); + assertFalse(isEmpty(setOf("one"))); + assertFalse(isEmpty(listOf("one"))); + } + + @Test + void testHasContent() { + assertFalse(hasContent(null)); + assertFalse(hasContent(new ArrayList<>())); + assertFalse(hasContent(new HashSet<>())); + assertTrue(hasContent(setOf("one"))); + assertTrue(hasContent(listOf("one"))); + } + + @Test + void testSize() { + assertEquals(0, size(null)); + assertEquals(0, size(new ArrayList<>())); + assertEquals(0, size(new HashSet<>())); + assertEquals(1, size(setOf("one"))); + assertEquals(1, size(listOf("one"))); + assertEquals(2, size(setOf("one", "two"))); + assertEquals(2, size(listOf("one", "two"))); + } }