日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
For循環(huán)和While循環(huán)之流的終結(jié)

 本文轉(zhuǎn)載自公眾號(hào)“讀芯術(shù)”(ID:AI_Discovery)

成都創(chuàng)新互聯(lián)公司服務(wù)項(xiàng)目包括麻城網(wǎng)站建設(shè)、麻城網(wǎng)站制作、麻城網(wǎng)頁(yè)制作以及麻城網(wǎng)絡(luò)營(yíng)銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,麻城網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到麻城省份的部分城市,未來相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

循環(huán)語(yǔ)句是編程的基本組成部分。列表中的每一項(xiàng)都有用處,讀取輸入,直到輸入結(jié)束,在屏幕上放置n個(gè)輸入框。每當(dāng)看到PR中的代碼添加了循環(huán)語(yǔ)句,我都怒不可遏。現(xiàn)在我必定仔細(xì)檢查代碼,確保循環(huán)可以終止。

我希望所有運(yùn)行良好的語(yǔ)句庫(kù)中都看不到循環(huán)語(yǔ)句的蹤影,但仍然有一些悄悄混進(jìn)來,所以我想告訴大家如何消除循環(huán)語(yǔ)句。

讓循環(huán)語(yǔ)句終結(jié)的關(guān)鍵是函數(shù)式編程。只需提供要在循環(huán)中執(zhí)行的代碼以及循環(huán)的參數(shù)(需要循環(huán)的內(nèi)容)即可。我用Java作示范語(yǔ)言,但其實(shí)許多語(yǔ)言都支持這種類型的函數(shù)式編程,這種編程可以消除代碼中的循環(huán)。

最簡(jiǎn)單的情況是對(duì)列表中的每個(gè)元素執(zhí)行操作。

 
 
 
 
  1. List list = List.of(1, 2, 3); 
  2. // bare for loop.  
  3. for(int i : list) { 
  4.    System.out.println("int = "+ i); 
  5. }// controlled for each 
  6. list.forEach(i -> System.out.println("int = " + i)); 

在這種最簡(jiǎn)單的情況下,無論哪種方法都沒有太大優(yōu)勢(shì)。但第二種方法可以不使用bare for循環(huán),而且語(yǔ)法更簡(jiǎn)潔。

我覺得forEach語(yǔ)句也有問題,應(yīng)該只應(yīng)用于副作用安全的方法。我所說的安全副作用是指不改變程序狀態(tài)。上例只是記錄日志,因此使用無礙。其他有關(guān)安全副作用的示例是寫入文件、數(shù)據(jù)庫(kù)或消息隊(duì)列。

