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 1b6ccdde9..e713cd499 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,7 +13,6 @@
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.comparator.CompareUtil;
@@ -51,12 +50,13 @@ public class ArrayUtil extends PrimitiveArrayUtil {
* @param values 元素值
* @return 数组
*/
- public static A ofArray(final Object values) {
- return ofArray(values, null);
+ public static A castOrWrapSingle(final Object values) {
+ return castOrWrapSingle(values, null);
}
/**
- * 转为数组,如果values为数组,返回,否则返回一个只有values一个元素的数组
+ * 转为数组,如果values为数组,返回,否则返回一个只有values一个元素的数组
+ * 注意:values的元素类型或其本身类型必须和提供的elementType完全一致
*
* @param 数组类型
* @param values 元素值
@@ -64,36 +64,33 @@ public class ArrayUtil extends PrimitiveArrayUtil {
* @return 数组
*/
@SuppressWarnings("unchecked")
- public static A ofArray(final Object values, final Class> elementType) {
+ public static A castOrWrapSingle(final Object values, final Class> elementType) {
if (isArray(values)) {
return (A) values;
}
+ return wrapSingle(values, elementType);
+ }
+
+ /**
+ * 包装单一元素为数组
+ *
+ * @param 数组类型
+ * @param value 元素值
+ * @param elementType 数组元素类型,{@code null}表示使用value的类型
+ * @return 数组
+ */
+ @SuppressWarnings("unchecked")
+ public static A wrapSingle(final Object value, final Class> elementType) {
// 插入单个元素
final Object newInstance = Array.newInstance(
- null == elementType ? values.getClass() : elementType, 1);
- Array.set(newInstance, 0, values);
+ null == elementType ? value.getClass() : elementType, 1);
+ Array.set(newInstance, 0, value);
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));
- }
-
- /**
- * 将集合转为数组
+ * 将集合转为数组,如果集合为{@code null},则返回空的数组(元素个数为0)
*
* @param 数组元素类型
* @param iterable {@link Iterable}
@@ -102,7 +99,26 @@ public class ArrayUtil extends PrimitiveArrayUtil {
* @since 3.0.9
*/
public static T[] ofArray(final Iterable iterable, final Class componentType) {
- return ofArray(IterUtil.getIter(iterable), componentType);
+ if (null == iterable) {
+ return newArray(componentType, 0);
+ }
+
+ if (iterable instanceof List) {
+ // List
+ return ((List) iterable).toArray(newArray(componentType, 0));
+ } else if (iterable instanceof Collection) {
+ // 其它集合
+ final int size = ((Collection) iterable).size();
+ final T[] result = newArray(componentType, size);
+ int i = 0;
+ for (final T element : iterable) {
+ result[i] = element;
+ i++;
+ }
+ }
+
+ // 自定义Iterable转为List处理
+ return ListUtil.of(iterable.iterator()).toArray(newArray(componentType, 0));
}
// endregion
@@ -666,7 +682,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
*/
public static T[] setOrAppend(final T[] array, final int index, final T value) {
if (isEmpty(array)) {
- return ofArray(value, null == array ? null : array.getClass().getComponentType());
+ return castOrWrapSingle(value, null == array ? null : array.getClass().getComponentType());
}
return ArrayWrapper.of(array).setOrAppend(index, value).getRaw();
}
@@ -683,7 +699,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
*/
public static A setOrAppend(final A array, final int index, final Object value) {
if (isEmpty(array)) {
- return ofArray(value, null == array ? null : array.getClass().getComponentType());
+ return castOrWrapSingle(value, null == array ? null : array.getClass().getComponentType());
}
return ArrayWrapper.of(array).setOrAppend(index, value).getRaw();
}
@@ -700,7 +716,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
*/
public static A setOrPadding(final A array, final int index, final Object value) {
if (index == 0 && isEmpty(array)) {
- return ofArray(value, null == array ? null : array.getClass().getComponentType());
+ return castOrWrapSingle(value, null == array ? null : array.getClass().getComponentType());
}
return ArrayWrapper.of(array).setOrPadding(index, value).getRaw();
}
@@ -719,7 +735,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
*/
public static A setOrPadding(final A array, final int index, final E value, final E paddingValue) {
if (index == 0 && isEmpty(array)) {
- return ofArray(value, null == array ? null : array.getClass().getComponentType());
+ return castOrWrapSingle(value, null == array ? null : array.getClass().getComponentType());
}
return ArrayWrapper.of(array).setOrPadding(index, value, paddingValue).getRaw();
}
@@ -805,7 +821,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
*/
public static A replace(final A array, final int index, final A values) {
if (isEmpty(array)) {
- return ofArray(values, null == array ? null : array.getClass().getComponentType());
+ return castOrWrapSingle(values, null == array ? null : array.getClass().getComponentType());
}
return ArrayWrapper.of(array).replace(index, values).getRaw();
}
@@ -833,16 +849,17 @@ public class ArrayUtil extends PrimitiveArrayUtil {
* 如果插入位置为负数,从原数组从后向前计数,若大于原数组长度,则空白处用默认值填充
*
* @param 数组类型
- * @param 数组元素类型
+ * @param 数组元素类型
* @param array 已有数组,可以为原始类型数组
* @param index 插入位置,此位置为对应此位置元素之前的空档
* @param newElements 新元素
* @return 新数组
* @since 4.0.8
*/
+ @SuppressWarnings("unchecked")
@SafeVarargs
- public static A insert(final A array, final int index, final T... newElements) {
- return ArrayWrapper.of(array).insert(index, newElements).getRaw();
+ public static A insert(final A array, final int index, final E... newElements) {
+ return ArrayWrapper.of(array).insertArray(index, (A) newElements).getRaw();
}
// endregion
@@ -1828,6 +1845,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
// endregion
// region ----- map
+
/**
* 按照指定规则,将一种类型的数组转换为另一种类型
*
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 464b4dd0a..0f24a991a 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
@@ -376,11 +376,11 @@ public class ArrayWrapper implements Wrapper, Iterable {
* 如果插入位置为负数,从原数组从后向前计数,若大于原数组长度,则空白处用默认值填充
*
* @param index 插入位置,支持负数。此位置为对应此位置元素之前的空档
- * @param element 元素
+ * @param element 单个元素
* @return 新数组
*/
public ArrayWrapper insert(final int index, final E element) {
- return insertArray(index, ArrayUtil.ofArray(element, this.componentType));
+ return insertArray(index, ArrayUtil.wrapSingle(element, this.componentType));
}
/**
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/convert/Converter.java b/hutool-core/src/main/java/org/dromara/hutool/core/convert/Converter.java
index f270aad01..beebc6064 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/convert/Converter.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/convert/Converter.java
@@ -50,4 +50,12 @@ public interface Converter {
default T convert(final Type targetType, final Object value, final T defaultValue) {
return (T) ObjUtil.defaultIfNull(convert(targetType, value), defaultValue);
}
+
+ /**
+ * 返回原值的转换器,不做转换
+ * @return Converter
+ */
+ static Converter identity(){
+ return (targetType, value) -> value;
+ }
}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/ArrayConverter.java b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/ArrayConverter.java
index a3b63c7b7..accfff5dd 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/ArrayConverter.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/ArrayConverter.java
@@ -12,14 +12,15 @@
package org.dromara.hutool.core.convert.impl;
+import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.codec.binary.Base64;
import org.dromara.hutool.core.collection.ListUtil;
+import org.dromara.hutool.core.collection.iter.IterUtil;
import org.dromara.hutool.core.convert.AbstractConverter;
import org.dromara.hutool.core.convert.Convert;
import org.dromara.hutool.core.io.SerializeUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.text.split.SplitUtil;
-import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.util.ByteUtil;
import java.io.Serializable;
@@ -73,7 +74,7 @@ public class ArrayConverter extends AbstractConverter {
}
return value.getClass().isArray() ? convertArrayToArray(targetComponentType, value)
- : convertObjectToArray(targetComponentType, value);
+ : convertObjectToArray(targetComponentType, value);
}
/**
@@ -114,10 +115,10 @@ public class ArrayConverter extends AbstractConverter {
* 非数组对数组转换
*
* @param targetComponentType 目标单个节点类型
- * @param value 被转换值
+ * @param value 被转换值
* @return 转换后的数组
*/
- private Object convertObjectToArray(final Class> targetComponentType, final Object value) {
+ private Object convertObjectToArray(final Class> targetComponentType, Object value) {
if (value instanceof CharSequence) {
if (targetComponentType == char.class || targetComponentType == Character.class) {
return convertArrayToArray(targetComponentType, value.toString().toCharArray());
@@ -125,9 +126,9 @@ public class ArrayConverter extends AbstractConverter {
//issue#2365
// 字符串转bytes,首先判断是否为Base64,是则转换,否则按照默认getBytes方法。
- if(targetComponentType == byte.class){
+ if (targetComponentType == byte.class) {
final String str = value.toString();
- if(Base64.isTypeBase64(str)){
+ if (Base64.isTypeBase64(str)) {
return Base64.decode(value.toString());
}
return str.getBytes();
@@ -138,12 +139,42 @@ public class ArrayConverter extends AbstractConverter {
return convertArrayToArray(targetComponentType, strings);
}
+ if(value instanceof Iterator){
+ value = IterUtil.asIterable((Iterator>)value);
+ }
+
+ final Object result;
+ if (value instanceof Iterable) {
+ result = convertIterableToArray(targetComponentType, (Iterable>) value);
+ } else if (value instanceof Number && byte.class == targetComponentType) {
+ // 用户可能想序列化指定对象
+ result = ByteUtil.toBytes((Number) value);
+ } else if (value instanceof Serializable && byte.class == targetComponentType) {
+ // 用户可能想序列化指定对象
+ result = SerializeUtil.serialize(value);
+ } else {
+ // everything else:
+ result = convertToSingleElementArray(targetComponentType, value);
+ }
+
+ return result;
+ }
+
+ /**
+ * 迭代器转数组
+ *
+ * @param targetComponentType 目标单个节点类型
+ * @param value 迭代器实现值
+ * @return 数组
+ */
+ private Object convertIterableToArray(final Class> targetComponentType, final Iterable> value) {
final Object result;
if (value instanceof List) {
// List转数组
final List> list = (List>) value;
- result = Array.newInstance(targetComponentType, list.size());
- for (int i = 0; i < list.size(); i++) {
+ final int size = list.size();
+ result = Array.newInstance(targetComponentType, size);
+ for (int i = 0; i < size; i++) {
Array.set(result, i, convertComponentType(targetComponentType, list.get(i)));
}
} else if (value instanceof Collection) {
@@ -156,31 +187,15 @@ public class ArrayConverter extends AbstractConverter {
Array.set(result, i, convertComponentType(targetComponentType, element));
i++;
}
- } else if (value instanceof Iterable) {
- // 可循环对象转数组,可循环对象无法获取长度,因此先转为List后转为数组
- final List> list = ListUtil.of((Iterable>) value);
- result = Array.newInstance(targetComponentType, list.size());
- for (int i = 0; i < list.size(); i++) {
- Array.set(result, i, convertComponentType(targetComponentType, list.get(i)));
- }
- } else if (value instanceof Iterator) {
- // 可循环对象转数组,可循环对象无法获取长度,因此先转为List后转为数组
- final List> list = ListUtil.of((Iterator>) value);
- result = Array.newInstance(targetComponentType, list.size());
- for (int i = 0; i < list.size(); i++) {
- Array.set(result, i, convertComponentType(targetComponentType, list.get(i)));
- }
- }else if (value instanceof Number && byte.class == targetComponentType) {
- // 用户可能想序列化指定对象
- result = ByteUtil.toBytes((Number)value);
- } else if (value instanceof Serializable && byte.class == targetComponentType) {
- // 用户可能想序列化指定对象
- result = SerializeUtil.serialize(value);
} else {
- // everything else:
- result = convertToSingleElementArray(targetComponentType, value);
+ // 可循环对象转数组,可循环对象无法获取长度,因此先转为List后转为数组
+ final List> list = ListUtil.of(value);
+ final int size = list.size();
+ result = Array.newInstance(targetComponentType, size);
+ for (int i = 0; i < size; i++) {
+ Array.set(result, i, convertComponentType(targetComponentType, list.get(i)));
+ }
}
-
return result;
}
diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/array/ArrayUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/array/ArrayUtilTest.java
index 195271744..e39fae3b1 100644
--- a/hutool-core/src/test/java/org/dromara/hutool/core/array/ArrayUtilTest.java
+++ b/hutool-core/src/test/java/org/dromara/hutool/core/array/ArrayUtilTest.java
@@ -1025,4 +1025,14 @@ public class ArrayUtilTest {
final int index = ArrayUtil.matchIndex(value -> value == 3, array);
assertEquals(2, index);
}
+
+ @Test
+ void testofArrayWithNonEmptyIterable() {
+ // Given
+ final List list = Arrays.asList("a", "b", "c");
+ // When
+ final String[] result = ArrayUtil.ofArray(list, String.class);
+ // Then
+ assertArrayEquals(list.toArray(new String[0]), result, "The array should match the list contents.");
+ }
}
diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/stream/StreamUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/stream/StreamUtilTest.java
index 034505ed8..6c9f3d0b5 100644
--- a/hutool-core/src/test/java/org/dromara/hutool/core/stream/StreamUtilTest.java
+++ b/hutool-core/src/test/java/org/dromara/hutool/core/stream/StreamUtilTest.java
@@ -21,8 +21,17 @@ import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
public class StreamUtilTest {
+ @Test
+ void toListTest() {
+ final Set