前八天筆記

DAY? 01

JAVA簡述

Java是由SUN公司在1995年推出的一門高級編程語言,是現今服務器端的首選編程語言,是大數據的基礎語言。Java的一個重要的特性是跨平臺。

Java之所以能夠跨平臺是因為有JVM(Java Virtual Machine, Java虛擬機)。所有的Java程序并不是直接和操作系統交互而是先交由JVM進行翻譯,然后JVM將程序翻譯為當前操作系統能夠理解的語言之后再交由操作系統執行。

注意:JAVA語言是跨平臺的但是JVM不是跨平臺的

技術結構

JAVASE --- Java Standard Edition --- Java標準版/基礎版。是Java技術結構的基礎

JAVAEE --- Java Enterprise Edition --- Java企業版,是在企業中進行團隊開發的時候使用

JAVAME --- Java Micro Edition --- Java微型版,是為一些小型電子的嵌入來提供方案

JDK --- Java Development Kit --- Java開發工具包,為Java程序的開發來提供基本的工具 --- 包含了工具包+ JRE?

JRE --- Java Runtime Environment --- Java運行時環境,為Java程序的運行來提供基本的環境 --- 包含了JVM + 核心類庫

JVM --- Java Virtual Machine --- Java虛擬機,是Java程序能夠跨平臺的前提

Oak --- 橡樹

JDK1.0 -> JDK1.1 -> JDK1.2 -> JDK1.3 -> JDK1.4 -> JDK1.5/JDK5.0 -> JDK1.6/JDK6 -> JDK1.7/JDK7.0 -> JDK1.8 -> JDK1.9/JDK17.9 -> JDK10/JDK18.3 -> JDK11/JDK18.9

擴展:LTS - long time service

www.oracle.com

注意:安裝路徑中不要出現空格和中文

將程序翻譯成計算機所能理解的語言 --- 編譯

Java文件在編譯完成之后會產生一個class文件 --- 字節碼文件(給計算機看的)

注意:

1. 程序要想運行需要一個入口 --- 主函數

2. class文件名和類名對應,在運行的時候要寫的是class文件名

3. 用public限制的類稱之為公共類,公共類要求類名和Java文件名必須一致。

4. 如果定義了包,在運行的時候需要添加包名(同一個盤符)

Java 包名.類名 java cn.tedu.de.Demo

5.如果想把Java文件編譯到指定包中,需要在包中聲明位置,然后使用下列命令編譯,再使用第四個知識點運行包內文件。

環境變量:指給當前的操作系統來指定運行參數的值

JAVA_HOME變量值為JDK的安裝路徑。

Path=%JAVA_HOME%\bin;

PS:不同盤符下的編譯和調用

編譯: javac D:\\(java文件的位置)包名.java

? ? ? 例子:javac D:\\OperatorDemo.java

運行:java(空格)-cp(空格)D:\\(java文件的位置)(空格)包名

?? 例子:java(空格)-cp(空格)D:\\(空格)OperatorDemo? ?

關鍵字

在Java中有特殊的含義。

到目前為止一共是53個關鍵字 --- 2個關鍵字沒有使用:const/goto --- 保留字

注意:關鍵字都是小寫的

標識符

在程序自定義的名稱

命名規則

由字母(常見語言的基本字符)、數字、_、$組成(但是減少使用$)

雖然java支持中文命名,但是減少使用

數字不能開頭

不能使用關鍵字

區分大小寫? Demo demo

見名知意

沒有主函數,程序依然能夠編譯

DAY? 02

復習:

1. Java跨平臺:基于JVM。針對每一個操作系統都有不同的jvm與之對應,jvm在這個過程中屏蔽了各個操作系統之間的差異性。

2. Java的技術結構:JAVASE JAVAEE JAVAME

3. JDK、JRE、JVM:JRE包含了JVM+核心類庫(Java程序運行所需要的基本的支持),為程序的運行提供環境。JDK包含了JRE+開發工具。

4. 入門程序:Java程序一定是寫到Java文件(.java);程序運行需要入口---主函數;類編譯完成之后會產生一個class文件。

5. javac -d 包的存放位置 要編譯的Java文件

? java包名.類名? ?

java cn.tedu.de.Demo?

6. 環境變量:JAVA_HOME=JDK的安裝路徑,Path = %JAVA_HOME%\bin;

7. 關鍵字:有特殊含義的單詞 --- 53個關鍵字 --- 2個保留字:const/goto --- 所有的關鍵字都是小寫

8. 標識符:程序自定義的名稱。由字母、數字、_、$組成,支持中文命名。不能以數字開頭,不能使用關鍵字,區分大小寫。見名知意。

駝峰命名法

類名/接口名:如果由多個單詞組成,那么每一個單詞的首字母大寫。 HelloWorld

變量名/方法名:如果由多個單詞組成,那么第一個單詞的首字母小寫,其余單詞的首字母大寫 playGame main

包名:如果由多個單詞組成,那么每一個單詞之間用 . 隔開,所有字母都是小寫 cn.tedu.de

常量名:如果由多個單詞組成,那么每一個單詞之間用_隔開,所有字母都是大寫 PLAY_GAME

注釋 單行注釋之間可以嵌套 ,多行注釋之間不能嵌套,文檔注釋不能嵌套多行注釋。

用于解釋說明的文字

// 注釋文字 單行注釋

/* 注釋文字*/ 多行注釋

/** 注釋文字 */文檔注釋 --- 里面的注釋內容可以利用javadoc命令提取出來形成文檔(就是對程序的說明書)

代碼內容:? javadoc文件名.java

字面量

在計算機中不可改變的量

整數常量:所有的整數 7 15 186 -42

小數常量:所有的小數 3.12 8.005 6.0 9.00

