![](/img/trans.png)
[英]Is there a better way to terminate iterator.forEachRemaining
[英]How to jump out of the method inside Java 8 Iterator.forEachRemaining loop?
簡化代碼如下。 我預計迭代內部的返回將導致跳出該方法。 相反,代碼執行下一次迭代,然后在方法內迭代后執行打印
public static void callIter() {
List<String> names = new ArrayList<>();
names.add("A");
names.add("B");
names.add("C");
ListIterator<String> nameIterator = names.listIterator();
nameIterator.forEachRemaining(name -> {
if (name.equals("B")) {
System.out.println("Found");
return;
}
System.out.println(name);
});
System.out.println("AfterIter");
}
return
完成對迭代器的每個(剩余)元素執行的代碼的執行。 它不會停止執行迭代/ forEachRemaining
。 這與您描述的行為相匹配。
對每個剩余元素執行給定操作,直到處理完所有元素或操作引發異常。 如果指定了該順序,則按迭代順序執行操作。 操作拋出的異常會轉發給調用者。
換句話說,如果您不想濫用異常,如果您打算在處理最后一個元素之前停止迭代,則不應使用forEachRemaining
。
forEach
方法,無論是Iterable.forEach
, Iterator.forEachRemaining
還是Stream.forEach
都是為了做名稱所暗示的,為每個元素應用一個動作,而不僅僅是一些。
停止迭代並不是這個API所預見的,可以通過查看Consumer
接口的功能簽名來識別,該接口是(T) -> void
,不包含任何集合或迭代器注意到停止條件的可能性。
在這個地方,您應該重新考慮是否使用正確的工具來完成工作。 比較您的方法,例如
List<String> names = Arrays.asList("A", "B", "C");
int ix = names.indexOf("B");
(ix<0? names: names.subList(0, ix)).forEach(System.out::println);
if(ix>=0) System.out.println("Found");
System.out.println("AfterIter");
當然,如果元素的打印僅用於調試目的,則實際操作簡化為
List<String> names = Arrays.asList("A", "B", "C");
if(names.contains("B")) System.out.println("Found");
System.out.println("AfterIter");
如果相等只是任意謂詞的占位符,則可以使用
List<String> names = Arrays.asList("A", "B", "C");
if(names.stream().anyMatch(s -> s.equals("B"))) System.out.println("Found");
System.out.println("AfterIter");
它可以適應任意條件。
這可以擴展到
List<String> names = Arrays.asList("A", "B", "C");
Optional<String> match = names.stream()
.peek(System.out::println)
.filter(Predicate.isEqual("B"))
.findFirst();
if(match.isPresent()) System.out.println("Found");
// or
match.ifPresent(s -> System.out.println("Found "+s));
System.out.println("AfterIter");
顯示,如何通過打印元素來調試處理,表達等式謂詞的另一種方法(仍然可以被其他謂詞替換),以及如何獲得非平凡謂詞的實際匹配元素。
通常,如果要使用Java 8的新API,請不要嘗試根據forEach
編寫邏輯。 相反,盡量避免forEach
,盡可能使用更合適的操作。
forEachRemaining沒有打破迭代的選項。 您可以通過流操作進行搜索,如下所示:
String name = names.stream().filter(name -> name.equals("B")).findFirst().orElse(null);
正如其他人所提到的,Iterator.forEachRemaining沒有一個簡單的中斷,因為它打算通過eachRemaining
運行。 我解決這個問題的方法是這種風格:
Iterator<Object> objects = ...;
while (objects.hasNext() && exitCondition) {
// Do what you would've inside of the for each
}
我的一位天才同事建議我在這種情況下在循環中拋出RuntimeException並在forEachRemainin循環之外捕獲它
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.