不安全的副作用會(huì)更改程序狀態(tài)。下面為示例及其解決方法:

 
 
 
 
  1. // bad side-effect, the loop alters sum 
  2. int sum = 0; 
  3. for(int i : list) { 
  4.     sum += i; 
  5. System.out.println("sum = " + sum);// no side-effect, sum iscalculated by loop 
  6. sum = list 
  7.        .stream() 
  8.        .mapToInt(i -> i) 
  9.        .sum(); 
  10. System.out.println("sum = " + sum); 

另一個(gè)常見的例子:

 
 
 
 
  1. // bad side-effect, the loop alters list2 
  2. List list2 = new ArrayList<>(); 
  3. for(int i : list) { 
  4.    list2.add(i); 
  5. list2.forEach(i -> System.out.println("int = " + i));// no sideeffect, the second list is built by the loop 
  6. list2 = list 
  7.          .stream() 
  8.          .collect(Collectors.toList()); 
  9. list2.forEach(i -> System.out.println("int = " + i)); 

當(dāng)你需要處理列表項(xiàng)方法中的索引時(shí)就會(huì)出現(xiàn)問題,但可以解決,如下:

 
 
 
 
  1. // bare for loop with index: 
  2. for(int i = 0; i < list.size(); i++) { 
  3.     System.out.println("item atindex "  
  4.       + i  
  5.       + " = "  
  6.       + list.get(i)); 
  7. }// controlled loop with index: 
  8. IntStream.range(0, list.size()) 
  9.    .forEach(i ->System.out.println("item at index " 
  10.     + i 
  11.     + " = " 
  12.     + list.get(i))); 

老生常談的問題:讀取文件中的每一行直到文件讀取完畢如何解決?

 
 
 
 
  1. BufferedReader reader = new BufferedReader( 
  2.        new InputStreamReader( 
  3.       LoopElimination.class.getResourceAsStream("/testfile.txt"))); 
  4. // while loop with clumsy looking syntax 
  5. String line; 
  6. while((line = reader.readLine()) != null) { 
  7.    System.out.println(line); 
  8. }reader = new BufferedReader( 
  9.        new InputStreamReader( 
  10.       LoopElimination.class.getResourceAsStream("/testfile.txt"))); 
  11. // less clumsy syntax 
  12. reader.lines() 
  13.    .forEach(l ->System.out.println(l)); 

應(yīng)對(duì)上述情況有一個(gè)非常簡(jiǎn)便的lines方法,可以返回Stream類型。但是如果一個(gè)字符一個(gè)字符地讀取呢?InputStream類沒有返回Stream 的方法。我們必須創(chuàng)建自己的Stream:

 
 
 
 
  1. InputStream is = 
  2.    LoopElimination.class.getResourceAsStream("/testfile.txt"); 
  3. // while loop with clumsy looking syntax 
  4. int c; 
  5. while((c = is.read()) != -1) { 
  6.   System.out.print((char)c); 
  7. // But this is even uglier 
  8. InputStream nis = 
  9.    LoopElimination.class.getResourceAsStream("/testfile.txt"); 
  10. // Exception handling makes functional programming ugly 
  11. Stream.generate(() -> { 
  12.    try { 
  13.       return nis.read(); 
  14.    } catch (IOException ex) { 
  15.       throw new RuntimeException("Errorreading from file", ex); 
  16.    } 
  17. }) 
  18.  .takeWhile(ch -> ch != -1) 
  19.  .forEach(ch ->System.out.print((char)(int)ch)); 

這種情況下while循環(huán)看起來更好。此外,Stream版本還使用了可以返回?zé)o限項(xiàng)目流的 generate函數(shù),因此必須進(jìn)一步檢查以確保生成過程終止,這是由于takeWhile方法的存在。

InputStream類存在問題,因?yàn)槿鄙賞eek 方法來創(chuàng)建可輕松轉(zhuǎn)換為Stream的Iterator。它還會(huì)拋出一個(gè)檢查過的異常,這樣函數(shù)式編程就會(huì)雜亂無章。在這種情況下可以使用while語(yǔ)句讓PR通過。

為了使上述問題更簡(jiǎn)潔,可以創(chuàng)建一個(gè)新的IterableInputStream類型,如下:

 
 
 
 
  1. static class InputStreamIterable implements Iterable { 
  2.   private final InputStream is; 
  3.   public InputStreamIterable(InputStreamis) { 
  4.     this.is = is; 
  5.   } 
  6.   public Iteratoriterator() { 
  7.      return newIterator() {               
  8.         public boolean hasNext() { 
  9.            try { 
  10.              // poor man's peek: 
  11.              is.mark(1); 
  12.              boolean ret = is.read() !=-1; 
  13.              is.reset(); 
  14.              return ret; 
  15.            } catch (IOException ex) { 
  16.              throw new RuntimeException( 
  17.                     "Error readinginput stream", ex); 
  18.            } 
  19.         } 
  20.         public Character next() { 
  21.            try { 
  22.              return (char)is.read(); 
  23.            } catch (IOException ex) { 
  24.              throw new RuntimeException( 
  25.                    "Error readinginput stream", ex); 
  26.            } 
  27.         } 
  28.      }; 
  29.   } 

這樣就大大簡(jiǎn)化了循環(huán)問題:

 
 
 
 
  1. // use a predefined inputstream iterator: 
  2. InputStreamIterable it = new InputStreamIterable( 
  3.     LoopElimination.class.getResourceAsStream("/testfile.txt")); 
  4. StreamSupport.stream(it.spliterator(), false) 
  5.    .forEach(ch -> System.out.print(ch)); 

如果你經(jīng)常遇到此類while循環(huán),那么你可以創(chuàng)建并使用一個(gè)專門的Iterable類。但如果只用一次,就不必大費(fèi)周章,這只是新舊Java不兼容的一個(gè)例子。

所以,下次你在代碼中寫for 語(yǔ)句或 while語(yǔ)句的時(shí)候,可以停下來思考一下如何用forEach 或 Stream更好地完成你的代碼。


網(wǎng)頁(yè)名稱:For循環(huán)和While循環(huán)之流的終結(jié)
文章出自:http://www.5511xx.com/article/cdecgje.html