方法的可變參數: 方法中有無參方法,有帶參方法,都多個參數的方法;代碼如下: public class Dome { /* 方法無參和帶參 */ public static void method() { System.out.println("我是一個無參的方法"); } public stati ...
方法的可變參數:
方法中有無參方法,有帶參方法,都多個參數的方法;代碼如下:
public class Dome { /* 方法無參和帶參 */ public static void method() { System.out.println("我是一個無參的方法"); } public static void method(int a) { System.out.println("我是一個帶參的方法"); } public static void method(int a,int b) { System.out.println("我是一個多參的方法"); } }
現在有一道題:定義一個方法,求2個數的和 和求多個數的和:我們的代碼可以如下:
public class Dome01 { public static void main(String[] args) { System.out.println(sum(1, 2)); System.out.println(sum(1, 2, 9)); } /* 定義一個求和方法sum */ public static int sum(int a, int b) { int sum = 0; sum = a + b; return sum; } /* 定義多個求和方法sum */ public static int sum(int a, int b, int c) { int sum = 0; sum = a + b + c; return sum; } }
現在又有一個問題,如果我不知道我要求幾個數的和,或者要求你寫方法來求2個數,3個數,4個數,5個數,就這樣一直下去,我們該怎麼辦,難道要一直的反覆的寫方法嘛,這樣肯定是不現實的。所以java引入了可變參數。
可變參數的語法如下:
public class Dome02 { /* 可變參數的定義: */ public static void main(String[] args) { int sum = sum(1, 2); // 第一次調用兩一參數的。 System.out.println(sum); int sum1 = sum(1, 2, 3); // 第二次調用三個參數 的。 System.out.println(sum1); } public static int sum(int... is) { // 可變參數的定義語法: 參數類型... 參數名 int sum = 0; for (int i = 0; i < is.length; i++) { sum = sum + is[i]; } return sum; } }
這樣就可以完美的解決上面的那個問題了。
Object...obj :
這裡過一下超類Object;obj是所有基本類型的超類,它包含所有的基本數據類型,如果把object當可變參數寫會如何。演示如下:
public class Dome08 { public static void main(String[] args) { //可以看見我們傳了所有的基本數據類型,還加了String這個引用類型 沒有報錯 obj("121",21,null,true,'a',1.2); } public static void obj(Object... objects) { /* 我們試著列印一下 */ for (int i = 0; i < objects.length; i++) { System.out.println(objects[i]); } } }
結果是什麼呢,沒錯就是和你想象的一樣:(將傳入的所有類型數據都列印了出來)
註意點:
- 可變參數定義用三個點多一個少一個都不可以。
- 傳參的數值必須和你所定義的類型相同,比如你定義了一個int...si 就不能傳 String或其他比int類型大的。
- 也可以如這樣定義:public static int sum(Stirng st, int... is){},可以和其他類型一起使用。
- 可變參數值的獲取和數組一樣,已下標的形式獲取,比如你定義了 int...is並傳了 1, 2兩個數,則is[0] 就等於1,is[1]就等於2。
遞歸方法:
遞歸演算法是一種演算法,在java中遞歸就是指 一個方法自身調用自己,就稱為遞歸。 由於遞歸是一種演算法思想所以就直接按實例來展示。
案例01:n的階乘
public class Dome03 { /* //簡單介紹一下階乘 * 一個正整數的階乘(factorial)是所有小於及等於該數的正整數的積,並且0的階乘為1。 * 自然數n的階乘寫作n!。1808年,基斯頓·卡曼引進這個表示法。 * 亦即n!=1×2×3×...×(n-1)×n。階乘亦可以遞歸方式定義:0!=1,n!=(n-1)!×n。 */ /* main入口 */ public static void main(String[] args) { int sum = sum(3); System.out.println(sum); } // 定義遞歸求階乘方法 public static int sum(int n) { // n代表求幾的階乘 if (n == 1 || n == 0) { // 由於 0 的階乘 是1 1 的階乘也是1 所以設成出口 return 1; } else { return n * sum(n - 1); // 反覆調用同一個方法直到碰上出口。 } } }
遞歸使用的註意點:
- 寫遞歸演算法一定要設置出口,否則會造成棧溢出;
- 遞歸方法的遞歸次數也不能太多,否則會造成棧溢出;
為什麼會造成棧溢出? 因為,方法中的變數隨著方法的調用而產生,隨著方法消失而消失(且是在棧中開闢空間);遞歸是在方法中調用自己,所以當第一次執行的方法沒有結束時,整個方法就不會被摧毀,所以空間就一直存在。然後在方法中再次調用方法就會重新開闢一個空間,反覆調用,就會反覆創建,但第一次的方法還沒有執行完。導致方法無法摧毀,在創建的空間超過棧自身的記憶體而導致棧溢出。(死迴圈也這個樣子)。
註:使用遞歸實現的功能,也可以用迴圈實現。
構造方法:
首先,我們需要知道的是每一個類都預設存在一個無參的構造方法。
構造方法的特點:
- 首先構造方法也是方法 同樣也被許可權修飾符所修飾
- 構造方法只有許可權修飾符,與static 返回值無關,方法名必須與類名同名 ,不能被static、final、synchronized、abstract和native修飾
- 構造方法有 無參構造方法和帶參構造方法
- 每一個類預設自帶一個無參構造方法
構造方法的作用:
- 構造出一個類的實例,當new對象的時候,程式首先執行的就是構造方法。
- 對實例化進行初始化
- 構造方法可以進行重載
public class Dome04 { String name; int age; /* 無參構造方法 */ public Dome04() { //方法名為類名 } /* 帶參構造方法 */ public Dome04(String name, int age) { //方法名為類名 且帶著參數 } }
this,static關鍵字:
this關鍵字說明: this是java提供的關鍵字,用來表示自身實例化對象。
三種使用方法:
- this.屬性名:用來訪問本類的成員方法,區分成員變數和局部變數
- this.方法名:來訪問本類中的方法,一般預設省略
- this()和this(參數1,參數2):來訪問本類的構造方法,訪問無參
this關鍵字演示代碼如下:
public class Dome05 { String name; int age; /* this關鍵字演示 */ public static void main(String[] args) { this.name; //this關鍵字不能在靜態方法中使用,main方法是一個靜態方法。 } public Dome05() { this("zhangsan", 20); this.test1(); //this.方法名。訪問 本類中的成員方法 } public Dome05(String name, int age) { this.name ="李四"; //this.屬性名調用成員變數並賦值 this.age = age; //this.屬性名區分成員變數的age和成員變數的age System.out.println(this.name); //this.name 調用成員變數name } public void test1() { System.out.println("我是一個成員方法"); } }
static關鍵字使用:static關鍵字是Java提供的,方便在沒有創建對象的情況下進行調用(方法/變數)。static可以用來修飾類的成員方法、類的成員變數,另外也可以編寫static代碼塊來優化程式性能。
- static靜態修飾符可以修飾變數、方法、代碼塊、修飾的變數叫做靜態變數,方法叫做靜態方法,代碼塊叫做靜態代碼塊
- 被靜態修飾的,在類被載入的時候也一起載入。
靜態變數被全局共用,且只有一個副本,在類初次載入的時候初始化。非靜態變數是對象所擁有的,在創建對象的時候被初始化,存在多個副本,各個對象擁有的副本互不影響;使用方法:static int i =0;
靜態方法由於靜態方法不依賴於任何對象就可以直接訪問,因此對於靜態方法來說,是沒有this的;靜態方法中不能訪問非靜態的成員變數
語法: static 返回值類型 方法名(參數列表){}
靜態代碼塊 :
- 靜態初始化塊,用於類的初始化操作
- static代碼塊隨著類的載入而載入,並且只初始化執行一次;
- 靜態代碼塊在類內方法外,可以存在多個
- 靜態初始化塊中不能直接訪問非static成員
代碼演示如下:
public class Dome06 { /* static關鍵字的使用 */ static int a = 0; //靜態的成員變數 int b = 1; static { System.out.println("我是一個靜態代碼塊"); } public static void name() { //靜態的成員方法 System.out.println(b); //靜態成員方法不可以訪問非靜態成員變數 System.out.println("我是一個靜態的成員方法"); } public void name2() { //普通的成員方法 System.out.println(a); //非靜態成員方法可以訪問靜態成員變數 System.out.println("我是一個普通的成員方法"); } }
除去靜態代碼塊之外,還有構造代碼塊,局部代碼塊 。如下:
public class Dome07 { //構造代碼塊:類中方法外,用{}括起,每次調用構造方法前執行,用於給對象進行初始化 { System.out.println("我是一個構造代碼塊"); } //靜態代碼塊:類中方法外,加static修飾,用於給類進行初始化 static { System.out.println("我是一個靜態代碼塊"); } public static void main(String[] args) { //局部位置,用於限定變數的生命周期,提高記憶體利用率。 { System.out.println("我是一個局部代碼塊"); } } }
單例模式:
單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一。這種類型的設計模式屬於創建型模式,它提供了一種創建對象的最佳方式。
這種模式涉及到一個單一的類,該類負責創建自己的對象,同時確保只有單個對象被創建。這個類提供了一種訪問其唯一的對象的方式,可以直接訪問,不需要實例化該類的對象。
註意:
-
1、單例類只能有一個實例。
-
2、單例類必須自己創建自己的唯一實例。
-
3、單例類必須給所有其他對象提供這一實例。
關鍵代碼:構造函數是私有的。
代碼實現:
1、懶漢式,線程不安全
public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
2、餓漢式
public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){} public static Singleton getInstance() { return instance; } }
作業:
01.評委打分:
-
-
選手的最後得分為:去掉一個最高分和一個最低分後 的4個評委平均值 (不考慮小數部分)。
public class Dome03GameScore { /* * 在編程競賽中,有6個評委為參賽的選手打分,分數為0-100的整數分。 選手的最後得分為:去掉一個最高分和一個最低分後 的4個評委平均值 * (不考慮小數部分)。 */ public static void main(String[] args) { int[] arrysScore = arrysScore(); int avgScore = avgScore(arrysScore); System.out.println("這位選手的最終得分是:"+ avgScore); } // 鍵盤錄入六位評委的打分 public static int[] arrysScore() { { System.out.println("錄入程式開始"); } int[] arrys = new int[6]; Scanner sc = new Scanner(System.in); for (int i = 0; i < arrys.length; i++) { System.out.println("請輸入第" + (i + 1) + "為評委老師的分數"); arrys[i] = sc.nextInt(); } return arrys; } // 求六個評委的分數最大值 public static int maxScore(int[] arrsys) { int temp = arrsys[0]; for (int i = 0; i < arrsys.length-1; i++) { if (arrsys[i] < arrsys[i + 1]) { temp = arrsys[i + 1]; } } return temp; } // 求六個評委的分數最小值 public static int minScore(int[] arrsys) { int temp = arrsys[0]; for (int i = 0; i < arrsys.length-1; i++) { if (arrsys[i] > arrsys[i + 1]) { temp = arrsys[i + 1]; } } return temp; } // 求評委分數的平均值(去掉最大值最小值的平均值) public static int avgScore(int[] arrys) { int avg = 0; for (int i = 0; i < arrys.length; i++) { if (arrys[i] == maxScore(arrys) || arrys[i] == minScore(arrys)) { continue; } else { avg = avg + arrys[i]; } } return avg / (arrys.length - 2); } }
02.有一分數序列:2/1,3/2,5/3,8/5,13/8,21/13....求出這個數列的前20項之和。
public class Dome03 { public static void main(String[] args) { /* 有一分數序列:2/1,3/2,5/3,8/5,13/8,21/13....求出這個數列的前20項之和。 */ // 方式一:for迴圈 double a = 2.0, b = 1.0, sum = 0; for (int i = 1; i < 20; i++) { double tem = 0; sum = sum + a / b; tem = a; a = a + b; b = tem; } // 方式二 遞歸 System.out.println(sum); double sumScore = sumScore(2, 1); System.out.println(sumScore); } // 方式二 遞歸 static double i = 1; static double temp = 0; static double sum = 0; public static double sumScore(double a, double b) {// 傳遞a b初始值 a=2,b=1 2/1;求和的值sum if (i < 20 && i >= 1) { sum = sum + a / b; /* System.out.println(sum); */ temp = a; a = a + b; b = temp; i++; return sumScore(a, b); } else { return sum; } } }
個人學習,內容簡略