mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
add methods
This commit is contained in:
parent
0a9a178fbc
commit
ae628d5a2c
@ -11,7 +11,7 @@ import java.util.NoSuchElementException;
|
||||
* @author Looly
|
||||
* @since 4.1.1
|
||||
*/
|
||||
public class ArrayIter<E> implements IterableIter<E>, Serializable {
|
||||
public class ArrayIter<E> implements IterableIter<E>, ResettableIter<E>, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
@ -126,6 +126,7 @@ public class ArrayIter<E> implements IterableIter<E>, Serializable {
|
||||
/**
|
||||
* 重置数组位置
|
||||
*/
|
||||
@Override
|
||||
public void reset() {
|
||||
this.index = this.startIndex;
|
||||
}
|
||||
|
@ -2212,17 +2212,8 @@ public class CollUtil {
|
||||
final List<T> list = ((List<T>) collection);
|
||||
return list.get(index);
|
||||
} else {
|
||||
int i = 0;
|
||||
for (T t : collection) {
|
||||
if (i > index) {
|
||||
break;
|
||||
} else if (i == index) {
|
||||
return t;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return IterUtil.get(collection.iterator(), index);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2303,7 +2294,9 @@ public class CollUtil {
|
||||
* @return 元素类型,当列表为空或元素全部为null时,返回null
|
||||
* @see IterUtil#getElementType(Iterable)
|
||||
* @since 3.0.8
|
||||
* @deprecated 请使用 {@link IterUtil#getElementType(Iterable)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static Class<?> getElementType(Iterable<?> iterable) {
|
||||
return IterUtil.getElementType(iterable);
|
||||
}
|
||||
@ -2315,7 +2308,9 @@ public class CollUtil {
|
||||
* @return 元素类型,当列表为空或元素全部为null时,返回null
|
||||
* @see IterUtil#getElementType(Iterator)
|
||||
* @since 3.0.8
|
||||
* @deprecated 请使用 {@link IterUtil#getElementType(Iterator)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static Class<?> getElementType(Iterator<?> iterator) {
|
||||
return IterUtil.getElementType(iterator);
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ import java.util.List;
|
||||
* <p>
|
||||
* 需要注意的是,在构造此对象时需要保证原子性(原对象不被修改),最好加锁构造此对象,构造完毕后解锁。
|
||||
*
|
||||
*
|
||||
* @param <E> 元素类型
|
||||
* @author Looly
|
||||
* @since 3.0.7
|
||||
@ -26,16 +25,24 @@ public class CopiedIter<E> implements IterableIter<E>, Serializable {
|
||||
|
||||
private final Iterator<E> listIterator;
|
||||
|
||||
public static <V> CopiedIter<V> copyOf(Iterator<V> iterator){
|
||||
/**
|
||||
* 根据已有{@link Iterator},返回新的{@code CopiedIter}
|
||||
*
|
||||
* @param iterator {@link Iterator}
|
||||
* @param <E> 元素类型
|
||||
* @return {@code CopiedIter}
|
||||
*/
|
||||
public static <E> CopiedIter<E> copyOf(Iterator<E> iterator) {
|
||||
return new CopiedIter<>(iterator);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param iterator 被复制的Iterator
|
||||
*/
|
||||
public CopiedIter(Iterator<E> iterator) {
|
||||
final List<E> eleList = CollUtil.newArrayList(iterator);
|
||||
final List<E> eleList = ListUtil.toList(iterator);
|
||||
this.listIterator = eleList.iterator();
|
||||
}
|
||||
|
||||
@ -51,10 +58,11 @@ public class CopiedIter<E> implements IterableIter<E>, Serializable {
|
||||
|
||||
/**
|
||||
* 此对象不支持移除元素
|
||||
*
|
||||
* @throws UnsupportedOperationException 当调用此方法时始终抛出此异常
|
||||
*/
|
||||
@Override
|
||||
public void remove() throws UnsupportedOperationException{
|
||||
public void remove() throws UnsupportedOperationException {
|
||||
throw new UnsupportedOperationException("This is a read-only iterator.");
|
||||
}
|
||||
}
|
||||
|
@ -8,12 +8,17 @@ import cn.hutool.core.lang.Matcher;
|
||||
import cn.hutool.core.lang.func.Func1;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.text.StrJoiner;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import com.sun.xml.internal.ws.util.xml.NodeListIterator;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Dictionary;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
@ -21,6 +26,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
@ -511,11 +517,7 @@ public class IterUtil {
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static <E> List<E> toList(Iterator<E> iter) {
|
||||
final List<E> list = new ArrayList<>();
|
||||
while (iter.hasNext()) {
|
||||
list.add(iter.next());
|
||||
}
|
||||
return list;
|
||||
return ListUtil.toList(iter);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -543,17 +545,35 @@ public class IterUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取集合的第一个元素
|
||||
* 遍历{@link Iterator},获取指定index位置的元素
|
||||
*
|
||||
* @param iterator {@link Iterator}
|
||||
* @param index 位置
|
||||
* @param <E> 元素类型
|
||||
* @return 元素,找不到元素返回{@code null}
|
||||
* @since 5.8.0
|
||||
*/
|
||||
public static <E> E get(final Iterator<E> iterator, int index) throws IndexOutOfBoundsException {
|
||||
Assert.isTrue(index >= 0, "[index] must be >= 0");
|
||||
while (iterator.hasNext()) {
|
||||
index--;
|
||||
if (-1 == index) {
|
||||
return iterator.next();
|
||||
}
|
||||
iterator.next();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取集合的第一个元素,如果集合为空(null或者空集合),返回{@code null}
|
||||
*
|
||||
* @param <T> 集合元素类型
|
||||
* @param iterable {@link Iterable}
|
||||
* @return 第一个元素
|
||||
* @return 第一个元素,为空返回{@code null}
|
||||
*/
|
||||
public static <T> T getFirst(Iterable<T> iterable) {
|
||||
if (null == iterable) {
|
||||
return null;
|
||||
}
|
||||
return getFirst(iterable.iterator());
|
||||
return getFirst(getIter(iterable));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -579,10 +599,7 @@ public class IterUtil {
|
||||
* @return 第一个元素
|
||||
*/
|
||||
public static <T> T getFirst(Iterator<T> iterator) {
|
||||
if (null != iterator && iterator.hasNext()) {
|
||||
return iterator.next();
|
||||
}
|
||||
return null;
|
||||
return get(iterator, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -627,29 +644,22 @@ public class IterUtil {
|
||||
* @return 元素类型,当列表为空或元素全部为null时,返回null
|
||||
*/
|
||||
public static Class<?> getElementType(Iterable<?> iterable) {
|
||||
if (null != iterable) {
|
||||
final Iterator<?> iterator = iterable.iterator();
|
||||
return getElementType(iterator);
|
||||
}
|
||||
return null;
|
||||
return getElementType(getIter(iterable));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得{@link Iterator}对象的元素类型(通过第一个非空元素判断)<br>
|
||||
* 注意,此方法至少会调用多次next方法
|
||||
*
|
||||
* @param iterator {@link Iterator}
|
||||
* @return 元素类型,当列表为空或元素全部为null时,返回null
|
||||
* @param iterator {@link Iterator},为 {@code null}返回{@code null}
|
||||
* @return 元素类型,当列表为空或元素全部为{@code null}时,返回{@code null}
|
||||
*/
|
||||
public static Class<?> getElementType(Iterator<?> iterator) {
|
||||
final Iterator<?> iter2 = new CopiedIter<>(iterator);
|
||||
while (iter2.hasNext()) {
|
||||
final Object t = iter2.next();
|
||||
if (null != t) {
|
||||
return t.getClass();
|
||||
}
|
||||
if (null == iterator) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
final Object ele = getFirstNoneNull(iterator);
|
||||
return null == ele ? null : ele.getClass();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -751,9 +761,9 @@ public class IterUtil {
|
||||
/**
|
||||
* 获取一个新的 {@link FilterIter},用于过滤指定元素
|
||||
*
|
||||
* @param iterator 被包装的 {@link Iterator}
|
||||
* @param filter 过滤断言,当{@link Filter#accept(Object)}为{@code true}时保留元素,{@code false}抛弃元素
|
||||
* @param <E> 元素类型
|
||||
* @param iterator 被包装的 {@link Iterator}
|
||||
* @param filter 过滤断言,当{@link Filter#accept(Object)}为{@code true}时保留元素,{@code false}抛弃元素
|
||||
* @param <E> 元素类型
|
||||
* @return {@link FilterIter}
|
||||
* @since 5.8.0
|
||||
*/
|
||||
@ -924,4 +934,124 @@ public class IterUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 遍历{@link Iterator}<br>
|
||||
* 当consumer为{@code null}表示不处理,但是依旧遍历{@link Iterator}
|
||||
*
|
||||
* @param iterator {@link Iterator}
|
||||
* @param consumer 节点消费,{@code null}表示不处理
|
||||
* @param <E> 元素类型
|
||||
* @since 5.8.0
|
||||
*/
|
||||
public static <E> void forEach(final Iterator<E> iterator, final Consumer<? super E> consumer) {
|
||||
if (iterator != null) {
|
||||
while (iterator.hasNext()) {
|
||||
final E element = iterator.next();
|
||||
if (null != consumer) {
|
||||
consumer.accept(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 拼接 {@link Iterator}为字符串
|
||||
*
|
||||
* @param iterator {@link Iterator}
|
||||
* @param <E> 元素类型
|
||||
* @return 字符串
|
||||
* @since 5.8.0
|
||||
*/
|
||||
public static <E> String toStr(final Iterator<E> iterator) {
|
||||
return toStr(iterator, ObjectUtil::toString);
|
||||
}
|
||||
|
||||
/**
|
||||
* 拼接 {@link Iterator}为字符串
|
||||
*
|
||||
* @param iterator {@link Iterator}
|
||||
* @param transFunc 元素转字符串函数
|
||||
* @param <E> 元素类型
|
||||
* @return 字符串
|
||||
* @since 5.8.0
|
||||
*/
|
||||
public static <E> String toStr(final Iterator<E> iterator, final Function<? super E, String> transFunc) {
|
||||
return toStr(iterator, transFunc, ", ", "[", "]");
|
||||
}
|
||||
|
||||
/**
|
||||
* 拼接 {@link Iterator}为字符串
|
||||
*
|
||||
* @param iterator {@link Iterator}
|
||||
* @param transFunc 元素转字符串函数
|
||||
* @param delimiter 分隔符
|
||||
* @param prefix 前缀
|
||||
* @param suffix 后缀
|
||||
* @param <E> 元素类型
|
||||
* @return 字符串
|
||||
* @since 5.8.0
|
||||
*/
|
||||
public static <E> String toStr(final Iterator<E> iterator,
|
||||
final Function<? super E, String> transFunc,
|
||||
final String delimiter,
|
||||
final String prefix,
|
||||
final String suffix) {
|
||||
final StrJoiner strJoiner = StrJoiner.of(delimiter, prefix, suffix);
|
||||
strJoiner.append(iterator, transFunc);
|
||||
return strJoiner.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从给定的对象中获取可能存在的{@link Iterator},规则如下:
|
||||
* <ul>
|
||||
* <li>null - null</li>
|
||||
* <li>Iterator - 直接返回</li>
|
||||
* <li>Enumeration - {@link EnumerationIter}</li>
|
||||
* <li>Collection - 调用{@link Collection#iterator()}</li>
|
||||
* <li>Map - Entry的{@link Iterator}</li>
|
||||
* <li>Dictionary - values (elements) enumeration returned as iterator</li>
|
||||
* <li>array - {@link ArrayIter}</li>
|
||||
* <li>NodeList - {@link NodeListIter}</li>
|
||||
* <li>Node - 子节点</li>
|
||||
* <li>object with iterator() public method,通过反射访问</li>
|
||||
* <li>object - 单对象的{@link ArrayIter}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param obj 可以获取{@link Iterator}的对象
|
||||
* @return {@link Iterator},如果提供对象为{@code null},返回{@code null}
|
||||
*/
|
||||
public static Iterator<?> getIter(final Object obj) {
|
||||
if (obj == null) {
|
||||
return null;
|
||||
} else if (obj instanceof Iterator) {
|
||||
return (Iterator<?>) obj;
|
||||
} else if (obj instanceof Iterable) {
|
||||
return ((Iterable<?>) obj).iterator();
|
||||
} else if (ArrayUtil.isArray(obj)) {
|
||||
return new ArrayIter<>(obj);
|
||||
} else if (obj instanceof Enumeration) {
|
||||
return new EnumerationIter<>((Enumeration<?>) obj);
|
||||
} else if (obj instanceof Map) {
|
||||
return ((Map<?, ?>) obj).entrySet().iterator();
|
||||
} else if (obj instanceof NodeList) {
|
||||
return new NodeListIterator((NodeList) obj);
|
||||
} else if (obj instanceof Node) {
|
||||
// 遍历子节点
|
||||
return new NodeListIterator(((Node) obj).getChildNodes());
|
||||
} else if (obj instanceof Dictionary) {
|
||||
return new EnumerationIter<>(((Dictionary<?, ?>) obj).elements());
|
||||
}
|
||||
|
||||
// 反射获取
|
||||
try {
|
||||
final Object iterator = ReflectUtil.invoke(obj, "iterator");
|
||||
if (iterator instanceof Iterator) {
|
||||
return (Iterator<?>) iterator;
|
||||
}
|
||||
} catch (final RuntimeException ignore) {
|
||||
// ignore
|
||||
}
|
||||
return new ArrayIter<>(new Object[]{obj});
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import java.util.Iterator;
|
||||
* @since 5.7.14
|
||||
*/
|
||||
public interface IterableIter<T> extends Iterable<T>, Iterator<T> {
|
||||
|
||||
@Override
|
||||
default Iterator<T> iterator() {
|
||||
return this;
|
||||
|
@ -0,0 +1,63 @@
|
||||
package cn.hutool.core.collection;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* 包装 {@link NodeList} 的{@link Iterator}
|
||||
* <p>
|
||||
* 此 iterator 不支持 {@link #remove()} 方法。
|
||||
*
|
||||
* @author apache commons,looly
|
||||
* @see NodeList
|
||||
* @since 5.8.0
|
||||
*/
|
||||
public class NodeListIter implements ResettableIter<Node> {
|
||||
|
||||
private final NodeList nodeList;
|
||||
/**
|
||||
* 当前位置索引
|
||||
*/
|
||||
private int index = 0;
|
||||
|
||||
/**
|
||||
* 构造, 根据给定{@link NodeList} 创建{@code NodeListIterator}
|
||||
*
|
||||
* @param nodeList {@link NodeList},非空
|
||||
*/
|
||||
public NodeListIter(final NodeList nodeList) {
|
||||
this.nodeList = Assert.notNull(nodeList, "NodeList must not be null.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return nodeList != null && index < nodeList.getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node next() {
|
||||
if (nodeList != null && index < nodeList.getLength()) {
|
||||
return nodeList.item(index++);
|
||||
}
|
||||
throw new NoSuchElementException("underlying nodeList has no more elements");
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws {@link UnsupportedOperationException}.
|
||||
*
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("remove() method not supported for a NodeListIterator.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
this.index = 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package cn.hutool.core.collection;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* 支持重置的{@link Iterator} 接口<br>
|
||||
* 通过实现{@link #reset()},重置此{@link Iterator}后可实现复用重新遍历
|
||||
*
|
||||
* @param <E> 元素类型
|
||||
* @since 5.8.0
|
||||
*/
|
||||
public interface ResettableIter<E> extends Iterator<E> {
|
||||
|
||||
/**
|
||||
* 重置,重置后可重新遍历
|
||||
*/
|
||||
void reset();
|
||||
}
|
@ -4,6 +4,7 @@ import cn.hutool.core.collection.ArrayIter;
|
||||
import cn.hutool.core.collection.IterUtil;
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -211,7 +212,7 @@ public class StrJoiner implements Appendable, Serializable {
|
||||
} else if (obj instanceof Iterable) {
|
||||
append(((Iterable<?>) obj).iterator());
|
||||
} else {
|
||||
append(String.valueOf(obj));
|
||||
append(ObjectUtil.toString(obj));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -261,24 +262,24 @@ public class StrJoiner implements Appendable, Serializable {
|
||||
/**
|
||||
* 追加{@link Iterator}中的元素到拼接器中
|
||||
*
|
||||
* @param <T> 元素类型
|
||||
* @param <E> 元素类型
|
||||
* @param iterable 元素列表
|
||||
* @param toStrFunc 元素对象转换为字符串的函数
|
||||
* @return this
|
||||
*/
|
||||
public <T> StrJoiner append(Iterable<T> iterable, Function<T, ? extends CharSequence> toStrFunc) {
|
||||
public <E> StrJoiner append(Iterable<E> iterable, Function<? super E, ? extends CharSequence> toStrFunc) {
|
||||
return append(IterUtil.getIter(iterable), toStrFunc);
|
||||
}
|
||||
|
||||
/**
|
||||
* 追加{@link Iterator}中的元素到拼接器中
|
||||
*
|
||||
* @param <T> 元素类型
|
||||
* @param <E> 元素类型
|
||||
* @param iterator 元素列表
|
||||
* @param toStrFunc 元素对象转换为字符串的函数
|
||||
* @return this
|
||||
*/
|
||||
public <T> StrJoiner append(Iterator<T> iterator, Function<T, ? extends CharSequence> toStrFunc) {
|
||||
public <E> StrJoiner append(Iterator<E> iterator, Function<? super E, ? extends CharSequence> toStrFunc) {
|
||||
if (null != iterator) {
|
||||
while (iterator.hasNext()) {
|
||||
append(toStrFunc.apply(iterator.next()));
|
||||
|
@ -9,6 +9,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -136,4 +137,11 @@ public class IterUtilTest {
|
||||
Assert.assertEquals(1, filtered.size());
|
||||
Assert.assertEquals("3", filtered.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTest() {
|
||||
HashSet<String> set = CollUtil.set(true, "A", "B", "C", "D");
|
||||
String str = IterUtil.get(set.iterator(), 2);
|
||||
Assert.assertEquals("C", str);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user