主頁 > 軟體設計 > JAVA入門萬字總結

JAVA入門萬字總結

2021-02-13 13:02:29 軟體設計

文章目錄

    • 引言
    • 什么是JAVA
    • 第一個JAVA程式
            • 結果
    • JAVA的資料型別
        • 內置資料型別
        • 參考資料型別
      • 內置資料型別
        • 整型
        • 浮點型
        • 字符型
        • 布爾型
      • 參考資料型別
      • 基礎型別轉換
        • 自動型別轉換
        • 強制型別轉換
    • JAVA符號
      • 算數運算子
      • 關系運算子
      • 邏輯運算子
      • 補充
    • JAVA邏輯判斷
      • if / else
      • switch case
    • JAVA回圈
      • for回圈
      • while回圈
        • break
        • continue
      • do while回圈
    • 判斷與回圈的應用
      • 求最大公因數
      • 求100以內的素數
      • 不死神兔
      • 水仙花數
      • 99乘法表
      • 求Pi的值
    • JAVA函式
      • 格式
      • 作用域
      • void關鍵字
      • 函式呼叫其他函式
    • JAVA陣列
      • 創建陣列
      • 訪問陣列元素
      • 遍歷陣列
      • 陣列與函式
        • 將陣列作為引數傳入函式
        • 將陣列作為回傳值輸出
      • 多維陣列
        • 小案例 Tic-Tac-Toe (井字棋)
        • 案例2,列印二維陣列初始值
    • JAVA類與物件
      • 物件創建
        • 構造方法
          • 無參構造
          • 有參構造
        • 注意
      • 物件方法
        • this關鍵字
        • 方法多載Overload
      • 物件封裝
      • 物件繼承
        • 介紹
        • 多型
          • 向上轉型
          • 向下轉型
          • instanceof關鍵字
        • super關鍵字
      • 物件是參考型別
      • 包裝類
    • JAVA字串
      • 常用方法
    • JAVA修飾符
      • static
        • 靜態方法
        • 靜態代碼塊
        • 靜態類
      • final
        • 最終類
        • 最終變數
        • 最終方法
        • 物件常量
      • abstract
        • 抽象類
        • 抽象方法
    • JAVA介面
      • 介紹
      • interface關鍵字
      • 注意
      • 補充
      • 案例
    • JAVA內部類
      • 成員內部類
      • 靜態內部類
      • 區域內部類
      • 匿名內部類
    • JAVA泛型
      • 泛型方法
      • 泛型類
      • 泛型介面
      • 通配符
    • JAVA集合
      • Collection介面
        • List介面
          • ArrayList
          • LinkedList
        • Set介面
          • HashSet
          • TreeSet
      • Map介面
        • Map遍歷
        • HashMap
        • TreeMap
    • JAVA常用類
      • Arrays類
      • Date和Calendar類
        • Date
        • Calendar
    • JAVA例外處理
      • 常見例外
      • 捕獲例外
      • Throws 關鍵字
        • 自定義例外類
    • JAVA IO處理
      • 流的概念
      • 流的分類
        • 位元組流
        • 字符流
      • 流的使用
        • 位元組流使用
          • 物件流與序列化
        • 字符流使用
          • 字符流讀取緩沖流
      • 檔案夾操作
        • FileFilter介面
      • Properties
    • 參考文獻
        • FileFilter介面
      • Properties
    • 參考文獻

引言

學習一門編程語言不是一件難事,在本書的前言我要鄭重強調一下這件事,學習如逆水行舟,不進則退;只要大家堅持,相信最后定會有所識訓,本書作為一本入門的工具書,會側重講解JAVA的基礎知識,旨在引導讀者進入JAVA的學習大門,

什么是JAVA

JAVA是一種面向物件的高階編程語言,在JAVA中有句老話:萬物皆物件,對于java的介紹我參考百科的一些解釋,(Java具有簡單性、面向物件、分布式、健壯性、安全性、平臺獨立與可移植性、多執行緒、動態性等特點 [2] ,Java可以撰寫桌面應用程式、Web應用程式、分布式系統和嵌入式系統應用程式等)

第一個JAVA程式

由于JAVA是一門面向物件的語言,在運行程式時我們需要單獨建立一個類物件,在此類物件的main()函式中運行,廢話不多說,直接上代碼

public class hello_world
{
	public static void main(String[] args) 
	{
		//這樣我們就創立好了第一個程式的框架
        //在main函式里面,我們就可以書寫一些需要的指令
	}
}

作為編程界的慣例,第一個程式當然是在console里面列印"Hello World"

public class hello_world
{
	public static void main(String[] args) 
	{
		System.out.println("hello world");
	}
}

System.out.println() 是一條將程式中的資料列印在控制臺,也就是console中的指令

在System.out.println后面有一對括號,在這個里面我們要傳入想要列印在console中的內容,即函式的引數

因為要將”hello world“轉化為計算機能看懂的語言,所以我們需要在"hello world"外加上雙引號,將其轉化為字串型別

這樣計算機就能讀懂我們的語言,從而輸出我們的指令,

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-pfoSMW1z-1613061611808)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210128115153341.png)]


JAVA的資料型別

當我們運行JAVA程式時,我們會進行一系列的數學計算,此時擁有存貯資料的變數就尤為重要,在JAVA中為了擁有存盤資料的變數,我們往往需要在記憶體中開辟一道空間,例如:

//在編輯器中的代碼變數
int x =5;
int y =6;

//在記憶體中存盤的變數資料, 變數名稱我們可以自定義

image-20210128120534839

JAVA的資料型別可以分為2大類

  1. 內置資料型別

  2. 參考資料型別

內置資料型別

Java 的內置資料型別一共有8種,8種中又可以分為4種,

  1. 整型: byte, short, int, long
  2. 浮點型: float, double
  3. 字符型: char
  4. 布爾型: boolean

整型

整型顧名思義,它是用來存盤整數的

雖然byte, short, int和long都屬于整型,但它們之間還是各有差異因為各自的取值不同,

資料型別資料范圍資料大小(bit /位)默認值
byte-128~127 (-2^7 ~(2^7)-1)1 byte= 8 bits0
short-32768~32767 (-2^15 ~(2^15)-1)2 bytes = 16 bits0
int-2^31 ~ (2^31)-14 bytes = 32 bits0
long-2^63 ~(2^63)-18 bytes = 64 bits0L

一般情況下,我們使用int型別來定義整數,因為int的范圍足以滿足我們日常的需求

byte a =100;

short b = 10000;

int c = 100000;

long d =10000000;

浮點型

與整型恰好相反,浮點型是用來存盤小數的,浮點型分為float和double,兩者的區別在于精度,

資料型別資料范圍資料大小(bit /位)默認值
float (單精度浮點型)1.4·10^-45 ~ 3.4·10^384 bytes = 32 bits0.0f
double(雙精度浮點型)4.9·10^-324 ~ 1.7·10^3088 bytes = 64 bits0.0d

雖然說浮點數可以表示小數,但是浮點數不能表示精確的數,例如貨幣,如果需要表示精確的數,需要借助其他java類例如Big Decimal來實作,例子: 1.40* 165 = 231 但是 計算機給出的計算是230.999999999997

通常浮點數在未宣告的前提下都是double型別,

float f1 = 234.5f;
double d1 = 123.4;

字符型

char型別是一個單一的16位Unicode字符, 表示字符時用單引號,char的范圍是0~65535,大小為16 bits

資料型別資料范圍資料大小(bit /位)默認值
char(字符)0~655352 bytes = 16 bits‘u0000’

對char變數賦值既可以使用數字,也可以使用字符,char可以存盤任何字符

public class test {
	public static void main(String[] args) {
		char a =65;
		char b ='A';
		System.out.println(a);
		System.out.println(b);
	}
}

結果

image-20210128134220486

布爾型

布爾型別指true和false,boolean資料只表示1位資訊,可作為標志flag來記錄true或false

資料型別資料范圍資料大小(bit /位)默認值
booleantrue / false1 bitfalse

參考資料型別

  1. 陣列
  2. 類與物件
  3. 字串

下面有一張圖來表示參考型別資料

image-20210130190446747

這張圖上p1,p2,p3,p4作為類物件,當他們被創建時,他們實際上時作為指標指向一些資料

在本節參考型別暫時提一下,在后面的章節中會詳細解釋這些

基礎型別轉換

在運行程式時,我們有時需要將不同型別的資料轉化為同一型別

型別轉換又可分為自動型別轉換與強制型別轉換

自動型別轉換

自動轉換條件是轉換前資料型別的位數低于轉換后資料型別的位數

轉化程序中可能會有精度損失

byte , short , char 可自動轉化為int

int 可轉化為 long

long 可轉化為 float

float 可轉化為 double

public class test {
	public static void main(String[] args) {
		char a =65;
		int b = a;
		System.out.println(a);
		System.out.println(b);
	}
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-uWyg1G64-1613061611811)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210128175039057.png)]

強制型別轉換

如果被轉化資料型別位數大于要轉化的資料型別的位數,此時需要用到強制型別轉換,注意Boolean型別不能被強制轉換

強制轉換格式

public class test {
	public static void main(String[] args) {
		char a ='A';
		byte b = (byte)a; //強制將char型別轉化為byte型別
        //其實將這些資料列印出來,也暗含了一層資料轉換
		System.out.println(a);
		System.out.println(b);
	}
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Sf8WSxcn-1613061611813)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210128175841728.png)]


JAVA符號

既然JAVA作為一門計算機編程語言,它一定能像計算器一樣為我們做一些運算,所以在本章我們將講解JAVA的運算子號,

算數運算子

運算優先級和現實生活中一樣,括號( ) > * 或 % 或 / > + 或 -

符號含義例子
=賦值int i =5; 把5賦值給i
+加號int i = (5+6);
-減號int j = (6-1);
*乘號int k = (7*8);
/取整int a = (7/8);
/除號double c = 7.0 /8;
%取余int b = (7%8);
//轉義字符寫注釋用的
public class test {
	public static void main(String[] args) {
		int i = 5+6;
		int j = 6-1;
		int k = 7*8;
		int a = 9 / 8;
		double b = 9.0 / 8;  //如果想用除法獲得小數,必須要用double型別的資料
		int c = 9 % 8;
		System.out.println("5+6 = "+i);
		System.out.println("6-1 = "+j);
		System.out.println("7*8 = "+k);
		System.out.println("(整除)9/8 = "+a);
		System.out.println("(除以)9.0/8 = "+b);
		System.out.println("(取余)9%8 = "+c);
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-EfkgjWuS-1613061611814)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210129202007447.png)]

//優先級測驗
public class test {
	public static void main(String[] args) {
		double a = (2+1)+3.0/5-6*7-(4/3);
		System.out.println("(2+1)+3.0/5-6*7-(4/3) = "+a); //注意(4/3) 是取整,結果是1 
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ACH71YxL-1613061611816)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210129202931197.png)]

關系運算子

在運行程式時,我們需要對一些資料進行判斷,此時就需要關系運算子

關系運算子判斷后,回傳true 或 false

符號含義例子
==等于(6 == 7) false
!=不等于(6 != 7) true
>大于(6 > 7) false
<小于(6 < 7) true
<=小于或等于(6 <= 7) true
>=大于或等于(6 >= 7) false

邏輯運算子

和電路圖中的邏輯門類似, 邏輯運算子就是

與, 或,非

A為true

B為false

符號含義例子
&&與,and,當左邊與右邊同時為true時回傳true(A && B) false
||或, or, 左邊或右邊任意一個滿足即回傳false(A||B) true
!非,與所選的條件相反!(A||B) false

補充

看別人的原始碼時有時會碰到以下的幾種符號

符號含義例子
++加一a++; a的值加1
減一b–; b的值減1
+=加等于a += b; 意思是a= a + b;
-=減等于a -= b; 意思是 a = a -b;
/n換行“/n”
/t水平制表符從左往右數8個空格

JAVA邏輯判斷

上文我們提到了邏輯運算子與關系運算子,這些符號會給我們回傳boolean 型別的資料 :true 或 false

true / false便是用在邏輯判斷中的

if / else

假如大家對其他語言,例如python有所了解, 判斷通常會使用if else陳述句,格式如下

if(條件陳述句){
    //執行的指令
}
else if(條件陳述句){
    //執行的指令
}
//else指的是最終條件,即排除if與else if條件之后
else{
    //執行的指令
}

例子

在這個例子里面會用到用戶輸入指令,Scanner

import java.util.Scanner;
public class test {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);  //創建scanner物件,這樣就可以從控制臺輸入
		System.out.print("a: ");
		int a = input.nextInt(); //nextInt()指輸入的值是int型別資料,該方法是通過物件呼叫,后面會講
		System.out.print("b: ");
		int b = input.nextInt();
        //比較a與b的大小
		if(a>b) {
			System.out.println("a大于b");
		}
		else if(a<b) {
			System.out.println("a小于b");
		}
		else {
			System.out.println("a等于b");
		}
		input.close();
	}
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-j6heCkcD-1613061611817)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210129210114533.png)]

除此之外,還有嵌套式的if else

if(a > b){
    if(a > c){
        //當a大于b 同時 a大于c時,列印"a is MAX"
        System.out.println("a is MAX");
    }
    else{
        System.out.println("b < a <c ");
    }
}

switch case

switch case 類似于條件判斷,通過switch的判斷來選取對應的case,格式如下

switch(condition){
    case value:
        //action
        break;
    case value2:
        //action
        break;
    default: //當case中的value沒有一個滿足condition時,default中的指令才會執行
        //action
}

例子

//輸出輸入數字所對應的英文(1-9)
import java.util.Scanner;
public class switch{
	public static void main(String[] args) {
		System.out.print("NUM: ");
		Scanner num = new Scanner(System.in);
		int digit = num.nextInt();
		String digitName; //String是字串型別,屬于參考資料型別,在后面有提到
		switch (digit) {
		case 1: 
                digitName = "one"; 
                break;
		case 2: 
                digitName = "two"; 
                break;
		case 3: 
                digitName = "three"; 
                break;
		case 4: 
                digitName = "four"; 
                break;
		case 5: 
                digitName = "five"; 
                break;
		case 6: 
                digitName = "six"; 
                break;
		case 7: 
                digitName = "seven"; 
                break;
		case 8: 
                digitName = "eight"; 
                break;
		case 9: digitName = "nine"; break; //有時為了節省空間,可以連在一起寫
		default: digitName = "I cannot distinguish this number"; break;
		}
		System.out.print(digitName);
		num.close();
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-MZpyKBrc-1613061611819)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210130101525956.png)]

每個case后面都跟有一個break,用于阻止case1中的action執行完畢后再執行case2的action

反例

import java.util.Scanner;
public class switch2{
	public static void main(String[] args) {
		System.out.print("NUM: ");
		Scanner num = new Scanner(System.in);
		int digit = num.nextInt();
		String digitName;
		switch (digit) {
		case 1: digitName = "one"; break;
		case 2: digitName = "two"; break;
		case 3: digitName = "three"; break;
		case 4: digitName = "four"; 
		case 5: digitName = "five";
		case 6: digitName = "six"; break; 
		case 7: digitName = "seven"; break;
		case 8: digitName = "eight"; break;
		case 9: digitName = "nine"; break;
		default: digitName = "I cannot distinguish this number"; break;
		}
		System.out.print(digitName);
		num.close();
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-hbcY1AyX-1613061611820)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210130101720253.png)]

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ggRlfTKu-1613061611821)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210130101740442.png)]

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-DW41QtCF-1613061611822)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210130101843945.png)]

由于沒有在case 4和 case 5后面加上break, 無論輸入的是4還是5,最終給予digitName的賦值始終是 “six”;

直白點說,break就是用來阻止程式繼續向下運行的指令


JAVA回圈

學完邏輯判斷與基本的運算,接下來我們要了解一下java中的回圈,

java的回圈如同其他語言一樣,包含

  1. for回圈
  2. while回圈
  3. do while回圈

for回圈

結構

for(初始值;回圈結束條件;初始值變化){
    //action
}

在for回圈中,初始值一般是我們自定義的,例子如下

//我們創造一個for回圈,這個回圈運行5次,每次列印我們定義的變數的值
for(int i=0;i<5;i++){
    System.out.println(i);
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-UxKmB9Ks-1613061611823)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210130103416060.png)]

從輸出的結果可以看出,當i的值等于5時,條件回傳為false,回圈終止

while回圈

格式

//判斷條件指的是滿足這個條件時,程式回圈運行
while(判斷條件){
    //action
}

例子

//與上面for回圈的案例類似
int i=0;
while(i <5) {
	System.out.println(i);
	i++; //前面計算符號補充部分有提及,i++指 i = i + 1
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-e0XuzCEk-1613061611824)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210130104404416.png)]

