一、javaSE(Java Platform, Standard Edition),標準版,各應用平臺的基礎,桌面開發和低端商務應用的解決方案。
--Java SE是基於JDK和JRE的,包括用於開發Java Web服務的類庫,同時,Java SE爲Java EE和Java ME提供了基礎。 二、javaEE(Java Platform,Enterprise Edition),企業版,以企業爲環境而開發應用程序的解決方案。
--Java EE 是在 Java SE 的基礎上構建的,可以幫助咱們開發和部署可移植、健壯、可伸縮且安全的服務器端 Java應用程序。 三、javaME(Java Platform,Micro Edition),微型版,致力於消費產品和嵌入式設備的最佳方案。
--是爲機頂盒、移動電話和PDA之類嵌入式消費電子設備提供的Java語言平臺,包括虛擬機和一系列標準化的Java API。
一、一種面向對象的編程語言。 二、一種與平臺無關的語言(根據JVM實現的)。 三、一種健壯性語言。 四、具備較高的安全性。
三:JDK、JRE與JVMjavascript
一、JVM:虛擬機,java虛擬機實際上只是一層接口,一層Java程序和操做系統通信的接口。.java源文件經編譯生成.class字節碼文件,
php
再由
java虛擬機加載並運行.class文件,若將.class文件當作一個軟件,那麼java虛擬機就是
css運行
這個軟件的操做系統。
html 二、
JRE:java運行環境,包括:JVM+系統類庫,它是運行Java程序的最小單位。
三、JDK:java開發工具包,包括:JRE+編譯運行指令,它是開發Java程序的最小單位。
java
注:安裝了JDK後,JRE已經存在無需額外安裝。程序員
四:Java程序開發與運行機制算法
一、編寫源程序,java源代碼文件。
數據庫
二、編譯源程序,編譯器編譯編譯成.java字節碼文件。
編程
三、運行時,Java虛擬機(JVM)將.Java源文件編譯成可運行的.class文件。
設計模式
四、Java環境變量的配置:
1)下載安裝JDK,進入電腦的高級系統設置,找到環境變量;
2)新建JAVA_HOME :%安裝路徑%\Java\jdk(安裝JDK路徑);
3)path 後追加兩個變量,即 : %JAVA_HOME%\bin 與%JAVA_HOME%\jre\bin;
4) 新建CLASSPATH系統變量,CLASSPATH= .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar (注意:必定要寫 ".;",標點所有爲英文狀態下)。
五:Java中的一些規則
一、應用
1) 一個源文件中只
能有一個public修飾的類,其餘類個數不限。
2)
一個
源文件有n個類時,編譯結果的class文件就有n個。
3) 源文件的名字必須和public修飾的類名相同
。
4)
Java語言中單詞拼寫大小寫嚴格區分。
5) main方法爲入口方法。
6) 每一句以分號(;)結束。
二、註釋
1) 單行註釋//
2) 多行註釋/* */
3) java文檔註釋/** */
三、標識符
1) 命名規則:
由字母、下劃線、數字和美圓符號組成;
不能以數字開頭;
區分大小寫;
不能是關鍵字和保留字(goto、const);
長度通常不超過15個字符。
2)
駝峯式命名:
包名:所有小寫。
類名:每一個單詞首字母都大寫。--大駝峯
方法名、參數名、變量名:第一單詞首字母小寫,後面其餘單詞首字母大寫。--小駝峯
六:Java語言基礎
一、關鍵字:Java中賦予了特殊含義的單詞
訪問控制 :public、private、protected
類,方法和變量修飾符 : abstract class extends final implements interface native new
static strictfp synchronized transient volatile
程序控制 : break continue return do while if else for instanceof switch case default
異常處理 : try cathc throw throws
包相關 : import package
基本類型 : boolean byte char double float int long short null true false
變量引用 : super this void
保留字 : goto const
二、數據類型
1) 基本數據類型:byte、short、int、long、float、double、char、boolean
數據類型 |
boolean |
byte |
char |
short |
int |
long |
float |
double |
void |
二進制位數 |
1 |
8 |
16 |
16 |
32 |
64 |
32 |
64 |
-- |
封裝類 |
Boolean |
Byte |
Character |
Short |
Integer |
Long |
Float |
Double |
Void |
2) 引用數據類型: 字符串 String、數組 []、類 class、接口 interface、枚舉 enum。
3) a.數據類型劃分:
基本類型變量:數據的值
引用類型變量:數據的地址
b.聲明的位置劃分: 局部變量 全局變量
區別:
一、默認值:局部變量沒有默認值,使用前必須初始化。
全局變量有默認值,默認爲0,沒必要須初始化。
二、聲明位置:局部變量在方法內。 全局變量在方法外類內。
三、做用位置:局部變量只能在本身聲明的方法裏。全局變量在整個類中。
自動類型轉換:從低級別到高級別,系統自動轉的;
強制類型轉換:把一個高級別的數賦給一個比該數的級別低的變量;
四、常量與變量
常量:在程序中,不會變化的數據。
變量:其實就是內存中的一個存儲空間,用於存儲常量數據。
做用:方便於運算。由於有些數據不肯定。因此肯定該數據的名詞和存儲空間。
特色:變量空間能夠重複使用。
變量的做用域:做用域從變量定義的位置開始,到該變量所在的那對大括號結束;
生命週期:變量從定義的位置開始就在內存中活了;變量到達它所在的做用域的時候就在內存中消失了;
五、運算符
1) 算術運算符:+ 、 - 、 * 、 / 、 % 、 ++ 、 --
2) 賦值運算符:= 、 += 、 -= 、 *= 、 /= 、 %=
3) 關係運算符:> 、 < 、 >= 、 <= 、 == 、 !=
4) 邏輯運算符:
! (通常用於boolean類型前,表示非);
& (只要有一個false 最終結果就是false);
| (但凡是有一個true 最終結果就是true);
^ (若是兩邊同樣,最終結果爲false;若是兩邊不一樣,最終結果爲true);
&& (若第一個表達式結果爲false,發生短路,第二個表達式不執行,最終結果爲false);
|| (若第一個表達式結果爲true,發生短路,第二個表達式不執行,最終結果是true)
5) 位運算符:用於操做二進制位的運算符。
~ 、 >> 、 << 、 >>>(無符號右移) 6) 字符串鏈接運算符:+ 7) 三目運算符:X ? Y : Z
X爲boolean類型表達式,若x的結果爲true,返回表達式Y的值,不然返回表達式Z的值。
七:Java中的流程控制
一、三種結構: 順序、分支、循環
1) if語句
a.if(
){}
b.
if(){}else{}
c.
if(){}else if(){}
d.if(){if(){}else()}
e.if()執行語句 esle 執行語句 (
注意:執行語句只有一條語句的時候.能夠將if esle 的大括號省略)
注意:()中爲boolean類型表達式,
{}中爲執行語句塊
equals : 比較字符串用,比較的是內容。
== : 比較數值,比較的是引用的地址。
基本數據類型:變量名、變量值在棧中。
引用數據類型:變量名在棧中,變量值在常量池中。
object中的equals比較的是地址,底層封裝的是==
== 比較基本數據類型時,比較的是內容
比較引用數據類型時,比較的是地址
String中也有equals,String中的equals被重寫過了,比較的是內容。
2)switch多分支語句
import java.util.Scanner;
public class MySwitch {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("請輸入今天星期幾:");
int week = scan.nextInt();
switch (week) {
case 1:
System.out.println("星期一");
break;
case 2:
System.out.println("星期二");
break;
case 3:
System.out.println("星期三");
break;
case 4:
System.out.println("星期四");
break;
case 5:
System.out.println("星期五");
break;
case 6:
System.out.println("星期六");
break;
case 7:
System.out.println("星期天");
break;
default:
System.out.println("今天要不要上班呢?");
break;
}
}
}
注意:
一、表達式必須是int、byte、char、short、enmu、String類型
二、case後必須是常量或者finall變量,不能是範圍
三、全部的case語句的值不能相同,不然編譯會報錯
四、default可要可不要
五、break用來執行完一個分支後使程序跳出switch語句塊,不然會一直會執行下去。
if與switch比較:
a.if能夠判斷範圍,也能夠判斷一個值switch只能判斷指定的值。
b.若只判斷指定的值,則使用switch語句,效率快 if判斷範圍,對數據判斷靈活,自身的格式也比較靈活。
3)for循環
for ([循環變量初始值設定]; [循環條件判斷]; [改變循環變量的值]){
循環體;
}
注意:
一、表達式2通常不能夠省略,不然死循環
二、表達式3能夠省略,可是在循環體中必須有語句修改變量,以使表達式2在某一時刻爲false結束循環。
三、若同時省略表達式1,表表達式3,則至關於while(表達式2)語句
四、三個表達式均省略 即for(;;)語句,此時至關於while(true)語句
五、表達式一、表達式3能夠是逗號表達式,以使循環變量值在修改時能夠對其它變量賦值
六、通常狀況下,表達式3,應向循環的結束變
1 public class Sfor { 2 3 public static void main(String[] args) { 4 for (int i = 1; i <= 9; i++) { 5 for (int j = 1; j <= i; j++) { 6 System.out.print(i+"*"+j+"="+j*i+" "); 7 } 8 System.out.print("\n"); 9 } 10 } 11 12 } 13 輸出結果是: 14 1*1=1 15 2*1=2 2*2=4 16 3*1=3 3*2=6 3*3=9 17 4*1=4 4*2=8 4*3=12 4*4=16 18 5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 19 6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 20 7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 21 8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 22 9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
4)while循環
while(條件表達式語句){
循環體語句;
}
do{
循環體;
}while( 循環條件判斷);
注意:
一、當第一次執行時,若表達式=false時,則while語句不執行,而do/while語句執行一次後面的語句
二、必定要切記在switch循環中,若是沒有break跳出語句,每個case都要執行一遍,在計算最終結果。
public class SWhile { public static void main(String[] args) { int x = 1; // 定義初值 int sum = 0; // 定義求和變量,用於存儲相加後的結果 while(x <= 10) { sum += x; // 循環相加,也即 sum = sum + x; x++; } System.out.println(sum); } } public class CDoWhile { public static void main(String[] args) { int a = 10; int b = 10; // while循環語句 while(a == 8) { System.out.println("a == " + a); a--; } // do···while循環語句 do { System.out.println("b == " + b); b--; } while(b == 8); } }
二、break、return和continue
break:跳出某個循環
continue:跳出本次循環,進入下一輪
return:以return;終止方法的執行
注意:if外有循環能夠用break、continue,單純if不能夠用。
三、遞歸
a.有返回值
b.有參數
c.可以有跳出循環的控制語句
d.本身調用本身
//用遞歸方法求累加
public class Recursion {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
System.out.print("請輸入要求的值:");
int N =scan.nextInt();
for(int n = 1; n <= N; n++) {
if(n % 20 == 0){
int sum = recursion(n);
System.out.println("1 到 " + n + " 的累加值是: " + sum);
}
}
}
public static int recursion(int n) {
if (n < 1) return 0;
return recursion(n - 1) + n;
}
}
八:重寫(Overriding)與重載(Overloading)
方法重載:指同一個類中的多個方法具備相同的名字,但這些方法具備不一樣的參數列表,即參數的數量或參數類型不能徹底相同
方法重寫:存在子父類之間的,子類定義的方法與父類中的方法具備相同的方法名字,相同的參數表和相同的返回類型
注:
(1)子類中不能重寫父類中的final方法
(2)子類中必須重寫父類中的abstract方法
(3)子類函數的訪問修飾權限不能小於父類的;
(4)子類的異常類型要小於父類;
重寫方法的規則:
一、參數列表必須徹底與被重寫的方法相同,不然不能稱其爲重寫而是重載。
二、返回的類型必須一直與被重寫的方法的返回類型相同,不然不能稱其爲重寫而是重載。
三、訪問修飾符的限制必定要大於被重寫方法的訪問修飾符(public>protected>default>private)
四、重寫方法必定不能拋出新的檢查異常或者比被重寫方法申明更加寬泛的檢查型異常。例如:父類的一個方法申明瞭一個檢查異常IOException,
在重寫這個方法是就不能拋出Exception,只能拋出IOException的子類異常,能夠拋出非檢查異常。
而重載的規則:
一、必須具備不一樣的參數列表;
二、能夠有不責罵的返回類型,只要參數列表不一樣就能夠了;
三、能夠有不一樣的訪問修飾符;
四、能夠拋出不一樣的異常;
重寫與重載的區別在於:
重寫多態性起做用,對調用被重載過的方法能夠大大減小代碼的輸入量,同一個方法名只要往裏面傳遞不一樣的參數就能夠擁有不一樣的功能或返回值。
用好重寫和重載能夠設計一個結構清晰而簡潔的類,能夠說重寫和重載在編寫代碼過程當中的做用非同通常.
一、重寫是在繼承關係中;重載是在同一個類中。
二、重寫是方法名、參數列表和父類相同;重載,方法名相同,參數列表不相同(個數、類型、順序)。
三、重寫返回值類型和父類相同;重載和返回值無關。
四、重寫訪問權限修飾符不能比父類更加嚴格;重載沒有要求。
九:面向對象和麪向過程
一、面向對象:是以具體的事物爲單位,考慮的是它的特徵(屬性)和行爲(方法)。
二、面向過程:是以具體的流程爲單位,考慮功能的實現。
十:類和對象
一、對象:看得見摸得着的具體事物。
類:抽象化的概念
二、類和對象的關係:
類是對象的模板/抽象化的概念,對象是類的實例。
三、建立類和對象
類:
特徵:全局變量/屬性/成員變量
動做:方法
對象:
類名 對象名=new 類名()
注意:一個類能夠建立多個對象,,每一個對象之間沒有關係。
十一:內存圖
一、棧:先進後出,存放基本數據類型變量名和變量值,引用數據類型的變量名,方法執行的時候進入棧中
二、堆:先進先出,new出來的對象的實例,包括類的屬性個方法。
十二:構造方法
一、構造方法是new關鍵字調用的,用來幫助構建對象
二、顯示構造對象
三、隱示構造對象(沒有顯示的狀況下存在)
四、構造對象能夠重載,參數類型不一致。
十三:關鍵字
一、static調用格式:
1)同一個類中:
靜態的: 方法名 屬性名
類名.方法名 類名.屬性名
對象名.方法名 對象名.屬性名
非靜態的: 對象名.屬性名 對象名.方法名
2)不一樣類中:
靜態的: 對象名.方法名 對象名.屬性名
類名.方法名 類名.屬性名
非靜態的: 對象名.屬性名 類名.方法名
注意:
一、static能夠修飾屬性、方法、代碼塊,不能夠修飾類和構造方法。
二、靜態方法隨着類的加載而加載。
三、在靜態方法區內的東西只有一份,全部的對象共享這一份空間,只要有一個對象對屬性進行修改,全部的對象調用都是修改後的數據。
四、代碼塊的執行順序:靜態代碼塊(只被調用一次)>構造代碼塊{}>構造方法>普通方法(需調用)
二、this關鍵字
1)能夠調用屬性和方法。 this.屬性名(全局變量) this.方法名();
2)在構造方法中:
a.this();括號內的參數個數、順序、類型根據調用的方法來決定。
b.必須放在第一行,只能調用一次。
c.調用構造方法時只能在構造方法中調用,調用屬性和方法時能夠在構造方法中能夠在普通方法中。
d.當全局變量和局部變量有重名字的時候,用this來區分。
三、super關鍵字
1)super指代父類對象。
2)super能夠調用屬性、方法、構造方法。
3)super調用父類的構造方法。
4)super調用構造方法時候必須放在第一行。
四、final最終的
1)能夠修飾全局變量,聲明的時候必須賦值,只能賦值一次。
2)能夠修飾局部變量,聲明時候能夠不賦值,但也只能賦值一次。
3)能夠修飾方法,能夠正常使用,不能被重寫。
4)能夠修飾類,能夠正常使用,不能被繼承。
5)用final修飾的屬性一般叫常量。
6)static final 全局變量。每一個字母都要大寫。
五、this和super的區別
1)this指的是本類建立的對象。 super指代的是父類的對象
2)this能夠調用屬性、方法、構造方法。 super也能夠調用屬性、方法、構造方法。
3)this調用屬性和方法的時候,調用本身本類的屬性和方法。 若是本類沒有,那就用super去父類中找
4)this調用構造方法調用,調用本類的其餘構造方法。 super調用父類的構造方法。
5)this和super在調用構造方法的時候必須放在第一行。
6)this和super不能同時存在
六、最小做用域最強原則: 局域變量在此方法中,比全局變量在此方法中的做用強。
十四:面向對象的三大特徵
一、封裝
做用:提升代碼的安全性 1)將屬性私有化,並提供對外界的接口(get/set方法)。 2)用private修飾的屬性和方法,只能在本類中使用。
二、繼承
做用:提升代碼的複用性,減小重複代碼 1)子類能夠繼承父類非私有的屬性和方法,不能繼承構造方法和私有的屬性和方法。 2)能夠綜合子類的共同特徵來去提煉父親的類。 3)子類在繼承父類的各類屬性和方法時,也能夠有本身的屬性和方法。 4)一個子類只能有一個父類,java只能單繼承,不能多繼承,由於多個類中的方法名相同,方法體不一樣,不知使用哪一個。 5)一個類繼承最頂端叫作基類或者超類,全部的超類叫作object 。 6)在繼承關係中,若是父類沒有無參數的構造方法,如何解決? a.子類中添加一個和父類構造方法參數列表相同的構造方法,經過super參數傳遞給父類的構造方法 b.若是父類容許修改的時候,能夠在父類中建立一個無參的構造方法 7)在繼承關係中,代碼塊的執行順序:父靜>子靜>父構造代碼塊>父構造方法>子構造代碼塊>子構造方法
三、多態
1)分類 編譯時多態:在編譯過程當中察覺的多態,重載,向上轉型。 運行時多態:在運行過程當中察覺的多態,向下轉型。 2)向上轉型、向下轉型是在繼承關係中,向下轉型必須在向上轉型的基之上。 3)在繼承關係中,父類的對象能夠指向子類的實例,父類引用實體方法的時候,是調用子類重寫之後的方法。 4)向上轉型 父類的引用指向子類的實體 父類類名 對象名=new 子類類(); 優勢:減小重複代碼,提升代碼的複用性 缺點:父類的引用沒法調用子類特有的屬性和方法 解決方案:向下轉型 5)向下轉型: 子類對象的父類引用賦給子類 子類類名 對象名=(子類類名)父類對象; 6) instanceof 判斷左邊的對象是否屬於右邊的類 對象名 instanceof 類名(子類類名) 7)匿名對象 new 類名() 只有堆空間,沒有棧空間,只能屬於一次,爲了節省代碼。
十五:
抽象abstract與接口interface
abstract:
做用:節省代碼,提升代碼的複用性
1)抽象類格式:訪問權限修飾符 abstract class 類名{ 2)抽象方法格式:訪問權限修飾符 abstract 返回值類型 方法名(形式參數列表); 注意: 一、若是一個類裏有抽象方法,那麼這個類必須聲明成抽象類。 二、一個類裏面能夠沒有抽象方法,能夠有非抽象方法, 三、類繼承抽象類: 把子類也用abstract修飾,變成抽象類。 子類重寫父類的抽象的方法 四、抽象類不能建立對象。 五、抽象類能夠有構造方法,在建立子類的時候,super隱式調用父類的構造方法,將父類的屬性和方法放到子類的對象空間裏。 六、在繼承你關係中,子類可以繼承抽象類的各類屬性和方法,除了私有的和構造方法。 七、只有公開的才能夠和abstract連用,static final private 都不能夠。 static屬於類方法,不容許覆蓋,abstract必須被覆蓋。final不能被重寫。
interface:
做用:規範了代碼,提升代碼的拓展性
一、格式:訪問權限修飾符 interface 接口名稱{}
二、實現類的格式:訪問權限修飾符 class 實現類名 implements 接口名{必須重寫接口中的全部的抽象方法}
三、接口中只有全局常量和抽象方法。
四、書寫的時候能夠省略部分修飾符,系統會默認給添上。
五、接口在實現的同時去繼承,extends在implement前面。
六、接口能夠多實現,實現的也必須是接口,方法名能夠重複,實現類實現一個就好了,由於沒有方法體,不會發生衝突。
抽象和接口的區別:
一、關鍵字:抽象類 abstract 接口interface
二、抽象類繼承 extends 接口實現 implements
三、子類繼承抽象類和 實現類實現接口的格式不一樣
四、接口中只有全局變量和抽象方法 抽象類中有各類屬性和方法
五、抽象類只能單繼承 接口能夠多實現
六、抽象類的子類只能繼承一個父類 實現類能夠實現多個接口,而且還能夠繼承父類
七、抽象類的做用:提升代碼的複用性 接口的做用:一、規範代碼二、提升代碼的拓展新
十六:訪問權限修飾符
本類中 本包中 其餘包子類 其餘包非子類
public √ √ √ √
protected √ √ √ ×
default √ √ × ×
private √ × × ×
十七:內部類
分類:成員內部類、靜態內部類、局部內部類、匿名內部類
一、成員內部類: 一、能夠用四種訪問權限修飾符修飾 二、能夠有本身的屬性和方法,除了靜態的。 三、可使用外部類的全部屬性和方法,包括私有的。 四、建立對象 一、經過建立外部類對象的方式建立對象 外部類 外部類對象=new 外部類(); 內部類 對象名=外部類對象.new 內部類(); 二、內部類 對象名=new 外部類.new 內部類(); 二、靜態內部類 一、格式:static class 類名{} 二、能夠聲明靜態的屬性和方法 三、可使用外部的靜態的屬性和方法 四、建立對象 內類名 對象名=new 內類名();(能夠直接建立) 外部類名.內部類 對象名=new 外部類.內部類(); 包名.外部類名.內部類 對象名=new 包名.外部類.內部類(); 五、外部類與內部類同名時,默認是使用內部類對象調用外部類屬性 this表明內部類對象 六、要想使用外部類屬性,須要使用外部類對象調用 三、局部內部類 一、在方法中聲明 二、只能用default修飾 三、能夠聲明屬性和方法,但不能是靜態的 四、建立對象,必須在聲明內部類的方法內建立 五、調用方法的時候,局部內部類纔會被執行 四、匿名內部類 一、匿名內部類只是用一次 二、格式: 父類或接口名 對象名=new 父類或接口名(參數列表){ 重寫抽象方法 } 調用抽象方法:對象名.方法名
十八:經常使用設計模式
一、單例模式 分類:懶漢式、餓漢式
一、構造方法私有化
二、在本類中建立本類對象
三、保證對象的惟一性final
四、給外界提供獲得對象的方法 static
五、在多線程中,餓漢式安全,懶漢式不安全
二、簡單工廠模式 批量建立對象
1 建立工廠類 : 建立對象的方法
2 果汁類 是全部種類果汁的父類
3 在工廠類的方法中返回果汁類
4 根據測試類中傳遞的字符串判斷到底返回哪一種果汁
5 測試類經過工廠類返回果汁對象
三、建造者模式
內部類使用場景 目的:靜態內部類建立外部類對象
一、 建立外部類,在其中建立一個靜態內部類
二、靜態內部類中寫屬性,構造方法和set get方法
三、靜態內部類中寫一個方法,必須返回外部類對象
四、 給外部類建立對象,傳遞參數。
四、裝飾者模式
一、在處理流中使用
二、子類重寫父類的方法,提升父類方法的功能及效率
三、爲了儘量減小重複代碼,在重寫的方法中用父類的對象調用父類原來的方法
四、獲得父類對象能夠經過將父類對象做爲子類屬性,經過子類構造方法傳遞父類對象
十九:數組及經常使用算法
一、聲明: int a[]; int []b;
二、初始化:
動態初始化:
一、a=new int[2]; int[0]=1;... 動態初始化:
二、b=new b[]{3,4}; 靜態初始化:int [] c={5,6};
三、數組經常使用的方法:
排序:Array.sort();
查找:Array.binarySearch();
打印:Array.toString();
複製:Array.copyof();
四、經常使用操做
一、冒泡排序 for(int i=0;i<a.length-1;i++){//控制外循環的次數 for(int j=0;j<a.length-1-i;j++){//控制內循環次數,比外循環少一次,與下一個比較 if(a[j]>a[j+1]){ int temp=a[j]; a[j]=a[j+1]; a[j+1]=temp; } } } 二、選擇排序 for (int i = 0; i < a.length-1; i++) { int k=i; for (int j = i; j < a.length-1; j++) { if (a[k]>a[j+1]) { k=j+1; } } if(i!=k){ int temp=a[i]; a[i]=a[k]; a[k]=temp; } } 三、順序查找 public static int find(int []b,int a){ for (int i = 0; i < b.length; i++) { if (a==b[i]) { return i; } } return -1; } 四、二分查找 public static int find(int b[],int a){ int max=b.length-1; int min=0; for (int i = 0; i < b.length; i++) { int midle=(max+min)/2; if(a==b[midle]){ return midle; }else if(a>b[midle]){ min=midle+1; }else if(a<b[midle]){ max=midle-1; } } return -1; }
二十:時間相關的類
一、Date類 .getTime();計算毫秒
二、SimpleDateFormat類 格式化時間 .format();返回的是String字符串
三、Calendar接口
日曆字段之間的轉換提供了一些方法
.get(Calendar.YEAR);
.get(Calendar.MONTH);// 默認是當前月份減一 從0開始的
.get(Calendar.DAY_OF_MONTH);
.get(Calendar.DAY_OF_WEEK);
Calendar calendar = Calendar.getInstance();
Date date = calendar.getTime();
四、Runtime運行時時間 .freeMemory(); 當前的系統剩餘空間
五、System.exit(0);退出程序,參數是0是正常退出
System.gc();調用垃圾回收器,不必定可以起來,只是起到一個促進的做用
二十一:Java異常處理機制
異常:
一、在運行時期出現的不正常的事件,從繼承的角度看,throwable是錯誤和異常的超類
二、錯誤Error:程序員沒法處理的嚴重性問題,資源耗盡,jvm系統內部的錯誤
異常Exception:程序員能夠處理的通常性問題,偶然的外界因素,編程的邏輯性錯誤
三、處理的必要性角度:
受檢異常:編譯時期就能發現的異常,必需要去處理的異常,繼承自Exception
非受檢異常:運行時期發現的異常,不是必需要去處理的,繼承自RuntimeException
四、異常的處理機制: 當運行代碼的時候首先先碰到異常,首先產生異常對象,拋出給jvm,jvm會攜帶異常對象,
去找代碼可以處理或者捕獲異常代碼,若是找到了,則交給這個代碼去處理,沒有找打,則程序中止運行。
五、異常處理的兩種方式
一、捕獲異常
try{可能會產生異常的代碼}catch(異常類 異常對象){處理異常的代碼}
try{}catch(){}catch(){}... catch中子類異常放在父類異常的上面
try{]catch(){}finally{} finally中的代碼必定會被執行到
try{}finally{}
1> 若是不去捕獲異常,發生異常,異常後面的代碼都不會被執行到
2> 若是捕獲異常 try/catch後面的代碼會被執行到
3> 捕獲異常,try塊中異常後面的代碼不會被執行到
二、拋出異常
產生異常的位置不去處理異常,由調用此方法的調用者去處理異
throws 方法的聲明後面 後面跟的是異常的類名 能夠跟多個類名之間用逗號隔開 能夠拋出受檢異常和非受檢異常
throw 方法的內部 異常的對象名 一個對象 拋出非受檢異常
六、自定義異常
自定義
受檢異常繼承Exception
非受檢異常 RuntimeException
final finally finalize區別
final 最終的,可修飾類,方法,屬性
類:不能被繼承
方法:不能被重寫,能夠被繼承
屬性:全局變量:聲明是必須初始化。局部變量:聲明的時候能夠不初始化。但都只能賦值一次
finally 跟try/catch後面,不管是否發生異常都會被執行。關閉數據庫,關閉數據流。
finalize 由系統調用,垃圾回收器回收以前作一些清理的工做。
二十二:
數組:長度固定,數據類型相同
集合:長度不固定,數據類型能夠不一樣,只能存對象
collection
List Set
Vector
ArrayList HashSet
LinkedList TreeSet
Map
HashMap
TreeMap
List:元素是有序的,元素能夠重複。由於該集合體繫有索引。
|--ArrayList:底層的數據結構使用的是數組結構。特色:查詢速度很快。可是增刪稍慢。線程不一樣步。
|--LinkedList:底層使用的是鏈表數據結構。特色:增刪速度很快,查詢稍慢。
|--Vector:底層是數組數據結構。線程同步。被ArrayList替代了。
Set:元素是無序(存入和取出的順序不必定一致),元素不能夠重複。
|--HashSet:底層數據結構是哈希表。線程不一樣步。 保證元素惟一性的原理:判斷元素的hashCode值是否相同。若是相同,還會繼續判斷元素的equals方法,是否爲true。
|--TreeSet:能夠對Set集合中的元素進行排序。默認按照字母的天然排序。底層數據結構是二叉樹。保證元素惟一性的依據:compareTo方法return 0。
Set集合的功能和Collection是一致的
一、HashSet: 哈希表 一、能夠經過元素的兩個方法,hashCode和equals來完成保證元素惟一性。若是元素的HashCode值相同,纔會判斷equals是否爲true。
若是元素的hashCode值不一樣,不會調用equals。
二、hashcode是內存地址經過必定運算的到的int類型的數值。返回值是int類型的數據,各個屬性的hash值。 相加
三、hashcode值相同,也不必定是同一個對象
四、調用hashcode方法能夠幫助去過濾調用徹底不可能相同的 對象,提升執行效率
五、equals最終肯定兩個對象是否相同的
Map :
1)該集合存儲鍵值對,一對一對往裏存
2)要保證鍵的惟一性 |--Hashtable:底層是哈希表數據結構,不能夠存入null鍵null值。該集合是線程同步的。JDK1.0,效率低。 |--HashMap:底層是哈希表數據結構。容許使用null鍵null值,該集合是不一樣步的。JDK1.2,效率高。 |--TreeMap:底層是二叉樹數據結構。線程不一樣步。能夠用於給Map集合中的鍵進行排序。 初始容量16,加載因子0.75 Map和Set很像。其實Set底層就是使用了Map集合。
二十三:Java多線程
1)線程和進程
一、線程
注意:多線程。從宏觀角度:同時執行了多個線程。
從微觀角度:同一時間只能執行一個線程
多個線程是競爭關係,搶佔cpu資源,不然只能等待。
二、進程和線程的區別
進程是應用程序,線程是一條執行路徑
進程有獨立的內存空間,崩潰不會影響其餘程序,
線程沒有獨立的空間,多個線程在同一個進程的空間,可能會影響其餘線程
一個進程中,至少有一個線程
三、主線程與子線程
主線程:main方法產生的線程,也叫做UI線程。
子線程:除了主線程之外的,也叫工做線程。
守護線程(即daemon thread),是個服務線程,準確地來講就是服務其餘的線程。
四、建立線程的方式
a.建立一個類繼承Thread,重寫run方法,建立線程對象,啓動線程,Thread.currentThread().getName(),哪一個線程調用,名字就是哪一個現成的名字.
b
.
共享資源類實現Runable接口,
重寫run方法,建立共享資源對象
,
建立線程對象,將共享資源對象添加到線程中
,啓動線程
c.實現callable接口,Callable接口表明一段能夠調用並返回結果的代碼;Future接口表示異步任務,是尚未完成的任務給出的將來結果。
因此說Callable用於產生結果,Future用於獲取結果。
d.線程池ThreadPoolExcutor
new ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,long keepAliveTime, TimeUnit unit,BlockingQueue workQueue,RejectedExecutionHandler handler)
(1)corePoolSize: 線程池維護線程的最少數量 (core : 核心)
(2)maximumPoolSize: 線程池維護線程的最大數量
(3)keepAliveTime: 線程池維護線程所容許的空閒時間
(4)unit: 線程池維護線程所容許的空閒時間的單位
(5)workQueue: 線程池所使用的緩衝隊列
(6)handler: 線程池對拒絕任務的處理策略
思考:說一下 runnable 和 callable 有什麼區別?
Runnable接口中的run()方法的返回值是void,它作的事情只是純粹地去執行run()方法中的代碼而已;
Callable接口中的call()方法是有返回值的,是一個泛型,和Future、FutureTask配合能夠用來獲取異步執行的結果。
五、run和start的區別
每一個線程都是經過某個特定Thread對象所對應的方法run()來完成其操做的,方法run()稱爲線程體。經過調用Thread類的start()方法來啓動一個線程。
start()方法來啓動一個線程,真正實現了多線程運行。這時無需等待run方法體代碼執行完畢,能夠直接繼續執行下面的代碼; 這時此線程是處於就緒狀態, 並無運行。
而後經過此Thread類調用方法run()來完成其運行狀態, 這裏方法run()稱爲線程體,它包含了要執行的這個線程的內容, Run方法運行結束, 此線程終止。而後CPU再調度其它線程。
run()方法是在本線程裏的,只是線程裏的一個函數,而不是多線程的。 若是直接調用run(),其實就至關因而調用了一個普通函數而已,直接待用run()方法必須等待run()方法執行完畢
才能執行下面的代碼,因此執行路徑仍是隻有一條,根本就沒有線程的特徵,因此在多線程執行時要使用start()方法而不是run()方法。
run沒有開闢新的棧空間,沒有新線程,都是主線程在執行
start開闢了新的棧空間,在新的棧空間啓動run()方法
六、線程的調度
setPriority();分配優先級,默認5,最低1,最高10
.join();插隊,阻塞指定的線程等到另外一個線程完成之後再繼續執行
.sleep();須要設置睡眠時間
.yield();禮讓,當執行到這個方法時,會讓出cpu時間,立馬變成可執行狀態
sleep和pield的區別:
sleep 線程進入被阻塞的狀態
yeild 線程轉入暫停執行的狀態
七、打斷線程的終止方式
一、用標記,當終止線程時,會執行完run方法
二、stop()方法,不建議使用,會執行不到特定的代碼
三、interrupt(),只能中斷正在休眠的線程,經過拋異常的方法中斷線程的終止。
InputStream inputStream=System.in;
int m=inputStream.read();
myThread2.interrupt();//經過外界輸入打斷
八、線程的五種狀態
新建(new) 就緒(runnable) 執行(running) 死亡(dead) 阻塞(blocked)
一、新建狀態(New):新建立了一個線程對象。
二、就緒狀態(Runnable):線程對象建立後,其餘線程調用了該對象的start()方法。該狀態的線程位於「可運行線程池」中,
變得可運行,只等待獲取CPU的使用權。即在就緒狀態的進程除CPU以外,其它的運行所需資源都已所有得到。
三、運行狀態(Running):就緒狀態的線程獲取了CPU,執行程序代碼。
四、阻塞狀態(Blocked):阻塞狀態是線程由於某種緣由放棄CPU使用權,暫時中止運行。直到線程進入就緒狀態,纔有機會轉到運行狀態。
阻塞的狀況分三種:
(1)、等待阻塞:運行的線程執行wait()方法,該線程會釋放佔用的全部資源,JVM會把該線程放入「等待池」中。
進入這個狀態後,是不能自動喚醒的,必須依靠其餘線程調用notify()或notifyAll()方法才能被喚醒,
(2)、同步阻塞:運行的線程在獲取對象的同步鎖時,若該同步鎖被別的線程佔用,則JVM會把該線程放入「鎖池」中。
(3)、其餘阻塞:運行的線程執行sleep()或join()方法,或者發出了I/O請求時,JVM會把該線程置爲阻塞狀態。
當sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程從新轉入就緒狀態。
五、死亡狀態(Dead):線程執行完了或者因異常退出了run()方法,該線程結束生命週期。
思考:(1)sleep() 和 wait() 有什麼區別?
sleep():方法是線程類(Thread)的靜態方法,讓調用線程進入睡眠狀態,讓出執行機會給其餘線程,等到休眠時間結束後,線程進入就緒狀態和其餘線程一塊兒競爭cpu的執行時間。
由於sleep() 是static靜態的方法,他不能改變對象的機鎖,當一個synchronized塊中調用了sleep() 方法,線程雖然進入休眠,可是對象的機鎖沒有被釋放,其餘線程依然沒法訪問這個
對象。
wait():wait()是Object類的方法,當一個線程執行到wait方法時,它就進入到一個和該對象相關的等待池,同時釋放對象的機鎖,使得其餘線程可以訪問,
能夠經過notify,notifyAll方法來喚醒等待的線程
(2)notify()和 notifyAll()有什麼區別?
若是線程調用了對象的 wait()方法,那麼線程便會處於該對象的等待池中,等待池中的線程不會去競爭該對象的鎖。
當有線程調用了對象的 notifyAll()方法(喚醒全部 wait 線程)或 notify()方法(只隨機喚醒一個 wait 線程),被喚醒的的線程便會進入該對象的鎖池中,鎖池中的線程會
去競爭該對象鎖。也就是說,調用了notify後只要一個線程會由等待池進入鎖池,而notifyAll會將該對象等待池內的全部線程移動到鎖池中,等待鎖競爭。
優先級高的線程競爭到對象鎖的機率大,倘若某線程沒有競爭到該對象鎖,它還會留在鎖池中,惟有線程再次調用 wait()方法,它纔會從新回到等待池中。而競爭到對象鎖的線程
則繼續往下執行,直到執行完了 synchronized 代碼塊,它會釋放掉該對象鎖,這時鎖池中的線程會繼續競爭該對象鎖。
2)同步
發生在兩個以兩個以上的線程中
解決代碼的重複問題 優勢:提升了線程中數據的安全性 缺點:下降了執行效率
一、同步代碼塊 synchronized(鎖){同步代碼塊} 注意:鎖分任意鎖和互斥鎖,鎖是對象,瑣是惟一的。
二、同步方法 public synchroinzed 返回值類型 方法名(){同步代碼}
三、在共享資源中:
線程操做相同,鎖是this
synchronized (this) {// 同步代碼塊,包含同步代碼塊。任意鎖,互斥鎖。
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + "---" + ticket--);
} else {
break;
}
}
線程操做不相同,鎖是共享資源對象
synchronized (card) {
card.setMoney(card.getMoney() + 1000);
System.out.println("Boy+1000---" + card.getMoney());
}
四、在同步方法中:
共享資源,線程操做相同,資源類中的鎖是this
共享資源,線程操做不相同,資源類中的鎖也是this
public synchronized void input(){
money+=100;
System.out.println("input+100----"+money);
}
(1)什麼是死鎖?
死鎖是指兩個或兩個以上的進程在執行過程當中,因爲競爭資源或者因爲彼此通訊而形成的一種阻塞的現象,若無外力做用,它們都將沒法推動下去。此時稱系統處於死鎖狀態或系統
產生了死鎖,這些永遠在互相等待的進程稱爲死鎖進程。是操做系統層面的一個錯誤,是進程死鎖的簡稱,最先在 1965 年由 Dijkstra 在研究銀行家算法時提出的,它是計算機操做系統
乃至整個併發程序設計領域最難處理的問題之一。
(2)怎麼防止死鎖?
死鎖的四個必要條件:
一、互斥條件:進程對所分配到的資源不容許其餘進程進行訪問,若其餘進程訪問該資源,只能等待,直至佔有該資源的進程使用完成後釋放該資源
二、請求和保持條件:進程得到必定的資源以後,又對其餘資源發出請求,可是該資源可能被其餘進程佔有,此事請求阻塞,但又對本身得到的資源保持不放
三、不可剝奪條件:是指進程已得到的資源,在未完成使用以前,不可被剝奪,只能在使用完後本身釋放
四、環路等待條件:是指進程發生死鎖後,若干進程之間造成一種頭尾相接的循環等待資源關係
這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之 一不知足,就不會發生死鎖。理解了死鎖的緣由,尤爲是產生死鎖的四個必要條件,
就能夠最大可能地避免、預防和 解除死鎖。因此,在系統設計、進程調度等方面注意如何不讓這四個必要條件成立,如何確 定資源的合理分配算法,避免進程永久佔據系統資源。
此外,也要防止進程在處於等待狀態的狀況下佔用資源。所以,對資源的分配要給予合理的規劃。
(3)說一下 synchronized 底層實現原理?
synchronized能夠保證方法或者代碼塊在運行時,同一時刻只有一個方法能夠進入到臨界區,同時它還能夠保證共享變量的內存可見性。Java中每個對象均可以做爲鎖,
這是synchronized實現同步的基礎:
普通同步方法,鎖是當前實例對象
靜態同步方法,鎖是當前類的class對象
同步方法塊,鎖是括號裏面的對象
(4)synchronized 和 Lock 有什麼區別?
首先synchronized是java內置關鍵字,在jvm層面,Lock是個java類;
synchronized沒法判斷是否獲取鎖的狀態,Lock能夠判斷是否獲取到鎖;
synchronized會自動釋放鎖(a 線程執行完同步代碼會釋放鎖 ;b 線程執行過程當中發生異常會釋放鎖),Lock需在finally中手工釋放鎖(unlock()方法釋放鎖),不然容易形成線程死鎖;
用synchronized關鍵字的兩個線程1和線程2,若是當前線程1得到鎖,線程2線程等待。若是線程1阻塞,線程2則會一直等待下去,而Lock鎖就不必定會等待下去,若是嘗試獲取不到鎖,
線程能夠不用一直等待就結束了;
synchronized的鎖可重入、不可中斷、非公平,而Lock鎖可重入、可判斷、可公平(二者皆可);
Lock鎖適合大量同步的代碼的同步問題,synchronized鎖適合代碼少許的同步問題。