八種方法(實(shí)現(xiàn)兩個(gè)數(shù)互換),絕了絕了!
實(shí)現(xiàn)兩個(gè)數(shù)互換的八種方法
基本數(shù)據(jù)類型
借助第三個(gè)變量
- package 貪心;/*
- 作者 :XiangLin
- 創(chuàng)建時(shí)間 :2020/9/15 22:48
- 文件 :XX.java
- IDE :IntelliJ IDEA
- */
- import java.util.Random;
- public class Exchange1 {
- public static void main(String[] args) {
- /**
- * 隨機(jī)生成兩個(gè)固定序列的0-100之間的整數(shù),
- * 其中101表示生成的數(shù)范圍區(qū)間在:[0-101)
- */
- Random random = new Random(47);
- int a = random.nextInt(101);
- int b = random.nextInt(101);
- System.out.println("交換前:a = " + a + ", b = " + b);
- /**
- * 借助第三個(gè)變量實(shí)現(xiàn)第三個(gè)數(shù)互換
- */
- int t = a; // t == a
- a = b; // a == b
- b = t; // b == t == a
- System.out.println("交換后:a = " + a + ", b = " + b);
- }
- }
控制臺(tái)輸出如下:
如果有不明白的朋友,可以自己準(zhǔn)備三個(gè)杯子,一個(gè)空杯代表變量t,兩個(gè)杯子裝上水分別代表變量a、b,然后互換一下a、b兩個(gè)杯子里的水即可明白。
不借助第三個(gè)變量
- package 貪心;/*
- 作者 :XiangLin
- 創(chuàng)建時(shí)間 :2020/9/15 22:51
- 文件 :cccc.java
- IDE :IntelliJ IDEA
- */
- import java.util.Random;
- public class Exchange2 {
- public static void main(String[] args) {
- /**
- * 隨機(jī)生成兩個(gè)固定序列的0-100之間的整數(shù),
- * 其中101表示生成的數(shù)范圍區(qū)間在:[0-101)
- */
- Random random = new Random(48);
- int a = random.nextInt(101);
- int b = random.nextInt(101);
- System.out.println("交換前:a = " + a + ", b = " + b);
- a = a + b; // a == a + b
- b = a - b; // b == a + b - b == a, 此時(shí)b == a
- a = a - b; // a == a + b - a == b, 此時(shí)a == b
- System.out.println("交換后:a = " + a + ", b = " + b);
- }
- }
控制臺(tái)輸出如下:
通過乘除操作實(shí)現(xiàn)兩個(gè)數(shù)互換
- package 貪心;/*
- 作者 :XiangLin
- 創(chuàng)建時(shí)間 :2020/9/15 22:54
- 文件 :xxx.java
- IDE :IntelliJ IDEA
- */
- import java.util.Random;
- public class Exchange3 {
- public static void main(String[] args) {
- /**
- * 隨機(jī)生成兩個(gè)固定序列的0-100之間的整數(shù),
- * 其中101表示生成的數(shù)范圍區(qū)間在:[0-101)
- */
- Random random = new Random(50);
- int a = random.nextInt(101);
- int b = random.nextInt(101);
- System.out.println("交換前:a = " + a + ", b = " + b);
- a = a * b; // 此時(shí)a == a * b
- b = a / b; // b == a * b / b == a, 此時(shí)b == a
- a = a / b; // a == a * b / a == b, 此時(shí)a == b
- System.out.println("交換后:a = " + a + ", b = " + b);
- }
- }
Output:
利用賦值運(yùn)算符
因?yàn)檫@兩種方法是筆者后面補(bǔ)充的,所以第七種和第八種方法放在前面
利用賦值和加減來(lái)實(shí)現(xiàn)兩個(gè)數(shù)互換
- package 貪心;/*
- 作者 :XiangLin
- 創(chuàng)建時(shí)間 :2020/9/15 22:58
- 文件 :xx.java
- IDE :IntelliJ IDEA
- */
- public class Exchange7 {
- public static void main(String[] args) {
- /**
- * 隨機(jī)生成兩個(gè)0-100之間的整數(shù),
- * 其中Math.random()會(huì)生成[0-1)之間任意的double類型的數(shù)
- * 因此101表示生成的數(shù)范圍區(qū)間在:[0-101)
- */
- int a = (int) (Math.random() * 101);
- int b = (int) (Math.random() * 101);
- System.out.println("交換前: a = " + a + ", b = " + b);
- a = b + a - (b = a); // a == b + a - a == b, a == b
- System.out.println("交換后: a = " + a + ", b = " + b);
- }
- }
控制臺(tái)輸出如下:
利用賦值和加乘來(lái)實(shí)現(xiàn)兩個(gè)數(shù)互換
- package 貪心;/*
- 作者 :XiangLin
- 創(chuàng)建時(shí)間 :2020/9/15 23:00
- 文件 :xxx.java
- IDE :IntelliJ IDEA
- */
- public class Exchange8 {
- public static void main(String[] args) {
- /**
- * 隨機(jī)生成兩個(gè)0-100之間的整數(shù),
- * 其中Math.random()會(huì)生成[0-1)之間任意的double類型的數(shù)
- * 因此101表示生成的數(shù)范圍區(qū)間在:[0-101)
- */
- int a = (int) (Math.random() * 101);
- int b = (int) (Math.random() * 101);
- System.out.println("交換前: a = " + a + ", b = " + b);
- a = b + (b = a) * 0; // a == b + a * 0 == b, a == b
- System.out.println("交換后: a = " + a + ", b = " + b);
- }
- }
控制臺(tái)輸出如下:
異或
在介紹第四種方法之前,首先要跟大家介紹一下Java中的"異或"操作符(^)。
異或操作符是Java中按位操作符的一種,那么什么是按位操作符呢?
按位操作符用來(lái)操作整數(shù)基本數(shù)據(jù)類型中的單個(gè)"比特"(bit),即二進(jìn)制位。我們都知道,計(jì)算機(jī)中是采用二進(jìn)制計(jì)數(shù),而不是十進(jìn)制計(jì)數(shù)。也就是說(shuō),計(jì)算機(jī)中沒有我們所謂的2、3、4、5 … 100 … 1000 … ,計(jì)算機(jī)中有的只是0和1,逢二便進(jìn)一。而按位操作符會(huì)對(duì)兩個(gè)參數(shù)中對(duì)應(yīng)的位,也就是對(duì)用二進(jìn)制表示的兩個(gè)參數(shù)相對(duì)應(yīng)的0或1,執(zhí)行布爾代數(shù)運(yùn)算,并最終生成一個(gè)結(jié)果。
當(dāng)然在Java中我們一般運(yùn)用按位操作符很少,而我們最開始接觸按位操作符,很可能是從C語(yǔ)言或者數(shù)字邏輯與電路。事實(shí)上,按位操作符來(lái)源于C語(yǔ)言面向底層的操作,這種操作經(jīng)常需要直接操縱硬件,設(shè)置硬件寄存器內(nèi)的二進(jìn)制位。而Java的設(shè)計(jì)初衷是嵌入電視機(jī)機(jī)頂盒內(nèi),所以這種面向底層的操作被保留了下來(lái)。Java技術(shù)的三大版本之一:JavaME,Java平臺(tái)微型版正是用作嵌入式開發(fā),用來(lái)開發(fā)數(shù)字機(jī)頂盒、可視電話等電子設(shè)備。
了解了按位操作符的概念,那么接下來(lái),我們來(lái)了解"異或"操作
如a ^ b,若a、b兩個(gè)值不同,則異或結(jié)果為1;若a、b兩個(gè)數(shù)相同,則異或結(jié)果為0。
大家如果要記憶的話,可以記住六字真言:同為0,異為1。
或者明白或運(yùn)算的朋友也可以通過字面意思來(lái)理解,若兩數(shù)相異(要么是0和1,要么是1和0),則執(zhí)行或運(yùn)算;若兩數(shù)相同(同為0,或同為1),則結(jié)果為0。
如果還是有點(diǎn)抽象的話,沒得事,直接上代碼:
- package 貪心;/*
- 作者 :XiangLin
- 創(chuàng)建時(shí)間 :2020/9/15 23:05
- 文件 :xxx.java
- IDE :IntelliJ IDEA
- */
- public class Test {
- public static void main(String[] args) {
- /**
- * 分別把結(jié)果以二進(jìn)制的形式輸出
- */
- System.out.println("3的二進(jìn)制:" + Integer.toBinaryString(3));
- System.out.println("4的二進(jìn)制:" + Integer.toBinaryString(4));
- System.out.println("3 ^ 3 的二進(jìn)制:" + Integer.toBinaryString(3 ^ 3));
- System.out.print("3 ^ 0 的二進(jìn)制:" + Integer.toBinaryString(3 ^ 0));
- if (3 == (3 ^ 0))
- System.out.println(",也就是十進(jìn)制的3");
- System.out.print("4 ^ 3 ^ 3 的二進(jìn)制:" + Integer.toBinaryString(4 ^ 3 ^ 3));
- if (4 == (4 ^ 3 ^ 3))
- System.out.println(",也就是十進(jìn)制的4");
- }
- }
Output:
好戲開場(chǎng),通過異或操作實(shí)現(xiàn)兩個(gè)數(shù)互換
- package 貪心;/*
- 作者 :XiangLin
- 創(chuàng)建時(shí)間 :2020/9/15 23:08
- 文件 :xx.java
- IDE :IntelliJ IDEA
- */
- import java.util.Random;
- public class Exchange4 {
- public static void main(String[] args) {
- /**
- * 隨機(jī)生成兩個(gè)固定序列的0-100之間的整數(shù),
- * 其中101表示生成的數(shù)范圍區(qū)間在:[0-101)
- */
- Random random = new Random(51);
- int a = random.nextInt(101);
- int b = random.nextInt(101);
- System.out.println("交換前:a = " + a + ", b = " + b);
- a = a ^ b; // 此時(shí), a == a ^ b
- b = a ^ b; // b == a ^ b ^ b == a, 此時(shí)b == a
- a = a ^ b; // a == a ^ b ^ a == b, 此時(shí)a == b
- System.out.println("交換后:a = " + a + ", b = " + b);
- }
- }
Output:
引用數(shù)據(jù)類型
想必大家已經(jīng)學(xué)了四種方法,已經(jīng)對(duì)兩個(gè)數(shù)互換信心滿滿,那么接下來(lái),我們來(lái)看一道面試題:
- package 貪心;/*
- 作者 :XiangLin
- 創(chuàng)建時(shí)間 :2020/9/15 23:10
- 文件 :xx.java
- IDE :IntelliJ IDEA
- */
- public class Exchange5 {
- public static void main(String[] args) {
- Integer a = 10;
- Integer b = 20;
- swop(a, b);
- // 打印結(jié)果:a = 20, b = 10
- System.out.println("a = " + a + ", b = " + b);
- }
- private static void swop(Integer a, Integer b) {
- // 完成此處代碼
- }
- }
如代碼所示,完成指定位置的代碼,使得程序最后的運(yùn)行結(jié)果為:a = 20, b = 10
你可能覺得這還不簡(jiǎn)單,然后"刷刷刷"完成可能如以下的代碼:
- private static void swop(Integer a, Integer b) {
- a = a ^ b;
- b = a ^ b;
- a = a ^ b;
- }
然后再看輸出結(jié)果就傻眼了:
納尼,不變?這是為什么?想知道為什么的可能需要自行了解一下Java內(nèi)存模型了,畢竟Java里面沒有C語(yǔ)言的指針(小聲bb)。當(dāng)然,本博主以后可能也會(huì)出這方面的博客。
下面讓我來(lái)揭曉正確答案吧!
- private static void swop(Integer a, Integer b) throws NoSuchFieldException, IllegalAccessException {
- // 完成此處代碼
- // a = a ^ b;
- // b = a ^ b;
- // a = a ^ b;
- int x = a;
- int y = b;
- // 運(yùn)用反射來(lái)操作Integer
- Class c = Integer.class;
- Field field = c.getDeclaredField("value");
- // 授權(quán)訪問私有
- field.setAccessible(true);
- // 將 a、b的值分別設(shè)置為y、x的值
- field.setInt(a, y);
- field.setInt(b, x);
- }
當(dāng)當(dāng)當(dāng)當(dāng),控制臺(tái)輸出如下:
至于如果有朋友想了解反射的知識(shí),可以關(guān)注我的博客哦!畢竟反射是我當(dāng)年學(xué)習(xí)JavaSE知識(shí)覺得最神奇也最喜歡的三個(gè)知識(shí)之一。
至于第六種方法嘛:
- private static void swop(Integer a, Integer b) {
- System.out.println("a = " + b + ", b = " + a);
- // 終止Java虛擬機(jī)的運(yùn)作
- System.exit(0);
- }
哈哈,不要打我哦,我就皮這一下…
畢竟,題目只是說(shuō),使得運(yùn)行結(jié)果為:a = 20, b = 10 即可(^_−)☆
所有巧合的是要么是上天注定要么是一個(gè)人偷偷的在努力。
結(jié)束!
作者:古闕月
原文鏈接:http://nxw.so/44cPJ
本文轉(zhuǎn)載自微信公眾號(hào)「五角錢的程序員」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系五角錢的程序員公眾號(hào)。