公司的一个java面试题
第一次在博客园写文章还有点小紧张。
我公司里最近在招java开发工程师,我看了同事出的一份面试题,总体还比较简单,考查的都是基础,没有什么奇怪的算法。其中一个题虽然描述很短,但放在了最后一道,同事说还比较经典。我一看还确实是个坑。
题目描述:
交换两个数。
分析:
用java实现交换两个数应该是比较经典而又坑的题目,使用过C/C++都知道C/C++的函数可以通过取地址值的方法操作实参,如
void swap(int &a,int &b) { int temp; temp=a; a=b; b=temp; }
但使用java的方法就出现问题了:java方法的形参分两种情况,一种是基本类型的参数,这类参数是传值,方法的调用不影响实参,另一种是引用类型,直接传递的是对象。于是问题来了,如何用java实现swap方法。
public class Solution { public static void main(String[] args) { int a=9; int b=4; System.out.println("------swap执行前------"); System.out.println("a:"+a); System.out.println("b:"+b); swap(a,b); System.out.println("------swap执行后------"); System.out.println("a:"+a); System.out.println("b:"+b); } public static void swap(int a, int b) { int temp; temp=a; a=b; b=temp; } }
结果自然不尽如人意:
------swap执行前------ a:9 b:4 ------swap执行后------ a:9 b:4
这个题如果有人这么回答,结果自然是再见。其实只要像下面这样就可以通过这道题,再向面试官或者在试卷上说明为什么不能写成静态方法,当然面试官满不满意要看他的心情。
public class Solution { public static void main(String[] args) { int a=9; int b=4; System.out.println("------swap执行前------"); System.out.println("a:"+a); System.out.println("b:"+b); int temp; temp=a; a=b; b=temp; System.out.println("------swap执行后------"); System.out.println("a:"+a); System.out.println("b:"+b); } }
再装逼点就用异或实现数据交换,写成下面这样:
public class Solution { public static void main(String[] args) { int a=9; int b=4; System.out.println("------swap执行前------"); System.out.println("a:"+a); System.out.println("b:"+b); a=a^b; b=a^b; a=a^b; System.out.println("------swap执行后------"); System.out.println("a:"+a); System.out.println("b:"+b); } }
或者是:
a=a+b; b=a-b; a=a-b;
或者直接用下面一句:
b=(a+b)-(a=b);
但绕半天那个问题还是没有解决,那如何是好呢?
思路一:使用数组交换数据的封装
public class Solution { public static void main(String[] args) { int a=9; int b=4; System.out.println("------swap执行前------"); System.out.println("a:"+a); System.out.println("b:"+b); int[] arr=new int[]{a,b}; swap(arr); System.out.println("------swap执行后------"); System.out.println("a:"+arr[0]); System.out.println("b:"+arr[1]); } public static void swap(int[] arr) { if(arr.length==2){ int temp=arr[0]; arr[0]=arr[1]; arr[1]=temp; } } }
思路二:自己写一个封装类
public class Solution { public int a; public int b; public Solution(int a,int b){ this.a=a; this.b=b; } public static void main(String[] args) { int a=9; int b=4; System.out.println("------swap执行前------"); System.out.println("a:"+a); System.out.println("b:"+b); Solution s=new Solution(a,b); swap(s); System.out.println("------swap执行后------"); System.out.println("a:"+s.a); System.out.println("b:"+s.b); } public static void swap(Solution s) { int temp=s.a; s.a=s.b; s.b=temp; } }
思路三:定义时候使用包装类Integer(不可行!)
解释:String,基本类型,包装类型都是值传递。
思路四(实际开发解决方案):开发中我们要交换两个数,直接写三行或者一行代码比调方法效率更高。再者说,开发人员为什么要交换a和b,在下面的代码中直接要什么用什么就好了。实际上,此类问题最常见的步骤是调用工具类后就能直接使用,实际上许多原生的api都有swap()方法,特别是使用集合的工具类Collections进行swap操作就更加方便。
API:
public static void swap(List<?> list,int i, int j)
在指定列表的指定位置处交换元素。(如果指定位置相同,则调用此方法不会更改列表。)
- 参数:
list
- 进行元素交换的列表。i
- 要交换的一个元素的索引。j
- 要交换的另一个元素的索引。- 抛出:
IndexOutOfBoundsException
- 如果 i 或 j 超出范围 (i < 0 || i >= list.size() || j < 0 || j >= list.size())。- 从以下版本开始:
- 1.4
思路五(拓展思路):我们能否定义一个工具类SwapUtil,我们自己完善这个工具类后,以后就拿来用就好?
总结:java中的内存分为堆内存(heap)和栈内存(stack),堆就是用来存放对象的,而栈则是存放一些数据基本类型的值。java中一切都是对象!
另:搞半天我也没有个对象,用java写swap的静态方法问题也是无解。