This commit is contained in:
Looly
2021-09-25 11:25:51 +08:00
parent 35b9212103
commit e16ec27c40
21 changed files with 183 additions and 251 deletions

View File

@@ -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而非DateTimeissue#I4BOAP@Gitee
* 【core 】 增加IterableIter、ComputeIter
### 🐞Bug修复
* 【http 】 修复HttpCookie设置cookies的方法不符合RFC6265规范问题pr#418@Gitee

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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();
}
}

View File

@@ -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> {
}

View File

@@ -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) {

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -41,9 +41,4 @@ public class MynlpResult implements Result {
public void remove() {
result.remove();
}
@Override
public Iterator<Word> iterator() {
return this;
}
}

View File

@@ -40,10 +40,4 @@ public class WordResult implements Result{
public void remove() {
this.wordIter.remove();
}
@Override
public Iterator<Word> iterator() {
return this;
}
}