[英]Implementation for Iterator<List<String>> doesn't work correctly
我必須為Iterator接口編寫一個實現。
其構造函數應如下所示:
public BlockIterator(Iterator<List<String>> iterator, String regex) {
長話短說,此實現應解析大型文件,因此無法將其保存到內存中(例如存儲和處理到數組或集合),所有操作均應“即時”進行。
同樣, next()
實現應將子列表從模式的第一次出現返回到下一個。 但是,不應包括下一個。
另外, hasNext()
應該是冪等的。 即使經過20次通話,結果也應該相同。
這是我的測試解決方案:
import com.google.common.collect.Lists;
import org.junit.Test;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
class BlockIterator implements Iterator<List<String>> {
private final Iterator<List<String>> iterator;
private final Pattern pattern;
public BlockIterator(Iterator<List<String>> iterator, String regex) {
this.iterator = iterator;
this.pattern = Pattern.compile(regex);
}
@Override
public boolean hasNext() {
while (iterator.hasNext()) {
List<String> line = iterator.next();
for (String word : line) {
Matcher matcher = pattern.matcher(word);
if (matcher.find()) {
return true;
}
}
}
return false;
}
@Override
public List<String> next() {
String matchWord = null;
List<String> result = Lists.newArrayList();
while (iterator.hasNext()) {
List<String> line = iterator.next();
for (String word : line) {
Matcher matcher = pattern.matcher(word);
if (matcher.find()) {
if (null != matchWord) {
return result;
} else {
matchWord = word;
}
}
if (null != matchWord) {
result.add(word);
}
}
}
return result;
}
}
public class BlockIteratorTest {
public static final List<List<String>> lines = Lists.newArrayList(
Lists.newArrayList("123"),
Lists.newArrayList("- test -"),
Lists.newArrayList("start"),
Lists.newArrayList("end"),
Lists.newArrayList("test123"));
@Test
public void testNext() throws Exception {
List<String> expectedFirstNext = Lists.newArrayList("- test -", "start", "end");
List<String> expectedSecondNext = Lists.newArrayList("test123");
BlockIterator blockIterator = new BlockIterator(lines.iterator(), "test");
List<String> actualFirstNext = blockIterator.next();
assertEquals(expectedFirstNext, actualFirstNext);
List<String> actualSecondNext = blockIterator.next();
assertEquals(expectedSecondNext, actualSecondNext);
}
@Test
public void testHasNext() throws Exception {
BlockIterator blockIterator = new BlockIterator(lines.iterator(), "test");
for (int i = 0; i < 20; i++) {
assertTrue(blockIterator.hasNext());
}
}
}
它幾乎沒有失敗:
hasNext()
不是冪等的 next()
調用之后,我們應該僅返回匹配subllist(因為不再有文本)。 在這種情況下,我找不到有效的解決方案。
有什么建議么?
試着玩這個游戲,不確定這是否是您的意思,但是它正在通過您的測試,所以...確實如此! 我不明白您的第二次失敗,也不確定內部列表中的單詞多於1個字時您想做什么,但是還是可以嘗試一下:
class IteratorTesting implements Iterator<List<String>> {
private final Iterator<List<String>> iterator;
private final Pattern pattern;
private boolean hasNext = false;
private List<String> next = null;
private String startNext = null;
public IteratorTesting(Iterator<List<String>> iterator, String regex) {
this.iterator = iterator;
this.pattern = Pattern.compile(regex);
hasNext = checkNext();
}
@Override
public boolean hasNext() {
return hasNext;
}
private boolean checkNext() {
String matchWord = null;
List<String> result = new ArrayList<>();
if(startNext != null)
result.add(startNext);
while(iterator.hasNext()) {
List<String> line = iterator.next();
for(String word : line) {
Matcher matcher = pattern.matcher(word);
if(matcher.find()) {
if(null != matchWord || startNext != null) {
next = result;
startNext = word;
return true;
} else {
matchWord = word;
}
}
if(null != matchWord || startNext != null) {
result.add(word);
}
}
}
next = result;
startNext = null;
return !next.isEmpty();
}
@Override
public List<String> next() {
List<String> current = next;
hasNext = checkNext();
return current;
}
}
我知道這是錯誤的代碼,即使是現在,我仍然可以立即重構某些東西( if(null != matchWord || startNext != null) {
...),不要討厭我。
你可以存儲與匹配列表中的一個字段,用空的比較它hasNext
,和返回值在next
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.