如果對這個不太明白,下面有一幅圖可以解釋

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-at8b94pM-1613061611825)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210130105844321.png)]

總共運行了5次,在第6次時條件判斷為false,所以回圈停止

break

while回圈還可以與之前switch case里面提到的break一起使用,例子如下

int i=0;
while(i < 7) {
    //當i 等于 5 時,回圈中止
	if(i == 5) {
		break; //break的作用是中止回圈
	}
	System.out.println(i);
	i++;
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-SRjU0ohf-1613061611826)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210130111831321.png)]

continue

與break對應的是continue,break是中止回圈

而continue是跳過這一輪回圈將要執行的陳述句,直接進入下一輪回圈,例子如下

public class test {
	public static void main(String[] args) {
		int i=0;
		while(i <7) {
			System.out.println(i);
			i++;
            //當i 等于 5時,跳過輸出這一輪的 "--------"
            //由于i++放在前面,所以輸出i后, i的值+1, 即在第5輪,輸出i=4過后跳過輸出 "--------"
			if(i == 5) {
				continue;
			}
			System.out.println("--------");
			
		}
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-pjRHZxY4-1613061611827)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210130112521021.png)]

do while回圈

格式

do{
    //action
}while(判斷條件);

do while回圈和while回圈的區別是:無論條件為何,do while回圈都會將action部分執行一遍,例子如下

public class test {
	public static void main(String[] args) {
		int i=0;
		do {
			System.out.println(i);
			i++;
		}while(i<0);
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-LvRoK3o2-1613061611828)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210130124327971.png)]


判斷與回圈的應用

前面幾章我們學習了java的運算子,邏輯判斷與回圈,這一章舉一些例子,靈活運用前面的知識

求最大公因數

題目:求出48與292的最大公因數與最小公倍數,

程式分析:使用輾轉相除法

public class LargestFactor {
	public static void main(String[] args) {
		int m =48;
		int n = 292;
		int a = m;	
		int b = n;
		int r = a%b;
		while (r!=0) {
			a = b;
			b = r;
			r = a%b;
		}
		 int divisor = b;    
		 
		 System.out.println("The Greatest Common Divisor:"+divisor);
		 System.out.println("The Lowest Common Multiple:"+(m*n)/divisor);
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-S6scExTR-1613061611829)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210130155438457.png)]

求100以內的素數

題目:輸出100以內的素數?

程式分析:素數是大于1的正整數,只能除以它本身與1

public class isprime {
	public static void main(String[] args) {
		for(int i=2; i<=100; i++) {
			boolean isPrime = true;
			for (int j=2; j<i; j++) {
				if((i%j) == 0) {
					isPrime = false;
					break;
				}
			}
			if(isPrime) {
				System.out.println(i+" is prime");
			}
		}
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-wZUo3rXp-1613061611829)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210130143041470.png)]

不死神兔

題目:古典問題:有一對兔子,從出生后第3個月起都生一對兔子,小兔子長到第3個月后每個月又生一對兔子,假如兔子都不死,問每個月的兔子對數為多少(20個月內)?

程式分析:兔子的規律為數列1,1,2,3,5,8,13,21…(斐波那契數列)

public class Test{
    public static void main(String[] args){
        long a=1;
        long b=1;
        long c=0;
        System.out.print(a+"\t"+b);
        //for回圈用來計數
        for(int i=3;i<=20;i++){
            //a,b,c交換資料
            c =a+b;
            a =b;
            b =c;
            System.out.print(c+"\t");
        }
    }
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-URMRdTWP-1613061611830)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210130140249510.png)]

水仙花數

題目:列印出1000以內的水仙花數,所謂的“水仙花數”是指一個三位數,其各位數字立方和等于該數本身,例如:152是一個“水仙花數”,因為153 =1的3次方+5的3次方+3的3次方,

程式分析:需要用到for回圈,每個數分解出個位,十位,百位

public class flower {
	public static void main(String[] args) {
		//水仙花數是三位數,從100開始,到1000結束
        for(int i=100; i<1000; i++ ) {
            //第一種獲取每位的方法
			int a = i/100;  //對i取整,獲取百位的數字
			int b = (i-a*100)/10; // 減去1的百位上的數字,除以10,獲取十位的數字
			int c = i-100*a-10*b; //個位就是排除十位與百位
			//第二種獲取每位的方法
            //int a = i/100; 
			//int b = (i%100)/10; //對i除以100取余,再通過10取整,獲得百位
			//int c = (i%100)%10; //對i除以100取余,再通過10取余,獲得個位
            int sum = a*a*a+b*b*b*b+c*c*c;
			if (sum==i) {
				System.out.println(i+"是水仙花數");
			}
		}
		System.out.println("Finish");
	}
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-XXBkYWV8-1613061611831)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210130133328919.png)]

99乘法表

題目:輸出9*9口訣

程式分析:嵌套式for回圈,注意換行

public class test {
	public static void main(String[] args) {
		for(int i=1;i<=9;i++) {
			for(int j=1;j<=i;j++) {
				System.out.print(j+"*"+i+"="+(i*j)+"\t");
			}
			System.out.println();
		}
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-eSlfSUmN-1613061611831)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210130155506835.png)]

求Pi的值

題目:根據Gregory-Leibniz series, 我們可以計算Pi的值,要求算到第10000個級數

程式分析:Pi = (4/1) - (4/3) + (4/5) - (4/7) + (4/9) - (4/11) + (4/13) … 觀察發現規律:分母為奇數,偶數-1,

public class test {
	public static void main(String[] args) {
		double rst=0.0;
		for(int i=1;i<=10000;i++){
            //判斷是偶數還是奇數
			if(i%2==1){
				rst += 4.0/(2.0*i-1); //分母為奇數1,3,5,7……
			}
			else{
				rst -= 4.0/(2*i-1);
			}
			
		}
		System.out.println(rst);
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-EU9GcD7q-1613061611832)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210130160022440.png)]


JAVA函式

函式,大家在初高中應該有所耳聞,例如f (x), f (x) 這個函式有名字f, 同時它也包含一個引數x,設定一個函式可以被我們連續呼叫,java或者說大部分主流的編程語言都繼承了數學中函式的特點,

在本書的前面幾章大家應該已經接觸到了函式,System.out的println(""),這個就是一個系統類的函式(方法)

我們可以將想要列印在console(控制臺)上的內容作為引數傳入此函式(方法),它就將內容呈現出來

格式

java的函式(在類物件中也可以叫做方法)格式

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-bTA4Pg2Z-1613061611834)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210130182507127.png)]

  • 函式回傳值型別可以為任意資料型別,int, double, char, string等
  • public static 都是修飾符,在后賣會講到
  • return 的值型別一定要與定義函式時一致

在函式或方法中引數還有另外一個名字,形參;而我們傳入時的引數叫實參(實際的引數)

作用域

說到函式或方法,那一定要提及作用域,即我們創建的引數能夠用在那些范圍內

下面我們用一個例子來解釋

public class test {
	public static void main(String[] args) {
		int a = 8;
		int b = 9;
		int c = add(a,b); //當要呼叫方法時,直接寫該函式的名字與應該傳入的引數
		System.out.println(a);
		System.out.println(b);
		System.out.println(c);
	}
	public static int add(int i, int j) {
		int a = i + j;
		return a;
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-EZnODs2e-1613061611835)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210130184251449.png)]

在上面的例子中,main主函式中的a, b, c是實參;而add函式中的i, j, a都是形參

我們可以看出雖然在main函式與add函式中a都是我們的引數,但是兩者為什么都不沖突呢?

因為作用域的不同導致了兩者的不同,在add函式中定義的引數的作用域僅僅在add函式中,不超過add,而main函式中定義的引數的作用域也僅僅在main中,無法擴散到add函式中,

假如main函式想要與add函式交換引數,就必須通過形參和return,

void關鍵字

有心的小伙伴也許已經發現了我們的main函式為什么沒有回傳值,且是回傳值型別是void

void的英文意思是空,即什么也沒有

同理,用在函式上時,表示該函式接收引數但不需要有回傳值,這個函式就像一個方法一樣,如下

//寫一個比較大小的程式
public class test {
	public static void main(String[] args) {
		int a = 19;
		int b = 79;
		int c = 100;
		MAX(a, b, c); //此時呼叫MAX方法,沒有回傳值
		
	}
	public static void MAX(int a, int b, int c) {
		System.out.println("NUM: "+a+" "+b+" "+c);
		int max = a;
		if(a < b) {
			max =b;
			if(b < c) {
				max = c;
			}
		}
		System.out.println("MAX is "+max);
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-eQRe1Svh-1613061611836)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210130190143049.png)]

函式呼叫其他函式

我們在一個函式中可以呼叫別的函式,例子如下

public class test {
	public static void main(String[] args) {
		int a = 19;
		int b = 79;
		int c = 100;
		MAX(a, b, c);
		
	}
	public static void MAX(int a, int b, int c) {
		System.out.println("NUM: "+a+" "+b+" "+c);
		int max = a;
		if(a < b) {
			max =b;
			if(b < c) {
				max = c;
			}
		}
		print(max); //直接輸入函式名與引數就可以使用該函式
	}

    //通過print函式我們把max的值列印出來    
	public static void print(int max) {
		System.out.println("MAX is "+max);
	}
}

JAVA陣列

上文提到了參考型別資料,在本章我將講解其中一個參考型別資料:陣列

對C語言或其他編程語言有所了解的伙伴應該聽說過陣列這個定義,陣列,顧名思義,是將一系列統一的資料放在一起的組合,比如我們想將 ‘h’,‘e’,‘l’,‘l’,‘o’ 這幾個字符放在一起之后再使用,此時我們就需要創建一個 字符型別的陣列,

為什么說陣列是參考型別的呢?

當我們創立一個陣列并賦予其值,并不是在記憶體中直接開辟含有這些資料的陣列,而是將陣列的指標指向這些資料,直白點說,陣列就像瀏覽器中的收藏夾,我們需要點擊哪個鏈接(資料)時,就打開這個收藏夾(陣列)

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-9hiEMme8-1613061611837)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210129163522377.png)]

以char型別的陣列為例,接下來將介紹幾種創建陣列的方法

創建陣列

//宣告陣列變數
char[] words;
char words[];

//創建陣列的幾種方法
//1
//每一組括號前要先宣告陣列中存盤資料的型別
words = new char[5]; //在后面的括號中放的資料是我們所定義的陣列的大小

//2
words2 = new char[5] //與上一個差不多
//當然宣告與創建陣列可以放在一起
char[] word = new char[5];
    
//3 
char[] words3 = {'h','e','l'.'l','o',};

當第1種和第2種陣列創建完畢后,默認內部的5個元素都為’\u0000’(char 型別的默認值);

當第3種陣列創建完畢后,默認的元素是初始化的那些元素

import java.util.Arrays;
public class test {
	public static void main(String[] args) {
		int[] words = new int[5];
		char words2[] = new char[5];
		char[] words3 = {'h','e','l','l','o'};
        //由于陣列無法直接通過System.out.println列印出來,
        //我們需要呼叫Arrays包中的toString()方法
		System.out.println("words "+Arrays.toString(words));
		System.out.println("words2 "+Arrays.toString(words2));
		System.out.println("words3 "+Arrays.toString(words3));
	}
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ougL3cAd-1613061611839)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210129170236619.png)]

訪問陣列元素

創建陣列是為了儲存資料,所以我們應該要明白如何訪問/呼叫陣列中的元素

我們需要通過陣列的下標來訪問陣列中的元素

在計算機編程語言中,陣列下標幾乎都是從0開始(陣列中第一個元素),因為這樣可以方便計算機的指標讀取資料

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-VPnPsy1p-1613061611840)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210129172730705.png)]

所以陣列中第一個元素下標是0,第二個元素下標是1,依次類推,注意最后一個元素的下標必須是(陣列長度-1),因為元素下標是從0開始的,

public class array2{
	public static void main(String[] args) {
		double[] values = {2,3,4,5};
		double one = values[0]; //注意獲取陣列中元素,接收的變數型別應與陣列一致
		double two = values[1];
		System.out.println(one);
		System.out.println(two);
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-6IIEPOJg-1613061611840)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210129173312581.png)]

有心的同學應該注意到了,我們存進去的元素是整數型別,為什么最后列印出來是double呢?

因為在存入double型別陣列中時,編譯器進行了自動型別轉換,將整型轉化為浮點double型別

遍歷陣列

為了讀取陣列中的元素,我們通常使用遍歷的方法

通過一組for回圈來獲取陣列中的每個元素

public class array2{
	public static void main(String[] args) {
		double[] values = {2,3,4,5};
        //public int length;是java陣列中自帶的方法,用于回傳該陣列的長度
		for(int i=0;i<values.length;i++) {
			System.out.println(values[i]);
		}

	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-mNk9DjfS-1613061611840)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210129174548429.png)]

我們還可以使用for-each(也叫增強for)來遍歷陣列

for(type element : array){
	System.out.println(element);
}

增強for允許我們在不訪問下標的情況下讀取陣列,十分方便

public class array2{
	public static void main(String[] args) {
		double[] values = {2,3,4,5};
		for(double value: values) {
			System.out.println(value);
		}

	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-xbhNNukY-1613061611841)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210129174548429.png)]

陣列與函式

我們可以把陣列作為一個回傳值或引數放在函式中

將陣列作為引數傳入函式

public class array2{
    //add 將陣列作為引數傳入函式,回傳陣列中所有元素的和
	public static double add(double[] values) {
		double total = 0; 
		for (double element : values)
			{
			 total = total + element;
			}
		return total;
	}
	public static void main(String[] args) {
		double[] values = {2,3,4,5};
		System.out.println(add(values));

	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-gzZI0CFL-1613061611842)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210129184602683.png)]

將陣列作為回傳值輸出

import java.util.Arrays;
//將輸入陣列每個元素加1,并回傳
public class array2{
	public static double[] add(double[] values) {
		for(int i=0;i<values.length;i++) {
			values[i] += 1;
		}
		return values;
	}
	public static void main(String[] args) {
		double[] values = {2,3,4,5};
		System.out.println(Arrays.toString(add(values)));

	}
}

多維陣列

我們的現實世界是由多個維度所組成,一條線是一維, 一個平面是二維,我們所在的空間是三維

和現實世界類似,陣列也可以創造多個維度

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-26KDN6dx-1613061611843)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210129185959447.png)]

創建二維陣列或多維陣列的方式與一維陣列類似


public class test {
	public static void main(String[] args) {
		int[][] num = new int[2][3]; //創建一個2行3列的二維陣列
		num[0][0] = 1; //給第一行,第一列的元素賦值為1
		num[1][0] = 2; //給第二行,第一列的元素賦值為2
        //因為是二維陣列,通過兩個for回圈來遍歷列印
		for(int i=0;i<num.length;i++) {
            //num.length是獲取二維陣列的行數
			for(int j=0;j<num[0].length;j++) {
                //num[0].length是獲取第一行陣列的個數,即num二維陣列的列數
				System.out.print(num[i][j]+" ");
			}
			System.out.println();
		}

	}
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-DgaM6fUI-1613061611843)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210129191554891.png)]

在本章中我們有運用到一個陣列的工具類, Arrays,在后面常用類中,我們會有詳細的解釋,

小案例 Tic-Tac-Toe (井字棋)

import java.util.Scanner;
public class TiTaTu{
	public static void main(String[] args) {
        //用二維陣列模擬棋盤, 0和1代表O和X
		int [][] array = {
				{0,1,0,1},
				{1,0,0,1},
				{1,1,1,1},
				{0,1,0,1},
		};
		boolean rst_X = false;
		boolean rst_O = false;
		int numOfX_S = 0;
		int numOfO_S = 0;
		int numOfX_RS = 0;
		int numOfO_RS = 0;
		int k = array.length -1;
		for(int n=0;n<array.length;n++) {
			int numOfX_H =0;
			int numOfO_H =0;
			for(int m=0;m<array[n].length;m++) {
				if(array[n][m] == 1) {
					numOfX_H++;
					if(numOfX_H == array.length ) {
						rst_X = true;
					}
				}
				else if(array[n][m] == 0){
					numOfO_H++;
					if(numOfO_H == array.length){
						rst_O = true;
					}
				}
			    
			}
			if(array[n][n] == 1) {
				numOfX_S++;
				if(numOfX_S == array.length ) {
					rst_X = true;
				}
			}
			else if(array[n][n] == 0) {
				numOfO_S++;
				if(numOfO_S == array.length ) {
					rst_O = true;
				}
			}
			//reverse diagonal line
			
				if(array[n][k] == 1) {
					numOfX_RS++;
					if(numOfX_RS == array.length ) {
						rst_X = true;
					}
				}
				else if(array[n][k] == 0) {
					numOfO_RS++;
					if(numOfO_RS == array.length ) {
						rst_O = true;
					}
				}
				k--;
			}
		
		
	 
		if(rst_X == true) {
			System.out.print("X win");
		}
		else if(rst_O == true) {
			System.out.print("O win");
		}
		else {
			System.out.print("Equal");
		}
	}
}