字符常量:將一個字母、數字或者是符號用 ‘’ 標識起來 ‘a’ ‘+’ ‘5’ ‘小’ ‘ ’

字符串常量:將一個或者多個字符用 “” 標識起來 “abc” “+” “”

布爾常量:true/false --- 用于表示邏輯值

空常量:null

進制

計數方式

二進制:0-1,滿2進1 1+1=10 11+1=100 111+1=1000。在程序中以0b/0B開頭標記一個二進制數字(從JDK1.7開始)? 0b1001 0b00101

八進制:0-7,滿8進1? 7+1=10 27+1=30 77+1=100要求以0開頭標記一個八進制數字 045 053

十進制:0-9,滿10進1 Java中數字默認就是十進制

十六進制:0-9,A-F,滿16進1 9+1=a a+1=b f+1=10 39+1=3a 3f+1=40? 99+1=9a 9f+1=a0 af+1=b0 ff+1=100要求以0x/0X作為開頭標記? 0xB3

進制的轉換

十進制轉換為二進制:將一個十進制數字不斷的除以2,然后獲取余數,將余數倒序排列,排列之后的結果就是對應的二進制

二進制轉化為十進制:從這個二進制數字的最低位次開始,然后每一位乘以當前的2的位次次冪,最后求和。

十進制轉化為其他進制:十進制數字向哪個進制轉化那么久除以對應的進制,然后取余數,將余數倒排

其他進制轉化為十進制:從這個進制的數字的低位次開始,然后按位次乘以當前的進制的位次次冪,最后求和

二進制轉化為八進制:從二進制數字的低位次開始,每三位劃分為一組產生一個八進制數字,最高位如果不足三位,補0。最后將產生的八進制數字排列 --- 三變一

八進制轉化為二進制:每一位八進制數字產生3位二進制數字,如果不足三位,補0. --- 一變三

十六進制和二進制之間的轉換類比八進制和二進制的轉換

擴展:十進制小數轉換為二進制

絕大部分的小數轉化為二進制都是無限的 --- 所以計算機在存儲小數的時候會產生舍入誤差

變量

在程序中用于存儲數據的容器。

變量不能重名。

變量必須先定義后使用

變量必須先給值后使用

變量必須在哪兒定義就在哪兒使用

擴展:計算機存儲單位

每一個二進制數字稱之為1位 --- bit - b

字節- Byte - B? 1B = 8b

千字節 - kilobyte - KB 1KB = 210B = 1024B

兆字節 - MB -> GB -> TB -> PB

8Mb = 1MB

100Mb = 12.5MB

3GB = 3000MB --- 在通信領域是按照千進制計算

數據類型

基本數據類型

數值型

整數型

byte - 字節型-? 1個字節 - -27~27-1 -> -128~127

byte b = 25; byte b2 = 127; byte b3 = -128;

short - 短整型 - 2個字節 - -215~215-1 -> -32768~32767

short s = 800; short s2 = 1500;

int - 整型 - 4個字節 - -231~231-1 -> -2.1*109~2.1*109 - Java中,整數默認為int類型

int i = 5;?

long - 長整型 - 8個字節 - -263~263-1 -> -1018~1018 需要以L/l作為結尾標記

long l = 54L;

浮點型

float - 單精度 - 4個字節 -> -1038~1038 - 需要以f/F作為結尾

double - 雙精度 - 8個字節 -> -10308~10308 Java中小數默認為double類型 - 小數結尾可以添加D/d作為標記

double d = 4.5; double d2 = 2.58; double d3 = 9.54D;

char - 字符型 - 2個字節 -> 0~65535 - 存儲用的就是utf-16?

char c = ‘a’; char c2 = '\ua4f3'; char c3 = ‘中’;

轉義字符

\t-制表符 table \r-回車 return \n-換行next?

\\-反斜杠\? \’-單引號? \”-雙引號

擴展:將字符轉換數字的過程稱之為編碼 --- 編碼表

ISO-8859-1 - 西歐碼表 - 1個字節表示1個字符 a

gb2312 - 國標碼 - gbk - 2個字節表示1個字符 - 收錄了常見的簡體漢字以及一部分常見的繁體漢字

Unicode編碼體系 - 收錄了世界上常見語言的基本字符 - 規定了一系列的編碼規則 - utf-8-> 3個字節表示一個字符 utf-16 -> 2個字節表示1個字符

注意:規定無論哪張碼表兼容西歐碼表

k 1 1 1 1

區 X 2 3 2

boolean - 布爾型 - true/false,用于表示邏輯值

boolean b = true; boolean b2 = false;

引用數據類型

數組[]?

類 class

接口interface?

數據類型的轉換

自動類型轉換/隱式轉換

byte b = 125;

int i = b;

規律一:小的類型自動轉化為大的類型

short s = 7;

long l = s;

long l = 500; // 500是一個整數,整數默認為int,int的范圍比long小,所以可以自動轉換

float f = 56.71F;

double d = f;

int i = 300;

double d = i;

規律二:整數類型可以自動轉化為浮點類型,可能會產生舍入誤差

int i = 500;

float f = i; // i是int類型,int的取值范圍比float小,所以int可以自動轉化為float

long l = 259L;

float f = l;

float f = -25; // -25是整數

char c = ‘a’;

int i = c;

規律三:字符可以自動提升為整數

強制類型轉換/顯式轉換

int i = 35;

byte b = (byte)i;

規律一:當把大的類型轉化為小的類型的時候,因為補碼的換算問題,所以可能會產生一些想不到數據

double d = 6.4;

int i = (int)d;

規律二:小數在轉化為整數的時候是舍棄小數位

擴展:數據的原反補三碼

數據類型的最高位是符號位 --- 如果最高位是0,則表示一個正數;如果最高位是1,則表示一個負數。

計算機中存儲的是數據的補碼,計算的也是數據的補碼

