1. 程式人生 > 實用技巧 >Java基礎(變數、資料型別、運算子、分支結構、迴圈結構、陣列、方法)

Java基礎(變數、資料型別、運算子、分支結構、迴圈結構、陣列、方法)

1Java基礎

1.1變數

1.1.1簡介

變數是一個代詞,指代在計算機的記憶體中的一塊空間,用來儲存程式在執行中所需要的資料。

1.1.2命名規則

  1. 只能包含字母、數字、_$,並且不能以數字開頭
  2. 不能使用關鍵字/保留字(是關鍵字的一種,但是佔著不用)51+2
  3. 嚴格區分大小寫(對大小寫敏感)
  4. 可以是中文、日文、韓文等命名,但不建議,有可能亂碼
  5. 建議:英文的見名知意、駝峰命名法,不要使用拼音。

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.2.1簡介

基本資料型別也叫原生資料型別Java保留了C語言中的8個基本資料型別,為了計算方便,速度快,但是不能參與面向物件開發。

包裝類S

1.2.2整數相關

  1. byte : 位元組型,1個位元組(8)-128 ~ 127用得一般
  2. short : 短整型,2個位元組(16)-32768 ~ 32767少到幾乎不用
  3. int : 整型,4個位元組(32)-2^31 ~ 2^31-1最常用

- Java中整數直接量預設為int型別,如: 12325010000

- 兩個int型別的變數操作,結果還是int型別,小數位無條件捨棄

  1. long : 長整型,8個位元組(64)
    -2^63 ~ 2^63-1用得一般

- long型別的直接量,要在整數後面加lL,如: 123L250L

- 如果要計算超出了long範圍的時候,可以使用BigInteger

1.2.3小數相關

  1. float : 浮點型,4個位元組(32)-2^31 ~ 2^31-1少到幾乎不用

- float型別的直接量,要在小數後面加fF,如: 3.14F

  1. double : 雙精度浮點型,8個位元組(64)-2^63 ~ 2^63-1最常用

- Java中小數直接量預設為double型別,如: 3.146.18

- 有可能會出現舍入誤差,精確運算時要慎用,(因為10進位制與2進位制之間轉換時有可能會損失精度)

- 要做小數的精確計算時,可以使用BigDecimal

1.2.4其他型別

  1. char : 字元型,2個位元組(無符號16)0 ~ 65535

- char型別的直接量,需要放在’’單引號中,單引號中有且僅有1個字元

- 使用Unicode編碼格式,實質上是整數,即char對應的碼,如: A->65a->97

- ”Java程式設計師在記憶體中佔多少個位元組?14

  1. boolean : 布林型,1個位元組(8)false/true

1.2.5附:面試題

  1. 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附:面試題

  1. 下面的程式碼編譯是否正確?
short s1 = 10;

short s2 = 20;

s1 = s1 + s2; //編譯錯誤,因為short型別的運算結果自動變成int型別

1.4運算子

1.4.1算術運算子 + - * / % ++ --

% : 取餘/取模,兩個數相除取餘數,如: 4/3=11+ 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;

- 三目運算子的執行過程:

  1. 先判斷boolean表示式1
  2. boolean表示式1true,執行:冒號左邊的表示式2,否則執行:冒號右邊的表示式3 //不建議使用,使用if

// 求兩個數中的最大值

int a = ?;

int b = ?;

int max = a > b? a: b;

System.out.println(max);

- 三目運算子可以巢狀,巢狀之後使程式碼結構不清晰,但是一般不用。

1.4.6字串連線符

+ 即可以用來做算數加法運算,也可以用來做字串的拼接運算。

  1. + 左右兩邊都是數字型別時,預設做加法運算;
  2. + 左右兩邊只要有字串型別時,預設做字串拼接執行;
  3. 字串拼接後,結果還是字串;

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,結果才是1
  2. |: 位或,兩邊都是0,結果才是0
  3. ~: 位反,~0=1~1=0
  4. ^: 位異或,一邊為1一邊為0時,結果才是1
  5. >>: 位有符號右移,將二進位制整體向右邊移動,前面補0,保留符號位(/)
  6. <<: 位有符號左移,將二進位制整體向左邊移動,後面補0,保留符號位(/)
  7. >>>: 位無符號右移,將二進位制整體向右邊移動,前面補0,不保留符號位,移完後都是正數

1.4.8附:面試題

  1. &和&&的區別?

& && 都可以用來做邏輯運算

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.4switch case

switch case 也是用來作為多路分支,優點是速度快,缺點是不夠靈活。場景:確定值的時候(不是一個範圍)

語法結構:

switch(表示式) {

case 1:

程式碼塊1;

break;

case 2:

程式碼塊2;

break;

case n:

程式碼塊n;

break;

default:

程式碼塊default;

}

- switch括號中的表示式結果只能是intString型別。

- 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.1while

語法結構:

while(條件) {

迴圈體程式碼塊

}

執行流程:

條件成立,就會迴圈執行迴圈體程式碼塊,直到條件不成立為止。

應用場景:

當咱們不知道要迴圈多少次時,也就是說迴圈次數不確定時。

1.6.2do while

語法結構:

do {

迴圈體程式碼塊

} while(條件);

執行流程:

1、先執行一次迴圈體程式碼塊

2、當條件成立,則繼續迴圈執行迴圈體程式碼塊,直到條件不成立為止。

應用場景:

當咱們要先執行一次迴圈體程式碼塊,再進行迴圈條件的判斷時。

在實際的開發中,do while迴圈用的較少。

1.6.3for

語法結構:

for (表示式1;表示式2;表示式3) {

迴圈體程式碼塊

}

說明:

  1. 表示式1- 迴圈變數的初始化
  2. 表示式2- 迴圈的條件
  3. 表示式3- 迴圈變數的改變(注:應該要向著迴圈結束去改變)

執行流程:

  1. 先執行表示式1,進行迴圈變數的初始化操作,注:只執行一次
  2. 再執行表示式2,進行迴圈條件的判斷

1)若條件成立,則執行迴圈體程式碼塊

2)若條件不成立,則結束迴圈

  1. 再執行表示式3,進行迴圈變數的改變
  2. 依次第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陣列的簡介

  1. 陣列是指一組資料的集合,陣列中的每個資料稱作為元素
  2. 陣列是一種線性表資料結構,它用一組連續的記憶體空間,來儲存一組具有相同型別的資料。
  3. 同一個陣列中存放的元素的型別必須要一致。
  4. 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];

上述程式碼相當於在記憶體中定義了10int型別的變數,第1個變量表示為arr[0],第2個變量表示為arr[1],以此類推,第10個變量表示為arr[9]。其中的01,…,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陣列的遍歷

遍歷是指對陣列中所有元素的訪問,依次對陣列中每個元素訪問一次。

  1. 順序遍歷

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);

}

  1. 倒序遍歷

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]

}

  1. 增強版for迴圈遍歷

int[] arr = {1, 4, 7};

// a表示每次迴圈從陣列中取出的那個元素,arr表示要遍歷的陣列

for(int a: arr){

System.out.println(a);

}

1.7.6陣列的排序

  1. 自帶排序

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]

  1. 氣泡排序(筆試)

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!

  1. &和&&的區別?