mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
add iter
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# 5.7.14 (2021-09-24)
|
||||
# 5.7.14 (2021-09-25)
|
||||
|
||||
### 🐣新特性
|
||||
* 【extra 】 修复HttpCookie设置cookies的方法,不符合RFC6265规范问题(issue#I4B70D@Gitee)
|
||||
@@ -11,6 +11,7 @@
|
||||
* 【setting】 增加YamlUtil
|
||||
* 【extra 】 SenvenZExtractor改名为SevenZExtractor,增加getFirst、get方法
|
||||
* 【core 】 DateConverter修改返回java.util.Date而非DateTime(issue#I4BOAP@Gitee)
|
||||
* 【core 】 增加IterableIter、ComputeIter
|
||||
|
||||
### 🐞Bug修复
|
||||
* 【http 】 修复HttpCookie设置cookies的方法,不符合RFC6265规范问题(pr#418@Gitee)
|
||||
|
@@ -2,7 +2,6 @@ package cn.hutool.core.collection;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
@@ -12,7 +11,7 @@ import java.util.NoSuchElementException;
|
||||
* @author Looly
|
||||
* @since 4.1.1
|
||||
*/
|
||||
public class ArrayIter<E> implements Iterator<E>, Iterable<E>, Serializable {
|
||||
public class ArrayIter<E> implements IterableIter<E>, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
@@ -130,10 +129,4 @@ public class ArrayIter<E> implements Iterator<E>, Iterable<E>, Serializable {
|
||||
public void reset() {
|
||||
this.index = this.startIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,73 @@
|
||||
package cn.hutool.core.collection;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* 带有计算属性的遍历器<br>
|
||||
* 通过继承此抽象遍历器,实现{@link #computeNext()}计算下一个节点,即可完成节点遍历<br>
|
||||
* 当调用{@link #hasNext()}时将此方法产生的节点缓存,直到调用{@link #next()}取出<br>
|
||||
* 当无下一个节点时,须返回{@code null}表示遍历结束
|
||||
*
|
||||
* @param <T> 节点类型
|
||||
* @author looly
|
||||
* @since 5.7.14
|
||||
*/
|
||||
public abstract class ComputeIter<T> implements Iterator<T> {
|
||||
|
||||
private T next;
|
||||
/**
|
||||
* A flag indicating if the iterator has been fully read.
|
||||
*/
|
||||
private boolean finished;
|
||||
|
||||
/**
|
||||
* 计算新的节点,通过实现此方法,当调用{@link #hasNext()}时将此方法产生的节点缓存,直到调用{@link #next()}取出<br>
|
||||
* 当无下一个节点时,须返回{@code null}表示遍历结束
|
||||
*
|
||||
* @return 节点值
|
||||
*/
|
||||
protected abstract T computeNext();
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (null != next) {
|
||||
// 用户读取了节点,但是没有使用
|
||||
return true;
|
||||
} else if (finished) {
|
||||
// 读取结束
|
||||
return false;
|
||||
}
|
||||
|
||||
T result = computeNext();
|
||||
if (null == result) {
|
||||
// 不再有新的节点,结束
|
||||
this.finished = true;
|
||||
return false;
|
||||
} else {
|
||||
this.next = result;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
if (false == hasNext()) {
|
||||
throw new NoSuchElementException("No more lines");
|
||||
}
|
||||
|
||||
T result = this.next;
|
||||
// 清空cache,表示此节点读取完毕,下次计算新节点
|
||||
this.next = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动结束遍历器,用于关闭操作等
|
||||
*/
|
||||
public void finish(){
|
||||
this.finished = true;
|
||||
this.next = null;
|
||||
}
|
||||
}
|
@@ -95,6 +95,7 @@ public class ConcurrentHashSet<E> extends AbstractSet<E> implements java.io.Seri
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
//noinspection SuspiciousMethodCalls
|
||||
return map.containsKey(o);
|
||||
}
|
||||
|
||||
|
@@ -21,7 +21,7 @@ import java.util.List;
|
||||
* @author Looly
|
||||
* @since 3.0.7
|
||||
*/
|
||||
public class CopiedIter<E> implements Iterator<E>, Iterable<E>, Serializable {
|
||||
public class CopiedIter<E> implements IterableIter<E>, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Iterator<E> listIterator;
|
||||
@@ -57,10 +57,4 @@ public class CopiedIter<E> implements Iterator<E>, Iterable<E>, Serializable {
|
||||
public void remove() throws UnsupportedOperationException{
|
||||
throw new UnsupportedOperationException("This is a read-only iterator.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@ import java.util.Iterator;
|
||||
* @param <E> 元素类型
|
||||
* @since 4.1.1
|
||||
*/
|
||||
public class EnumerationIter<E> implements Iterator<E>, Iterable<E>, Serializable{
|
||||
public class EnumerationIter<E> implements IterableIter<E>, Serializable{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Enumeration<E> e;
|
||||
@@ -38,10 +38,4 @@ public class EnumerationIter<E> implements Iterator<E>, Iterable<E>, Serializabl
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,17 @@
|
||||
package cn.hutool.core.collection;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* 提供合成接口,共同提供{@link Iterable}和{@link Iterator}功能
|
||||
*
|
||||
* @param <T> 节点类型
|
||||
* @author looly
|
||||
* @since 5.7.14
|
||||
*/
|
||||
public interface IterableIter<T> extends Iterable<T>, Iterator<T> {
|
||||
@Override
|
||||
default Iterator<T> iterator() {
|
||||
return this;
|
||||
}
|
||||
}
|
@@ -11,8 +11,6 @@ import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.Serializable;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* 将Reader包装为一个按照行读取的Iterator<br>
|
||||
@@ -36,15 +34,10 @@ import java.util.NoSuchElementException;
|
||||
* @author looly
|
||||
* @since 4.1.1
|
||||
*/
|
||||
public class LineIter implements Iterator<String>, Iterable<String>, Closeable, Serializable {
|
||||
public class LineIter extends ComputeIter<String> implements IterableIter<String>, Closeable, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** The reader that is being read. */
|
||||
private final BufferedReader bufferedReader;
|
||||
/** The current line. */
|
||||
private String cachedLine;
|
||||
/** A flag indicating if the iterator has been fully read. */
|
||||
private boolean finished = false;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
@@ -69,82 +62,31 @@ public class LineIter implements Iterator<String>, Iterable<String>, Closeable,
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
/**
|
||||
* 判断{@link Reader}是否可以存在下一行。
|
||||
* If there is an {@code IOException} then {@link #close()} will be called on this instance.
|
||||
*
|
||||
* @return {@code true} 表示有更多行
|
||||
* @throws IORuntimeException IO异常
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext() throws IORuntimeException {
|
||||
if (cachedLine != null) {
|
||||
return true;
|
||||
} else if (finished) {
|
||||
return false;
|
||||
} else {
|
||||
try {
|
||||
while (true) {
|
||||
String line = bufferedReader.readLine();
|
||||
if (line == null) {
|
||||
finished = true;
|
||||
return false;
|
||||
} else if (isValidLine(line)) {
|
||||
cachedLine = line;
|
||||
return true;
|
||||
}
|
||||
protected String computeNext() {
|
||||
try {
|
||||
while (true) {
|
||||
String line = bufferedReader.readLine();
|
||||
if (line == null) {
|
||||
return null;
|
||||
} else if (isValidLine(line)) {
|
||||
return line;
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
close();
|
||||
throw new IORuntimeException(ioe);
|
||||
// 无效行,则跳过进入下一行
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
close();
|
||||
throw new IORuntimeException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回下一行内容
|
||||
*
|
||||
* @return 下一行内容
|
||||
* @throws NoSuchElementException 没有新行
|
||||
*/
|
||||
@Override
|
||||
public String next() throws NoSuchElementException {
|
||||
return nextLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回下一行
|
||||
*
|
||||
* @return 下一行
|
||||
* @throws NoSuchElementException 没有更多行
|
||||
*/
|
||||
public String nextLine() throws NoSuchElementException {
|
||||
if (false == hasNext()) {
|
||||
throw new NoSuchElementException("No more lines");
|
||||
}
|
||||
String currentLine = this.cachedLine;
|
||||
this.cachedLine = null;
|
||||
return currentLine;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭Reader
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
finished = true;
|
||||
super.finish();
|
||||
IoUtil.close(bufferedReader);
|
||||
cachedLine = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 不支持移除
|
||||
*
|
||||
* @throws UnsupportedOperationException 始终抛出此异常
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Remove unsupported on LineIterator");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,9 +98,4 @@ public class LineIter implements Iterator<String>, Iterable<String>, Closeable,
|
||||
protected boolean isValidLine(String line) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<String> iterator() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ import java.util.List;
|
||||
* @author qiqi.chen
|
||||
* @since 5.7.10
|
||||
*/
|
||||
public class PartitionIter<T> implements Iterator<List<T>>, Iterable<List<T>>, Serializable {
|
||||
public class PartitionIter<T> implements IterableIter<List<T>>, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
@@ -40,11 +40,6 @@ public class PartitionIter<T> implements Iterator<List<T>>, Iterable<List<T>>, S
|
||||
this.partitionSize = partitionSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<List<T>> iterator() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return this.iterator.hasNext();
|
||||
|
@@ -0,0 +1,12 @@
|
||||
package cn.hutool.core.text.split;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Splitter implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private int limit;
|
||||
private boolean ignoreEmpty;
|
||||
private boolean caseInsensitive;
|
||||
|
||||
}
|
@@ -12,7 +12,7 @@ public class PartitionIterTest {
|
||||
@Test
|
||||
public void iterTest() {
|
||||
final LineIter lineIter = new LineIter(ResourceUtil.getUtf8Reader("test_lines.csv"));
|
||||
final PartitionIter<String> iter = new PartitionIter<>(lineIter.iterator(), 3);
|
||||
final PartitionIter<String> iter = new PartitionIter<>(lineIter, 3);
|
||||
for (List<String> lines : iter) {
|
||||
Assert.assertTrue(lines.size() > 0);
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
package cn.hutool.extra.tokenizer;
|
||||
|
||||
import cn.hutool.core.collection.ComputeIter;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* 对于未实现{@link Iterator}接口的普通结果类,装饰为{@link Result}<br>
|
||||
@@ -10,23 +11,7 @@ import java.util.NoSuchElementException;
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractResult implements Result{
|
||||
|
||||
private Word cachedWord;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (this.cachedWord != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final Word next = nextWord();
|
||||
if(null != next) {
|
||||
this.cachedWord = next;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public abstract class AbstractResult extends ComputeIter<Word> implements Result{
|
||||
|
||||
/**
|
||||
* 下一个单词,通过实现此方法获取下一个单词,null表示无下一个结果。
|
||||
@@ -35,22 +20,7 @@ public abstract class AbstractResult implements Result{
|
||||
protected abstract Word nextWord();
|
||||
|
||||
@Override
|
||||
public Word next() {
|
||||
if (false == hasNext()) {
|
||||
throw new NoSuchElementException("No more word !");
|
||||
}
|
||||
final Word currentWord = this.cachedWord;
|
||||
this.cachedWord = null;
|
||||
return currentWord;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Jcseg result not allow to remove !");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Word> iterator() {
|
||||
return this;
|
||||
protected Word computeNext() {
|
||||
return nextWord();
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
package cn.hutool.extra.tokenizer;
|
||||
|
||||
import java.util.Iterator;
|
||||
import cn.hutool.core.collection.IterableIter;
|
||||
|
||||
/**
|
||||
* 分词结果接口定义<br>
|
||||
@@ -9,6 +9,6 @@ import java.util.Iterator;
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
public interface Result extends Iterator<Word>, Iterable<Word>{
|
||||
public interface Result extends IterableIter<Word> {
|
||||
|
||||
}
|
||||
|
@@ -1,25 +1,24 @@
|
||||
package cn.hutool.extra.tokenizer.engine.ansj;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.ansj.domain.Term;
|
||||
|
||||
import cn.hutool.extra.tokenizer.Result;
|
||||
import cn.hutool.extra.tokenizer.Word;
|
||||
import org.ansj.domain.Term;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Ansj分词结果实现<br>
|
||||
* 项目地址:https://github.com/NLPchina/ansj_seg
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
public class AnsjResult implements Result{
|
||||
public class AnsjResult implements Result {
|
||||
|
||||
private final Iterator<Term> result;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param ansjResult 分词结果
|
||||
*/
|
||||
public AnsjResult(org.ansj.domain.Result ansjResult) {
|
||||
|
@@ -1,12 +1,11 @@
|
||||
package cn.hutool.extra.tokenizer.engine.hanlp;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import com.hankcs.hanlp.seg.common.Term;
|
||||
|
||||
import cn.hutool.extra.tokenizer.Result;
|
||||
import cn.hutool.extra.tokenizer.Word;
|
||||
import com.hankcs.hanlp.seg.common.Term;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* HanLP分词结果实现<br>
|
||||
@@ -37,11 +36,4 @@ public class HanLPResult implements Result {
|
||||
public void remove() {
|
||||
result.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Word> iterator() {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -36,9 +36,9 @@ public class IKAnalyzerResult extends AbstractResult {
|
||||
} catch (IOException e) {
|
||||
throw new TokenizerException(e);
|
||||
}
|
||||
if (null != next) {
|
||||
return new IKAnalyzerWord(next);
|
||||
if (null == next) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
return new IKAnalyzerWord(next);
|
||||
}
|
||||
}
|
||||
|
@@ -1,14 +1,12 @@
|
||||
package cn.hutool.extra.tokenizer.engine.jcseg;
|
||||
|
||||
import cn.hutool.extra.tokenizer.Result;
|
||||
import cn.hutool.extra.tokenizer.AbstractResult;
|
||||
import cn.hutool.extra.tokenizer.TokenizerException;
|
||||
import cn.hutool.extra.tokenizer.Word;
|
||||
import org.lionsoul.jcseg.ISegment;
|
||||
import org.lionsoul.jcseg.IWord;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* Jcseg分词结果包装<br>
|
||||
@@ -17,10 +15,9 @@ import java.util.NoSuchElementException;
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
public class JcsegResult implements Result{
|
||||
public class JcsegResult extends AbstractResult {
|
||||
|
||||
private final ISegment result;
|
||||
private Word cachedWord;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
@@ -31,41 +28,16 @@ public class JcsegResult implements Result{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (this.cachedWord != null) {
|
||||
return true;
|
||||
}
|
||||
IWord next;
|
||||
protected Word nextWord() {
|
||||
IWord word;
|
||||
try {
|
||||
next = this.result.next();
|
||||
word = this.result.next();
|
||||
} catch (IOException e) {
|
||||
throw new TokenizerException(e);
|
||||
}
|
||||
if(null != next) {
|
||||
this.cachedWord = new JcsegWord(next);
|
||||
return true;
|
||||
if(null == word){
|
||||
return null;
|
||||
}
|
||||
return false;
|
||||
return new JcsegWord(word);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Word next() {
|
||||
if (false == hasNext()) {
|
||||
throw new NoSuchElementException("No more word !");
|
||||
}
|
||||
final Word currentWord = this.cachedWord;
|
||||
this.cachedWord = null;
|
||||
return currentWord;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Jcseg result not allow to remove !");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Word> iterator() {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,12 +1,11 @@
|
||||
package cn.hutool.extra.tokenizer.engine.jieba;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import com.huaban.analysis.jieba.SegToken;
|
||||
|
||||
import cn.hutool.extra.tokenizer.Result;
|
||||
import cn.hutool.extra.tokenizer.Word;
|
||||
import com.huaban.analysis.jieba.SegToken;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Jieba分词结果实现<br>
|
||||
@@ -41,10 +40,4 @@ public class JiebaResult implements Result{
|
||||
public void remove() {
|
||||
result.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Word> iterator() {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -35,9 +35,9 @@ public class MmsegResult extends AbstractResult {
|
||||
} catch (IOException e) {
|
||||
throw new TokenizerException(e);
|
||||
}
|
||||
if (null != next) {
|
||||
return new MmsegWord(next);
|
||||
if (null == next) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
return new MmsegWord(next);
|
||||
}
|
||||
}
|
||||
|
@@ -41,9 +41,4 @@ public class MynlpResult implements Result {
|
||||
public void remove() {
|
||||
result.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Word> iterator() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@@ -40,10 +40,4 @@ public class WordResult implements Result{
|
||||
public void remove() {
|
||||
this.wordIter.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Word> iterator() {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user