直接計算出來的二進制數字是數據的原碼

如果是正數,那么原反補三碼一致

int i = 7;

00000000 00000000 00000000 00000111 原碼

00000000 00000000 00000000 00000111 反碼

00000000 00000000 00000000 00000111 補碼

如果是負數,那么反碼是在原碼的基礎上,最高位不變,其余位0<->1;補碼是在反碼的基礎上+1

int j = -9;

10000000 00000000 00000000 00001001 原碼

11111111 11111111 11111111 11110110 反碼

11111111 11111111 11111111 11110111 補碼?

注意:規定用-0表示當前類型的最小值

運算符

算術運算符

+ - * / % ++ --

注意:

1. byte/short/char在運算的時候自動提升為int

2. 整型在運算的時候保持類型不變

3. 小類型和大類型運算,結果一定是大類型

4. 任意整數/0 - ArithmeticException - 算術異常

?? 任意非零數字/0.0 任意非零小數/0 - Infinity - 無窮大

0/0.0 0.0/0.0 0.0/0 - NaN - Not a Number - 非數字

DAY 03

復習:

1. 注釋:是程序中用于解釋說明的文字 - 文檔注釋中的文字可以利用javadoc命令進行提取

2. 字面量:整數、小數、字符、字符串、布爾、空

3. 進制:實際上是一種計數方式。

二進制:0-1,滿2進1,需要以0b開頭(從JDK1.7開始)

八進制:0-7,滿8進1,需要以0開頭

十進制:0-9,滿十進1,程序中默認就是十進制

十六進制:0-9,a-f,滿16進1,需要以0x開頭

注意進制之間的轉換規則

4. 變量:數據類型 變量名 = 數據; - 變量必須在定義的范圍內使用;變量必須先定義后使用,也必須先給值后使用

5. 數據類型:

基本數據類型

byte short int long float double char boolean

byte的取值范圍:-128~127

整數默認為int,小數默認為double

long類型需要以l/L作為結尾

float類型需要以F/f作為結尾

char類型的默認編碼是utf-16 - 2個字節

boolean用于表示邏輯值

引用數據類型

數據[] 類class 接口interface

6. 數據類型的轉換

隱式轉換

小類型可以自動轉化為大類型

整數可以自動轉化為小數,可能會產生精度損失

字符可以自動轉化為整數

顯式轉換

大類型轉換為小類型,因為字節的損失可能導致數據不精確

小數轉換為整數的時候需要舍棄小數位

運算符

算術運算符

+ - * / % ++ --

注意:

1. byte/short/char在運算的時候會自動提升為int

2. 整數的運算結果一定是整數

3. 小類型和大類型運算結果一定是大類型

4. 任意整數/0 - ArithmeticException

非零數字/0.0 非零小數/0 - Infinity

0.0/0.0 0.0/0 0/0.0 - NaN - 非數字

% 取模運算 - 取余運算

9%4=1 3%8=3

-9%4=-1 9%-4=1 -9%-4=-1

%的結果的正負看的是%左邊數據的正負 -> 如果左邊的數字是一個正數,那么結果就是正數;反之,那么結果就是負數

5%1.4=0.8 6.3%1.7=1.2?

++/-- 自增/自減運算

++/--如果在變量之前,那么先自增/自減,然后參與后續運算

++/--如果在變量之后,那么先將值取出來參與運算,然后變量再自增/自減

int i = 6;

// int j = i++ + ++i; -> 14

int j = ++i + i++; -> 14

byte/short/char都可以參與自增運算

char c = ‘b’;

int i = c + 2; -> 100

‘a’ ~ ‘z’ -> 97~122 ‘A’ ~ ‘Z’ -> 65~90 ‘0’ ~ ‘9’ -> 48~57

char c = ‘0’;

int i = c + 3; -> 51

賦值運算符

= += -= *= /= %= &= |= ^= <<= >>= >>>=

byte/short/char可以參與賦值運算

除了=以外,其余的符號都要求這個變量得先有值

注意:在Java中不支持連等定義但是支持連等賦值

int i = 5;

i += i *= i -= 3; -> 15

i = 5 + (5 * (5 - 3));

int j = 7;

j -= j *= j++; -> -42

j = 7 - (7 * 7);

關系/比較運算符

==相等 !=不等 > < >= <=

注意:不支持連著的比較方式

邏輯運算符

注意:邏輯運算符算的是邏輯值

&與 |或 !非 ^異或 &&短路與 ||短路或

true&true=true true&false=false false&true=false?

false&false=false

true|true=true true|false=true false|true=true

false|false=false

!true=false !false=true

true^true=false true^false=true false^true=true

false^false=false

&&:如果前邊的表達式的結果為false,則后邊的表達式不再運算,整個表達式的結果就確定為false

||:如果前邊的表達式的結果為true,則后邊的表達式就不再運算,整個表達式的結果就確定為true

注意:||如果在&&的前邊可以把&&短路掉

位運算符

注意:位運算符針對整數的補碼進行運算,所以運算結果也是補碼

& | ^ << >> >>> ~取反

交換值的方式

方式一:異或法

int i = 5, j = 9;

i = i ^ j;

j = i ^ j; -> j = i ^ j ^ j; -> j = i;

i = i ^ j; -> i = i ^ j ^ i; -> i = j;

方式二:加減法

int i =5, j = 9;

i = i + j;

j = i - j; -> j = i + j - j; -> j = i;

i = i - j; -> i = i + j - i; -> i = j;

方式三:追尾法

int i = 5, j = 9;

int temp = i;

i = j;

j = temp;

總結:三種方式的比較

異或法的效率是最高的。只能針對整數進行交換,局限性太大

加減法的效率是低于異或但是高于追尾。理論上可以交換數值類型,但實際上很少用于交換小數

