1 Java基礎
1.1 變數
1.1.1 簡介
變數是一個代詞,指代在計算機的記憶體中的一塊空間,用來存盤程式在運行中所需要的資料,
1.1.2 命名規則
- 只能包含字母、數字、_和$,并且不能以數字開頭;
- 不能使用關鍵字/保留字(是關鍵字的一種,但是占著不用);51+2
- 嚴格區分大小寫(對大小寫敏感);
- 可以是中文、日文、韓文等命名,但不建議,有可能亂碼;
- 建議:英文的見名知意、駝峰命名法,不要使用拼音,
1.1.3 宣告
變數的宣告指的是在記憶體中開辟一塊指定大小的記憶體空間,默認還沒有存資料,
語法結構:資料型別 變數名;
// 宣告了一個int型別變數num int num; // 宣告了三個int型別變數a、b、c int a, b, c;
1.1.4 初始化
變數的初始化指的是對變數的第一次賦值,
語法結構:資料型別 變數名 = 值;
1.宣告同時初始化 // 宣告變數num,同時賦值為250 int num = 250; 2.先宣告再初始化 // 宣告變數num int num; // 給num賦值為250 num = 250; 3.同時宣告多個變數(用得較少) // 同時宣告變數a、b、c int a, b, c; // 同時宣告變數a、b、c,并分別賦值為100、200、300 int a=100, b=200, c=300;
1.1.5 訪問(操作)
- 變數在使用之前必須要宣告并初始化;
- 變數的操作必須與型別匹配,
1.2 資料型別
1.2.1 簡介
基本資料型別也叫原生資料型別,Java保留了C語言中的8個基本資料型別,為了計算方便,速度快,但是不能參與面向物件開發,
包裝類S
1.2.2 整數相關
- byte : 位元組型,1個位元組(8位),-128 ~ 127,用得一般
- short : 短整型,2個位元組(16位),-32768 ~ 32767,少到幾乎不用
- int : 整型,4個位元組(32位),-2^31 ~ 2^31-1,最常用
- Java中整數直接量默認為int型別,如: 123、250、10000
- 兩個int型別的變數操作,結果還是int型別,小數位無條件舍棄
- long : 長整型,8個位元組(64位),-2^63 ~ 2^63-1,用得一般
- long型別的直接量,要在整數后面加l或L,如: 123L、250L
- 如果要計算超出了long范圍的時候,可以使用BigInteger類
1.2.3 小數相關
- float : 浮點型,4個位元組(32位),-2^31 ~ 2^31-1,少到幾乎不用
- float型別的直接量,要在小數后面加f或F,如: 3.14F
- double : 雙精度浮點型,8個位元組(64位),-2^63 ~ 2^63-1,最常用
- Java中小數直接量默認為double型別,如: 3.14、6.18
- 有可能會出現舍入誤差,精確運算時要慎用,(因為10進制與2進制之間轉換時有可能會損失精度)
- 要做小數的精確計算時,可以使用BigDecimal類
1.2.4 其他型別
- char : 字符型,2個位元組(無符號16位),0 ~ 65535
- char型別的直接量,需要放在’’單引號中,單引號中有且僅有1個字符
- 使用Unicode編碼格式,實質上是整數,即char對應的碼,如: A->65,a->97
- ”Java程式員”在記憶體中占多少個位元組?14
- boolean : 布爾型,1個位元組(8位),false/true
1.2.5 附:面試題
- Java中的原生資料型別有哪些?各自的范圍是多少?
1.3 基本資料型別的轉換
1.3.1 自動型別轉換,從小型別到大型別
byte --> short --> int --> long --> float --> double --> char
1.3.2 強制型別轉換,從大型別到小型別強轉,有可能發生精度丟失、溢位,向下造型
double d = 3.14; //float f = d; //編譯錯誤,大型別不能直接賦值給小型別 float f = (float) d; //將d中的資料強轉成float型別 int i = (int) d; //強制轉換,i=3,精度丟失 long l = 200; byte b = (byte) l; //強制轉換,溢位了
1.3.3 附:面試題
- 下面的代碼編譯是否正確?
short s1 = 10; short s2 = 20; s1 = s1 + s2; //編譯錯誤,因為short型別的運算結果自動變成int型別
1.4 運算子
1.4.1 算術運算子 + - * / % ++ --
% : 取余/取模,兩個數相除取余數,如: 4/3=商1余1+ 5/3求模
++ : 自增,變數自身加1
++a 先運算后賦值、 a++先賦值后運算
int a = 11; // 先賦值后加1:先把a變數的值10賦給a++運算式(a++=10),然后a變數自身再加1(a=11) int b = a++; Int b=++a; System.out.println(a); //11 System.out.println(b); //10 int x = 10; // 先加1后賦值:x變數先自身加1(x=11),然后再將x變數的值11賦給++x運算式(++x=11) int y = ++x; System.out.println(x); //11 System.out.println(y); //11 int c=5; int f=2;//3 int d=f++; System.out.println(f);//3
-- : 自減,變數自身減1
int a = 10; // 先賦值后減1:先把a變數的值賦給a--運算式(a--=10),然后a變數自身再減1(a=9) int b = a--;//先賦值再減減 System.out.println(a); //9 System.out.println(b); //10 int x = 10; // 先減1后賦值:x變數先自身減1(x=9),然后再將x變數的值9賦給--x運算式(--x=9) int y = --x;//先運算后賦值 System.out.println(x); //9 System.out.println(y); //9
1.4.2 關系運算子 > < >= <= == !=
System.out.println( 10 > 5 ); //true
System.out.println( 10 < 5 ); //false
System.out.println( 10 >= 10 ); //true
System.out.println( 10 <= 10 ); //true
System.out.println( 10 == 10 ); //true
System.out.println( 10 != 10 ); //false
- 關系運算子的結果為boolean型別
1.4.3 邏輯運算子 && || !
&& : 邏輯與/短路與,兩邊運算式都為true,結果才為true,若左邊的運算式為false時會發生短路(右邊的運算式不再執行了),
|| : 邏輯或/短路或,只要一邊運算式為true,結果就為true,若左邊的運算式為true時會發生短路(右邊的運算式不再執行了),
! : 非/取反,非真true則假false,非假false則真true
// 判斷是否為閏年:1.年份能被4整除并且不能被100整除,2.年份能直接被400整除 int year = 2020; 3200 boolean b = (year%4==0 && year%100!=0) || year%400==0; System.out.println(“是否為閏年?” + b);
- 邏輯運算子一般配合關系運算子來使用
- 邏輯運算子的結果為boolean型別
1.4.4 賦值運算子 = += -= *= /= %=
= : 普通賦值運算子
+= -= *= /= %= : 擴展賦值運算子
int a = 10;
a += 20; //相當于: a = a + 20;
- 擴展賦值運算子默認有型別轉換的特點
short s1 = 10;
short s2 = 20;
s1 = s1 + s2; //編譯錯誤,short型別運算后的結果是int型別,int不能直接賦給short
s1 += s2; //編譯通過,相當于: s1 = (short) (s1 + s2);
1.4.5 三目運算子
三目運算子也叫三元運算子,因為它是由3個運算式組成的,
語法結構:boolean運算式1 ? 運算式2 : 運算式3;
- 三目運算子的執行程序:
- 先判斷boolean運算式1
- 若boolean運算式1為true,執行:冒號左邊的運算式2,否則執行:冒號右邊的運算式3, //不建議使用,使用if
// 求兩個數中的最大值
int a = ?;
int b = ?;
int max = a > b ? a : b;
System.out.println(max);
- 三目運算子可以嵌套,嵌套之后使代碼結構不清晰,但是一般不用,
1.4.6 字串連接符
+ 即可以用來做算數加法運算,也可以用來做字串的拼接運算,
- 若 + 左右兩邊都是數字型別時,默認做加法運算;
- 若 + 左右兩邊只要有字串型別時,默認做字串拼接運行;
- 字串拼接后,結果還是字串;
int a = 250;
String s1 = “hello”;
String s2 = s1 + a; // “hello”+250 => “hello250”
String str = 5 + 7 + “abc” + 7 + 5;
System.out.println(str); //”12abc75”
1.4.7 位運算子(擴展)
位運算子是針對二進制運算的,常見的位運算子有以下這些:
- & : 位與,兩邊都是1,結果才是1
- | : 位或,兩邊都是0,結果才是0
- ~ : 位反,~0=1,~1=0
- ^ : 位異或,一邊為1一邊為0時,結果才是1
- >> : 位有符號右移,將二進制整體向右邊移動,前面補0,保留符號位(正/負)
- << : 位有符號左移,將二進制整體向左邊移動,后面補0,保留符號位(正/負)
- >>> : 位無符號右移,將二進制整體向右邊移動,前面補0,不保留符號位,移完后都是正數
1.4.8 附:面試題
- & 和 && 的區別?
& 和 && 都可以用來做邏輯運算
a)&是位與運算子,&&是邏輯與運算子
b)&不會發生短路,&&是會發生短路的
2. 使用最有效的方式計算 8/4 的結果?
8 >> 2
00001000 >> 2 = 00000010
1.5 分支結構
Java編程語言中有三種語法結構,分別是:順序結構、分支結構、回圈結構,
分支結構指的是根據條件的判斷去決定是否執行某段代碼,簡單的說就是可以選擇性的去執行某些代碼,
1.5.1 單路分支
單路分支是指如果條件成立了就去執行指定的代碼,否則就不執行,
語法結構:if(條件) { 條件成立時執行的代碼... }
int price = ?; if (price >= 500) { System.out.println(“打8折!”); } //超市、 特殊寫法: if(price >=500) System.out.println(“打8折!”); //不常用
1.5.2 雙路分支
雙路分支是指如果條件成立了就去執行指定的第一段代碼,否則就去執行指定的第二段代碼,場景:一個條件做兩件事情
語法結構:
if(條件) { //true/false
第一段代碼... true
}else{
第二段代碼... flase
}
// 判斷年份是否為閏年
int year = 2020;
if (year%4==0 && year%100!=0 || year%400==0) {
System.out.println(year + “是閏年!”);
} else {
System.out.println(year + “不是閏年!”);
}
1.5.3 多路分支(嵌套分支)
多路分支是指在多個條件的判斷下,去執行其中條件成立指定的代碼,場景:多個條件做多件事情,確定一個范圍
語法結構:
if (條件1) {
代碼塊1
} else if(條件2) {
代碼塊2
} else if(條件n) {
代碼塊n
} else {
代碼塊else
}
// 其實,上面的代碼是下面嵌套代碼的簡寫!
if (條件1) {
代碼塊1
} else {
if(條件2) {
代碼塊2
} else {
if(條件n) {
代碼塊n
} else {
代碼塊else
}
}
}
// 成績等級判斷
int score = ?;
if (score >= 90) {
System.out.println(“A-優秀”);
} else if (score >= 80) {
System.out.println(“B-良好”);
} else if (score >= 70) {
System.out.println(“C-中等”);
} else if (score >= 60) {
System.out.println(“D-及格”);
} else {
System.out.println(“E-不及格”);
}
1.5.4 switch case
switch case 也是用來作為多路分支,優點是速度快,缺點是不夠靈活,場景:確定值的時候(不是一個范圍)
語法結構:
switch(運算式) {
case 值1:
代碼塊1;
break;
case 值2:
代碼塊2;
break;
case 值n:
代碼塊n;
break;
default:
代碼塊default;
}
- switch括號中的運算式結果只能是int和String型別,
- case 后面的值一定要是直接量或常量,不能是變數,
- break 用來中斷switch陳述句,也就是不要再執行break后面的代碼;注意:如果沒有break的話,case將會出現穿透的效果(會一路執行到switch內部代碼的最后,或是一路執行到后面遇到的break為止),
// 模擬取款機程式
int cmd = ?;
switch (cmd) {
case 1:
System.out.println(“查詢余額”);
break;
case 2:
System.out.println(“轉賬”);
break;
case 3:
System.out.println(“取款”);
break;
default:
System.out.println(“輸入有誤”);
}
1.6 回圈結構
回圈指的是反復/重復去執行一段相同或相似的代碼,
1.6.1 while
語法結構:
while(條件) {
回圈體代碼塊
}
執行流程:
當條件成立,就會回圈執行回圈體代碼塊,直到條件不成立為止,
應用場景:
當咱們不知道要回圈多少次時,也就是說回圈次數不確定時,
1.6.2 do while
語法結構:
do {
回圈體代碼塊
} while(條件);
執行流程:
1、先執行一次回圈體代碼塊
2、當條件成立,則繼續回圈執行回圈體代碼塊,直到條件不成立為止,
應用場景:
當咱們要先執行一次回圈體代碼塊,再進行回圈條件的判斷時,
在實際的開發中,do while回圈用的較少,
1.6.3 for
語法結構:
for (運算式1; 運算式2; 運算式3) {
回圈體代碼塊
}
說明:
- 運算式1 - 回圈變數的初始化
- 運算式2 - 回圈的條件
- 運算式3 - 回圈變數的改變(注:應該要向著回圈結束去改變)
執行流程:
- 先執行運算式1,進行回圈變數的初始化操作,注:只執行一次
- 再執行運算式2,進行回圈條件的判斷
1) 若條件成立,則執行回圈體代碼塊
2) 若條件不成立,則結束回圈
- 再執行運算式3,進行回圈變數的改變
- 依次第2.和第3.步回圈執行
應用場景:
當回圈次數固定時,建議使用for回圈,
1.6.4 回圈的關鍵字
break 是中斷的意思,在回圈中使用時,可以使當前回圈結束,注:break只能結束一層回圈,
continue 是繼續的意思,用在回圈中,跳過本次回圈continue后面的代碼,從而進入下一次回圈,
int sum = 0;
for(int i = 0; i < 10; i++) {
if(i % 2 == 0){
continue;
}
sum += i;
}
int sum = 0;
for(int i = 0; i < 10; i++) {
if(i == 5){
break;
}
sum += i;
}
System.out.println(sum);
1.6.5 回圈的嵌套
回圈的嵌套指的是在回圈中可以嵌套另一個回圈,可以多層嵌套,但是開發中回圈的嵌套最好不要超過3層,
// 九九乘法表
for(int i = 1; i <= 9; i++) { //回圈9次,控制行數
for(int j = 1; j <= i; j++) { //控制列數,列數跟隨行數底層而增加的
System.out.print( i + “*” + j + “=” + (i * j) );
}
System.out.println();
}
說明:
外層回圈執行一次,它的內層回圈要執行完一輪,
1.7 陣列
1.7.1 陣列的簡介
- 陣列是指一組資料的集合,陣列中的每個資料稱作為元素,
- 陣列是一種線性表資料結構,它用一組連續的記憶體空間,來存盤一組具有相同型別的資料,
- 同一個陣列中存放的元素的型別必須要一致,
- 在Java中,陣列是一種參考資料型別,
1.7.2 陣列的宣告
宣告陣列是指告訴Java陣列的型別是什么,
// 1.中括號[]寫在型別的后面,Java中推薦這種寫法
int[] arr;
// 2.中括號[]寫在變數名的后面
int arr[];
int[][] arr;
int arr[][];
int[] arr[];
1.7.3 陣列的初始化
語法結構:
// 先宣告陣列
int[] arr;
// 對陣列默認初始化
arr = new int[10];
上述代碼相當于在記憶體中定義了10個int型別的變數,第1個變數表示為arr[0],第2個變數表示為arr[1],以此類推,第10個變數表示為arr[9],其中的0,1,…,9稱為陣列的下標/索引,下標從0開始,到“陣列的長度-1”結束,
當然,除了上面初始化陣列的方式外,還可以像下面這樣:
// 宣告和初始化寫在一起,陣列中默認每個元素的初始化值為0
int[] arr = new int[10];
// 宣告和初始化一起,但是手動指定初始化的值
int[] arr = {1, 2, 3};
// 宣告和初始化一起,手動指定好初始化的值,注意:[]中括號中不能再指定長度
int[] arr = new int[]{1, 2, 3};
問題:int[] arr = {1,2,3} 與 int[] arr = new int[]{1,2,3} 的區別?
int[] arr = {1,2,3} 只能宣告和初始化寫在一起,不能分開寫,如:
int[] arr;
arr = {1,2,3}; //編譯錯誤的
int[] arr = new int[]{1,2,3} 可以宣告和初始化寫在一起,也可以分開,如:
int[] arr;
arr = new int[]{1,2,3}; //編譯成功
1.7.4 陣列的訪問
通過下標/索引來訪問元素,陣列提供了一個length屬性,來獲取陣列的長度(元素的個數),
int[] arr = {1, 4, 7, 8};
System.out.println(arr.length); //列印陣列的長度:4
arr[0] = 100; //給arr中的第1個數賦值為100,此時:[100, 4, 7, 8]
System.out.println(arr[3]); //輸出arr中的最后一個數:8
System.out.println(arr[arr.length-1]); //靈活的輸出arr中最后一個元素
arr[4] = 88; //錯誤的,下標越界/超范圍,ArrayIndexOutOfBoundsException
1.7.5 陣列的遍歷
遍歷是指對陣列中所有元素的訪問,依次對陣列中每個元素訪問一次,
- 順序遍歷
int[] arr = {1, 4, 7};
for(int i = 0; i < arr.length; i++){
int a = arr[i]; //arr[0], arr[1], arr[2]
System.out.println(a);
}
- 倒序遍歷
int[] arr = {1, 4, 7};
for(int i = arr.length - 1; i >= 0; i--){
System.out.println(arr[i]); //arr[2], arr[1], arr[0]
}
- 增強版for回圈遍歷
int[] arr = {1, 4, 7};
// a表示每次回圈從陣列中取出的那個元素,arr表示要遍歷的陣列
for(int a : arr){
System.out.println(a);
}
1.7.6 陣列的排序
- 自帶排序
int[] arr = {3, 6, 9, 2, 5, 8, 1, 4, 7};
// Arrays.sort(T[] arr) 默認按照升序(從小到大)來排序的
java.util.Arrays.sort(arr);
System.out.println(Arrays.toString(arr)); //列印排序后的陣列,[1, 2, 3, 4, 5, 6, 7, 8, 9]
- 冒泡排序(筆試)
int[] arr = {3, 6, 9, 2, 5, 8, 1, 4, 7};
for(int i=0; i<arr.length-1; i++){ //控制趟數
for(int j=0; j<arr.length-1-i; j++){ //控制每趟的次數
//如果當前元素比后一個元素大,則交換位置
if(arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
System.out.println(Arrays.toString(arr)); //列印排序后的陣列
1.7.7 陣列的工具類
Java中提供了java.util.Arrays工具類,可以對陣列進行排序、檢索、轉換、輸出等操作,
Arrays.sort(arr); //對陣列進行排序
int index = Arrays.binarySearch(arr, key); //對陣列進行二分查找,注:陣列中的元素一定是升序的
String str = Arrays.toString(arr); //將陣列轉換為字串
int[] newArr = Arrays.copyOf(arr, len); //擴容/縮容 陣列
1.8 方法
1.8.1 方法的簡介
方法也稱為函式/程序,封裝的一段特定的邏輯功能、有名字的代碼塊,
方法可以使程式結構清晰、便于代碼的重復使用,
1.8.2 方法的定義
語法結構:
修飾符 回傳值型別 方法名 ( [引數型別 引數名1, 引數型別 引數名2, ...] ) {
方法體
[return 回傳值;]
}
上述代碼的語法格式具體說明如下:
- 修飾符:用于限定方法的宣告,常見的有訪問控制修飾符、靜態修飾符、最終修飾符 等等,
- 回傳值型別:用于限定方法回傳值的資料型別,為了告訴呼叫者知道要用什么型別來接識訓傳結果,
- 引數型別:用于限定呼叫方法時傳入引數的資料型別,
- 引數名:是一個變數,用于接收呼叫方法時傳入的資料,
- return 關鍵字:用于結束方法以及回傳方法指定型別的值,
- 回傳值:被return陳述句回傳的資料,該值會回傳給呼叫者,
方法中的“[引數型別 引數名1, 引數型別 引數名2, ...]”稱為引數串列,表示方法在呼叫時需要接收的引數,如果方法不需要接收任何引數,則引數串列為空,即()括號內不寫任何內容,
如果方法中沒有回傳值,那么回傳值型別要宣告為void,方法中的return陳述句可以省略,
例如:
//無回傳值無引數的方法
public static void sayHi() {
System.out.println("Hi");
}
//有回傳值有引數的方法
public static int sum(int a, int b) {
int result = a + b;
return result;
}
//封裝冒泡排序演算法,方便重復呼叫
public static void bubbleSort(int[] arr) {
for(int i=0; i<arr.length-1; i++){ //控制趟數
for(int j=0; j<arr.length-1-i; j++){ //控制每趟的次數
//如果當前元素比后一個元素大,則交換位置
if(arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
- 什么時候方法要定義引數?
當方法中要使用到的資料,但是又不能在方法中寫死,那么這時就可以把這些資料先定義為方法的引數,讓呼叫者在呼叫方法時再具體傳遞過來,引數可以使得方法變得更加靈活,
- 什么時候方法要定義具體回傳值型別?
當方法中邏輯計算完成之后,要回傳計算的結果給呼叫者時,那么就得定義具體的回傳值型別,
1.8.3 方法的呼叫
- 無參無回傳值方法的呼叫
方法名();
System.out.println();
- 有參無回傳值方法的呼叫
方法名(引數值..);
System.out.println(250);
- 無參有回傳值方法的呼叫
資料型別 變數名 = 方法名();
double num = Math.random();
- 有參有回傳值方法的呼叫
資料型別 變數名 = 方法名(引數值..);
double sqrt = Math.sqrt(4);
good luck!
- & 和 && 的區別?
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/231286.html
標籤:Java
上一篇:多執行緒與高并發常見面試題(1)
