簡體   English   中英

如何跳出Java 8 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 這與您描述的行為相匹配。

forEachRemainingJavadoc聲明:

對每個剩余元素執行給定操作,直到處理完所有元素或操作引發異常。 如果指定了該順序,則按迭代順序執行操作。 操作拋出的異常會轉發給調用者。

換句話說,如果您不想濫用異常,如果您打算在處理最后一個元素之前停止迭代,則不應使用forEachRemaining

forEach方法,無論是Iterable.forEachIterator.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM