From 3359e740ac6f7ae9a72c6ae011e7f5964c3cedf7 Mon Sep 17 00:00:00 2001 From: Looly Date: Sun, 2 Jun 2024 10:05:41 +0800 Subject: [PATCH] =?UTF-8?q?ListUtil=E5=A2=9E=E5=8A=A0move=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 +- .../cn/hutool/core/collection/ListUtil.java | 64 ++++++++------ .../hutool/core/collection/ListUtilTest.java | 85 ++++++++++++------- 3 files changed, 96 insertions(+), 56 deletions(-) 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> list = Arrays.asList(map1, map2, map3); ListUtil.swapElement(list, map2, map3); Map map = list.get(2); - Assert.assertEquals("李四", map.get("2")); + assertEquals("李四", map.get("2")); ListUtil.swapElement(list, map2, map1); map = list.get(0); - Assert.assertEquals("李四", map.get("2")); + assertEquals("李四", map.get("2")); } @Test @@ -244,21 +246,42 @@ public class ListUtilTest { // 替换原值 ListUtil.setOrPadding(list, 0, "a"); - Assert.assertEquals("[a]", list.toString()); + assertEquals("[a]", list.toString()); //append值 ListUtil.setOrPadding(list, 1, "a"); - Assert.assertEquals("[a, a]", list.toString()); + assertEquals("[a, a]", list.toString()); // padding null 后加入值 ListUtil.setOrPadding(list, 3, "a"); - Assert.assertEquals(4, list.size()); + assertEquals(4, list.size()); } @Test public void reverseNewTest() { final List view = ListUtil.of(1, 2, 3); final List reverse = ListUtil.reverseNew(view); - Assert.assertEquals("[3, 2, 1]", reverse.toString()); + assertEquals("[3, 2, 1]", reverse.toString()); + } + + @Test + public void testMoveElementToPosition() { + List list = new ArrayList<>(Arrays.asList("A", "B", "C", "D")); + + // Move "B" to position 2 + List expectedResult1 = new ArrayList<>(Arrays.asList("A", "C", "B", "D")); + assertEquals(expectedResult1, ListUtil.move(list, "B", 2)); + + list = new ArrayList<>(Arrays.asList("A", "B", "C", "D")); + + // Move "D" to position 0 + List expectedResult2 = new ArrayList<>(Arrays.asList("D", "A", "B", "C")); + assertEquals(expectedResult2, ListUtil.move(list, "D", 0)); + + list = new ArrayList<>(Arrays.asList("A", "B", "C", "D")); + + // Move "E" (not in list) to position 1 + List expectedResult3 = new ArrayList<>(Arrays.asList("A", "E", "B", "C", "D")); + assertEquals(expectedResult3, ListUtil.move(list, "E", 1)); } }