案例2,列印二維陣列初始值

public class Print2DArray{
	public static void PrintOut(int[][] array) {
		for(int i=0; i<array.length;i++) {
			for(int j=0;j<array[i].length;j++) {
				System.out.printf("%3d", array[i][j]);
			}
			System.out.println();
		}
	}
	public static void main(String[] args) {
		int[][] a = new int[5][5];
		PrintOut(a);
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-9gpzHDwx-1613061611845)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210131235733815.png)]


JAVA類與物件

不知道大家以前有沒有聽說過這樣一句話“萬物皆物件”,這句話出自Think in Java,一本今典的java書籍,在java中,任何東西都可以被描述成一個類,且每個類都能被用來實體化物件;因為周圍的世界是由各種各樣的物件所構成,所以我們可以利用java來模擬我們周圍的世界,創建各種各樣的類例如:學生類,老師類,汽車類,飛機類,

物件創建

創建一個物件的前提是有這個物件的類,我們先創建一個Animal類

package Class_Study;
public class animal {
	private int age; //private是修飾符,后面會講
	public animal(){
		//action 我們可以在這里添加一些指令
	}
	public animal(int num) {
		age = num;
	}
	public void roar() {
		System.out.println("I am yelling.");
	}
}

擁有了animal這個類后,我們就可以實體化(創建)一個animal物件

animal Tom = new animal();

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-5iOegIrB-1613061611846)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210131105309311.png)]

以后要是想對animal物件進行一些操作,直接通過Tom呼叫animal的內部方法(長得像函式的東西)即可,

構造方法

在類中的函式統一稱作“方法”

有人也許注意到了在animal類中為什么還有與animal同名的方法呢?

這些方法叫做構造方法,也稱建構式,

無參構造
public animal(){ //public是修飾符
	System.out.println("I am an animal."); //在無參構造方法里面,我們可以寫一些指令
}

像這一個構造方法,就是無參構造方法,當我們實體化物件時,可以不需要添加引數

animal Tom = new animal();

假如我們書寫的類中沒有寫構造方法,如下

package Class_Study;
public class animal {
	public void roar() {
		System.out.println("I am yelling.");
	}
}

此時,編譯器會自動給我們加上一個無參構造方法,等同于這樣

package Class_Study;
public class animal {
	public animal(){
	}
	public void roar() {
		System.out.println("I am yelling.");
	}
}
有參構造

有參構造方法就是在無參構造的基礎上增添了引數,方便我們將外部的引數傳遞給實體化的物件

我們第一個實體化物件的例子中除了有無參構造方法,還有有參構造方法

public animal(int num) {
	age = num;  //將外部的引數num賦值給物件內部的age
    System.out.println("My age is "+ age); //將age的值輸出到控制臺上
}

因為是有參構造方法,我們實體化時可以加引數

int age = 3;
animal Tom = new animal(age); 
//由于作用域的不同,我們在main函式中定義的age并不與animal物件中的age相沖突

注意

當我們既沒有寫無參構造也沒有寫有參構造時,編譯器會自動給我們加上一個無參構造方法,

但如果我們自己寫了有參構造方法無參構造方法任意一個以后,編譯器不會自動添加無參構造方法

物件方法

上面也提到了,在類物件中函式叫做方法method, 除了叫法不同,各種功能與函式一致

package Class_Study;
public class animal {
	private int age;
    public animal(){
	}
    public animal(int num) {
		age = num;
		System.out.println("My age is "+ age);
	}
	public void roar() {
		System.out.println("I am yelling.");
	}
}

在animal類中,roar就是物件方法,使用roar方法必須通過animal的實體化的物件來呼叫

public class animalTest {
	public static void main(String[] args) {
		animal Tom = new animal(3);
		Tom.roar();
	}
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-pGFaF1y5-1613061611847)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210131113112130.png)]

因為在實體化程序中使用了有參構造方法,有參構造方法中有一行指令是列印age: "System.out.println("My age is “+ age);” 所以在控制臺中出現 My age is 3

我們通過Tom來呼叫類方法

Tom.roar();

所以程式執行此方法,在控制臺中列印 “I am yelling”

this關鍵字

this關鍵字可以用于在本類中呼叫,本類方法或實體變數; 它也可以用于呼叫本類中其他構造方法;

this可以理解為當前物件

一個一個分析;

  1. 實體變數

當我們方法中的形參與類物件中的引數名字一樣時,使用this關鍵字可以避免運行時的error,如下

沒有使用this 關鍵字時

public class animal {
	private int age;
	public animal(){
		System.out.println("I am an animal.");
	}
	public animal(int age) {
		age = age;
		
	}
	public void printAge() {
		System.out.println("My age is "+ age);
	}
	public void roar() {
		System.out.println("I am yelling.");
	}
	
}
public class animalTest {
	public static void main(String[] args) {
		animal Tom = new animal(3);
		Tom.printAge();
	}
}

此時的編譯器

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-EtV3iFye-1613061611848)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210131115030599.png)]

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-uVx1YGRR-1613061611849)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210131184425189.png)]

為什么我們輸的是3,而列印的卻是0 ?因為我們并沒有將值真正賦給物件的age

為了避免這種無效賦值的情況,我們需要使用this

this的作用相當于告訴編譯器,你要把我傳進的引數age賦值給類物件的age,然后呼叫類物件的age列印輸出

public class animal {
	private int age;
	public animal(){
		System.out.println("I am an animal.");
	}
	public animal(int age) {
		this.age = age;
	}
    public void printAge() {
		System.out.println("My age is "+ this.age);
	}
	public void roar() {
		System.out.println("I am yelling.");
	}
	
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-dchxMTLs-1613061611850)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210131184639113.png)]

  1. 本類方法

為了表示方便,在本類中呼叫本類方法,可以在呼叫的方法前加上this

public class animal {
	private int age;
	public animal(){
		System.out.println("I am an animal.");
	}
	public animal(int age) {
		this.age = age;
		System.out.println("My age is "+ this.age);
	}
	public void roar() {
		System.out.println("I am yelling.");
		this.Hungry(); 
	}
	public void Hungry() {
		System.out.println("I am hungry!!");
	}
	
}

這個this加或不加都沒關系,編譯器會幫我們自動加上

  1. 呼叫本類的其他構造方法

this可以呼叫構造方法,這樣能避免相同初始化代碼

this()是用來呼叫無參構造方法的

沒加this()

public class animal {
	private int age;
	public animal(){
		System.out.println("I am an animal.");
	}
	public animal(int age) {
		this.age = age;
		
	}
	public void printAge() {
		System.out.println("My age is "+ this.age);
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-zvACJehR-1613061611851)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210131185804560.png)]

加上this();

public class animal {
	private int age;
	public animal(){
		System.out.println("I am an animal.");
	}
	public animal(int age) {
		this(); //必須方法構造方法最前面
		this.age = age;
		
	}
	public void printAge() {
		System.out.println("My age is "+ this.age);
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ZwmzIw2j-1613061611852)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210131185909356.png)]

可見,加上this()就呼叫了animal的無參構造方法

注意,this();必須在呼叫的方法最前面

this(a); 可以呼叫有參構造方法, a是有參構造需要的引數,例子如下

public class animal {
	private int age;
	public animal(){
		this(3);
		System.out.println("I am an animal.");
	}
	public animal(int age) {
		this.age = age;
		
	}
	public void printAge() {
		System.out.println("My age is "+ this.age);
	}
}
//測驗類
public class animalTest {
	public static void main(String[] args) {
		animal Tom = new animal();
		Tom.printAge();
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-apcvmb6p-1613061611853)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210131190535142.png)]

我們直接呼叫animal的無參構造,但是age是有初始值的,就是我們在無參構造中this(3);傳入的age,

方法多載Overload

方法可以多載,當然之前學習的函式也可以多載;多載后的方法可以接收不同引數

所謂的多載Overload針對同一個類,在這個類里面可以包含名字相同但是接收引數不同的的方法,例子如下,


public class animal {
	private int age;
	public animal(){
		System.out.println("I am an animal.");
	}
	public animal(int age) {
		this();
		this.age = age;
		
	}
	
	public void printAge() {
		System.out.println("My age is "+ this.age);
	}
	//對printAge進行Overload
	public void printAge(int year) {
		this.age += year;
		System.out.println("After "+year+" years. My age is "+this.age);
	}	
}

public class animalTest {
	public static void main(String[] args) {
		animal Tom = new animal(3);
		Tom.printAge();
		Tom.printAge(4);
	}
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-9I3kwb1h-1613061611854)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210131195018061.png)]

其實方法的多載就像無參構造方法與有參構造方法一樣

物件封裝

封裝,顧名思義將資料封起來,不讓外界輕易訪問,在java開發時,我們有時不希望外界訪問或改變我們設計好的資料,此時需要將這些資料封裝起來,

為了封裝資料,我們需要一些訪問修飾符,例如public, private(這些在前面大家應該已經遇到了,但是不知道是什么)

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-vVjr7yf7-1613061611855)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210131201852288.png)]

一般用訪問修飾符時,都用public 或 private ,public定義的資料都可以訪問,但是private的只有本類才能訪問

封裝可以使資料更安全,假如說想要獲取或改變資料,可以使用get, set, 例子如下

public int getAge() {
	return age;
}
public void setAge(int age) {
    //有set的好處就是,假設在給age賦值時傳入的時string型別或其他型別,set里面可以加上判斷
	this.age = age;
}

物件繼承

介紹

聊完上面幾章,我們進入物件中比較重要的環節,物件繼承,這就像兒子與父親一樣,所以被繼承的類大家稱為父類,繼承的類稱之為子類

子類對于父類的繼承

  1. 子類繼承父類所有public方法與屬性, 也可以添加自己獨有的方法
  2. JAVA繼承遵循單一繼承關系, 即一個子類只能繼承一個父類
  3. 當子類添加自己方法時可以對父類方法進行覆寫, override, 例如父類可以使用a方法,子類繼承a方法,可以再寫一遍a方法,使a方法實作另一種
//繼承語法: 

class B extends A{      } //B是子類, A是父類, 子類繼承父類

例子

package Class_Study;
//animal是父類
public class animal {
	private int age;
	public animal(){
		System.out.println("I am an animal.");
	}
	public animal(int age) {
		this.age = age;
		System.out.println("My age is "+ this.age);
	}
	public void roar() {
		System.out.println("I am yelling.");
	}
	
}
package Class_Study;

public class TestForAnimal {
	public static void main(String[] args) {
		Dog kit = new Dog();
		kit.roar();
	}
}
class Dog extends animal{
	Dog(){
		System.out.println("I am a dog.");
	}
	//方法覆寫override
	public void roar() {
		//super.roar();這個super關鍵字后面再講
		System.out.println("I am hungry. I need meat");
	}
}

在實體化子類物件時,我們會先呼叫父類的默認構造方法,再呼叫子類的構造方法,

這就是為什么會出現"I am an animal"

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-zzGaJQ6b-1613061611856)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210131234622162.png)]

在上面這個例子中,dog類是animal類的子類,它繼承了父類的方法

Dog kit = new Dog(); //實體化子類物件,呼叫子類的無參構造方法

在具有繼承關系的創建中,系統先創建父類再創建子類, 如果有默認的構造方法, 先呼叫父類A的默認無參構方法,再呼叫子類B的所屬構造方法, 這就是為什么我們呼叫dog類的無參構造方法時,先列印“I am an animal.”,再列印“I am a dog.”

//方法覆寫override
	public void roar() {
		System.out.println("I am hungry. I need meat");
	}

在子類中,子類擁有與父類相同的方法,這樣可以對父類的方法進行覆寫,(方法的Override必須是方法一樣)(即訪問修飾符+回傳值型別+名稱+傳入引數型別一樣)

多型

世間萬物都有屬于自己的類,這些類之間又可以進行分類,例如汽車,飛機等可以被分在(繼承)交通工具類里面;老師,學生,家長可以被分在(繼承)人這個類里面,我們可以用交通工具類或人類來作為汽車或學生寬泛的表示方法,

  1. 使用父類作為方法形參實作多型, 使方法引數型別更為寬泛
  2. 使用父類作為方法回傳值實作多型, 使方法可以回傳不同子類物件

例子: A a = new B(); A是B的父類

使用多型時,只能使用父類的方法或子類覆寫父類的方法, 例如

//例子
package Class_Study;

public class animal {
	private int age;
	public animal(){
		System.out.println("I am an animal.");
	}
	public animal(int age) {
		this.age = age;
		System.out.println("My age is "+ this.age);
	}
	public void roar() {
		System.out.println("I am yelling.");
	}
	
}
package Class_Study;

public class TestForAnimal {
	public static void main(String[] args) {
		animal kit = new Dog();
		kit.roar(); // 作為父類的kit只能呼叫子類覆寫后的方法或自己本身的方法
	}
}
class Dog extends animal{ //狗類繼承了父類animal類,覆寫了roar()這個方法
	Dog(){
		System.out.println("I am a dog.");
	}
	//方法覆寫override
	public void roar() {
		System.out.println("I am hungry. I need meat");
	}
	public void run() {
		System.out.println("I can use four legs to run!!");
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-R2PomW1Q-1613061611856)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210202104457940.png)]

假設我們作為父類,再呼叫子類的方法,例如這個:用kit animal類呼叫dog子類的run方法,出現錯誤

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-I5o8Lhwj-1613061611857)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210202104550114.png)]

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-OCuMepQD-1613061611858)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210202104646229.png)]

向上轉型

格式

//Animal類是Dog類的父類
Animal a = new Dog()

剛才上面那個例子就使用了向上轉型的方法(子類轉為父類),

向下轉型

向下轉型前提是 原來實體是子類(先向上轉型):

Animal a = new Dog()    
Dog dog = (Dog) a //利用強轉向下轉型

多型的好處是有很強的擴展性,例如這樣

speak(new Cat());
speak(new Dog());//此時我們將cat類與dog類作為引數傳進去
public void speak(Animal a){
    a.roar(); //函式會自動向上轉型,呼叫cat與dog類中Override父類Animal的roar方法
}

instanceof關鍵字

向下轉型前,應判斷參考中物件的真實型別,以達到準確性

語法, (dog instanceof animal)//回傳結果為boolean

if (args instanceof type) {
	type new_name = (type) args;		
}
package Class_Study;

public class TestForAnimal {
	public static void main(String[] args) {
		animal animal = new Dog();
		if (animal instanceof Dog) { //判斷animal的真實型別是否是Dog類,是的話進行向下轉型
			Dog dog = (Dog) aanimal;
			dog.run();
		}
	}
}


class Dog extends animal{
	Dog(){
		System.out.println("I am a dog.");
	}
	//方法重寫override
	public void roar() {
		System.out.println("I am hungry. I need meat");
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-xQxxYVnP-1613061611859)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210202115137520.png)]

super關鍵字

作為子類,我們繼承了父類的方法,但當我們繼承父類后并Override父類方法后,我們就不能再使用父類的方法,為了能再次使用,我們需要使用super關鍵字

和this()一樣,super()必須是第一條陳述句

可以呼叫父類的屬性和方法

super.upload() // 父類的方法
super.value //父類的屬性,注意這個屬性必須是public公共屬性,私有屬性無法繼承

例子,呼叫父類屬性

public class Value {
	public static void main(String[] args) {
		B b =new B();
		b.print();
	}
}
class A{
	int value =10;
}

class B extends A{
	int value = 20;
	public void print() {
		int value =30;
		System.out.println(value);  //就近原則,選取本方法中的value
		System.out.println(this.value); //this呼叫本類中的value
		System.out.println(super.value);//super呼叫父類中的value
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Rhj3h0qR-1613061611859)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210202121542748.png)]

例子,呼叫父類的方法

package Class_Study;
//父類
public class animal {
	private int age;
	public animal(){
	}
	public animal(int age) {
		this.age = age;
		System.out.println("My age is "+ this.age);
	}
	public void roar() {
		System.out.println("I am yelling.");
	}
	
}
package Class_Study;
//子類
public class TestForAnimal {
	public static void main(String[] args) {
		Dog dog = new Dog();
		dog.roar(); 
	}
}


class Dog extends animal{
	Dog(){
		System.out.println("I am a dog.");
	}
	//方法重寫override
	public void roar() {
		super.roar(); //通過super呼叫父類的roar方法
		System.out.println("I am hungry. I need meat");
	}
	
