diff --git a/CHANGELOG.md b/CHANGELOG.md
index 91653efa1..ccccfb9d9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,7 @@
# 🚀Changelog
-------------------------------------------------------------------------------------------------------------
-# 5.8.0.M2 (2022-03-30)
+# 5.8.0.M2 (2022-03-31)
### ❌不兼容特性
* 【extra 】 【可能兼容问题】BeanCopierCache的key结构变更
@@ -10,6 +10,7 @@
### 🐣新特性
* 【core 】 MapUtil增加entry、ofEntries方法
* 【core 】 ZipWriter增加add方法重载
+* 【core 】 IterUtil增加filtered,增加FilterIter(issue#2228)
### 🐞Bug修复
* 【core 】 IdcardUtil#getCityCodeByIdCard位数问题(issue#2224@Github)
diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/FilterIter.java b/hutool-core/src/main/java/cn/hutool/core/collection/FilterIter.java
new file mode 100644
index 000000000..9c5ae2201
--- /dev/null
+++ b/hutool-core/src/main/java/cn/hutool/core/collection/FilterIter.java
@@ -0,0 +1,96 @@
+package cn.hutool.core.collection;
+
+import cn.hutool.core.lang.Assert;
+import cn.hutool.core.lang.Filter;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * 包装 {@link Iterator}并根据{@link Filter}定义,过滤元素输出
+ * 类实现来自Apache Commons Collection
+ *
+ * @author apache commons, looly
+ * @since 5.8.0
+ */
+public class FilterIter implements Iterator {
+
+ private final Iterator extends E> iterator;
+ private final Filter super E> filter;
+
+ /**
+ * 下一个元素
+ */
+ private E nextObject;
+ /**
+ * 标记下一个元素是否被计算
+ */
+ private boolean nextObjectSet = false;
+
+ /**
+ * 构造
+ *
+ * @param iterator 被包装的{@link Iterator}
+ * @param filter 过滤函数,{@code null}表示不过滤
+ */
+ public FilterIter(final Iterator extends E> iterator, final Filter super E> filter) {
+ this.iterator = Assert.notNull(iterator);
+ this.filter = filter;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return nextObjectSet || setNextObject();
+ }
+
+ @Override
+ public E next() {
+ if (false == nextObjectSet && false == setNextObject()) {
+ throw new NoSuchElementException();
+ }
+ nextObjectSet = false;
+ return nextObject;
+ }
+
+ @Override
+ public void remove() {
+ if (nextObjectSet) {
+ throw new IllegalStateException("remove() cannot be called");
+ }
+ iterator.remove();
+ }
+
+ /**
+ * 获取被包装的{@link Iterator}
+ *
+ * @return {@link Iterator}
+ */
+ public Iterator extends E> getIterator() {
+ return iterator;
+ }
+
+ /**
+ * 获取过滤函数
+ *
+ * @return 过滤函数,可能为{@code null}
+ */
+ public Filter super E> getFilter() {
+ return filter;
+ }
+
+ /**
+ * 设置下一个元素,如果存在返回{@code true},否则{@code false}
+ */
+ private boolean setNextObject() {
+ while (iterator.hasNext()) {
+ final E object = iterator.next();
+ if (null != filter && filter.accept(object)) {
+ nextObject = object;
+ nextObjectSet = true;
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/IterUtil.java b/hutool-core/src/main/java/cn/hutool/core/collection/IterUtil.java
index 57067264e..ddcafe36b 100644
--- a/hutool-core/src/main/java/cn/hutool/core/collection/IterUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/collection/IterUtil.java
@@ -745,17 +745,20 @@ public class IterUtil {
* @since 5.7.22
*/
public static List filterToList(Iterator iter, Filter filter) {
- final List result = new ArrayList<>();
- if (null != iter) {
- E ele;
- while (iter.hasNext()) {
- ele = iter.next();
- if (null == filter || filter.accept(ele)) {
- result.add(ele);
- }
- }
- }
- return result;
+ return toList(filtered(iter, filter));
+ }
+
+ /**
+ * 获取一个新的 {@link FilterIter},用于过滤指定元素
+ *
+ * @param iterator 被包装的 {@link Iterator}
+ * @param filter 过滤断言,当{@link Filter#accept(Object)}为{@code true}时保留元素,{@code false}抛弃元素
+ * @param 元素类型
+ * @return {@link FilterIter}
+ * @since 5.8.0
+ */
+ public static FilterIter filtered(final Iterator extends E> iterator, final Filter super E> filter) {
+ return new FilterIter<>(iterator, filter);
}
/**
diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/TransIter.java b/hutool-core/src/main/java/cn/hutool/core/collection/TransIter.java
index 058a61d8b..116fd697a 100644
--- a/hutool-core/src/main/java/cn/hutool/core/collection/TransIter.java
+++ b/hutool-core/src/main/java/cn/hutool/core/collection/TransIter.java
@@ -24,7 +24,7 @@ public class TransIter implements Iterator {
* @param backingIterator 源{@link Iterator}
* @param func 转换函数
*/
- public TransIter(Iterator extends F> backingIterator, Function super F, ? extends T> func) {
+ public TransIter(final Iterator extends F> backingIterator, final Function super F, ? extends T> func) {
this.backingIterator = Assert.notNull(backingIterator);
this.func = Assert.notNull(func);
}
diff --git a/hutool-core/src/test/java/cn/hutool/core/collection/IterUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/collection/IterUtilTest.java
index a0f9c7991..6e74468ba 100644
--- a/hutool-core/src/test/java/cn/hutool/core/collection/IterUtilTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/collection/IterUtilTest.java
@@ -103,4 +103,37 @@ public class IterUtilTest {
private String carNumber;
private String carName;
}
+
+ @Test
+ public void filterTest(){
+ List obj2 = ListUtil.toList("3");
+ List obj = ListUtil.toList("1", "3");
+
+ IterUtil.filter(obj.iterator(), obj2::contains);
+
+ Assert.assertEquals(1, obj.size());
+ Assert.assertEquals("3", obj.get(0));
+ }
+
+ @Test
+ public void filteredTest(){
+ List obj2 = ListUtil.toList("3");
+ List obj = ListUtil.toList("1", "3");
+
+ final FilterIter filtered = IterUtil.filtered(obj.iterator(), obj2::contains);
+
+ Assert.assertEquals("3", filtered.next());
+ Assert.assertFalse(filtered.hasNext());
+ }
+
+ @Test
+ public void filterToListTest(){
+ List obj2 = ListUtil.toList("3");
+ List obj = ListUtil.toList("1", "3");
+
+ final List filtered = IterUtil.filterToList(obj.iterator(), obj2::contains);
+
+ Assert.assertEquals(1, filtered.size());
+ Assert.assertEquals("3", filtered.get(0));
+ }
}