追尾法的效率是最低的??梢越粨Q任意一個類型的值

三元運算符

格式:邏輯值 ? 表達式1 : 表達式2

執行順序:先執行邏輯值,如果邏輯值為true,則執行表達式1;反之則執行表達式2

三元表達式本身是一個表達式,意味著這個表達式執行完成之后需要有一個結果 --- 這個結果必須能定義對應類型的變量來接住

a > b ? “abc” : true; -> 沒有辦法定義一個統一類型的結果來存儲,這種寫法就是錯誤的

double d = a > b ? 3 : 5.25;

float f = a > b ? ‘a’ : 3.5f;

練習: 輸出分數對應的等級 >=90-A >=80-B >=70-C >=60-D <60-E

擴展:從控制臺獲取數據

import java.util.Scanner;

Scanner s = new Scanner(System.in);

int i = s.nextInt(); // 獲取整數

double d = s.nextDouble(); // 獲取小數

String str = s.next(); // 獲取字符串

運算符的優先級

~ ! ++ -- * / % + - << >> >>> 關系 邏輯 & | ^ 三元 賦值

一元 > 二元 > 三元 > 賦值(程序的運行順序是從上到下,從左到右,一定要注意運算符的優先級)

流程控制

順序結構:指代碼是從上到下從左到右來依次編譯運行的

分支結構

判斷結構

if(邏輯值){

代碼塊;

}

執行順序:先執行邏輯值,如果邏輯值為true,則執行代碼塊;反之則不執行

注意:如果if中的代碼塊只有1句話,那么可以省略{}不寫

if(邏輯值){

Code1;

} else {

Code2;

}

執行順序:先執行邏輯值,如果邏輯值為true,那么執行Code1;反之執行Code2

練習:

1. 輸入三個數字,獲取三個數字中的最小值

2. 輸入一個數字表示重量,如果重量<=20,則每千克收費0.35元;如果超過20千克不超過100千克的范圍,則超過的部分按照每千克0.5元收費;如果超過100千克,則超過的范圍按照每千克0.8元收費。計算輸入的重量對應的總費用

if(邏輯值1){

Code1;

} else if(邏輯值2){]

Code2;

}

...

else {

Code;

}

執行順序:先執行邏輯值1,如果邏輯值1為true,則執行Code1;反之則執行邏輯值2,如果邏輯值2為true,則執行Code2;反之則順次繼續往下執行

練習:

輸入一個數字表示月份,然后輸出這個月份所對應的季節。3-5-春 6-8-夏 9-11-秋 12、1、2-冬

Day04

復習:

1. 運算符

算術:

% - 取余 - 注意結果的正負號

++/--在變量之前需要先自增后運算;在變量之后先運算后自增;byte/short/char參與運算

賦值:

除了=,其他的符號都要求變量先有值才能使用

byte/short/char可以參與賦值運算

不允許連等定義但是允許連等賦值

比較:

不允許用比較運算符表示一個連續的范圍 --- 3 < n < 5

邏輯:

^:相同為假不同為真

&&和||的短路特性

位:

針對整數的補碼進行運算

交換值的方式:追尾法、加減法、異或法

三元:

執行順序:先執行邏輯值,如果邏輯值為true則執行表達式1;反之執行表達式2

三元表達式中的兩個式子的結果類型必須能夠轉化

流程控制

順序結構:指代碼從上到下從左到右依次編譯運行

分支結構

判斷結構

if(){}

if(){}else {}

if(){}else if(){}

練習:輸入一個數字,然后輸出這個數字表示星期幾

3 -> 星期三

選擇結構

switch(選擇){

case 選項1:Code1;break;

case 選項2:Code2;break;

...

}

switch()中需要一個選項,選項只能是byte/short/char/int,從JDK1.7開始,允許使用String

如果每一個case之后都有break,case順序不影響結果

如果有一個或者多個case之后沒有break,那么這個時候case之間的順序影響結果

練習:輸入兩個數字以及一個符號,輸出這兩個數字在這個符號下運算產生的結果

5 9 + -> 14

switch(){

case “+”:...

case “-”:...

}

練習:輸入三個數字表示年月日,輸出這一天在這一年是第幾天

2012 3 5 ---> 65

2014 3 5 ---> 64

需要判斷平年閏年:逢百整除400;不逢百整除4

2012 % 4 == 0 --- true

2100 % 400 == 0 --- false?

循環結構

用于完成一些相同或者相似的重復的操作

while(邏輯值){

Code;

}

執行順序:

練習:

1. 求1-100以內所有的奇數的和 --- i = 1; i += 2;

2. 打印100以內能被3整除而不能被7整除的數字 --- 先獲取3的倍數? int i = 0; i += 3;

3. 輸入一個數字,輸出這個數字是一個幾位數

4. 輸入一個數字,輸出這個數字的所有的因數 --- 從1開始,逐個數字取余這個輸入的數字,看是否能夠整除

20:1 2 4 5 10 20

定義一個循環,需要三個要素:定義一個變量來控制次數,利用判斷條件決定循環結束;在循環過程中需要改變變量

do{

Code;

} while(邏輯值);

注意:無論條件是否滿足,do-while的循環體必然至少執行一次。

for(定義循環變量; 控制條件; 改變循環變量){

Code;

}

習慣上如果變化不規律或者次數不確定一般使用while循環;如果變化規律或者是次數固定,一般是用for循環

求1-10的和 --- for循環

int sum = 0;

for(int i = 1; i <= 10; i++){

sum += i;

}

從控制臺獲取一個大于10的奇數

Scanner s = new Scanner(System.in);

int n = s.nextInt();

// 使用while循環

while(n < 10 || n % 2 == 0){

n = s.nextInt();

}

// 使用for循環