	public void run() {
		System.out.println("I can use four legs to run!!");
	}
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ObOJS1cO-1613061611860)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210202122338431.png)]

super也可以呼叫父類構造方法

super() // 呼叫無參構造方法
super(5, 6) //呼叫有參構造方法

在繼承章節開頭我們碰見的那個例子里面,當呼叫我們呼叫子類構造方法時,系統會自動呼叫父類的無參構造方法,即在子類無參構造之前加上super();如下

package Class_Study;
//父類
public class animal {
	private int age;
	public animal(){
        //父類的無參構造
		System.out.println("I am an animal.");
	}
	public animal(int age) {
		this.age = age;
		System.out.println("My age is "+ this.age);
	}
	public void roar() {
		System.out.println("I am yelling.");
	}
	
}
package Class_Study;
//子類
public class TestForAnimal {
	public static void main(String[] args) {
		Dog dog = new Dog();
	}
}


class Dog extends animal{
	Dog(){
		super();
		System.out.println("I am a dog.");
	}
	//方法重寫override
	public void roar() {
		super.roar();
		System.out.println("I am hungry. I need meat");
	}
	
	public void run() {
		System.out.println("I can use four legs to run!!");
	}
}

加上super()

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-0Ggqw58j-1613061611862)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210202122732411.png)]

沒加super()

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-gnFoirY4-1613061611862)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210202122802897.png)]

編譯器默認調父類無參構造方法(在沒加super()的前提下),不管子類呼叫的是否是無參還是有參構造

當C物件繼承B物件,B物件繼承A物件時,實體化C物件,先呼叫A的無參構造,然后呼叫B的無參構造,最后呼叫C的無參構造

//子類呼叫父類的有參構造
Dog(){
	super(3); //在Dog子類的無參構造方法中,呼叫父類的有參構造
	System.out.println("I am a dog.");
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-2ZfTYONx-1613061611862)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210202123738106.png)]

物件是參考型別

為什么說物件是參考型別?

我們new一個物件,其實是用一個指標指向這個部分資料集合,例子如下

//創建一個Point類,有x,y值
public class Point {
	private int x;
	private int y;
	public void SetPoint(int x, int y){
		this.x =x;
		this.y =y;
	}
	public void show() {
		System.out.println("("+this.x+" , "+this.y+")");
	}
}

public class TestPoint {
	public static void main(String[] args) {
		//實體化一個Point類
        Point a = new Point();
        //將a點的地址傳入SetPoint函式
		SetPoint(a);
        //如果物件不是參考型別,a點的x,y值就不會改變
		a.show();
	}
	public static void SetPoint(Point b) {
		b.SetPoint(5, 5);
	}
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Ko0rP80P-1613061611862)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210202215944627.png)]

上面例子的box diagram

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-HQCsyKc1-1613061611863)(C:\Users\23881\OneDrive - Rose-Hulman Institute of Technology\未命名.jpg)]

包裝類

由于基本型別不是物件,在萬物皆物件的JAVA中,我們有時需要將這些資料封裝成物件,這就是包裝類

基本資料包裝類
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

基本型別封裝的好處

  1. 方便進行物件操作
  2. 便于資料與字串之間的轉換

例如:將數字1轉為字串1,再將字串1轉為數字1

public class NumDemo1
{
	public static void main(String[] args) 
	{
		int i =1;
        //把基本資料int封裝成Integer
		Integer num = new Integer(i);
        //數字轉為字串
		String word = num.toString();
        //列印轉成的型別
		System.out.println(word.getClass());
        //將字串轉為數字,列印轉成的型別
		System.out.println(Integer.valueOf(word).getClass());
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ikgqHyJ3-1613061611864)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210209194231137.png)]

JAVA字串

在前面大家已經不止一次接觸到了字串String型別資料,String字串是一個功能強大的類,它可以將多個字符放在一起,如下

char word = 'h';
String words = "hello world";

字串與字符有一點區別:字串內容放在雙引號內,而字符則是單引號,

特點

  1. 字串是常量,創建后不可改變
  2. 字串字面值儲存在字串池中,可以共享
  3. String str = new String(“Java”)在堆里面創建一個物件

常用方法

public int length() //回傳字串長度
public char charAt(int index) //根據下標獲取字符
public boolean contains(String str) //判斷當前字串是否包含傳進去的字符str
public int indexOf(String str)//查找str首次出現的下標,存在則回傳該下標,不存在則回傳-1
public int lastIndexOf(String str)//查找字串當中最后出現的下標索引
public String trim()//去除字串前后的空格
public String toUpperCase()//全部轉為大寫
public boolean endWith(String str)//判斷字串是否是以str結尾
public boolean startWith(String str)//同樣,也有以str開頭的判斷
public String replace(char oldChar, char newChar)//將原來舊的字串替換為新的字串
public String concat(String s)//回傳連接后的字串, s是加在后面的字串
public String substring(int beginIndex, int endIndex)//回傳一個分割過后的字串
public char[] toCharArray()//將字串轉換成陣列
Arrays.toString(char[] string)//為了將陣列內的字符列印出來,呼叫Arrays工具類

下面用一串代碼來演示如何使用這些方法

package StringStudy;

import java.util.Arrays;//為了把陣列中的內容轉成字串并列印出來

public class Demo1 {
	public static void main(String[] args) {
		String words = "hello";
        System.out.println(words);
		words = "world";
		System.out.println(words);
		String str = new String("Java");
		String str2 = new String("Java");
		System.out.println("str與str2是否在同一地址:"+(str == str2));
		System.out.println("str與str2是否內容完全相同"+str.equals(str2));
		System.out.println("words在第一個的字串是:"+words.charAt(0));
		System.out.println("將words轉化為陣列后的	  Array:"+Arrays.toString(words.toCharArray()));
		System.out.println("將words轉化為陣列后的Array[0]:"+words.toCharArray()[0]);
		System.out.println("判斷words中是否含有w:"+words.contains("w"));
		System.out.println("判斷words中是否含有wd:"+words.contains("wd"));
		System.out.println("回傳對應字串rd的下標:"+words.indexOf("rd"));
		words = "hello";
		System.out.println("回傳對應字串l的下標:"+words.indexOf("l"));
		System.out.println("回傳對應字串l最后的下標:"+words.lastIndexOf("l"));
		String student = " Peter Bear ";
		System.out.println("After deleting SPACE in String----"+student.trim()+"----");
		System.out.println("將字母全部改為大寫:"+student.toUpperCase());
		System.out.println("將原來的字串中的內容進行替換:"+student.replace("ear", "ear is 18 years old."));
		String website = "www.peterbear.com";
		System.out.println("回傳在原來的字串后面增添內容的字符出:"+student.concat("'s website: ").concat(website));
		
		
	}
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-SPyl6PwK-1613061611865)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210202231723332.png)]

JAVA修飾符

再類物件封裝中我們提到的private, public屬于JAVA的訪問修飾符;在本章我們將介紹其他的修飾符:非訪問修飾符

static

static中文翻譯是靜態,所以關于static 的方法和屬性叫做靜態屬性和靜態方法

使用靜態修飾符后程式會發生哪些變化?

  1. 靜態屬性和方法利用類名進行呼叫(假如說一個類僅含有static成員,那么這個類被稱作工具類)

  2. 靜態成員是全類所共享的成員

  3. static 關鍵字用來宣告獨立于物件的靜態變數(靜態屬性),無論一個類實體化多少物件,它的靜態變數只有一份拷貝, 靜態變數也被稱為類變數,區域變數不能被宣告為 static 變數,

//靜態屬性
static int count=10;

例子如下

package modifier;
//創建一個類,這個類有靜態屬性與非靜態屬性,含靜態方法與非靜態方法
public class StaticStudy {
	public int cnt=0; //非靜態屬性
	public static int cnt2=0; //靜態屬性,靜態變數
	public void add() {
		cnt++;
	}
    public static void add2() {
		cnt2++;
	}
	public void show() {
        //因為靜態成員是全類所共享的成員,所以非靜態方法可以呼叫靜態成員變數
		System.out.println("非靜態計數器"+cnt);
		System.out.println("靜態計數器: "+cnt2);
	}
}
package modifier;

public class TestStatic {
	public static void main(String[] args) {
		StaticStudy num = new StaticStudy();//實體化一個類物件
		num.show();//初始值,呼叫show非靜態方法
		num.add();
		StaticStudy.add2();//通過類名呼叫靜態方法
		num.show();//add后的值
		System.out.println("類名呼叫靜態屬性: "+StaticStudy.cnt2);//類名呼叫靜態屬性
		System.out.println("----實體化第二個物件"+"----");
		StaticStudy num2 = new StaticStudy();//再實體化一個類物件
		num2.add();
		StaticStudy.add2();
		num2.show();
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-3pDt1S75-1613061611866)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210203133932014.png)]

從上面例子我們不難發現無論一個類實體化多少物件,它的靜態變數只有一份拷貝,

未命名 2

靜態方法

特點

  1. 靜態方法可以直接訪問靜態成員
private static int cnt3=0;
public static int cnt2=0; //靜態屬性,靜態變數 
public static void add2() { //靜態方法給cnt2加一
		cnt2++;
	}
  1. 但是靜態方法不能直接訪問非靜態成員

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-sc5hPlgF-1613061611867)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210203125411520.png)]

  1. 靜態方法不能使用this和super關鍵字

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ARoVq8mg-1613061611867)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210203134731231.png)]

  1. 靜態方法不能重寫,只能繼承,沒有多型

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-PGG1TWGV-1613061611868)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210203135945647.png)]

靜態代碼塊

static{      }
//整個程式執行程序中,只執行一次
//可以執行一些必要的初始化行為

//與其相反的是非靜態代碼塊
{
    
}

靜態代碼塊中只能放靜態成員

系統初始化程序:靜態代碼塊---->main函式---->非靜態代碼塊---->建構式

這里請參考下面的鏈接

靜態類

倘若一個類是靜態的,它一定是靜態內部類//這個在講到內部類的時候再具體分析

final

final意為最終的,最后的,即不可變的

最終類

final修飾的不能被繼承, 例如String, Math,System類,這些類的均無法被繼承

當FinalStudy準備繼承Point類時,由于Point類是被final修飾,所以無法被繼承

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-op8xRSgo-1613061611868)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210203144245874.png)]

最終變數

final int num = 10;
final static string address = "school";

只能被賦值一次(常量)
1. 在構造方法中賦值
如果有一個對常量賦值,其他的構造方法都要對其進行賦值
2. 創建常量時直接賦值

我們創建了一個Point類,使用final修飾了原點,當我們想要改變原點資料時,失敗

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-jvHcb2d3-1613061611870)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210203145808713.png)]

對于最終變數有兩種初始化方法,

第一種:直接創建時就賦值

final int Origion_x=0;
final int Origion_y=0;

第二種:使用代碼塊進行賦值

final int Origion_x;
final int Origion_y;
{
	Origion_x=0;
	Origion_y=0;
}

第三種:在構造方法中

final int Origion_x;
final int Origion_y;
Point(){
	Origion_x=0;
	Origion_y=0;
}

倘若變數用static + final修飾,為靜態常量,初始化要在靜態代碼塊中進行

第一種:直接創建時就賦值

static final int Origion_x=0;
static final int Origion_y=0;

第二種:使用代碼塊進行賦值

static final int Origion_x;
static final int Origion_y;
static{
	Origion_x=0;
	Origion_y=0;
}

最終方法

不能被子類覆寫或者重寫,只能繼承

我們給父類的Print方法加上final修飾后,子類FinalStudy無法Override Print方法,所以只能繼承該方法

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-zfanjxGD-1613061611870)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210203144655295.png)]

例子如下

package modifier;

public class FinalStudy extends Point{
	
}

class Point{
	private int x;
	private int y;
	public void SetPoint(int x, int y) {
		this.x =x;
		this.y =y;
	}
	
	public final void Print() {
		System.out.println("( "+this.x+", "+this.y+" )");
	}
}
package modifier;
//測驗
public class TestFinal {
	public static void main(String[] args) {
		FinalStudy point = new FinalStudy();
		point.SetPoint(1, 2);
		point.Print();
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Jlc1QG5v-1613061611871)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210203145143119.png)]

物件常量

final修飾基本型別:值不可變

final 修飾參考型別:地址不可改變

例子如下

class Point{
	private int x;
	private int y;
	static final int Origion_x;
	static final int Origion_y;
	static{
		Origion_x=0;
		Origion_y=0;
	}
	public void SetPoint(int x, int y) {
		this.x =x;
		this.y =y;
	}
	
	public void Print() {
		System.out.println("原點: "+"( "+Origion_x+", "+Origion_y+" )");
		System.out.println("( "+this.x+", "+this.y+" )");
	}
}
package modifier;

import java.util.Arrays;

public class TestFinal {
	public static void main(String[] args) {
		final int[] nums = new int[] {1,3,5,7};
		System.out.println(Arrays.toString(nums));
//		nums = new int[] {5,6,7};//此時不能對nums再進行賦值,因為已經nums已經變成了常量
		nums[0] = 9; //但是nums內部的資料可以進行更改,因為nums是參考型別
		System.out.println(Arrays.toString(nums));
		final Point p1 = new Point();
		p1.SetPoint(6, 6);
		p1.Print();
		p1.SetPoint(10, 10);
		p1.Print();
	}
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-vMvOHovl-1613061611871)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210203154357345.png)]

abstract

abstract中文意思是抽象,抽象即為不具體

抽象類

一個類不能同時被abstract和final修飾

當類物件沒有具體的含義,可以將該類改為抽象類

例如Animal類,它本身沒有任何意義各種方法比較抽象,但是繼承Animal類的子類Dog類和Cat類有意義,所以要把Animal類改為抽象類

作用

  1. 可以被子類繼承,提供共性的屬性和方法
  2. 可以宣告為參考,更自然的使用多型

抽象類當中可以包含抽象方法,也可以包含非抽象方法

//語法:
public abstract class Animal{  }

如果一個類被改為抽象類,該類就不可以被實體化, 即不能new 物件;但是我們能夠用這個類來作為參考,就像多型向上轉型一樣

下面是一個關于抽象類的例子

package modifier;

public class TestAbstract {
	public static void main(String[] args) {
		Dog dog = new Dog();
		dog.speak();
		Animal bird = new Bird(); //可以宣告為參考,更自然的使用多型
		bird.speak();
        //dog和bird呼叫父類的walk方法
        dog.walk();
		bird.walk();
	}
}


abstract class Animal{
	public abstract void speak();
	public abstract void move();
    //抽象類中包含非抽象方法
    public void walk() {
		System.out.println("I am walking");
	}
}

class Dog extends Animal{
	@Override
	public void speak() {
		System.out.println("Wang Wang Wang……");
		
	}

	@Override
	public void move() {
		System.out.println("Dog uses his four legs to run");
		
	}
}

class Bird extends Animal{

	@Override
	public void speak() {
		System.out.println("Yin Yin Yin……");
		
	}

	@Override
	public void move() {
		// TODO Auto-generated method stub
		
	}
	
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-5xEga0Yh-1613061611872)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210203162947766.png)]

抽象方法

一但類當中包含抽象方法,此類必須是抽象類

父類物件的方法本身沒有意義,但為了實作多型(向上轉型)又不得不保留

Animal dog = new Dog();
dog.eat();

抽象方法只有方法的宣告,沒有方法實作,此外抽象方法只能在抽象類當中

//格式
public abstract void eat();

子類繼承父類,子類必須重寫父類的抽象方法,否則子類必須是抽象類

//抽象的felid貓科動物類繼承抽象的動物類,其中增添了抽象的貓科動物捕獵方法
abstract class felid extends Animal{
	abstract void hunt();
}

抽象類與抽象方法的小案例:

建立一個Vehicle的交通工具抽象類和一個主人類,列印主人回家時開的什么車,是什么品牌

package Polymophic_And_Abstract;

public class Master {
	private final String name; //將主人的名字封裝起來
	public Master(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	
	public void GoHome(Vehicle vehicle) {
		System.out.println(this.getName()+"回家了");
		vehicle.run();
	}
}
package Polymophic_And_Abstract;

public class TestForVehicle {
		public static void main(String[] args) {
			Master jim = new Master("Jim");
			Vehicle car = new Car("奔馳");
			jim.GoHome(car);
	}
}

//創建一個抽象的Vehicle類
abstract class Vehicle {
	private final String band;
	public Vehicle(String band) {
		this.band = band;
	}

	public String getBand() {
		return band;
	}
    //一個抽象方法
	public abstract void run();
	
}
//Car繼承抽象的Vehicle交通工具類
class Car extends Vehicle{
	
