摘要:陳楊一流的創建源集合一流的創建源集合集合默認方法接口與靜態類實現接口與靜態類實現二接口二接口接口對數據源中元素進行遍歷或分區延遲綁定數據源綁定時機首次遍歷切分查詢大小而不是在創建時非延遲綁定數據源綁定時機創建時或的方法首次調用與
package com.java.design.java8.Stream.StreamDetail.BaseStreamDetail; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.Arrays; import java.util.List; import java.util.function.Consumer; import java.util.function.IntConsumer; /** * @author 陳楊 */ @SpringBootTest @RunWith(SpringRunner.class) public class SpliteratorDetail { private IntConsumer intConsumer; private Consumer consumer; private List一、流的創建--源(集合)list; @Before public void init() { intConsumer = System.out::println; consumer = System.out::println; list = Arrays.asList("Kirito", "Asuna", "Sinon", "Yuuki", "Alice"); } private void action(IntConsumer intConsumer) { intConsumer.accept(100); } @Test public void testSpliteratorDetail() {
// 一、流的創建--源(集合) /* Collection集合默認方法 list.stream() default Stream二、Spliterator 接口stream () { return StreamSupport.stream(spliterator(), false); } @Override default Spliterator spliterator () { return Spliterators.spliterator(this, 0); } public static Spliterator spliterator(Collection extends T> c, int characteristics) { return new IteratorSpliterator<>(Objects.requireNonNull(c), characteristics); }*/ // Collector 接口 與 Collectors 靜態類實現 // Spliterator 接口 與 Spliterators 靜態類實現
// 二、Spliterator 接口 // Spliterator 接口 // 對數據源中元素進行遍歷或分區 // An object for traversing and partitioning elements of a source.
// 延遲綁定數據源 // 綁定時機:首次遍歷、切分、查詢大小 而不是在創建時 // A late-binding Spliterator binds to the source of elements at the // point of first traversal, first split, or first query for estimated size, // rather than at the time the Spliterator is created. // 非延遲綁定數據源 // 綁定時機:Spliterator創建時 或Spliterator的方法首次調用 // A Spliterator that is not late-binding binds to the source of elements // at the point of construction or first invocation of any method.
// Spliterator 與 Iterator 的區別: // // Spliterator 優勢:通過分解和單元素迭代 支持串行與并行 // 比Iterator迭代通過hasNext與next性能更好 // Spliterators, like {@code Iterator}s, are for traversing the elements of a source. // The Spliterator API was designed to support efficient parallel traversal // in addition to sequential traversal, by supporting decomposition as well as single-element iteration. // In addition, the protocol for accessing elements via a Spliterator is designed to impose // smaller per-element overhead than {@code Iterator}, and to avoid the inherent // race involved in having separate methods for {@code hasNext()} and {@code next()}.三、Spliterator特性值
/* public interface Spliterator四、Spliterator方法{ // 三、Spliterator特性值 * Characteristic value signifying that an encounter order is defined for * elements. If so, this Spliterator guarantees that method * {@link #trySplit} splits a strict prefix of elements, that method 分割前后對元素加嚴格前綴 * {@link #tryAdvance} steps by one element in prefix order, and that 按照元素的順序前綴遍歷 * {@link #forEachRemaining} performs actions in encounter order. 對剩余元素按照相遇順序執行action * * A {@link Collection} has an encounter order if the corresponding * {@link Collection#iterator} documents an order. If so, the encounter * order is the same as the documented order. Otherwise, a collection does * not have an encounter order. * 集合是有序的,則文檔是有序的 * 集合是無序的,則文檔是無序的 * * @apiNote Encounter order is guaranteed to be ascending index order for * any {@link List}. But no order is guaranteed for hash-based collections * such as {@link HashSet}. Clients of a Spliterator that reports * {@code ORDERED} are expected to preserve ordering constraints in * non-commutative parallel computations. * 基于索引升序的List 排序-->有序 * 基于Hash散列的HashSet 排序-->無序 * 非并發情況下期望要保留 有序集合中 元素的順序 以返還給客戶端調用者 public static final int ORDERED = 0x00000010; * Characteristic value signifying that, for each pair of * encountered elements {@code x, y}, {@code !x.equals(y)}. This * applies for example, to a Spliterator based on a {@link Set}. 基于Set的去重DISTINCT public static final int DISTINCT = 0x00000001; * Characteristic value signifying that encounter order follows a defined * sort order. If so, method {@link #getComparator()} returns the associated * Comparator, or {@code null} if all elements are {@link Comparable} and * are sorted by their natural ordering. * *
A Spliterator that reports {@code SORTED} must also report * {@code ORDERED}. * 已排序的一定是有序的 * * @apiNote The spliterators for {@code Collection} classes in the JDK that * implement {@link NavigableSet} or {@link SortedSet} report {@code SORTED}. * 如果基于集合的spliterator實現了NavigableSet或SortedSet接口 則為SORTED public static final int SORTED = 0x00000004; * Characteristic value signifying that the value returned from * {@code estimateSize()} prior to traversal or splitting represents a * finite size that, in the absence of structural source modification, * represents an exact count of the number of elements that would be * encountered by a complete traversal. * 源中元素個數有限 源元素結構特性未被修改 estimateSize能在完整遍歷過程中 精準計算 public static final int SIZED = 0x00000040; * Characteristic value signifying that the source guarantees that * encountered elements will not be {@code null}. (This applies, * for example, to most concurrent collections, queues, and maps.) * 源中元素都不為null public static final int NONNULL = 0x00000100; * Characteristic value signifying that the element source cannot be * structurally modified; that is, elements cannot be added, replaced, or * removed, so such changes cannot occur during traversal. A Spliterator * that does not report {@code IMMUTABLE} or {@code CONCURRENT} is expected * to have a documented policy (for example throwing * {@link ConcurrentModificationException}) concerning structural * interference detected during traversal. * 源中元素結構不可變 * 源中元素在遍歷過程中 不能被 添加 替換(包含修改) 刪除 * 如果遍歷時 發送元素結構發生改變 則不能表示為IMMUTABLE或CONCURRENT 拋出ConcurrentModificationException public static final int IMMUTABLE = 0x00000400; * Characteristic value signifying that the element source may be safely * concurrently modified (allowing additions, replacements, and/or removals) * by multiple threads without external synchronization. If so, the * Spliterator is expected to have a documented policy concerning the impact * of modifications during traversal. * *
A top-level Spliterator should not report both {@code CONCURRENT} and * {@code SIZED}, since the finite size, if known, may change if the source * is concurrently modified during traversal. Such a Spliterator is * inconsistent and no guarantees can be made about any computation using * that Spliterator. Sub-spliterators may report {@code SIZED} if the * sub-split size is known and additions or removals to the source are not * reflected when traversing. * *
A top-level Spliterator should not report both {@code CONCURRENT} and * {@code IMMUTABLE}, since they are mutually exclusive. Such a Spliterator * is inconsistent and no guarantees can be made about any computation using * that Spliterator. Sub-spliterators may report {@code IMMUTABLE} if * additions or removals to the source are not reflected when traversing. * * @apiNote Most concurrent collections maintain a consistency policy * guaranteeing accuracy with respect to elements present at the point of * Spliterator construction, but possibly not reflecting subsequent * additions or removals. * 頂層的Spliterator不能同時擁有CONCURRENT和SIZED特性 * 并發時可能存在對源進行添加、替換(修改)、刪除 以改變元素個數 * 頂層的Spliterator不能同時擁有CONCURRENT和IMMUTABLE特性 * 這兩種特性是互斥的 * 大多數并發集合都保持一致性策略,以確保在拆分器構造點存在的元素的準確性,但可能不反映隨后的添加或刪除 public static final int CONCURRENT = 0x00001000; * Characteristic value signifying that all Spliterators resulting from * {@code trySplit()} will be both {@link #SIZED} and {@link #SUBSIZED}. * (This means that all child Spliterators, whether direct or indirect, will * be {@code SIZED}.) * *
A Spliterator that does not report {@code SIZED} as required by * {@code SUBSIZED} is inconsistent and no guarantees can be made about any * computation using that Spliterator. * * @apiNote Some spliterators, such as the top-level spliterator for an * approximately balanced binary tree, will report {@code SIZED} but not * {@code SUBSIZED}, since it is common to know the size of the entire tree * but not the exact sizes of subtrees. * 頂層二叉樹是SIZED 但不是SUBSIZED 因為不知道子樹的大小 * 從trySplit返回的子Spliterator都是SIZED 和 SUBSIZED public static final int SUBSIZED = 0x00004000;
// 四、Spliterator方法 * If a remaining element exists, performs the given action on it, * returning {@code true}; else returns {@code false}. If this * Spliterator is {@link #ORDERED} the action is performed on the * next element in encounter order. Exceptions thrown by the * action are relayed to the caller. * 嘗試遍歷: 如果有下一個元素 就對其執行action 如果是有序的 按照元素相遇順序 對其執行action 如果有異常 將異常信息返回給方法調用者 tryAdvance() 完成了 Iterator的hasNext()與next() boolean tryAdvance(Consumer super T> action); * Performs the given action for each remaining element, sequentially in * the current thread, until all elements have been processed or the action * throws an exception. If this Spliterator is {@link #ORDERED}, actions * are performed in encounter order. Exceptions thrown by the action * are relayed to the caller. 按順序遍歷剩余元素 并對每個元素執行action 直到遍歷結束 將異常信息返回給方法調用者 default void forEachRemaining(Consumer super T> action) { do { } while (tryAdvance(action)); } * If this spliterator can be partitioned, returns a Spliterator * covering elements, that will, upon return from this method, not * be covered by this Spliterator. * *If this Spliterator is {@link #ORDERED}, the returned Spliterator * must cover a strict prefix of the elements. * *
Unless this Spliterator covers an infinite number of elements, * repeated calls to {@code trySplit()} must eventually return {@code null}. * Upon non-null return: *
This method may return {@code null} for any reason,
* including emptiness, inability to split after traversal has
* commenced, data structure constraints, and efficiency
* considerations.
*
* @apiNote
* An ideal {@code trySplit} method efficiently (without
* traversal) divides its elements exactly in half, allowing
* balanced parallel computation. Many departures from this ideal
* remain highly effective; for example, only approximately
* splitting an approximately balanced tree, or for a tree in
* which leaf nodes may contain either one or two elements,
* failing to further split these nodes. However, large
* deviations in balance and/or overly inefficient {@code
* trySplit} mechanics typically result in poor parallel
* performance.
嘗試對Spliterator中元素進行trySplit
若能進行拆分,則返回一個新的Spliterator對象 裝載已分割的元素
如果分割前有序,分割后也是有序的
分割結果不為null:
進行有限分割后 最終能得到非null元素
分割結果為null:
對有限元素個數的分割:進行無限分割
分割前元素個數為null
遍歷開始后無法拆分 數據結構約束 性能考量
Spliterator If this Spliterator is {@link #SIZED} and has not yet been partially
* traversed or split, or this Spliterator is {@link #SUBSIZED} and has
* not yet been partially traversed, this estimate must be an accurate
* count of elements that would be encountered by a complete traversal.
* Otherwise, this estimate may be arbitrarily inaccurate, but must decrease
* as specified across invocations of {@link #trySplit}.
*
* @apiNote
* Even an inexact estimate is often useful and inexpensive to compute.
* For example, a sub-spliterator of an approximately balanced binary tree
* may return a value that estimates the number of elements to be half of
* that of its parent; if the root Spliterator does not maintain an
* accurate count, it could estimate size to be the power of two
* corresponding to its maximum depth.
估算元素數量(即將遍歷的元素個數)
如果元素數量無限 未知 或計算成本很昂貴 返回Long.Max_Value
如果Spliterator是一個SIZED或SUBSIZED estimate則是完整遍歷所需要的值(accurate精確)
long estimateSize();
* Convenience method that returns {@link #estimateSize()} if this
* Spliterator is {@link #SIZED}, else {@code -1}.
characteristic.SIZED -->返回確定的大小 否則為 -1L
default long getExactSizeIfKnown() {
return (characteristics() & SIZED) == 0 ? -1L : estimateSize();
}
* Returns a set of characteristics of this Spliterator and its
* elements. The result is represented as ORed values from {@link
* #ORDERED}, {@link #DISTINCT}, {@link #SORTED}, {@link #SIZED},
* {@link #NONNULL}, {@link #IMMUTABLE}, {@link #CONCURRENT},
* {@link #SUBSIZED}. Repeated calls to {@code characteristics()} on
* a given spliterator, prior to or in-between calls to {@code trySplit},
* should always return the same result.
*
* If a Spliterator reports an inconsistent set of
* characteristics (either those returned from a single invocation
* or across multiple invocations), no guarantees can be made
* about any computation using this Spliterator.
*
* @apiNote The characteristics of a given spliterator before splitting
* may differ from the characteristics after splitting. For specific
* examples see the characteristic values {@link #SIZED}, {@link #SUBSIZED}
* and {@link #CONCURRENT}.
*
* @return a representation of characteristics
返回Spliterator與其元素的一個特性值標識
在分割期間或之前 其元素的特性不變
分割前后若元素的特性發生了變更 對其進行計算行為是不能受到保證的
int characteristics();
* Returns {@code true} if this Spliterator"s {@link
* #characteristics} contain all of the given characteristics.
判斷是否包含此元素特性
default boolean hasCharacteristics(int characteristics) {
return (characteristics() & characteristics) == characteristics;
}
* If this Spliterator"s source is {@link #SORTED} by a {@link Comparator},
* returns that {@code Comparator}. If the source is {@code SORTED} in
* {@linkplain Comparable natural order}, returns {@code null}. Otherwise,
* if the source is not {@code SORTED}, throws {@link IllegalStateException}.
如果source是有序的:
如果是按照比較器進行排序 則返回該比較器
如果是Comparable natural order 則返回null
如果source是無序的 拋出IllegalStateException異常
default Comparator super T> getComparator() {
throw new IllegalStateException();
}
* A Spliterator specialized for primitive values.
* 針對于原生類型值的特化分割器
*
* @param This class is mostly for library writers presenting stream views
* of data structures; most static stream methods intended for end users are in
* the various {@code Stream} classes.
* StreamSupport提供數據結構的流視圖的library 大多數為終端用戶使用的靜態流方法在Stream類中
*
* @since 1.8
*
public final class StreamSupport {
* Creates a new sequential or parallel {@code Stream} from a
* {@code Spliterator}.
*
*
* The spliterator is only traversed, split, or queried for estimated
* size after the terminal operation of the stream pipeline commences.
* 僅在流管道的終端操作開始后,才遍歷、拆分或查詢spliterator的估計大小。
*
* It is strongly recommended the spliterator report a characteristic of
* {@code IMMUTABLE} or {@code CONCURRENT}, or be
* late-binding. Otherwise,
* {@link #stream(java.util.function.Supplier, int, boolean)} should be used
* to reduce the scope of potential interference with the source. See
* Non-Interference for
* more details.
* 強烈建議對spliterator設置characteristic(IMMUTABLE CONCURRENT late-binding)
* 以減少潛在的干擾源范圍
*
public static A concrete intermediate stage is generally built from an
* {@code AbstractPipeline}, a shape-specific pipeline class which extends it
* (e.g., {@code IntPipeline}) which is also abstract, and an operation-specific
* concrete class which extends that. {@code AbstractPipeline} contains most of
* the mechanics of evaluating the pipeline, and implements methods that will be
* used by the operation; the shape-specific classes add helper methods for
* dealing with collection of results into the appropriate shape-specific
* containers.
*
*
* After chaining a new intermediate operation, or executing a terminal
* operation, the stream is considered to be consumed, and no more intermediate
* or terminal operations are permitted on this stream instance.
* 在鏈式添加中間操作或一個終止操作后 流視做被消費
* 流只能被消費一次 已消費-->不允許在此流實例中存在更多的中間操作或終止操作
*
* @implNote
* For sequential streams, and parallel streams without
* stateful intermediate
* operations, parallel streams, pipeline evaluation is done in a single
* pass that "jams" all the operations together. For parallel streams with
* stateful operations, execution is divided into segments, where each
* stateful operations marks the end of a segment, and each segment is
* evaluated separately and the result used as the input to the next
* segment. In all cases, the source data is not consumed until a terminal
* operation begins.
* 串行流 與 無狀態的并行流
* 流的消費 是將中間的操作進行“jams”(打包放一起)對流中每個元素執行action-->single pass
*
* 有狀態的并行流
* 執行分成segments 分別對segment執行有狀態操作 并將其結果作為下一個segment輸入
*
* 在任何情況下,有且只有在一個終止操作被調用時 流真正被消費
abstract class AbstractPipeline 五、Consumer 與 IntConsumer、LongConsumer、DoubleConsumer
// Consumer 與 IntConsumer 為什么能進行強制類型轉換?
// Consumer 與 IntConsumer 之間沒有繼承關系 層次上無關系
// Consumer 與 IntConsumer 當傳入的參數是整型int,Integer時 會自動進行裝箱拆箱
// ((IntConsumer) action::accept) 是Lambda表達式
// Lambda表達式 是一種匿名函數 沒有方法聲明 具有上下文自動推測類型功能
* {@inheritDoc}
* @implSpec
* If the action is an instance of {@code IntConsumer} then it is cast
* to {@code IntConsumer} and passed to
* {@link #tryAdvance(java.util.function.IntConsumer)}; otherwise
* the action is adapted to an instance of {@code IntConsumer}, by
* boxing the argument of {@code IntConsumer}, and then passed to
* {@link #tryAdvance(java.util.function.IntConsumer)}.
@Override
default boolean tryAdvance(Consumer super Integer> action) {
if (action instanceof IntConsumer) {
return tryAdvance((IntConsumer) action);
}
else {
if (Tripwire.ENABLED)
Tripwire.trip(getClass(),
"{0} calling Spliterator.OfInt.tryAdvance((IntConsumer) action::accept)");
return tryAdvance((IntConsumer) action::accept);
}
}
* {@inheritDoc}
* @implSpec
* If the action is an instance of {@code IntConsumer} then it is cast
* to {@code IntConsumer} and passed to
* {@link #forEachRemaining(java.util.function.IntConsumer)}; otherwise
* the action is adapted to an instance of {@code IntConsumer}, by
* boxing the argument of {@code IntConsumer}, and then passed to
* {@link #forEachRemaining(java.util.function.IntConsumer)}.
@Override
default void forEachRemaining(Consumer super Integer> action) {
if (action instanceof IntConsumer) {
forEachRemaining((IntConsumer) action);
}
else {
if (Tripwire.ENABLED)
Tripwire.trip(getClass(),
"{0} calling Spliterator.OfInt.forEachRemaining((IntConsumer) action::accept)");
forEachRemaining((IntConsumer) action::accept);
}
}
}
* A Spliterator specialized for {@code long} values.
* @since 1.8
public interface OfLong extends OfPrimitive
六、Consumer 與 IntConsumer 的強制類型轉換測試
// 六、Consumer 與 IntConsumer 的強制類型轉換測試
// 傳入面向對象 對象
this.action(intConsumer);
// 傳入Lambda表達式 函數式編程
this.action(intConsumer::accept);
this.action(value -> intConsumer.accept(value));
this.action(consumer::accept);
this.action(value -> consumer.accept(value));
// 面向對象強制類型轉換 報錯java.lang.ClassCastException
// this.action((IntConsumer) consumer);
// this.action(((IntConsumer) consumer)::accept);
// this.action(t -> ((IntConsumer) consumer).accept(t));
// 函數式編程強制類型轉換 Lambda表達式沒變
this.action((IntConsumer) consumer::accept);
this.action((IntConsumer) (t -> consumer.accept(t)));
this.action((IntConsumer) t -> consumer.accept(t));
七、Iterator-based Spliterators 與 StreamSupport底層實現
// 七、Iterator-based Spliterators 與 StreamSupport底層實現
// Iterator-based Spliterators
/*
* A Spliterator using a given Iterator for element
* operations. The spliterator implements {@code trySplit} to
* permit limited parallelism.
* spliterator利用trySplit實現有限的并行化操作
*
* static class IteratorSpliterator
八、流源分析
// 八、流源分析
/*
流源的創建
Abstract base class for an intermediate pipeline stage or pipeline source
stage implementing whose elements are of type {@code U}.
抽象基類:用于實現其元素類型為{@code U}的中間管道階段或管道源階段
ReferencePipeline 操作引用類型 (將源階段 與 [0,n)個中間操作階段 看做一個對象)
* @param
九、Array.asList()流源遍歷注意事項
// 九、Array.asList()流源遍歷注意事項
/*
為什么 未調用IteratorSpliterator.forEachRemaining()
list.stream().forEach(System.out::println); 執行過程分析
Arrays.asList()
private static class ArrayList
十、測試結果
. ____ _ __ _ _
/ / ___"_ __ _ _(_)_ __ __ _
( ( )\___ | "_ | "_| | "_ / _` |
/ ___)| |_)| | | | | || (_| | ) ) ) )
" |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.2.RELEASE)
2019-02-20 18:09:13.662 INFO 2224 --- [ main] c.j.d.j.S.S.B.SpliteratorDetail : Starting SpliteratorDetail on DESKTOP-87RMBG4 with PID 2224 (started by 46250 in E:IdeaProjectsdesign)
2019-02-20 18:09:13.663 INFO 2224 --- [ main] c.j.d.j.S.S.B.SpliteratorDetail : No active profile set, falling back to default profiles: default
2019-02-20 18:09:14.133 INFO 2224 --- [ main] c.j.d.j.S.S.B.SpliteratorDetail : Started SpliteratorDetail in 0.653 seconds (JVM running for 1.335)
100
100
100
100
100
100
100
100
class java.util.Arrays$ArrayList
Kirito
Asuna
Sinon
Yuuki
Alice
Kirito
Asuna
Sinon
Yuuki
Alice
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/73344.html
摘要:陳楊一流的定義流支持串行并行聚合操作元素序列二流的創建流的創建以方法生成流三 package com.java.design.java8.Stream.StreamDetail; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframe...
摘要:陳楊一靜態工廠類實現方式一靜態工廠類實現方式靜態工廠類最終由實現通過實現通過實現底層由實現是的一種具化表現形式使用拼接字符串二靜態工廠類常用收集器二靜態工廠類常用收集器返回一個不可修改的按照相遇的順序返回一個不可修改的無序返回 /** * @author 陳楊 */ @SpringBootTest @RunWith(SpringRunner.class) public class...
摘要:一自定義收集器陳楊將集合轉換為集合存放相同元素二自定義收集器陳楊將學生對象按照存放從中間容器數據類型轉換為結果類型數據類型一致若不一致拋出類型轉換異常對中間容器數據結果類型進行強制類型轉換多個線程同時操作同一個容器并行多線 一、自定義SetCustomCollector收集器 package com.java.design.Stream.CustomCollector; impor...
摘要:一收集器接口陳楊收集器接口匯聚操作的元素類型即流中元素類型匯聚操作的可變累積類型匯聚操作的結果類型接口一種可變匯聚操作將輸入元素累積到可變結果容器中在處理完所有輸入元素后可以選擇將累積的結果轉換為最終表示可選操作歸約操作 一、Stream收集器 Collector接口 package com.java.design.java8.Stream; import com.java.desi...
摘要:一流轉換為數組集合陳楊將流轉換為數組將流轉換為數組將流轉換為集合將流轉換為集合解析 一、流 轉換為數組、集合 package com.java.design.java8.Stream; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context...
閱讀 3054·2023-04-26 00:40
閱讀 2391·2021-09-27 13:47
閱讀 4197·2021-09-07 10:22
閱讀 2966·2021-09-06 15:02
閱讀 3307·2021-09-04 16:45
閱讀 2484·2021-08-11 10:23
閱讀 3599·2021-07-26 23:38
閱讀 2900·2019-08-30 15:54