天天看點

Stream.forEach和Collection.forEach一、定義二、執行順序三、自定義疊代器

Stream.forEach和Collection.forEach

  • 一、定義
  • 二、執行順序
    • 1、Parallel Stream
  • 三、自定義疊代器

一、定義

forEach由 Iterable.forEach 定義,而stream.forEach 由 Stream.forEach 定義。 Stream.forEach 的定義允許以任何順序處理元素 - 即使對于順序流也是如此。 但對于并行流, Stream.forEach 很可能會無序處理元素。

Iterable.forEach 從源擷取一個Iterator并在其上調用 forEachRemaining()。

Stream.forEach 的實作都将建立一個源自其中一個疊代器的Spliterator,然後在Iterator上調用 forEachRemaining

二、執行順序

Collection.forEach()使用集合的疊代器(如果指定了一個),集合裡元素的處理順序是明确的。相反,Collection.stream().forEach()的處理順序是不明确的。

1、Parallel Stream

public void test29() {
        List<String> list = Arrays.asList("A","B","C","D");
        list.forEach(System.out::print);
        System.out.println("=================================================");
        list.stream().forEach(System.out::print);
        System.out.println("=================================================");
        list.parallelStream().forEach(System.out::print);
        System.out.println("=================================================");
    }
           

我們會看到 list.forEach()以插入順序處理元素,而 list.parallelStream().forEach()在每次運作會産生不同的結果。一個可能的輸出是:

Stream.forEach和Collection.forEach一、定義二、執行順序三、自定義疊代器

三、自定義疊代器

/**
 * @author lichangyuan
 * @create 2022-03-03 16:05
 */
public class ReverseList extends ArrayList<String> {

    @Override
    public Iterator<String> iterator() {

        int startlndex = this.size() - 1;
        List<String> list = this;

        Iterator<String> it = new Iterator<String>() {

            private int currentlndex = startlndex;

            @Override
            public boolean hasNext() {
                return currentlndex >= 0;
            }

            @Override
            public String next() {
                String next = list.get(currentlndex);
                currentlndex--;
                return next;
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
        return it;
    }
}
           
@Test
    public void test30() {
        List<String> list = Arrays.asList("A","B","C","D");
        List<String> myList = new ReverseList();
        myList.addAll(list);

        myList.forEach(System.out::print);
        System.out.println("=================================================");
        myList.stream().forEach(System.out::print);
        System.out.println("=================================================");
        myList.parallelStream().forEach(System.out::print);
        System.out.println("=================================================");
    }
           

結果不同的原因是在清單中使用的 forEach()會使用自定義疊代器,而 stream().forEach()隻是從清單中逐個擷取元素,會忽略疊代器。