	public Car(String band) {
		super(band);
	}
//implements 實作run()方法
	@Override
	public void run() {
		System.out.println(super.getBand()+"牌的車在路上跑");
	}
	
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-LD8zFs2k-1613061611872)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210203170116415.png)]

JAVA介面

介紹

介面相當于是特殊的抽象類,定義方法,組成部分與抽象類類似

介面沒有構造方法,所以不能創建物件但是可以implements,一個類可以實作多個介面,例如

C extends A implements B implements C

介面也可以和父類一樣實作多型(向上轉型)
僅可呼叫介面中實作的方法,不能呼叫實體化物件所獨有的方法

介面往往可以代表一種能力,一但類物件實作了該介面,它也具備了這種能力

實作介面時,訪問修飾符必須是public

介面與抽象類相同之處:

  1. 可編譯成位元組碼檔案
  2. 不能創建物件
  3. 可以作為參考型別 // 當作為參考型別時,僅可呼叫實作了的介面;
  4. 具有Object類中定義的方法(Object類是所有類物件的父類)

不同之處:

  1. 介面所有屬性都是用public static final修飾
  2. 介面所有方法都是用public abstract 修飾
  3. 介面沒有構造方法,動態代碼塊和靜態代碼塊

類無法使用多繼承,但是介面可以實作多繼承介面

package Interface;

public interface Ability extends flyable, swimmable{
	public abstract void fire();
}

interface flyable{
	public abstract void fly();
}

interface swimmable{
	public abstract void swim();
}

interface關鍵字

類物件是class,而介面則是interface

public interface A{ 
    public static final String  FIELD = "Value"  
    public abstract void method(); 
}

注意

介面只能定義:公開靜態常量 和***公開抽象方法***

public static final String FIELD="Value"; //公開靜態常量,使用時,直接用介面進行呼叫
public abstract void method();//公開抽象方法只用寫回傳值型別和方法名

類一但implement就必須實作覆寫介面中全部抽象方法,此類就是該介面的實作類

補充

標記介面,例如Serializable介面

public interface Serializable{}; //表示實作這個介面的物件可以被序列化和克隆
public interface Cloneable{};

案例

  1. 給人實作飛的能力
//先創建fly的介面
package Interface;

public interface fly {
	public abstract void fly();
}
//然后創建一個人類,來實作fly介面
package Interface;

public class Person implements fly{
	String name;
	int age;
	Person(String name, int age){
		this.name= name;
		this.age = age;
	}
	public void eat() {
		System.out.println(this.name+" 在吃飯……");
	}
	public void sleep() {
		System.out.println(this.name+" 在睡覺……");
	}
    //由于繼承了介面,我們必須實作介面的方法
	@Override
	public void fly() {
		System.out.println(this.name+" can fly");
		
	}
}
//寫一個測驗類
package Interface;

public class TestPerson {
	public static void main(String[] args) {
		Person jim = new Person("Jim",20);
		jim.fly();
        //利用介面作為參考型別
		fly baby = new Person("baby", 30);
		baby.fly();
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-BKnAsRfa-1613061611874)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210203194232960.png)]

  1. USB案例

USB介面是大家熟知的一種介面,風扇,U盤,都是USB介面,我們要將USB介面插入電腦

//1先創建USB介面
package USB_Interface;

public interface USB {
	public abstract void Service();
}
//2實作Fan,U盤的介面
//U盤
public class USB_Flash implements USB {

	@Override
	public void Service() {
		System.out.println("USB-Flash has connected to the computer");
		
	}
	
}
//風扇
public class Fan implements USB{

	@Override
	public void Service() {
		System.out.println("Fan starts to run");
		
	}
	
}

//3由于我們要將U盤和風扇插入電腦中,所以要創建一個電腦類
package USB_Interface;

public class Computer {
	private USB usb1;
	private USB usb2;
	
	public USB getUsb1() {
		return usb1;
	}

	public void setUsb1(USB usb1) {
		this.usb1 = usb1;
	}

	public USB getUsb2() {
		return usb2;
	}

	public void setUsb2(USB usb2) {
		this.usb2 = usb2;
	}

	public void Run() {
		System.out.println("Computer starts to work!!");
		if(this.getUsb1() != null) {
			usb1.Service();
		}
		if(this.getUsb2() != null) {
			usb2.Service();
		}
	}
	
}
//4最終的測驗類
package USB_Interface;

public class Test_USB {
	public static void main(String[] args) {
		Computer Windows = new Computer();
		Windows.setUsb1(new Fan());
		Windows.setUsb2(new USB_Flash());
		Windows.Run();
	}
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-3MSfafuL-1613061611874)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210203200029587.png)]

JAVA內部類

創建在類內部的類叫做內部類,

class Outer{
    //外部類
	class Inner{
	//內部類
	}
}

內部類擁有和普通類一樣的屬性,可以擁有方法,能夠去實作介面,繼承

如果外部類與內部類成員屬性名字相同,則優先訪問內部類成員
如果想要訪問同名外部類成員,需要先寫上外部類名字,再this.name,或直接Outer.this.name

既然已經有了外部類,那為什么還要內部類呢?

好處

  1. 內部類可以對外部類全部內容進行訪問
  2. 方便訪問外部類的私有屬性(內部類可直接訪問外部類的私有成員而不破壞封裝)

成員內部類

package InnerClass;

import InnerClass.OuterClass.InnerClass;

public class NormalInnerTest {
	public static void main(String[] args) {
		//1. 第一種實體化內部類的方法
        //OuterClass outer = new OuterClass();
		//InnerClass inner = outer.new InnerClass();
        
        //2. 第二種實體化內部類的方法,一步到位
        InnerClass inner = new OuterClass().new InnerClass();
		inner.print();
	}
}

class OuterClass{
	private String words="Outer Class";
	class InnerClass{
		public void print() {
			System.out.println(OuterClass.this.words);
			new OuterClass().print();
			System.out.println("Inner Class: Hello World");
		}
	}
	public void print() {
		System.out.println(words+": Hello World");
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-hkMTS7sx-1613061611875)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210204213254151.png)]

成員內部類不能定義靜態成員

靜態內部類

靜態內部類可以不依賴外部類物件實體化物件

只有靜態內部類可以用static修飾

//實體化靜態內部類
Outer.Inner StaticInnerDemo =new Outer.Inner();

案例

package InnerClass;


class Outer{
    //外部類中包含靜態成員變數與非靜態成員變數
	private static String inf = "Hello World";
	private String inf2 = "GoodBye World";
	
    //創建靜態內部類
	public static class Inner{
        //靜態內部類里面包含靜態方法與非靜態方法
		private static void print() {
			System.out.println("\t靜態成員變數: "+inf);
			//靜態內部類無法直接呼叫非靜態變數
//			System.out.println(inf2);
//由于外部類成員變數為私有,需要借助外部類來訪問
			Outer out = new Outer(); 
			System.out.println("\t非靜態成員變數: "+out.inf2);
		}
        //非靜態方法
		public void print2() {
			System.out.println("\t非靜態方法呼叫靜態成員變數: "+inf);
		}
	}
	//普通內部類
	public  class Inner2{
        //普通成員內部類無法創建靜態方法
		public void print() {	
            //但是可以呼叫外部類中的靜態成員變數
			System.out.println("\t靜態成員變數: "+inf);
			System.out.println("\t非靜態成員變數: "+inf2);
		}
		
	}
    
	//外部類能夠創建非靜態方法
	public void fun() {
        //在外部類的方法中實體化內部類
		Inner innerDemo = new Inner();
		System.out.println("靜態內部類的靜態方法");
        //直接通過內部類類名訪問靜態方法
		Inner.print();
		System.out.println("靜態內部類的非靜態方法");
        //訪問內部類非靜態方法需要通過實體化的物件來訪問
		innerDemo.print2();
	}
	

	
}
public class InnerClassDemo1 {
	public static void main(String[] args) {
		//實體化靜態內部類
		Outer.Inner StaticInnerDemo =new Outer.Inner();
		//實體化普通內部類
		Outer shell = new Outer();
        shell.print();
		Outer.Inner2 NormalInnerDemo = shell.new Inner2();
		System.out.println("靜態內部類的非靜態方法");
		StaticInnerDemo.print2();
		System.out.println("普通內部類的方法");
		NormalInnerDemo.print();
	}
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-470Blw7C-1613061611875)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210204215906597.png)]

區域內部類

把一個類定義在方法內部,這個類叫做區域內部類,就像定義在方法中的變數叫區域變數一樣

區域內部類不能定義訪問修飾符,即不能定義為static

但是可以包含靜態常量,private final static int count =2000;

public void fun(final String temp){
	class Inner{
		public void print(){
                System.out.println(info);
                System.out.println(temp);
            }
 	 }
		//實體化內部類,呼叫內部類方法
        new Inner().print();
}

匿名內部類

在java中處理內部類之外,還有一種匿名內部類,

匿名內部類就是指沒有一個具體名稱的類,此概念是在介面和抽象類的應用上發展起來的,

有時這種類只用一次,命名又可惜,所以就使用匿名內部類

以之前寫的Ability介面為例

//介面
package InnerClass;

public interface Ability extends flyable{
	public abstract void swim();
}

interface flyable{
	public abstract void fly();
}
package InnerClass;

import Interface.Ability;

public class AnonymousInnerClass {
	public static void main(String[] args) {
		Ability SuperMan = new Ability(){

			@Override
			public void swim() {
				// TODO Auto-generated method stub
				System.out.println("I can swim");
			}

			@Override
			public void fly() {
				// TODO Auto-generated method stub
				System.out.println("I can fly");
				
			}
			
		};
		SuperMan.swim();
		SuperMan.fly();
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-fPyxVxD5-1613061611875)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210204225913164.png)]

使用匿名內部類時,必須繼承一個父類或實作一個介面

JAVA泛型

JAVA泛型英文generics,

本質是引數化型別,就是把型別作為引數傳遞,泛型物件不能被實體化T type = new T();

這么說大家估計還是覺得這個定義比較抽象,

舉個例子:我們要寫一個排序方法,這個方法能夠對int型別,String型別,double型別都進行排序,此時要使用泛型方法

泛型可以提高代碼的重復性,防止型別轉換例外,提高代碼的安全性

泛型字母含義

E - Element:指集合中的元素

T - Type:Java型別,種類

K - Key:鍵

V - Value:值

N - Number:數值型別

格式

<T,...> //T是型別占位符,是一種參考型別

泛型方法

泛型方法可以接收不同型別的引數,根據傳進去的引數做適當的處理,格式如下

//<T> 宣告此方法為泛型方法, T指出回傳值是泛型T
//Class<T> 指明泛型T的具體型別, c用來創建泛型T代表的類物件
public <T> T getObject(Class<T> c){
    //創建一個泛型物件
    T t = c.newInstance();
    return t;
}

例子,有三個不同型別的陣列,分別列印出其中的值

package GenericsStudy;

public class GenericDemo1 {
	//泛型方法
	public static < E > void printArray(E [] inputArray) {
		//輸出陣列元素
		for (E element : inputArray) {
			System.out.printf("%s ", element);
		}
		System.out.println();
	}
    
	public static void main(String[] args) {
		//創建不同型別陣列
		Integer[] intArray = {1, 2, 3, 4, 5};
		Double[] doubleArray = {1.1, 2.2, 3.3, 4.4};
		Character[] charArray = {'H', 'E', 'L','L','O'};
		System.out.println("整型陣列元素為:");
        //因為是寫在本類里面,所以可以直接呼叫
        //如果是測驗類寫在本類外面,需要通過類名來呼叫靜態方法,
		printArray(intArray);
		
		System.out.println("\n雙精度型陣列元素:");
		printArray(doubleArray);
		
		System.out.println("\n字串陣列元素:");
		printArray(charArray);
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-bNTFMXgx-1613061611876)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210205114935980.png)]

案例2

撰寫一個add方法,傳入不同型別的數字型別,并回傳相加的值,相加的值是double型別

package GenericsStudy;

public class GenericsDemo5 {
    //extends是為了做泛型界定,即泛型T必須是Number的子類
	public static <T extends Number> double add(T num1, T num2) {
		double sum=0.0;
		sum = num1.doubleValue() + num2.doubleValue();
		return sum;
	}
	public static void main(String[] args) {
		System.out.println("double 型別相加:5.5 + 6.7 ="+add(5.5, 6.7));
		System.out.println("int 型別相加:5 + 7 ="+add(5, 7));
		System.out.println("double 與 int 型別相加:5.5+6 ="+add(5.5, 6));
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-h5bQ1WUk-1613061611876)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210205211611985.png)]

泛型類

既然方法可以定義為泛型,類也可以定義成泛型

泛型類中可以包含泛型方法,多個型別引數

package GenericsStudy;

public class GenericDemo3<T> {
	private T t;
	public void add(T t) {
		this.t = t;
	}
	public T get() {
		return this.t;
	}
	public static void main(String[] args) {
		GenericDemo3<Integer> one = new GenericDemo3<Integer>();
		GenericDemo3<String> two = new GenericDemo3<String>();
		one.add(1);
		two.add("Hello World");
		System.out.println(one.get());
		System.out.println(two.get());
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-I2ZSAv5l-1613061611877)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210205214226660.png)]

上面提到了,泛型可以存盤多個型別,下面我們來寫一個簡易字典,僅包含一對key和value

package GenericsStudy;

public class GenericDemo6 {
	public static void main(String[] args) {
		Dictionary<String, Integer> dic1 = new Dictionary<String, Integer>();
		dic1.put("Peter",110);
		System.out.println(dic1.getKey());
		System.out.println(dic1.getValue());
		System.out.println(dic1.getAll());
	}
}

class Dictionary<K, V>{
	private K key;
	private V value;
	public void put(K key, V value) {
		this.key = key;
		this.value = value;
	}
	//獲取key
	public K getKey() {
		return key;
	}
	//獲取value
	public V getValue() {
		return value;
	}
    //獲取key與value的字串
	public String getAll() {
		return key.toString()+":"+value.toString();
	}
	
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-fJEknvNO-1613061611878)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210205215953250.png)]

泛型介面

繼承了泛型介面的類會變成泛型類

package GenericsStudy;

public class GenericDemo7 {
	public static void main(String[] args) {
		ImpleData<String> Imple = new ImpleData<String>();
		Imple.print("Hello World");
	}
}

//創建一個泛型介面
interface  Data<T>{
	T getData(T t1);
}

//ImpleData實作了Data介面
class ImpleData<T> implements Data<T>{
	
	@Override
	public T getData(T t1) {
		return t1;
	}
	
	public void print(T t1) {
		System.out.println("Print: "+this.getData(t1));
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-S8qvVnlv-1613061611879)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210205221855579.png)]

通配符

通配符是指這個 問號:?,

List <?> seq = new ArrayList<>();

  • <? extends T>表示該通配符所代表的型別是T型別的子類,

? extends通常與List一起用,List是一種存盤資料的容器和Array陣列類似,在后面的章節有介紹

package GenericsStudy;
import java.util.List;

public class GenericDemo4 {
	public static void main(String[] args) {
        /*由于我們extends Number了,種類只能是Number類或Number的子類
       		如果使用String型別,會報錯  */
		List<Number> sequence = new ArrayList<>();
		sequence.add(1);
		sequence.add(2);
		sequence.add(1.4);
		sequence.add(7.9f);
		getDate(sequence);
	}
	public static void getDate(List<? extends Number> data) {
		for(Object i : data) {
			System.out.println(i);
		}
	}
}
  • <? super T>表示該通配符所代表的型別是T型別的父類,
  • 不能同時宣告泛型通配符上界和下界

JAVA集合

我們Java后端一般要進行資料處理,假設所有資料都是儲存在陣列里面,大小長度受限,不方便;所以我們在本章將引進集合的概念,集合是物件的容器,定義了對多個物件進行操作的常用方法,可實作陣列的功能,但比陣列更靈活,注意:陣列可以存盤基本型別,如int,但是集合只能存盤參考型別,如String,所以在集合中存數字時,要將int型別轉化為Integer型別

對于集合中的元素我們想要遍歷有2種方法

  1. 增強for(for each回圈)
for(Object i :container1) {
	System.out.println(i);
}
  1. 通過迭代器來遍歷
//迭代器是通過集合內部的方法來獲得的
Iterator<Object> itr = container1.iterator();  
//itr.hasNext()是判斷是否還有下一個元素,如果是,該回圈開始執行
while(itr.hasNext()) {
    //列印出下一個元素
	System.out.println(itr.next());
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-5kVeBFEv-1613061611880)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210207164038116.png)]

Collection介面

Collection介面是眾多集合的父介面,List介面,Set介面都是繼承Collection介面,然后通過實作類實作其中的方法,由于Collection,Set, List都是介面,創建時必須要用實作類;比如List的實作類ArrayList,Set的實作類HashSet.

