# 第一章:瞭解(chapter) ## 複習方法: 找到視頻 每個章節 結合筆記。 https://www.bilibili.com/video/BV1fh411y7R8?p=266&spm_id_from=pageDriver&vd_source=5c60787a1cdddc0e6d23d53b ...
第一章:瞭解(chapter)
複習方法: 找到視頻 每個章節 結合筆記。
第一階段:建立編程思想(包括:基本語法、數組、排序和查找、面向對象編程、零錢通、房屋出租系統、迷宮、八皇後、漢諾塔 )
第二階段:提升編程能力(包括: 枚舉和註解、Exception、常用類、集合、泛型、線程、IO流、坦克大戰)
第三階段: 增強分析需求,代碼實現能力(包括: 網路編程、反射、Mysql、JDBC和連接池、正則表達式、Java8 Java11 新特性、馬踏棋盤、滿漢樓、多用戶通信系統)
如何快速學習Java新技術.(重點!!)
步驟1:需求 | 步驟2:解決方法 | 步驟3:引出新技術和知識點 | 步驟5:快速入門:(基本的程式:CRUD)先進行增刪改查 |
---|---|---|---|
工作需求 跳槽 技術控 | 1. 能否使用舊技術.能解決,但不完美\解決不了,新技術有是什麼優勢. | 步驟4: 學習新技術和知識點的基本原理和基本語法(不要考慮細節.)先會用再考慮血肉. | 步驟6:開始考慮研究技術細節\註意事項\使用規範\如何優化. 優化永無止境. 這個才是拉開差距的地方.每個人看到的點不一樣. |
第一小節: 1~3
1. JAVA就業方向
-
JavaEE軟體工程師
- 電商\團購\眾籌\sns\教育\金融
-
大數據軟體工程師
- 應用\演算法\分析和挖掘
-
Android軟體工程師
- 安卓軟體工程師
2.JAVA開發場景-ssm android hadoop(大數據) 程式員角度
- Spring(輕量級的容器框架)
- SpringMVC(分層的web開發框架)
- MyBatis(持久性框架)
- android(安卓)
- hadoop(大數據)
3.應用方面
-
企業級應用
- 軟體系統\各類型網站\金融\電信\交通\電子商務等.
-
Android平臺應用
- 安卓電視\app
-
移動(嵌入式開發)領域:
- 嵌入式開發 pos機\汽車通訊設備\機頂盒\大屏幕投影娛樂設備等.
4.程式是什麼
程式是: 電腦執行某些操作或解決某些問題而編寫的一系列有序指令的集合.
編程上 輸入->計算->輸出這樣的步驟.
電腦上, 編程文件->javac 講java文件轉錄成class文件 ->再運行class文件,才能實現.
第二小節:
JVM的主要組成部分及其作用有哪些 - 編程語言 - 億速雲 (yisu.com) 細看這部分
1.java 概述
-
java8和java11 是LTS 公共版本
java8 23-可擴展到30-年
java11 23-可擴展到26-年
-
java95年第一個版本,GOSLING(gosling)為創始人
-
javaSE(標準版)JAVAEE(企業版)\JAVAME(移動終端和編程.)沒用了已經
2.java特點
-
Java是面向對象的(oop)
-
java是健壯的.強類型機制 \異常處理 \垃圾自動回收等是其健壯性的重要保障
-
java語言是跨平臺性的.(主要因為JVM)
Test.java文件編譯成Test.class文件. 這個class文件可以在Windows和Linux操作系統下運行.這就是跨平臺性.
根本原因是JVM.不同操作系統,使用不一樣的JVM. -
java語言是解釋型語言.
- 解釋性語言:javascript\PHP\java
- 編譯性語言:c\c++
區別:
解釋性語言: 編譯後的代碼,不能直接被機器執行,需要解釋器來執行,( javac )(就是轉化為class文件).
編譯性語言:可以直接被機器執行.
所以難怪 性能差一些.
3.java運行機制及運行過程
-
java核心機制\java虛擬機[JVM java virtual machine]
-
基本介紹:
1.)JVM 是一個虛擬的電腦,具有指令集並使用不用的存儲區域. 負責執行指令 \管理數據 \記憶體 \寄存器\都包含在JDK**中
2.)對於不同的平臺,有不同的虛擬機.
3.)java虛擬機機制屏蔽了地城運行平臺的差別,實現了"一次編譯,到處運行"
-
運行過程 :
集成開發工具寫的java文件 通過javac(編譯器編譯)成class文件(位元組碼文件) 然後載入到jvm中 先載入類裝載器(裝載類和靜態類等) 然後開始運行程式
java文件通過編譯器變成了.class文件,接下來類載入器又將這些.class文件載入到JVM中。 其實可以一句話來解釋:類的載入指的是將類的.class文件中的二進位數據讀入到記憶體中,將其放在運行時數據區的方法區內,然後在堆區創建一個 java.lang.Class對象,用來封裝類在方法區內的數據結構。
最後由解釋器
4.什麼是JDK\JRE
JDK:
- JDK全稱(Java Development kit) java開發工具包
- JDK= JRE + java的開發工具 (java,javac,javadoc,javap等)
- JDK是提供給Java開發人員使用的,其中包含了java的開發工具,也包括了JRE,所以安裝了JDK就不用單獨安裝JRE了.
JRE:
- JRE(Java Runtime Environment) java 運行環境
- JRE= JVM +java的核心類庫[類]
- 包括Java虛擬機(JVM java virtual Machine)和java 程式所需的核心類庫
- 需要運行JAVA程式 就只要安裝JRE就可以了,因為已經編譯過了.'
JDK = JRE + java開發工具
JRE = JVM + 核心類庫
jre 就是jvm + 核心類庫 保障java程式運行
jdk 在jre的基礎上添加了開發工具 java javac javadoc javap等等
5.JDK 安裝
公共JRE eclipse有時候要使用公共JRE. 可以不安裝.
環境變數的作用,是為了在dos的任何目錄都能使用java和javac
環境變數界面有兩個
一個是用戶變數
一個用系統變數
分別有不同的作用域
僅當前用戶
和使用該電腦的所有用戶
第三小節:
1.java入門.
第一個java文件. 列印 "Hello,World".
源文件 | 位元組碼文件 | 結果 |
---|---|---|
先編寫 .java文件 | javac編譯 成 .class 文件 | 運行 類 結果 |
運行問題:, 中文編碼報錯.
因為cmd控制台使用的GBK格式, 右鍵cmd控制台查看控制台的屬性
需要更改為GBK格式 才能使用,也可以使用GB18030,
2.java的格式問題
-
源文件 必須是 java為拓展名
-
main方法有固定格式不能更改
public static void main(String[] args){}
-
嚴格區分大小寫\分號";"結尾\大括弧成對出現
-
一個源文件中有且只有一個public類,文件名也需要按這個類名命名.其他類個數不限,
可以將main寫在非public類中,然後指定運行非public類,入口方法就是非public的main方法了.
一個java文件有多個類,編譯後,沒一個類 都會生成一個.class文件.
每個非public類中都可以使用主方法,因為生成的獨立的class文件, 只要調用對應的類的class文件.
第四小節
1.轉義字元
Tab鍵在DOS可以自動補全。
\t == table 製表符
'\r' 回車,回到當前行的行首,而不會換到下一行,如果接著輸出的話,本行以前的內容會被逐一覆蓋;
'\n' 換行,換到當前位置的下一行,而不會回到行首
Unix系統里,每行結尾只有“<換行>”,即"\n";Windows系統裡面,每行結尾是“<回車><換行>”,即“\r\n”;Mac系統里,每行結尾是“<回車>”,即"\r";。
一個直接後果是,Unix/Mac系統下的文件在Windows里打開的話,所有文字會變成一行;而Windows里的文件在Unix/Mac下打開的話,在每行的結尾可能會多出一個^M符號。
// \t:製表位\實現對齊的功能. 空四個位元組.
System.out.println("北京\t深圳\t上海");
// \n: 換行符
System.out.println("jack\nsmith\nmary");
// \\: 一個\
System.out.println("\\t"+"\n雙斜杠"+"\\\\t");
// \": 一個"
// \': 一個'
//跳過
// \r:一個回車
//1. 會先輸出黃烘南,\r後面的字 會替換掉前面的黃烘南三個字
System.out.println("黃烘南\r好");
//好烘南
//回車加換行.
System.out.println("黃烘南\r\n好好學習");
//黃烘南
//好好學習
//練習
System.out.println("書名\t作者\t價格\t銷量\n三國\t羅貫中\t120\t1000");
//書名 作者 價格 銷量
//三國 羅貫中 120 1000
2.容易產生的錯誤
1與l
0和o
中英文符號問題
拼寫錯誤
非法字元錯誤問題
3.註釋(comment)
做好註釋.
多行快捷鍵是ctrl +shift+/ 單行快捷鍵是ctrl+/
多行註釋不可以在嵌套多行註釋.
單行\多行\文檔
//單行註釋 comment
/*多行註釋
多行快捷鍵是ctrl +shift+/ 單行快捷鍵是ctrl+/
多行註釋不可以在嵌套多行註釋.
*/
文檔註釋:
註釋內容可以被JDK提供的工具 javadoc所解析,生成一套網頁文件形式體現的程式說明文檔,一般寫在類的前面
瞭解基本格式\如何生成\實例
/**
* @author hhn
* @version 1.0
*
* */
public class Hello{
//編寫一個主方法 程式入口
public static void main(String[] args){
//輸出
System.out.println("黃烘南 is studying java ");
}
}
javadoc附錄:
標簽 | 描述 | 示例 |
---|---|---|
@author | 標識一個類的作者,一般用於類註釋 | @author description |
@deprecated | 指名一個過期的類或成員,表明該類或方法不建議使用 | @deprecated description |
指明當前文檔根目錄的路徑 | Directory Path | |
@exception | 可能拋出異常的說明,一般用於方法註釋 | @exception exception-name explanation |
從直接父類繼承的註釋 | Inherits a comment from the immediate surperclass. | |
插入一個到另一個主題的鏈接 | ||
插入一個到另一個主題的鏈接,但是該鏈接顯示純文本字體 | Inserts an in-line link to another topic. | |
@param | 說明一個方法的參數,一般用於方法註釋 | @param parameter-name explanation |
@return | 說明返回值類型,一般用於方法註釋,不能出現再構造方法中 | @return explanation |
@see | 指定一個到另一個主題的鏈接 | @see anchor |
@serial | 說明一個序列化屬性 | @serial description |
@serialData | 說明通過 writeObject() 和 writeExternal() 方法寫的數據 | @serialData description |
@serialField | 說明一個 ObjectStreamField 組件 | @serialField name type description |
@since | 說明從哪個版本起開始有了這個函數 | @since release |
@throws | 和 @exception 標簽一樣. | The @throws tag has the same meaning as the @exception tag. |
顯示常量的值,該常量必須是 static 屬性。 | Displays the value of a constant, which must be a static field. | |
@version | 指定類的版本,一般用於類註釋 | @version info |
4.java代碼規範
-
類、方法的註釋,要以javadoc的方式來寫
-
非java Doc的註釋,往往是給代碼的維護者觀看,如何修改等問題
-
使用tab操作,實現縮進,預設整體向右移動,使用shift+tab整體左移
-
運算符和 = 兩邊習慣性各加一個空格 比如: int = 1 + 1; 要每個都分開
-
源文件使用utf-8編碼
-
行寬不超過80 一行不超過80
-
代碼編寫次行風格和行尾風格.
次行: 每次進行大括弧都進行換行
行尾: 大括弧在行尾.
5.DOS命令
DOS原理:
指令--->發送給DOS系統, (1.接受指令,2.解析指令,3.執行指令.)--->最終體現在windows操作系統中
顏色:
·命令:color f0
幫助:color ?
作用:改變背景及字體顏色
·命令:cls
作用:清屏
目錄
·命令:dir
作用:瀏覽當前文件夾的內容(帶<dir>標識的為文件夾,否則為文件)
其他用法:
dir 指定路徑
dir d:\
dir d:\pic
dir /a #瀏覽所有內容,包括隱藏內容
·命令:盤符:
作用:切換分區, 如:c: d: e:
·命令:cd ..
作用:退出一級目錄
·命令:cd 文件夾名
作用:進入文件夾
·Tab鍵:補全路徑功能
·命令:cd \
作用:直接退到根目錄
命令: tree 加目錄名
作用:生成子級目錄樹
·路徑:
相對路徑:針對當前路徑有效,如: ..\456
絕對路徑:從根開始寫路徑,如: \123\345
·註釋:
fsutil fsinfo drives #可以查看當前系統的分區列表
文件操作:
·命令:md 文件夾 [文件夾 文件夾 ....]
·命令:rd 文件夾 [文件夾 文件夾 ....]
作用:刪除空文件夾
命令:rd 文件夾 /s/q
(/s是遞歸刪除,/q是無提示刪除)
作用:無提示遞歸刪除非空文件夾
·創建文件方法:
echo 字元串 >>[路徑\]文件名.擴展名
註釋:>>和>都可以將命令的輸出內容輸入到某文件中,若文件不存在,則同時創建該文件
·>>為追加
·>為覆蓋
·>nul為不顯示回顯
·2>為錯誤信息輸出並覆蓋
·2>>為錯誤信息輸出並追加
·2>nul 經典用法:屏幕上不要有任何的報錯
如:rd . /s/q 2>nul
·顯示文件內容命令:
type 文件名.擴展名
作用:瀏覽一個文件的內容
·命令:del 文件名.擴展名
作用:刪除文件
·del *.txt #刪除所有txt結尾的文件
·del *.* #刪除所有文件
·del *.* /s /q #無提示刪除所有文件
註釋:*為通配符,代表任意字元,任意長度
?為單字元匹配
·ren 原名 新名 #重命名,可以重命名文件和文件夾。
·命令:copy [路徑\]源文件全名 目標路徑[\新文件全名]
作用:複製文件
·命令:move [路徑\]源文件全名 目標路徑[\新文件全名]
作用:移動文件
6.相對\絕對路徑
相對路徑:
從當前目錄開始定位,形成的一個路徑.
只有單個目錄
"java快速學習\javacode"
從頂層開始定位,形成的路徑.
"C:\Users\qianl\Desktop\java快速學習\javacode"
例子:
從當前目錄訪問另一個目錄的文件.
相對路徑:
"cd ..\..\abc2\test200\hello.txt"
絕對路徑:
"cd d:"
"\abc2\test200\hello.txt"
第二章:變數
第一小節:
1.字元串拼接
57 是一個常量
"57" 是一個字元串常量(5和7這兩個字元的序列)
計算時:
System.out.println("57 + 32 = " + (57 + 32));
1.先計算小括弧,再由於是字元串 + 數字 (或者數字 + 字元串)都會將 數字 變成 字元串. 最終拼和成"57 + 32 = 89".
如果不加括弧,則會變成: 字元串 + 57 然後 字元串 + 32 .變成"57 + 32 = 5732"
如果計算放在前面,那麼就沒有關係. 因為從左往右進行.
2.變數的聲明
變數三大要素:
類型+名稱+值
int x = 1; 聲明和賦值 (聲明加初始化 也是初始值)
int類型 名為x的盒子 盒子里的值為 1;
integer 整數
3.數據類型
類型名稱 | 關鍵字 | 占用記憶體 | 取值範圍 |
---|---|---|---|
位元組型 | byte | 1 位元組 | -128~127 |
短整型 | short | 2 位元組 | -32768~32767 |
整型 | int | 4 位元組 | -2147483648~2147483647 |
長整型 | long | 8 位元組 | -9223372036854775808L~9223372036854775807L |
單精度浮點型 | float | 4 位元組 | +/-3.4E+38F(6~7 個有效位) |
雙精度浮點型 | double | 8 位元組 | +/-1.8E+308 (15 個有效位) |
字元型 | char | 2 位元組 | ISO 單一字元集 |
布爾型 | boolean | 1 位元組 | true 或 false |
1.整數類型
long類型需要註意加 "l" 或者: "L" 通常大寫
int x = 1; int只有8個位元組
int x = 1L; long有16個位元組,範圍超了.
int x = (int)(1L);
2.浮點類型
預設是double類型
浮點數 = 符號位 + 指數位 + 尾數位.
因為小數,精度丟失 (所以都是近似值)
**d也可以使用d為結尾 ** 可加可不加 小數預設是double
即: double d1 = 3d; //ok的 d1 = 3.0
float f = 1.1f; 4個位元組
double d = 1.1; 8個位元組
//如果是0開頭的小數可以省略
double d1 = 0.123
double d2 = .123
//也可以使用科學計數法
5.12e2 //512.0
5.12e-2 // 0.0512
使用陷阱:就是分數問題.
double num1 = 2.7;
double num2 = 8.1/3; // 計算是2.7 輸出的是 2.69999999997
num2 是一個接近2.7的小數,是近似值.
原因是 8.1這個數被轉變為二進位的時候,最小二倍數法,取得的小數是很長的,超過了double的精度,所以這個數被截斷了,除於3的時候就變成了一個不足2.7的數了.
原因是 8.1這個數被轉變為二進位的時候,最小二倍數法,取得的小數是很長的,超過了double的精度,所以這個數被截斷了,除於3的時候就變成了一個不足2.7的數了. 之後再用乘二取餘法
應該以兩個數的差值的絕對值,在某個進度範圍內進行判斷.
Math.abs() 獲取絕對值
使用Math類的方法
3.char類型
單個字元使用char 長字元串使用String類
char 單引號, String使用雙引號 這裡的String是"類" 首字母大寫才是類
char的本質是"ISO 單一字元集"; 也就是一串數字
char類型也是可以計算的,本質是數字,所以計算的結果也是一串數字對應的字元
存儲:
比如:'a'是97 會轉換成二進位(110 0001),然後進行存儲.
char c1 = 'a';
char c2 = '黃';
char c3 = '\t'; //表示製表符的四個空格
char c4 = 97; //表示ISO單一字元集
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
a
黃
a
只有英文字元,不用漢字就不用那麼多個字元了.
註意,utf-8 是一個可變長的所以不是所有漢字都是3個位元組(1到6個位元組)
4.boolean類型
註意點: java中不能使用0或者非0整數來替代true和false python 非強制性語言可以 預設是False
boolean bool = true;
if (bool == true) {
System.out.println("考試通過了,恭喜");
}else {
System.out.println("下次努力");
}
4.二進位
byte是一個8位的數,
第一個是符號位,後面為實際存儲
十進位轉二進位:
最小二倍數法
首位為符號位, 指數位+尾數位, 進行科學計數法以後,小數點浮點,所以叫浮點數. 通過補碼來進行數據還原.
取出來的叫原碼 要轉化為反碼 反碼+1 變補碼 然後java都是補碼進行計算的
二進位轉十進位:
乘2取餘法
乘2 整數位大於1捨去,取餘數
5.java8 線上API
https://www.matools.com/api/java8
按包——》找類——》找方法。也可以直接檢索
API的結構 :註意 每個包內 介面,類,異常有很多個。
java基礎包
java.applet Applet所需的類和介面
java.awt 圖形用戶界面所需的類和介面
java.beans Java bean所需的類和介面
♥ java.io 系統輸入/輸出所需的類和介面
♥ java.lang Java語言編程的基礎類和介面
java.math 支持任意精度整數和任意精度小數的類和介面(與lang下的math類更專業)
♥ java.net 網路應用的類和介面
java.nio 定義緩衝區,它們是數據容器,並提供其他NIO包的概述
java.rmi 遠程調用(RMI)的類和介面
java.security 用於安全框架的類和介面
♥ java.sql 訪問和處理數據源中數據的類和介面
java.text 支持按與語言無關方式處理文本、數據、數字和消息的類和介面
java.time 日期,時間,瞬間和持續時間的主要API
♥ java.util 集合框架、事件模型、日期和時間機制、國際化等的類和介面
java擴展包等
javax.accessibility 定義用戶界面組件與提供對這些組件的訪問的輔助技術之間的合同
javax.activity 包含ORB機械在解組時拋出的活動服務相關異常
javax.annotation.processing 用於聲明註釋處理器和允許註釋處理器與註釋處理工具環境通信的設施
javax.crypto 提供加密操作的類和介面
javax.imageio Java Image I / O API的主要包………
javax.rmi 支持RMI-IIOP的類和介面
javax.serverlet 支持serverlet編程的類和介面
javax.sound 支持音頻設備數字介面(MIDI)的類和介面
javax.swing 擴充和增強基本圖形用戶界面功能的類和介面
javax.transaction 包含有幾個關於事務上下文異常的類
org.omg.CORBA 支持OMG CORBA API到Java語言映射的類和介面
等等
6.類型轉換
小範圍轉變成大範圍能自動轉型,大變小需要強制轉換.
小類能自動繼承大類的方法, 但是大類沒有小類的方法.
1.自動轉換:
精度小的類型自動轉換為精度大的數據類型,這就是自動轉換 精度(容積)
auto == automatic (自動化)
表示自動化的意思
註意事項:
所以沒聲明具體類型的數字 預設為 int類型
- 多類型數據混合計算,自動轉換為容量最大的類型,然後計算
- byte, short 和char之間不能互相自動轉換
- byte ,short和char之間可以計算,會先轉換為int類型, 因為char算是數字 (int類型).
- boolean不參與轉換.
- 表達式結果,自動提升為操作數中最大的類型.
2.強制類型轉換
基本方法:
int x = (int)(1L);
需要的值類型 = (需要的值類型)(被轉換的類型);
兩種可能:
1.精度缺失,
沒有四捨五入 int等整型 直接去除小數點後的數
2.數據溢出
不再聲明的範圍內的數 溢出
細節說明:
主要是char和int變數之間,需要強制轉換,.
我的結果:
正確結果:
註意:
1.第一和第二題, 9和11 都預設為int類型,計算取最高的類型.
2.第三題,計算全部轉換成了最高的float類型 可以自動轉換給double.
3.第四題, byte和short進行計算會自動變成int類型 這時候 就不能再自動轉給byte short 和char了
3.String類型轉換成基本數據類型
基本數據類型轉String ,加雙引號
String轉基本數據類型, 需要使用包裝類
每一個數據類型都有一個包裝類,也就是將基本數據類型變成對應的"類"
parse 解析
基礎類型與對應包裝類編寫區別
除了int Integer
char Character
其他都是首字母大寫
String轉換char類型,
使用 String.charAt( index ) 方法,返回在index位置的char字元。(返回值:char )
使用 String.toCharArray( ) 方法,將String 轉化為 字元串數組。(返回值:char[] )
也可以轉換成字元串數組
char轉換成String類型
//1.效率最高得到一種方法
String s = String.valueOf('c');
//2.將字元串數組轉化為字元串
String s = String.valueOf(new char[] {'G','e','o','o','o'});
//3.用 Character 的 toString(char) 方法 ==> 實際上還是調用了String.valueOf(char)
String s = Character.toString('c');
//4.new 一個 Character 調用 toString()
String s = new Character('c').toString();
//5.直接用 空 String 拼接 'c'
String s = "" + 'c' ;
//第5種方法效率最低,因為String類是 final 屬性
// "" + 'c' 時候需要創建新的 String 類 ,如果進行很多次拼接則要創建很多個類虛擬機棧可能會溢出
註意事項:
- String的數據是非數字的時候,轉換成整數的話,就會拋出異常.程式會中止.那麼捕獲和處理方法需要寫出.
7.鍵盤輸入規範
註意點:
1.導入包 import java.util.Scanner;
2.固定格式: Scanner stdIn = new Scanner(System.in);
3.不能以 Scanner為類名, 會重寫Scanner方法.
4.限制輸入的數據類型 ,靠next+類型 來限制.
//註意導入類(文本掃描)
import java.util.Scanner;
public class Inport{
public static void main(String[] args) {
// 固定格式
Scanner stdIn = new Scanner(System.in);
System.out.println("請輸入要計算的值");
System.out.println("x:");
int x = stdIn.nextInt();
System.out.println("y:");
int y = stdIn.nextInt();
System.out.println("x + y = " + (x + y));
System.out.println("x - y = " + (x - y));
System.out.println("x * y = " + (x * y));
System.out.println("x / y = " + (x / y));
}
}
8.生成隨機數(Random)
也可以使用Math方法進行,註意看API的 Random的方法
//註意導入類 隨機數類
import java.util.Random;
public class Random01{
public static void main(String[] args) {
// 固定格式
Random Rand = new Random();
int lucky = Rand.nextInt(10); //0~9的隨機數.
System.out.println("今天的幸運數字是:" + lucky + ".");
// 1. 1~9的隨機數
// 2. -9~-1的隨機數
// 3. 10~99的隨機數
int one = 1;
int num = Rand.nextInt(10); //1~9的隨機數.
System.out.println("今天的幸運數字是:" + (num + one) + ".");
int num1 = Rand.nextInt(9);//0到 8
System.out.println("今天的負數是:" + (-(num1 + one)) + "."); //- (1到9)
int num2 = Rand.nextInt(90);// 0到89
System.out.println("今天的正數是:" + (num2 + 10) + ".");//+10 變成10-99
}
}
//Math.Random 是生成隨機數,會生成一個 double類型的數 [0.0,1.0)
//任務,一直生成1到100的數
for (; ; ) {
//加1才能成為1到100
i = (int)(Math.random()*100) + 1;
System.out.println(i);
j++;
if (i == 97){
System.out.println(i + "次數" + j);
break;
}
第三章:運算符
1.算術運算符
加減乘除 求餘 自增自減(按照順序進行計算.)
有兩個操作數的也叫二元運算符
除法計算問題:
記住一個問題:
計算以最高精度的數為準,整數預設int 小數預設double
所以下麵的 10 / 4 = 2 10.0 / 4 = 2.5
取模問題:
取模有一個公式:
本質: m % n = m - (int)(m / n) * n
註意:餘值結果符號和 m (被模數) 符號有關,m為負數則餘值為負數,m為正數則餘值為正數。 同時註意,(m/n的結果 是會被化為int類型的)
自加問題:
註意 :
int j = 8;
int k = j++; //取值後運算.
以後輸出的k = 8, j = 9;
原理:
使用了中間數 temp 來進行臨存儲 值
替換成 j與k
int j = 1;
k = j++;
// temp = j; k = temp; j = j + 1;
// 1 1 結果 k = 1 j = 2
//這樣更符合 先賦值,後運算.
int j = 1;
k = ++j;
// j = j + 1; temp = j; k = temp;
// j=2 temp = 2 k = 2
//這樣更符合 先賦值,後運算.
1.先賦值後計算:
i = 10; i1 = 11; i2 = 20
2.先計算後賦值
i2 = 19 ; i = i2 = 19; i1 = 11 ;
除法計算:
由於5/9 都是預設int類型,得到的小於1 所以直接捨去小數位,變成0 後面什麼都是0
更改方法:
改為5.0以後, 因為計算變成全部都是double類型, 所以變成了有小數位的,得到的結果也就有小數了.
2. 關係運算符
結果都是boolean類型 ,只有true和false兩種結果
通常在if的判斷語句中使用
= (表示賦值)
== 表示比較
hsp 是不是String類中的對象
3.邏輯運算符
分組學習:
短路 && || !
短路:
判斷條件時 , 判斷第一個條件就可能可以得到結果, 作用與& 和 | 相同,右邊的情況將不再執行. && 的時候 左邊為false 則短路 (只要有一個是假 就整個是假)
|| 的時候 左邊為true 則短路 (只要有一個真 就整個是真)
如下: 短路&& 由於a<1 不成立,後面的代碼將不再執行 也就是右邊的++b不再執行. ↑
輸出為: 4 和 9
邏輯 & | ^
^ 異或表示結果不同
例題1:
例題2:
4.賦值運算符
就是 計算的同時賦值.
1.註意 只能是變數,同時 左邊只能是變數, 效果等價正常加減乘除. 因為也是計算,所以會類型轉換(註意是,強制類型轉換! ) byte b = 2; b += 3 ; 也就是 b = (byte)(b+3);
5.三元運算符
三元運算符,可以替代簡單的 if 判斷計算.
註意: 最後的a和b結果是 結果後 會重新賦值與變動,
6.運算符優先順序
只有單目運算和賦值運算,才會從右向左進行. 慢慢熟悉
7.標識符規則
規則是強制
規範是公約但不強制
標識符: 就是所以可以自己命名字元的 就叫標識符
主要:
- 不能使用關鍵字和goto 這個保留字, 不能數字開頭 註意大小寫,
中間不能有空格!!
標識符規範:
-
類: 開頭大寫 駝峰
-
finial : 全大寫中間 _ 連接
-
方法,變數 totalNum 駝峰
8.進位問題
二進位:
0b 0B
八進位 0開頭
十六進位 0x 或者 0X
二進位轉十進位
八進位轉十進位
十六進位轉十進位
十進位轉二進位
最小二倍數法 倒取餘數
一個位元組是8位 前面補0
就是0010 0010
十進位轉八進位
十進位轉十六進位
二進位轉八進位 十六進位
原因: 2的三次方就是8 正好8進位
二進位轉十六進位
原因 : 2的四次方就是16 正好16進位
八進位轉二進位
十六進位轉換位二進位
9.位運算 位移運算(原碼\反碼\補碼) & | ^ ~
//>>> 叫無符號位移 沒有<<<符號
相當於除2和乘2 低位溢出 << 2 這個2相當於 2的次方
例子:
重點:
1.正數包括0 其反碼 補碼 都是他本身
2.負數的反碼是符號位除外取反, 補碼是 反碼+1
3.電腦全部使用的是補碼的形式進行的
4.運算結果要看原碼(也就是需要進行補碼的還原)
位運算規則
例子:
2&3的運算:
重點: int類型 是4個位元組的 一共 32位
計算是補碼的計算,
結果是原碼!
負數的取反運算
(~-2)
整數的取反
(~2)
第五章:程式控制結構 (開始理解編程思想)
1.順序控制
程式從上到下逐行執行,中間沒有任何判斷和跳轉
註意事項: 聲明和使用的順序 不能錯誤
例子如下:
2.分支控制( if else switch)
讓程式有選擇的執行,分支控制有:
1.單分支
基本語法:
單分支
if(條件表達式){
執行代碼塊; (判斷為 true時執行,否則跳過)
}
如果只有一條語句代碼塊 , 可以不用{}, 到那時還是建議使用
單分支流程圖:
2.雙分支
基本語法:
示意:
Scanner stdIn = new Scanner(System.in);
System.out.println("請輸入年齡");
int age = stdIn.nextInt();
if(age>18){
System.out.println("送進監獄");
}else {
System.out.println("送進管教所");
}
雙分支流程圖:
3.多分支
基本語法:
註意: 1)多分支中 可以沒有else語句, 如果所有條件都是false 則一個執行入口都沒有.
- 如果有else,所有表達式都是false 則執行else的代碼塊
多分支流程圖:
嵌套分支:
例題:
先進行是否決賽的判斷 所以獲取成績,只有成績達標了 才獲取性別
註意字元串變字元類型:
練習:
價格 money
獲取月份
獲取年齡
if(month 為 旺季){
if (18 < age){
票價 money/2
}else if( 18<= age && age <=60){
票價 money
}else{
money/3
}
}else{
if ( 18<= age && age <=60 ){
票價 = 40
}else {
票價 = 20
}
}
4.switch分支結構
swutch的結構:
由switch和 case語句塊組成
switch流程圖:
註意一點: 沒有break語句的 跳出switch的話, 就會直接執行語句塊2 不會進行判斷 也就是
穿透switch.
例子:
註意格式,還有輸入值與判斷值的類型對應
//固定格式:
Scanner stdIn = new Scanner(System.in);
System.out.println("請輸入a-g");
char day = stdIn.next().charAt(0);
switch(day){
case 'a':
System.out.println("今天星期一");
break;
case 'b':
System.out.println("今天星期二");
break;
case 'c':
System.out.println("今天星期三");
break;
case 'd':
System.out.println("今天星期四");
break;
case 'e':
System.out.println("今天星期五");
break;
case 'f':
System.out.println("今天星期六");
break;
case 'g':
System.out.println("今天星期日");
break;
default:
System.out.println("無效字元");
break;
}
switch 分支細節:
1.類型一致或能自動轉換,
2.返回值必須是固定類型()
3,必須是常量,不能是變數
4,default是可選的
5.沒有break會產生 switch穿透.
例題:
靈活思路
表達式是可以計算和轉換的,轉換成可以使用的返回值類型:
switch嵌套在if中
使用穿透switch:
就是條件合併,345 只顯示一條輸出語句
如下;
if和switch的比較:
switch 適合 值比較小 且符合6個類型的情況
if則是進行範圍判斷.
3.迴圈控制( for while dowhile 多重迴圈(雙迴圈))
1.for迴圈控制
基本語法:
註意四要素.
for迴圈流程圖:
先進行迴圈變數的初始化,然後判斷迴圈條件, 真則執行語句, 執行完成再進行迴圈變數的迭代
例題: 列印十次"Hello,world"
for(int i = 1;i <= 10;i++){ // 1 到 10次 輸出完 不滿足條件就跳出.
System.out.println("Hello,World");
}
for迴圈的細節:
1.條件判斷必須是Boolean值
2.初始化可以寫for 外面 然後只用一個變數名來引用 迭代可以寫執行語句後面. 執行順序一樣. 註意還是要 加 ";" 如果條件也進行省略 那就會死迴圈
如圖:
3, 註意初始化的多個需要類型一致,逗號分隔(格式) 迭代也能多條語句
4, 輸出結果為: 00,12,24
for迴圈重點例題:
列印1~100之間所以9的倍數,並統計個數,計算總和.
public class For01{
public static void main(String[] args) {
int sumNum = 0;
int j = 0;
int start = 1;
int end = 100; //將初始值和條件 變成 可以賦值的變數, 從解決個案問題 變成解決共性問題
int number = 9;
for(int i = start; i <= end; i++){
if(i % number == 0){
sumNum += i;
j += 1;
System.out.println("9的倍數:" + i );
}
}
System.out.println("個數:" + j);
System.out.println("和:" + sumNum);
}
}
編程思想問題:
2.while迴圈控制
基本語法:
while迴圈控制流程圖:
執行條件,進行迴圈體, 迭代
操作和迭代放一起了
例子:
3.do..while
do..while 是至少迴圈一次.
基本語法. 先執行 後判斷,
執行流程圖:
例題1:
例題2: 就是先打一頓再說
4.多重迴圈控制
就是迴圈的嵌套, for迴圈的嵌套 ,一般不要超過2次
分析: i可以取 0 1 j 可以 取 0 1 2 所以總次數是 2*3 一共6次
列印九九乘法表:
for(int i = 1;i <= 9;i++){
for(int j = 1 ;j <= i;j++){
System.out.print(j + "x" + i + "=" + i*j + "\t"); //print 不換行,+\t 排版
}
System.out.println(""); //列印完一輪開始換行
}
列印空心金字塔:
//列印*金字塔 1 3 5 7 9 個星 空格 星 與行數的關係
for(int i = 1;i <= 5; i++){
for(int k = 1;k <= (5-i);k++){ // 這裡的0 需要註意,要和i互動
System.out.print(" ");
}
for (int j = 1;j <= (2*i-1); j++) { //這裡也是 需要與i互動
System.out.print("*");
}
System.out.println("");
}
列印空心金字塔
//可以將i=5 替換成變數,獲得一個想多大就多大的空心金字塔
//列印空心*金字塔 1 3 5 7 9 個星 空格 星 與行數的關係
for(int i = 1;i <= 5; i++){
for(int k = 1;k <= (5-i);k++){ // 這裡的0 需要註意,要和i互動
System.out.print(" ");
}
for (int j = 1;j <= (2*i-1); j++) { //這裡也是 需要與i互動
/* if(i == 5){
System.out.print("*");
}else if (j == 1 || j == (2*i-1)) { //使得第一個星和最後一個星正常列印,同時排除最後一層金字塔
System.out.print("*");
}else{
System.out.print(" ");
}*/
if (j == 1 || j == (2*i-1) || i == 5) { //使得第一個星和最後一個星正常列印,同時排除最後一層金字塔
System.out.print("*");
}else{
System.out.print(" ");
}
}
System.out.println("");
}
4.迴圈終止,跳過,退出break 和 continue 和return
1.break:終止語句塊的執行
流程圖:
例題:
//Math.Random 是生成隨機數,會生成一個 double類型的數 [0.0,1.0)
//任務,一直生成1到100的數
迴圈跳出
//Math.Random 是生成隨機數,會生成一個 double類型的數 [0.0,1.0)
//任務,一直生成1到100的數
int i = 0; //收集隨機數
int j = 0;//收集次數
for (; ; ) {
System.out.println((int)(Math.random()*100) + 1); //加1才能成為1到100
i = (int)(Math.random()*100);
j++;
if (i == 97){
System.out.println(i + "次數" + j);
break;
}
}
註意事項:
可以通過標簽語句來指定嵌套語句中的那一層語句塊
沒有寫break 預設退出最近的(break所在的迴圈)
在1-100以內的數求和, 求出當和 第一次大於20的當前數
int sum = 0;
int num = 20;
int i = 1; //作用域擴大了
for(;i <= 100; i++){
sum += i;//累積
if(sum > num){
System.out.println("和>20時候 當前數i+" + i);
break;
}
}
System.out.println("當前數=" + i);//當前數
重點:equals比較
避免空指針, 就是name的值可能是null的 然後避免null去調用方法
2.continue (持續)
基本語法:
註意: 跳過本次執行,開始下次迴圈
流程圖:
繼續下一次迴圈
例題:
也可以使用標簽 (也就是goto)
3.return
1.return關鍵字並不是專門用於跳出迴圈的,return的功能是結束一個方法。 一旦在迴圈體內執行到一個return語句,return語句將會結束該方法,迴圈自然也隨之結束。與continue和break不同的是,return直接結束整個方法,不管這個return處於多少層迴圈之內。
章節綜合練習題:
題目1: break
註意: while的使用方法, 她可以直接使用true來進行無限迴圈
public static void main(String[] args) {
double money = 100000;
int number = 0;
while(true){
if (money > 50000) {
money *= 0.95;
number++;
}else if (money >= 1000) {
money -= 1000;
number++;
}else{
break;
}
}
System.out.println("剩下多少錢" + money + "次數" + number);
}
求水仙花數
System.out.println(number1 + "次數" + number2);*/
int number1 = 0;//水仙花數
int number2 = 0;//非水仙花數
for(int d = 100;d < 1000;d++){
int d1=d % 10;
int d2 =d / 10 % 10;
int d3 =d / 100 % 10;
if((d1 * d1 * d1 + d2 * d2 * d2 + d3 * d3 * d3) == d){
System.out.println(d);
number1++;
}else{
number2++;
}
}
System.out.println(number1 + "次數" + number2);
迴圈加雙判斷, 更加簡潔. if里嵌套if的方法
//每行輸出5個1-100之間不能被5整除的數
int num = 0;
for(int d = 1;d < 100;d++){
if((d % 5 != 0 )){
num++;
System.out.print(d+"\t");
if ( num % 5 == 0 ) {
System.out.println();
}
}
}
問題:聽懂和會做: 做題會、項目不會
首先,二者並不是等價的,只有知識,沒有實踐。
缺乏練習過程
聽懂教練的話,不去使用器械,並不會長肌肉。
思想與業務邏輯要聯繫、
我亦無他,唯手熟爾。
第六章:數組的重要性(array 數組)引用類型
使用現有的知識去考慮,設置單個變數去記錄每個數組的數,再進行計算。
數組,則是一個變數去處理一串同類型的數。
//數組類型 數組名 數據 0到5 就是六個數
double[] hens = {3,5,1,3.4,2,50};
//可以遍歷
double total = 0;
for(int i = 0; i < hens.length; i++){
//下標訪問數組
total +=hens[i];
}
System.out.println(total + "平均" + total/6);
1.數組的使用
1.數組初始化
1.動態初始化 1.
一共做了兩步:
聲明和創建數組一起.
數據類型 數據名[] = new 數據類型[大小] ;
//這是為了給c/c++程式員的寫法。
//java中還是放在前面
// 數據類型[] 數據名 = new 數據類型[大小];
dataType[] arrayRefVar = new dataType[arraySize];
2.動態初始化 2.
//第二種:
//先聲明 再賦值.
double[] a; //還沒使用內部空間,只是一個空值,
a = new double[10];// new了以後才開闢空間 一共10個 8個位元組的數據.
3.靜態初始化.
// 第二種方法: 直接賦值.
dataType[] arrayRefVar = {value0, value1, ..., valuek};
2.數組的註意事項
1,數組是相同類型.
2.數組中元素可以是所有類型 ,基礎類型和引用類型,但只能一種.
3.創建後,沒有賦值會有預設值.
-
int\short\byte\long\ 都是0
-
false\double 0.0
float\double 0.0
-
char \u0000
-
boolean false
-
String null
3.使用數組的步驟 : 1.聲明數組\開闢空間. 2. 給數組的元素進行賦值 3. 使用數組
4.數組下標從0開始.
5.使用範圍必須在下標範圍內 否則越界異常
6.數組屬於引用類型,數組型數據是對象(object). 就是數組的本質是個對象.
3.數組練習
1,創建一個char類型的26個元素的數組,分明放置'A'-'Z'.使用for迴圈訪問所以元素並列印出來.
//1,創建一個char類型的26個元素的數組,分明放置'A'-'Z'.使用for迴圈訪問所以元素並列印出來.
//1 先查找A的對應數字是多少.
char a = 'A';
System.out.println((int)a); // 65
// 創建可以容納26個字母的數組
char[] array1 = new char[26];
//賦值與列印數組
//方法一:
for(int i = 0;i < array1.length; i++){
array1[i] = (char)(65+i);
System.out.println(array1[i]);
}
//方法二:
int i = 0;
for(char element: array1){
element = (char)(65+i);
i++;
System.out.println(element);
}
2.請寫出一個數組int[] 的最大值{4,-1,9,23,10},並得到對應的下標.
//2.請寫出一個數組int[] 的最大值{4,-1,9,10,23},並得到對應的下標.
//比較大小 需要一個中間值來進行
int[] intArray = {3,-1,9,23,10};
int sum = 0; //sum = intArray[0]; 假設第一個數就是最大值
int subscript = 0;
System.out.println(intArray.length);//5
for(int i = 0; i < intArray.length; i++ ){ // int i = 1; 這樣可以直接從第二個數開始比較
if(sum < intArray[i]){
sum = intArray[i];
subscript = i;
}
}
System.out.println("最大值"+sum + "下標為"+subscript);
4.數組賦值機制 (assign 分配)
1.基本數據類型的賦值,這個值指的是具體的數據,而且互相互不影響.
//數值拷貝
int n1 =2; int n2 = n1;
//這個時候 n1 = 2 , n2 = 2;
2.數組在預設情況下,是引用傳遞, 賦的值是地址, 會影響原有的值
//assign(分配)
int[] arr1 = {1,2,3};
int[] arr2 = arr1;
arr2[0] = 10;
for(int element:arr1){
System.out.println(element);
}
10
2
3
值傳遞(值拷貝) 和 引用傳遞 的區別
值傳遞 (值拷貝)
引用傳遞
指向的是同一個空間
5.數組拷貝
使用Array方法進行拷貝,或者方法進行拷貝;
//數組拷貝 創建數組2成為同樣長度的數組
int[] arr1 = {10,20,30};
int[] arr2 = new int[arr1.length];
int x = 0;
for(int i1:arr1){
arr2[x] = i1;
x++;
}
//測試拷貝是否成功,修改數組2
arr2[0] = 19;
//列印數組1
for(int i1:arr1){
System.out.println(i1);
}
// 10 20 30
//列印數組2
for(int i2:arr2){
System.out.println(i2);
}
// 19 20 30
6.數組反轉
同一數組反轉.
註意迴圈次數 除於2
長度從1開始的 所以長度作為下標時 需要減1
//數組反轉
int[] arr = {11,22,33,44,55,66};
//反轉數組 使用中間變數
//使用變數
int reverse = 0;
for(int i = 0;i < arr.length/2; i++){ //因為是同時替換兩端的數,所以只要進行一半。 3.
reverse = arr[i];
arr[i] = arr[arr.length-1-i];
arr[arr.length-1-i] = reverse;
}
for (int i:arr ) {
System.out.println(i);
}
使用逆序賦值
註意: 第一 arr 逆序取值,賦值給arr2 (正向取值)
取值為下標時 長度-1
最後進行數組賦值,指向同一個地址.
arr原有的指向空間會被指定為垃圾, jvm空間不足時進行銷毀
7.數組擴容
動態添加元素,
數組擴容 需要一個中間數組.
//數組擴容
int[] arr = {1,2,3};
int[] arr1 = new int[arr.length + 1];
int reverse = 0;
for(int i = 0;i < arr.length; i++){
arr1[i] = arr[i];
}
arr1[arr1.length-1] = 4;
arr = arr1;
for (int i:arr ) {
System.out.println(i);
}
數組擴容 用戶決定是否繼續添加 也可以使用do while
//數組擴容 用戶決定是否繼續添加
Scanner stdIn = new Scanner(System.in);
int[] arr = new int[0];
for(;;){
System.out.println("請問是否繼續添加值 y/n");
char result = stdIn.next().charAt(0);
if(result == 'y'){
System.out.println("請問輸入要增加的數字");
int number = stdIn.nextInt();
int[] arr1 = new int[arr.length + 1];
int reverse = 0;
for(int i = 0;i < arr.length; i++){
arr1[i] = arr[i];
}
arr1[arr1.length-1] = number;
arr = arr1;
for (int i:arr ) {
System.out.println(i);
}
}else{
System.out.println("程式結束");
break;
}
}
for (int i:arr ) {
System.out.println(i);
}
2.排序
1.冒泡排序法:
五個元素 24,69,80,57,13
使數組成為從小到大的有序數列.
冒泡排序: 時間複雜度n^2
//冒泡排序 需要交換,就需要一個中介.
//需要註意的就是 判斷條件 (1.迴圈結束,2.if判斷條件)
int[] BubbleSort = {24,69,80,57,13};
int num = 0;
for(int i = 0;i < BubbleSort.length-1; i++){ //次數 進行4次就可以了
for(int j = 1; j < BubbleSort.length-i; j++){ // 小於(長度-i) 因為第一次就會篩出最大的一個
//有問題肯定是判斷出問題
if(BubbleSort[j-1] > BubbleSort[j]){
num = BubbleSort[j-1];
BubbleSort[j-1] = BubbleSort[j];
BubbleSort[j] = num;
}
}
}
for(int i = 0; i < BubbleSort.length; i++){
System.out.println(BubbleSort[i]);
}
2.冒泡排序優化:
使用標識,減少第一個迴圈
//冒泡排序 需要交換,就需要一個中介.
//需要註意的就是 判斷條件 (1.迴圈結束,2.if判斷條件)
int[] BubbleSort = {24,69,80,57,13};
int num = 0;
System.out.println(BubbleSort.length);
for(int i = 0;i < BubbleSort.length-1; i++){ //次數 進行4次 只需要4次就可以
int flag = 1;//每次迴圈重新初始化
for(int j = 1; j < BubbleSort.length-i; j++){ // 小於(長度-i) 因為第一次就會篩出最大的一個
//有問題肯定是判斷出問題
if(BubbleSort[j-1] > BubbleSort[j]){
num = BubbleSort[j-1];
BubbleSort[j-1] = BubbleSort[j];
BubbleSort[j] = num;
flag = 0;
//標記發生了交換
}
}
//運行完for第二個迴圈 就會進來判斷 沒有交換 就說明排序完成
if(flag == 1){
return;
}
}
for(int i = 0; i < BubbleSort.length; i++){
System.out.println(BubbleSort[i]);
}
冒泡排序優化: 因為內迴圈的後面幾位已經比較完成了 所以不用進行再次比較
記錄下最後交換的下標 來賦值給內迴圈結束時間.
//冒泡排序 需要交換,就需要一個中介.
//需要註意的就是 判斷條件 (1.迴圈結束,2.if判斷條件)
int[] BubbleSort = {24,69,80,57,13};
int num = 0;
int tempPostion = 0;
int len = BubbleSort.length-1;//記錄內迴圈條件
for(int i = 0;i < BubbleSort.length-1; i++){ //次數 進行4次 只需要4次就可以
int flag = 1;//每次迴圈重新初始化
for(int j = 0; j < len-i ; j++){ // 小於(長度-i) 因為第一次就會篩出最大的一個
//有問題肯定是判斷出問題
if(BubbleSort[j] > BubbleSort[j+1]){
num = BubbleSort[j];
BubbleSort[j] = BubbleSort[j+1];
BubbleSort[j+1] = num;
flag = 0;
//標記發生了交換
tempPostion = j;
}
}
//運行完for第二個迴圈 就會進來判斷 沒有交換 就說明排序完成
len = tempPostion;
if(flag == 1){
return;
}
}
for(int i = 0; i < BubbleSort.length; i++){
System.out.println(BubbleSort[i]);
}