0%

Java中数组的值传递

今天在做LeetCode27题(https://leetcode.cn/problems/remove-element/)时发现了一个问题,我自己的解法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**
* Created with IntelliJ IDEA.
*
* @Author: smionf
* @Date: 2024/04/19/16:40
* @Description:
*/
public class LC27RemoveElement {
public static int removeElement(int[] nums, int val) {
int[] newNums = new int[nums.length];
int count = 0,j=0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == val) {
count++;
continue;
}
newNums[j]=nums[i];
j++;
}
nums = newNums;

return nums.length-count;
}

public static void main(String[] args) {
int[] nums = {3,2,2,3};
int lg = removeElement(nums, 3);
System.out.println(lg);
System.out.println("------------");
for (int i = 0; i < nums.length; i++) {
System.out.println(nums[i]);
}
}
}

以上代码的打印结果是[3,2,2,3]而不是[2,2,0,0],没有通过debug发现原因。

查询资料(参考链接:java 值传递 数组传递 - The_PopCore - 博客园 (cnblogs.com))发现原因如下:

以上代码中,虽然在removeElement方法中将符合条件的元素替换为0,但是在main方法中打印数组时,打印的仍然是原始的nums数组,而没有打印替换后的nums数组。这是因为Java中的数组是按值传递的,所以在removeElement方法中修改nums数组并不会影响main方法中的nums数组。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Test{

String str = new String("good");
char[] ch = {'a','b','c'};
int i = 10;
public void change(String str,char ch,int i){

str = "test ok";
ch = 'g';
this.i = i+1;
}

public static void main(String[] args){

Test tt = new Test();
tt.change(tt.str,tt.ch[0],tt.i);
System.out.println(tt.i);
System.out.print(tt.str+" and ");
System.out.println(tt.ch);
}
}

change()方法里的入参为char ch;

传递的是个char值的单个数组元素,此时ch=’g’;是不影响源数组元素的。

this.i = i+1;这里面等号左边的i是属性i,等号右边的i是局部变量(入参里的i);

此时i+1后赋值给属性的i,自然会改变属性i的值,同时17行,tt.i又是调用属性的i,输出的结果是:

1
2
3
11

good and abc

顺带附上LeetCode27题我的解法:

题目:

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例 1:

1
2
3
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。

示例 2:

1
2
3
输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,3,0,4]
解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。

这道题可以用双指针解法(快指针寻找新数组的元素 ,新数组就是不含有目标元素的数组,慢指针指向更新 新数组下标的位置):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.simonf.array;

/**
* Created with IntelliJ IDEA.
*
* @Author: smionf
* @Date: 2024/04/19/16:40
* @Description:
*/
public class LC27RemoveElement {
public static int removeElement(int[] nums, int val) {
int slowIndex = 0;//新数值元素的更新位置
int fastIndex ;
for (fastIndex = 0; fastIndex < nums.length; fastIndex++) {
if (nums[fastIndex] == val) {
continue;
}
nums[slowIndex] = nums[fastIndex];
slowIndex++;
}
return slowIndex;
}

public static void main(String[] args) {
int[] nums = {3, 2, 2, 3};
int lg = removeElement(nums, 3);
System.out.println(lg);
System.out.println("------------");
for (int i = 0; i < nums.length; i++) {
System.out.println(nums[i]);
}
}


}
-------------本文结束感谢您的阅读-------------

欢迎关注我的其它发布渠道