//引入集合模塊
import java.util.Collection
//創建集合,由于Collection是介面,我們用Collection的實作類ArrayList來實作
//Collection集合是泛型集合,< >中我們要添加存盤的資料型別, Object類是所有類的父類
Collection<Object> container1 = new ArrayList<>();

由于集合是無法儲存基本型別的,當我們存入基本型別時,集合會自動裝箱

list.add(20); 實際上是list.add(new Integer(20));

如果有一些方法解釋不全,可以參考以下API鏈接

API: https://www.runoob.com/manual/jdk1.6/

常用方法作用例子
boolean add(E e)添加元素,添加成功回傳truecontainer1.add(“apple”);
void clear()移除collection中的所有元素container1.clear();
int size()回傳集合中元素的個數int size = container1.size();
boolean contains(Object o)如果此 collection 包含指定的元素,則回傳 truecontainer1.contains(“apple”);
Iterator iterator()回傳collection的所有元素的迭代器Iterator itr = container1.iterator();
boolean isEmpty()判斷此集合是否為空container1.isEmpty();
boolean remove(Object o)移除集合中的某物件container1.remove(1);
Object[] toArray將此集合轉為陣列Object[ ] arrray = container1.toArray();

例子1

package CollectionStudy;

import java.util.ArrayList;//引入ArrayList
import java.util.Collection;//引入Collection
import java.util.Iterator; //引入迭代器

public class CollectionDemo1 {
	public static void main(String[] args) {
        //使用多型
		Collection<Object> container1 = new ArrayList<>();
		//添加元素
        container1.add("apple");
		container1.add(1);

		//增強for遍歷元素
		System.out.println("----增強For----");
		for(Object i :container1) {
			System.out.println(i);
		}
		//迭代器遍歷元素
		System.out.println("----Iterator----");
		Iterator<Object> itr = container1.iterator();  
		while(itr.hasNext()) {
			System.out.println(itr.next());
		}
	} 
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-0fxJJdV0-1613061611880)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210207115019530.png)]

例子2

Collection集合可以存盤其他參考資料型別,我們創建一個學生類,并將學生類添加進ArrayList集合(Collection的實作類)

package CollectionStudy;
//Students類
public class Students {
	private int age;
	private String name;
	public Students(int age, String name) {
		super();
		this.age = age;
		this.name = name;
		
	}
	public int getAge() {
		return age;
	}
	public String getName() {
		return name;
	}
    //重寫toString方法,按照我們的規定回傳字串
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		
		return "Student [ name: "+this.getName()+", age: "+this.getAge()+"  ]";
	}
}
//測驗類
package CollectionStudy;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class CollectionDemo2 {
	public static void main(String[] args) {
		Students Tom = new Students(18, "Tom");
		Students Jimmy = new Students(22, "Jimmy"); //先實體化2個students物件
		Collection<Students> container = new ArrayList<Students>();
		container.add(Tom);
		container.add(Jimmy);
		//遍歷 1
		for(Object student : container) {
			System.out.println(student);
		}
		System.out.println("\t----Line-----");
		//遍歷 2
		Iterator<Students> itr = container.iterator();
		while(itr.hasNext()) {
			System.out.println(itr.next());
		}
	}
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-5vVj96uo-1613061611881)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210207165739022.png)]

我們想用集合的contains方法,來判斷是否包含某參考元素

Students Jimmy = new Students(22, "Jimmy");
Collection<Students> container = new ArrayList<Students>();
container.add(Jimmy);
System.out.println(container.contains(Jimmy));

結果是:true

假設我們傳進去的不是Jimmy,而是: new Students(22, “Jimmy”)

結果是:false

為了避免這個問題,我們需要重寫students類中的equals方法

//在Students類中重寫此方法	
	@Override
	public boolean equals(Object obj) {
		if(this == obj) {
			return true;
		}
		if(obj == null) {
			return false;
		}
		if(obj instanceof Students) {
			Students students = (Students) obj;
			if(this.name.equals(students.name)&&this.age == students.age) {
				return true;
			}
		}
		return false;
	}

再次呼叫測驗類

結果為:true

List介面

List是有序(添加順序與遍歷順序一致),有下標,元素可重復的集合

List的獨有方法

如果有一些方法解釋不全,可以參考以下API鏈接

API: https://www.runoob.com/manual/jdk1.6/

方法解釋例子
void add(int index, Object o)在index位置插入物件oconatiner2.add(0, “Hello”);
boolean addAll(int index, Collection c)將一個集合元素增添到index位置container2.addAll(0,container1);
Object get(int index)回傳集合中指定位置的元素container2.get(0);
List subList(int fromIndex, int toIndex)回傳fromIndex與toIndex之間的元素container2.subList(0, 5);
ArrayList

ArrayList是由陣列結構實作的,查詢快,增刪慢

增添包:import java.util.ArrayList;

構造方法:ArrayList container = new ArrayList<>();
E為泛型即ArrayList可以增添任何類

常用方法解釋
public boolean add(E e);添加元素
public E get(int index)按照索引獲取元素,從0開始
public E set(int index, E element)可以替換指定元素
public boolean remove(Object 0)根據內容洗掉元素
public E remove(int index)根據index洗掉元素,回傳洗掉元素

例子

我們要創建一個Students類,將幾個students物件存入ArrayList類中

package CollectionStudy;

public class Students {
	private int age;
	private String name;
	public Students(int age, String name) {
		super();
		this.age = age;
		this.name = name;
		
	}
	public int getAge() {
		return age;
	}
	public String getName() {
		return name;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		
		return "Student [ name: "+this.getName()+", age: "+this.getAge()+"  ]";
	}
	
}
package CollectionStudy;

import java.util.ArrayList;
import java.util.Arrays;

public class ArrayListCollection {
	public static void main(String[] args) {
		ArrayList<Students> container = new ArrayList<>();
		Students Jim = new Students(18, "Jim");
		Students Tom = new Students(20, "Tom");
        //成功add元素后,回傳是否成功
		System.out.println("是否增添了Jim:"+container.add(Jim));
		container.add(Tom);
		System.out.println("獲取第一個元素:"+container.get(0));
		//把第2個元素設定為Alex
		container.set(1, new Students(78, "Alex"));
		System.out.println("第2個元素是:"+container.get(1));
		//container包含的元素個數
		System.out.println("元素個數:"+container.size());
		//將ArrayList轉化為陣列
		Object[] array = container.toArray();
		System.out.println("將ArrayList轉化為陣列:"+Arrays.toString(array));
		//洗掉元素,洗掉Jim的資訊
		System.out.println("洗掉: "+container.remove(Jim));
		System.out.println("洗掉后個數:"+container.size());
	}
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-f4FSI5pI-1613061611882)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210208192224042.png)]

假如我們增添,洗掉時用的不是Jim, 而是new Students(18, “Jim”); ?

package CollectionStudy;

import java.util.ArrayList;
import java.util.Arrays;

public class ArrayListCollection {
	public static void main(String[] args) {
		ArrayList<Students> container = new ArrayList<>();
		Students Jim = new Students(18, "Jim");
//		Students Tom = new Students(20, "Tom");
		System.out.println("是否增添了Jim:"+container.add(Jim));
		container.add(new Students(20, "Tom"));
		System.out.println("獲取第一個元素:"+container.get(0));
		//把第2個元素設定為Alex
		container.set(1, new Students(78, "Alex"));
		System.out.println("第2個元素是:"+container.get(1));
		//container包含的元素個數
		System.out.println("元素個數:"+container.size());
		//將ArrayList轉化為陣列
		Object[] array = container.toArray();
		System.out.println("將ArrayList轉化為陣列:"+Arrays.toString(array));
		
        //洗掉元素,注意,此時我們new Students(18,"Jim");
		System.out.println("洗掉: "+container.remove(new Students(18, "Jim")));
		System.out.println("洗掉后個數:"+container.size());
	}
}

結果

即使我們洗掉new Students(18,“Jim”);(內容相同),但是還是無法完全洗掉,洗掉回傳為false

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Aiks5UEV-1613061611882)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210208192723418.png)]

所以此時我們需要重寫Students里面的equals方法(ArrayList判斷remove時呼叫的方法)

	@Override
	public boolean equals(Object obj) {
		if(this == obj) {
			return true;
		}
		if(obj == null) {
			return false;
		}
		if(obj instanceof Students) {
			Students students = (Students) obj;
			if(this.name.equals(students.name)&&this.age == students.age) {
				return true;
			}
		}
		return false;
	}

結果,成功洗掉

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-CODsJJaJ-1613061611883)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210208193019582.png)]

LinkedList

Link意思為鏈,鏈表集合就像所以資料被鏈子連接在一起一樣

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-T7g0GKYZ-1613061611884)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210208193746827.png)]

特點:鏈表結構實作,增刪快,查詢慢

使用方法與ArrayList類似

例子

繼續用LinkedList存盤Students類的資訊

同樣,我們先不重寫equals方法

package CollectionStudy;

public class Students {
	private int age;
	private String name;
	public Students(int age, String name) {
		super();
		this.age = age;
		this.name = name;
		
	}
	public int getAge() {
		return age;
	}
	public String getName() {
		return name;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		
		return "Student [ name: "+this.getName()+", age: "+this.getAge()+"  ]";
	}
	
}
package CollectionStudy;

import java.util.LinkedList;

public class LinkedListDemo1 {
	public static void main(String[] args) {
		LinkedList<Students> container = new LinkedList<>();
		System.out.println("增添Tom: "+container.add(new Students(20, "Tom")));
		container.add(new Students(18, "Jim"));
		//pop從container中彈出元素
		System.out.println("Pop第一個元素:"+container.pop());
		container.add(new Students(18, "Jim")); 
		container.add(new Students(72,"Trump"));
		System.out.println("洗掉元素Jim:"+container.remove(new Students(18, "Jim")));
		//遍歷
		for(Object i :container) {
			System.out.println(i);
		}
	}
}
    

結果Jim無法被洗掉,同時***我們還發現List可以存盤相同的元素***

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-vsjNqaj3-1613061611885)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210208200323333.png)]

此時,我們再重寫Students的equals方法

	@Override
	public boolean equals(Object obj) {
		if(this == obj) {
			return true;
		}
		if(obj == null) {
			return false;
		}
		if(obj instanceof Students) {
			Students students = (Students) obj;
			if(this.name.equals(students.name)&&this.age == students.age) {
				return true;
			}
		}
		return false;
	}

結果,成功洗掉

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-dNaB7hId-1613061611885)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210208200612292.png)]

Set介面

上文我們介紹了List介面與其的實作類,現在我們開始講Set介面

Set是無序(添加順序與遍歷順序不一致),無下標,***元素不可重復***的集合

但是使用new可以插入內容相同的元素,因為Set判斷的依據是equals方法,如果equals方法未重寫則根據地址判斷.

例子引入

package setStudy;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class SetIntroduction {
	public static void main(String[] args) {
        //我們使用Set集合的實作類HashSet來創建集合
		Set<Object> container = new HashSet<>();
		container.add("Hello");
		container.add("World");
		container.add("Hello");
		container.add("My Friend");
		Iterator<Object> itr = container.iterator();
		while(itr.hasNext()) {
			System.out.println(itr.next());
		}
	}
}

這里由于是字串,系統內部有equals方法,所以第二個"Hello"無法加入Set集合

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-rxbghmdD-1613061611886)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210208202251947.png)]

HashSet

HashSet是Set集合的一個實作類

存盤結構:哈希表(陣列+鏈表+紅黑樹)

存盤程序

(1)根據hashcode計算保存的位置,如果此位置為空,則直接保存,如果不為空,則執行第二步

(2) 再執行equals方法,如果equals方法為true,則認為重復,否則形成鏈表,即添加到HashSet容器中

因為HashSet是以equal與hashcode進行比較,所以要重寫hashcode與equals,這樣就可以排除new的干擾,

構造方法

//E為任意種類的資料
HashSet<E> container = new HashSet<>();

基本操作與List / Set / Collection類似

增添元素:add(E e);

洗掉元素:remove(E e);

也有迭代器:Iterator iterator();

package setStudy;

import java.util.HashSet;

public class HashSetStudy {
	public static void main(String[] args) {
		HashSet<String> container = new HashSet<>();
		container.add("tim");
		container.add("Ketty");
		container.add("Yellow");
		System.out.println("HashSet中的內容:"+container.toString());
		System.out.println("HashSet的大小:"+container.size());
		System.out.println("此HashSet中是否含有Ketty資料:"+container.contains("Ketty"));
		
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-YvBItWvM-1613061611887)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210208203127750.png)]

案例2

像ArrayList一樣,我們創建Students類,增添Students元素

package setStudy;

public class Students {
	private int age;
	private String name;
	public Students(int age, String name) {
		super();
		this.age = age;
		this.name = name;
		
	}
	public int getAge() {
		return age;
	}
	public String getName() {
		return name;
	}
	@Override
	public String toString() {
		return "Student [ name: "+this.getName()+", age: "+this.getAge()+"  ]";
	}
}
package setStudy;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class HashSetDemo2 {
	public static void main(String[] args) {
		HashSet<Object> container = new HashSet<>();
		System.out.println("添加成功:"+container.add(new Students(18, "Jim")));
		System.out.println("添加成功:"+container.add(new Students(19, "Jone")));
		System.out.println("添加成功:"+container.add(new Students(18, "Alex")));
		System.out.println("添加成功:"+container.add(new Students(18, "Jim")));
		Iterator<Object> itr = container.iterator();
		while(itr.hasNext()) {
			System.out.println(itr.next());
		}
	}
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-INqkJjIu-1613061611888)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210208204141673.png)]

當我們增添內容相同的元素new Students(18, “Jim”)時,系統先判斷是否是同一地址,如果沒有看是否重寫了equals和hashcode方法,因為判斷地址不一樣又沒重寫equals方法(照系統默認的equals方法),所以添加成功

現在我們重寫Students類的equals和hashcode方法

	@Override
	public boolean equals(Object obj) {
		if(this == obj) {
			return true;
		}
		if(obj == null) {
			return false;
		}
		if(obj instanceof Students) {
			Students students = (Students) obj;
			if(this.name.equals(students.name)&&this.age == students.age) {
				return true;
			}
		}
		return false;
	}
	@Override
	public int hashCode() {
		//第一種轉換string的方法
//		String age = String.valueOf(this.age);
		//第二種
//		String age = this.age+"";
		String age = Integer.toString(this.age);
		return age.hashCode()*this.name.hashCode();
	}
	

結果,相同內容的資料添加失敗

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-GX7opgtZ-1613061611888)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210208204223172.png)]

TreeSet

實作Set介面的還有一個類,TreeSet,基于排列順序實作元素不重復

此實作為基本操作(addremovecontains

實作了SortedSet介面,對集合元素自動排序

傳入TreeSet的元素物件型別必須實作Comparable介面(指定排序規則)

因為TreeSet是通過ComparaTo方法確認是否為重復元素,所以可以通過內部類來override比較方法

使用TreeSet時,最好不要用Object類

package setStudy;

import java.util.TreeSet;

public class TreeSetStudy {
	public static void main(String[] args) {
		TreeSet<String> container = new TreeSet<>();
		container.add("Hello");
		container.add("xyz");
		container.add("world");
		container.add("hello");
		container.add("99");
		System.out.println(container.toString());
	}
}

String型別,(0,1,2…)默認數字在前–>大寫–>小寫(a,b,c…z)

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-qX8419Ic-1613061611889)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210208204509037.png)]

案例2

還是Students的案例

package setStudy;

public class Students {
	private int age;
	private String name;
	public Students(int age, String name) {
		super();
		this.age = age;
		this.name = name;
		
	}
	public int getAge() {
		return age;
	}
	public String getName() {
		return name;
	}
	@Override
	public String toString() {
		return "Student [ name: "+this.getName()+", age: "+this.getAge()+"  ]";
	}
}
package setStudy;

import java.util.Iterator;
import java.util.TreeSet;

public class TreeSetStudy {
	public static void main(String[] args) {
		TreeSet<Students> container = new TreeSet<>();
		System.out.println("添加成功:"+container.add(new Students(18, "Jim")));
		System.out.println("添加成功:"+container.add(new Students(19, "Jone")));
		System.out.println("添加成功:"+container.add(new Students(18, "Alex")));
		System.out.println("添加成功:"+container.add(new Students(18, "Jim")));
		
		//遍歷
		Iterator<Students> itr = container.iterator();
		while(itr.hasNext()) {
			System.out.println(itr.next());
		}
	}
}

由于我們再Students類中沒有重寫CompareTo方法,報錯

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-NIbDItbe-1613061611890)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210208205925362.png)]

繼承Comparable介面重寫CompareTo方法