for(; n < 10 || n % 2 == 0; n = s.nextInt()){

}

練習:打印九九乘法表

1*1=1

1*2=2 2*2=4

1*3=3 2*3=6 3*3=9

。。。

練習:

百錢百雞 --- 3文錢1只公雞,2文錢1只母雞,1文錢3只小雞;100文錢如何買恰好100只雞? --- 先定義一個循環表示公雞,嵌套一個循環表示母雞,計算小雞的個數,根據各種雞的個數來計算錢數是否為100

break和continue

break:用于選擇結構和循環結構,表示結束當前的一層結構

continue:只能用于循環結構,表示跳過本次循環繼續下次循環(只能跳過一層循環)

擴展作業:一個循環打印九九乘法表

數組

存儲同一類型的多個數據的容器---大小是固定的

數組會對放入其中的數據(元素)進行編號,編號是從0開始的 - 下標

數組的容量 --- 長度

定義格式

數據類型[] 數組名 = new 數據類型[長度];

int[] arr = new int[5]; --- 表示定義一個能存儲5個整型元素的數組

arr[3] = 10;

內存

Java將所占用的內存劃分為了5塊:棧內存、堆內存、方法區、本地方法棧、PC計數器(寄存器)

棧內存

用于存儲變量的。變量在棧內存使用完成之后會立即移除出棧內存。

堆內存

用于存儲對象(數組是一種特殊的對象)的。元素在存入堆內存中之后會自動的賦予默認值:byte/short/int-0 long-0L float-0.0f double-0.0 char-‘\u0000’ boolean-false,其他類型的默認值都是null。對象在用完之后是在不確定的某個時刻被回收。

logab = logcb/logca? logabn = nlogab logab = loga + logb

DAY05

復習:

1. 流程控制

順序結構

分支結構:

判斷結構:if, if-else, if-else if

選擇結構:switch-case --- 選項的類型可以是byte/ short/ char/ int, 從JDK1.7開始,允許使用String。case之后有無break,那么他的順序將會影響結果

循環結構:while, do-while, for

do-while的循環體無論如何都會至少執行一次。

在次數固定或者是變化規律的前提下,建議使用for循環;在次數不固定或者變化不規律的情況下,建議使用while循環

循環嵌套

break和continue

break:用于選擇和循環結構,表示終止當前的一層結構。

continue:用于循環結構,表示跳出當前的一次循環繼續下次循環(也是只能跳一層)

數組

用于存儲多個同一類型的數據的容器 --- 大小是固定的

下標是從0開始,所以最大下標是長度-1

定義格式

數據類型[] 數組名 = new 數據類型[長度];

數據類型[] 數組名 = new 數據類型[]{元素1, 元素2, ...};--- 這種方式在定義的時候給定了具體的元素同時也規定了數組的長度

int[] arr = new int[]{5,3,7,1,8,9,2}; 表示定義了一個元素類型為整型的數組,數組中的元素是5,3,7,1,8,9,2,意味著數組的長度是7

數組類型[] 數組名 = {元素1, 元素2, ...}; --- 不允許分開定義

數組的內存

數組存儲在堆內存中,并且在堆內存中會自動賦予默認值:byte/short/int - 0, long - 0L, float - 0.0f, double - 0.0, char - ‘\u0000’, boolean - false,其他所有類型的默認值都是null

注意:數組在賦值的時候賦的實際上是地址

數組的應用

1. 操作指定位置上的元素:數組名[下標]

2. 獲取數組的長度:數組名.length

3. 遍歷數組

// 方式一:下標是從0->length - 1

for(int i = 0; i < arr.length; i++){

System.out.println(arr[i]);

}

// 方式二:直接獲取每一個位置上的元素

// 增強for循環

// 只能遍歷數組但是不能改變數組中的元素

for(int i : arr){

System.out.println(i);

}

// 方式三:將數組中的元素一個個的拿出來拼接成字符串

String str = Arrays.toString(arr);

System.out.println(str);

4. 獲取數組中最值(最大值/最小值)

方式一:定義變量來記錄數組中的最大值,然后遍歷數組,讓數組中的元素依次與最大值進行比較;如果大于最大值,則將用這個元素覆蓋原來的最大值

方式二:定義變量來記錄最大值的下標

5. 數組的排序

時間復雜度:在程序中找一段必然會執行的代碼,將這段代碼的執行時間認為是單位1,執行這個單位1需要的次數就是時間復雜度 - 時間復雜度不考慮系數,一般來說是找最高階 -> O(nx), O((logn)x),O(nx(logn)y)

空間復雜度:這段程序執行所需要額外耗費的空間就是空間復雜度

擴展:冒泡排序和選擇排序都是穩定的排序算法 --- 排序算法的穩定與否的依據是相等的元素在排序的時候是否需要交換

6. 反轉數組:首尾互換 --- 時間復雜度O(n),空間復雜度o(1)

7. 數組元素的查找:

數組元素無序的前提下,獲取一個元素的位置只能通過遍歷的方式一一比較。

如果數組元素有序,使用二分查找 --- 空間復雜度o(1),時間復雜度O(logn)

2x = n -> x = log2n -> logn --- 默認以2為底數

8. 數組的復制

System.arraycopy(要復制的數組, 要復制的起始下標, 存放的數組, 要存放的起始下標, 個數);

二維數組

存儲的元素是一維數組 --- 存儲數組的數組

定義格式

數據類型[][] 數組名 = new 數據類型[包含的一維數組的個數][每一個一維數組的長度];

int[][] arr = new int[3][5]; 表示定義了一個能存儲3個整型一維數組的二維數組,每一個一維數組能5個整型元素

數據類型[][] 數組名 = new 數據類型[包含的一維數組的個數][];

int[][] arr = new int[5][]; 定義了一個能存儲5個整型一維數組的二維數組 --- 必須先保證這一位上的一維數組先給定大小,然后再給值

