Java基礎(chǔ)快速入門教程之進(jìn)制、位運(yùn)算與數(shù)組操作
進(jìn)制介紹與Java書寫格式
計(jì)算機(jī)底層使用二進(jìn)制進(jìn)行運(yùn)算與存儲(chǔ),但在開發(fā)中我們也會(huì)接觸到八進(jìn)制、十進(jìn)制、十六進(jìn)制。
掌握這些進(jìn)制及它們?cè)贘ava中的書寫方式,有助于理解底層原理。
| 進(jìn)制 | 規(guī)則 | Java書寫格式 |
|---|---|---|
| 十進(jìn)制 | 逢十進(jìn)一,借一當(dāng)十,默認(rèn)數(shù)值類型 | 直接書寫,如 10 |
| 二進(jìn)制 | 逢二進(jìn)一,借一當(dāng)二,只有 0 和 1 | 0b 開頭,如 0b10,b 大小寫均可 |
| 八進(jìn)制 | 逢八進(jìn)一,借一當(dāng)八 | 0 開頭,如 010 |
| 十六進(jìn)制 | 逢十六進(jìn)一,借一當(dāng)十六,用 0-9 和 a-f 表示 | 0x 開頭,如 0x10,x 大小寫均可 |
注意事項(xiàng)
- 上述進(jìn)制標(biāo)識(shí)從 JDK7 開始支持。
- 控制臺(tái)打印時(shí),無論代碼中書寫何種進(jìn)制,最終展示的都是 十進(jìn)制 數(shù)值。
示例
// Demo1.java
package com.wb.demo;
public class Demo1 {
public static void main(String[] args) {
System.out.println(10);
System.out.println("二進(jìn)制數(shù)據(jù)0b10的十進(jìn)制表示為:" + 0b10); // 2
System.out.println("八進(jìn)制數(shù)據(jù)010的十進(jìn)制表示為:" + 010); // 8
System.out.println("十六進(jìn)制數(shù)據(jù)0x10的十進(jìn)制表示為:" + 0x10); // 16
}
}任意進(jìn)制轉(zhuǎn)十進(jìn)制
1 )公式
系數(shù) × 基數(shù)^權(quán)次冪 再求和
- 系數(shù):每一位上的數(shù)字
- 基數(shù):當(dāng)前進(jìn)制的基,如二進(jìn)制基數(shù)是2,十六進(jìn)制是16
- 權(quán):從數(shù)字最右邊開始,編號(hào)為0,依次向左遞增
- 再求和: 各項(xiàng)結(jié)果相加
示例:二進(jìn)制 0b100 轉(zhuǎn)十進(jìn)制
| 系數(shù) | 基數(shù) | 權(quán)次冪 | 計(jì)算結(jié)果 |
|---|---|---|---|
| 1 | 2 | 2 | 1×2²=4 |
| 0 | 2 | 1 | 0 |
| 0 | 2 | 0 | 0 |
求和:4 + 0 + 0 = 4
示例:十六進(jìn)制 0x100 轉(zhuǎn)十進(jìn)制
| 系數(shù) | 基數(shù) | 權(quán)次冪 | 計(jì)算結(jié)果 |
|---|---|---|---|
| 1 | 16 | 2 | 1×16²=256 |
| 0 | 16 | 1 | 0 |
| 0 | 16 | 0 | 0 |
求和:256。
該公式適用于 任意進(jìn)制轉(zhuǎn)十進(jìn)制。
十進(jìn)制轉(zhuǎn)任意進(jìn)制
公式:除基取余,商為0時(shí)停止,余數(shù)倒序排列。
示例:十進(jìn)制 11 轉(zhuǎn)二進(jìn)制
| 除基 | 商 | 余數(shù) |
|---|---|---|
| 11÷2 | 5 | 1 |
| 5÷2 | 2 | 1 |
| 2÷2 | 1 | 0 |
| 1÷2 | 0 | 1 |
余數(shù)倒序:1011,所以 11(10) = 1011(2)
示例:十進(jìn)制 60 轉(zhuǎn)十六進(jìn)制
| 除基 | 商 | 余數(shù) |
|---|---|---|
| 60÷16 | 3 | 12© |
| 3÷16 | 0 | 3 |
余數(shù)倒序:3C,所以 60(10) = 0x3C
快速進(jìn)制轉(zhuǎn)換法(8421碼)
1 ) 8421碼(BCD代碼)
將二進(jìn)制每一位對(duì)應(yīng)的固定值記下,直接累加即可快速得到十進(jìn)制值
| 二進(jìn)制位權(quán)重 | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
|---|---|---|---|---|---|---|---|---|
| 對(duì)應(yīng)二進(jìn)制位 | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
- 二進(jìn)制位為 1 時(shí),取該位權(quán)重并相加;為 0 則忽略
2 ) 二進(jìn)制轉(zhuǎn)十進(jìn)制示例
二進(jìn)制:0b 1 1 0 1權(quán)重:8 4 2 1取1的位:8 + 4 + 1 = 13
3 ) 二進(jìn)制轉(zhuǎn)八進(jìn)制
將二進(jìn)制從右向左每 3位 一組(因?yàn)榘诉M(jìn)制最大為7,3位二進(jìn)制最大為7),每組按8421碼求和,結(jié)果拼在一起。
二進(jìn)制: 0b 11 1100分組: 011 110 (補(bǔ)零對(duì)齊)8421: 0+2+1=3 4+2+0=6八進(jìn)制: 36
Java中沒有直接的八進(jìn)制轉(zhuǎn)換API,但此方法適合手算理解。
4 ) 二進(jìn)制轉(zhuǎn)十六進(jìn)制
每 4位 一組(十六進(jìn)制最大為15),每組求和,大于9的用字母表示。
二進(jìn)制: 0b 11 1100分組: 0011 11008421: 2+1=3 8+4=12 → C十六進(jìn)制: 3C
原碼、反碼、補(bǔ)碼
計(jì)算機(jī)中的數(shù)據(jù)以 二進(jìn)制補(bǔ)碼 形式運(yùn)算,而原碼用來直觀查看數(shù)值大小,反碼是轉(zhuǎn)換過程的中間狀態(tài)。
- 原碼:最高位為符號(hào)位(0正1負(fù)),其余位表示數(shù)值。
- 反碼:正數(shù)的反碼等于原碼;負(fù)數(shù)反碼為原碼除符號(hào)位外按位取反。
- 補(bǔ)碼:正數(shù)的補(bǔ)碼等于原碼;負(fù)數(shù)補(bǔ)碼為反碼末位加一。
示例:int 強(qiáng)轉(zhuǎn)為 byte 的解釋
Java中 int 占4字節(jié),byte 占1字節(jié)。將 130 強(qiáng)轉(zhuǎn)為 byte 會(huì)發(fā)生精度損失,結(jié)果為 -126。
過程如下:
130的int原碼(補(bǔ)碼相同,正數(shù)):00000000 00000000 00000000 10000010- 強(qiáng)轉(zhuǎn)為
byte截取低8位:10000010(此時(shí)已是補(bǔ)碼,且符號(hào)位為1,表示負(fù)數(shù)) - 補(bǔ)碼求原碼:
補(bǔ)碼減1得反碼:10000001
反碼取反(符號(hào)位不變)得原碼:11111110
原碼對(duì)應(yīng)的十進(jìn)制:-(2+4+8+16+32+64) = -126
位運(yùn)算 - 基本位運(yùn)算符
位運(yùn)算符直接對(duì)整數(shù)的二進(jìn)制位操作,運(yùn)算速度快。二進(jìn)制位中,1 表示 true,0 表示 false。
| 運(yùn)算符 | 名稱 | 運(yùn)算規(guī)則 |
|---|---|---|
& | 位與 | 全1才1(有0則0) |
| ` | 位或 | 有1則1 |
^ | 位異或 | 相同為0,不同為1 |
~ | 取反 | 所有位(含符號(hào)位)0變1,1變0 |
示例代碼
// Demo2.java
package com.wb.demo;
public class Demo2 {
public static void main(String[] args) {
System.out.println(6 & 2); // 2
System.out.println(~6); // -7
}
}運(yùn)算過程分析
6 & 2:
00000000 00000000 00000000 00000110 (6)` & 00000000 00000000 00000000 00000010 (2)` ----------------------------------------- 00000000 00000000 00000000 00000010 → 2
~ 6:
00000000 00000000 00000000 00000110 (6 的補(bǔ)碼) ~ 11111111 11111111 11111111 11111001 (取反后仍為補(bǔ)碼)
得到的是負(fù)數(shù)的補(bǔ)碼,反推原碼:
補(bǔ)碼減 1 : 11111111 11111111 11111111 11111000 (反碼) 反碼取反(符號(hào)位不變): 10000000 00000000 00000000 00000111 → -7
位運(yùn)算 - 位移運(yùn)算符
| 運(yùn)算符 | 名稱 | 運(yùn)算規(guī)律 |
|---|---|---|
| << | 有符號(hào)左移 | 左移 n 位相當(dāng)于乘 2^n,右側(cè)補(bǔ) 0 |
| >> | 有符號(hào)右移 | 右移 n 位相當(dāng)于除 2^n,左側(cè)補(bǔ)符號(hào)位 |
| >>> | 無符號(hào)右移 | 右移 n 位,左側(cè)一律補(bǔ) 0(很少使用) |
示例代碼
// Demo3.java
package com.wb.demo;
public class Demo3 {
public static void main(String[] args) {
System.out.println(12 << 1); // 24
System.out.println(12 << 2); // 48
}
}12 << 2 運(yùn)算過程:
12 二進(jìn)制(補(bǔ)零至8位示意): 00001100
左移2位: 00110000 → 十進(jìn)制 48
符號(hào)位丟棄,右側(cè)補(bǔ) 0
案例:數(shù)據(jù)交換
1 ) 方式一:使用臨時(shí)變量
最常用、最易讀的交換方式
// Test1.java
package com.wb.test;
public class Test1 {
public static void main(String[] args) {
int a = 10;
int b = 20;
int temp = a;
a = b;
b = temp;
System.out.println("a=" + a); // 20
System.out.println("b=" + b); // 10
}
}2 ) 方式二:利用異或運(yùn)算
利用異或特性:一個(gè)數(shù)異或另一個(gè)數(shù)兩次,結(jié)果不變
// Test1_1.java
package com.wb.test;
public class Test1_1 {
public static void main(String[] args) {
int a = 10;
int b = 20;
a = a ^ b;
b = a ^ b; // b = (a^b) ^ b = a
a = a ^ b; // a = (a^b) ^ a = b
System.out.println("a=" + a);
System.out.println("b=" + b);
}
}驗(yàn)證異或特性的例子
// Demo4.java
package com.wb.demo;
public class Demo4 {
public static void main(String[] args) {
System.out.println(10 ^ 5 ^ 10); // 結(jié)果還是 5
}
}實(shí)際開發(fā)建議使用臨時(shí)變量方式,異或方式多出現(xiàn)在面試題中
案例:數(shù)組反轉(zhuǎn)
需求:將數(shù)組 {19, 28, 37, 46, 50} 反轉(zhuǎn)為 {50, 46, 37, 28, 19}
核心思路
使用 雙指針 分別指向數(shù)組首尾,交換元素后指針向中間移動(dòng),直到指針相遇
1 ) 第一步:手動(dòng)交換首尾元素(理解基礎(chǔ))
// Test2_2.java
package com.wb.test;
public class Test2_2 {
public static void main(String[] args) {
int[] arr = {11, 22, 33, 44, 55};
// 交換 arr[0] 和 arr[4]
int temp = arr[0];
arr[0] = arr[4];
arr[4] = temp;
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}2 )第二步:使用循環(huán)完成整個(gè)反轉(zhuǎn)
// Test2.java
package com.wb.test;
public class Test2 {
public static void main(String[] args) {
int[] arr = {19, 28, 37, 46, 50};
// 雙指針
int start = 0;
int end = arr.length - 1;
// 當(dāng) start < end 時(shí)進(jìn)行交換
for ( ; start < end; start++, end--) {
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
// 遍歷輸出反轉(zhuǎn)后的數(shù)組
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}3 ) 循環(huán)的另一種緊湊寫法(在 for 初始化中定義雙指針):
for(int start = 0, end = arr.length - 1; start < end; start++, end--) {
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}總結(jié)
本文介紹了Java中常見的進(jìn)制表示與轉(zhuǎn)換、原反補(bǔ)碼的運(yùn)作原理以及位運(yùn)算、位移運(yùn)算,并結(jié)合經(jīng)典案例“數(shù)據(jù)交換”和“數(shù)組反轉(zhuǎn)”加深理解。
這些基礎(chǔ)知識(shí)是理解Java底層運(yùn)算和閱讀源碼的重要鋪墊。
到此這篇關(guān)于Java基礎(chǔ)快速入門教程之進(jìn)制、位運(yùn)算與數(shù)組操作的文章就介紹到這了,更多相關(guān)java進(jìn)制、位運(yùn)算與數(shù)組內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java調(diào)用未知類的指定方法簡(jiǎn)單實(shí)例
這篇文章介紹了java調(diào)用未知類的指定方法簡(jiǎn)單實(shí)例,有需要的朋友可以參考一下2013-09-09
SSH框架網(wǎng)上商城項(xiàng)目第14戰(zhàn)之商城首頁(yè)UI的設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了SSH框架網(wǎng)上商城項(xiàng)目第14戰(zhàn)之商城首頁(yè)UI的設(shè)計(jì),感興趣的小伙伴們可以參考一下2016-06-06
Spring事務(wù)隔離級(jí)別簡(jiǎn)介及實(shí)例解析
JDK9的新特性之String壓縮和字符編碼的實(shí)現(xiàn)方法
Spring?@Conditional通過條件控制bean注冊(cè)過程
SpringBoot項(xiàng)目報(bào)錯(cuò):"Error?starting?ApplicationContext....
SpringBoot業(yè)務(wù)邏輯異常的處理方法介紹