package setStudy;

public class Students implements Comparable<Object>{
	private int age;
	private String name;
	public Students(int age, String name) {
		super();
		this.age = age;
		this.name = name;
		
	}
	public int getAge() {
		return age;
	}
	public String getName() {
		return name;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		
		return "Student [ name: "+this.getName()+", age: "+this.getAge()+"  ]";
	}
    
	@Override
	public int compareTo(Object obj) {
		Students stu = (Students) obj;
		return (stu.name.hashCode() - this.name.hashCode());
	}
	

}

此時TreeSet根據我們重寫的compareTo方法來判斷Object是否重復,我們的判斷依據是students的名字的hashcode,

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-9iik1hVF-1613061611890)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210208211200435.png)]

Map介面

Map是一種將Key與value(鍵物件與值物件)相互映射的集合

KeyValue
1Biden
2Trump

有時能用Map就不要用List,查找資訊Map使用效率有時比List要高

//通過HashMap這個實作類來創建一個Map物件
//Students是傳入Key的型別, String是value的型別
Map<Students, String> container = new HashMap<>();
常用方法解釋
V put(K key, V value)放入鍵值對
Object get(Object Key)通過key來獲取值value
Set KeySet()回傳所有的Key的Set集合
Collection values()回傳包含所有值的collection集合
boolean containsKey(Object key)如果此映射包含對于指定鍵的映射關系,則回傳 true
boolean containsValue(Object Value)如果此映射將一個或多個鍵映射到指定值,則回傳 true
V remove(Object key)如果存在,根據key移除此鍵值對

如果有一些方法解釋不全,可以參考以下API鏈接

API: https://www.runoob.com/manual/jdk1.6/

實作Map介面的類有HashMap, TreeMap等

Map遍歷

  1. KeySet()
Map <String, String> map = new HashMap<>();
Set<String> key = map.KeySet(); //是所有的Key的集合. 隨后可以使用增強for 或迭代器去遍歷
System.out.println("\tKeySet");
for( Students i : container.keySet() ) 
{
System.out.println(i.getName()+"----"+container.get(i));
}

  1. EntrySet()

EntrySet()的效率要略高于KeySet()

for(Entry<Students, String> i :container.entrySet()) 
{
System.out.println(i.getKey().getName()+"----"+i.getValue());
}

HashMap

HashMap和HashSet類似,也是存盤資料的集合;HashSet是存盤值資料,而HashMap是存盤鍵值對資料

在HashMap中Key的資料是根據hashcode來存的

HashMap是無序的,即我們插入和取出的順序是不一樣的

Students案例

由于是根據hashcode來存盤key,我們需要重寫students中的hashcode和equals方法

package Map_Key_Value;

public class Students {
	private int age;
	private String name;
	public Students(int age, String name) {
		super();
		this.age = age;
		this.name = name;
		
	}
	public int getAge() {
		return age;
	}
	public String getName() {
		return name;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		
		return "Student [ name: "+this.getName()+", age: "+this.getAge()+"  ]";
	}
	@Override
	public boolean equals(Object obj) {
		if(this == obj) {
			return true;
		}
		if(obj == null) {
			return false;
		}
		if(obj instanceof Students) {
			Students students = (Students) obj;
			if(this.name.equals(students.name)&&this.age == students.age) {
				return true;
			}
		}
		return false;
	}
	@Override
	public int hashCode() {
		// TODO Auto-generated method stub
		
		//第一種轉換string的方法
//		String age = String.valueOf(this.age);
		//第二種
//		String age = this.age+"";
		String age = Integer.toString(this.age);
		return age.hashCode()*this.name.hashCode();
	}
	

}
package Map_Key_Value;

import java.util.HashMap;
import java.util.Map.Entry;

public class OriginalMap {
	public static void main(String[] args) {
		HashMap<Students, String> container = new HashMap<>();
//		Students Jim = new Students(18, "Jim");
//		container.put(Jim, "CSSE120");
		container.put(new Students(18, "Jim"), "CSSE120");
		container.put(new Students(20, "John"), "CSSE220");
		container.put(new Students(17, "Alex"), "MA112");
		container.put(new Students(20, "Eric"), "ESL102");
		System.out.print("獲取 Students(18, \"Jim\") 的值:");
		System.out.println(container.get(new Students(18, "Jim")));//get value
		
        //遍歷
        //使用KeySet方法
		System.out.println("\tKeySet遍歷");
		for(Students i:container.keySet()) {
			System.out.println(i.getName()+"----"+container.get(i));
		}
		//使用EntrySet方法
		System.out.println("\tEntrySet遍歷");
//		Set<Map.Entry<Students, String>> entrys = container.entrySet();
		
		for(Entry<Students, String> i : container.entrySet()) {
			System.out.println(i.getKey().getName()+"----"+i.getValue());
		}
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-rtUa3yt3-1613061611892)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210208215330562.png)]

TreeMap

TreeMap存盤資料根據compareTo方法,對于自定義物件需要override比較方法,這個與TreeSet類似

下面就不多解釋了,不懂可以查看API

API: https://www.runoob.com/manual/jdk1.6/

JAVA常用類

java中還有一些常用的工具類,這些類都是日常開發時可能會用到的

Arrays類

Arrays是陣列的意思,Arrays是為陣列所開發的工具類(方法是靜態static方法)

arrays能處理的型別有int, double, long, char等

常用方法解釋
static boolean equals(int[ ] a, int[ ] a2)如果兩個int型別陣列相等,則回傳true
static int hashCode(int[ ] a)回傳指定陣列的哈希值
static void sort(double[ ] a)對指定陣列進行升序排序
static String toString(char[ ] a)將陣列內容轉化為字串
static void sort(T[ ] a, Comparator<? super T> c )根據指定比較器的順序對指定物件陣列進行排序

Date和Calendar類

Data和Calendar是java中表示時間的兩個類,它們能回傳當前的時間的毫秒值

毫秒值表示自 1970 年 1 月 1 日 00:00:00 GMT 以來經過的毫秒數,

Date

構造方法

//以當前時間來初始化物件
Date date = new Date();

//建構式接收一個引數,這個引數是從1970年起的毫秒數
Date date = new Date(long millisec)
常用方法解釋
String toString()格式化日期轉義形式yyyy-mm-dd的日期
int getHours()獲取此刻的小時
String toLocaleString()回傳當前本地格式的時間(方法已過時)
package DateAndCalendar;
import java.util.Date;
public class DateDemo1 {
	public static void main(String[] args) {
		Date date = new Date();
		System.out.println(date.toString());
		System.out.println(date.toLocaleString());
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ZHhV2f1Y-1613061611892)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210209130751457.png)]

我們可以使用SimpleDateFormat將日期輸出格式化

格式含義例子
yyyy2020
MM1
dd22
HH24小時制13
hh12小時制1
ss07
S毫秒7000
E星期幾Monday
D一年中的第幾天365
F一個月中的第幾周的周幾2
w一年中的第幾周7
W一個月中的第幾周2
aAM / PMPM
z時區CST
package DateAndCalendar;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateDemo1 {
	public static void main(String[] args) {
		Date date = new Date();
//		System.out.println(date.toString());
//		System.out.println(date.toLocaleString());
		SimpleDateFormat Df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println(Df.format(date));
	}
}

我們還能用時間來做一個定時器

package DajavateAndCalendar;
//在10s之內,持續列印hello, 結束時列印world
public class DateDemo1 {
	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		while(true) {
			long end = System.currentTimeMillis();
			if((end-start)>10000) {
				System.out.println("world");
				break;
			}
			System.out.println("hello");
		}
	}
}

Calendar

通過Calendar我們可以獲取時間中特定的資料

Calendar類的功能要比Date類強大很多,而且在實作方式上也比Date類要復雜一些,

由于Calendar是protected型別,只能通過其他方法進行構建

static Calendar getInstance()
//使用默認時區獲取日歷

Calendar date = Calendar.getInstance();

在Calendar中,系統定義了一些常量

Calendar.YEAR 年

Calendar.MONTH 月

Calendar.DATE 日期

Calendar.HOUR 小時

Calendar.MINUTE 分鐘

Calendar.SECOND 秒

Calendar.DAY_OF_WEEK 星期幾

常用方法

int get(int field)
calendar.get(Calendar.YEAR)//可用于獲取calendar特定的年-月-日
abstract void add(int field, int amount) //根據日歷給特定的欄位增減時間量
void set(int year, int month, int day, int hourOfDay, int minute, int second)//設定特定值

例子

package DateAndCalendar;
import java.util.Calendar;
import java.util.Date;
public class CalendarDemo1 {
	public static void main(String[] args) {
		Calendar calendar = Calendar.getInstance();
		System.out.println(calendar.getTime());
		int year = calendar.get(Calendar.YEAR);
		int month = calendar.get(Calendar.MONTH)+1;
		int day = calendar.get(Calendar.DAY_OF_MONTH);
		System.out.println("Today is "+year+"-"+month+"-"+day);
	}
}

JAVA例外處理

在寫程式時我們可能會遇到程式報錯的情況,此時編譯器會出現紅色的提示,如下

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-jgGqCjwp-1613061611893)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210209194701662.png)]

這就是例外Exception

所有的例外都是從java.lang.Exception中繼承的,Exception類是Throwable類的子類,Throwable還有一個子類Error

常見例外

  1. 用戶輸入了非法資料
  2. 要打開的檔案不存在
  3. 網路連接通信時中斷,或者JVM記憶體溢位

三大類例外
1. 檢查性例外(checked exception)
如用戶輸入例外或者打開一個不存在的檔案(這些例外在編譯時不能被簡單地忽略)
2. 運行時例外
運行時可能被程式員避免的例外
3. 錯誤
錯誤不是例外,通常是擺脫程式員控制的問題,例如當記憶體溢位時,會報錯誤

檢查性例外

  1. InterruptedException
    一個執行緒被另一個執行緒中斷,拋出該例外,
  2. NoSuchFieldException
    請求的變數不存在

非檢查性例外
1. ArithmeticException
2. NumberFormatException
當應用程式試圖將字串轉換成一種數值型別,但該字串不能轉換為適當格式時,拋出該例外
3. NullPointerException
4. IndexOutOfBoundsException
遍歷超過
5. UnsupportedOperationException

捕獲例外

//捕獲例外的基礎語法
try{
    
}catch(IOException e1){
    //如何處理該例外,例外e1的型別可以為Exception的子類或Exception;
}catch(ArithmeticException e2){
    
}finally{
    //finally可加可不加
    //如果加了,無論是否發生例外,finally 代碼塊中的代碼總會被執行, 
    //一般這里用于釋放記憶體,如input.close()
}

例子

我們要用戶輸入兩個數并互除,在除法中,被除數不能為0,所以我們要捕獲這個例外

package Exception;

import java.util.Scanner;

public class ExceptionStudyDemo1 {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		try {
			System.out.print("Num1: ");
			int num = input.nextInt();
			System.out.print("Num2: ");
			int num2 = input.nextInt();
            //注意此時num/num2得出的數字是整數
			System.out.println("Num1 / Num2 = "+num/num2);
		}
		catch(ArithmeticException a) {
			System.out.println(a.getMessage()); //獲取為什么錯誤
		}
		finally {
			input.close();
		}
	}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-HCb0goWT-1613061611894)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210211155159674.png)]

解決方法

添加一個

double rst = num*1.0/num2;java
package Exception;

import java.util.Scanner;

public class ExceptionStudyDemo1 {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		try {
			System.out.print("Num1: ");
			int num = input.nextInt();
			System.out.print("Num2: ");
			int num2 = input.nextInt();
			double rst = num*1.0/num2;
			System.out.println("Num1 / Num2 = "+rst);
		}
		catch(ArithmeticException a) {
			System.out.println(a.getMessage());
		}
		finally {
			input.close();
		}
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-qNDO2WYq-1613061611895)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210211155458450.png)]

Throws 關鍵字

throws中文意思是拋出,當一個函式有一個例外,此時我們不想處理時,我們可以throws這個Exception,交給函式外的部分處理

還是剛才num / num2的例子

package Exception;

import java.util.Scanner;

public class ExceptionStudyDemo1 {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		try {
			System.out.print("Num1: ");
			int num = input.nextInt();
			System.out.print("Num2: ");
			int num2 = input.nextInt();
			divide(num, num2);
		}
		catch(ArithmeticException a) {
			System.out.println(a.getMessage());
		}
		finally {
			input.close();
		}
	}
	public static void divide(int num, int num2) throws ArithmeticException{
		System.out.println("Num1 / Num2 = "+num/num2);
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-VOPcrIp5-1613061611895)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210211160006853.png)]

自定義例外類

所有例外必須是Throwable的子類,如果希望寫一個檢查性例外,則需要繼承Exception類;如果是運行時例外,則繼承RuntimeException類
繼承語法

class CustomException extends Exception{  
	//里面根據編譯器自動生成
}


package Exception;
import java.util.Scanner;
public class ExceptionStudyDemo1 {
public static void main(String[] args) {
	Scanner input = new Scanner(System.in);
	try {
		System.out.print("Num1: ");
		int num = input.nextInt();
		System.out.print("Num2: ");
		int num2 = input.nextInt();
		divide(num, num2);
		}
	catch(CustomException a){  
    	//捕獲自定義例外 
	}
public static void divide(int num, int num2) throws CustomException{ //在方法中拋出例外
	if(num2 == 0) {
		throw new CustomException(); //在方法中加入此陳述句,即為判斷那種情況下拋出自定義例外
    	}
	}
}

自定義例外有什么用呢?

當我們自己開發時,有時需要自己定義一些例外(別人能看懂的例外類名字),這樣可以方便開發

JAVA IO處理

我們每次運行一個程式,此時我們輸入的資料僅僅是存在快取中的,倘若我們關掉程式,資料就會隨之消失,為了把資料存起來,我們需要學習IO處理(Input Output),這樣資料才可以寫入記憶體硬碟里面,

流的概念

流stream可以為資料與目的之間建立通道,通過流我們可以把在記憶體中的資訊寫入到硬碟中;同理,我們也可以將硬碟中的資料讀取,print在控制臺里面
通過流讀取的不管是位元組還是字符,一般回傳的都是int值

流的分類

流有很多種類,按照處理資料側重點的不同可以分為輸入/輸出位元組流與輸入/輸出字符流;

這里我參考某位博主的圖片來解釋:https://blog.csdn.net/mu_wind/article/details/108674284

在這里插入圖片描述

位元組流

位元組流每次讀取或寫入一個位元組,2字符=1位元組, 1位元組(Byte) = 8位 (bit),位元組流可以處理影像,視頻等

一般英文字母一個字母為一個位元組(位元組是以int型別表示而字母則是以char型別表示)

字符流

字符流每次讀取或寫入一個字符,字符流只能用于處理文字資訊

中文與英文有點區別,1個中文代表1個字符(char),1個字符 = 2個位元組, 加入用位元組流讀取中文字符會出現亂碼

流的使用

位元組流使用

輸入位元組流

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-wjOhF8K1-1613061611896)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210211224816778.png)]

//實體化物件
FileInputStream file = new FileInputStream("E:\\java程式\\ReadFile.txt");

//讀取檔案內容
//讀取出來的是位元組流資訊,要轉化成char或string才能列印
//file.read()一次讀取一個位元組,如果有回傳此位元組,若沒有回傳-1
int data;
while((data = file.read()) != -1) {
	System.out.print((char)data);
}

//使用自制緩沖區讀取資料
byte[] buffer = new byte[3];//自制的一次能儲存3個位元組的緩沖區
int count=0;
while((count = file.read(buffer))!=-1) {
	System.out.print(new String(buffer,0,count));
}

//注意打開的檔案使用后要關閉
file.close();

輸出位元組流

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-DSBb74TV-1613061611898)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210211224920029.png)]

//實體化物件
//true表示如果給出的檔案地址已存在,則在此檔案的基礎上再寫如內容
FileOutputStream Out = new FileOutputStream("E:\\java程式\\OutPutFile.txt",true);

//寫入內容
String words = "HELLO WORLD ";
Out.write(words.getBytes()); //通過位元組流來寫入,必須是位元組形式

//同樣,寫完記得關閉
Out.close();

由于普通的輸入輸出位元組流效率不高,一般需要與緩沖流相互配合

檔案內容先讀入緩沖區,接著被程式訪問,這樣可以減少程式訪問硬碟的次數

緩沖輸入輸出流

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-tZ7vrIER-1613061611899)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210211225026578.png)]

//使用緩沖區讀取資料
FileInputStream file = new FileInputStream("E:\\java程式\\ReadFile.txt");
BufferedInputStream buf = new BufferedInputStream(file);
int data;
while((data = buf.read()) != -1) {
	System.out.print((char)data);
}