arr[0] = new int[3];

arr[1] = new int[7];

arr[2] = new int[2];

數據類型[][] 數組名 = {{數組1}, {數組2}, {數組3},...};

int[][] arr = {{2,4,1}, {4,7,2,9}, {3}, {5,0,6,7,4,3}}; --- 二維數組的大小為4

注意:[]如果在變量名之前那么緊跟數據類型,也就意味著后面定義的變量實際上都是數組;但如果[]在變量名之后,那么[]只管跟著的這個變量不會去影響其他的變量。

內存存儲

練習:楊輝三角

1

1 1

1 2 1

1 3 3 1

1 4 6 4 1

特點:每一行的開始和結束都是1;其余位置的元素是計算:

arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];

輸入一個數字n表示行數,輸出對應的前n行

DAY06

復習:

1. 數組

定義格式

內存存儲:數組是存儲在堆內存中,在棧內存中存儲堆內存中對應的地址。數組在存入堆內存的時候需要自動賦予默認值。--- 數組在賦值的時候給的也是地址

int[] arr1 = new int[3];

int[] arr2 = arr1; // 指向同一個空間

數組應用:

數組的遍歷:通過下標遍歷,增強for循環

元素的排序:冒泡排序(相鄰兩個元素兩兩比較),選擇排序(選定一個元素和其他元素來依次比較)--- 時間復雜度O(n2),空間復雜度o(1),是穩定的排序算法;Arrays.sort只能進行升序排序

數組的反轉:首尾互換 - 時間復雜度O(n),空間復雜度o(1)

元素的查找:元素無序,循環遍歷;元素有序,二分查找 - 時間復雜度O(logn),空間復雜度o(1)

數組的復制:System.arraycopy - Arrays.copyOf

2. 二維數組

用于存儲一維數組

定義格式

內存存儲:二維數組的每一個位置上存儲的是對應的一維數組的地址;如果沒有指定一維數組的大小,那么二維數組的位置上存儲得是null

方法

當在程序中需要重復使用某段邏輯或者功能,將這段邏輯提取出來形成一種新的形式---方法,也叫函數

定義格式

修飾符 返回值類型 方法名(參數列表){

方法體;

return 返回值;

}

// 寫一個方法求1-n的和

// 明確結果:求1-n的和,那么和是一個整數,意味著結果是int類型,所以返回值類型也就是int類型

// 明確未知量:求1-n的和,n在方法中不能自動產生,需要使用方法的人來傳入一個值,這個時候需要以參數形式來體現

// 定義方法的時候在()中定義了參數 --- 形式參數 - 形參?

public static int sum(int n){

int sum = 0;

for(int i = 1; i <= n; i++){

sum += i;

}

return sum;

}

練習:

1. 哥德巴赫猜想:任何一個大于等于6的偶數都可以分解成兩個質數之和。

16 = 3 + 13

16 = 5 + 11

輸入大于等于6的偶數,然后輸出它所有的分解形式

思路:在這個過程中要重復執行的代碼是判斷質數

2. 親密數:如果A的所有因子(含1而不含本身)之和等于B,而且B的所有因子(含1而不含本身)之和等于A,A和B就是一對親密數

16:1+2+4+8 = 15

15:1+3+5 = 9

打印5000以內所有的親密數

思路:需要重復執行的邏輯是獲取一個數的所有因子之和

方法的重載

在同一個類中,存在了方法名一致而參數列表不同(參數個數不同或者是對應位置上的參數類型不同)的方法 --- 方法的重載 --- 依靠參數列表來區分調用的方法

方法在調用的時候會進行模糊匹配---參數類型在沒有最符合的情況下會自動提升,就會導致提升之后可能會有多個匹配

方法的傳值

注意:

1. 方法是在棧內存中執行

2. 方法在傳值的時候,基本類型傳遞的實際值,數組傳遞的是地址。

3. 傳遞地址之后,如果地址沒有發生改變,則代碼執行影響原來的數組;如果地址發生了改變,則改變之后的代碼不會影響原來的數組

方法的遞歸

展現形式:方法調用了自己本身

練習:輸入一個數字n,求n! = n(n-1)(n-2)...1

6! = 6*5*4*3*2*1=720

注意:在遞歸的時候,當執行次數過多會產生StackOverflowError - 棧溢出錯誤

總結:在一些場景中,如果能確定這一項和前n項的關系,那么可以使用遞歸 ---> 逆推

IDE --- 智能開發工具

Eclipse(日食) --- 免費、基于插件、開源、綠色?

Kepler(開普勒) -> Luna(月神) -> Mars(火星) -> Neon(霓虹燈) -> Oxygen(氧氣)

面向對象

面向對象是一種思維方式,相對于面向過程而言的。

面向過程在流程中關注動作執行的每一個細節 --- 自己動手做

面向對象重點找這個對象,只要找到了對象,那么這個對象所具有的功能就能夠被使用 --- 找別人做

面向對象一定比面向過程好嗎?--- 不一定 ---相對簡單的事務建議使用面向過程,相對復雜的事務建議使用面向對象

面向對象本身是基于面向過程的

類與對象的關系

根據一類對象進行抽取和總結,將這類對象的特征抽取成了屬性,將這類對象的行為抽取成了方法,用類表示這一類對象 -> 類是對象的抽取和概括的過程

對象的內存存儲

成員變量和局部變量

1. 定義位置:成員變量定義在類內方法外;局部變量是定義在方法或者是語句里面

2. 作用范圍:成員變量作用在整個類內;局部變量是只能作用在定義它的方法或者語句中

3. 內存位置:成員變量隨著對象的創建而存在了堆內存中并且在堆內存中賦予了默認值;局部變量在棧內存中存儲

