八种方法(实现两个数互换),绝了绝了!

开发 前端
当然在Java中我们一般运用按位操作符很少,而我们最开始接触按位操作符,很可能是从C语言或者数字逻辑与电路。

 [[343266]]

实现两个数互换的八种方法

基本数据类型

借助第三个变量

  1. package 贪心;/* 
  2. 作者     :XiangLin 
  3. 创建时间 :2020/9/15 22:48 
  4. 文件     :XX.java 
  5. IDE      :IntelliJ IDEA 
  6. */ 
  7.  
  8. import java.util.Random; 
  9.  
  10. public class Exchange1 { 
  11.     public static void main(String[] args) { 
  12.         /** 
  13.          * 随机生成两个固定序列的0-100之间的整数, 
  14.          * 其中101表示生成的数范围区间在:[0-101) 
  15.          */ 
  16.         Random random = new Random(47); 
  17.         int a = random.nextInt(101); 
  18.         int b = random.nextInt(101); 
  19.         System.out.println("交换前:a = " + a + ", b = " + b); 
  20.  
  21.         /** 
  22.          * 借助第三个变量实现第三个数互换 
  23.          */ 
  24.         int t = a; // t == a 
  25.         a = b;     // a == b 
  26.         b = t;     // b == t == a 
  27.         System.out.println("交换后:a = " + a + ", b = " + b); 
  28.     } 

控制台输出如下:

 

如果有不明白的朋友,可以自己准备三个杯子,一个空杯代表变量t,两个杯子装上水分别代表变量a、b,然后互换一下a、b两个杯子里的水即可明白。

 

不借助第三个变量

  1. package 贪心;/* 
  2. 作者     :XiangLin 
  3. 创建时间 :2020/9/15 22:51 
  4. 文件     :cccc.java 
  5. IDE      :IntelliJ IDEA 
  6. */ 
  7.  
  8. import java.util.Random; 
  9.  
  10. public class Exchange2 { 
  11.     public static void main(String[] args) { 
  12.         /** 
  13.          * 随机生成两个固定序列的0-100之间的整数, 
  14.          * 其中101表示生成的数范围区间在:[0-101) 
  15.          */ 
  16.         Random random = new Random(48); 
  17.         int a = random.nextInt(101); 
  18.         int b = random.nextInt(101); 
  19.         System.out.println("交换前:a = " + a + ", b = " + b); 
  20.  
  21.         a = a + b; // a == a + b 
  22.         b = a - b; // b == a + b - b == a, 此时b == a 
  23.         a = a - b; // a == a + b - a == b, 此时a == b 
  24.         System.out.println("交换后:a = " + a + ", b = " + b); 
  25.     } 

控制台输出如下:

 

通过乘除操作实现两个数互换

  1. package 贪心;/* 
  2. 作者     :XiangLin 
  3. 创建时间 :2020/9/15 22:54 
  4. 文件     :xxx.java 
  5. IDE      :IntelliJ IDEA 
  6. */ 
  7.  
  8. import java.util.Random; 
  9.  
  10. public class Exchange3 { 
  11.     public static void main(String[] args) { 
  12.         /** 
  13.          * 随机生成两个固定序列的0-100之间的整数, 
  14.          * 其中101表示生成的数范围区间在:[0-101) 
  15.          */ 
  16.         Random random = new Random(50); 
  17.         int a = random.nextInt(101); 
  18.         int b = random.nextInt(101); 
  19.         System.out.println("交换前:a = " + a + ", b = " + b); 
  20.  
  21.         a = a * b; // 此时a == a * b 
  22.         b = a / b; // b == a * b / b == a, 此时b == a 
  23.         a = a / b; // a == a * b / a == b, 此时a == b 
  24.         System.out.println("交换后:a = " + a + ", b = " + b); 
  25.     } 

Output:

 

利用赋值运算符

因为这两种方法是笔者后面补充的,所以第七种和第八种方法放在前面

利用赋值和加减来实现两个数互换

  1. package 贪心;/* 
  2. 作者     :XiangLin 
  3. 创建时间 :2020/9/15 22:58 
  4. 文件     :xx.java 
  5. IDE      :IntelliJ IDEA 
  6. */ 
  7.  
  8. public class Exchange7 { 
  9.     public static void main(String[] args) { 
  10.  
  11.         /** 
  12.          *  随机生成两个0-100之间的整数, 
  13.          *  其中Math.random()会生成[0-1)之间任意的double类型的数 
  14.          *  因此101表示生成的数范围区间在:[0-101) 
  15.          */ 
  16.         int a = (int) (Math.random() * 101); 
  17.         int b = (int) (Math.random() * 101); 
  18.         System.out.println("交换前: a = " + a + ", b = " + b); 
  19.  
  20.         a = b + a - (b = a); // a == b + a - a == b, a == b 
  21.         System.out.println("交换后: a = " + a + ", b = " + b); 
  22.     } 

控制台输出如下:

 

利用赋值和加乘来实现两个数互换

  1. package 贪心;/* 
  2. 作者     :XiangLin 
  3. 创建时间 :2020/9/15 23:00 
  4. 文件     :xxx.java 
  5. IDE      :IntelliJ IDEA 
  6. */ 
  7.  
  8. public class Exchange8 { 
  9.     public static void main(String[] args) { 
  10.  
  11.         /** 
  12.          *  随机生成两个0-100之间的整数, 
  13.          *  其中Math.random()会生成[0-1)之间任意的double类型的数 
  14.          *  因此101表示生成的数范围区间在:[0-101) 
  15.          */ 
  16.         int a = (int) (Math.random() * 101); 
  17.         int b = (int) (Math.random() * 101); 
  18.         System.out.println("交换前: a = " + a + ", b = " + b); 
  19.  
  20.         a = b + (b = a) * 0; // a == b + a * 0 == b, a == b 
  21.         System.out.println("交换后: a = " + a + ", b = " + b); 
  22.     } 

控制台输出如下:

 

异或

在介绍第四种方法之前,首先要跟大家介绍一下Java中的"异或"操作符(^)。

异或操作符是Java中按位操作符的一种,那么什么是按位操作符呢?

按位操作符用来操作整数基本数据类型中的单个"比特"(bit),即二进制位。我们都知道,计算机中是采用二进制计数,而不是十进制计数。也就是说,计算机中没有我们所谓的2、3、4、5 … 100 … 1000 … ,计算机中有的只是0和1,逢二便进一。而按位操作符会对两个参数中对应的位,也就是对用二进制表示的两个参数相对应的0或1,执行布尔代数运算,并最终生成一个结果。

当然在Java中我们一般运用按位操作符很少,而我们最开始接触按位操作符,很可能是从C语言或者数字逻辑与电路。事实上,按位操作符来源于C语言面向底层的操作,这种操作经常需要直接操纵硬件,设置硬件寄存器内的二进制位。而Java的设计初衷是嵌入电视机机顶盒内,所以这种面向底层的操作被保留了下来。Java技术的三大版本之一:JavaME,Java平台微型版正是用作嵌入式开发,用来开发数字机顶盒、可视电话等电子设备。

了解了按位操作符的概念,那么接下来,我们来了解"异或"操作

如a ^ b,若a、b两个值不同,则异或结果为1;若a、b两个数相同,则异或结果为0。

大家如果要记忆的话,可以记住六字真言:同为0,异为1。

或者明白或运算的朋友也可以通过字面意思来理解,若两数相异(要么是0和1,要么是1和0),则执行或运算;若两数相同(同为0,或同为1),则结果为0。

如果还是有点抽象的话,没得事,直接上代码:

  1. package 贪心;/* 
  2. 作者     :XiangLin 
  3. 创建时间 :2020/9/15 23:05 
  4. 文件     :xxx.java 
  5. IDE      :IntelliJ IDEA 
  6. */ 
  7.  
  8. public class Test { 
  9.     public static void main(String[] args) { 
  10.         /** 
  11.          * 分别把结果以二进制的形式输出 
  12.          */ 
  13.         System.out.println("3的二进制:" + Integer.toBinaryString(3)); 
  14.         System.out.println("4的二进制:" + Integer.toBinaryString(4)); 
  15.         System.out.println("3 ^ 3 的二进制:" + Integer.toBinaryString(3 ^ 3)); 
  16.  
  17.         System.out.print("3 ^ 0 的二进制:" + Integer.toBinaryString(3 ^ 0)); 
  18.         if (3 == (3 ^ 0)) 
  19.             System.out.println(",也就是十进制的3"); 
  20.  
  21.         System.out.print("4 ^ 3 ^ 3 的二进制:" + Integer.toBinaryString(4 ^ 3 ^ 3)); 
  22.         if (4 == (4 ^ 3 ^ 3)) 
  23.             System.out.println(",也就是十进制的4"); 
  24.     } 

Output:

 

好戏开场,通过异或操作实现两个数互换

  1. package 贪心;/* 
  2. 作者     :XiangLin 
  3. 创建时间 :2020/9/15 23:08 
  4. 文件     :xx.java 
  5. IDE      :IntelliJ IDEA 
  6. */ 
  7.  
  8. import java.util.Random; 
  9.  
  10. public class Exchange4 { 
  11.     public static void main(String[] args) { 
  12.         /** 
  13.          * 随机生成两个固定序列的0-100之间的整数, 
  14.          * 其中101表示生成的数范围区间在:[0-101) 
  15.          */ 
  16.         Random random = new Random(51); 
  17.         int a = random.nextInt(101); 
  18.         int b = random.nextInt(101); 
  19.         System.out.println("交换前:a = " + a + ", b = " + b); 
  20.  
  21.         a = a ^ b; // 此时, a == a ^ b 
  22.         b = a ^ b; // b == a ^ b ^ b == a, 此时b == a 
  23.         a = a ^ b; // a == a ^ b ^ a == b, 此时a == b 
  24.         System.out.println("交换后:a = " + a + ", b = " + b); 
  25.     } 

Output:

 

引用数据类型

想必大家已经学了四种方法,已经对两个数互换信心满满,那么接下来,我们来看一道面试题:

  1. package 贪心;/* 
  2. 作者     :XiangLin 
  3. 创建时间 :2020/9/15 23:10 
  4. 文件     :xx.java 
  5. IDE      :IntelliJ IDEA 
  6. */ 
  7.  
  8. public class Exchange5 { 
  9.     public static void main(String[] args) { 
  10.         Integer a = 10; 
  11.         Integer b = 20; 
  12.  
  13.         swop(a, b); 
  14.         // 打印结果:a = 20, b = 10 
  15.         System.out.println("a = " + a + ", b = " + b); 
  16.     } 
  17.  
  18.     private static void swop(Integer a, Integer b) { 
  19.         // 完成此处代码 
  20.     } 

如代码所示,完成指定位置的代码,使得程序最后的运行结果为:a = 20, b = 10

你可能觉得这还不简单,然后"刷刷刷"完成可能如以下的代码:

  1. private static void swop(Integer a, Integer b) { 
  2.         a = a ^ b; 
  3.         b = a ^ b; 
  4.         a = a ^ b; 
  5.     } 

然后再看输出结果就傻眼了:

 

纳尼,不变?这是为什么?想知道为什么的可能需要自行了解一下Java内存模型了,毕竟Java里面没有C语言的指针(小声bb)。当然,本博主以后可能也会出这方面的博客。

下面让我来揭晓正确答案吧!

  1.  private static void swop(Integer a, Integer b) throws NoSuchFieldException, IllegalAccessException { 
  2.         // 完成此处代码 
  3. //        a = a ^ b; 
  4. //        b = a ^ b; 
  5. //        a = a ^ b; 
  6.  
  7.         int x = a; 
  8.         int y = b; 
  9.  
  10.         // 运用反射来操作Integer 
  11.         Class c = Integer.class; 
  12.         Field field = c.getDeclaredField("value"); 
  13.         // 授权访问私有 
  14.         field.setAccessible(true); 
  15.         // 将 a、b的值分别设置为y、x的值 
  16.         field.setInt(a, y); 
  17.         field.setInt(b, x); 
  18.  
  19.  
  20.     } 

当当当当,控制台输出如下:

 

至于如果有朋友想了解反射的知识,可以关注我的博客哦!毕竟反射是我当年学习JavaSE知识觉得最神奇也最喜欢的三个知识之一。

至于第六种方法嘛:

  1. private static void swop(Integer a, Integer b) { 
  2.        System.out.println("a = " + b + ", b = " + a); 
  3.        // 终止Java虚拟机的运作 
  4.        System.exit(0); 
  5.    } 

哈哈,不要打我哦,我就皮这一下…

毕竟,题目只是说,使得运行结果为:a = 20, b = 10 即可(^_−)☆

所有巧合的是要么是上天注定要么是一个人偷偷的在努力。

结束!

作者:古阙月

原文链接:http://nxw.so/44cPJ

本文转载自微信公众号「五角钱的程序员」,可以通过以下二维码关注。转载本文请联系五角钱的程序员公众号。

 

 

责任编辑:武晓燕 来源: 五角钱的程序员
相关推荐

2021-04-22 09:56:32

MYSQL开发数据库

2020-08-20 08:39:54

CTO代码数据

2012-07-13 11:32:16

网络出口

2023-12-29 09:23:25

Python回调函数遍历字典

2021-08-09 23:53:50

排序中国

2010-05-31 09:51:51

云计算ROI

2022-12-20 07:44:09

梅西封王卡塔尔

2021-12-12 18:38:31

visio画图工具

2012-05-09 14:57:38

梦想InstagramOffer

2017-10-20 09:04:54

数据中心方法绿化

2009-04-07 10:52:00

职场工作方法

2022-09-04 12:43:03

算法裁员Meta

2010-11-23 11:53:37

MySQL查询表字段

2022-10-14 10:36:10

职业道路职业生涯

2022-07-05 15:15:11

Python日期命令

2024-01-10 08:20:50

Linux编辑器pico

2022-08-30 00:31:12

机器学习超参数调优算法

2020-10-28 11:40:08

MySQL索引数据库

2010-07-26 15:42:34

Perl模块

2023-12-08 13:40:24

HbaseMySQL数据库
点赞
收藏

51CTO技术栈公众号