//緩沖區用完也最好記得關閉
buf.close();
//使用緩沖區輸出資料
package IOStudy;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;

public class buf {
	public static void main(String[] args) throws Exception {
		System.out.println("hello world");
		FileOutputStream file = new FileOutputStream("E:\\java程式\\BufferOutput.txt",true);
		BufferedOutputStream buf = new BufferedOutputStream(file);
		for(int i=0;i<4;i++) {
			buf.write("hello world ".getBytes());
			buf.flush(); //使用緩沖區每寫入一次資料要重繪一遍
		}
		System.out.println("Finish");
		buf.close();
	}
}
物件流與序列化

位元組流可以傳輸任何資料型別,包括物件,由此產生了另一個流,物件流

創建方法

ObjectOutputStream obj = new ObjectOutputStream(new FileOutputStream(source, true));

ObjectInputStream 讀取Obj資料順序根據寫入順序來,先進先出

在使用物件流寫入物件資料時,該物件必須實作Serializable介面
之前介面部分有提到Serializable沒有任何方法和常量,它是一個標記類

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-SMPV6LNC-1613061611899)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210211225831552.png)]

下面我們要將兩個學生類的資訊儲存到硬碟中,再通過一個程式將內容讀取出來

//學生類,要實作Serializable介面
package IOStudy;

import java.io.Serializable;

public class Student implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = -4870784691100550826L;
	private String name;
	private int age;
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "["+this.getName()+" , "+this.getAge()+"]";
	}
	
	
}
//寫入資訊
package IOStudy;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

public class ObjectWrite {
	public static void main(String[] args) throws Exception{
		String source = "E:\\java程式\\ObjWriter.bin";
		ObjectOutputStream obj = new ObjectOutputStream(new FileOutputStream(source));
		Student Biden = new Student("Biden", 78);
		Student Trump = new Student("Trump", 72);
		obj.writeObject(Trump);
		obj.writeObject(Biden);
		obj.writeObject(null);
		obj.close();
		System.out.println("Finish");
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-3t55wuuK-1613061611900)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210212000040489.png)]

//讀取資訊
package IOStudy;

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;

public class ObjectRead {
	public static void main(String[] args) throws Exception{
		String source ="E:\\java程式\\ObjWriter.bin";
		ObjectInputStream obj = new ObjectInputStream(new FileInputStream(source));
		Object stu;
		while((stu=obj.readObject())!= null) {
			System.out.println(stu);
		}
		obj.close();
	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-5g4mgD9P-1613061611901)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210212000057958.png)]

字符流使用

字符流輸入輸出

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Q0B1QXiv-1613061611901)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210211225130652.png)]

//實體化物件
FileReader read = new FileReader(Source);
//讀取操作與位元組流類似

//案例(反例),我們使用默認的解碼格式讀取資料
package IOStudy;

import java.io.FileInputStream;
import java.io.FileReader;
import java.io.InputStreamReader;

public class ReadFile2 {
	public static void main(String[] args) throws Exception{
		String Source = "E:\\java程式\\字符Reader.txt";
		FileReader read = new FileReader(Source);
		int count =0;
		while((count = read.read())!= -1) {
			System.out.print((char)count);
		}
		read.close();
	}
}

結果,中文出現亂碼

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-9Mfg0ljR-1613061611903)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210211232655649.png)]

由于英文一個字母只占一個位元組,默認的GBK解碼沒有問題,但是中文一個字占3個位元組,使用GBK解碼(與文本保存的格式不同)出現了亂碼,

為了保證能正確解碼,我們讀取字符檔案時要指定解碼格式,例如UTF-8

//下面是對上面例子的修改
package IOStudy;


import java.io.FileInputStream;
import java.io.FileReader;
import java.io.InputStreamReader;

public class ReadFile2 {
	public static void main(String[] args) throws Exception{
		String Source = "E:\\java程式\\字符Reader.txt";
		InputStreamReader read = new InputStreamReader(new FileInputStream(Source),"UTF-8");
		int count =0;
		while((count = read.read())!= -1) {
			System.out.print((char)count);
		}
	}
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-cmLS8dzw-1613061611903)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210211233135453.png)]

中文字符流寫出時,不用擔心上面編碼的問題,系統默認是GBK編碼,例子如下

package IOStudy;

import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.OutputStreamWriter;

public class WriteFile2 {
	public static void main(String[] args) throws Exception{
		String Source = "E:\\java程式\\字符Writer.txt";
		FileWriter file = new FileWriter(Source);
		file.write(" 世界你好 ");
		System.out.println("Finish");
		file.close();
		
	}
}

寫入的結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Fl8HL4f9-1613061611903)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210211233838187.png)]

ANSI就是GBK編碼格式

當然,我們也可以指定輸出格式,像輸入一樣

package IOStudy;

import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.OutputStreamWriter;

public class WriteFile2 {
	public static void main(String[] args) throws Exception{
		String Source = "E:\\java程式\\字符Writer.txt";
		OutputStreamWriter file = new OutputStreamWriter(new FileOutputStream(Source,true), "UTF-8");
//		FileWriter file = new FileWriter(Source);
		file.write(" 世界你好 ");
		System.out.println("Finish");
		file.close();
		
	}
}

結果:檔案使用UTF-8編碼格式

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-yYUtAIF2-1613061611904)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210211234107217.png)]

字符流讀取緩沖流
package IOStudy;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;

public class BufferCharRead {
	public static void main(String[] args) throws Exception{
		String source = "E:\\編程.txt";
		BufferedReader buf = new BufferedReader(new InputStreamReader(new FileInputStream(source), "GBK"));
		for(int i=0;i<20;i++)//列印緩沖區中的前20行
            //buf.readLine()指讀一行資料
			System.out.println(buf.readLine());
		buf.close();
	}
}

檔案夾操作

java的IO處理還包括檔案夾的一些操作,例如檔案夾的創建,洗掉等

//構造方法
//--1--
File file = new File(String parent_path, String child_path);
//--2--
File file = new File(String absolute_path)
目錄操作解釋
createNewFile()創建一個新檔案,不是檔案夾
mkdir()創建一個新目錄
delete()洗掉檔案或空目錄
exists()判斷File物件所表示的物件是否存在
getAbsolutePath()獲取檔案的絕對路徑
getName()獲取目錄的名字
getParent()獲取檔案/目錄所在的目錄,
該檔案夾所在絕對路徑E:\java程式\PicSource\Summer_Pocket
Parent就是E:\java程式\PicSource
Child就是Summer_Pocket
isDirectory()判斷是否是目錄
isFile()判斷是否是檔案
length()獲取檔案的長度,以位元組為單位
renameTo()修改檔案名為
listFiles()列出目錄中的所有內容
File[] files = file.listFiles();
回傳的是File型別陣列
File[] file2 = file.listFiles(FileFilter filter);//可以通過Filefilter進行過濾檔案的目的

FileFilter介面

	
public interface FileFilter
//需要實作的方法
boolean accept(File pathname)

案例

存了一些圖片在某個檔案夾中,我們要將這些圖片重命名,按1-50的順序重命名

package IOStudy;

import java.io.File;
import java.io.FileFilter;
import java.util.Scanner;

public class FileOperator {
	public static void main(String[] args) throws Exception {
		File file = new File("E:\\java程式\\PicSource");
		System.out.println("dictory's name: "+file.getName());
		File[] files = file.listFiles();
		Integer count =0;
		for(File pic:files) {
			File image = new File(file.getAbsolutePath(),count.toString()+".jpg");
			if(pic.isFile()) {
				pic.renameTo(image);
				count++;
			}
		}
		File[] file2 = file.listFiles(new FileFilter() {

			@Override
			public boolean accept(File pathname) {
				if(pathname.getName().endsWith(".jpg"))
					return true;
				return false;
			}
			
		});
		for(File pic:file2) {
			
			System.out.println(pic.getName());
		}	
		
	}
}

結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-fqe9AdYz-1613061611905)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210212002426056.png)]

Properties

properties是一個屬性集合,繼承HashTable,是一個執行緒安全的集合;properties可以儲存鍵值對,同時鍵值對是字串型別,它沒有泛型,

//構造方法
Properties container = new Properties();

//常用方法
container.setProperty("Trump","72");

//使用迭代器遍歷properties中的鍵值對
Iterator<Entry<Object, Object>> itr = container.entrySet().iterator();
while(itr.hasNext()) {
	Entry<Object, Object> set = itr.next();
	System.out.println(set.getKey()+"=====>"+set.getValue());
}

//使用Set遍歷鍵值對
Set<String> set = container.stringPropertyNames();
for(String pro:set) {
	System.out.println(pro+"=====>"+container.getProperty(pro));
}

//load加載存盤在硬碟中property的內容
container.load(FileInputStream fis);

//以適合的方法將鍵值對寫入到輸出流,可以保存注釋
container.store(FileOutputStream fos, String comment); 
//-----//
		//store方法,以適合的方法將鍵值對寫入到輸出流,可以保存注釋
		FileOutputStream fos = new FileOutputStream("E:\\java程式\\properties_save.txt");
		container.store(fos, "American President");
		fos.close();
//----//


//將屬性串列輸出到指定的輸出流
container.list(PrintWriter file);

舉一個儲存properties的例子

package IOStudy;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;

public class PropertyStudy {
	public static void main(String[] args) throws Exception {
		Properties container = new Properties();
		container.setProperty("Trump", "72");
		container.setProperty("Biden", "74");
		System.out.println(container.getProperty("Trump"));
		//使用迭代器遍歷
		Iterator<Entry<Object, Object>> itr = container.entrySet().iterator();
		while(itr.hasNext()) {
			 Entry<Object, Object> set = itr.next();
			System.out.println(set.getKey()+"=====>"+set.getValue());
		}	
		//將屬性串列輸出到指定的輸出流
		PrintWriter file =new PrintWriter(new FileOutputStream("E:\\java程式\\properties_save.txt"));
		container.list(file);
		file.close();

	}
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-qPwJjFAh-1613061611907)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210212000516493.png)]

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-rRe7NZqH-1613061611908)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210212000544377.png)]

讀取properties在硬碟中的內容

	//load加載properties內容
		FileInputStream fis = new FileInputStream("E:\\java程式\\properties_save.txt");
		container.load(fis);
		fis.close();
		Set<String> set = container.stringPropertyNames();
		for(String pro:set) {
			System.out.println(pro+"=====>"+container.getProperty(pro));
		}
		

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-2oIxvIii-1613061611908)(C:\Users\23881\AppData\Roaming\Typora\typora-user-images\image-20210212000811298.png)]

參考文獻

API:https://www.runoob.com/manual/jdk1.6/

菜鳥教程:https://www.runoob.com/java/java-tutorial.html

JAVA final關鍵字:https://blog.csdn.net/PickUpOldDriver/article/details/80566628

JAVA static block:https://blog.csdn.net/qq_35868412/article/details/89360250

JAVA this關鍵字:https://blog.csdn.net/qq_43555323/article/details/84993460

JAVA IO:https://blog.csdn.net/baobeiSimple/article/details/1713797

BufferedReader(new InputStreamReader(new FileInputStream(source), “GBK”));
for(int i=0;i<20;i++)//列印緩沖區中的前20行
//buf.readLine()指讀一行資料
System.out.println(buf.readLine());
buf.close();
}
}




### 檔案夾操作

java的IO處理還包括檔案夾的一些操作,例如檔案夾的創建,洗掉等

```java
//構造方法
//--1--
File file = new File(String parent_path, String child_path);
//--2--
File file = new File(String absolute_path)

目錄操作解釋
createNewFile()創建一個新檔案,不是檔案夾
mkdir()創建一個新目錄
delete()洗掉檔案或空目錄
exists()判斷File物件所表示的物件是否存在
getAbsolutePath()獲取檔案的絕對路徑
getName()獲取目錄的名字
getParent()獲取檔案/目錄所在的目錄,
該檔案夾所在絕對路徑E:\java程式\PicSource\Summer_Pocket
Parent就是E:\java程式\PicSource
Child就是Summer_Pocket
isDirectory()判斷是否是目錄
isFile()判斷是否是檔案
length()獲取檔案的長度,以位元組為單位
renameTo()修改檔案名為
listFiles()列出目錄中的所有內容
File[] files = file.listFiles();
回傳的是File型別陣列
File[] file2 = file.listFiles(FileFilter filter);//可以通過Filefilter進行過濾檔案的目的

FileFilter介面

	
public interface FileFilter
//需要實作的方法
boolean accept(File pathname)

案例

存了一些圖片在某個檔案夾中,我們要將這些圖片重命名,按1-50的順序重命名

package IOStudy;

import java.io.File;
import java.io.FileFilter;
import java.util.Scanner;

public class FileOperator {
	public static void main(String[] args) throws Exception {
		File file = new File("E:\\java程式\\PicSource");
		System.out.println("dictory's name: "+file.getName());
		File[] files = file.listFiles();
		Integer count =0;
		for(File pic:files) {
			File image = new File(file.getAbsolutePath(),count.toString()+".jpg");
			if(pic.isFile()) {
				pic.renameTo(image);
				count++;
			}
		}
		File[] file2 = file.listFiles(new FileFilter() {

			@Override
			public boolean accept(File pathname) {
				if(pathname.getName().endsWith(".jpg"))
					return true;
				return false;
			}
			
		});
		for(File pic:file2) {
			
			System.out.println(pic.getName());
		}	
		
	}
}

結果

[外鏈圖片轉存中…(img-fqe9AdYz-1613061611905)]

Properties

properties是一個屬性集合,繼承HashTable,是一個執行緒安全的集合;properties可以儲存鍵值對,同時鍵值對是字串型別,它沒有泛型,

//構造方法
Properties container = new Properties();

//常用方法
container.setProperty("Trump","72");

//使用迭代器遍歷properties中的鍵值對
Iterator<Entry<Object, Object>> itr = container.entrySet().iterator();
while(itr.hasNext()) {
	Entry<Object, Object> set = itr.next();
	System.out.println(set.getKey()+"=====>"+set.getValue());
}

//使用Set遍歷鍵值對
Set<String> set = container.stringPropertyNames();
for(String pro:set) {
	System.out.println(pro+"=====>"+container.getProperty(pro));
}

//load加載存盤在硬碟中property的內容
container.load(FileInputStream fis);

//以適合的方法將鍵值對寫入到輸出流,可以保存注釋
container.store(FileOutputStream fos, String comment); 
//-----//
		//store方法,以適合的方法將鍵值對寫入到輸出流,可以保存注釋
		FileOutputStream fos = new FileOutputStream("E:\\java程式\\properties_save.txt");
		container.store(fos, "American President");
		fos.close();
//----//


//將屬性串列輸出到指定的輸出流
container.list(PrintWriter file);

舉一個儲存properties的例子

package IOStudy;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;

public class PropertyStudy {
	public static void main(String[] args) throws Exception {
		Properties container = new Properties();
		container.setProperty("Trump", "72");
		container.setProperty("Biden", "74");
		System.out.println(container.getProperty("Trump"));
		//使用迭代器遍歷
		Iterator<Entry<Object, Object>> itr = container.entrySet().iterator();
		while(itr.hasNext()) {
			 Entry<Object, Object> set = itr.next();
			System.out.println(set.getKey()+"=====>"+set.getValue());
		}	
		//將屬性串列輸出到指定的輸出流
		PrintWriter file =new PrintWriter(new FileOutputStream("E:\\java程式\\properties_save.txt"));
		container.list(file);
		file.close();

	}
}

[外鏈圖片轉存中…(img-qPwJjFAh-1613061611907)]

[外鏈圖片轉存中…(img-rRe7NZqH-1613061611908)]

讀取properties在硬碟中的內容

	//load加載properties內容
		FileInputStream fis = new FileInputStream("E:\\java程式\\properties_save.txt");
		container.load(fis);
		fis.close();
		Set<String> set = container.stringPropertyNames();
		for(String pro:set) {
			System.out.println(pro+"=====>"+container.getProperty(pro));
		}
		

[外鏈圖片轉存中…(img-2oIxvIii-1613061611908)]

參考文獻

API:https://www.runoob.com/manual/jdk1.6/

菜鳥教程:https://www.runoob.com/java/java-tutorial.html

JAVA final關鍵字:https://blog.csdn.net/PickUpOldDriver/article/details/80566628

JAVA static block:https://blog.csdn.net/qq_35868412/article/details/89360250

JAVA this關鍵字:https://blog.csdn.net/qq_43555323/article/details/84993460

JAVA IO:https://blog.csdn.net/baobeiSimple/article/details/1713797

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/259276.html

標籤:其他

上一篇:劍指offer25-合并兩個排序的鏈表

下一篇:常用設計模式概覽

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more