JDK8原始碼之Spliterator並行遍歷迭代器

2021-07-27 09:21:59 字數 4296 閱讀 2077

public

inte***ce spliterator while (tryadvance(action));

} //對任務分割,返回乙個新的spliterator迭代器

spliteratortrysplit();

//用於估算還剩下多少個元素需要遍歷

long estimatesize();

//當迭代器擁有sized特徵時,返回剩餘元素個數;否則返回-1

default

long getexactsizeifknown()

//返回當前物件有哪些特徵值

int characteristics();

//是否具有當前特徵值

default

boolean hascharacteristics(int characteristics)

//如果spliterator的list是通過comparator排序的,則返回comparator

//如果spliterator的list是自然排序的 ,則返回null

//其他情況下拋錯

default comparator<? super t> getcomparator()

特徵值其實就是為表示該spliterator有哪些特性,用於可以更好控制和優化spliterator的使用。關於獲取比較器getcomparator這乙個方法,目前我還沒看到具體使用的地方,所以可能理解有些誤差。特徵值如下:(部分屬於猜測)

//

public

static

final

int ordered = 0x00000010;

//public

static

final

int distinct = 0x00000001;

//排序

public

static

final

int sorted = 0x00000004;

//大小

public

static

final

int sized = 0x00000040;

//沒有null

public

static

final

int nonnull = 0x00000100;

public

static

final

int immutable = 0x00000400;

public

static

final

int concurrent = 0x00001000;

public

static

final

int subsized = 0x00004000;

static

final

class

arraylistspliterator

implements

spliterator

//獲取結束位置(存在意義:首次初始化石需對fence和expectedmodcount進行賦值)

private

int getfence()

}return hi;

}//分割list,返回乙個新分割出的spliterator例項

public arraylistspliteratortrysplit()

//返回true 時,只表示可能還有元素未處理

//返回false 時,沒有剩餘元素處理了。。。

public

boolean tryadvance(consumer<? super e> action)

return

false;

}//順序遍歷處理所有剩下的元素

public

void foreachremaining(consumer<? super e> action)

else

mc = expectedmodcount;

if ((i = index) >= 0 && (index = hi) <= a.length)

//遍歷時發生結構變更時丟擲異常

if (lst.modcount == mc)

return;}}

throw

new concurrentmodificationexception();

}public

long estimatesize()

public

int characteristics()

}

測試**如下:

listarrs = new arraylist<>();

arrs.add("a");

arrs.add("b");

arrs.add("c");

arrs.add("d");

arrs.add("e");

arrs.add("f");

arrs.add("h");

arrs.add("i");

arrs.add("j");

spliteratora = arrs.spliterator();

//此時結果:a:0-9(index-fence)

spliteratorb = a.trysplit();

//此時結果:b:4-9,a:0-4

spliteratorc = a.trysplit();

//此時結果:c:4-6,b:4-9,a:6-9

spliteratord = a.trysplit();

//此時結果:d:6-7,c:4-6,b:4-9,a:7-9

可以看到每次分割,都會分割剩餘的前一半,fence之不變,index後移。同時也發現:

1.arraylistspliterator本質上還是對原list進行操作,只是通過index和fence來控制每次處理範圍

2.也可以得出,arraylistspliterator在遍歷元素時,不能對list進行結構變更操作,否則拋錯。

可以看到spliterator類裡面可以看到這麼乙個介面,那麼這個介面是幹什麼的,原始碼:

public

inte***ce

ofprimitive

extends

spliterator.ofprimitive

>

extends

spliterator

while (tryadvance(action));

}}

可以看到,這個介面基本沒有變動,這是多增加兩個泛型宣告而已,本質上和spliterator沒有太大的區別,只不過,它限制tryadvance的引數action型別t_cons和trysplit的返回引數t_splitr必須在實現介面時先宣告型別。

基於ofprimitive介面,又衍生出了ofint、oflong、ofdouble等專門用來處理int、long、double等分割迭代器介面(在spliterators有具體的實現)。

//與arraylist不同的是,array是實現宣告的,因此不必擔心遍歷過程中發生結構變更。

static

final class intarrayspliterator implements spliterator.ofint

public

intarrayspliterator(int array, int origin, int fence, int additionalcharacteristics)

@override

public ofint trysplit()

@override

public

void

foreachremaining(intconsumer action) while (++i < hi);}}

@override

public

boolean

tryadvance(intconsumer action)

return

false;

}@override

public

long

estimatesize()

@override

public

intcharacteristics()

@override

public comparator<? super integer> getcomparator()

}

hashmap原始碼分析jdk8

最近看了下jdk8的hashmap原始碼,相比於7,在儲存結構上有了些改變。1.在jdk8之前,hashmap的儲存結構是陣列 鍊錶的形式,那麼這種方式隨著鍊錶的長度增加,效率也凸顯出來。所以在jdk8中這塊做了優化,當鍊表超過一定長度時轉化為紅黑樹來解決這個問題,下面用流程圖畫出hashmap 的...

HsahMap原始碼分析(jdk8)

基於雜湊表的 map 介面的實現。此實現提供所有可選的對映操作,並允許使用 null 值和 null 鍵。除了非同步和允許使用 null 之外,hashmap 類與 hashtable 大致相同。此類不保證對映的順序,特別是它不保證該順序恆久不變。此實現假定雜湊函式將元素適當地分布在各桶之間,可為基...

ubuntu原始碼安裝jdk8

最近學習j a,想起來沒有在ubuntu上使用過 因此想安裝下環境,並在ubuntu上試用mpxj讀取mpp檔案 新建目錄 mkdir usr lib jvm解壓 tar zxvf jdk 8u211 linux x64.tar.gz c usr lib jvm修改環境變數 vim bashrc追加...