diff --git a/CHANGELOG.md b/CHANGELOG.md
index 636bbfce8..fdbc23004 100755
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,10 +2,11 @@
# 🚀Changelog
-------------------------------------------------------------------------------------------------------------
-# 5.8.29(2024-05-29)
+# 5.8.29(2024-06-02)
### 🐣新特性
* 【core 】 DateUtil增加offsetYear方法
+* 【core 】 ListUtil增加move方法(issue#3603@Github)
### 🐞Bug修复
diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java b/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java
index 88debbf3e..e1e521966 100755
--- a/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java
@@ -5,20 +5,11 @@ import cn.hutool.core.comparator.PropertyComparator;
import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Matcher;
-import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.PageUtil;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.RandomAccess;
+import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;
@@ -420,10 +411,10 @@ public class ListUtil {
* 在指定位置设置元素。当index小于List的长度时,替换指定位置的值,否则追加{@code paddingElement}直到到达index后,设置值
* 注意:为避免OOM问题,此方法限制index的最大值为{@code (list.size() + 1) * 10}
*
- * @param 元素类型
- * @param list List列表
- * @param index 位置
- * @param element 新元素
+ * @param 元素类型
+ * @param list List列表
+ * @param index 位置
+ * @param element 新元素
* @param paddingElement 填充的值
* @return 原List
* @since 5.8.4
@@ -435,12 +426,12 @@ public class ListUtil {
/**
* 在指定位置设置元素。当index小于List的长度时,替换指定位置的值,否则追加{@code paddingElement}直到到达index后,设置值
*
- * @param 元素类型
- * @param list List列表
- * @param index 位置
- * @param element 新元素
+ * @param 元素类型
+ * @param list List列表
+ * @param index 位置
+ * @param element 新元素
* @param paddingElement 填充的值
- * @param indexLimit 最大索引限制
+ * @param indexLimit 最大索引限制
* @return 原List
* @since 5.8.28
*/
@@ -450,7 +441,7 @@ public class ListUtil {
if (index < size) {
list.set(index, element);
} else {
- if(indexLimit > 0){
+ if (indexLimit > 0) {
// issue#3286, 增加安全检查
if (index > indexLimit) {
throw new ValidateException("Index [{}] is too large for limit: [{}]", index, indexLimit);
@@ -617,8 +608,8 @@ public class ListUtil {
}
return (list instanceof RandomAccess)
- ? new RandomAccessPartition<>(list, size)
- : new Partition<>(list, size);
+ ? new RandomAccessPartition<>(list, size)
+ : new Partition<>(list, size);
}
/**
@@ -663,8 +654,8 @@ public class ListUtil {
}
return (list instanceof RandomAccess)
- ? new RandomAccessAvgPartition<>(list, limit)
- : new AvgPartition<>(list, limit);
+ ? new RandomAccessAvgPartition<>(list, limit)
+ : new AvgPartition<>(list, limit);
}
/**
@@ -705,4 +696,29 @@ public class ListUtil {
}
}
}
+
+ /**
+ * 将元素移动到指定列表的新位置。
+ *
+ * - 如果元素不在列表中,则将其添加到新位置。
+ * - 如果元素已在列表中,则先移除它,然后再将其添加到新位置。
+ *
+ *
+ * @param list 原始列表,元素将在这个列表上进行操作。
+ * @param element 需要移动的元素。
+ * @param newPosition 元素的新位置,从0开始计数,位置计算是以移除元素后的列表位置计算的
+ * @param 列表和元素的通用类型。
+ * @return 更新后的列表。
+ * @since 5.8.29
+ */
+ public static List move(List list, T element, int newPosition) {
+ Assert.notNull(list);
+ if (false == list.contains(element)) {
+ list.add(newPosition, element);
+ } else {
+ list.remove(element);
+ list.add(newPosition, element);
+ }
+ return list;
+ }
}
diff --git a/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java
index cb26c1e56..f0fd596d5 100644
--- a/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java
@@ -16,23 +16,25 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import static org.junit.Assert.assertEquals;
+
public class ListUtilTest {
@Test
public void splitTest() {
List> lists = ListUtil.split(null, 3);
- Assert.assertEquals(ListUtil.empty(), lists);
+ assertEquals(ListUtil.empty(), lists);
lists = ListUtil.split(Arrays.asList(1, 2, 3, 4), 1);
- Assert.assertEquals("[[1], [2], [3], [4]]", lists.toString());
+ assertEquals("[[1], [2], [3], [4]]", lists.toString());
lists = ListUtil.split(Arrays.asList(1, 2, 3, 4), 2);
- Assert.assertEquals("[[1, 2], [3, 4]]", lists.toString());
+ assertEquals("[[1, 2], [3, 4]]", lists.toString());
lists = ListUtil.split(Arrays.asList(1, 2, 3, 4), 3);
- Assert.assertEquals("[[1, 2, 3], [4]]", lists.toString());
+ assertEquals("[[1, 2, 3], [4]]", lists.toString());
lists = ListUtil.split(Arrays.asList(1, 2, 3, 4), 4);
- Assert.assertEquals("[[1, 2, 3, 4]]", lists.toString());
+ assertEquals("[[1, 2, 3, 4]]", lists.toString());
lists = ListUtil.split(Arrays.asList(1, 2, 3, 4), 5);
- Assert.assertEquals("[[1, 2, 3, 4]]", lists.toString());
+ assertEquals("[[1, 2, 3, 4]]", lists.toString());
}
@Test
@@ -54,7 +56,7 @@ public class ListUtilTest {
final List> ListSplitResult = ListUtil.split(list, size);
stopWatch.stop();
- Assert.assertEquals(CollSplitResult, ListSplitResult);
+ assertEquals(CollSplitResult, ListSplitResult);
Console.log(stopWatch.prettyPrint());
}
@@ -62,25 +64,25 @@ public class ListUtilTest {
@Test
public void splitAvgTest() {
List> lists = ListUtil.splitAvg(null, 3);
- Assert.assertEquals(ListUtil.empty(), lists);
+ assertEquals(ListUtil.empty(), lists);
lists = ListUtil.splitAvg(Arrays.asList(1, 2, 3, 4), 1);
- Assert.assertEquals("[[1, 2, 3, 4]]", lists.toString());
+ assertEquals("[[1, 2, 3, 4]]", lists.toString());
lists = ListUtil.splitAvg(Arrays.asList(1, 2, 3, 4), 2);
- Assert.assertEquals("[[1, 2], [3, 4]]", lists.toString());
+ assertEquals("[[1, 2], [3, 4]]", lists.toString());
lists = ListUtil.splitAvg(Arrays.asList(1, 2, 3, 4), 3);
- Assert.assertEquals("[[1, 2], [3], [4]]", lists.toString());
+ assertEquals("[[1, 2], [3], [4]]", lists.toString());
lists = ListUtil.splitAvg(Arrays.asList(1, 2, 3, 4), 4);
- Assert.assertEquals("[[1], [2], [3], [4]]", lists.toString());
+ assertEquals("[[1], [2], [3], [4]]", lists.toString());
lists = ListUtil.splitAvg(Arrays.asList(1, 2, 3), 2);
- Assert.assertEquals("[[1, 2], [3]]", lists.toString());
+ assertEquals("[[1, 2], [3]]", lists.toString());
}
@Test
public void splitAvgTest2() {
List> lists = ListUtil.splitAvg(Arrays.asList(1, 2, 3), 5);
- Assert.assertEquals("[[1], [2], [3], [], []]", lists.toString());
+ assertEquals("[[1], [2], [3], [], []]", lists.toString());
}
@Test(expected = IllegalArgumentException.class)
@@ -93,9 +95,9 @@ public class ListUtilTest {
public void editTest() {
final List a = ListUtil.toLinkedList("1", "2", "3");
final List filter = (List) CollUtil.edit(a, str -> "edit" + str);
- Assert.assertEquals("edit1", filter.get(0));
- Assert.assertEquals("edit2", filter.get(1));
- Assert.assertEquals("edit3", filter.get(2));
+ assertEquals("edit1", filter.get(0));
+ assertEquals("edit2", filter.get(1));
+ assertEquals("edit3", filter.get(2));
}
@Test
@@ -183,8 +185,8 @@ public class ListUtilTest {
sub.remove(0);
// 对子列表操作不影响原列表
- Assert.assertEquals(4, of.size());
- Assert.assertEquals(1, sub.size());
+ assertEquals(4, of.size());
+ assertEquals(1, sub.size());
}
@Test
@@ -205,18 +207,18 @@ public class ListUtilTest {
);
final List order = ListUtil.sortByProperty(beanList, "order");
- Assert.assertEquals("test1", order.get(0).getName());
- Assert.assertEquals("test2", order.get(1).getName());
- Assert.assertEquals("test3", order.get(2).getName());
- Assert.assertEquals("test4", order.get(3).getName());
- Assert.assertEquals("test5", order.get(4).getName());
+ assertEquals("test1", order.get(0).getName());
+ assertEquals("test2", order.get(1).getName());
+ assertEquals("test3", order.get(2).getName());
+ assertEquals("test4", order.get(3).getName());
+ assertEquals("test5", order.get(4).getName());
}
@Test
public void swapIndex() {
final List list = Arrays.asList(7, 2, 8, 9);
ListUtil.swapTo(list, 8, 1);
- Assert.assertEquals(8, (int) list.get(1));
+ assertEquals(8, (int) list.get(1));
}
@Test
@@ -230,11 +232,11 @@ public class ListUtilTest {
final List