JavaSE基础学习
Java SE
一、Java SE 基礎
1.變量
- 變量就是內存中的存儲空間,空間中存儲著經常發生改變的數據
- 定義格式:數據類型 變量名 = 數據值;
- int salary = 10000
- 使用:根據變量名進行使用
- 注意事項
- 變量在作用域范圍內才可以使用 變量名不允許重復定義 一條語句可以定義多個變量 變量在使用之前一定要進行賦值
2.標識符
- * 作用:給類、變量、方法等取名字的符號單詞* 命名規則:可以由數字、字母、下劃線(_)和美元符($)其中一種或多種組成不能以數字開頭不能是關鍵字或特殊直接量(true,flase,null) * 區分大小寫* 注意:不需要記憶規則,使用idea自動檢查即可
3.基本數據類型的分類和使用
-
整數型
- byte:1個字節,范圍-128~127 short:2個字節 int:4個字節 long:8個字節
-
浮點型:
- float:4個字節 double:8個字節
-
字符型
- char:2個字節
-
布爾型
- boolean:1個字節,就兩個值true和false
4.switch語句
- 1.格式
- 2.switch語句的case穿透現象
- 注意:在switch語句中,如果case控制的語句體后面不寫break,將會出現穿透現象
- 現象:當case 開始穿透,后續的case就不會具有匹配效果,內部的語句都會執行,知道看見break,或者將整體switch語句執行完畢,才會結束。
- 應用場景:當發現switch語句中,多個case給出的語句出現了重復的,就可以考慮 使用case穿透來優化代碼
5.String
- 1.API:應用程序編程接口(Application Programming Interface )
- Java API:指的就是JDK中提供的各種功能的Java類
Java概述
Java語言背景介紹
問題:
1.什么是計算機語言,學習它有什么作用?
2.java語言的創始人是誰,在哪一年發布的呢?
3.java目前分為幾個平臺版本,我們學習的是哪些版本?
4.JavaEE主要是用于什么方向的開發?
Java語言介紹
- 語言:人與人交流溝通的表達方式
- 計算機語言:人與計算機溝通交流的一種特殊語言
- Java語言是Sun公司(Stanford University Network)在1995年推出,1996年發布第一版開發工具包jdk1.0
- Java之父:詹姆斯·高斯林
Java語言的三個版本
- JavaSE:Java語言的標準版
- JavaSE主要用于桌面應用的開發,是其他兩個版本的基礎
- 桌面應用:用戶只要打開程序,程序的界面會讓用戶在最短的時間內找到他們需要的功能,同時主動帶領用戶完成他們的工作并得到最好的體驗
- JavaME:Java語言的小型版,用于嵌入式消費類電子設備
- 已經被Android和ios取代,不是我們學習的重點
- JavaEE:Java語言的企業版,用于Web方向的網站開發
- 網頁、網站和服務器
- 網頁:通過瀏覽器將數據展示在用戶面前,跟后臺服務器沒有交互
- 網站:通過跟后臺服務器的交互,將查詢到的真實數據再通過網頁展示出來
- 簡單理解:網站=網頁+后臺服務器
- 網頁、網站和服務器
Java跨平臺原理
問題:
1.對于跨平臺,這個平臺指的是什么呢?
2.java程序是如何做到能夠在不同的操作系統上運行的呢?
3.不同平臺上的JVM虛擬機是一樣的嗎?
- 平臺與跨平臺
- 平臺:不同的操作系統,比如:Windows、Mac、Linux…
- 跨平臺:java程序可以在任意的操作系統上運行
- 跨平臺的原理
- Java程序本身不能在不同的系統上直接運行,但是可以每個系統安裝一個匹配系統的JVM
- JVM將Java程序翻譯成對應系統可以看懂并且執行的程序
- 總結:要想跨平臺運行java程序,只需要在不同的操作系統中,安裝一個與操作系統對應的Java虛擬機(JVM)即可
- 注意:Java虛擬機本身不允許跨平臺,允許跨平臺的是Java程序
JRE和JDK
問題:
1.開發一個java程序的三個步驟是什么?
2.什么是java類,有什么作用?
3.在JRE中提供核心類庫,有什么意義呢?
4.JVM、JRE、JDK之間具有什么關系?
-
JRE:Java Runtime Environment,java運行環境,包含JVM虛擬機及Java核心類庫,是java語法能夠被使用的前提
- 類:java文件在代碼中的集合體現(類=java文件/一個java文件/一個java類)
- 類庫:存放多個java文件的倉庫
- 核心類庫:java已經寫好的,非常核心的代碼倉庫。常用‘’詞典“
- 核心理解:編寫代碼的過程中,需要用到java存放在JRE中,已經寫好的java文件
-
JDK:Java Development Kit,java軟件開發工具包,內部包含了代碼的編譯工具(javac.exe)和運行工具(java.exe)
- JDK=JRE+開發工具
- JRE=JVM+核心類庫
-
開發Java程序的三個步驟
- 編寫源代碼
- 創建文本文件
- 修改文件后綴名為.java
- 在文件中按照java的語法格式書寫代碼
- 編譯源代碼
- 寫好的Java源文件不能直接被JVM識別和執行。需要用JDK中提供的翻譯工具(javac.exe)將其翻譯成字節碼文件(.class文件),這個過程就是編譯
- 運行程序:利用JDK提供的運行工具(java.exe)運行字節碼文件
-
課后練習
- 下列關于JDK、JRE、JVM關系描述正確的是( )
- A:?JDK是開發工具,JRE是運行環境,JVM是虛擬機。三者沒有關聯
- B: JDK是運行環境,包含了JRE。JRE是開發工具,包含了JVM。JVM是虛擬機,保證了跨平臺
- C: JDK是開發工具,包含了JRE。JRE是運行環境,包含了JVM。JVM是虛擬機,可以保證跨平臺
- D:?JRE是虛擬機,保證了跨平臺。JVM是運行環境,包含了JRE。JDK是開發工具,包含了JVM
- 下列關于JDK、JRE、JVM關系描述正確的是( )
JDK的下載和安裝
問題:
1.安裝jdk,能否安裝在中文路徑的文件夾下?
2.jdk的版本這么多,我們基礎班學習,選擇使用哪個版本?
3.怎么判斷jdk已經安裝成功了?
4.jdk根目錄下的bin目錄中主要是存放什么文件的?
Java語言的發展史
JDK的下載和安裝
- 下載
- 直接訪問:https://www.oracle.com/java/
- 找到download java按鈕,鼠標點擊,進入下載頁
- 然后就可以選擇版本進行安裝,一般只會展示最新版和穩定版
- 注意:下載之前需要注冊Oracle賬號,用郵箱注冊即可
JDK的安裝目錄(根目錄介紹)
第一個程序
常用DOS命令
問題:
1.打開DOS命令提示符操作窗口的步驟是什么?
2.常用的DOS命令有哪些,分別具有什么功能?
3.如何快速的進入某個文件所在目錄的對應DOS環境中?
-
學習DOS命令意義
- 為了能夠使用JDK中bin目錄下的java.exe和javac.exe這兩個工具
- 未來學習使用Linux系統,需要提前適應命令行操作界面風格
-
打開DOS的方式想·
- 按下 win+r 鍵,彈出運行窗口
- 在窗口中輸入cmd
- 點擊確定
-
常用DOS命令
-
命令補充
命令 說明
mkdir 文件夾名 創建一個文件夾
rmdir [/s] 文件夾名 刪除一個[非空]文件夾
del 文件名 刪除文件
cd.>要新建的文件名 創建一個空白文件
rename 要重命名的文件名 重命名之后的文件名 修改一個文件的文件名
move 被移動的文件 要移動到的位置[\移動后的文件名] 剪切一個文件到指定路徑下,也可以更改剪切后的文件名
copy 被復制的文件 要復制到的位置[\復制后的文件名] 復制一個文件到指定路徑下,也可以更改復制后的文件名 -
快速進入bin目錄所在的DOS命令提示符
- DOS命令練習
- 在桌面創建一個文件夾dos-test
- 進入dos-test文件夾
- 創建一個dos.txt文件
- 自己選擇一個非C盤的路徑,創建一個文件夾dos-copy
- 將dos-test中的文件復制到dos-copy中
- 回到桌面,刪除dos-test文件夾
- 退回C盤根路徑
- 清除屏幕
- 退出
Path環境變量的配置
問題:
1.安裝jdk之后,為什么要配置Path環境變量?
2.配置環境變量時,變量JAVA_HOME的值是什么?
3.Path變量的配置,是在用戶變量中還是在系統變量中?
4.如何校驗jdk的path環境變量是否配置成功?
配置Path環境變量的意義
可以在任意目錄下,都能訪問到bin目錄中的javac和java工具
Path環境變量的配置
-
找到桌面上計算機圖標,鼠標右擊,選擇屬性
-
找到高級系統設置,一般在左上方
-
選擇高級、環境變量
-
在系統變量中新建一個變量
-
變量名是:JAVA_HOME,變量值是jdk的根目錄地址,點擊確定
-
再到系統變量框里找到path變量,編輯它
-
在path變量的編輯框中,點擊新建,然后輸入:%JAVA_HOME%\bin
-
需要注意的是,如果path變量框是上面的樣式,是不需要加分號結束的
-
但如果是下方的樣式,那么輸入%JAVA_HOME%\bin;是需要帶分號結束
-
設置好之后,需要一直點擊確定結束
-
驗證path環境變量是否配置成功,需要重新打開一個dos命令行窗口界面驗證,不能使用原有的窗口
-
在dos命令行窗口分別輸入java -version,java,javac三個命令驗證
HelloWorld案例詳解
問題:
1.書寫Java代碼時,class這個單詞是用來干什么的?
2.一個Java程序能不能沒有main主方法?
3.代碼System.out.println(“學習Java的人不是帥哥,就是美女!”);的作用是什么?
4.class前面的public這個單詞,有什么作用?
一個java程序,有且僅有一個main方法,屬于固定寫法
- 一個java程序可以有很多個類,所以類是java程序的最基本組成單位
- 如果Java程序有很多個類,運行這個程序,從有main方法的類中開始
類名必須和文件名保持一致,因為類名前面有public修飾
HelloWorld程序說明:
- java在基礎班沒有豐富的視覺界面顯示,只能通過控制臺這種簡單的界面去呈現內容。你現在打印的這個內容,以后真正的顯式地方,是網頁上
- 基礎班暫時不學習網頁內容,這個要到就業班才會學習
IDEA的安裝和使用
IDEA的概述和安裝
概述
IDEA全程是IntelliJ IDEA,是用于Java語言開發的集成環境,它是業界公認的目前用于Java程序開發最好的工具。
集成環境:把代碼編寫、編譯、運行、調試等多種功能綜合到一起的開發工具
下載和安裝
下載:https://www.jetbrains.com/idea/download/other.html
安裝:雙擊下一步即可,注意不要安裝在中文路徑下
IDEA中的項目結構
Idea項目結構介紹
小結
- project中可以創建多個module
- module中可以創建多個package
- package中可以創建多個class
- 這樣的結構劃分,是為了方便管理類文件的
- 如果不用這些層級去管理類文件,全部放在同一個文件夾中,以后的項目有大量java類文件,不容易找
- 同一個文件夾下不能出現同名的java類,這樣給類取名字就很麻煩了
- java類文件不做分類管理,就好比沃爾瑪的商品不做分類,堆在一塊
IDEA中的第一個代碼
操作步驟(2021版):
創建Project(項目)
創建Module(模塊)
project創建好之后,會自動彈出創建module的窗口
如果不通過自動彈出的創建module窗口創建,也可以在project的界面中操作
配置Module
創建Package(包)
創建class(類)
編寫代碼,運行程序
IDEA常用快捷鍵
//psvm: 一鍵生成主方法
//sout: 生成輸出語句
//ctrl+alt+L: 格式化代碼
//alt+Enter: 代碼修正提示
//ctrl+/: 添加(取消)單行注釋
//ctrl+shift+/ : 添加(取消)多行注釋
//ctrl+D : 復制當前行的代碼
//ctrl+X : 剪切
//ctrl+V : 粘貼
//alt+1: 打開/隱藏項目結構
//alt+4: 打開/隱藏控制臺
//fori : 10次的for循環
IDEA操作模塊
刪除模塊
導入模塊
直接通過project界面導入已存在的module
通過Project structure設置導入module
最后就是一直選擇next下一步即可
IDEA打開、關閉項目-類名、包名修改
關閉項目
打開項目
如果列表中要打開的項目已被移除:
修改類名
修改包名
基礎語法
注釋
問題: 1.什么是注釋,程序當中的注釋有什么作用? 2.java中注釋分為幾類,分別是什么? 3.注釋會不會影響程序的編譯和運行?注釋的概述
- 在程序指定位置添加的說明性信息
- 對代碼進行解釋說明,方便我們程序員更好的去閱讀代碼。
注釋的分類
格式:// 注釋信息只有一行,并且在雙斜線后面
格式:/ 注釋信息可以有很多行,位置被包裹住 /
格式:/* 注釋信息 /
//練習:給HelloWorld程序添加注釋
//這是一個類,類的名字叫A
public class A{
/*
這是程序的主方法,一個java程序有且僅有一個main方法。
*/
public static void main(String[] args){
//這是一個在控制臺打印輸出內容的語句,小括號中是輸出的內容。
//在控制臺輸出自己的姓名、對喜歡的人想說的話
System.out.println(“好棒哦,notepad真給力”);
}
}
基礎語法
關鍵字
問題:
1.java中的“關鍵字”是什么?
2.Java中的“關鍵字”有哪些特點?
3.main方法中的名字“main”是不是關鍵字?
- 概念:被java賦予了特定涵義的英文單詞
- 特點:
- 關鍵字的字母全部都是小寫
- 常用的代碼編輯器,針對關鍵字有特殊的顏色標記,非常直觀
- main不是關鍵字,但是也很關鍵
- java中有48個關鍵字,和2個保留關鍵字
字面量
問題:
1.Java中的字面量有哪幾種類型?
2.'10’這個數據在Java中屬于字符字面量嗎?
3.能不能使用打印語句去打印空字面量?
字面量的分類:
- 字符串字面量:被雙引號所包裹的內容
- 整數字面量:所有整數
- 小數字面量:所有小數
- 字符字面量:被單引號包裹的內容,里面只能存放單個字符。字符是字符串的組成部分。
- 布爾、字面量:只有兩個值,分別是true和false,分別代表真和假、成立和不成立這種對立的意思(以后學習運算符和流程結構時需要用到)
- 空字面量:null。代表不存在的,空的。不能被輸出打印。
變量
3.1 變量概述
概念:在程序運行期間,其值可以發生改變的量。
理解:變量就是內存中的存儲空間,空間中存儲著經常發生改變的數據
定義格式
變量的使用(變量名進行使用)
//練習
//定義一個int類型的變量,并且賦值為18
//使用變量,將變量中的數據打印出來
//再次給變量賦值,替換之前的數據
//再次打印該變量
內存圖變化
-
第一步:
-
第二步:
3.2 變量的注意事項
- 變量的作用域:
- 從變量聲明的那一行開始,到它所在的大括號結束的區域有效
- 注意事項:
- 在變量的作用域內,變量名不允許重復定義
- 一條語句可以定義多個變量,但需要用逗號進行分割
- 變量在使用前一定要進行賦值
數據類型
問題:
1.Java中的數據類型有幾種?
2.Java中數據類型的轉換方式有幾種?
4.1 類型分類
-
Java的數據類型
- 基本數據類型(4類8種)
- 引用數據類型(類、接口、數組,比如String)
-
基本數據類型分類
-
案例
//練習:在下面輸出語句的后面添加注釋,標明打印內容分別屬于什么數據類型
System.out.println(‘1’);//
System.out.println(520);//
System.out.println(3.14);//
System.out.println(0.618F);//
System.out.println(5201314L);//
System.out.println(false);//
4.2 類型轉換
隱式轉換
-
概念:將數據類型中取值范圍小的數值或變量,給取值范圍大的類型賦值。直接賦值。
int xiao=10;
//int的取值范圍比double小,所以可以給double類型直接賦值
double da=xiao;
//總結:小的給大的,天經地義
1.總結:
//舉例:200ml的可樂導入1L的瓶子,直接倒水,不會‘溢出’。所謂的數據類型轉換就是不同類型的杯子中裝水,怎么裝更合適。
2.舉例: -
數據類型范圍從小到大排序
隱式轉換的細節
-
不同數據類型進行運算,小的數據類型會提升為大的之后,再參與運算
//買早餐案例
//買包子,2元,int類型收
int baoZi = 2;
//買了個雞蛋,1.5元,double類型接收
double egg = 1.5;
//小類型的baoZi和大類型的雞蛋相加,包子提升成double類型參與運算:double+double
double zaoCan=baoZi+egg; -
特殊關注:byte、short、char(比int類型范圍小的)三種數據進行運算的時候,不管是否有更高的數據類型,都會提升為int,再參與運算
//案例1:byte+short
byte b=10;
short s=29;
//分析:byte+short -> int +int -> int
int num1=m+s;
//自案例
//案例2:byte+char
char c=‘a’;
//分析:byte+char -> int+int -> int
int num2=b+c;
//案例3:byte+short+double
double d=3.14;
//分析:byte+short+double -> int+int+double -> double+double+double -> double
double num3=b+s+d;
強制轉換
-
概念:把一個表示數據范圍大的數值或變量賦值給另一個表示數據范圍小的變量
-
格式:目標數據類型 變量名 = (目標數據類型) 值或變量;
//案例1:
int a=10;
//byte b=a; //編譯報錯:錯誤,不兼容的類型,從int轉換到byte可能會有損失(精度損失)
//利用強轉格式解決
byte b=(byte)a; -
精度損失
//案例1:浮點數強轉成整數
//給定一個變量為double類型
double d=520.1314;
//給定一個變量為int類型,比double類型范圍小,強制數據類型轉換
int i=(int)d;
System.out.println(a);//結果:520
//思考:是否遵循四舍五入?
//double類型變量重新復制
d=0.618;
//再次強轉
i=(int)d;
System.out.println(a);//結果:0
//結論:小數強轉成整數,會直接舍掉小數部分//案例2:大整數強轉成小數
//給定一個變量為int類型
int num1=520;
//強轉byte類型,注意byte取值范圍:-128~127
byte num2=(byte)num1;
System.out.println(num2);//結果:8
//思考:byte類型最大值為127,為什么結果是8? -
精度損失的原因
標識符
問題:
1.什么是標識符,有什么作用?
2.標識符的定義規則是什么?
3.標識符常見的命名規定有哪些?
概述:給類、變量、方法等起名字的符號
硬性規則(必須得遵守,不遵守,程序就報錯):
//合法標識符
age
L_ni3
$get
//非法標識符
7shang8xia //不能以數字開頭
&abc //&不屬于標識符的組成
class //不能是關鍵字
常見命名規定(軟性規則)
- 小駝峰命名法:給變量、方法命名
- 標識符是一個單詞的時候,首字母小寫。比如:name
- 標識符由多個單詞組成,首個單詞全部小寫,其余單詞首字母大寫。比如:firstName
- 大駝峰命名法:給類命名
- 標識符不管多少個單詞,每個單詞首字母大寫,比如:HelloWorld
//練習1:以下哪些變量的命名是符合標識符規則的?在注釋后面標注
String name=“張三”;//
int age=17;//
int do=23;//
double π=3.14;//
char dollar=′dollar='dollar=′';//
char 86RMB=‘¥’;//
//練習2:使用大駝峰或小駝峰式進行命名
//2.1 定義一個類名,該類用來表示一個學生
//2.2 定義一個變量名,用來代表人的年齡
//2.3 定義一個變量名,用來代表學生的學號
//2.4 定義一個類名,用來代表第一個變量練習的類
鍵盤錄入
- 學習鍵盤錄入的目的:
- 可以在程序運行后,將鍵盤錄入的數據獲取到程序中操作
- 實現鍵盤錄入的步驟:
-
導包:需要在class的上面寫
- import java.util.Scanner;
-
創建Scanner對象,只有sc可以變,其他是固定格式
- Scanner sc=new Scanner(System.in);
-
使用變量接收鍵盤錄入的數據,變量名num可以變,其他固定格式
- int num = sc.nextInt();
-
使用鍵盤錄入的數據,這里是打印數據
- System.out.println(num);
//練習:利用鍵盤錄入,在控制臺錄入自己的座右銘,并打印
-
運算符
-
運算符和表達式
- 概念
- 運算符:對常量或者變量進行操作的符號
- 表達式:用運算符把常量或變量連接起來符合java語法的式子就可以稱之為表達式
- 概念
-
案例
int a=10;
int b=20;
int c=a+b;
// + 是算數運算符,a+b 是表達式,也叫算術表達式。
-
種類
-
案例
//案例1:+、-、*
int a=2;
int b=3;
// + 運算
int num1=a+b;
// - 運算
int num2=a-b;
// * 運算
int num3=a*b;
System.out.println(num1);
System.out.println(num2);
System.out.println(num3);//案例2:/
//整數除法
System.out.println(10/2);//結果:5
System.out.println(10/3);//結果:3
//分析:10/3 -> int/int -> int。 所以小數部分直接省去。
//要得到小數,表達式中得有小數
System.out.println(10.0/3);
System.out.println(10/3.0);//案例3:%
//求10除以3的余數: 10 / 3 = 3 ······ 1
System.out.println(10%3);//結果:1//案例4:混合運算
int a=2;
byte b=3;
char c=‘a’;
System.out.println(c+a*b);
//類型分析:char+int+byte -> int+int+int -> int
//順序分析:先乘后減
//結果:字符怎么加!!! 提升成int是多少呀?
//試著編譯:不報錯!
- ASCII碼表:美國信息交換標準代碼
- 是計算機中,字節到字符的一套對應關系。
- 在碼表中,每一個字符都有一個與之對應的數字。
- 為什么要有碼表呀?
計算機底層所有的數據都是二進制數字,字符也不例外。我們使用電腦能看到的文字都是一個個的字符組成的。那這些字符應該用哪些二進制數字表示呢?如果每個國家都不一樣,數據在互聯網上就很難在國際上流通了。
所以老美就搞了這么一個標準,大家都共同遵守。
-
常用的字符碼表對照
-
運算過程
-
char類型在參與數學運算的時候,先查找碼表中對應的數字,再參與運算
char c=‘a’;
System.out.println(c+1); //結果:98
-
-
概述:字符串的“+”操作不是算數運算,而是字符串拼接運算。
-
特點:在“+”操作的時候,如果出現了字符串,“+”就是連接運算符。當連續進行“+”操作時,從左往右逐個進行。
//案例1:
//做一行愛一行
System.out.println(“Java”+520+1314);
//挑幾個我喜歡的數字,我喜歡高一點的女孩子,175…
System.out.println(175+120+66+103+56+“Hello”);
- 需求:鍵盤錄入一個三位數,將其拆分為個位、十位、百位后,打印在控制臺
- 思路:
- 使用Scanner鍵盤錄入一個三位數;
- 計算個位數:數值 % 10。比如123的個位數是3,123 % 10的結果就是3;
- 計算十位數:數值 / 10 % 10。比如123的十位數是2,123 / 10得12,12 % 10的結果就是2;
- 計算百位數:數值 / 100。比如123的百位數是1,123 / 100得1。
- 公式:
-
個位數:數值 / 10的0次方 % 10;
-
十位數:數值 / 10的1次方 % 10;
-
百位數:數值 / 10的2次方 % 10;
-
千位數:數值 / 10的3次方 % 10;
-
…
//需求:鍵盤錄入一個三位數,將其拆分為個位、十位、百位后,打印在控制臺
//1. 使用Scanner鍵盤錄入一個三位數
//1.1 導入Scanner包:import java.util.Scanner;
import java.util.Scanner;
public class Test{
public static void main(String[] args){
//1.2 創建Scanner對象
Scanner sc = new Scanner(System.in);
//1.3 提示用戶鍵盤錄入
System.out.println(“親,請輸入一個三位數哦:”);
//1.4 鍵盤錄入數字
int num = sc.nextInt();
//2. 計算個位數:數值 % 10
int ge = num % 10;
//3. 計算十位數:數值 / 10 % 10
int shi = num / 10 % 10;
//4. 計算百位數:數值 / 100
int bai = num / 100;
//5. 假設輸入的數字是520,打印內容:整數520的個位為:0,十位為2,百位為:5
//5.1 分析:字符串拼接操作
System.out.println(“整數” + num + “的個位為:” + ge + “,十位為” + shi + “,百位為:” + bai);
}
}
-
大家都玩微信吧?如果有朋友給你發消息,如果你沒看,每發一條消息,紅點的消息記錄就多一條。說明微信有個程序一直再計數,每次增加1。
System.out.println("女神:在嗎?我有事跟你說"); //定義一個int類型的變量記錄未讀消息數 int count = 1; System.out.println("---您有" + count + "條未讀消息---");System.out.println("女神:我懷孕了"); count = count + 1; System.out.println("---您有" + count + "條未讀消息---");System.out.println("女神:可能不是你的,但我還是愛你的"); count = count + 1; System.out.println("---您有" + count + "條未讀消息---");System.out.println("女神:我想和你結婚,盡快"); System.out.println("開啟了好友人認證,你還不是他的好友。請先發送好友申請..."); //問題:每次count都得加1再賦值給自己,特別麻煩,有沒有更簡單的方法呢?利用java的自增運算符就可以簡化注意事項:
- 可以放在變量的前面,也可以放在變量的后面
- 如果是單獨給變量使用,放前放后都一樣(常用操作)
- 如果參與運算
- 在前:先對變量進行自增或自減,再拿變量的值參與操作
- 在后:先拿變量原本的值參與運算,然后變量自己再進行自增或自減。變化后的變量值不參與運算
- 只能操作變量,不能操作常量
案例演示
//案例1:單獨使用
int count=0;
//在前
++count;
System.out.println(count);//結果:1
count++;
System.out.println(count);//結果:2
//無區別,都是自己的值加1
總結
自增自減最后都要給自己加1或者減1,然后會給自己賦值。當然這個賦值運算省略了。說道到賦值,在java中我們已經知道了=是賦值運算符,那除了=之外,還有沒有其他的賦值運算符呢?這里可以告訴大家,還有5種賦值運算符。
-
介紹
-
案例演示
案例1:加后賦值
int a=24;
int b=2;
a+=b;// a=a+b;
System.out.println(a);案例2:減后賦值
a-=b;// a=a-b;
System.out.println(a);案例3:乘后賦值
a*=b;// a=a*b;
System.out.println(a);案例4:除后賦值
a/=b;// a=a/b;
System.out.println(a);案例4:取余后賦值
a/=5;// a=a%5;
System.out.println(a); -
注意事項:擴展的賦值運算符隱含了強制類型轉換
//案例1
int a=23;
byte b=12;
b=a+b; //編譯報錯
//分析:int+byte -> int+int -> int。int不能直接賦值給byte
System.out.println(b);//案例2:擴展的賦值運算符
int a=23;
byte b=12;
b+=a;//編譯通過
//分析:b+=a -> b=(b的數據類型)(b+a) -> byte=(byte)(byte+int) -> byte=byte
System.out.println(b);
在java中,普通的賦值運算符是用=號表示,所以以后int a=23;的實際讀法,應該是把23賦值給了int類型的a。話說到這,如果我不是做賦值,就是要判斷相等呢?=號都被占用了,哪個符合能用作判斷相等的操作呢?
-
介紹
關系運算符是用來判斷兩個變量(常量、表達式)之間的關系,比如相等關系、不等關系和大小關系。運算結果都是布爾值,要么是true,要么是false。 -
代碼演示
//案例1:操作變量
int a=23;
int b=12;
System.out.println(a>b);//結果:true//案例2:操作常量
System.out.println(3<2);//結果:false//案例3:操作變量和常量
System.out.println(a>=3);//結果:true//案例4:操作表達式
int num1 = 5;
System.out.println(num1 * 2 + 1 != 11);//結果:false
國家開始推新冠疫苗啦,讓全民接種。但是不是所有人都能打的,在年齡上有限制。規定是只給18~59歲的人群注射。
//定義一個變量,代表要接種疫苗的人,叫小明 String name="小明"; //小明今年14歲 int age=14; //篩選,結果是true就能打,否則不能打 boolean result= 18<=age<=59; //編譯報錯,不允許這么寫。 //如果不能一次性寫,那就得寫兩行代碼,在java中,能不能一次判斷完呢?-
介紹
-
作用:用于連接多個比較表達式的條件,得到最終的結果是個布爾值
- 其中&、|、^三種,左右兩邊不管是變量、常量還是表達式都可以
- 這些變量、常量、表達式最終的結果必須t布爾類型或數字
- !的后面放布爾值,不能放其他類型
-
代碼案例
//案例1:操作變量
//有房
boolean fang = true;
//沒車
boolean che = false;
//&:左右兩邊都是true,結果才是true。 要求高
System.out.println(fang & che);//結果:false
//|:左右兩邊有一個為true,結果就是true。要求低
System.out.println(fang | che);//結果:true//案例2:操作變量和常量
System.out.println(fang & false);//結果:false
System.out.println(fang & true);//結果:true
System.out.println(che | true );//結果:true//案例3:操作常量
System.out.println(true & false);//結果:false
System.out.println(false | true);//結果:true
// ^:左右兩邊的值不一樣,結果才是true
System.out.println(true ^ true);//結果:false
System.out.println(false ^ true);//結果:true//案例4:操作表達式
//今年18歲
int age = 18;
//年齡必須在18到59歲才能打疫苗
System.out.println(age >= 18 & age <= 59);//結果:true
-
介紹
-
與運算:
- 邏輯與:&,無論左邊真假,右邊都要執行
- 短路與:&&,如果左邊為true,右邊就執行。如果左邊為false,右邊不用執行
-
或運算:
- 邏輯或:|,無論左邊真假,右邊都要執行
- 短路或:||,如果左邊為false,右邊執行。如果左邊為true,右邊不執行
-
代碼演示
//案例1:&&的短路效果
int a=3;
int b=4;
System.out.println(a>3&&++b>4);
//分析:a>2的結果是false,所以&&后面不執行。b沒有做自增運算
System.out.println(“b:”+b); //結果:4//案例2:||的短路效果
int num1=3;
int num2=4;
System.out.println(num1>2||num2–<4);
//分析:num1>2的結果是true,所以||后不執行,num2沒有做自減運算
System.out.println(“num2:”+num2); //結果:4
-
格式:關系表達式 ? 表達式1:表達式2;
-
執行流程:
- 首先計算關系表達式的結果
- 如果結果是true,則取表達式1的結果做最終結果
- 如果結果是false,則取表達式2的結果做最終結果
-
代碼演示
//案例1:求兩個變量中的最大值
int a=28;
int b=18;
//分析:先讓看a是否大于b,如果a大于b,則a是最大值,將a的值賦值給變量max,否則就是b賦值給max
int max=a>b?a:b;
System.out.println(“最大值是:”+max);//注意事項:表達式1和表達式2最終結果的數據類型必須一致。為什么?如果不一致,三元運算符最后的要賦值的話,拿什么數據類型接收?是不是就無法確定了?
分支語句
-
介紹:java代碼的默認執行流程:從上到下,從左往右
-
代碼案例
//案例
//從上往下
System.out.println(“我是黑馬程序員”);
System.out.println(“我的目標是月薪過萬”);
System.out.println(“前提是要努力學習,鍵盤敲爛”);
//從左往右
System.out.println(“高薪就業!”+“人生巔峰!”+“迎娶白富美!”);
2.1 第一種格式
-
格式
…
if(關系表達式){
語句體;
}
…//執行流程
//1. 首先計算關系表達式的值,這個結果只能是布爾值
//2. 如果關系表達式的值為true,就執行語句體
//3. 如果關系表達式的值為false,就不執行語句體
//4. if語句結束,繼續執行后面的代碼內容 -
代碼案例
//案例1:小明上網
System.out.println(“今天是周末,天氣真好,小明出門玩耍”);
//定義一個int類型變量,代表小明的年齡
int age=19;
System.out.println(“看到了一間網吧,準備進去玩兩把”);
System.out.println(“網管問:你成年了嗎?”);
//使用if語句進行判斷
if(age>=18){
System.out.println(“小明說:我成年了”);
System.out.println(“領卡、卡機、五連跪”);
}
System.out.println(“小明轉身回家”); -
注意事項
- 如果語句體只有1條語句,大括號可以不寫(不推薦)
- if語句中小括號后面不能加分號,如果加分號,就代表if語句結束了
2.2 第二種格式
-
格式
…
if(關系表達式){
語句體1;
} else {
語句體2;
}
…//執行流程
//1. 首先計算關系表達式的值,這個結果只能是布爾值
//2. 如果關系表達式的值為true,就執行語句體1
//3. 如果關系表達式的值為false,就不執行語句體2
//4. if語句結束,繼續執行后面的代碼內容 -
代碼案例
//案例1:判斷一個數是奇數還是偶數
//給定一個待判斷的整數
int num=23;
//開始進行判斷
//尋找奇數的規律,偶數可以被2整除,意味著偶數對2取余數的結果是0,這個就可以作為判斷的條件
if(num % 2==0){
System.out.println(“偶數”);
}else{
System.out.println(“奇數”);
}//案例2:判斷兩個數誰是最大值
int num1=5;
int num2=3;
//三元運算的方式
int max= num1>num2?num1:num2;
//利用if-else完成
//誰最大,需要判斷num1是否大于num2,這就可以作為一個條件
if(num1>num2){
System.out.println(“最大數是:”+num1);
}else{
System.out.println(“最大數是:”+num2);
}
2.3 第三種格式
-
格式
…
if(關系表達式1){
語句體1;
} else if(關系表達式2) {
語句體2;
} else if
…
} else {
語句體n+1;
}
…//執行流程
//1. 首先計算關系表達式1的值,這個結果只能是布爾值
//2. 如果關系表達式1的值為false,就執行關系表達式2
//3. 如果關系表達式2的值為false,就執行關系表達式3
//4. …
//5. 有任何關系表達式的值為true,就執行對應的語句體
//6. 如果沒有任何關系表達式的值為true,就執行語句體n+1 -
代碼案例
/**
- 案例1:根據學生成績,程序給出對應的評價
- 90~100:優秀
- 80~89:良好
- 70~79:中等
- 60~69:及格
- 0~59:請努力!
*/
//定義一個變量接收成績
int score=89;
//需求中有5種條件,每種對應一個評價。剛好和if-else if的結構匹配
if (score >= 90 && score <= 100) {
System.out.println(“優秀”);
} else if (score >= 80 && score <= 89) {
System.out.println(“良好”);
} else if (score >= 70 && score <= 79) {
System.out.println(“中等”);
} else if (score >= 60 && score <= 69) {
System.out.println(“及格”);
} else {
System.out.println(“請努力加油!”);
}
2.4 案例:考試獎勵
//需求:鍵盤錄入學生考試成績,根據成績,程序給出不同的獎勵//思路: //1. 考試成績未知,需要用鍵盤錄入,拿到考試成績 //1.1 導入Scanner包,在代碼的最上方第一行 import java.util.Scanner;//1.2 創建Scanner對象 Scanner sc=new Scanner(System.in); //1.3 提示用戶鍵盤錄入成績 int score=sc.nextInt();//2. 判斷錄入的學生成績是否在合法范圍之內 if(score>=0&&score<=100){//合法成績//3. 在合法的if塊中,判斷成績范圍if(score>=95&&score<=100){//4. 為每種判斷設置對應的獎勵System.out.println("獎勵自行車一輛");} else if(score>=90&&score<=94){System.out.println("獎勵游樂場玩一次");} else if(score>=80&&score<=89){System.out.println("獎勵變形金剛一個");} else {System.out.println("挨頓揍,這個城市又多了一個傷心的人");} //注意,下面這個else是外層判斷輸入成績是否合法對應if結構,不是內層的。 }else{//非法成績System.out.println("您輸入的成績有誤"); }3.1 格式和執行流程
-
格式
switch(表達式){
case 值1:
語句體1;
break;
case 值2:
語句體2;
break;
…
case 值n:
語句體n;
break;
default:
語句體n+1;
break;
}
/**- 格式說明:
- 表達式:可以取值為byte、short、int、char,JDK5以后可以是枚舉,JDK7以后可以是String;
- case:后面跟的值,是要和表達式進行匹配的值。如果匹配的結果是一樣的,就執行對應語句體;
- break:表示中斷、結束的意思,用來結束switch語句;
- default:表示所有的情況都不匹配的時候,就執行該處語句體的內容,和if語句的else相似。
*/
/**
- 執行流程:
- 1.首先計算表達式的值;
- 2.依次和case后面的值進行比較,如果有對應值的話,就會執行相應語句,在執行的過程中,遇到break就會結
- 束,其他語句體不會再執行;
- 3.如果所有的case后面的值和表達式的值都不匹配,就會執行default里面的語句體,然后程序結束掉
*/
-
注意事項
- case給出的值不允許重復
case后面的 - 值只是常量,不能是變量
- case給出的值不允許重復
3.2 case穿透
-
注意:在switch語句中,如果case控制的語句體后面不寫break,將出現穿透現象;
-
現象:當開始出現case穿透,后續的case就不會具有匹配效果,內部的語句不會結束,繼續向下執行。直到看到break,或者將整個switch語句執行完畢,switch才會結束
-
應用:當發現switch語句中,多個case給出的語句體出現重復的時候,就可以考慮使用case穿透來優化代碼
//案例:鍵盤錄入112,代表當前月份。其中35是春季,68是夏季,911是秋季,12~2是冬季。
//1.使用Scanner鍵盤錄入
//1.1 導包
import java.util.Scanner;
public class Test03 {
public static void main(String[] args) {
//1.2 創建Scanner對象
Scanner sc = new Scanner(System.in);
//1.3 提示用戶鍵盤錄入,防止程序要開始錄入的時候,用戶不知道
System.out.println(“請輸入當前月份”);
//1.4 開始鍵盤錄入選擇,并用int類型的變量season接收鍵盤錄入的數字值
int season = sc.nextInt();
//2.根據錄入的數字值,匹配不同的月份
switch (choice) {
case 3:
case 4:
case 5:
System.out.println(“春天到了,這是個萬物復蘇的季節”);
break;
case 6:
case 7:
case 8:
System.out.println(“夏天熱情似火,路邊的小姐姐都很好看”);
break;
case 9:
case 10:
case 11:
System.out.println(“秋天收獲勞動的過時,大地的饋贈”);
break;
case 12:
case 1:
case 2:
System.out.println(“冬天里寒風凜凜,小姐姐的身材看不到了”);
break;
default:
System.out.println(“您輸入的月份有問題哦!”);
break;
}
}
}
循環語句
循環:重復做某件事情,具有明確的開始和停止標記
1.1 格式和執行流程
-
格式
for(初始化語句;條件判斷語句;條件控制語句){
循環體語句;
}
//執行流程
//1.執行初始化語句
//2.執行條件判斷語句,看起結果是true還是false。
//3.如果是false,循環結束
//4.如果是true,繼續執行循環體語句
//5.循環體語句執行結束,執行條件控制語句
//6.回到第二步繼續 -
代碼演示
1.2 案例:輸出數據15和51
-
思路分析:
-
打印1~5:
-
打印5~1:
-
-
代碼演示
//打印1~5
//打印的動作是重復的,所以必須把輸出語句放到循環內部
//重復5次,并且是從1開始打印,那么就要控制變量在1,2,3,4,5都能取到
for(int i=1;i<=5;i++){
System.out.println(i);
}
//打印5~1
//同上,只是打印從5開始,變量的值取5,4,3,2,1,依次遞減
for(int i=5;i>=1;i–){
System.out.println(i);
}//思考:如何只利用一個循環解決?
//分析:總共循環打印10次,可以先讓變量取到1~10
for(int i=1;i<=10;i++){
//如果僅僅是直接打印i的值,則無法打印51,打印的是610
//System.out.println(i);
//所以不能直接打印i,必須加條件限制,只有當i<=5的時候可以直接打印
if(i<=5&&i>=1){
System.out.println(i);
}
//如果只有上面的條件限制,則無法阻擋610的打印,思考610和5~1之間的關系
//11-6=5,11-7=4,11-8=3,11-9=2,11-10=1
//找到規律,可以開始判斷條件,當i取6~10的時候如此操作
if(i<=10&&i>=6){
System.out.println(11-i);
}
}
1.3 案例:求1~5數據和
-
思路分析
-
代碼演示
//定義一個int類型的變量,專門用來接收求和的值,一開始沒有任何值,所以是0
int sum=0;
//因為是求15的和,所以要保證能取到15這幾個數字,并且求和的話是加了5次,所以循環也能控制成5次
for(int i=1;i<=5;i++){
//每次相加,都是拿累計好的值加新取到的1~5的值,累計值是由sum表示,所以是拿sum和i相加
//sum+i;
//加完之后,累計值要改變,所以還得賦值回給sum
//sum=sum+i;
//這種自己加某個值再賦值給自己的操作,可以使用擴展賦值運算符搞定
sum+=i;
}
//循環結束,可以確定i的每個值都取到了,并且加過了,這個時候的sum已經是最后的結果
System.out.println(“1-5之間的數據和是:”+sum);
1.4 案例:求1~100偶數和
-
思路分析
-
代碼演示
//分析:要取到1~100的值,數字有100個,那么得循環100次
//定義一個變量,做累計相加的值的容器
int sum=0;
for(int i=1;i<=100;i++){
//這100個數字,不是所有數字都是偶數,什么樣的數字才能被稱為偶數?一個數被2整除,沒有余數就是偶數
if(i%2==0){
//滿足條件的i才會進來,此時i就是偶數,利用上一個案例的知識,可以在此處累計相加
sum+=i;
}
}
//循環結束,就可以打印sum的值
System.out.println(“1-100之間的偶數和是:”+sum);
1.5 案例:水仙花數
-
水仙花數
-
思路分析
-
代碼演示
//1. 通過循環能獲得100~999這所有的數
for(int i=100;i<=999;i++){
//針對當前i的值,i一定是三位數,所以要拆分成個位、十位、百位
//2.分別定義變量代表個位、十位、百位
int ge=i%10;
int shi=i/10%10;
int bai=i/100;
//3.水仙花數的條件就是:個位數的三次方+十位數的三次方+百位數的三次方等于原來的數
if(gegege+shishishi+baibaibai==i){
//4.滿足條件的數就是水仙花數,可以打印
System.out.println(“水仙花數:”+i);
}
}
1.6 案例:每行打印2個水仙花數(統計)
-
需求分析
-
代碼實現
//1. 通過循環能獲得100~999這所有的數
//2. 定義一個變量,記錄打印了多少個數,定義的時候還一個都沒有打印,所以初始值是0
int count=0;
for(int i=100;i<=999;i++){
//針對當前i的值,i一定是三位數,所以要拆分成個位、十位、百位
//3.分別定義變量代表個位、十位、百位
int ge=i%10; 521-------1
int shi=i/10%10; 521—52—2
int bai=i/100; 521------5
//4.水仙花數的條件就是:個位數的三次方+十位數的三次方+百位數的三次方等于原來的數
if(gegege+shishishi+baibaibaii){
//5.滿足條件的數就是水仙花數,打印的時候注意,第一不要換行,第二要留一個空格隔開
System.out.print(i+" ");
//6.每打印一個數字,count的值就得記錄1次,值要加1
count++;
//7.此時就應該馬上判斷打印了多少個數字,如果是偶數,馬上就要開始換行了
//8.判斷一個數是否是偶數,只需要對2取余數是0就可以了
if(count%20){
//9.僅僅換行,不打印
System.out.println();
}
}
}
2.1 格式和執行流程
-
格式
//基本格式
while(條件判斷語句){
循環體語句;
}//完整格式
初始化語句;
while(條件判斷語句){
循環體語句;
條件控制語句;
}//執行流程
//1.執行初始化語句;
//2.執行條件判斷語句,看結果是true還是false
//3.如果是false,循環結束。如果是true,則繼續執行循環體語句
//4.執行條件控制語句
//5.若循環內部沒有使用特殊關鍵字結束循環,則回到第2步繼續 -
代碼案例
//案例:打印999次“我愛你的第X天”
//1.有記錄次數,并且循環的次數和記錄的次數相關,所以初始化語句就可以定義一個int類型的變量
int count=1;
//2.開始循環,當count值一直小于等于999次的時候,就還可以打印
while(count<=999){
System.out.println(“我愛你的第”+count+“天”);
//每打印1次,count的次數就得加1
count++;
} -
注意事項
//1.while后面的小括號后,千萬不要寫分號,例如
int count=1;
//1.1小括號后面馬上接分號,代表沒有循環體語句,后面的大括號部分就不屬于while循環的范圍
//1.2這就會導致count的值一直無法執行到自加操作,會一直滿足count<=999,而出現程序卡死的情況
while(count<=999);
{
System.out.println(“我愛你的第”+count+“天”);
//每打印1次,count的次數就得加1
count++;
}
2.2 案例:珠穆朗瑪峰
-
需求分析
-
代碼實現
//1.需要求次數,那就說明每次循環需要計數一次,那就得在循環外定義一個變量去接收折疊的次數
//循環開始前,沒有折疊,所以初始化值是0。注意不能放到循環內去定義變量
int count=0;
//2.要判斷停止循環的條件是什么,就是紙張的厚度大于等于珠峰高度的時候
//紙張的高度是隨著折疊而變化的,屬于變化的量,那就定義一個變量代表紙張厚度
double paper=0.1;
//3.反復折疊屬于重復操作,并且不知道折多少次,使用while循環比較合適
while(paper<=8844430){
//4.當紙張厚度小于珠峰的時候就要折疊,折疊的動作是重復的,折疊的后果是紙張厚度要乘以2
paper*=2;
//5.折疊一次,計數器要加1次
count++;
}
//通過不斷的循環,paper的厚度一直增加,知道大于等于珠峰高度的時候,條件判斷的結果為false,結束循環
//此時就可以打印折疊次數
System.out.println(“折疊”+count+“次,達到珠峰高度”);
-
格式
//基本格式
do{
循環體語句;
}while(條件判斷語句);//完整格式
初始化語句;
do{
循環體語句;
條件控制語句;
}while(條件判斷語句);//執行流程
//1.執行初始化語句
//2.執行循環體語句
//3.執行條件控制語句
//4.執行條件判斷語句,看結果是true還是false
//5.如果是false,循環結束。如果是true,繼續執行
//6.回到第2步繼續 -
代碼案例
//案例:在控制臺輸出3次:代碼練習了X遍(X代表次數)
//定義一個變量用來記錄打印的次數
int count=0;
do{
//進入循環就練習一遍代碼,所以次數要加1次
count++;
System.out.println(“代碼練習了”+count+“遍”);
//這里不能是<=,因為練了5次,就可以結束了,不能再循環練習
}while(count<5); -
特點
do…while循環,無論條件是否滿足,都會執行一次循環體語句
很少用,了解即可
三種循環的區別
- 三種循環的區別
- for、while循環: 必須滿足條件才執行(先判斷再執行)
- do…while::不管條件是否成立,循環語句體至少執行一次(先執行再判斷)
- 三種循環的場景
-
循環開始前,知道次數,使用for循環
-
循環開始前,不知道次數,使用while循環
-
do…while一般不用
//案例1:for循環外嘗試使用變量
//循環開始,可以知道循環3次
for(int i=1;i<=3;i++){
//for循環內部使用for循環中定義的變量,沒有問題
System.out.println(“i:”+i);
}
//編譯報錯,因為變量i是for循環中定義,只能在循環中使用,循環結束,i也從內存中消失
System.out.println(“i:”+i);//案例2:將上面的for循環,替換成while循環
//1.將變量i的聲明和初始化提取到循環外操作
int i=1;
//2.條件判斷保留
while(i<=3){
//可以打印
System.out.println(“i:”+i);
}
//循環外打印循環外定義的變量,可以打印
System.out.println(“i:”+i);
-
-
格式
//1.while死循環
while(true){
循環體語句;
}//2.for死循環
for(;😉{
循環體語句;
}//3.do…while死循環
do{
循環體語句;
}while(true); -
代碼演示
//案例1:死循環使用的場景-while
//當重復的動作完全無法判斷會執行多少次的時候,并且可能沒有上限或下限時,使用while死循環
//例如:鍵盤錄入一個3位數,當錄入的數字是一個水仙花數的是時候,打印該數字,并結束程序
//分析:3位數的數字非常多,用戶可能一直都無法錄入成功,所以無法判斷錄入的次數,重復的上下限也不好判斷
//使用while死循環//1. 導包
import java.util.Scanner;public class TestWhileLoop {
public static void main(String[] args) {
//2.創建Scanner對象
Scanner sc = new Scanner(System.in);
//無法判斷錄入多少次會成功,并且錄入數字的次數,上下限無法確定
//3.使用while死循環
while (true) {
//4.提示用戶錄入一個三位數
System.out.println(“親,請輸入一個三位數哦:”);
//5.鍵盤錄入一個整數
int num = sc.nextInt();
//6.獲取該數字的個位、十位、百位
int ge = num % 10;
int shi = num / 10 % 10;
int bai = num / 100;
//7.判斷該數字是否是水仙花數
if (ge * ge * ge + shi * shi * shi + bai * bai * bai == num) {
//8.如果是水仙花數,就能進入,打印該數字
System.out.println(num);
/*
* 9.問題來了,此時我們是想讓循環能夠結束的,但是現在還做不到。
* 循環依然還是不斷執行,無法結束。
* 所以如果java能具備一個可以隨時結束循環的操作,死循環就可以完美的使用。
* 在DOS界面中,可以直接利用Ctrl+C強制結束程序而結束循環,這樣不推薦
/
}
}
}
}
/*- 總結:死循環可以讓重復的動作一直執行下去。
- 所以死循環的使用,必須能夠具備一個可以讓程序根據情況而隨時結束循環的操作。
*/
-
概述
- 跳過當前循環過程,馬上進入下一次循環過程:continue
- 結束當前循環,循環語句結束:break
-
代碼演示
//案例1:打印1到10之間的整數,不要把2和4打印出來
for(int i=1;i<=10;i++){
//i等于2和4都不能打印,所以必須加條件判斷限制
if(i2||i4){
//當i等于2或者4的時候進來,但是此時是不想要執行后面的打印語句的
//使用continue把當前循環體過程馬上結束,后面的打印語句就無法執行了,直接進入下一次循環中
continue;
}
System.out.println(i);
}//案例2:在上一個視頻案例中,加上break,讓程序可以被結束
…
if (ge * ge * ge + shi * shi * shi + bai * bai * bai == num) {
//如果是水仙花數,就能進入,打印該數字
System.out.println(num);
//已經獲得了水仙花數,不需要再重復執行,循環可以結束,利用break
break;
}
…//案例3:學生管理系統
//我們在學習switch的時候,練過一個學生管理系統的案例Scanner sc = new Scanner(System.in);
//1.以下內容,我們是需要能夠反復執行,知道用戶錄入退出系統的時候,才會結束
//2.不知道用戶要用多久,所以無法判斷循環次數和使用上限,選擇while死循環
while(true){
System.out.println(“歡迎使用本學生管理系統”);
//提示用戶鍵盤錄入
System.out.println(“請選擇功能:1.增加學生 2.刪除學生 3.修改學生 4.查詢學生 5.退出”);
int choice = sc.nextInt();
//根據錄入的數字值,選擇執行不同的功能
switch (choice) {
case 1:
System.out.println(“增加學生…”);
break;
case 2:
System.out.println(“刪除學生…”);
break;
case 3:
System.out.println(“修改學生…”);
break;
case 4:
System.out.println(“查詢學生…”);
break;
default:
System.out.println(“退出系統…”);
//3.退出系統,我們本想著用break結束循環,但是發現無法做到
break;
}
} -
注意事項
- break除了可以用于結束循環語句,也可以用于結束switch語句
- 但是如果一個循環語句內部有switch語句,則switch中的break只能結束switch,無法結束循環
-
總結:break和continue只能跳出、跳過自己所在的那一層關系,如果想要跳出、跳過指定的一層,可以加入標號
-
示例
標號名:while(true){
switch(表達式){
case 值1:
break 標號;
…
}
} -
代碼演示
//給當前循環加上一個標號’loop’,名字可以隨便取
loop:while(true){
System.out.println(“歡迎使用本學生管理系統”);
//提示用戶鍵盤錄入
System.out.println(“請選擇功能:1.增加學生 2.刪除學生 3.修改學生 4.查詢學生 5.退出”);
int choice = sc.nextInt();
//根據錄入的數字值,選擇執行不同的功能
switch (choice) {
case 1:
System.out.println(“增加學生…”);
break;
case 2:
System.out.println(“刪除學生…”);
break;
case 3:
System.out.println(“修改學生…”);
break;
case 4:
System.out.println(“查詢學生…”);
break;
default:
System.out.println(“退出系統…”);
//3.利用結束標號的形式,指定讓break結束外層循環語句
break loop;
}
}
Random
-
作用:用于產生一個隨機數
-
使用步驟
- 導包:import java.util.Random;
- 創建對象:Random r=new Random();
- 獲取隨機數:int num=r.nextInt(10);//獲取隨機數的范圍[0,9]
-
代碼演示
//案例:有一個搖號機,可以搖出1~16號的球,當搖出6號球的時候,獲得一等獎
//1. 導包
import java.util.Random;public class TestRandom {
public static void main(String[] args) {
//2.創建Random對象,這個對象就好比是“搖號機”
Random random = new Random();
//3.號碼是不斷的獲取的,直到獲得6號的時候中一等獎
//4.使用while死循環
while (true) {
//5.利用Random對象,獲取隨機數,隨機數范圍是1~16
//.nextInt(16)的隨機數范圍是015,在這個范圍上加1,范圍就變成了116
int num = random.nextInt(16) + 1;
//6.如果隨機數是6,就獲得一等獎
if (num == 6) {
System.out.println(“恭喜你獲得一等獎,獎品是:李小璐親自為你做頭發”);
//7.結束循環
break;
}
}
}
數組
是一種容器,用來存儲(同種數據類型)的多個值。
-
格式
//數組類型變量的聲明方式1:
數據類型[] 數組名;
//數組樂行變量的聲明方式2:
數據類型 數組名[]; -
代碼演示
//聲明一個用來存放int類型數據的數組
int[] arrs;
//或
int arrs[];//聲明一個用來存放double類型數據的數組
double[] nums;
//或
double nums[];//聲明一個用來存放String類型數據的數組
String[] strs;
//或
String strs[];//注意:數組類型變量和基本數據類型的變量一樣,都必須先初始化,才能使用
數組的動態初始化
初始化:就是在內存中,為數組容器開辟空間,并將數據存入容器中的過程
動態初始化:初始化時只指定數組長度,由系統為數組分配初始值
格式
//格式
數據類型[] 變量名= new 數據類型[數組長度];
//范例
int[] arr= new int[3];
代碼演示
//案例:
//利用數組的冬天初始化,創建一個int類型的數組,可以存放5個int類型的值
int[] arr=new int[5];
//同上,創建一個可以存放3個byte類型的數組
byte[] bts=new byte[3];
//分別打印這兩個數組
System.out.println(arr); //結果:[I@10f87f48
System.out.println(bts); //結果:[B@b4c966a
//直接打印數組,無法獲取數組中的數據
//打印的值是該數組容器的內存地址值
/**
- [:代表數組
- I:代表是int類型
- @:分隔符
- 10f87f48:16進制內存地址值
*/
數組元素訪問
-
索引
- 索引是數組中空間的編號
- 索引從0開始
- 索引是連續的
- 索引逐一增加,每次加1
- 最大的索引值是數組長度減1
- 作用:訪問數組容器中的空間位置
- 索引是數組中空間的編號
-
代碼演示
//訪問數組內部存儲的數據:通過索引訪問
//數組名[索引]//代碼演示:取數據
//動態初始化一個長度為5的int類型數組
int[] arr=new int[5];
//訪問該數組中索引為3的位置的數據
System.out.println(arr[3]);//結果:0
//訪問int數組中索引為5的位置的數組
System.out.println(arr[5]);//運行錯誤,因為數組長度是5,索引最大只能到4//動態初始化一個String類型的數組,長度為3
String[] strs=new String[3];
System.out.println(strs[2]);//結果:null//總結
/**- 初始化數組之后,哪怕沒有給數組存數據,系統也會默認給數組分配初始值。
- 基本數組類型:
- 整數類型的數組,初始化值是0;
- 小數類型的數組,初始化值是0.0;
- 字符類型的數組,初始化值是’ ';
- 布爾類型的數組,初始化值是false
- 引用數據類型:
- 初始化值是null
- 了解:如果是數組類型的數組,那初始化值就是一個地址值
*/
//代碼演示:存數據
//數組名[索引]=數據值;
//套用格式
arr[0]=2;
arr[3]=4;
System.out.println(arr[0]);//結果:2
System.out.println(arr[3]);//結果:4
一個數組內存圖
棧內存:方法運行時,進入的內存,局部變量都存放于這塊內存中
堆內存:new出來的內容都會進入堆內存,并且會存在地址值
方法區:字節碼文件(.class文件)加載時進入的內存
本地方法棧:調用操作系統相關資源
寄存器:交給CPU去使用
兩個數組內存圖
int[] arr1 = new int[2];
System.out.println(arr1);
arr1[0] = 11;
arr1[1] = 22;
System.out.println(arr1[0]);
System.out.println(arr1[1]);
System.out.println(“---------------”);
int[] arr2 = new int[3];
System.out.println(arr2);
arr1[0] = 33;
arr1[1] = 44;
arr1[2] = 55;
System.out.println(arr1[0]);
System.out.println(arr1[1]);
System.out.println(arr1[2]);
多個數組指向相同內存圖
int[] arr1 = new int[2];
arr1[0] = 11;
arr1[1] = 22;
int[] arr2 = arr1;
arr1[0] = 33;
System.out.println(arr1[0]);
System.out.println(arr1[1]);
System.out.println(“---------------”);
System.out.println(arr2[0]);
System.out.println(arr2[1]);
數組的靜態初始化
-
靜態初始化:初始化時指定每個數組元素的初始值,由系統決定數組長度
-
格式范例
//完整格式
//數據類型[] 數組名=new 數據類型[]{數據1,數據2,數據3,…,數據n};
//簡化格式
//數據類型[] 數組名={數據1,數據2,數據3,…,數據n};//完整格式范例
int[] arr = new int[]{23, 14, 9};
System.out.println(arr[0]);//結果:23
System.out.println(arr[1]);//結果:14
System.out.println(arr[2]);//結果:9//簡化格式范例
int[] arr2 = {66,88};
System.out.println(arr[0]);//結果:66
System.out.println(arr[1]);//結果:88 -
兩種初始化的使用場景
- 動態初始化:只明確元素個數,不明確具體數值,推薦使用動態初始化。
- 要存的數據,在創建數組前還不知道是什么,比如需要鍵盤錄入的數據。只知道要錄入幾個。
- 靜態初始化:需求中已經明確了要操作的具體數據,直接靜態初始化即可
- 要存的數據,在數組創建的時候已經有了,比如將全班學員的成績存入數組
- 動態初始化:只明確元素個數,不明確具體數值,推薦使用動態初始化。
-
索引越界異常:訪問了數組中不存在的索引,造成索引越界異常
public class Demo01 {
public static void main(String[] args) {
int[] arr = new int[]{23, 14, 9};
System.out.println(arr[3]);
}
} -
空指針異常:訪問的數組已經不再指向堆內存的數據,造成空指針異常
-
null:空值,代表不存在。表示不指向任何有效對象。
public class Demo01 {
public static void main(String[] args) {
int[] arr = new int[]{23, 14, 9};
System.out.println(arr[1]);
arr = null;
System.out.println(arr[1]);
}
}
-
-
格式
//數組定義及初始化
int[] arr={…};
//…
//遍歷數組
for(int i=0;i<arr.length;x++){
//arr[i],獲取到的就是數組對應索引為i的數據
//由于i的值從0開始,逐一增加,所以每次循環就能獲得一個數組數據,循環結束,數組數據也都拿了一遍
// arr[i];
//至于拿出來的數據是直接打印,還是用一個變量接收,用作后面使用,完全看需求決定
} -
注意
- 遍歷數組,是指取出數組中所有數據的一個過程,不能局限理解為就是打印數組數據
數組獲取最大值
求最值的思路:
1.假設數組中的0索引元素為最大值max(擂主)
2.讓其他的元素和max比較,把較大的值賦值給max(打贏的站在擂臺上)
3.最終max就是最大值(最后站在擂臺上的就是最大值)
//案例:求數組中的最小值,并打印
//定義一個數組,靜態初始化
int[] arr={1,3,46,8,2,5,9,7};
//1.假設數組中的0索引元素為最小值(擂主)
int min=arr[0];
//2.讓其他的元素和min比較,把較小的值賦值給min(打贏的站在擂臺上)
for (int i = 1; i < arr.length; i++) {
if(arr[i]<min){
//3.arr[i]比上一個小一點的守擂的min還要小,所以就讓arr[i]去守擂
min=arr[i]; //打贏的站在擂臺上
}
}
//4.最終min就是最小值(最后站在擂臺上的就是最小值)
System.out.println(“最小值為:”+min);
數組元素求和
-
需求:鍵盤錄入5個整數,存儲到數組中,并對數組求和
-
思路
- 創建鍵盤錄入對象,準備鍵盤錄入數字
- 定義一個求和變量,準備記錄累加后的值
- 動態初始化一個長度為5的int數組,準備存儲鍵盤錄入的數據
- 將鍵盤錄入的數值存儲到數組中
- 遍歷數組,取出每一個元素,并求和
- 輸出總和
-
代碼演示
//1.創建鍵盤錄入對象,準備鍵盤錄入數字
Scanner sc = new Scanner(System.in);
//2.定義一個求和變量,準備記錄累加后的值
int sum = 0;
//3.動態初始化一個長度為5的int數組,準備存儲鍵盤錄入的數據
int[] arr = new int[5];
//4.由于數組有多長錄入幾次,就是遍歷數組錄入
for (int i = 0; i < arr.length; i++) {
//5.提示用戶錄入數字
System.out.println(“請錄入一個整數:”);
int num = sc.nextInt();
//6.將鍵盤錄入的數值存儲到數組中,
arr[i] = num;
}//7.遍歷數組,求和
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
//8.輸出總和
System.out.println(“數組中所有元素的和是:”+sum);
-
需求:已知一個數組==arr = {19,28,37,46,50};==鍵盤錄入一個數據,查找該數據在數組中的索引,并在控制臺輸出找到的索引值
-
分析思路
- 分析:
- 鍵盤錄入一個數據后,讓這個數據和數組中的每一個元素進行比較,如果數據值相等,返回該數據值對應的索引即可。
- 但是,加入錄入了一個數組中不存在的數據,這個時候,就沒有任何內容輸出了,很明顯是有問題的,在實際開發中,如果對應的索引不存在,我們一般都是返回一個負數,而且經常用-1來標識。
- 分析:
-
思路:
-
代碼演示
int[] array={10,20,30,40,15,60,15,80};
//1.鍵盤錄入需要查找的元素
Scanner sc=new Scanner(System.in);
//提示用戶錄入數據
System.out.println(“請錄入需要查找的數據:”);
int key=sc.nextInt();int index=-1; //記錄查找的索引,規定-1表示沒有找到元素
//2.遍歷數組中的元素和key進行比較
for (int i = 0; i < array.length; i++) {
if(array[i]key){
index=i;
//一旦找到了,后面的數據就不需要再遍歷了,直接結束循環即可
break;
}
}
//判斷index的值,是否等于-1
if(index-1){
System.out.println(“對不起,沒有這個元素”);
}else{
System.out.println(key+“元素在數組中的索引為:”+index);
}
-
需求
-
思路
-
代碼實現
//1.定義數組,用于存儲評委的分數
int[] array=new int[6];//2.循環的采用鍵盤錄入的方式,代表評委打分
Scanner sc=new Scanner(System.in);
for (int i = 0; i < array.length; i++) {
//2.1 提示用戶錄入分數
System.out.println(“請輸入第”+(i+1)+“評委的分數:”);
int num = sc.nextInt();
//2.2 把分數存入數組中
array[i]=num;
}//3.求數組元素的最大值
//3.1 把數組中的0索引元素假設為最大值
int max=array[0];
for (int i = 1; i < array.length; i++) {
//3.2 把數組中元素較大的值賦值給max
if(array[i]>max){
max=array[i];
}
}
System.out.println(“最大值為:”+max);//4.求數組元素的最小值
int min=array[0];
for (int i = 1; i < array.length; i++) {
//4.1 把數組中元素較小的值賦值給min
if(array[i]<min){
min=array[i];
}
}
System.out.println(“最小值為:”+min);//5.求數組元素的和
int sum=0;
for (int i = 0; i < array.length; i++) {
sum+=array[i];
}
System.out.println(“所有元素的和為:”+sum);//6.求平均值
double avg=(sum-max-min)*1.0/(array.length-2);
System.out.println(“最終得分:”+avg);
二維數組
- 概述:二維數組也是一種容器,不同于一維數組,該容器存儲的都是一維數組容器
- 為什么要有二維數組:
- 假設給一個學校做一個學生管理系統,該學校有6個年級,每個年級10跟班,每個班60個學生。需要用數組存放這些學生的數據
- 如果我們把這些學生數據存放在一個數組里面,這個數組的數據過于龐大,你要到里面找對應學生的成績會很困難
- 如果一個班級成績裝一個數組,通過班級去找學生,會簡單一點
- 但是這些數組如果不統一管理,還要判斷學生是哪個年級
- 所以如果用一個長度為6的數組,每個索引位置存放一個年紀的數據,那管理起來就很方便了
- 比如我要找3年級2班的張三成績,那就是先找到三年級,再找到2班,然后再到2班里面去遍歷出張三的成績
動態初始化
//格式1:數據類型[][] 變量名 = new 數據類型[m][n];
//m表示這個二維數組,可以存放多少個一維數組。n表示每一個一維數組,可以存放多少個元素
int[][] arr = new int[2][3];
System.out.println(arr);//結果:[[I@10f87f48
System.out.println(arr[0]);//結果:[I@b4c966a
System.out.println(arr[1]);//結果:[I@2f4d3709
//以上結果表明,二維數組中存儲的數據還是數組,所以打印的就是地址值
System.out.println(arr[0][0]);//結果:0
System.out.println(arr[0][1]);//結果:0
System.out.println(arr[0][2]);//結果:0
//以上結果表明,二維數組中存儲的是一維數組,可以通過二維數組和一維數組的索引拿到存儲的數據值
//可以存值,就可以賦值
arr[1][0] = 11;
arr[1][1] = 22;
arr[1][2] = 33;
訪問元素的細節問題
int[] arr1 = {11, 22, 33};
int[] arr2 = {44, 55, 66};
int[] arr3 = {77, 88, 99, 100};
int[][] arr = new int[3][3];
//此時二維數組索引2位置指向的數組是一個長度為3的數組,此時給該數組索引為3的位置賦值會索引越界
arr[2][3] = 101;
arr[0] = arr1;
arr[1] = arr2;
//通過賦值操作,讓原本指向長度為3的數組指向了一個長度為4的數組,該數組索引最大值是3
arr[2] = arr3;
//由于已經更換了指向的數組,所以可以通過二維索引3找到對應的值
System.out.println(arr[2][3]);
靜態初始化
//格式:數據類型[][] 變量名={{元素1,元素2,…},{元素1,元素2,…},…};
//范例:int[][] arr={{11,22},{33,44}};
//代碼案例
int[] arr1 = {11, 22, 33};
int[] arr2 = {44, 55, 66};
int[][] arr = {{11, 22, 33}, {44, 55, 66}};
System.out.println(arr[0][1]);
int[][] array = {arr1, arr2};//結果:22
System.out.println(arr[1][0]);//結果:44
案例:遍歷
需求:已知一個二維數組arr = {{11, 22, 33}, {33, 44, 55,}};遍歷該數組,取出所有元素并打印
思路:
代碼實現
int[][] arr = {{11, 22, 33}, {33, 44, 55,}};
//1.先遍歷二維數組,把里面的一維數組拿出來
for (int i = 0; i < arr.length; i++) {
//2.根據拿出的一維數組,再遍歷這個一維數組
for (int j = 0; j < arr[i].length; j++) {
//3.打印對應一維數組中的值
System.out.println(arr[i][j]);
}
}
案例:求和
需求:某公司季度和月份統計的數據如下:單位(萬元)
- 第一季度:22 , 66 , 44
- 第二季度:77 , 33 , 88
- 第三季度:25 , 45 , 65
- 第四季度:11 , 66 , 99
思路:
代碼實現
//1.定義求和變量,準備記錄最終累加結果
int sum = 0;
//2.使用二維數組來存儲數據,每個季度是一個一維數組,再將4個一維數組裝起來
int[][] arr = {{22, 66, 44}, {77, 33, 88}, {25, 45, 65}, {11, 66, 99}};
//3.遍歷二維數組,取出所有元素,累加求和
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
sum += arr[i][j];
}
}
//4.打印最終累加結果
System.out.println(sum);
方法
- 概述:就是一段具有獨立功能的代碼塊,不調用就不執行
- 作用:
- 如果程序里面有好幾段內容是需要實現相同功能,不使用方法的話,會導致有大量重復的代碼。這種重復代碼每次都要重新寫一遍。所以如果不用方法,代碼的重復度太高,復用性太差
- 方法的出現,把重復代碼變成類似于‘共享單車’的存在,誰有需要就直接用。提高了代碼的復用性
- 前提:
- 方法必須是先創建才可以使用,該過程稱為方法定義
- 方法創建后并不是直接運行的,需要手動在代碼中調用后才可以執行,該過程稱為方法調用
-
格式
//方法定義格式(無參數、無返回值的公共靜態方法)
public static void 方法名(){
//方法體:就是需要復用(被反復使用)的邏輯代碼
}
//范例
public static void printHello(){
System.out.println(“Hello method!”);
}//方法調用:方法名();
//范例:
public static void main(String[] args) {
printHello();
} -
注意事項
-
方法必須先定義后調用,否則程序將報錯
-
方法與方法之間是平級關系,不能嵌套定義
-
- 方法沒有被低調用的時候,都在方法區中的字節碼文件(.class)中存儲
- 方法被調用的時候,需要進入到棧內存中運行
練習:奇偶數判斷
需求
思路
代碼演示
public static void main(String[] args){
//3.調用方法
method();
}
//1.定義一個方法,功能為:判斷一個數是否為奇數或者偶數
public static void method(){
//2.判斷奇偶數邏輯
int a=10;
if(a%2==0){
System.out.println(“偶數”);
}else{
System.out.println(“奇數”);
}
}
帶參數方法的定義和調用
-
為什么要有帶參數方法
- 當方法內部邏輯有用到需要根據不同用戶,不同需求去變化的值的時候,就可以定義帶參數方法,把這種可能會改變的值用方法的參數替代
-
帶參數方法的定義
//單個參數
public static void 方法名(數據類型 變量名){方法體;}
//范例
public static void method(int num){方法體;}//多個參數
public static void 方法名(數據類型 變量名1,數據類型 變量名2,…){方法體;}
//范例
public static void getMax(int num1,int num2){方法體;}//注意
//1.方法定義時,參數中的數據類型與變量名都不能缺少,缺少任意一個程序都將報錯
//2.方法定義時,多個參數之間使用逗號分隔 -
帶參數方法的調用
-
代碼練習
/*
- 練習1:定義一個方法,接收一個int類型的參數,判斷該數字是是奇數還是偶數,在控制臺打印出來。
- 在主方法中調用
*/
/*
- 練習2:定義一個方法,接收兩個int類型的數字,判斷哪個數字是最大值,打印最大值
- 在主方法中調用
*/
形參和實參
概念
- 形參:形式參數,是指方法定義中的參數
- 實參:實際參數,方法調用中的參數
帶參數方法的練習:打印n~m之間所有的奇數
-
需求:設計一個方法(print)用于打印n到m之間所有的奇數
-
思路:
-
代碼演示
-
為什么要有帶返回值的方法
- 我們經常會根據一個方法產出的結果,來去組織另外一段代碼邏輯,為了拿到這個方法產生的結果,就需要定義帶有返回值的方法
-
帶返回值方法的定義
-
帶返回值方法的調用
-
代碼演示
//案例:計算兩個數的乘積
public static void main(String[] args) {
//3.調用方法,因為方法定義了兩個參數,都是整數,所以這里要給兩個整數的實參
//4.因為方法有返回值,所以可以在方法調用處使用一個變量接收這個方法調用完的返回值
//5.方法返回值什么類型,接收的變量就應該是什么類型
int result = cheng(2, 3);
System.out.println(result);//結果:6
}
//1.兩個整數的乘積,結果還是整數,所以返回值類型應該為int
public static int cheng(int num1,int num2) {
//2.通過return關鍵,返回乘積
return num1 * num2;
}
-
需求:設計一個方法可以獲取兩個數的較大值,數據來自于參數
-
思路:
-
代碼實現
-
擴展練習
//仿照課堂案例,求三個數的最大值
-
格式
-
代碼演示
-
方法不能嵌套定義
-
方法的返回值類型為void,表示該方法沒有返回值,沒有返回值的方法可以省略return語句不寫,如果要寫return語句,后面不能跟具體的數據
-
return語句下面,不能編寫代碼,因為永遠執行不到,屬于無效代碼
-
return語句,如果要返回值,只能帶回一個結果
//案例:沒有返回值的方法,可以省略return不寫
public static void eat(){
System.out.println(“吃飯”);
//return的其中一個作用,是結束整個方法,但是不可以帶返回值
return;
//return 3; 方法本身沒有規定返回值,在此處就不能帶返回值,因為你也不知道返回什么類型比較合適
}//案例:計算器加法運算
public static int add(int num1,int num2){
// return的第二個作用,就是返回一個值
return num1+num2;
}//案例:return語句下面,不能編寫代碼
public static void drink(int age){
if(age<8){
System.out.println(“喝白開水”);
//此處是個if判斷語句,按照邏輯推斷,如果進入if語句中,下面的代碼邏輯肯定是不想再執行
//如果此處不加以限制,if執行結束,代碼依然會執行:喝紅牛
//所以此處可以加上return,直接結束方法
return;
//注意,說的return下面不能加代碼,是指同一個邏輯代碼塊(大括號)中而已
}
System.out.println(“喝紅牛”);
}
- 概念:在同一個類中,方法名相同,參數列表不同(參數順序不同也算不同,變量名不同不算)的多個方法,形成了方法的重載。
- 方法簽名:JVM調用方法的時候是通過方法簽名去區分的,方法簽名包括方法名,參數數量、類型和順序
- 注意:參數順序不同雖然也可以構成方法重載,但是不推薦,沒有意義
-
需求:使用方法重載的思想,設計比較兩個整數是否相同的方法,兼容全整數類型(byte,short,int,long)
-
思路:
-
代碼練習
-
方法的形參在內存當中也就是一個變量而已
-
一個方法在傳遞參數的時候,如果是基本數據類型,那么傳遞的就是該變量所記錄的具體的數值
public static void main(String[] args) {
int number = 100;
System.out.println(“main方法中,調用change方法前:” + number);//結果:100
//基本數據類型,傳遞的是number的數值,而非變量
change(number);
//打印的變量,依然還是main方法中的變量,此變量的值未有任何改變,依然是100
System.out.println(“main方法中,調用change方法后:” + number);//結果:100
}//方法的形參相當于是這個方法中的一個局部變量,屬于change方法,和main方法中的變量不是同一個
public static void change(int number) {
//在未執行下方賦值操作時,從main方法傳遞過來的是值100,將100賦值給了change方法的變量number
//此時修改的是change方法中的變量number值,對main方法中的number無影響
number = 200;
System.out.println(“在change方法中的:” + number);//結果:200
}
-
方法傳遞,如果傳入的是引用數據類型,傳進去的就是該引用數據類型的內存地址
public static void main(String[] args) {
//定義一個數組,數組是引用數據類型
int[] arr = {23, 12, 44, 77};
//該數組在堆內存中的一個空間存放,變量arr持有的是這個空間的地址
System.out.println(“在main方法中,調用change方法前:” + arr[1]);//結果:12
//arr是引用數據類型變量,傳入的就是arr持有的數組在堆內存的地址,而非數組本身
change(arr);
System.out.println(“在main方法中,調用change方法后:” + arr[1]);//結果:0
}public static void change(int[] arr) {
//調用方法,將傳遞過來的地址賦值給了change方法中的變量arr,change方法中的arr也持有這個地址
//通過持有的地址,可以找到堆內存中的數組,所以可以對其修改值
arr[1] = 0;
//打印的就是修改之后的0值
System.out.println(“在change方法中的:” + arr[1]);//結果:0
}
-
需求:設計一個方法,用于數組遍歷,要求遍歷的結果是在一行上的。例如:[11,22,33,44,55]
-
思路:
-
代碼演示
public static void main(String[] args) {
//1.靜態初始化一個數組
int[] arr = {11, 22, 33, 44, 55};
printArr(arr);
}//2.定義一個方法,對數組進行遍歷。因為是打印,所以是不需要返回值的
public static void printArr(int[] arr) {
//3.要打印數組中所有數據,必須要先遍歷數組
for (int i = 0; i < arr.length; i++) {
//4.將數組中每個元素取出來
int num = arr[i];
//5.打印數組中該元素的值,但是因為有格式要求,所以不要換行打印
//6.當i=0和i是最后一個索引的時候,打印格式要加上中括號
if (i == 0) {
System.out.print(“[” + num + ", ");
} else if (i == arr.length - 1) {
System.out.print(num + “]”);
} else {
//7.打印的數字之間要用逗號和空格隔開
System.out.print(num + ", ");
}
}
}
-
需求:設計一個方法用于獲取數組中元素的最大值
-
思路:
-
代碼演示:
-
需求:設計一個方法,該方法能夠同時獲取數組的最大值,和最小值
-
思路:
-
代碼演示:
基礎練習
案例需求
朋友聚會的時候可能會玩一個游戲:逢七過。規則是:從任意一個數字開始報數,當你要報的數字包含7或者是7的倍數時都要說:過。為了幫助大家更好的玩這個游戲,這里我們直接在控制臺打印出1-100之間的滿足逢七必過規則的數據。這樣,大家將來在玩游戲的時候,就知道哪些數據要說:過。代碼實現
/*思路:1:數據在1-100之間,用for循環實現數據的獲取2:根據規則,用if語句實現數據的判斷:要么個位是7,要么十位是7,要么能夠被7整除3:在控制臺輸出滿足規則的數據*/ public class Test1 {public static void main(String[] args) {//數據在1-100之間,用for循環實現數據的獲取for(int x=1; x<=100; x++) {//根據規則,用if語句實現數據的判斷:要么個位是7,要么十位是7,要么能夠被7整除if(x%10==7 || x/10%10==7 || x%7==0) {//在控制臺輸出滿足規則的數據System.out.println(x);}}} }案例需求
有這樣的一個數組,元素是{68,27,95,88,171,996,51,210}。求出該數組中滿足要求的元素和,要求是:求和的元素個位和十位都不能是7,并且只能是偶數代碼實現
package com.itheima.test;public class Test2 {/*有這樣的一個數組,元素是{68,27,95,88,171,996,51,210}。求出該數組中滿足要求的元素和,要求是:求和的元素個位和十位都不能是7,并且只能是偶數*/public static void main(String[] args) {// 1. 定義數組int[] arr = {68, 27, 95, 88, 171, 996, 51, 210};// 2. 求和變量int sum = 0;// 3. 遍歷數組for (int i = 0; i < arr.length; i++) {// 4. 拆分出個位和十位int ge = arr[i] % 10;int shi = arr[i] / 10 % 10;// 5. 條件篩選if (ge != 7 && shi != 7 && arr[i] % 2 == 0) {sum += arr[i];}}// 6. 打印結果System.out.println(sum);} }案例需求
定義一個方法,用于比較兩個數組的內容是否相同代碼實現
/*思路:1:定義兩個數組,分別使用靜態初始化完成數組元素的初始化2:定義一個方法,用于比較兩個數組的內容是否相同3:比較兩個數組的內容是否相同,按照下面的步驟實現就可以了首先比較數組長度,如果長度不相同,數組內容肯定不相同,返回false其次遍歷,比較兩個數組中的每一個元素,只要有元素不相同,返回false最后循環遍歷結束后,返回true4:調用方法,用變量接收5:輸出結果*/ public class Test3 {public static void main(String[] args) {//定義兩個數組,分別使用靜態初始化完成數組元素的初始化int[] arr = {11, 22, 33, 44, 55};//int[] arr2 = {11, 22, 33, 44, 55};int[] arr2 = {11, 22, 33, 44, 5};//調用方法,用變量接收boolean flag = compare(arr,arr2);//輸出結果System.out.println(flag);}//定義一個方法,用于比較兩個數組的內容是否相同/*兩個明確:返回值類型:boolean參數:int[] arr, int[] arr2*/public static boolean compare(int[] arr, int[] arr2) {//首先比較數組長度,如果長度不相同,數組內容肯定不相同,返回falseif(arr.length != arr2.length) {return false;}//其次遍歷,比較兩個數組中的每一個元素,只要有元素不相同,返回falsefor(int x=0; x<arr.length; x++) {if(arr[x] != arr2[x]) {return false;}}//最后循環遍歷結束后,返回truereturn true;} }案例需求
已知一個數組 arr = {19, 28, 37, 46, 50}; 鍵盤錄入一個數據,查找該數據在數組中的索引。并在控制臺輸出找到的索引值。如果沒有查找到,則輸出-1代碼實現
/*思路:1:定義一個數組,用靜態初始化完成數組元素的初始化2:鍵盤錄入要查找的數據,用一個變量接收3:定義一個索引變量,初始值為-14:遍歷數組,獲取到數組中的每一個元素5:拿鍵盤錄入的數據和數組中的每一個元素進行比較,如果值相同,就把該值對應的索引賦值給索引變量,并結束循環6:輸出索引變量*/ public class Test4 {public static void main(String[] args) {//定義一個數組,用靜態初始化完成數組元素的初始化int[] arr = {19, 28, 37, 46, 50};//鍵盤錄入要查找的數據,用一個變量接收Scanner sc = new Scanner(System.in);System.out.println("請輸入要查找的數據:");int number = sc.nextInt();//調用方法int index = getIndex(arr, number);//輸出索引變量System.out.println("index: " + index);}//查找指定的數據在數組中的索引/*兩個明確:返回值類型:int參數:int[] arr, int number*/public static int getIndex(int[] arr, int number) {//定義一個索引變量,初始值為-1int index = -1;//遍歷數組,獲取到數組中的每一個元素for(int x=0; x<arr.length; x++) {//拿鍵盤錄入的數據和數組中的每一個元素進行比較,如果值相同,就把該值對應的索引賦值給索引變量,并結束循環if(arr[x] == number) {index = x;break;}}//返回索引return index;} }案例需求
已知一個數組 arr = {19, 28, 37, 46, 50}; 用程序實現把數組中的元素值交換,交換后的數組 arr = {50, 46, 37, 28, 19}; 并在控制臺輸出交換后的數組元素。代碼實現
/*思路:1:定義一個數組,用靜態初始化完成數組元素的初始化2:循環遍歷數組,這一次初始化語句定義兩個索引變量,判斷條件是開始索引小于等于結束索引3:變量交換4:遍歷數組*/ public class Test5 {public static void main(String[] args) {//定義一個數組,用靜態初始化完成數組元素的初始化int[] arr = {19, 28, 37, 46, 50};//調用反轉的方法reverse(arr);//遍歷數組printArray(arr);}/*兩個明確:返回值類型:void參數:int[] arr*/public static void reverse(int[] arr) {//循環遍歷數組,這一次初始化語句定義兩個索引變量,判斷條件是開始索引小于等于結束索引for (int start = 0, end = arr.length - 1; start <= end; start++, end--) {//變量交換int temp = arr[start];arr[start] = arr[end];arr[end] = temp;}}/*兩個明確:返回值類型:void參數:int[] arr*/public static void printArray(int[] arr) {System.out.print("[");for (int x = 0; x < arr.length; x++) {if (x == arr.length - 1) {System.out.print(arr[x]);} else {System.out.print(arr[x] + ", ");}}System.out.println("]");} }案例需求
在編程競賽中,有6個評委為參賽的選手打分,分數為0-100的整數分。選手的最后得分為:去掉一個最高分和一個最低分后 的4個評委平均值 (不考慮小數部分)。代碼實現
思路:
1:定義一個數組,用動態初始化完成數組元素的初始化,長度為6
2:鍵盤錄入評委分數
3:由于是6個評委打分,所以,接收評委分數的操作,用循環改進
4:定義方法實現獲取數組中的最高分(數組最大值),調用方法
5:定義方法實現獲取數組中的最低分(數組最小值) ,調用方法
6:定義方法實現獲取數組中的所有元素的和(數組元素求和) ,調用方法
7:按照計算規則進行計算得到平均分
8:輸出平均分
案例需求
請從26個英文字母(大小寫都包含),以及數字0-9中,隨機產生一個5位的字符串驗證碼并打印在控制臺
效果:uYq8I,3r4Zj
代碼實現
import java.util.Random;public class Test {public static void main(String[] args) {// 1. 將所需要用到的字符存入數組char[] datas = initData();Random r = new Random();String result = "";// 2. 隨機取出5個字符for (int i = 1; i <= 5; i++) {int index = r.nextInt(datas.length);char c = datas[index];result += c;}// 3. 打印驗證碼System.out.println(result);}private static char[] initData() {char[] chs = new char[62];int index = 0;for (char i = 'a'; i <= 'z'; i++) {chs[index] = i;index++;}for (char i = 'A'; i <= 'Z'; i++) {chs[index] = i;index++;}for (char i = '0'; i <= '9'; i++) {chs[index] = i;index++;}return chs;} }面向對象基礎
1.1 面向對象編程思想
-
面向對象編程(oop)
- 是一種以對象為中心的編程思想,通過指揮對象實現具體的功能
-
需求:洗衣服
-
對象:客觀存在的事物。例如廚師、洗衣機這些都是客觀存在的事物,并且都有自己能夠完成的功能。這些事物就可以通過java代碼的形式描述成為程序中的對象。然后就可以指揮這些對象去調用里面一個個的功能
-
小結
- 客觀存在的任何一種事物,都可以看作為程序中的對象
- 使用面向對象思想可以將復雜的問題簡單化
- 將我們從執行者的位置,變成了指揮者
-
代碼演示
//面向過程:解決數組遍歷問題
int[] arr = {11, 22, 33, 44, 55, 66};
//1. 打印左括號,不能換行
System.out.print(“[”);
//2. 遍歷數組,取出數組中每一個值
for (int i = 0; i < arr.length; i++) {
//3. 判斷是否是最后一個元素
if (i == arr.length - 1) {
//4.如果是最后一個元素,除了打印元素值,還要加上括號
System.out.println(arr[i] + “]”);
} else {
//5. 如果不是最后一個元素,打印數值不能換行,而且還要用空格隔開
System.out.print(arr[i] + " ");
}
}
//總結:面向過程的思想,總共分為了5個步驟,每一個步驟都需要自己實現//面向對象:解決數組遍歷問題
public class OopTest {
public static void main(String[] args) {
int[] arr = {11, 22, 33, 44, 55, 66};
//1.先想誰可以實現數組遍歷的功能
//2.想起了數組操作員,創建數組操作員對象
//3.利用對象解決問題
數組操作員 二狗 = new 數組操作員();
二狗.遍歷打印數組(arr);
}
}class 數組操作員 {
public static void 遍歷打印數組(int[] arr) {
//1. 打印左括號,不能換行
System.out.print(“[”);
//2. 遍歷數組,取出數組中每一個值
for (int i = 0; i < arr.length; i++) {
//3. 判斷是否是最后一個元素
if (i == arr.length - 1) {
//4.如果是最后一個元素,除了打印元素值,還要加上括號
System.out.println(arr[i] + “]”);
} else {
//5. 如果不是最后一個元素,打印數值不能換行,而且還要用空格隔開
System.out.print(arr[i] + " ");
}
}
}
}
1.2 類和對象的關系
-
什么是類
- 類是對現實生活中一類具有共同屬性和行為的事物的抽象
- 類是對事物,也就是對象的一種描述,可以將類理解為一張設計圖,根據設計圖,可以創建出具體存在的事物。
- 根據類去創建對象
-
類的組成
- 屬性:該事物的各種特征
- 例如黑馬學生事物的屬性:姓名、年齡、畢業院校…
- 行為:該事物存在的功能(能夠做的事情)
- 例如黑馬學生事物的行為:學習、Java編程開發…
- 屬性:該事物的各種特征
-
什么是對象?
- 是能夠看得到摸得著的真實存在的實體
1.3 類的定義
-
類的組成:屬性和行為
- 屬性:在代碼中通過成員變量來體現(類中方法外的變量)
- 行為:在代碼中通過成員方法來體現(和前面的方法相比,去掉static關鍵字即可)
-
類的定義步驟:
-
定義類
-
編寫類的成員變量
-
編寫類的成員方法
public class 類名{
//成員方法 //方法1 //方法2 //...
//成員變量
//變量1的數據類型 變量1;
//變量2的數據類型 變量2;
//…}
-
-
代碼實現
//視頻案例:學生類
//姓名是一段內容,可以使用字符串類型去表示String name = "張三";//年齡是一個整數,可以使用int類型去表達int age = 23;//2.行為:學習//成員方法:跟之前定義的方法一樣,只不過去掉了staticpublic void study() {System.out.println("好好學習,天天向上");}//3.不建議在這種用來描述事物的類中寫main主方法,主方法一般單獨寫一個測試類去實現
public class Student {
//1.屬性:姓名,年齡
//成員變量:跟之前定義的變量格式一樣,只不過位置發生了改變,從方法中跑到了類中方法外}
/**
- 練習:老師類
- 屬性:姓名,年齡,學科
- 行為:工作
*/
1.4 對象的創建和使用
-
創建對象
- 格式:類名 對象名=new 類名();
- 范例:Student stu=new Student();
-
使用對象
- 使用成員變量
- 格式:對象名.變量名
- 范例:stu.name
- 使用成員變量
-
使用成員方法
- 格式:對象名.方法名()
- 范例:stu.study();
-
代碼演示
//創建學生類對象,并且給其屬性賦值。獲取其屬性值,調用其方法
public class TestStudent {
public static void main(String[] args) {
//1. 創建學生類對象,把對象賦值給學生類型的變量stu
Student stu = new Student();
//2. 使用成員變量
System.out.println(stu.name);//結果:null
System.out.println(stu.age);//結構:0
//3. 就算沒有給成員變量賦值,也可以使用,整數基本數據類型默認是0,字符串類型默認是null
//4. 給成員變量賦值
stu.name = “張三”;
stu.age = 23;
System.out.println(stu.name);//結果:張三
System.out.println(stu.age);//結果:23
//5.使用成員方法
stu.study();
//6.打印對象
System.out.println(stu);//結果:com.itheima.test.Student@b4c966a
//打印對象,默認打印的是:全類名(包名+類名)+ 地址哈希值
}
}
public class Student {
String name;
int age;
public void study() {
System.out.println(“好好學習,天天向上”);
}
}
1.5 案例:手機類的創建和使用
-
需求:定義一個手機類,然后定義一個手機測試類,在收集測試類中通過對象完成成員變量和成員方法的使用
-
分析:
- 手機應該有哪些屬性?
- 品牌
- 價格
- …
- 手機應該有哪些行為?
- 打電話
- 發短信
- …
- 手機應該有哪些屬性?
-
思路
-
代碼實現
public class Phone {
//成員方法:打電話public void call(String name) {System.out.println("給" + name + "打電話");}//成員方法:發短信public void sendMessage() {System.out.println("群發短信");}
//成員變量:品牌、價格
String brand;
int price;}
//測試類
public class TestPhone {
public static void main(String[] args) {
//1. 創建對象
Phone phone = new Phone();
//2. 給成員變量賦值
phone.brand = “大米”;
phone.price=2999;
//3. 打印賦值后的成員變量
System.out.println(phone.brand + “…” + phone.price);
//4. 調用成員方法
phone.call(“張三”);
phone.sendMessage();
}
}
2.1 單個對象內存圖
- 有new就在堆內存開辟空間,對象就是堆內存的一個塊空間,存儲有對象的屬性值和方法調用地址
- 對象的變量名存儲的其實是對象在堆內存空間的地址值,jvm虛擬機可以根據地址值找到對象空間
- 能找到對象空間,從而能獲取對象的屬性數據,調用對象的方法
2.2 兩個對象內存圖
- 有幾個new,就會在堆內存開辟幾個對象空間
- 同一個類的不同對象空間中屬性名字都是一樣的,但是其存儲的屬性數據相互獨立
- 同一個類的不同對象空間中方法地址一樣,所以調用的方法也是一樣的
2.3 兩個引用指向同一個對象內存圖
-
代碼執行到Student stu2=stu1;的時候,通過s1指向的堆內存中對象的地址,將s2也指向這個地址,所以s1和s2都指向同一個對象
-
代碼執行到stu1=null;的時候,stu1原本持有的是堆內存中學生對象的地址,由于置null,此指向切斷了。s1再也無法找到堆內存中該學生對象
-
在執行完stu2=null;之后,就沒有變量再指向堆內存中的學生對象,此對象無法再被使用到。所以垃圾回收器會在空閑的時候將這個學生對象的空間給清理掉
-
當堆內存中,對象或數組產生的地址,通過任何方式都不能被找到后,就會判定為內存中的"垃圾",垃圾會被Java垃圾回收器,空閑的時候自動進行清理
- 成員變量:類中方法外定義的變量
- 局部變量:方法中的變量
- 成員變量和局部變量的區別
4.1 private關鍵字
問題: 1.為什么說通過對象名給其屬性賦值具有安全隱患問題? 2.private關鍵字可以用來修飾哪些內容? 3.使用private修飾屬性之后,還需要做什么操作?- 概述:
- 是一個權限修飾符
- 可以修飾成員(成員變量和成員方法)
- 特點:
- 被private修飾的成員只能在本類中才能訪問,其他包,其他類都不能訪問
- 針對private修飾的成員變量,如果需要被其他類使用,要提供相應的操作
- 提供"get變量名()"方法,用于獲取成員變量的值,方法用public修飾
- 提供"set變量名(參數)"方法,用于設置成員變量的值,方法用public修飾
4.2 private關鍵字的使用
- 一個標準類的編寫:
-
把成員變量用private修飾
-
提供對應的setXxx()/getXxx()方法
/**
-
學生類:
-
屬性:姓名,年齡
-
需求:
-
1.利用private對類的屬性進行封裝
-
2.給屬性提供設置值和獲取值的方法
-
3.在測試類中測試
*/
public class Student {
//1.為了以后別人不能隨意給我的屬性賦值,就給這兩個成員變量加上private
private int age;
private String name;//2.加上了private之后,這兩個屬性的變量,以后就只能在當前這個Student類中被訪問,外類無法訪問
//3.外類無法訪問,這個變量定義的就沒有意義了,所以還要對外提供對這兩個變量的訪問方式
//提供set和get方法,給外界使用
//4.提供給屬性設置值的方法
//設置年齡值,目的是給本類的age變量賦值,賦的值應該是int類型
//這個值是別人調用方法的時候傳過來的,所以應該作為形式參數聲明
public void setAge(int a) {
//聲明了形式參數,別人調用的時候就得傳一個int值過來,那這個值目的是給age變量賦值
age = a;
}//有了賦值的,就應該要有取值的
public int getAge() {
//這里是把age變量的值返回給方法調用處,直接return
return age;
}public void setName(String n) {
name = n;
}public String getName() {
return name;
}public void show() {
//這個方法只是做展示對象數據的作用,也沒有返回值
System.out.println(name + “…” + age);
}
}
public class Test03 {
public static void main(String[] args) {
Student stu = new Student();
stu.show();
stu.setAge(17);
stu.setName(“張三”);
stu.show();
System.out.println(stu.getAge());
System.out.println(stu.getName());
}
} -
-
4.3 this關鍵字
問題: 1.類方法的形式參數名和類屬性名出現重名,會有什么問題? 2.this關鍵字有哪些作用? 3.在方法中打印this關鍵字,打印的內容代表誰?-
概述:
- 代表所在類的對象引用(對象在堆內存當中的地址值)
- 方法被哪個對象調用,this就代表哪個對象
-
作用:可以調用本類的成員(變量、方法),解決局部變量和成員變量的重名問題
-
注意:如果局部變量和成員變量重名,Java使用的是就近原則
//練習:使用this關鍵字,優化老師類的set方法
//2.行為:工作public void work() {System.out.println("傳道受業解惑");}//3.針對屬性,增加set\get方法。并且使用this優化get方法public void setName(String name) {this.name=name;}public String getName() {return name;}public void setAge(int age) {this.age=age;}public int getAge() {return age;}public void setObj(String obj) {this.obj=obj;}public String getObj() {return obj;}
public class Teacher {
//屬性:姓名、年齡、學科
//1.利用private修飾各個屬性
private String name;
private int age;
private String obj;}
4.4 this內存原理
- 結論:
- 方法被哪個對象調用,方法中的this就代表哪個對象的引用
4.5 封裝
問題: 1.封裝的思想指的是什么? 2.將一個類的屬性私有化就是封裝嗎? 3.在程序中引入封裝思想,有什么好處?- 封裝是面向對象的三大特征之一(封裝,繼承,多態)
- 隱藏實現細節,進對外暴露公共的訪問方式(方法)
- 封裝常見的體現
- 私有成員變量(隱藏),提供setXxx和getXxx方法(暴露公共的訪問)
- 將代碼抽取到方法中(隱藏了實現細節),這是對代碼的一種封裝
- 將屬性抽取到類中,這是對數據的一種封裝
- 封裝的好處:
- 提高了代碼的安全性(private和set/get)
- 提高了代碼的復用性(方法,可以重復使用)
5.1 構造方法的格式和執行時機
問題: 1.沒有給一個類定義構造方法,為什么也能夠調用? 2.能不能在構造方法中使用return關鍵字返回一個值? 3.構造方法是在什么時候就會被調用?-
概述:構建、創造對象的時候,所調用的方法
-
格式:
-
方法名和類名相同,大小寫也要一致;
-
沒有返回值類型,連void都沒有;
-
沒有具體的返回值(不能由return帶回結果數據)
//格式:
}
public class 類名{
//…
public 類名(參數列表){
構造方法體;
}
//…
}
//2.范例:
public class Person{
private String name;
private int age;
public Person(){}
-
-
執行時機:
- 創建對象的時候調用,每創建一次對象,就會執行一次構造方法
- 不能手動調用構造方法。只能使用new關鍵字調用
5.2 構造方法的作用
問題: 1.構造方法除了創建對象,還有什么作用? 2.給一個類提供了有參數的構造方法,還會有默認空參的構造嗎?-
創造屬于類的對象
-
用于給對象的數據==(屬性)==進行初始化
//案例:
public Student(String name, int age) {this.name = name;this.age = age;}public void show() {System.out.println(name + "..." + age);}
public class Student {
private String name;
private int age;}
//練習:修改Person類,能夠讓Person類通過構造方法給對象屬性賦值。并在測試類中驗證
5.3 構造方法的注意事項
問題: 1.無論什么情況下,系統都會提供一個默認構造方法嗎? 2.以后在寫一個標準類的時候,構造方法應該如何寫?- 構造方法的創建
- 如果沒有定義構造方法,系統將給出一個默認的無參數構造方法
- 如果定義了構造方法,系統將不再提供默認的構造方法
- 構造方法的重載
- 如果自定義了帶參數構造方法,還要使用無參數構造方法,就必須再寫一個無參數構造方法
- 推薦的使用方式
- 無論是否使用,都手動書寫無參數構造方法,和帶參數構造方法
- 總結:
- 無參構造和有參構造都要寫
5.4 案例:標準類的代碼編寫和使用
- 需求:
- 成員變量:使用private修飾
- 構造方法:
- 提供一個無參構造方法
- 提供一個帶多個參數的構造方法
- 成員方法
- 提供每一個成員變量對應的setXxx()/getXxx()
- 提供一個顯示對象信息的show()
- 創建對象并為其成員變量賦值的兩種方式
-
無參構造方法創建對象后使用setXxx()賦值
-
使用帶參構造方法直接創建帶有屬性值的對象
/**
-
因為程序是為了現實服務的,以后假設我們寫了一個學生管理系統,系統中就存在一個數據叫學生數據
-
而僅僅用基本數據類型的數據無法完全描述學生數據,因為學生數據中有學號、姓名、年齡、分數等等
-
這些數據里面有各種數據類型:int、String等
-
這個時候就可以使用面向對象思想,用一個類去描述這類信息
*/
public class Student {
//1.定義類的屬性,學生有哪些屬性?
//學號
private String id;
//姓名
private String name;
//年齡
private int age;
//分數
private int score;
//2.為了不讓外接隨意更改我的屬性值,給我一些非法的值,比如分數給一個-100分,全部用private修飾
//3.屬性被封裝了,但是這些屬性值,未來外接還是要使用的呀,那怎么用呢?提供對應的set\get方法//5.提供構造方法
public Student(String id, String name, int age, int score) {
//這里給屬性賦值,那么構造方法就應該有形式參數
this.id = id;
this.name = name;
this.age = age;
this.score = score;
}public Student() {
}//4.針對所有的屬性,都有對應方法給這些屬性設置值和獲取他們的值
public String getId() {
return id;
}public void setId(String id) {
this.id = id;
}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;
}public int getScore() {
return score;
}public void setScore(int score) {
this.score = score;
}public void show() {
System.out.println(id + “…” + name + “…” + age + “…” + score);
}
}
public class Test01 {
public static void main(String[] args) {
//1.創建一個學生對象:類名 變量名=new 構造方法();
Student stu1 = new Student();
//2.對象現在只有默認值,沒有使用的價值,開始賦值
//使用常規的set方法賦值。格式:對象名.方法名(值);
stu1.setId(“001”);
stu1.setName(“張三”);
stu1.setAge(23);
stu1.setScore(98);
//3.現在stu1對象已經有了值,展示看看
stu1.show();
//代表值賦值成功,以后你可以在程序中使用對象去存儲比較復雜的數據值
//4.但是上面的代碼還是復雜了一點,賦值操作臺頻繁
//有一種簡單的賦值操作,就是利用構造方法賦值,給這個類提供一個帶參數的構造方法
Student stu2 = new Student(“002”, “李四”, 22, 100);
stu2.show();
//5.明明有了構造方法可以賦值,為什么還要有set方法?
//因為一用構造方法,就是一個新的對象,因為構造方法不能修改屬性值,只能創建對象的時候給它賦值一次
//而set方法可以反復修改同一個對象的值,作用不一樣
}
} -
-
1.1 API概述-幫助文檔的使用
問題: 1.什么是API,使用API文檔有什么好處? 2.如何使用API文檔,應該看文檔的哪些內容?- 什么是API
- API (Application Programming Interface) :應用程序編程接口
- 官方寫好的一個個可以被我們使用的對象工具的模板(類),每個類里面都有提供給我們的屬性和功能
- 什么是API文檔:
- 這么多的類和功能,我們不可能記得住,需要使用文檔去查詢他們的使用方式,這個文檔就是API文檔
- API幫助文檔使用:
- 打開幫助文檔
- 找到索引選項卡中的輸入框
- 在輸入框中輸入Random
- 看類在哪個包下,因為不同包下可能有同名類
- 看類的描述,要明白這個類是不是我們想要的工具
- 看構造方法,如果是我們要的,那我們得知道如何創建它的對象
- 看成員方法,我們要知道這個工具具體有哪些功能,使用的時候需不需要給條件
1.2 鍵盤錄入字符串
問題: 1.Scanner鍵盤錄入字符串總共有幾種方式? 2.Scanenr使用next()方法錄入字符串會存在什么問題? 3.是否需要解決nextLine()方法存在的問題?-
Scanner類錄入字符串的方法:
- next():遇到了空格,就不再錄入數據了,結束標記:空格,tab鍵
- nextLine():可以將數據完整的接收過來,結束標記:回車換行符
-
注意事項:
- next()方法錄入字符串,字符串不能帶空格,否則信息將錄入不全
- nextLine()方法錄入字符串,不要和nextInt()方法連用,否則會直接跳過,直接結束
-
nextLine()和錄入其他數據的問題解決方案:
- 以后錄入字符串都用next();
- 如果非要錄入帶空格的字符串,如果是和錄入其他數據混用,在錄入其他數據之后,馬上寫一個sc.nextLine();不用變量接收。目的是消費掉回車
-
總結:
- 今天核心是API文檔的使用,所以這個小結只是利用Scanner舉例
- 看文檔的過程中,也會發現有自己不懂的內容,比如方法的參數中出現了一些沒有學過的類,這通常都不需要關注,以后會接觸
- 看文檔注意,先明確自己的需求,然后看方法名,猜測一下哪個方法是自己想要的。結合方法的參數和返回值一起去推測,參數告訴你執行這個功能需要什么條件,返回值告訴你執行完這個功能,我能給你什么數據
-
案例練習:
- 需求:
- 已有學生類如下,請根據屬性內容,補全其構造方法和setter\getter方法
- 控制臺提示錄入4名學生的各項信息,將錄入的信息封裝成學生對象存入數組
- 在控制臺打印4名學生的信息
- 效果圖:
-
鍵盤錄入學生信息:
-
打印所有學生信息:
-
- 需求:
-
代碼材料:
public class Student {
//學生id
private String id;
//學生姓名
private String name;
//學生年齡
private int age;
//學生評語
private String estimate;
} -
代碼實現:
//1.要鍵盤錄入四名學生信息,存入數組,數組長度是4
//創建鍵盤錄入對象
Scanner sc = new Scanner(System.in);
//創建一個長度為4的學生數組
Student[] stus = new Student[4];
//2.開始錄入4名學生信息,錄入的操作是重復的,重復的次數是明確的,使用for
for (int i = 0; i < stus.length; i++) {
//3.提示用戶錄入信息
System.out.println(“請輸入第” + (i + 1) + “名學生信息”);
System.out.println(“請輸入學生學號:”);
String id = sc.next();
System.out.println(“請輸入學生姓名:”);
String name = sc.next();
System.out.println(“請輸入學生年齡:”);
int age = sc.nextInt();
//加一個nextLine消費回車
sc.nextLine();
System.out.println(“請輸入學生評語:”);
String estimate = sc.nextLine();
//4.學生信息錄入了,但是都是零散的數據,要把這些零散數據統一管理
//根據信息創建學生對象
Student stu = new Student(id, name, age, estimate);
//5.存入數組
stus[i] = stu;
}
//6.循環結束,所有學生信息都存入了數組,開始遍歷打印所有學生信息
for (int i = 0; i < stus.length; i++) {
//7.取出學生對象
Student student = stus[i];
System.out.println(“學號:” + student.getId() + “,姓名:” + student.getName() + “,年齡:” + student.getAge() + “,評語:” + student.getEstimate());
}
2.1 String概述
問題: 1.如果使用的是java.lang包下的類,是否需要進行導包? 2.在創建String類對象的時候,它有什么特殊的地方? 3.String類的length()方法返回的長度是根據什么得到的?2.2 String類常見構造方法
問題: 1.有多少種常見的字符串對象創建方式? 2.哪種字符串創建方式,實際上是創建了兩個字符串對象?常用的構造方法
示例代碼
//案例:分別用以上4種方式創建字符串對象,并且打印2.3 創建字符串對象的區別對比
問題: 1.如何比較兩個字符串對象在內存中的地址是否相同?== 2.在什么情況下,字符串不會重新創建,而是直接復用?賦值一個已經存在的字符串常量 3.字符串常量在內存中的哪個位置進行存儲?字符串常量池-
通過構造方法創建
通過 new 創建的字符串對象,每一次 new 都會申請一個堆內存空間,雖然內容相同,但是地址值不同 -
直接賦值方式創建
以“”方式給出的字符串,只要字符序列相同(順序和大小寫),無論在程序代碼中出現幾次,JVM 都只會建立一個 String 對象,并在字符串池中維護//案例:分別用構造方法創建的字符串和用“”方式給出的字符串,使用==進行比較
//用字符串常量賦值
String s1 = “hello”;
String s2 = “hello”;
//以上兩個字符串對象在字符串常量池,s1和s2指向的地址相同
System.out.println(s1 == s2);//結果:trueString s3 = new String(“abc”);
String s4 = new String(“abc”);
//以上兩個字符串對象不在字符串常量池,就直接在堆內存中
//s3和s4指向的地址不相同,有幾個new,就有幾個地址
System.out.println(s3 == s4);//結果:false
2.4 String特點:常見面試題
-
字符串變量直接賦值字符串常量,指向的地址是字符串常量池中的對象
-
字符串變量賦值的是一個字符串類型變量和其他字符串的拼接
- 底層在堆內存中會有StringBuilder對象做拼接,得到StringBuilder對象,然后調用它的toString方法得到一個String對象,這個String對象是在堆內存中,只是拿到了常量池中的字符串值
-
字符串白能量賦值的是兩個字符串常量拼接,會有常量優化機制,指向的還是常量池中的那個拼接后的字符串對象
//定義兩個變量,接收相同字符串常量
String s1 = “abc”;
String s2 = “abc”;
System.out.println(s1 == s2);//true。都是指向常量池的"abc"字符串String s3 = “ab”;
String s4 = s3 + “c”;
//底層在堆內存中會有StringBuilder對象做拼接,得到StringBuilder對象,然后調用它的toString方法
//得到String對象,這個String對象是在堆內存中,只是拿到了常量池中的字符串值
//所以s3指向的是常量池中的字符串對象,s4指向的是堆內存中的字符串對象,地址不一樣
System.out.println(s4 == s1);//flase。String s4=“ab”+“c”;
//如果字符串拼接都是用字符串常量,會有常量優化機制,底層不會用StringBuilder做拼接
//所以s1和s4都還是指向常量池中的字符串
System.out.println(s4 == s1);//true。//給一個變量加上final關鍵字,就相當于這個變量變成了常量
final String s5 = “ab”;
String s6 = s5 + “c”;
System.out.println(s6 == s1);//true
2.5 字符串的比較
問題: 1.在實際開發中,字符串的比較一般使用什么方式? 2.如果要忽略大小寫去比較兩個字符串內容是否相同,用哪個方法?- == 比較基本數據類型:比較的是具體的值
- == 比較引用數據類型:比較的是對象地址值
String類 : public boolean equals(String s) 比較兩個字符串內容是否相同、區分大小寫
代碼 :
//equals練習:使用equals方法分別比較字符串常量、變量以及使用new創建的字符串對象//equalsIgnoreCase練習:使用方法比較兩個大小寫不同的字符串2.6 用戶登錄案例
案例需求 :
- 已知用戶名和密碼,請用程序實現模擬用戶登錄。總共給三次機會,登錄之后,給出相應的提示
實現步驟 :
代碼實現 :
//1.用戶登錄功能,實際上是用你錄入的信息和系統中已存在的正確信息比較 //2.定義一對正確的用戶名和密碼 String usr = "admin"; String pwd = "123"; Scanner sc = new Scanner(System.in); //3.開始鍵盤錄入用戶名和密碼,有3次機會,重復錄入,并且知道次數,使用for for (int i = 0; i < 3; i++) {System.out.println("請輸入用戶名:");String username = sc.next();System.out.println("請輸入密碼:");String password = sc.next();//4.有了鍵盤錄入的信息,開始比較if (username.equals(usr) && password.equals(pwd)) {System.out.println("登錄成功");//登錄成功,結束循環break;} else {if (i==2) {System.out.println("您今日登錄次數已達上限,請明日再來");break;}System.out.println("登錄失敗,您還有" + (2 - i) + "次機會");} }2.7 遍歷字符串案例
案例需求 :
鍵盤錄入一個字符串,使用程序實現在控制臺遍歷該字符串實現步驟 :
核心方法:
- length():這是返回字符串的長度,和數組的length不同,數組的那個是屬性,這個是方法,要帶小括號
- charAt(int index):返回字符串對應索引的字符,字符串索引也是從0開始
- toCharArray():返回的是字符串對應的字符數組
代碼實現 :
//1.鍵盤錄入一個字符串 System.out.println("請輸入:"); Scanner sc = new Scanner(System.in); String str = sc.next(); //2.先獲取字符串長度,然后遍歷,使用length()方法獲取字符串長度 for (int i = 0; i < str.length(); i++) {//3.要根據i的值獲取字符串中的字符,推薦使用charAt方法System.out.println(str.charAt(i)); } System.out.println("==========================="); //4.直接現將字符串轉換成字符數組,推薦使用toCharArray char[] chars = str.toCharArray(); //5.遍歷字符數組 for (int i = 0; i < chars.length; i++) {System.out.println(chars[i]); }2.8 統計字符次數案例
案例需求 :
鍵盤錄入一個字符串,使用程序實現在控制臺遍歷該字符串實現步驟 :
代碼實現 :
//1.創建鍵盤錄入對象 Scanner sc = new Scanner(System.in); System.out.println("請輸入:"); String str = sc.next(); //2.要統計字符串中大小寫字符,數字字符的個數,你得先把字符串轉換成數組 char[] chars = str.toCharArray(); //定義計數器,記錄大小寫字符和數字字符的個數 int bigCount = 0; int smallCount = 0; int numCount = 0; //3.遍歷字符數組 for (int i = 0; i < chars.length; i++) {char c = chars[i];//4.拿到字符之后,該判斷這個字符是屬于哪一個區間if (c >= '0' & c <= '9') {//5.統計小寫字符出現的次數numCount++;} else if (c >= 'a' && c <= 'z') {smallCount++;//因為除了大小寫字母和數字字符,還有其他字符,所以不能直接用else} else if (c >= 'A' & c <= 'Z') {bigCount++;} } //6.循環結束,打印各個字符的個數 System.out.println(numCount); System.out.println(smallCount); System.out.println(bigCount);2.9 手機號屏蔽-字符串截取
案例需求 :
以字符串的形式從鍵盤接受一個手機號,將中間四位號碼屏蔽最終效果為:1561234實現步驟 :
代碼實現 :
//1.使用鍵盤錄入 Scanner sc = new Scanner(System.in); System.out.println("請輸入手機號:"); String telPhone = sc.next(); //2.假設錄入的字符串是13912341234,接下來開始針對這個字符串進行截取操作 //如果要替換中間四個數字,變為*,可以截取前三個和后四個,中間拼接**** //使用substring方法,截取前三個,調用方法截取后,調用方法的字符串不變,只是返回一個新的字符串 String start = telPhone.substring(0, 3); //3.拿結尾的四個 String end = telPhone.substring(7); //4.最后把頭+****+尾進行拼接 System.out.println(start + "****" + end);2.10 敏感詞替換-字符串替換
案例需求 :
鍵盤錄入一個 字符串,如果字符串中包含(TMD),則使用***替換實現步驟 :
鍵盤錄入一個字符串,用 Scanner 實現
替換敏感詞
String replace(CharSequence target, CharSequence replacement)
將當前字符串中的target內容,使用replacement進行替換,返回新的字符串
CharSquence:以后如果你看到方法的形式參數是它,說明就丟字符串進去就可以了。它是字符串的干爹。
輸出結果
代碼實現 :
//1.創建鍵盤錄入對象 Scanner sc = new Scanner(System.in); System.out.println("請輸入一句話:"); String str = sc.next(); //2.把字符串中非法字符串使用***替換,核心方法是replace str = str.replace("TMD", "***"); //3.打印替換后的字符串 System.out.println(str);課后練習:
/*** 需求:* 1.鍵盤錄入一個初始字符串,例如:I love heima,heiheimama love me* 2.再使用鍵盤錄入一個目標字符串,可以將初始字符串中的目標字符串刪除* 3.在控制臺打印處理后的字符串內容,例如輸入目標字符串:heima,控制臺輸出:* I love , love me*/2.11 切割字符串
案例需求 :
以字符串的形式從鍵盤錄入學生信息,例如:“張三 , 23”從該字符串中切割出有效數據,封裝為Student學生對象實現步驟 :
- 注意:字符串regex如果是==.,請使用.==
代碼實現 :
//1.鍵盤錄入 Scanner sc = new Scanner(System.in); System.out.println("請輸入:"); String str = sc.nextLine(); //2.針對字符串做切割操作,以逗號座位分隔進行切割,按照題意,切出來有2個部分 String[] strs = str.split(","); //結果返回的是一個字符串數組,說明切出來的是多個字符串,根據題意,切出來2個 System.out.println(strs[0]); System.out.println(strs[1]); //3.一般情況下,在工作中,如果我們獲取到了零散的數據,我們通常都會使用一個對象將其封裝起來 //專門用來封裝數據的類,一般放在domain包下 //創建學生對象,存儲數據 Student stu = new Student(strs[0], strs[1]); System.out.println(stu.getName() + "的年齡是" + stu.getAge());2.12 String方法小結
String類的常用方法 :
方法名 返回值類型 說明 equals(Object anObject) boolean 比較字符串的內容,嚴格區分大小寫equalsIgnoreCase(String anotherString) boolean 比較字符串的內容,忽略大小寫
length() int 返回此字符串的長度
charAt(int index) char 返回指定索引處的 char 值
toCharArray() char[] 將字符串拆分為字符數組后返回
substring(int beginIndex, int endIndex) String 根據開始和結束索引進行截取,得到新的字符串(包含頭,不包含尾)
substring(int beginIndex) String 從傳入的索引處截取,截取到末尾,得到新的字符串
replace(CharSequence target, CharSequence replacement) String 使用新值,將字符串中的舊值替換,得到新的字符串
split(String regex) String[] 根據傳入的規則切割字符串,得到字符串數組
3.1 StringBuilder類概述
問題: 1.使用StringBuilder有什么好處? 2.如何獲取1970-01-01 00:00:00到系統當前時間所經歷的毫秒值? 3.將一段代碼抽取到方法中的快捷鍵是什么?-
概述 : StringBuilder 是一個可變的字符串類,我們可以把它看成是一個容器,這里的可變指的是 StringBuilder 對象中的內容是可變的
-
作用:提高字符串的操作效率
-
System.currentTimeMillis():獲取1970年1月1日0時0分0秒到當前時間所經歷過的毫秒值
-
代碼練習:
//練習:分別用String和StringBuilder操作字符串,對比兩者操作的時間
public static void method1() {//2.在操作字符串之前,獲取系統當前時間的毫秒值long start = System.currentTimeMillis();String s = "";for (int i = 0; i < 50000; i++) {s += i;}//操作之后,再去獲取系統的毫秒值long end = System.currentTimeMillis();System.out.println(end - start);}public static void method2() {//2.在操作字符串之前,獲取系統當前時間的毫秒值long start = System.currentTimeMillis();StringBuilder builder = new StringBuilder();for (int i = 0; i < 50000; i++) {builder = builder.append(i);}//操作之后,再去獲取系統的毫秒值long end = System.currentTimeMillis();System.out.println(end - start);}
public class Test01 {
public static void main(String[] args) {
//1.對比String和StringBuilder操作字符串消耗的時間
method1();
method2();
}}
3.2 StringBuilder類的構造方法
問題: 1.打印用空參構造方法創建的StringBuilder對象,會有什么結果? 2.打印用帶參構造方法創建的StringBuilder對象,會有什么結果?常用的構造方法
方法名 說明
public StringBuilder() 創建一個空白可變字符串對象,不含有任何內容
public StringBuilder(String str) 根據字符串的內容,來創建可變字符串對象
示例代碼
public class StringBuilderDemo01 {public static void main(String[] args) {//public StringBuilder():創建一個空白可變字符串對象,不含有任何內容StringBuilder sb = new StringBuilder();System.out.println("sb:" + sb);System.out.println("sb.length():" + sb.length());//public StringBuilder(String str):根據字符串的內容,來創建可變字符串對象StringBuilder sb2 = new StringBuilder("hello");System.out.println("sb2:" + sb2);System.out.println("sb2.length():" + sb2.length());} }3.3 StringBuilder常用的成員方法
問題: 1.StringBuilder有哪幾種常見的功能方法? 2.StringBuilder對象是否可以添加不同的數據類型到容器中? 3.StringBuilder的append方法返回對象自己,有什么作用?-
添加和反轉方法
方法名 說明
public StringBuilder append(任意類型) 添加數據,并返回對象本身
public StringBuilder reverse() 返回相反的字符序列
public int length() 返回長度(字符出現的個數)
public String toString() 把StringBuilder轉換為String -
示例代碼
//需求:創建一個StringBuilder對象,分別調用幾個成員方法,觀察效果
3.4 StringBuilder提高效率的原理
-
原理圖:
-
字符串的加法拼接:
-
StringBuilder拼接:
-
-
StringBuilder類和String類的區別:
- String類:內容是不可變的
- StringBuilder類:內容是可變的
3.5 對稱字符串案例:String和StringBuilder之間的相互轉換
-
需求:鍵盤接收一個字符串,程序判斷該字符串是否是對稱字符串,并在控制臺打印是或不是
-
思路:
-
代碼實現:
//1.鍵盤錄入
Scanner sc = new Scanner(System.in);
System.out.println(“請輸入一個對稱字符串:”);
String str = sc.nextLine();
//2.要判斷一個字符串是不是對稱字符串,把這個字符串反轉一下,然后對比內容
//如果反轉后的內容和反轉前的內容一樣,就屬于對稱字符串,比如123321
//要把字符串進行反轉,這個時候我們就要想,字符串對象自己能不能做?
//查了api,發現不能做。這個時候要想,和字符串相關的工具還有哪些?想到了StringBuilder
//就去查api,發現了一個reverse方法可以做到
//3.通過構造方法把String變成StringBuilder
StringBuilder sb = new StringBuilder(str);
//4.調用reverse反轉
sb.reverse();
//5.將反轉后的字符串內容和原字符串內容比較
//注意,這里要保證都是字符串類型比較,所以sb要轉成String
if (str.equals(sb.toString())) {
System.out.println(“是對稱字符串”);
} else {
System.out.println(“不是對稱字符串”);
} -
StringBuilder轉換為String
public String toString():通過 toString() 就可以實現把 StringBuilder 轉換為 String -
String轉換為StringBuilder
public StringBuilder(String s):通過構造方法就可以實現把 String 轉換為 StringBuilder
3.6 StringBuilder拼接字符串案例
-
需求 :
- 定義一個方法,把 int 數組中的數據按照指定的格式拼接成一個字符串返回,調用該方法,
- 并在控制臺輸出結果。例如,數組為int[] arr = {1,2,3}; ,執行方法后的輸出結果為:[1, 2, 3]
-
實現步驟 :
- 定義一個 int 類型的數組,用靜態初始化完成數組元素的初始化
- 定義一個方法,用于把 int 數組中的數據按照指定格式拼接成一個字符串返回。
返回值類型 String,參數列表 int[] arr - 在方法中用 StringBuilder 按照要求進行拼接,并把結果轉成 String 返回
- 調用方法,用一個變量接收結果
- 輸出結果
-
代碼實現 :
public class Test03 {
public static String getStr(int[] arr) {//2.要操作字符串,就要創建StringBuilder對象,去做拼接//拼接的數據從數組中來,所以還要遍歷數組StringBuilder sb = new StringBuilder("[");for (int i = 0; i < arr.length; i++) {//3.直接拼接不太好,因為字符串里面有特殊的格式,以中括號開始,而且是拼接數據之前//開始拼接數字,但是有區別,最后一個跟中括號的結束if (i == arr.length - 1) {//是最后一個元素,拼接的時候不能拼逗號sb.append(arr[i]).append("]");} else {sb.append(arr[i]).append(",");}}//4.方法返回的是字符串,要轉一下return sb.toString();}
public static void main(String[] args) {
//1.靜態初始化
int[] arr = {1, 2, 3};
String str = getStr(arr);
System.out.println(str);
}}
- ArrayList
1.1 集合和數組的區別對比
問題: 1.相對于數組,集合容器有什么特點? 2.在什么情況下,更推薦使用集合容器存放數據?- 集合類的特點:提供一種存儲空間可變的存儲模型,存儲的數據容量可以發生改變
- 集合和數組的區別
- 共同點:都是存儲數據的容器
- 不同點:數組的容量是固定的,集合的容量是可變的
1.2 ArrayList的構造方法和添加方法
問題: 1.ArrayList集合的大小可變,底層是通過什么實現的?數組 2.通過空參構造創建的ArrayList集合對象,初始容量是多少?10 3.ArrayList集合可以存放多種數據類型的數據嗎?可以 4.如何指定ArrayLList集合只存儲特定的數據類型?加一個泛型public ArrayList() 創建一個空的集合對象
public boolean add(E e) 將指定的元素追加到此集合的末尾
public void add(int index,E element) 在此集合中的指定位置插入指定的元素
ArrayList :
可調整大小的數組實現 <E> : 是一種特殊的數據類型,泛型。泛型可以代表一種不確定的類型,類型的確定在聲明這個類的變量的時候注意,不是所有的類都可以加泛型哦。目前你只在ArrayList后面加泛型怎么用呢 ?
在出現E的地方我們使用引用數據類型替換即可 舉例:ArrayList<String>, ArrayList<Student>-
練習:
/**
- 創建一個可以存儲字符串類型數據的ArrayList集合對象
- 向集合中添加三個元素:hello world java
- 向集合中2索引處添加一個JavaSE
*/
ArrayList list = new ArrayList<>();
list.add(“李小璐”);
list.add(“白百何”);
list.add(“馬蓉”);
//ArrayList集合對象可以直接打印
System.out.println(list);
//向集合中2索引處添加一個JavaSE
list.add(2,“JavaSE”);
System.out.println(list);
1.3 ArrayList類常用方法
問題: 1.調用ArrayList集合刪除的功能,可以返回哪些數據類型? 2.調用ArrayList集合的修改指定位置元素的方法,返回值是什么?成員方法 :
public boolean remove(Object o) 刪除指定的元素,返回刪除是否成功
public E remove(int index) 刪除指定索引處的元素,返回被刪除的元素
public E set(int index,E element) 修改指定索引處的元素,返回被修改的元素
public E get(int index) 返回指定索引處的元素
public int size() 返回集合中的元素的個數
示例代碼 :
//練習:創建一個集合,用來存儲和管理學生對象數據//增加數據//刪除數據 System.out.println("======刪除數據======");//指定位置刪除System.out.println("======修改數據======");System.out.println("======獲取數據======");System.out.println("======獲取集合長度======");1.4 案例:ArrayList存儲字符串并遍歷
案例需求 :
創建一個存儲字符串的集合,存儲3個字符串元素,使用程序實現在控制臺遍歷該集合實現步驟 :
代碼實現 :
//1.創建集合 ArrayList<String> hanzimen = new ArrayList<>(); //2.使用add方法添加3個字符串 hanzimen.add("王寶強"); hanzimen.add("賈乃亮"); hanzimen.add("吳簽"); //3.使用循環遍歷集合。集合提供了size()方法,可以獲取集合的長度 for (int i = 0; i < hanzimen.size(); i++) {//4.使用集合get方法可以獲取集合中的元素,根據索引獲取String hanzi = hanzimen.get(i);System.out.println(hanzi); }1.5 案例:ArrayList存儲學生對象并遍歷
案例需求 :
創建一個存儲學生對象的集合,存儲3個學生對象,使用程序實現在控制臺遍歷該集合實現步驟 :
代碼實現 :
//1.創建集合,用于存儲學生對象,這里存儲的數據是學生對象,類型指定為Student //注意,如果沒有Student類,要先去創建Student類 ArrayList<Student> stus = new ArrayList<>(); //在一個類中使用了另外一個包下的類,就需要先導包才能使用,idea可以自動導包 //2.創建學生對象,封裝學生數據 Student stu1 = new Student("張三", 23, 98.8, "男"); Student stu2 = new Student("李四", 24, 96.8, "女"); Student stu3 = new Student("王五", 20, 100, "男"); //3.使用集合容器,用add方法添加數據 stus.add(stu1); stus.add(stu2); stus.add(stu3); //4.集合中有數據了,開始遍歷集合 for (int i = 0; i < stus.size(); i++) {//5.從集合中取出索引對應的學生對象,使用get方法Student stu = stus.get(i);//6.拿出來的是學生對象,不能直接打印,得調用學生對象的獲取屬性的方法System.out.println(stu.getName() + "..." + stu.getAge()); }1.6 案例:鍵盤錄入學生信息到集合
案例需求 :
創建一個存儲學生對象的集合,存儲3個學生對象,使用程序實現在控制臺遍歷該集合學生的姓名和年齡來自于鍵盤錄入實現步驟 :
代碼實現 :
public class Test05 {public static void main(String[] args) {//1.創建集合,用來存儲Student對象ArrayList<Student> stus = new ArrayList<>();//2.鍵盤錄入學生信息,封裝成學生對象,使用循環錄入也可以,但是比較麻煩//為了提高代碼的復用性,可以把錄入學生數據的這些代碼使用方法封裝起來//6.利用寫好的方法獲取3次學生對象Student stu1 = getStudent();Student stu2 = getStudent();Student stu3 = getStudent();//7.將對象存儲到集合中stus.add(stu1);stus.add(stu2);stus.add(stu3);//8.遍歷集合,打印學生數據for (int i = 0; i < stus.size(); i++) {//9.通過集合get方法獲取集合中存儲的學生對象Student stu = stus.get(i);//10.通過學生對象的get方法獲取屬性System.out.println(stu.getName() + "..." + stu.getAge());}}//3.定義一個獲取學生對象的方法,這個方法返回值就是Student類型public static Student getStudent() {//4.創建鍵盤錄入對象Scanner sc = new Scanner(System.in);System.out.println("請輸入學生姓名:");String name = sc.next();System.out.println("請輸入學生年齡:");int age = sc.nextInt();System.out.println("請輸入學生分數:");double score = sc.nextDouble();System.out.println("請輸入學生性別:");String sex = sc.next();//5.有了零散的學生數據,封裝成學生對象管理Student stu = new Student(name, age, score, sex);//返回學生對象return stu;} }1.7 案例:集合刪除元素
案例需求 :
創建一個存儲String的集合,內部存儲(test,張三,李四,test,test)字符串,刪除所有的test字符串,刪除后,將集合剩余元素打印在控制臺實現步驟 :
代碼實現:
//1.創建集合 ArrayList<String> strs = new ArrayList<>(); //2.存儲幾個字符串,用于測試 strs.add("test"); strs.add("張三"); strs.add("李四"); strs.add("test"); strs.add("test"); //3.刪除集合中的test字符串,遍歷集合,將里面的元素一個個取出來 for (int i = 0; i < strs.size(); i++) {//4.使用get方法獲取集合中的字符串String s = strs.get(i);//5.判斷拿出來字符串s是否內容是test,如果是就刪除//這里要注意,為了防止空指針異常,使用字符串常量去調用equals方法/*if (s.equals("test")) {//這里不建議這么寫,容易出現空指針}*/if ("test".equals(s)) {//如果是test,就刪除,調用集合的remove方法strs.remove(i);//6.集合刪除一個元素后,后面的所有元素會往前挪動一位,如果此時索引不做操作//就會導致所以繼續往后,挪過來的第一個元素就會漏掉,應該讓索引減1i--;} } //7.打印集合,看看是否刪除 System.out.println(strs);1.8 案例:集合數據篩選
案例需求 :
定義一個方法,方法接收一個集合對象(泛型為Student),方法內部將年齡低于18的學生對象找出并存入集合對象,方法返回新集合實現步驟 :
代碼實現:
public class Test07 {public static void main(String[] args) {//7.創建學生對象和集合,用于測試ArrayList<Student> stus = new ArrayList<>();stus.add(new Student("張三",23,98.0,"男"));stus.add(new Student("李四",12,98.0,"男"));stus.add(new Student("王五",15,98.0,"男"));//8.調方法測試ArrayList<Student> newStus = getStus(stus);//打印新集合for (int i = 0; i < newStus.size(); i++) {Student stu = newStus.get(i);System.out.println(stu.getName() + "..." + stu.getAge());}}//1.定義一個方法,用于獲取我們要的集合public static ArrayList<Student> getStus(ArrayList<Student> stus) {//2.方法內部遍歷傳過來的集合,把低于18歲的學生存入新集合//創建一個新的集合ArrayList<Student> newStus = new ArrayList<>();//3.遍歷傳過來的集合for (int i = 0; i < stus.size(); i++) {//4.從集合中獲取學生對象,并判斷年齡Student stu = stus.get(i);if (stu.getAge() < 18) {//5.把這個學生對象存入新集合newStus.add(stu);}}//6.返回新的集合對象return newStus;} }2.學生管理系統
2.1 學生管理系統實現步驟
- 案例需求
針對目前我們的所學內容,完成一個綜合案例:學生管理系統!該系統主要功能如下:
添加學生:通過鍵盤錄入學生信息,添加到集合中
刪除學生:通過鍵盤錄入要刪除學生的學號,將該學生對象從集合中刪除
修改學生:通過鍵盤錄入要修改學生的學號,將該學生對象其他信息進行修改
查看學生:將集合中的學生對象信息進行展示
退出系統:結束程序 - 實現步驟
- 定義學生類,包含以下成員變量
學生類: Student成員變量:
學號:sid
姓名:name
年齡:age
生日:birthday
構造方法:
無參構造
帶四個參數的構造成員方法:
每個成員變量對應給出get/set方法 - 學生管理系統主界面的搭建步驟
2.1 用輸出語句完成主界面的編寫
2.2 用Scanner實現鍵盤錄入數據
2.3 用switch語句完成操作的選擇
2.4 用循環完成再次回到主界面 - 學生管理系統的添加學生功能實現步驟
3.1 用鍵盤錄入選擇添加學生
3.2 定義一個方法,用于添加學生
顯示提示信息,提示要輸入何種信息
鍵盤錄入學生對象所需要的數據
創建學生對象,把鍵盤錄入的數據賦值給學生對象的成員變量
將學生對象添加到集合中(保存)
給出添加成功提示
3.3 調用方法 - 學生管理系統的查看學生功能實現步驟
4.1 用鍵盤錄入選擇查看所有學生信息
4.2 定義一個方法,用于查看學生信息
顯示表頭信息
將集合中數據取出按照對應格式顯示學生信息,年齡顯示補充“歲”
4.3 調用方法 - 學生管理系統的刪除學生功能實現步驟
5.1 用鍵盤錄入選擇刪除學生信息
5.2 定義一個方法,用于刪除學生信息
顯示提示信息
鍵盤錄入要刪除的學生學號
調用getIndex方法,查找該學號在集合的索引
如果索引為-1,提示信息不存在
如果索引不是-1,調用remove方法刪除并提示刪除成功
5.3 調用方法 - 學生管理系統的修改學生功能實現步驟
6.1 用鍵盤錄入選擇修改學生信息
6.2 定義一個方法,用于修改學生信息
顯示提示信息
鍵盤錄入要修改的學生學號
調用getIndex方法,查找該學號在集合的索引
如果索引為-1,提示信息不存在
如果索引不是-1,鍵盤錄入要修改的學生信息
集合修改對應的學生信息
給出修改成功提示
6.3 調用方法 - 退出系統
使用System.exit(0);退出JVM
2.2 學生類的定義
package com.itheima.domain;/*** 該類用于存儲和管理本系統的學生數據*/ public class Student {//屬性:學號、姓名、年齡、生日,分別用成員變量代表//為了提高安全性,使用private修飾屬性private String sid;private String name;private int age;private String birthday;//標準類的書寫,寫完了屬性,就要寫構造方法,空參和滿參public Student() {}public Student(String sid, String name, int age, String birthday) {this.sid = sid;this.name = name;this.age = age;this.birthday = birthday;}//屬性被private修飾了,要給他們添加設置值和獲取值的方法,以供外界使用public String getSid() {return sid;}public void setSid(String sid) {this.sid = sid;}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;}public String getBirthday() {return birthday;}public void setBirthday(String birthday) {this.birthday = birthday;} }2.3 菜單搭建
/*** 本類就是用于完成學生管理系統的核心功能,所以要加上主方法*/ public class StudentManager {public static void main(String[] args) {//1.程序從這里開始,軟件一旦運行,首先展示的頁面就是它第一個需要完成的功能,菜單顯示//菜單顯示:提示用戶根據展示的信息錄入選擇,在根據選擇執行不同的功能,這個過程可能有很多次//技術體系:while死循環+switch選擇結構//2.展示菜單頁面,用輸出語句//創建鍵盤錄入對象Scanner sc = new Scanner(System.in);//5.到這一步,該選擇只能完成1次,不符合軟件的需求,要能夠重復選擇執行,不知道重復的次數//使用while死循環,不用把創建鍵盤錄入對象放進來,反復創建對象比較消耗內存lo:while (true) {System.out.println("--------歡迎來到學生管理系統--------");System.out.println("1 添加學生");System.out.println("2 刪除學生");System.out.println("3 修改學生");System.out.println("4 查看學生");System.out.println("5 退出");System.out.println("請輸入您的選擇:");//3.錄入選擇,錄入字符串,因為這樣的話,你錄入錯了,也不會報錯String choice = sc.next();//4.根據錄入的內容,執行不同的分支,這是switch結構switch (choice) {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可以被switch和循環消費,這里要指定結束循環,使用標號的方式break lo;default:System.out.println("您的輸入有誤,請檢查后重試");break;}}} }2.4 添加學生:基本實現
public static void main(String[] args) {//2.1 我們的學生數據是放到集合中存儲的,先創建ArrayList集合ArrayList<Student> stus = new ArrayList<>();......case "1":// System.out.println("添加學生");//2.2 定義一個方法來處理添加學生的邏輯addStudent(stus);break;...... }public static void addStudent(ArrayList<Student> stus) {//2.3 提示用戶鍵盤錄入學生信息Scanner sc = new Scanner(System.in);System.out.println("請輸入學號:");String sid = sc.next();System.out.println("請輸入姓名:");String name = sc.next();System.out.println("請輸入年齡:");int age = sc.nextInt();System.out.println("請輸入生日:");String birthday = sc.next();//2.4 擁有了零散的學生信息,必須封裝到學生對象中,方便管理Student stu = new Student(sid, name, age, birthday);//2.5 有了學生數據,將這個學生對象丟進通過方法的參數傳遞過來的集合中stus.add(stu);//方法需不需要返回集合對象?不需要,因為集合對象是引用數據類型,你對她的操作,主方法也能看到更改 }2.5 查看學生代碼實現
public static void main(String[] args) {......case "4"://System.out.println("查看學生");queryStudents(stus);break;...... } /** * 查看學生 * * @param stus */ public static void queryStudents(ArrayList<Student> stus) {//3.1 如果執行查詢學生,不能馬上就開始遍歷,因為有可能傳過來的集合是個空的//先判斷集合是否是空的,如果是空的,就可以提示用戶,然后結束方法if (stus.size() == 0) {System.out.println("無數據,請添加后再查詢");//直接使用return結束方法,方法彈棧return;}//3.2 在遍歷之前,先把格式上的表頭打印出來,讓你知道打印的每一列分別是什么數據System.out.println("學號\t\t姓名\t\t年齡\t\t生日");//3.3 如果沒有進入if語句,說明集合不是空的,可以打印。另外也不會結束方法for (int i = 0; i < stus.size(); i++) {//3.4 從集合中拿出學生對象Student student = stus.get(i);//3.5 開始打印數據System.out.println(student.getSid() + "\t" + student.getName() + "\t" + student.getAge() + "\t\t" + student.getBirthday());} }2.6 判斷學號是否存在的方法定義
/** * 定義一個方法用來返回學號在集合中對應的索引位置 * 需要提供集合、被查詢的學號 * 返回的是索引 */ public static int getIndex(ArrayList<Student> list, String sid) {//4.1 定義一個變量代表要返回的索引值,現在沒有開始判斷,假設這個索引不存在,給個不存在的初始化值int index = -1;//4.2 遍歷集合,拿出里面的學生對象for (int i = 0; i < list.size(); i++) {Student stu = list.get(i);//4.3 從學生對象中拿出學號String id = stu.getSid();//4.4 開始判斷從學生對象中拿出來的id是否和你傳遞過來的id內容相同if (id.equals(sid)) {//4.5 如果相同,說明學生集合中有你傳過來的學號對應的學生,用集合中的索引替換indexindex = i;}}//4.6 循環結束,如果if語句一直沒有進去過,index就是-1,那就是沒找到return index; }2.7 刪除學生代碼實現
public static void main(String[] args) {......case "2"://System.out.println("刪除學生");deleteStudent(stus);break;...... } /** * 刪除學生 * @param stus */ public static void deleteStudent(ArrayList<Student> stus) {//5.1 提示用戶錄入要刪除的學號Scanner sc = new Scanner(System.in);System.out.println("請輸入要刪除的學號:");String delSid = sc.next();//5.2 你輸入的學號不一定就存在,如果不存在重新輸入,存在才能刪除,先判斷輸入的學號是否存在//獲取學號對應的索引的邏輯已經寫好,調用getIndex方法即可int index = getIndex(stus, delSid);//5.3 判斷index的值,如果index是-1,就說明沒找到,否則就找到了if (index == -1) {//5.4 沒找到,提示用戶System.out.println("查無此人,請重新輸入");} else {//5.5 找到了,就可以根據索引,直接從集合中刪除學生對象stus.remove(index);System.out.println("刪除成功!");} }2.8 修改學生代碼實現
public static void main(String[] args) {......case "3"://System.out.println("修改學生");updateStudent(stus);break;...... } /** * 修改學生 * @param stus */ public static void updateStudent(ArrayList<Student> stus) {//6.1 鍵盤錄入需要修改的學生學號,判斷是否存在,不存在重新輸入。存在,就開始修改//邏輯和刪除一樣,直接復制代碼//6.2 提示用戶錄入要修改的學號Scanner sc = new Scanner(System.in);System.out.println("請輸入要修改的學號:");String updateSid = sc.next();int index = getIndex(stus, updateSid);//6.3 判斷index的值,如果index是-1,就說明沒找到,否則就找到了if (index == -1) {//6.4 沒找到,提示用戶System.out.println("查無此人,請重新輸入");} else {//6.5 找到了,就要開始修改,你要錄入修改的內容System.out.println("請輸入新的學生姓名:");String name = sc.next();System.out.println("請輸入新的學生年齡:");int age = sc.nextInt();System.out.println("請輸入新的學生生日:");String birthday = sc.next();//6.6 有了學生數據,重新封裝到學生對象中Student stu = new Student(updateSid, name, age, birthday);//6.7 把這個學生對象,改到集合中,使用集合的set方法stus.set(index, stu);System.out.println("修改成功!");} }2.9 解決添加學生學號重復的問題
public static void addStudent(ArrayList<Student> stus) {//2.3 提示用戶鍵盤錄入學生信息Scanner sc = new Scanner(System.in);//7.1 輸入學號,如果存在就得重新輸入學號,因為不能添加已存在的學生,無法判斷輸入多少次成功String sid;while (true) {System.out.println("請輸入學號:");sid = sc.next();//7.2 調用getIndex方法,判斷你輸入的學號是否存在int index = getIndex(stus, sid);if (index == -1) {//不存在,可以繼續輸入,結束這個死循環break;}}System.out.println("請輸入姓名:");String name = sc.next();System.out.println("請輸入年齡:");int age = sc.nextInt();System.out.println("請輸入生日:");String birthday = sc.next();//2.4 擁有了零散的學生信息,必須封裝到學生對象中,方便管理Student stu = new Student(sid, name, age, birthday);//2.5 有了學生數據,將這個學生對象丟進通過方法的參數傳遞過來的集合中stus.add(stu);System.out.println("添加成功!");//方法需不需要返回集合對象?不需要,因為集合對象引用數據類型,你對她的操作,主方法也能看到更改 }總結
以上是生活随笔為你收集整理的JavaSE基础学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 28 | 读写分离有哪些坑?
- 下一篇: java 错误代码2503_错误代码:1