From 5f892b34b06f49c0de1cfb3599c6cad5849e19eb Mon Sep 17 00:00:00 2001 From: zihluwang Date: Tue, 25 Mar 2025 19:52:15 +0800 Subject: [PATCH 1/2] feat: chunk list with specified list type --- .../onixbyte/devkit/utils/CollectionUtil.java | 112 ++++++++++++++++++ .../com/onixbyte/devkit/utils/ListUtil.java | 90 +++++++++----- 2 files changed, 173 insertions(+), 29 deletions(-) create mode 100644 devkit-utils/src/main/java/com/onixbyte/devkit/utils/CollectionUtil.java diff --git a/devkit-utils/src/main/java/com/onixbyte/devkit/utils/CollectionUtil.java b/devkit-utils/src/main/java/com/onixbyte/devkit/utils/CollectionUtil.java new file mode 100644 index 0000000..44c75c0 --- /dev/null +++ b/devkit-utils/src/main/java/com/onixbyte/devkit/utils/CollectionUtil.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2024-2025 OnixByte. + * + * 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 com.onixbyte.devkit.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.function.Supplier; + +/** + * A utility class providing static methods for manipulating collections. + * + * @author zihluwang + */ +public final class CollectionUtil { + + private static final Logger log = LoggerFactory.getLogger(CollectionUtil.class); + + /** + * Private constructor to prevent instantiation of this utility class. + */ + private CollectionUtil() { + } + + /** + * Splits a collection into a list of sub-collections, each with a maximum size specified by + * the caller. + *

+ * This method takes an original collection and divides it into smaller sub-collections, + * ensuring that each sub-collection contains no more than the specified maximum size. If the + * original collection's size is less than or equal to the maximum size, it is returned as a + * single sub-collection. The sub-collections are created using the provided collection factory. + * + * @param the type of elements in the collection + * @param the type of the collection, which must extend {@link Collection} + * @param originalCollection the collection to be split into sub-collections + * @param maxSize the maximum number of elements allowed in each sub-collection + * @param collectionFactory a supplier that creates new instances of the sub-collection type + * @return a list of sub-collections, each containing up to {@code maxSize} elements + * @throws IllegalArgumentException if {@code originalCollection} is {@code null}, + * {@code maxSize} is less than zero, or + * {@code collectionFactory} is {@code null} + */ + public static > List chunk(C originalCollection, + int maxSize, + Supplier collectionFactory) { + // check inputs + if (Objects.isNull(originalCollection)) { + throw new IllegalArgumentException("Collection must not be null."); + } + + if (maxSize < 0) { + throw new IllegalArgumentException("maxSize must greater than 0."); + } + + if (Objects.isNull(collectionFactory)) { + throw new IllegalArgumentException("Factory method cannot be null."); + } + + var result = new ArrayList(); + var size = originalCollection.size(); + + // if original collection is empty or the size less than maxSize, return it as a single + // sub collection + if (size <= maxSize) { + var singleCollection = collectionFactory.get(); + singleCollection.addAll(originalCollection); + result.add(singleCollection); + return result; + } + + // use iterator to split the given collection + var iter = originalCollection.iterator(); + var count = 0; + var currentSubCollection = collectionFactory.get(); + + while (iter.hasNext()) { + var element = iter.next(); + currentSubCollection.add(element); + count++; + + // add sub collection to result when current sub collection reached maxSize or + // collection traverse is completed + if (count % maxSize == 0 || !iter.hasNext()) { + result.add(currentSubCollection); + currentSubCollection = collectionFactory.get(); + } + } + + return result; + } + +} diff --git a/devkit-utils/src/main/java/com/onixbyte/devkit/utils/ListUtil.java b/devkit-utils/src/main/java/com/onixbyte/devkit/utils/ListUtil.java index 00000bc..f1ed1ba 100644 --- a/devkit-utils/src/main/java/com/onixbyte/devkit/utils/ListUtil.java +++ b/devkit-utils/src/main/java/com/onixbyte/devkit/utils/ListUtil.java @@ -19,25 +19,77 @@ package com.onixbyte.devkit.utils; import java.util.ArrayList; import java.util.List; +import java.util.Objects; +import java.util.function.Supplier; /** - * A utility class for splitting a List into multiple sub lists, where each sublist has a maximum - * number of elements specified by the user. + * A utility class providing static methods for manipulating lists. * * @author siujamo + * @author zihluwang */ public final class ListUtil { /** * Private constructor to prevent instantiation of this utility class. - *

- * This class provides static methods for list manipulation and is not intended to be - * instantiated. The private constructor ensures that no instances can be created, enforcing - * the utility nature of the class. */ private ListUtil() { } + /** + * Splits a given List into a List of sub lists, where each sublist contains at most + * {@code maxSize} elements. The original list is not modified, and new sub lists are created + * to hold the partitioned data. + *

+ * If the original list's size is less than or equal to {@code maxSize}, a single sublist + * containing all elements is returned. If the list is empty, an empty list of sub lists + * is returned. + * + * @param the type of elements in the list + * @param originalList the list to be split, must not be null + * @param maxSize the maximum number of elements in each sublist, must be positive + * @param listFactory list factory + * @return a List of sub lists, where each sublist has at most {@code maxSize} elements + * @throws IllegalArgumentException if {@code originalList} is null or {@code maxSize} is less + * than or equal to 0 + */ + public static List> chunk(List originalList, int maxSize, Supplier> listFactory) { + // check input + if (Objects.isNull(originalList)) { + throw new IllegalArgumentException("List cannot be null"); + } + + if (maxSize <= 0) { + throw new IllegalArgumentException("Max size should be greater than 0"); + } + + if (Objects.isNull(listFactory)) { + throw new IllegalArgumentException("List factory cannot be null"); + } + + var result = new ArrayList>(); + var size = originalList.size(); + + // if the original list is empty or smaller than maxSize, return it as a single sublist + if (size <= maxSize) { + var singleSubList = listFactory.get(); + singleSubList.addAll(originalList); + result.add(singleSubList); + return result; + } + + // split the list + for (var i = 0; i < size; i += maxSize) { + var end = Math.min(i + maxSize, size); // ensure not to exceed list length + var subList = originalList.subList(i, end); + var subListWrapper = listFactory.get(); + subListWrapper.addAll(subList); + result.add(subListWrapper); // create a new list to avoid reference issues + } + + return result; + } + /** * Splits a given List into a List of sub lists, where each sublist contains at most * {@code maxSize} elements. The original list is not modified, and new sub lists are created @@ -53,30 +105,10 @@ public final class ListUtil { * @return a List of sub lists, where each sublist has at most {@code maxSize} elements * @throws IllegalArgumentException if {@code originalList} is null or {@code maxSize} is less * than or equal to 0 + * @see #chunk(List, int, Supplier) */ - public static List> splitList(List originalList, int maxSize) { - // check input - if (originalList == null || maxSize <= 0) { - throw new IllegalArgumentException("List cannot be null and maxSize must be positive"); - } - - var result = new ArrayList>(); - var size = originalList.size(); - - // if the original list is empty or smaller than maxSize, return it as a single sublist - if (size <= maxSize) { - result.add(new ArrayList<>(originalList)); - return result; - } - - // split the list - for (var i = 0; i < size; i += maxSize) { - var end = Math.min(i + maxSize, size); // ensure not to exceed list length - List subList = originalList.subList(i, end); - result.add(new ArrayList<>(subList)); // create a new list to avoid reference issues - } - - return result; + public static List> chunk(List originalList, int maxSize) { + return chunk(originalList, maxSize, ArrayList::new); } } From 68bf18d944b6c6e105ff2cefca8af260cee63213 Mon Sep 17 00:00:00 2001 From: zihluwang Date: Wed, 2 Apr 2025 20:54:17 +0800 Subject: [PATCH 2/2] feat: use the same private constructor comment within the whole repository --- .../src/main/java/com/onixbyte/devkit/utils/AesUtil.java | 2 +- .../src/main/java/com/onixbyte/devkit/utils/Base64Util.java | 2 +- .../src/main/java/com/onixbyte/devkit/utils/BoolUtil.java | 2 +- .../src/main/java/com/onixbyte/devkit/utils/HashUtil.java | 2 +- .../src/main/java/com/onixbyte/devkit/utils/MapUtil.java | 2 +- .../src/main/java/com/onixbyte/devkit/utils/RangeUtil.java | 2 +- .../com/onixbyte/devkit/utils/unsafe/ReflectMapUtil.java | 2 +- .../main/java/com/onixbyte/nums/PercentileCalculator.java | 2 +- .../main/java/com/onixbyte/nums/model/QuartileBounds.java | 3 +-- .../onixbyte/simplejwt/authzero/AuthzeroTokenResolver.java | 5 ++--- .../src/main/java/com/onixbyte/simplejwt/SecretCreator.java | 2 +- .../com/onixbyte/simplejwt/constants/PredefinedKeys.java | 2 +- 12 files changed, 13 insertions(+), 15 deletions(-) diff --git a/devkit-utils/src/main/java/com/onixbyte/devkit/utils/AesUtil.java b/devkit-utils/src/main/java/com/onixbyte/devkit/utils/AesUtil.java index 85bb220..b834ecc 100644 --- a/devkit-utils/src/main/java/com/onixbyte/devkit/utils/AesUtil.java +++ b/devkit-utils/src/main/java/com/onixbyte/devkit/utils/AesUtil.java @@ -158,7 +158,7 @@ public final class AesUtil { } /** - * Private constructor will protect this class from being instantiated. + * Private constructor to prevent instantiation of this utility class. */ private AesUtil() { } diff --git a/devkit-utils/src/main/java/com/onixbyte/devkit/utils/Base64Util.java b/devkit-utils/src/main/java/com/onixbyte/devkit/utils/Base64Util.java index 9dc467d..4062a0a 100644 --- a/devkit-utils/src/main/java/com/onixbyte/devkit/utils/Base64Util.java +++ b/devkit-utils/src/main/java/com/onixbyte/devkit/utils/Base64Util.java @@ -109,7 +109,7 @@ public final class Base64Util { } /** - * Private constructor to prevent instantiation of the class. + * Private constructor to prevent instantiation of this utility class. */ private Base64Util() { } diff --git a/devkit-utils/src/main/java/com/onixbyte/devkit/utils/BoolUtil.java b/devkit-utils/src/main/java/com/onixbyte/devkit/utils/BoolUtil.java index 3d70220..310eb7a 100644 --- a/devkit-utils/src/main/java/com/onixbyte/devkit/utils/BoolUtil.java +++ b/devkit-utils/src/main/java/com/onixbyte/devkit/utils/BoolUtil.java @@ -98,7 +98,7 @@ public final class BoolUtil { } /** - * Private constructor prevent from being initialised. + * Private constructor to prevent instantiation of this utility class. */ private BoolUtil() {} diff --git a/devkit-utils/src/main/java/com/onixbyte/devkit/utils/HashUtil.java b/devkit-utils/src/main/java/com/onixbyte/devkit/utils/HashUtil.java index 1006a3d..ca98667 100644 --- a/devkit-utils/src/main/java/com/onixbyte/devkit/utils/HashUtil.java +++ b/devkit-utils/src/main/java/com/onixbyte/devkit/utils/HashUtil.java @@ -229,7 +229,7 @@ public final class HashUtil { } /** - * Private constructor will protect this class from being instantiated. + * Private constructor to prevent instantiation of this utility class. */ private HashUtil() { } diff --git a/devkit-utils/src/main/java/com/onixbyte/devkit/utils/MapUtil.java b/devkit-utils/src/main/java/com/onixbyte/devkit/utils/MapUtil.java index 57f5b11..7f489f5 100644 --- a/devkit-utils/src/main/java/com/onixbyte/devkit/utils/MapUtil.java +++ b/devkit-utils/src/main/java/com/onixbyte/devkit/utils/MapUtil.java @@ -113,7 +113,7 @@ public final class MapUtil { } /** - * Private constructor prevent class being instantiated. + * Private constructor to prevent instantiation of this utility class. */ private MapUtil() { } diff --git a/devkit-utils/src/main/java/com/onixbyte/devkit/utils/RangeUtil.java b/devkit-utils/src/main/java/com/onixbyte/devkit/utils/RangeUtil.java index faf4925..34681fa 100644 --- a/devkit-utils/src/main/java/com/onixbyte/devkit/utils/RangeUtil.java +++ b/devkit-utils/src/main/java/com/onixbyte/devkit/utils/RangeUtil.java @@ -37,7 +37,7 @@ public final class RangeUtil { private final static Logger log = LoggerFactory.getLogger(RangeUtil.class); /** - * Private constructor prevent class being instantiated. + * Private constructor to prevent instantiation of this utility class. */ private RangeUtil() { } diff --git a/map-util-unsafe/src/main/java/com/onixbyte/devkit/utils/unsafe/ReflectMapUtil.java b/map-util-unsafe/src/main/java/com/onixbyte/devkit/utils/unsafe/ReflectMapUtil.java index 74f8464..3d98e15 100644 --- a/map-util-unsafe/src/main/java/com/onixbyte/devkit/utils/unsafe/ReflectMapUtil.java +++ b/map-util-unsafe/src/main/java/com/onixbyte/devkit/utils/unsafe/ReflectMapUtil.java @@ -240,7 +240,7 @@ public final class ReflectMapUtil { } /** - * Private constructor will protect this class from being instantiated. + * Private constructor to prevent instantiation of this utility class. */ private ReflectMapUtil() { } diff --git a/num4j/src/main/java/com/onixbyte/nums/PercentileCalculator.java b/num4j/src/main/java/com/onixbyte/nums/PercentileCalculator.java index e351e5a..2ae1b54 100644 --- a/num4j/src/main/java/com/onixbyte/nums/PercentileCalculator.java +++ b/num4j/src/main/java/com/onixbyte/nums/PercentileCalculator.java @@ -54,7 +54,7 @@ public final class PercentileCalculator { private final static Logger log = LoggerFactory.getLogger(PercentileCalculator.class); /** - * Private constructor prevents from being initialised. + * Private constructor to prevent instantiation of this utility class. */ private PercentileCalculator() { } diff --git a/num4j/src/main/java/com/onixbyte/nums/model/QuartileBounds.java b/num4j/src/main/java/com/onixbyte/nums/model/QuartileBounds.java index 5daf4f8..60b9470 100644 --- a/num4j/src/main/java/com/onixbyte/nums/model/QuartileBounds.java +++ b/num4j/src/main/java/com/onixbyte/nums/model/QuartileBounds.java @@ -86,8 +86,7 @@ public record QuartileBounds( private Double lowerBound; /** - * Private constructor for {@code Builder}, ensuring it can only be instantiated through the - * {@link QuartileBounds#builder()} method. + * Private constructor to prevent instantiation of this utility class. */ private Builder() { } diff --git a/simple-jwt-authzero/src/main/java/com/onixbyte/simplejwt/authzero/AuthzeroTokenResolver.java b/simple-jwt-authzero/src/main/java/com/onixbyte/simplejwt/authzero/AuthzeroTokenResolver.java index 759054c..aa5f2d3 100644 --- a/simple-jwt-authzero/src/main/java/com/onixbyte/simplejwt/authzero/AuthzeroTokenResolver.java +++ b/simple-jwt-authzero/src/main/java/com/onixbyte/simplejwt/authzero/AuthzeroTokenResolver.java @@ -155,8 +155,7 @@ public class AuthzeroTokenResolver implements TokenResolver { private ECPublicKey publicKey; /** - * Private constructor prevents this class being initialised at somewhere it should not - * be initialised. + * Private constructor to prevent instantiation of this utility class. */ private Builder() { } @@ -643,7 +642,7 @@ public class AuthzeroTokenResolver implements TokenResolver { ); /** - * Private constructor prevent this class being initialised mistakenly. + * Private constructor to prevent instantiation of this utility class. * * @param jtiCreator a creator that can create JWT id * @param algorithm an algorithm to sign this JWT diff --git a/simple-jwt-facade/src/main/java/com/onixbyte/simplejwt/SecretCreator.java b/simple-jwt-facade/src/main/java/com/onixbyte/simplejwt/SecretCreator.java index 831bc88..0b24439 100644 --- a/simple-jwt-facade/src/main/java/com/onixbyte/simplejwt/SecretCreator.java +++ b/simple-jwt-facade/src/main/java/com/onixbyte/simplejwt/SecretCreator.java @@ -128,7 +128,7 @@ public final class SecretCreator { } /** - * Private constructor will protect this class from being instantiated. + * Private constructor to prevent instantiation of this utility class. */ private SecretCreator() { } diff --git a/simple-jwt-facade/src/main/java/com/onixbyte/simplejwt/constants/PredefinedKeys.java b/simple-jwt-facade/src/main/java/com/onixbyte/simplejwt/constants/PredefinedKeys.java index 9dc480a..af3b315 100644 --- a/simple-jwt-facade/src/main/java/com/onixbyte/simplejwt/constants/PredefinedKeys.java +++ b/simple-jwt-facade/src/main/java/com/onixbyte/simplejwt/constants/PredefinedKeys.java @@ -90,7 +90,7 @@ public final class PredefinedKeys { List.of(ISSUER, SUBJECT, AUDIENCE, EXPIRATION_TIME, NOT_BEFORE, ISSUED_AT, JWT_ID); /** - * Private constructor will protect this class from being instantiated. + * Private constructor to prevent instantiation of this utility class. */ private PredefinedKeys() { }