4. 生命周期:成員變量再對象創建的時候出現,在對象被回收的時候銷毀;局部變量在方法或者語句執行的時候創建,方法或者語句執行完成之后就立即銷毀

Eclipse - 日食

免費、開源、綠色、基于插件

Eclipse是由Java語言開發的

Kepter - Luna(JDK1.7) - Mars - Neon - Oxygen

Intelli J --- IDEA --- 收費

Ctrl + c 復制

Ctrl + v 粘貼

Ctrl + x 剪切

Ctrl + s 保存

Alt + / 快捷提示鍵

Ctrl + 1 錯誤提示鍵

Ctrl + Shift + o 導包

Alt + Shift + S source

Ctrl + Shift + f 調整格式 --- 不能在任何輸入法下使用

Alt + ↑/↓? 整行上移/下移

Ctrl + F11 運行

Ctrl + F 搜索

Alt + Ctrl + ↑/↓ 整行向上/向下復制一行

Ctrl + D 刪除一行

Ctrl + / 添加/取消單行注釋

Ctrl + Shift + / 添加多行注釋

Ctrl + Shift + \ 取消多行注釋

Alt + ← 切換到上一個編輯的頁面

Ctrl + N 新建

Ctrl + W 關閉當前的界面

Alt + F4? 關閉當前的應用程序

DAY? 07

復習:

1. 方法:需要重復使用某段邏輯的時候,就將這段邏輯提取成新的形式。

定義格式:修飾符 返回值類型 方法名(參數列表){方法體; return 返回值;} --- 形參,實參 --- 方法名+參數列表 -> 方法簽名

public static int add(int i, int j){} --- add(int, int)

方法的重載:在同一個類中存在了方法名一致而參數列表不同(參數的個數/對應位置上的參數類型)的方法

方法的傳值:基本類型傳遞的是實際值;對象傳遞的是地址,地址不變的前提下可以改變其中的屬性或者元素。

方法的遞歸:在方法中調用了自己本身。當遞歸層次太深會出現StackOverflowError --- 棧溢出錯誤 --- 遞歸的思路往往是逆推的思維方式

2. 面向對象與面向過程的比較:都是思維方式。面向過程是注重流程中的每一個步驟,清楚每一個步驟中的細節(自己做);面向對象是注重對象,只要擁有了對象就能使用對象身上的功能(找別人做)。面向對象是基于面向過程的。相對簡單的事務使用面向過程,相對復雜的事務使用面向對象。--- 面向對象更適合于團隊的開發;面向過程一般而言比面向對象更適合于效率開發。

3. 類與對象的關系:類是對象的概括/抽取,對象是類的具體實現

4. 對象的內存存儲:對象是存儲在堆內存中,在棧內存中會存儲對象的地址引用。對象在存儲到內存中之后其中的屬性會自動賦予默認值。--- 對象在使用完成之后不一定立即移出堆內存而是在不定的某個時刻被回收。

5. 成員變量和局部變量:定義位置、作用范圍、內存位置、生命周期

構造方法

特點:與類同名而沒有返回值類型的方法

作用:創建對象

this關鍵字

this關鍵字在類中調用本類里面的屬性和方法,代表當前在活動的對象。

this語句 -> this(參數列表) - 表示在本類的構造方法中調用本類對應形式的其他的構造方法 - this語句必須放在構造方法的第一行

代碼塊

構造代碼塊:定義在類中用{}包起來的代碼 --- 在創建對象的時候先于構造方法執行

局部代碼塊:定義在方法中用{}包起來的代碼 --- 提高了棧內存的利用率

面向對象的特征

封裝、繼承、多態(抽象)

封裝

將代碼進行提取和總結,抽取成不同的形式 --- 封裝

體現形式:方法、類(屬性的私有化 - 將屬性限制為私有的,然后提供對外的設置和獲取的方法,然后在方法中進行限制使數據更加符合常理)

優勢:提高了代碼的復用性,保證了數據的合法性

權限修飾符

指在Java中用于限定使用范圍的關鍵字

本類中 子類中 同包類中 其他類中

public 可以 可以 可以 可以

protected 可以 可以 可以 不可以

默認 可以 同包子類可以 可以 不可以

private 可以 不可以 不可以 不可以

練習:定義一個類表示矩形(長方形),提供獲取周長和面積的方法

繼承

如果一些類中含有相同的代碼,那么可以將這些相同的代碼提取到一個新的類中,然后通過extends關鍵字讓原來的類和新的類產生關系 --- 繼承。 通過繼承,原來的類就稱之為了子類(派生類),新的類就成了父類(超類/基類)。

子類通過繼承父類可以使用父類中的一部分方法和屬性

注意:子類繼承了父類的全部的數據域(方法+屬性),但是繼承之后只有一部分數據域對子類可見

在Java中,支持的是類和類之間的單繼承 -> 一個子類只能繼承一個父類,但是一個父類可以有多個子類

單繼承一定優于多繼承嗎? - 不對

多繼承比單繼承能夠更好的提高代碼的復用性

class A {

public int m(){return 9;}

}

class B {

public boolean m(){return false;}

}

class C extends A, B{}

C c = new C();

c.m(); // 返回值類型能確定嗎?

多繼承導致在調用方法的時候可能產生歧義

優勢:提高代碼的復用性,避免方法的調用產生歧義

super關鍵字

在子類中用于表示父類對象的引用,可以在子類中調用父類中的方法的屬性。

super語句 --- 子類在繼承父類之后,子類的構造方法中會含有一個super語句。如果沒有手動指定super語句,那么默認使用super()調用父類無參的構造;如果父類只提供了含參構造,那么子類就必須手動提供對應形式的super語句 --- super語句必須在子類構造方法的首行

方法的重寫/覆蓋

