国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

如何解決Java中list.foreach不能使用字符串拼接的問(wèn)

發(fā)布時(shí)間:2021-09-27 17:50 來(lái)源:億速云 閱讀:0 作者:小新 欄目: 開(kāi)發(fā)技術(shù)

這篇文章將為大家詳細講解有關(guān)如何解決Java中list.foreach不能使用字符串拼接的問(wèn)題,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

    list.foreach不能使用字符串拼接

    如圖,不能使用String進(jìn)行拼接

    因為L(cháng)ambda的本質(zhì)實(shí)際上是匿名內部類(lèi),所以t必須是final類(lèi)型(不過(guò)代碼中的final可以省略),是不可以重新賦值的。

    可以使用

    final StringBuilder str = new StringBuilder("已選擇:");

    如圖二

    foreach循環(huán)中不能使用字符串拼接

    問(wèn)題

    @Test
        public void forEachTest(){
            String str = "中國你好!";
            List<String> list = Arrays.asList("a","b","c","d");        
            list.forEach(item->{
             //編輯錯誤:Variable used in lambda expression should be final or effectively final
                str += item;
            });
            //可以使用增強for
    //        for (String item : list) {
    //            str += item;
    //        }
            System.out.println("結果:" + str);
        }

    該編譯不通過(guò)的根本原因:Lambda表達式中的局部變量要使用final的問(wèn)題。

    因為String類(lèi)型屬于引用數據類(lèi)型,String字符串有不可變的特性,String在進(jìn)行字符串拼接時(shí),每次都會(huì )指向不同的地址值,因此str變量不能被看作是一個(gè)final類(lèi)型,也就不符合Lambda表達式的使用要求。

    解決

    使用StringBuffer或StringBuilder:

    @Test
        public void forEachTest(){
            //String str = "中國你好!";
            List<String> list = Arrays.asList("a","b","c","d");
            StringBuffer stringbuffer = new StringBuffer("中國你好!");
            list.forEach(item->{
                stringbuffer .append(item);
            });
            //可以使用增強for
    //        for (String item : list) {
    //            str += item;
    //        }
            System.out.println("結果:" + sb);
        }

    原理 ??

    StringBuffer是一個(gè)引用數據類(lèi)型,在進(jìn)行append()時(shí),只是修改了內容,并沒(méi)有改變地址值,這個(gè)stringbuffer變量就在編譯時(shí)看成了final類(lèi)型的變量,因此可以使用。

    Lambda表達式中的局部變量要使用final的問(wèn)題

    lambda表達式使用局部變量要用final

    lambda表達式本身是一個(gè)匿名內部類(lèi)的一種編寫(xiě)形式,可以操作外部的變量

    使用實(shí)例變量或靜態(tài)變量是沒(méi)有限制的(可認為是通過(guò) final 類(lèi)型的局部變量 this 來(lái)引用前兩者)

    使用局部變量必須顯式的聲明為 final 或實(shí)際效果的的 final 類(lèi)型,即該變量從未被改變過(guò)

    @Test
        public void finalTest(){
            String str = "中國你好!";        
            //在Lambda中使用該變量,該變量不能被修改過(guò),java8會(huì )默認加上final
            //str = "c";
            List<String> list = Arrays.asList("a","b","c","d");
            List<String> collect = list.stream().filter(item -> {
                return item.equals(str);
            }).collect(Collectors.toList());
            System.out.println("結果:" + collect);
      //不能改變str,否則Lambda表達式中編譯失敗
      //str = "山東你好";
        }

    一個(gè)局部變量如果要在匿名類(lèi)或是 Lambda 表達式中訪(fǎng)問(wèn),那么這個(gè)局部變量必須是 final 的,即使沒(méi)有修飾為 final 類(lèi)型,編譯器也會(huì )自動(dòng)加上 final 修飾符。

    在 Java 8 下,即使局部變量未聲明為 final 類(lèi)型,一旦在 Lambda 表達式(匿名類(lèi)) 中使用,就被強型加上了 final 屬性,所以后面就無(wú)法再次給 str 賦值了。

    為什么 Lambda 表達式(匿名類(lèi)) 不能訪(fǎng)問(wèn)非 final 的局部變量呢?

    因為實(shí)例變量存在堆中,而局部變量是在棧上分配,Lambda 表達式(匿名類(lèi)) 會(huì )在另一個(gè)線(xiàn)程中執行。如果在線(xiàn)程中要直接訪(fǎng)問(wèn)一個(gè)局部變量,可能線(xiàn)程執行時(shí)該局部變量已經(jīng)被銷(xiāo)毀了,而 final 類(lèi)型的局部變量在 Lambda 表達式(匿名類(lèi)) 中其實(shí)是局部變量的一個(gè)拷貝。

    在java編譯時(shí),匿名內部類(lèi)也會(huì )被當作普通的類(lèi)處理,只不過(guò)編譯器生成它構造方法的時(shí)候,除了將外部類(lèi)的引用傳遞了過(guò)來(lái),還將基本數據類(lèi)型的變量復制了一份過(guò)來(lái),并把引用數據類(lèi)型的變量引用也傳遞了過(guò)來(lái)。因此,基本數據類(lèi)型的變量當然不能修改了,不然就會(huì )跟外部的變量產(chǎn)生不一致,這樣的話(huà)變量的傳遞也就變得毫無(wú)意義了。

    免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。

    少妇人妻系列无码专区视频| 无遮掩60分钟从头啪到尾| 中文字幕日本人妻久久久免费| 无码AV天堂一区二区三区| 亚洲国产成人久久一区| 国产高清在线精品一区APP|