This commit is contained in:
Looly 2024-07-05 13:17:54 +08:00
parent c054d025dd
commit 47b21b951f
8 changed files with 140 additions and 68 deletions

View File

@ -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> A ofArray(final Object values) {
return ofArray(values, null);
public static <A> A castOrWrapSingle(final Object values) {
return castOrWrapSingle(values, null);
}
/**
* 转为数组如果values为数组返回否则返回一个只有values一个元素的数组
* 转为数组如果values为数组返回否则返回一个只有values一个元素的数组<br>
* 注意values的元素类型或其本身类型必须和提供的elementType完全一致
*
* @param <A> 数组类型
* @param values 元素值
@ -64,36 +64,33 @@ public class ArrayUtil extends PrimitiveArrayUtil {
* @return 数组
*/
@SuppressWarnings("unchecked")
public static <A> A ofArray(final Object values, final Class<?> elementType) {
public static <A> A castOrWrapSingle(final Object values, final Class<?> elementType) {
if (isArray(values)) {
return (A) values;
}
return wrapSingle(values, elementType);
}
/**
* 包装单一元素为数组
*
* @param <A> 数组类型
* @param value 元素值
* @param elementType 数组元素类型{@code null}表示使用value的类型
* @return 数组
*/
@SuppressWarnings("unchecked")
public static <A> 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 <T> 数组元素类型
* @param iterator {@link Iterator}
* @param componentType 集合元素类型
* @return 数组
* @since 3.0.9
*/
public static <T> T[] ofArray(final Iterator<T> iterator, final Class<T> componentType) {
if (null == iterator) {
return newArray(componentType, 0);
}
return ListUtil.of(iterator).toArray(newArray(componentType, 0));
}
/**
* 将集合转为数组
* 将集合转为数组如果集合为{@code null}则返回空的数组元素个数为0
*
* @param <T> 数组元素类型
* @param iterable {@link Iterable}
@ -102,7 +99,26 @@ public class ArrayUtil extends PrimitiveArrayUtil {
* @since 3.0.9
*/
public static <T> T[] ofArray(final Iterable<T> iterable, final Class<T> componentType) {
return ofArray(IterUtil.getIter(iterable), componentType);
if (null == iterable) {
return newArray(componentType, 0);
}
if (iterable instanceof List) {
// List
return ((List<T>) iterable).toArray(newArray(componentType, 0));
} else if (iterable instanceof Collection) {
// 其它集合
final int size = ((Collection<T>) 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> 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> 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> 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, E> 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> 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 {
* 如果插入位置为负数从原数组从后向前计数若大于原数组长度则空白处用默认值填充<br>
*
* @param <A> 数组类型
* @param <T> 数组元素类型
* @param <E> 数组元素类型
* @param array 已有数组可以为原始类型数组
* @param index 插入位置此位置为对应此位置元素之前的空档
* @param newElements 新元素
* @return 新数组
* @since 4.0.8
*/
@SuppressWarnings("unchecked")
@SafeVarargs
public static <A, T> A insert(final A array, final int index, final T... newElements) {
return ArrayWrapper.of(array).insert(index, newElements).getRaw();
public static <A, E> 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
/**
* 按照指定规则将一种类型的数组转换为另一种类型
*

View File

@ -376,11 +376,11 @@ public class ArrayWrapper<A, E> implements Wrapper<A>, Iterable<E> {
* 如果插入位置为负数从原数组从后向前计数若大于原数组长度则空白处用默认值填充<br>
*
* @param index 插入位置支持负数此位置为对应此位置元素之前的空档
* @param element 元素
* @param element 单个元素
* @return 新数组
*/
public ArrayWrapper<A, E> insert(final int index, final E element) {
return insertArray(index, ArrayUtil.ofArray(element, this.componentType));
return insertArray(index, ArrayUtil.wrapSingle(element, this.componentType));
}
/**

View File

@ -50,4 +50,12 @@ public interface Converter {
default <T> 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;
}
}

View File

@ -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;
}

View File

@ -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<String> 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.");
}
}

View File

@ -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<Object[]> a = SetUtil.of(new Object[]{1, 2}, new Object[]{3, 4});
final List<Object> objects = StreamUtil.of(a).collect(Collectors.toList());
assertEquals(2, objects.size());
}
@Test
void testIterateHierarchies() {
// 创建一个三层的树结构每个节点都有两个子节点

View File

@ -97,6 +97,17 @@ public class StatementBuilder implements Builder<StatementWrapper> {
return this;
}
/**
* 设置SQL的"?"对应的参数
*
* @param params 参数列表
* @return this
*/
public StatementBuilder setParamList(final List<Object> params) {
this.boundSql.setParams(params);
return this;
}
/**
* 设置是否返回主键
*

View File

@ -12,11 +12,11 @@
package org.dromara.hutool.db.sql;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.collection.iter.ArrayIter;
import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.lang.Opt;
import org.dromara.hutool.core.stream.StreamUtil;
import org.dromara.hutool.db.DbException;
import org.dromara.hutool.db.config.DbConfig;
import org.dromara.hutool.db.handler.ResultSetUtil;
@ -25,6 +25,7 @@ import org.dromara.hutool.db.handler.RsHandler;
import java.sql.*;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Statement和PreparedStatement工具类
@ -86,7 +87,7 @@ public class StatementUtil {
.setReturnGeneratedKey(false)
.setSqlFilter(Opt.ofNullable(config).map(DbConfig::getSqlFilters).get())
.setSql(sql)
.setParams(ArrayUtil.ofArray(paramsBatch, Object.class))
.setParamList(StreamUtil.of(paramsBatch).collect(Collectors.toList()))
.buildForBatch();
}