在父子類中存在了方法簽名相同的非靜態方法。遵循 “兩等兩小一大”原則:

1. 方法簽名相同

2. 如果父類中的方法的返回值類型是基本類型/void,那么子類重寫的方法的返回值類型與父類一致

class A {

public void m(){}

}

class B extends A {

public void m(){}

}

3. 如果父類中的方法的返回值類型是引用類型,那么子類在重寫方法的時候,返回值類型要么與父類一致,要么是父類方法返回值類型的子類

class A {}

class B extends A {}

class? C {

public A m(){return null;}

}

class D extends C {

public B m(){return null;}

}

4. 子類重寫的方法的權限修飾符的范圍要大于等于父類中對應方法的權限修飾符的范圍

class A {

public void m(){}

}

class B extends A {

public void m(){}

}

注意:如果父類中的方法用private修飾,那么這個方法對子類不可見,所以此時與子類中的方法構不成重寫

多態

編譯時多態:方法的重載

add(2, 4) -> add(int, int)

add(3, 1, 7) -> add(int, int, int)

運行時多態:向上造型和方法的重寫 --- 基于繼承的

注意:如果使用向上造型來創建對象,那么這個對象所能調用的方法看的是父類中的聲明,方法如何執行看的是子類中的實現過程

重寫的理解

1. 子類重寫的方法的權限修飾符的范圍要大于等于父類中對應方法的權限修飾符的范圍

2. 如果父類中的方法的返回值類型是引用類型,那么子類在重寫方法的時候,返回值類型要么與父類一致,要么是父類方法返回值類型的子類

注意:Java中所有的基本類型之間沒有繼承關系,之所以能夠自動提升,是因為所表示的范圍是否能夠包含

DAY08

復習:

1. 構造方法:

特點:與類同名而沒有返回值類型

作用:用于創建對象

當類中沒有手動指定構造方法的時候在編譯的時候自動添加一個無參構造

2. this關鍵字:代表本類的在活動的對象,用于在本類中調用本類的方法和屬性 --- this語句,表示調用本類中其他的對應形式的構造方法,必須放在首行

3. 代碼塊:

構造代碼塊:在創建對象的時候先于構造方法執行一次 --- 用于完成一些初始化操作

局部代碼塊:提高棧內存的利用率

4. 封裝:

體現形式:方法、類(屬性的私有化 -> 將屬性設置為private,對外提供對應的get/set的方法,在方法中可以進行限定使數據更加符合場景要求)

優勢:提高復用性,保證數據的合法性

5. 繼承 :用extends關鍵字來完成繼承關系 --- 支持的類與類之間的單繼承 --- 單繼承和多繼承的優劣性 --- 提高復用性,避免方法調用產生歧義 --- 子類可以繼承父類全部的數據域,但是只有一部分可見

6. 多態:

編譯時多態:方法的重載

運行時多態:

向上造型:用父類來聲明用子類來創建 --- 對象能干什么看的是父類,對象如何執行方法看的是子類。

方法的重寫(Override):父子類中存在了方法簽名完全相同的非靜態方法。--- 兩等兩小一大

7. 權限修飾符:public protected 默認 private --- protected在子類中使用的時候指的是在對應的子類中使用,不能跨子類使用

8. super關鍵字:在子類中表示父類對象的引用,用于調用父類中的方法和屬性 --- super語句,表示在子類的構造方法中調用父類對應形式的構造方法。子類構造方法中如果沒有手動指定super語句,那么默認調用父類無參構造(super());如果父類只提供了含參構造,那么子類的構造方法中必須手動提供對應形式的super語句

static - 靜態

修飾符 - 用于修飾數據、方法、代碼塊以及內部類

靜態變量

用static修飾變量,稱之為靜態變量,也叫類變量。在類加載的時候加載到了方法區,并且在方法區中被賦予了默認值。靜態變量是先于對象出現的,所以習慣上是通過類名來調用靜態變量。每一個對象存儲的是這個靜態變量在方法區中的地址,所以靜態變量是被這個類的所有對象所共享的

靜態變量能否定義到構造方法中?---不能。靜態變量是在類加載的時候出現,先于對象出現。構造方法在創建對象的時候執行。

注意:

1. 類是加載到方法區中的

2. 類是在第一次使用的時候才加載,加載之后就不會移除

練習:定義一個類,統計這個類創建對象的個數

靜態方法

用static修飾的方法,稱之為靜態方法。靜態方法隨著類的加載而加載到方法區中,但是在方法區中不執行只存儲,在方法被調用的時候到棧內存執行。靜態方法先于對象存在,所以習慣上是通過類名來調用靜態方法。

main Arrays.sort() System.arraycopy()

靜態方法中可以定義靜態變量嗎?--- 不能 --- 靜態方法在調用的時候執行,靜態方法執行的時候里面的變量才能初始化;靜態變量是在類加載的時候初始化

靜態方法中能否使用this/super?--- 不行 --- this代表當前在活動的對象,靜態方法先于對象存在

能否在靜態方法中直接使用本類中的非靜態方法/非靜態屬性?--- 不行

public class A {

int i = 5;

public static void m(){

int j = (this.)i;

}

}

靜態方法可以重載嗎?---可以

靜態方法可以被繼承嗎?---可以

靜態方法可以重寫嗎?---不可以

靜態方法雖然不能被重寫,但是父子類中可以存在方法簽名一致的靜態方法 --- 靜態方法的隱藏(hide)

注意:父子類中可以存在方法簽名一致的方法,要么都是非靜態(重寫)要么都是靜態(隱藏)

靜態代碼塊

用static{}包起來的代碼 --- 在類加載的時候執行一次

執行順序:父類靜態 -> 子類靜態 -> 父類非靜態 -> 父類的構造方法 -> 子類非靜態 -> 子類的構造方法

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容