diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/array/ArrayUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/array/ArrayUtil.java index dc3ebac5c..9d18162eb 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/array/ArrayUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/array/ArrayUtil.java @@ -13,9 +13,9 @@ package org.dromara.hutool.core.array; import org.dromara.hutool.core.collection.ListUtil; +import org.dromara.hutool.core.collection.iter.IterUtil; import org.dromara.hutool.core.collection.set.SetUtil; import org.dromara.hutool.core.collection.set.UniqueKeySet; -import org.dromara.hutool.core.collection.iter.IterUtil; import org.dromara.hutool.core.comparator.CompareUtil; import org.dromara.hutool.core.convert.Convert; import org.dromara.hutool.core.exceptions.UtilException; @@ -27,7 +27,6 @@ import org.dromara.hutool.core.util.ObjUtil; import org.dromara.hutool.core.util.RandomUtil; import java.lang.reflect.Array; -import java.nio.ByteBuffer; import java.util.*; import java.util.function.Function; import java.util.function.Predicate; @@ -44,8 +43,8 @@ public class ArrayUtil extends PrimitiveArrayUtil { /** * 转为数组,如果values为数组,返回,否则返回一个只有values一个元素的数组 * - * @param 数组类型 - * @param values 元素值 + * @param 数组类型 + * @param values 元素值 * @return 数组 */ public static A ofArray(final Object values) { @@ -73,6 +72,34 @@ public class ArrayUtil extends PrimitiveArrayUtil { return (A) newInstance; } + /** + * 将集合转为数组 + * + * @param 数组元素类型 + * @param iterator {@link Iterator} + * @param componentType 集合元素类型 + * @return 数组 + * @since 3.0.9 + */ + public static T[] ofArray(final Iterator iterator, final Class componentType) { + if (null == iterator) { + return newArray(componentType, 0); + } + return ListUtil.of(iterator).toArray(newArray(componentType, 0)); + } + + /** + * 将集合转为数组 + * + * @param 数组元素类型 + * @param iterable {@link Iterable} + * @param componentType 集合元素类型 + * @return 数组 + * @since 3.0.9 + */ + public static T[] ofArray(final Iterable iterable, final Class componentType) { + return ofArray(IterUtil.getIter(iterable), componentType); + } // ---------------------------------------------------------------------- isEmpty /** @@ -474,7 +501,7 @@ public class ArrayUtil extends PrimitiveArrayUtil { * * * @param 数组类型 - * @param array 已有数组 + * @param array 已有数组 * @param index 位置 * @param values 新值 * @return 新数组或原有数组 @@ -1133,56 +1160,32 @@ public class ArrayUtil extends PrimitiveArrayUtil { /** * 获取子数组 * - * @param array 数组 - * @param start 开始位置(包括) - * @param end 结束位置(不包括) + * @param array 数组 + * @param beginInclude 开始位置(包括) + * @param endExclude 结束位置(不包括) * @return 新的数组 * @since 4.0.6 + * @param 数组类型 */ - public static Object[] sub(final Object array, final int start, final int end) { - return sub(array, start, end, 1); + public static A sub(final A array, + final int beginInclude, final int endExclude) { + return ArrayWrapper.of(array).getSub(beginInclude, endExclude); } /** * 获取子数组 * - * @param array 数组 - * @param start 开始位置(包括) - * @param end 结束位置(不包括) - * @param step 步进 + * @param array 数组 + * @param beginInclude 开始位置(包括) + * @param endExclude 结束位置(不包括) + * @param step 步进 * @return 新的数组 * @since 4.0.6 + * @param 数组类型 */ - public static Object[] sub(final Object array, int start, int end, int step) { - final int length = length(array); - if (start < 0) { - start += length; - } - if (end < 0) { - end += length; - } - if (start > end) { - final int tmp = start; - start = end; - end = tmp; - } - if (start >= length) { - return new Object[0]; - } - if (end > length) { - end = length; - } - - if (step <= 1) { - step = 1; - } - - final List list = new ArrayList<>(); - for (int i = start; i < end; i += step) { - list.add(get(array, i)); - } - - return list.toArray(); + public static A sub(final A array, + final int beginInclude, final int endExclude, final int step) { + return ArrayWrapper.of(array).getSub(beginInclude, endExclude, step); } /** @@ -1317,55 +1320,6 @@ public class ArrayUtil extends PrimitiveArrayUtil { return StrJoiner.of(conjunction).append(array).toString(); } - /** - * {@link ByteBuffer} 转byte数组 - * - * @param bytebuffer {@link ByteBuffer} - * @return byte数组 - * @since 3.0.1 - */ - public static byte[] toArray(final ByteBuffer bytebuffer) { - if (bytebuffer.hasArray()) { - return Arrays.copyOfRange(bytebuffer.array(), bytebuffer.position(), bytebuffer.limit()); - } else { - final int oldPosition = bytebuffer.position(); - bytebuffer.position(0); - final int size = bytebuffer.limit(); - final byte[] buffers = new byte[size]; - bytebuffer.get(buffers); - bytebuffer.position(oldPosition); - return buffers; - } - } - - /** - * 将集合转为数组 - * - * @param 数组元素类型 - * @param iterator {@link Iterator} - * @param componentType 集合元素类型 - * @return 数组 - * @since 3.0.9 - */ - public static T[] toArray(final Iterator iterator, final Class componentType) { - if (null == iterator) { - return newArray(componentType, 0); - } - return ListUtil.of(iterator).toArray(newArray(componentType, 0)); - } - - /** - * 将集合转为数组 - * - * @param 数组元素类型 - * @param iterable {@link Iterable} - * @param componentType 集合元素类型 - * @return 数组 - * @since 3.0.9 - */ - public static T[] toArray(final Iterable iterable, final Class componentType) { - return toArray(IterUtil.getIter(iterable), componentType); - } // ---------------------------------------------------------------------- remove /** @@ -1688,7 +1642,7 @@ public class ArrayUtil extends PrimitiveArrayUtil { final Set set = new LinkedHashSet<>(array.length, 1); Collections.addAll(set, array); - return toArray(set, (Class) getComponentType(array)); + return ofArray(set, (Class) getComponentType(array)); } /** @@ -1717,7 +1671,7 @@ public class ArrayUtil extends PrimitiveArrayUtil { set.addIfAbsent(t); } } - return toArray(set, (Class) getComponentType(array)); + return ofArray(set, (Class) getComponentType(array)); } /** diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/array/ArrayWrapper.java b/hutool-core/src/main/java/org/dromara/hutool/core/array/ArrayWrapper.java index 41f72b541..03dc2d3a0 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/array/ArrayWrapper.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/array/ArrayWrapper.java @@ -7,6 +7,7 @@ import org.dromara.hutool.core.util.ObjUtil; import java.lang.reflect.Array; import java.util.Arrays; +import java.util.Comparator; import java.util.function.Predicate; import java.util.function.UnaryOperator; @@ -410,38 +411,141 @@ public class ArrayWrapper implements Wrapper { /** * 获取子数组 * - * @param begin 开始位置(包括) - * @param end 结束位置(不包括) + * @param beginInclude 开始位置(包括) + * @param endExclude 结束位置(不包括) * @return 新的数组 * @see Arrays#copyOfRange(Object[], int, int) * @since 4.2.2 */ @SuppressWarnings({"unchecked", "SuspiciousSystemArraycopy"}) - public A getSub(int begin, int end) { + public A getSub(int beginInclude, int endExclude) { final int length = this.length; - if (begin < 0) { - begin += length; + if (beginInclude < 0) { + beginInclude += length; } - if (end < 0) { - end += length; + if (endExclude < 0) { + endExclude += length; } - if (begin > end) { - final int tmp = begin; - begin = end; - end = tmp; + if (beginInclude > endExclude) { + final int tmp = beginInclude; + beginInclude = endExclude; + endExclude = tmp; } - if (begin >= length) { + if (beginInclude >= length) { return (A) Array.newInstance(this.componentType, 0); } - if (end > length) { - end = length; + if (endExclude > length) { + endExclude = length; } - final A result = (A) Array.newInstance(this.componentType, end - begin); - System.arraycopy(this.array, begin, result, 0, end - begin); + final A result = (A) Array.newInstance(this.componentType, endExclude - beginInclude); + System.arraycopy(this.array, beginInclude, result, 0, endExclude - beginInclude); return result; } + /** + * 获取子数组 + * + * @param beginInclude 开始位置(包括) + * @param endExclude 结束位置(不包括) + * @param step 步进 + * @return 新的数组 + */ + @SuppressWarnings("unchecked") + public A getSub(int beginInclude, int endExclude, int step) { + final int length = this.length; + if (beginInclude < 0) { + beginInclude += length; + } + if (endExclude < 0) { + endExclude += length; + } + if (beginInclude > endExclude) { + final int tmp = beginInclude; + beginInclude = endExclude; + endExclude = tmp; + } + if (beginInclude >= length) { + return (A) Array.newInstance(this.componentType, 0); + } + if (endExclude > length) { + endExclude = length; + } + + if (step <= 1) { + step = 1; + } + + final int size = (endExclude - beginInclude + step - 1) / step; + final A result = (A) Array.newInstance(this.componentType, size); + int j = 0; + for (int i = beginInclude; i < endExclude; i += step) { + Array.set(result, j, get(i)); + j++; + } + return result; + } + + /** + * 检查数组是否有序,升序或者降序 + *

若传入空数组,则返回{@code false};元素全部相等,返回 {@code true}

+ * + * @param comparator 比较器 + * @return 数组是否有序 + * @throws NullPointerException 如果数组元素含有null值 + * @since 6.0.0 + */ + public boolean isSorted(final Comparator comparator) { + if (isEmpty()) { + return false; + } + final int lastIndex = this.length - 1; + // 对比第一个和最后一个元素,大致预估这个数组是升序还是降序 + final int cmp = comparator.compare(get(0), get(lastIndex)); + if (cmp < 0) { + return isSorted(comparator, false); + } else if (cmp > 0) { + return isSorted(comparator, true); + } + + // 可能全等数组 + for (int i = 0; i < lastIndex; i++) { + if (comparator.compare(get(i), get(i + 1)) != 0) { + return false; + } + } + return true; + } + + /** + * 数组是否有有序 + *
    + *
  • 反序,前一个小于后一个则返回错
  • + *
  • 正序,前一个大于后一个则返回错
  • + *
+ * + * @param comparator {@link Comparator} + * @param isDESC 是否反序 + * @return 是否有序 + */ + public boolean isSorted(final Comparator comparator, final boolean isDESC) { + if (null == comparator) { + return false; + } + + int compare; + for (int i = 0; i < this.length; i++) { + compare = comparator.compare(get(i), get(i + 1)); + if ((isDESC && compare < 0) || + (false == isDESC && compare > 0)) { + // 反序,前一个小于后一个则返回错 + // 正序,前一个大于后一个则返回错 + return false; + } + } + return true; + } + @Override public String toString() { final A array = this.array; diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/comparator/CompareUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/comparator/CompareUtil.java index 8d358125d..f1673bf2e 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/comparator/CompareUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/comparator/CompareUtil.java @@ -317,7 +317,7 @@ public class CompareUtil { */ @SuppressWarnings("unchecked") public static Comparator comparingIndexed(final Function keyExtractor, final Iterable objs) { - return comparingIndexed(keyExtractor, false, ArrayUtil.toArray(objs, (Class) objs.iterator().next().getClass())); + return comparingIndexed(keyExtractor, false, ArrayUtil.ofArray(objs, (Class) objs.iterator().next().getClass())); } /** diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/io/BufferUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/io/BufferUtil.java index 712234401..d72e6ebfb 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/io/BufferUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/io/BufferUtil.java @@ -20,6 +20,7 @@ import org.dromara.hutool.core.util.CharsetUtil; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; +import java.util.Arrays; /** * {@link ByteBuffer} 工具类
@@ -31,6 +32,26 @@ import java.nio.charset.Charset; */ public class BufferUtil { + /** + * {@link ByteBuffer} 转byte数组 + * + * @param bytebuffer {@link ByteBuffer} + * @return byte数组 + */ + public static byte[] toBytes(final ByteBuffer bytebuffer) { + if (bytebuffer.hasArray()) { + return Arrays.copyOfRange(bytebuffer.array(), bytebuffer.position(), bytebuffer.limit()); + } else { + final int oldPosition = bytebuffer.position(); + bytebuffer.position(0); + final int size = bytebuffer.limit(); + final byte[] buffers = new byte[size]; + bytebuffer.get(buffers); + bytebuffer.position(oldPosition); + return buffers; + } + } + /** * 拷贝到一个新的ByteBuffer * diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/array/ArrayWrapperTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/array/ArrayWrapperTest.java new file mode 100644 index 000000000..1390b68a6 --- /dev/null +++ b/hutool-core/src/test/java/org/dromara/hutool/core/array/ArrayWrapperTest.java @@ -0,0 +1,41 @@ +package org.dromara.hutool.core.array; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class ArrayWrapperTest { + + @Test + void getSubTest() { + ArrayWrapper array = ArrayWrapper.of(new int[]{1, 2, 3, 4, 5}); + int[] sub = array.getSub(1, 4); + Assertions.assertArrayEquals(new int[]{2, 3, 4}, sub); + + array = ArrayWrapper.of(new int[]{1, 2, 3, 4, 5, 6}); + sub = array.getSub(1, 4); + Assertions.assertArrayEquals(new int[]{2, 3, 4}, sub); + } + + @Test + void getSubStepTest() { + ArrayWrapper array = ArrayWrapper.of(new int[]{1, 2, 3, 4, 5}); + int[] sub = array.getSub(1, 4, 2); + Assertions.assertArrayEquals(new int[]{2, 4}, sub); + + array = ArrayWrapper.of(new int[]{1, 2, 3, 4, 5, 6}); + sub = array.getSub(1, 4, 2); + Assertions.assertArrayEquals(new int[]{2, 4}, sub); + + array = ArrayWrapper.of(new int[]{1, 2, 3, 4, 5, 6}); + sub = array.getSub(0, 5, 2); + Assertions.assertArrayEquals(new int[]{1, 3, 5}, sub); + + array = ArrayWrapper.of(new int[]{1, 2, 3, 4, 5, 6}); + sub = array.getSub(0, 5, 3); + Assertions.assertArrayEquals(new int[]{1, 4}, sub); + + array = ArrayWrapper.of(new int[]{1, 2, 3, 4, 5, 6}); + sub = array.getSub(1, 6, 2); + Assertions.assertArrayEquals(new int[]{2, 4, 6}, sub); + } +} diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/util/ArrayUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/util/ArrayUtilTest.java index aa6901c0b..fff4307cd 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/util/ArrayUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/util/ArrayUtilTest.java @@ -305,7 +305,7 @@ public class ArrayUtilTest { @Test public void toArrayTest() { final List list = ListUtil.of("A", "B", "C", "D"); - final String[] array = ArrayUtil.toArray(list, String.class); + final String[] array = ArrayUtil.ofArray(list, String.class); Assertions.assertEquals("A", array[0]); Assertions.assertEquals("B", array[1]); Assertions.assertEquals("C", array[2]);