文章目錄
-
- 第一章 計算機基礎
-
- jiva技術架構
- java最大的特點——跨平台
- JDK的下載下傳與安裝
- 配置path環境變量
- VSCode修改方式
- 運作java程式
- 第二章 基本資料與運算
-
- 關鍵字
- 辨別符
- 注釋
- 常量與進制
- 原反補的轉換
-
- 原碼
- 反碼
- 補碼
- 移碼
- 例題
- 變量
- 回顧一下指針
- 資料類型
- 運算符
-
- 算數運算符
- 指派運算符
- 比較運算符
- 邏輯運算符
- 位運算符
- 三目運算符
- 補充:變量交換問題
- 第三章 流程控制語句
-
- if條件語句
- switch分支語句
- for循環語句
- while循環語句
- break、continue跳轉語句
- 第四章 常用類
-
- Math類
-
- 自帶常量
- 取整方法
- 三角函數
- ‘指數函數
- 其他方法
- 用法
- Scanner類
-
- 方法
- 用法
- String類
-
- 擷取相關
- 判斷相關
- 修改相關
- Character類
- 第五章 函數
-
- 函數的概念
- 函數的運作原理
- 函數重載
- 函數的遞歸
-
- 定義
- 案例
- 第六章 數組
-
- 數組的概念及定義
-
- 數組概念
- 數組定義
-
- 一維數組的定義
-
- 定義
- 方法
- 二維數組的定義
-
- 定義
- 方法
- 常用數組操作
-
- 數組周遊問題
- 數組最值問題
- 數組擴容問題
- 數組排序問題
-
- 選擇排序算法
- 冒泡排序算法
- 插入排序算法
- 計數排序算法
- 基數排序算法
- 二分查找算法
- 可變長參數清單
第一章 計算機基礎
jiva技術架構
- JavaSE Java Standard Edition Java标準版:桌面型應用程式
- JavaEE Java Enterprise Edition Java企業版:伺服器應用程式
- JavaME Java Micro Edition Java微型版:嵌入式應用程式
java最大的特點——跨平台
跨平台的意思就是說,一個軟體可以在多個平台上運作,而不用更改軟體的内容。
是因為JVM的功勞:JVM(Java Virtual Machine)Java虛拟機。
Java源代碼檔案字尾名為xxx.java 所編譯出來的二進制檔案字尾名為xxx.class
JVM主要負責将java語言的位元組碼檔案轉換為本地作業系統指令的一個工具軟體。 是以,最終是位元組碼檔案在跨平台!
JDK的下載下傳與安裝
- 先登入注冊Oracle
- 去Oralce官網下載下傳JDK,最新JDK15,我們目前用JDK8 https://www.oracle.com
- 點選Products
- 點選SoftWare下的Java
- 右上角DownloadJava
- 找到JavaSE8 點選JDK Download
- 下拉 在下載下傳清單中選擇Windows X64
- 輕按兩下打開jdk安裝程式
- 點選下一步
- JDK不需要更改目錄 直接下一步
- JRE不需要更改目錄 直接下一步
- 安裝完成 點選關閉即可
- 驗證jdk是否安裝成功
- win+r 打開cmd 輸入 java -version
java version "1.8.0_77" `
`Java(TM) SE Runtime Environment (build 1.8.0_77-b03) `
`Java HotSpot(TM) 64-Bit Server VM (build 25.77-b03, mixed mode)
配置path環境變量
- 複制jdk中bin目錄的絕對位址 C:\Program Files\Java\jdk1.8.0_77\bin
- 右鍵此電腦 點選屬性
- 點選進階系統設定
- 點選環境變量
- 系統變量中選擇Path
- 右上角 建立 将位址複制進去即可
- 一路确定出去
- 重新開機cmd 再去嘗試javavc java
VSCode修改方式
VSCode代碼編輯器 https://code.visualstudio.com/
漢化:左下角管理 Extension 搜尋Chinese 選擇Chinese中文簡體漢化包 點選綠色install 右下角提示 重新開機 重新開機即可
主題:管理 顔色主題 自選
編碼:管理 設定 文本編輯器 檔案 Encoding 選擇gbk結尾
字型:管理 設定 文本編輯器 字型 font size
關聯代碼所在的檔案夾:檔案 打開檔案夾 選擇JavaDay01
運作java程式
步驟一:建立Java源代碼檔案并寫入類
點選建立檔案按鈕,輸入Java源代碼檔案名稱和字尾名,例如 JavaDay01.java 在檔案中寫入如下代碼:
public class JavaDay01 {
}
注 : public class Sample01 中的 Sample01 是類名,而且在Java源代碼中,可以存在多個類,但是 最多隻能有一個public開頭的類,并且該類的類名必須與檔案名保持一緻!!! |
---|
步驟二:編譯該代碼檔案 |
打開控制視窗cmd,将目錄切換到javaDay01目錄下
C:\Users\HX>cd Desktop\\xuexi\\javademo
再輸入 javac Sample01.java 對源代碼檔案進行編譯
C:\Users\HX\Desktop\xuexi\javademo<javac JavaDay01.java
如果沒有任何輸出,則表明編譯成功,并生成同名的位元組碼檔案 Sample01.class
步驟三:運作該位元組碼檔案
輸入 java javaday01即可
C:\Users\HX\Desktop\xuexi\javademo<java JavaDay01
第二章 基本資料與運算
關鍵字
關鍵字是指被進階程式設計語言賦予特殊含義的一些單詞,關鍵字一般都是由小寫字母組成。好比是漢 語當中的一些專有名詞:北京,天安門,兵馬俑。不能亂用。
- 用于定義資料類型的關鍵字:byte short int long float double char boolean void class interface
- 用于定義資料類型值的關鍵字:true false null
- 用于定義流程控制語句的關鍵字:if else switch case default while do for break(退出目前循環) continue(結束目前循環) return
- 用于定義通路權限修飾符的關鍵字:public protected private
- 用于定義繼承關系的關鍵字:extends(繼承) implements(實作接口)
- 用于定義執行個體對象的關鍵字:new this super instanceof
- 用于定義函數類型的關鍵字:static final abstract synchronized(同步線程)
- 用于處理異常的關鍵字:try catch finally throw throws
- 用于包的關鍵字:package import
- 其他的一些修飾關鍵字:native assert volatile transient
辨別符
辨別符指的是我們在程式中對變量、函數、類、接口、常量所定義的名稱,也就是說這些名稱是我 們自定義的。
辨別符必須滿足以下組成規則:
- 辨別符可以由數字、字母、下劃線 _ 、美元符 $ 組成
- 辨別符不能以數字開頭,當然下劃線和美元符其實是可以開頭的,但不推薦
- 辨別符不能是關鍵字
- 辨別符也不能是Java内置類的名稱
- 辨別符可以為任意長度,但必須是一個連續的詞
- 辨別符嚴格區分大小寫
注釋
注釋是用于注解和說明程式的一些程式中的内置文本資訊的,但這些内置文本不屬于代碼的範疇。 是以在對含有注釋的源代碼進行編譯時,所生成的位元組碼中不含有注釋。注釋是給人看的!
注釋主要有三種:
- 單行注釋 //注釋内容 直到換行為止
- 多行注釋
- 文檔注釋 :文檔注釋可以被編譯器識别,并生成相應 的程式說明書。對某一個類進行文檔生成時,該類必須是public型
常量與進制
常量就是指在程式中直接出現的一些資料,也叫字面量
常量都有哪些:
- 整數常量
- 小數常量
- 字元常量:由一個字母、數字、符号被單引号( ‘’ )辨別的資料
- 字元串常量:由若幹個字母、數字、符号被雙引号( “” )辨別的資料
- 布爾類型常量
- null常量
public class Sample {
public static void main(String[] args) {
//整數常量
System.out.println(10); //十進制整數
System.out.println(0b1001); //二進制整數 列印出來是十進制
System.out.println(0123); //八進制整數
System.out.println(0xAF3); //十六進制整數
//小數常量
System.out.println(3.14);
System.out.println(5.234e3);
System.out.println(1.2e-3);
//字元常量
System.out.println('a');
//System.out.println('ab'); ERROR
System.out.println('9');
//System.out.println('12'); ERROR
System.out.println('我');
System.out.println(' ');
//System.out.println(''); ERROR
//System.out.println('''); ERROR
System.out.println('\''); //列印 '
System.out.println('\n'); //列印 換行
System.out.println('\t'); //列印 縮進
//字元串常量
System.out.println("abcd");
System.out.println("a");
System.out.println(""); //字元串空串 vs null真空
System.out.println("\"");
//布爾常量
System.out.println(true);
System.out.println(false);
}
}
原反補的轉換
原碼
轉換 當x 大于0時 x=x
當x大于0且小于1時 x=x
例如 0.1111=0.1111
當x為整數時 x=x
例如 01111=01111
當x 小于0時 x= 1-x=1+|x|
當x為小數時 x=(2-2^(-n))+x
例如 1.1111=1.0000
當x為整數時 x=2n-x=2n+|x|
例如 11111=11111
反碼
轉換 當x 大于0時 x=x
當x大于0且小于1時 x=x
例如 0.1111=0.1111
當x為整數時 x=x
例如 01111=01111
當x 小于0時
當x為小數時 x=(2-2^(-n))+x
例如 1.1111 = 1.0000
當x為整數時 x=(2^(n+1)-1)+x
例如 11111= 10000
補碼
轉換 當x 大于0時 x=x
當x大于0且小于1時 x=x
例如 0.1111=0.1111
當x為整數時 x=x
例如 01111=01111
當x 小于0時
當x為小數時 x=2+x=2-|x|
例如 1.0001=1.1111
當x大于1時 x=2(n+1)+x=2(n+1)-|x|
例如 11110=10010
移碼
補碼符号位相反即可
例題
真值 | 原碼 | 反碼 | 補碼 |
---|---|---|---|
+70 | 01000110 | 010000110 | 01000110 |
-70 | 11000110 | 10111001 | 10111010 |
-0.875 | 1.1110 | 1.0001 | 1.0010 |
0.875 | 0.1110 | 0.1110 | 0.1110 |
+0 | 0.0000 | 0.0000 | 0.0000 |
-0 | 1.0000 | 1.1111 | 0.0000 |
-1.0000 | 無法表示 | 1.1111 | 1.0000 |
變量
指的是變化的量
- 變量的本質就是在記憶體中程式所處的程序中的一個臨時存儲區域
- 該區域的存儲值有限制的
- 該區域值的變化必須是同類型的或向下相容的
- 該區域有其自身的實體記憶體位址-指針
- 該區域中 存儲值的限制 和 資料的變化類型 由 資料類型 來決定
- 該區域中 其空間的配置設定 和 空間的實體記憶體位址 由計算機底層來決定
回顧一下指針
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-0ilHrWwq-1631327940075)(/QWGC70%5DWXPY%5BG@@XRPT2XOO.png)]
#include<stdio.h>
void main() {
int a = 3; //建立一個普通的整型變量 存3這個常量
int* b; //建立一個一重指針變量 存的是a變量的位址
b = &a;
int** c; //建立一個二重指針變量 存的是b變量的位址
c = &b;
printf("a的位址:%d\n",&a); //列印a的位址 0x123
printf("a的内容:%d\n",a); //列印a空間的内容 3
printf("b的位址:%d\n",&b); //0x456
printf("b的内容:%d\n",b); //0x123
printf("拿着b的内容去找變量a:%d\n",*b); //3
printf("c的位址:%d\n",&c); //0x789
printf("拿着c的内容去找變量b:%d\n",*c); //0x123
printf("拿着c的内容去找變量b,拿着b的内容去找變量a:%d\n",**c); //3
//printf("%d\n",*a);
printf("%d\n",*&*c); //0x123
printf("%d\n",&*&**&c); //0x456
}
結果如下
a的位址:6422300
a的内容:3
b的位址:6422296
b的内容:6422300
拿着b的内容去找變量a:3
c的位址:6422292
拿着c的内容去找變量b:6422300
拿着c的内容去找變量b,拿着b的内容去找變量a:3
6422300
6422296
資料類型
在Java當中,資料類型主要分為兩大類:
- 基本資料類型:在變量的空間中存儲資料
- 整形
- byte 1位元組 2^8 256 -128~127 -2^7 ~ 2^7 - 1
- short 2位元組 2^16 65536 -32768~32767 -2^15 ~ 2^15 - 1
- int 4位元組
- long 8位元組
- 浮點型
- float 4位元組
- double 8位元組
- 字元類型
- char 2位元組
- 布爾型
- boolean 不确定
注:在常量中,整型常量預設int類型,小數常量預設是double類型
布爾類型,如果是單一變量的話,在JVM中true被認為是1 false被認為是0 是以是4位元組存
如果是布爾類型數組的話,在JVM中true和false被認為是byte類型 1位元組
- 引用資料類型:資料是在堆記憶體中存儲,變量僅僅存放的是資料在堆記憶體中的位址
- 字元串
- 數組
- 對象
在Java中,但凡存儲在堆記憶體中的資料,統稱為對象
運算符
算數運算符
算數運算 符 | 含義 | 備注 |
---|---|---|
+ | 加法 | 1+2=3 如果加号左右有字元串 則加号為連接配接符 |
- | 減法 | 3-2=1 |
* | 乘法 | 3*2=6 |
/ | 除法 | 3/2=1 3.0/2=1.5 如果除号兩邊都是整數 結果為整數;有小數 結果為小 數 |
% | 取餘 | 9%5=4 注意一點,如果前或後為負數(取餘看被除數 取商看除數) |
a++ | 後置自增 | a自身加一,使用原來的值 |
++a | 前置自 增 | a自身加一,使用加之後的值 |
a– | 後置自 減 | a自身減一,使用原來的值 |
–a | 前置自 減 | a自身減一,使用加之後的值 |
指派運算符
+= 加法指派 a+=3 相當于 a=a+3
注意 指派運算符隻能用在變量身上
比較運算符
運算的結果為布爾類型
- / >大于
- / < 小于
- / >= 大于等于
- / <= 小于等于
- / != 不等于
邏輯運算符
- & 單與
- | 單或
- ^ 異或
- ! 非、
- && 雙與
- || 雙或
public class Sample {
public static void main(String[] args) {
int x = 0;
int y = 0;
System.out.println(x++ > 0 & y++ > 0);
System.out.println(x);
System.out.println(y);
x = 0;
y = 0;
System.out.println(x++ > 0 && y++ > 0);
System.out.println(x);
System.out.println(y);
//&& 如果左邊為假 則右邊不用執行
//|| 如果左邊為真 則右邊不用執行
//相同為假 不同為真
System.out.println(true ^ true);
System.out.println(true ^ false);
System.out.println(false ^ false);
System.out.println(false ^ true);
}
}
位運算符
- & 位與
- | 位或
- ^ 位異或
- />> 右移
- << 左移
public class Sample {
public static void main(String[] args) {
int x = 7;
int y = 12;
System.out.println(x & y);
/*
0111
1100 &
0100 4
*/
System.out.println(x | y);
/*
0111
1100 |
1111 15
*/
System.out.println(x ^ y);
/*
0111
1100 ^
1011 11
*/
System.out.println(x << 3);
/*
0111
0111000
x * 2^3
*/
System.out.println(56 >> 2);
/*
111000
1110
56 / 2^2
*/
}
}
注意 當 用 i<<1+1;時 系統會認為 i<<2;
public class weiyi{
public static void main(String []args){
int i=1;
i<<=1+1;
System.out.println(i);//4
i+=1;
System.out.println(i);//5
i=1;
i<<=1;
i+=1;
System.out.println(i);//3
}
}
三目運算符
資料類型 變量名 = 布爾表達式?值1:值2;
int number = 10 % 2 == 0? 10 : 2;
補充:變量交換問題
方法一:int a = 3; int b = 7;
方法二int c = a; a = b; b = c; System.out.println(a); System.out.println(b);
方法三a = a + b; b = a - b; a = a - b; System.out.println(a); System.out.println(b);
a = a ^ b; b = a ^ b; a = a ^ b; System.out.println(a); System.out.println(b);
第三章 流程控制語句
if條件語句
單分支if語句
if(布爾類型表達式){
語句組;
}
雙分支if-slse語句
if(布爾類型表達式){
語句組;
}else
多分支 if -else 語句
if (布爾表達式1) {
語句組A;
} else if (布爾表達式2) {
語句組B;
} else if (布爾表達式3) {
語句組C;
} else {
語句組D;
}
switch分支語句
與if分支語句一樣,都是對條件的判斷 。switch一般用在條件較多的情況下,但是有一個重要的細節,if語言可以對區間值或固定值進行判斷,switch隻能對固定值進行判斷
switch(變量){
case 值1:
語句組A:
break;
case 值2:
語句組B;
break;
.......
case 值n: //if (變量==值n) {語句組N;}
語句組N;
default: // else {語句組N+1;}
語句組N+1;
break;
}
switch中的一些使用細節
- switch所傳入的變量,char,byte,short,int,String或者枚舉類型
- 值1,值2,一直到值n,這幾個值必須是同一個資料類型的
- 當變量比對的相關case的值的時候,執行case中的語句,直到遇到break結束,如果該case語句 中沒有break,則繼續向下執行,直到遇到另外一個break結束。
for循環語句
循環主要解決具有規律性的且具有重複性的代碼問題,避免程式備援
循環四要素
- 循環的初始化:循環的第1次執行從哪裡開始
- 循環的繼續條件:循環從目前輪是否向後執行下一輪
- 循環體:需要被循環執行的部分
- 循環的步長、周期:目前循環到下一輪循環之間的變化 我們常見的循環問題可以分為兩大類:
- 已知循環次數的 一般用for語句做
- 未知循環次數但是已知循環結束條件 一般用while語句做
for (1循環的初始化;2.循環的繼續條件;4.循環的步長) {
3.循環體
}
1-2-3-4-2-3-4-2-3-4-2不滿足則結束循環
for循環示範
import java.util.Scanner;
public class Sample {
public static void main(String[] args) {
/*
*****
*/
for (int i = 1; i <= 5; i++) {
System.out.print("*");
}
System.out.println();
System.out.println("=============================");
/*
*****
*****
*****
*****
*/
for (int j = 1; j <= 4; j++) {
for (int i = 1; i <= 5; i++) {
System.out.print("*");
}
System.out.println();
}
System.out.println("=============================");
/*
*
**
***
****
*****
******
*******
*/
for (int line = 1; line <= 7; line++) {
for (int i = 1; i <= line; i++) {
System.out.print("*");
}
System.out.println();
}
System.out.println("=============================");
/*
******
*****
****
***
**
*
*/
for (int line = 6; line >= 1; line--) {
for (int i = 1; i <= line; i++) {
System.out.print("*");
}
System.out.println();
}
System.out.println("=============================");
/* i j
* 1 1
** 2 1 2
*** 3 1 2 3
**** 4 1 2 3 4
***** 5 1 2 3 4 5
****** 6 1 2 3 4 5 6 j <= i
***** 7 1 2 3 4 5
**** 8 1 2 3 4
*** 9 1 2 3
** 10 1 2
* 11 1 j <= 12 - i
j <= i && j <= 12 - i
*/
for (int i = 1; i <= 11; i++) {
for (int j = 1; j <= i && j <= 12 - i; j++) {
System.out.print("*");
}
System.out.println();
}
System.out.println("=============================");
/* i |i - 6|
* 1 -5
** 2 -4
*** 3 -3
**** 4 -2
***** 5 -1
****** 6 0
***** 7 1
**** 8 2
*** 9 3
** 10 4
* 11 5
*/
for (int i = 1; i <= 11; i++) {
for (int k = 1; k <= Math.abs(i - 6); k++) {
System.out.print(" ");
}
for (int j = 1; j <= i && j <= 12 - i; j++) {
System.out.print("* ");
}
System.out.println();
}
System.out.println("=============================");
/* j
* 1
* * 1 2
* * 1 2 3
* * 1 2 3 4
* * 1 2 3 4 5
* * 1 2 3 4 5 6
* * 1 2 3 4 5
* * 1 2 3 4
* * 1 2 3
* * 1 2
* 1
j == 1 j == i j + i == 12
*/
for (int i = 1; i <= 11; i++) {
for (int k = 1; k <= Math.abs(i - 6); k++) {
System.out.print(" ");
}
for (int j = 1; j <= i && j <= 12 - i; j++) {
if (j == 1 || j == i || j + i == 12) {
System.out.print("* ");
} else {
System.out.print(" ");
}
}
System.out.println();
}
}
}
while循環語句
while循環主要用于解決循環次數未知,但循環結束條件已知的情況。
while其實和for循環是可以互相轉換的,是因為都逃不開循環四要素
for (int i = 1; i <= 5; i++) {
System.out.println(i);
}
可以轉換為while循環
int i = 1;
while (i <= 5) {
System.out.println(i);
i++;
}
while的文法格式
1.循環的初始化
while (2.循環繼續條件) {
3.循環體
4.循環的步長、周期
}
break、continue跳轉語句
break在循環語句中叫做終止語句,終止的是break最近的一層循環
continue在循環語句中叫做跳過語句,跳過本次循環開啟下一輪循環
public class Sample {
public static void main(String[] args) {
for(int j=0;j<2;j++){
for (int i = 1; i <= 5; i++) {
if (i == 3) {
break;
} else {
System.out.println(i);
}
}
}
//結果 1 2 1 2
for (int i = 1; i <= 5; i++) {
if (i == 3) {
continue;
} else {
System.out.println(i);
}
}
//結果 1 2 4 5
}
}
第四章 常用類
Math類
Math類是用于數學計算的一個工具類
對于工具類而言,裡面的大部分成員都是靜态的static
自帶常量
- static double E;自然對數
- static double PI;圓周率
取整方法
- static double cell(double a);向上取整
- static double floor(double a);向下取整
- static long round(double a);四舍五入
三角函數
- static double sin(double a):正弦函數 參數是弧度值
- static double cos(double a):餘弦函數
- static double tan(double a):正切函數
- static double toDegrees(double a):将弧度轉角度
- static double toRadians(double angles):将角度轉弧度
- static double asin(double a):反正弦函數
- static double acos(double a):反餘弦函數
- static double atan(double a):反正切函數
‘指數函數
- static double pow(double a, double b):求a的b次幂
- static double sqrt(double a):求a的平方根
- static double cbrt(double a):求a的立方根
其他方法
- static double abs(double a):求a的絕對值
- static double hypot(double deltX, double deltY):傳回 兩點間距離
- static double max(a,b):傳回a和b之間的最大值
- static double min(a,b):傳回a和b之間的最小值
- static double random():傳回[0,1)之間的随機小數
用法
public class Sample {
public static void main(String[] args) {
System.out.println(Math.E);//2.718281828459045
System.out.println(Math.PI);//3.141592653589793
System.out.println(Math.ceil(3.1));//4.0
System.out.println(Math.ceil(3.9));//4.0
System.out.println(Math.ceil(-3.1));//-3.0
System.out.println(Math.ceil(-3.9));//-3.0
System.out.println(Math.floor(3.1));//3.0
System.out.println(Math.floor(3.9));//3.0
System.out.println(Math.floor(-3.1));//-4.0
System.out.println(Math.floor(-3.9));//-4.0
System.out.println(Math.round(3.1));//3
System.out.println(Math.round(3.9));//4
System.out.println(Math.round(-3.1));//-3
System.out.println(Math.round(-3.9));//-4
System.out.println(Math.sin(Math.PI/6));//0.4999999999999999
System.out.println(Math.cos(Math.PI/3));//0.5000000000000001
System.out.println(Math.tan(Math.PI/4));//0.9999999999999999
System.out.println(Math.toDegrees(Math.PI/2));//90.0
System.out.println(Math.toRadians(90));//1.5707963267948966
System.out.println(Math.cbrt(8));//2.0
System.out.println(Math.hypot(0 - 1, 0 - 1));//1.4142135623730951
}
}
Scanner類
主要用于負責資料輸入的類,底層是和IO流相關。
需要先導包
導包方法: import java.util.Scanner;
輸入資料前提方法Scanner xxxx = new Scanner(System.in);
擷取方法: 類型 line = input.方法();
方法
- String next():擷取直到遇到空格為止的一個字元串
- String nextLine():擷取直到遇到回車為止的一個字元串
- int nextInt():擷取下一個整數
- byte short long double nextDouble();擷取下一個double類型數
- boolean nextBoolean();擷取下一個booleat類型數
- float nextFloat();擷取下一個float類型數
用法
import java.util.Scanner;
public class Sample {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("輸入一句話:");
String line = input.nextLine();
System.out.println(line);
System.out.print("輸入三個單詞:");
String word1 = input.next();
String word2 = input.next();
String word3 = input.next();
System.out.println(word1);
System.out.println(word2);
System.out.println(word3);
}
}
String類
String是一個類,它描述的是字元串。在Java代碼當中,所有字元串常量(字元串字面量)都是 String類的一個執行個體對象。并且,字元串一旦建立,則不可修改! 不可修改其長度,不可修改其内容 。所 以将來對字元串内容的改變,不能在原地改,隻能重新建立一個字元串。
public class Sample {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "ab" + "dc";
//上述代碼一共有幾個字元串?
//四個"abc" "ab" "dc" "abdc"
}
}
擷取相關
- char charAt(int index):擷取指定角标index處的字元
- int indexOf(int ch):擷取指定字元(編碼)在字元串中第一次(從左到右)出現的地方傳回的是 角标。如果是-1 表示不存在
- int lastIndexOf(int ch):擷取指定字元(編碼)在字元串中第一次(從右到做)出現的地方傳回的 是角标 int indexOf(String str):擷取指定字元串在本字元串中第一次(從左到右)出現的地方傳回的是 角标
- int lastIndexOf(String str):擷取指定字元串在本字元串中第一次(從右到左)出現的地方傳回 的是角标
- int length():擷取字元串的長度(字元的個數)
- String[] split(String regex):将字元串按照regex的定義進行切割(regex指的是正規表達式)
- String substring(int beginIndex):截取一段子字元串,從beginIndex開始到結尾
- String substring(int beginIndex, int endIndex):截取一段子字元串,從beginIndex開始到 endIndex(不包含)
判斷相關
- int compareTo(String anotherString):按照字典順序比較兩個字元串的大小
- boolean contains(String another):判斷目前字元串中是否包含指定字元串
- another boolean equals(String another):比較目前字元串與指定字元串的内容是否相同
- boolean isEmpty():判斷目前字元串是否為空,length() == 0
- boolean startsWith(String prefix):判斷該字元串是否以prefix開頭
- boolean endsWith(String suffix);判斷該字元是否以suffix結尾
修改相關
- String toLowerCase():将字元串中所有的英文字母全部變為小寫
- String toUpperCase():将字元串中所有的英文字母全部變為大寫
- String trim():将字元串中兩端的多餘空格進行删除
- String replace(char oldCh,char newCh):将字元串中oldCh字元替換成newCh字元
Character類
Character它是char基本資料類型的 包裝類 ,有這麼幾個靜态方法我可目前可以使用到的
- static boolean isDigit(char ch):判斷字元是否是數字
- static boolean isLetter(char ch):判斷字元是否是字母
- static boolean isLetterOrDigit(char ch):判斷字元是否是數字或字母
- static boolean isLowerCase(char ch):判斷是否是小寫字母
- static boolean isUpperCase(char ch):判斷是否是大寫字母
- static boolean isSpaceChar(char ch):判斷是否空白字母(空格 制表符 回車)
第五章 函數
函數的概念
函數的定義就是指一段具有獨立功能的代碼,減少代碼備援,提高程式的使用率和效率。
如何去定義函數
- 需要一個封閉的空間,将這段獨立性的代碼進行封裝,用一對大括号
- 需要對每一個封閉的空間進行命名,函數名
- 函數所需要的一些原始資料
- 函數所産生的一些結果資料
函數的文法格式
修飾符 函數類型 傳回值類型 函數名(資料類型 資料1,資料2,資料3){
獨立功能的代碼片段;
return 函數的結果;
}
- 修飾符 :指的是函數的通路權限,public private 預設 protected
- 函數類型:函數的分類,本地函數native,靜态函數 static ,同步函數synchronized
- 傳回值類型:指的就是函數計算結果的資料類型 如果函數沒有傳回值 則為void
- 函數名:就是函數的名稱
- 參數清單:指的是外界向函數傳入的資料(實際參數),由這些參數變量進行接收(形式參 數)
- 函數體:具有獨立功能的代碼片段;
- return:僅僅表示函數結束!如果函數有傳回值,則return後跟傳回值;如果沒有傳回值,則 return可以不寫,但是是存在的(隐藏的 在最後一行)
根據形參和傳回值來看,函數有如下幾個分類
- 有參數有傳回值
求三個數字當中的最大值
public class Sample {
public static void main(String[] args) {
int max = getMax(1,2,3);
System.out.println(max);
}
public static int getMax (int a , int b , int c) {
/*
if (a >= b && a >= c) {
return a;
}else if (b >= a && b >= c) {
return b;
}else {
return c;
}
*/
if (a >= b && a >= c) {
return a;
}
if (b >= a && b >= c) {
return b;
}
if (c >= a && c >= b) {
return c;
}
return -10000;
}
- 有參數無傳回值
- 無參數有傳回值
擷取目前時間的字元串
public class Sample {
public static void main(String[] args) {
String currentTime = getTime();
System.out.println(currentTime);
}
public static String getTime() {
//1.擷取總毫秒數
long millis = System.currentTimeMillis();
//2.計算總秒數
long seconds = millis / 1000;
//3.計算總分鐘數
long minutes = seconds / 60;
//4.計算總小時數
long hours = minutes / 60;
//5.計算目前小時數
long currentHours = hours % 24;
//6.計算目前分鐘數
long currenrMinutes = minutes % 60;
//7.計算目前秒數
long currentSeconds = seconds % 60;
return currentHours + ":" + currenrMinutes + ":" +currentSeconds;
}
}
- 無參數無傳回值
其實就是在函數中直接輸出想要擷取的資訊
函數的運作原理
函數的運作是基于棧運作的
棧:是一種先進後出的容器,我們這裡面所說的棧是指JVM中的棧記憶體空間
每一個函數,叫做棧幀,棧幀中所包含的内容有函數的定義,參數清單,函數的執行内容代碼
每一個函數要運作,就相當于這個棧幀進入到棧記憶體中-入棧
如果一個函數即将結束,将這個棧幀從棧頂移出-出棧
如果棧記憶體中有多個棧幀,運作的是最上面的棧幀,底下的棧幀暫停運作,直到該棧幀為棧頂元素
比如:主函數先進棧,開始逐行運作,如果執行到第n行,調用另外一個函數A,則主函數在第n行 暫停運作,将另一個函數A的棧幀入棧,再繼續逐行運作,直到函數A的内容執行完畢,函數A出棧,主 函數接着從第n行繼續向下執行。以此類推。
函數重載
同一個類中可以出現多個同名函數,這個現象就叫做函數的重載(overload)
如何區分是否重載
- 前提必須是同名
- 傳回值類型無關(傳回值類型隻和函 數的計算功能相關)
- 和權限也沒有關系
- 和形式參數的名稱也無關
- 隻和形式參數的資料類型有關 (數量,排列組合)
下列哪些是該函數的重載:
- int show(int x, float y, char z) :不算重載 資料類型都是int float char
- void show(float b,int a,char c):算重載,順序不一樣float int char
- void show(int a,int b,int c):算重載,順序不一樣int int int
- double show():算重載,參數不一樣
尋找重載的流程
- 看是否有确切的參數定義比對,int int 找 int int
- 看是否有可相容的參數定義比對,int int找double double或int double或double int
- 如果可相容的參數定義比對較多,會報引用确定報錯 引用不明确
即 如果 int int既可以找 double int也可以找int double 引用不明确會報錯
函數的遞歸
定義
函數的遞歸就是指函數自身調用自身。
相對而言,從記憶體的角度而言,函數如果過多的自我調用,勢必會對記憶體不友好,占用過多
通常來講,同樣的問題用遞歸寫要比用疊代寫代碼量較少
寫遞歸時,一定要先确定遞歸結束條件-遞歸邊界
案例
遞歸實作斐波那契數列
public class Sample {
public static void main(String[] args) {
/*
1 1 2 3 5 8 13 21 34 55 ...
1 x=1,x=2
f(x) =
f(x-1) + f(x-2) x>2
f(5)
f(4) f(3)
f(3) f(2) f(2) f(1)
f(2) f(1)
*/
//遞歸O(2^n)
System.out.println(f(35));
//疊代O(n)
System.out.println(fibo_it(35));
}
public static int fibo_it(int x) {
if (x == 1 || x == 2) {
return 1;
}
/*
1 1 2 3
c
a b
*/
int a = 1;
int b = 1;
int c = 0;
for (int i = 3; i <= x; i++) {
c = a + b;
a = b;
b = c;
}
return c;
public static int f(int x) {
if (x == 1 || x == 2) {
return 1;
}else {
return f(x-1) + f(x-2);
}
}
}
漢諾塔問題
public class Demo81 {
/*
前4個 x->z
前3個 x->y
前2個 x->z
前1個 x->y
第2個 x->z
前1個 y->z
第3個 x->y
前2個 z->y
前1個 z->x
第2個 z->y
前1個 x->y
第4個 x->z
前3個 y->z
前2個 y->x
前1個 y->z
第2個 y->x
前1個 z->x
第3個 y->z
前2個 x->z
前1個 x->y
第2個 x->z
前1個 y->z
*/
public static void main(String[] args) {
String x = "x";
String y = "y";
String z = "z";
hano(3,x,y,z);
//前3層從 x->z
//前2層從 x->y
}
public static void hano(int level,String begin,String mid,String end) {
if (level == 1) {
System.out.println(begin+"->"+end);
} else {
//前level-1層
hano(level - 1,begin,end,mid);
System.out.println(begin+"->"+end);
//前leve1-1層
hano(level - 1,mid,begin,end);
}
}
}
第六章 數組
數組的概念及定義
數組概念
數組主要用于解決大量資料計算和存儲的問題
比如:輸入100個數字,統計其中的最大值和最小值并計算平均值,建立100個變量,會有一堆if else語句,比較麻煩。
數組是Java提供的一種最簡單的資料結構,可以用來存儲一個元素 個數固定 且 類型相同 的有序 集。
數組在記憶體中的情況
棧:主要用于運作函數的記憶體
堆:主要用于存儲資料對象的記憶體
每一個數組而言,都是存在堆記憶體當中,每一個數組都是一個對象
注意
數組本質上就是在堆記憶體中一系列位址連續且空間大小相等的存儲空間(變量),每一個存 儲空間用來存儲資料(基本,引用)
數組是在堆記憶體中存儲,稱之為是一個對數對象,并且在堆記憶體中存儲的資料都有 預設初始 化 的流程。是以數組建立之初,每一個存儲空間裡面都會被JVM初始化該資料類型對應的零值。
數組的位址是連續的,是以通過公式:An=A1+(n-1)*d可以快速通路到其他的元素,是以對于 數組而言查找元素比較快的。将元素的真實實體位址轉換成對應的角标擷取元素。
如何來調用數組呢?
通過一個變量存儲該數組在堆記憶體當中的首元素的位址。 當數組一旦定義出來,其長度不可變,存儲空間的内容是可變的 是以我們在定義數組的時候,要麼把長度固定,要麼直接輸入相關的元素。
數組定義
一維數組的定義
定義
//建立一個指定長度且指定資料類型的一維數組,名稱為數組名,雖然沒有指定元素,但是會有預設值
資料類型[] 數組名 = new 資料類型[長度];
//建立一個指定元素且指定資料類型的一維數組,名稱為數組名,雖然有指定元素,還是有預設初始化這個步驟的!
資料類型[] 數組名 = new 資料類型[]{資料1,資料2,...,資料n};
資料類型[] 數組名 = {資料1,資料2,...,資料n};
方法
arr.length 一維數組的長度
二維數組的定義
定義
二維數組,在表現形式上就是一個表格,在操作表格的時候以行列來操作
1 | ||
---|---|---|
0.0 | 0.1 | |
1 | 1.0 | 1.1 |
2 | 2.0 | 2.1 |
所謂的二維數組,本質上就是一個一維數組,隻不過該一維數組裡面的元素是另一個一維數組而已
public class Sample {
public static void main(String[] args) {
//資料類型[][] 矩陣名 = new 資料類型[row][col];
int[][] matrix = new int[3][2];
/*
資料類型[][] 矩陣名 = new 資料類型[][] {
{...},
{...},
{...}
};
資料類型[][] 矩陣名 = {
{...},
{...},
{...}
};
*/
int[][] matrix2 = {
{1,2,3},
{4,5,6},
{7,8,9}
};
for (int i = 0; i < matrix2.length; i++) {
for (int j = 0; j < matrix2[i].length; j++) {
System.out.print(matrix2[i][j] + " ");
}
System.out.println();
}
int[][] matrix3 = {
{1},
{1,2,3},
{1,2,3,4},
{7,6,5,4,3,2,1}
};
for (int i = 0; i < matrix3.length; i++) {
for (int j = 0; j < matrix3[i].length; j++) {
System.out.print(matrix3[i][j] + " ");
}
System.out.println();
}}}
方法
arr.length 二維數組的行數
arr.[0]表示另一個一維數組
arr[0].length 第一個一維數組的長度
常用數組操作
數組周遊問題
public class Sample {
public static void main(String[] args) {
int[] arr = new int[]{1,2,3,4,5,6,7,8,9};
//String str str.length()-函數
//int[] arr arr.length-屬性
for (int i = 0; i < arr.length; i++) {
arr[i] = arr[i] * 10;
System.out.println(arr[i]);
}
//通過角标周遊 可以在周遊的過程中對指定的元素進行修改
//foreach周遊 主要針對的是一些可疊代對象 Iterable
/*
for (資料類型 變量名 : 可疊代容器) {
}
*/
for (int num : arr) {
//num -> arr[i]
num = num / 10;
System.out.println(num);
}
//這種周遊方式 隻能擷取元素,不能修改元素
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
數組最值問題
public class Sample {
public static void main(String[] args) {
int[] arr = new int[]{3,6,8,2,9,4,5,1,7};
int min = arr[0];
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
}
if (arr[i] > max) {
max = arr[i];
}
}
System.out.println(max);
System.out.println(min);
}
}
數組擴容問題
public class Sample {
public static void main(String[] args) {
int[] arr = new int[]{1,2,3,4,5};
arr = add(arr,6);
arr = add(arr,6);
arr = add(arr,6);
arr = add(arr,6);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}//123456666
//在指定的數組arr中添加元素element
public static int[] add(int[] arr, int element) {
int[] newArr = new int[arr.length + 1];
for (int i = 0; i < arr.length; i++) {
newArr[i] = arr[i];
}
newArr[newArr.length - 1] = element;
return newArr;
}
}
數組排序問題
選擇排序算法
從小到大正方向擷取
public class Sample {
//選擇排序
public static void main(String[] args) {
int[] arr = {8,9,2,6,7,1,4,5,3};
for (int i = 0; i < arr.length - 1; i++) { //-1 n個數字沒有第n輪
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]) {
swap(arr,i,j);
}
}
}
print(arr);
}
//[1, 2, 3, 4, 5]
public static void print(int[] arr) {
System.out.print("[");
for (int i = 0; i < arr.length;i++) {
System.out.print(arr[i]);
if (i == arr.length - 1) {
System.out.println("]");
} else {
System.out.print(", ");
}
}
}
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
冒泡排序算法
從大到小反方向擷取
public class Sample {
//冒泡排序
public static void main(String[] args) {
int[] arr = {8,9,2,6,7,1,4,5,3};
for (int i = 0; i <arr.length - 1; i++) {//-1 表示n個數字隻有n-1輪
for (int j = 0; j < arr.length - 1 - i; j++) {//-1 避免重複比較(目前最大和上一
輪最大)
if (arr[j] > arr[j + 1]) {
swap(arr,j,j+1);
}
}
}
print(arr);
}
public static void print(int[] arr) {
System.out.print("[");
for (int i = 0; i < arr.length;i++) {
System.out.print(arr[i]);
if (i == arr.length - 1) {
System.out.println("]");
} else {
System.out.print(", ");
}
}
}
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
插入排序算法
從前到後逐個排序
public class Sample {
//插入排序
public static void main(String[] args) {
int[] arr = {8,9,2,6,7,1,4,5,3};
for (int i = 1; i < arr.length; i++) {
int e = arr[i];
int j = 0;
for (j = i; j > 0 && arr[j - 1] > e; j--) {
arr[j] = arr[j - 1];
}
arr[j] = e;
}
print(arr);
}
public static void print(int[] arr) {
System.out.print("[");
for (int i = 0; i < arr.length;i++) {
System.out.print(arr[i]);
if (i == arr.length - 1) {
System.out.println("]");
} else {
System.out.print(", ");
}
}
}
}
計數排序算法
建立最大減去最小個空間 然後輸入個數
public class Sample {
//計數排序
public static void main(String[] args) {
int[] arr = {-2,9,-1,12,8,-3,6,7,4,5,2,1,0,8,6,7,4,-3,-2,-1,-1,7};
int min = arr[0];
int max = arr[0];
//O(n)
for (int i = 1; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
}
if (arr[i] > max) {
max = arr[i];
}
}
int[] temp = new int[max - min + 1];
//對應關系 index = number - min number = index + min
//O(n)
for (int i = 0; i < arr.length; i++) {
temp[arr[i] - min]++;
}
//temp[index] 表示index對應的數字number出現的次數
int k = 0;
//O(n)
for (int index = 0; index < temp.length; index++) {
while (temp[index] != 0) {
arr[k] = index + min;
k++;
temp[index]--;
}
}
print(arr);
}
public static void print(int[] arr) {
System.out.print("[");
for (int i = 0; i < arr.length;i++) {
System.out.print(arr[i]);
if (i == arr.length - 1) {
System.out.println("]");
} else {
System.out.print(", ");
}
}
}
}
基數排序算法
個十百千位從小到大排序
import java.util.LinkedList;
public class Sample {
//基數排序
public static void main(String[] args) {
int[] arr = {102,203,321,13,12,78,96,34,37,28,6,8,5,6};
//1.先找到最大值 決定輪數
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
int radex = (max + "").length();
//2.建立十個桶 每一個桶是LinkedList
LinkedList<Integer>[] queues = new LinkedList[10];
for (int i = 0; i < queues.length; i++) {
queues[i] = new LinkedList<Integer>();
}
//3.進行數字分類和規整
//r=0個位 r=1十位 r=2百位...
for (int r = 0; r < radex; r++) {
//先按照r進行分類
for (int i = 0; i < arr.length; i++) {
int index = getIndex(arr[i],r);//擷取數字的r位 傳回該數字要去的桶的角标0~9
queues[index].offer(arr[i]);
}
//然後在重新規整到arr裡
int k = 0;
for (int index = 0; index < queues.length; index++) {
while(!queues[index].isEmpty()) {
arr[k++] = queues[index].poll();
}
}
}
print(arr);
}
public static int getIndex(int number, int r) {
//123 r=0
//123 r=1
//123 r=2
int index = 0;
for (int i = 0; i <= r; i++) {
index = number % 10;
number /= 10;
}
return index;
}
public static void print(int[] arr) {
System.out.print("[");
for (int i = 0; i < arr.length;i++) {
System.out.print(arr[i]);
if (i == arr.length - 1) {
System.out.println("]");
} else {
System.out.print(", ");
}
}
}
}
二分查找算法
有一個前提,所查找的資料集必須是有序的(升序,降序)
public class Sample {
//二分查找
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,7,8,9};
int min = 0;
int max = arr.length - 1;
int mid = (min + max) / 2;
int key = 10;
while (arr[mid] != key) {
if (key < arr[mid]) {
max = mid - 1;
}
if (arr[mid] < key) {
min = mid + 1;
}
if (min > max) {
mid = -1;
break;
}
mid = (min + max) / 2;
}
System.out.println(mid);
}
}
可變長參數清單
進入函數的時候建立一維數組
public class Sample {
public static void main(String[] args) {
show(1);
show(1,2,3);
show("hehe","lala","haha","xixi","heihei");
}
public static void show(int ... nums) {
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i] + " ");
}
System.out.println();
}
public static void show(String ... strs) {
for (int i = 0; i < strs.length; i++) {
System.out.print(strs[i] + " ");
}
System.out.println();
}
}