[問題] 使用stream 跟 for loop 印出來不一樣 ?

作者: ntpuisbest (阿龍)   2022-04-28 00:10:04
※狀況概述: 最近在練習leetcode 的 removeElement
發現使用stream api 和 使用for loop 去指定元素 答案會不一樣?
使用steam api 在函數裡面有正確改成功 但是 在main 裡面就不一樣了
有點難以敘述,請直接看code
※程式碼:
public class LC0027RemoveElement {
public static int removeElement(int[] nums, int val) {
List<Integer> intList = new ArrayList<Integer>(nums.length);
int count=0;
int length=nums.length;
for (int i : nums){
if(i==val) {
count++;
}
}
System.out.println("length: "+nums.length);
System.out.println("count: "+count);
for (int i : nums){
intList.add(i);
}
System.out.println("size: " + intList.size() );
intList.removeAll(Arrays.asList(val));
nums = intList.stream().mapToInt(i -> i).toArray();
System.out.println("size: " + intList.size() );
// for(int i=0;i< intList.size();i++) {
// nums[i]=intList.get(i);
// }
System.out.println("nums in function:"+ Arrays.toString(nums)
return length-count;
}
public static void main(String[] args) {
int [] nums= { 3, 1, 2, 3, 2 };
int val=3;
int answer;
answer=removeElement(nums ,val);
System.out.println(answer);
System.out.println("print nums in main "+ Arrays.toString(num
s)
}
}
結果如下:
註解掉for loop的版本
https://imgur.com/YlOHT1Y
沒有註解調for loop的版本
https://imgur.com/mVzZBtl
我的思路是 先將 nums這個陣列裡面的值都copy 到 arraylist裡面
然後利用arraylist裡面的方法將 val 都移除掉
移除完之後再產生 nums = intList.stream().mapToInt(i -> i).toArray();
問題是 nums在函數裡面是有被更改的 為何在main裡面沒有被更改 ??
令人疑惑的另外一件事情是
如果將我註解的for loop 拿掉
這樣函數裡面印出來的 跟 main 裡面去印 nums 都會一致
有點搞不太懂理由是為何
作者: mikemike1021 (mike)   2022-04-28 04:57:00
沒有註解掉 for-loop 的還有那段 nums = ... map 那段嗎? 如果沒有的話,那函式內是有改掉的,但只有改掉前三個值,但 nums 本身長度沒有被改int [] nums 傳進函式的只是陣列位置的,nums = ...map 那段把位置換掉而已,並沒有更改到外面的,但是main nums 指的位置還是原先那塊,所以外面的不會變。
作者: lycantrope (阿寬)   2022-04-28 09:19:00
傳入func的是nums位置,nums[i]是將數值放入指定位置但map則是產生新的地址命名為nums,原始的nums不會變
作者: ssccg (23)   2022-04-28 12:33:00
nums = intList.stream().mapToInt(i -> i).toArray();是產生新的Array,將reference存到nums這個變數當然就不是原本nums指到的Array跟for相等的寫法是 IntStream.range(0, intList.size()).forEach(i -> nums[i]=intList.get(i));另外你想做個移除元素的方法,但是陣列長度根本不能改,選用這個容器你從很基本的地方就錯了
作者: gasbomb (虛空雷神獸)   2022-04-28 23:47:00
題目貼上來看看 沒頭沒尾的看不懂你的問題啊 看到了 是leetcode第27題 這題你要做的是把指定的元素移到array的最後 也就是[3,1,2,3,2]變成[1,2,2,3,3]才對同學題目不要只看1/4啊 第二段有說不能改陣列長度的語言(就是java)要用交換的 然後第四段有說不能夠宣告新的陣列
作者: fgh81113 (阿景)   2022-04-30 23:39:00
可能是jdk問題吧 https://imgur.com/oA73a4M這個是沒註解的版本你可以用debug模式一步一步看結果阿
作者: ntpuisbest (阿龍)   2022-05-04 10:53:00
我的jdk好像真的有些問題跟leetcode不一樣,不過找不太到出在哪哈哈

Links booklink

Contact Us: admin [ a t ] ucptt.com