拆分为流
我正在為我工??作的公司準備正則表達式教程更新。 原始教程創建于2012年,從那時起Java發生了一點變化。 有新的Java語言版本,盡管Java中的正則表達式處理仍不完善(nb。它仍使用非確定性FSA),但仍有一些新功能。 我在上一篇文章中針對新的Java 9方法寫過一些文章。 但是這一次,我必須查看自2012年以來的所有新功能。
從1.8開始的splitAsStream
這樣,我在java.util.regex.Pattern類中找到了splitAsStream 。 它與方法split幾乎相同,除了返回的不是String對象的數組而是流。 最簡單的實現是
public Stream<String> splitAsStream(final CharSequence input) {return Arrays.stream(p.split(input)); }當圖書館試圖跟上新風和支持潮流時,我可以看到許多這樣的實現。 沒有什么比將數組或列表從某些現有功能轉換為流更簡單了。
但是,解決方案是低于標準,失去了流的本質:僅執行所需的工作。 我的意思是,“應僅在處理流時執行所需的工作”,而不是在開發人員將數組或集合返回方法轉換為返回一個流的情況下進行。 流以一種精簡的方式及時交付結果。 您會看到我們有多少個懶惰的表情。
JDK實現利用了流的性能優勢。 如果您查看源代碼,則可以立即看到實現比前面提到的簡單解決方案稍微復雜一些。 由于我沒有時間去研究實現,也許沒有興趣,因此我使用了另一種方法來證明實現尊重流的惰性。
該方法的參數是CharSequence而不是String 。 CharSequence是String實現的接口,但我們也可以實現它。 為了感覺到這種情況下的流實現多么懶惰,我創建了一個CharSequence實現,它通過調試打印出了方法調用。
class MyCharSequence implements CharSequence {private String me;MyCharSequence(String me) {this.me = me;}@Overridepublic int length() {System.out.println("MCS.length()=" + me.length());return me.length();}@Overridepublic char charAt(int index) {System.out.println("MCS.charAt(" + index + ")=" + me.charAt(index));return me.charAt(index);}@Overridepublic CharSequence subSequence(int start, int end) {System.out.println("MCS.subSequence(" + start + "," + end + ")="+ me.subSequence(start, end));return me.subSequence(start, end);} }有了此類,我可以執行以下簡單的main方法:
public static void main(String[] args) {Pattern p = Pattern.compile("[,\\.\\-;]");final CharSequence splitIt =new MyCharSequence("one.two-three,four;five;");p.splitAsStream(splitIt).forEach(System.out::println); }輸出顯示該實現確實很懶:
MCS.length()=24 MCS.length()=24 MCS.length()=24 MCS.charAt(0)=o MCS.charAt(1)=n MCS.charAt(2)=e MCS.charAt(3)=. MCS.subSequence(0,3)=one one MCS.length()=24 MCS.charAt(4)=t MCS.charAt(5)=w MCS.charAt(6)=o MCS.charAt(7)=- MCS.subSequence(4,7)=two two MCS.length()=24 MCS.charAt(8)=t MCS.charAt(9)=h MCS.charAt(10)=r MCS.charAt(11)=e MCS.charAt(12)=e MCS.charAt(13)=, MCS.subSequence(8,13)=three three MCS.length()=24 MCS.charAt(14)=f MCS.charAt(15)=o MCS.charAt(16)=u MCS.charAt(17)=r MCS.charAt(18)=; MCS.subSequence(14,18)=four four MCS.length()=24 MCS.charAt(19)=f MCS.charAt(20)=i MCS.charAt(21)=v MCS.charAt(22)=e MCS.charAt(23)=; MCS.subSequence(19,23)=five five MCS.length()=24實現繼續進行,當它找到流的第一個元素時,將其返回。 我們可以處理字符串“ one”,并且只有在返回其他元素時,它才能處理其他字符。 為什么必須在開始時調用方法長度3次? 我不知道。 也許它想非常確定序列的長度不會發生神奇的變化。
士氣
這是一個很好的例子,說明如何擴展庫以支持流。 如果應用程序僅將集合或數組轉換為第一個版本中的流,這不是問題,但是如果分析表明性能可以收回投資,則應實現真正的流惰性。
邊注
CharSequence的實現是可變的,但是處理要求它保持恒定,否則結果不確定。 我可以確認。
下周,我將展示splitAsStream一種可能用法,該splitAsStream利用的功能是它在字符序列中的讀入超出了需要的范圍。
翻譯自: https://www.javacodegeeks.com/2017/11/split-as-stream.html
總結
- 上一篇: 使用Dropwizard度量标准监视和测
- 下一篇: 广州柏俐臣有哪些品牌