From 7d81b20e2b87ff7730303147e59e6459e69bb964 Mon Sep 17 00:00:00 2001 From: Looly Date: Sun, 13 Sep 2020 11:04:13 +0800 Subject: [PATCH] add trans --- CHANGELOG.md | 1 + .../cn/hutool/core/collection/CollUtil.java | 16 +++- .../cn/hutool/core/collection/IterUtil.java | 14 ++++ .../core/collection/SpliteratorUtil.java | 24 ++++++ .../core/collection/TransCollection.java | 73 +++++++++++++++++++ .../cn/hutool/core/collection/TransIter.java | 46 ++++++++++++ .../core/collection/TransSpliterator.java | 51 +++++++++++++ 7 files changed, 223 insertions(+), 2 deletions(-) create mode 100644 hutool-core/src/main/java/cn/hutool/core/collection/SpliteratorUtil.java create mode 100644 hutool-core/src/main/java/cn/hutool/core/collection/TransCollection.java create mode 100644 hutool-core/src/main/java/cn/hutool/core/collection/TransIter.java create mode 100644 hutool-core/src/main/java/cn/hutool/core/collection/TransSpliterator.java diff --git a/CHANGELOG.md b/CHANGELOG.md index e711cc8ee..65d0583ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * 【setting】 StatementUtil增加null缓存(pr#1076@Github) * 【core 】 扩充Console功能,支持可变参数(issue#1077@Github) * 【crypto 】 增加ECKeyUtil(issue#I1UOF5@Gitee) +* 【core 】 增加TransXXX(issue#I1TU1Y@Gitee) ### Bug修复 * 【core 】 修复Dict.of错误(issue#I1UUO5@Gitee) diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java b/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java index 48915ed4d..a8f1d1939 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java @@ -414,9 +414,9 @@ public class CollUtil { /** * 自定义函数判断集合是否包含某类值 * - * @param collection 集合 + * @param collection 集合 * @param containFunc 自定义判断函数 - * @param 值类型 + * @param 值类型 * @return 是否包含自定义规则的值 */ public static boolean contains(Collection collection, Predicate containFunc) { @@ -2837,6 +2837,18 @@ public class CollUtil { } } + /** + * 使用给定的转换函数,转换源集合为新类型的集合 + * + * @param 源元素类型 + * @param 目标元素类型 + * @return 新类型的集合 + * @since 5.4.3 + */ + public static Collection trans(Collection collection, Function function) { + return new TransCollection<>(collection, function); + } + // ---------------------------------------------------------------------------------------------- Interface start /** 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 53b15b249..3a5881dd0 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 @@ -807,4 +807,18 @@ public class IterUtil { public static Iterator empty() { return Collections.emptyIterator(); } + + /** + * 按照给定函数,转换{@link Iterator}为另一种类型的{@link Iterator} + * + * @param 源元素类型 + * @param 目标元素类型 + * @param iterator 源{@link Iterator} + * @param function 转换函数 + * @return 转换后的{@link Iterator} + * @since 5.4.3 + */ + public static Iterator trans(Iterator iterator, Function function) { + return new TransIter<>(iterator, function); + } } diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/SpliteratorUtil.java b/hutool-core/src/main/java/cn/hutool/core/collection/SpliteratorUtil.java new file mode 100644 index 000000000..0fe812309 --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/collection/SpliteratorUtil.java @@ -0,0 +1,24 @@ +package cn.hutool.core.collection; + +import java.util.Spliterator; +import java.util.function.Function; + +/** + * {@link Spliterator}相关工具类 + * + * @author looly + * @since 5.4.3 + */ +public class SpliteratorUtil { + + /** + * 使用给定的转换函数,转换源{@link Spliterator}为新类型的{@link Spliterator} + * + * @param 源元素类型 + * @param 目标元素类型 + * @return 新类型的{@link Spliterator} + */ + public static Spliterator trans(Spliterator fromSpliterator, Function function) { + return new TransSpliterator<>(fromSpliterator, function); + } +} diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/TransCollection.java b/hutool-core/src/main/java/cn/hutool/core/collection/TransCollection.java new file mode 100644 index 000000000..84c08fadb --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/collection/TransCollection.java @@ -0,0 +1,73 @@ +package cn.hutool.core.collection; + +import cn.hutool.core.lang.Assert; + +import java.util.AbstractCollection; +import java.util.Collection; +import java.util.Iterator; +import java.util.Spliterator; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; + +/** + * 使用给定的转换函数,转换源集合为新类型的集合 + * + * @param 源元素类型 + * @param 目标元素类型 + * @author looly + * @since 5.4.3 + */ +public class TransCollection extends AbstractCollection { + + private final Collection fromCollection; + private final Function function; + + /** + * 构造 + * + * @param fromCollection 源集合 + * @param function 转换函数 + */ + public TransCollection(Collection fromCollection, Function function) { + this.fromCollection = Assert.notNull(fromCollection); + this.function = Assert.notNull(function); + } + + @Override + public Iterator iterator() { + return IterUtil.trans(fromCollection.iterator(), function); + } + + @Override + public void clear() { + fromCollection.clear(); + } + + @Override + public boolean isEmpty() { + return fromCollection.isEmpty(); + } + + @Override + public void forEach(Consumer action) { + Assert.notNull(action); + fromCollection.forEach((f) -> action.accept(function.apply(f))); + } + + @Override + public boolean removeIf(Predicate filter) { + Assert.notNull(filter); + return fromCollection.removeIf(element -> filter.test(function.apply(element))); + } + + @Override + public Spliterator spliterator() { + return SpliteratorUtil.trans(fromCollection.spliterator(), function); + } + + @Override + public int size() { + return fromCollection.size(); + } +} \ No newline at end of file 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 new file mode 100644 index 000000000..4c0c8dd59 --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/collection/TransIter.java @@ -0,0 +1,46 @@ +package cn.hutool.core.collection; + +import cn.hutool.core.lang.Assert; + +import java.util.Iterator; +import java.util.function.Function; + +/** + * 使用给定的转换函数,转换源{@link Iterator}为新类型的{@link Iterator} + * + * @param 源元素类型 + * @param 目标元素类型 + * @author looly + * @since 5.4.3 + */ +public class TransIter implements Iterator { + + private final Iterator backingIterator; + private final Function func; + + /** + * 构造 + * + * @param backingIterator 源{@link Iterator} + * @param func 转换函数 + */ + public TransIter(Iterator backingIterator, Function func) { + this.backingIterator = Assert.notNull(backingIterator); + this.func = Assert.notNull(func); + } + + @Override + public final boolean hasNext() { + return backingIterator.hasNext(); + } + + @Override + public final T next() { + return func.apply(backingIterator.next()); + } + + @Override + public final void remove() { + backingIterator.remove(); + } +} diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/TransSpliterator.java b/hutool-core/src/main/java/cn/hutool/core/collection/TransSpliterator.java new file mode 100644 index 000000000..78b9b8a19 --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/collection/TransSpliterator.java @@ -0,0 +1,51 @@ +package cn.hutool.core.collection; + +import java.util.Spliterator; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * 使用给定的转换函数,转换源{@link Spliterator}为新类型的{@link Spliterator} + * + * @param 源元素类型 + * @param 目标元素类型 + * @author looly + * @since 5.4.3 + */ +public class TransSpliterator implements Spliterator { + private final Spliterator fromSpliterator; + private final Function function; + + public TransSpliterator(Spliterator fromSpliterator, Function function) { + this.fromSpliterator = fromSpliterator; + this.function = function; + } + + @Override + public boolean tryAdvance(Consumer action) { + return fromSpliterator.tryAdvance( + fromElement -> action.accept(function.apply(fromElement))); + } + + @Override + public void forEachRemaining(Consumer action) { + fromSpliterator.forEachRemaining(fromElement -> action.accept(function.apply(fromElement))); + } + + @Override + public Spliterator trySplit() { + Spliterator fromSplit = fromSpliterator.trySplit(); + return (fromSplit != null) ? new TransSpliterator<>(fromSplit, function) : null; + } + + @Override + public long estimateSize() { + return fromSpliterator.estimateSize(); + } + + @Override + public int characteristics() { + return fromSpliterator.characteristics() + & ~(Spliterator.DISTINCT | Spliterator.NONNULL | Spliterator.SORTED); + } +}