Java
Hello world!
psvm解釋語句,main方法,main(引數),以上無引數,sout輸出
注:
- 注意大小寫
- 檔名和類名需要保持一致
- 命名規則,首字母小寫 駝峰式命名
識別符號
- 能字母,$,_,開頭
- 不能以關鍵字作為變數名或方法名
- 注意大小寫(大寫的跟小寫的不是同一個變數)
- 不能以特殊符號,數字來命名
- 下劃線之後可以存在數字
佔位符
%
表示佔位符,因此,連續兩個%%
表示一個%
字元本身
佔位符 | 說明 |
---|---|
%d | 格式化輸出整數 |
%x | 格式化輸出十六進位制整數 |
%f | 格式化輸出浮點數 |
%e | 格式化輸出科學計數法表示的浮點數 |
%s | 格式化字串 |
資料型別
基本型別
注
擴充
整數
浮點數
float
接近但不等於,大約 (少用浮點數進行比較 有誤差)
字元
強制轉換成數字(字元的本質是數字)
編碼
跳脫字元
\t 製表符
\n 換行
ps:
if (flag==true){}
和
if (flag){}
是一樣的,只是寫法不同
型別轉換
強制轉換 :(型別)變數名 高到底
自動轉換: ... 低到高
- 不能對布林值進行轉換
- 存在記憶體溢位或精度問題
變數
變數作用域
賦值
變數的一個重要特徵是可以重新賦值
第一次賦值時定義過了變數型別,第二次賦值時則不需要重新賦值
將一個變數的值重新賦值另一個變數
類變數
從屬於類,隨著類一起存在一起消失
例項變數
從屬於物件,如果未設定初始化,輸出型別的預設值
區域性變數
必須聲名和初始化值
定義在某個方法內,當程式執行完該方法的時候 無法呼叫該變數
常量
final 常量名 常量值
變數命名
運算子
自增 自減
邏輯運算子
b是假 上來就結束執行 稱為短路運算
如果後面的執行 結果為6
位運算
當出現字串時,後面的數字將會被轉化成字串型別顯示出來 所以輸出是1020
三元運算子
b ? x : y
包機制
包 其實就是資料夾
利用公司域名倒置作包名 eg:com.baidu.www
匯入包
Doc
引數資訊
@author 作者名
@version 版本號
@since 指明需要最早使用的的jdk版本
@return 返回值情況
@throws 異常丟擲情況
生成Doc文件
命令列:javadoc 引數 java檔案
javadoc -encoding UTF-8 -charset UTF-8 Doc.java
IDEA生成doc文件
生成doc
生成了
控制流程
輸入
``System.in代表標準輸入流
Scanner物件
透過Scanner類來獲取使用者的輸入,透過Scanner類的next()
與nextLine()
方法獲取輸入的字串,用hasNext()
與hasNextLine()
判斷是否還有輸入的資料
next
nextLine
簡潔版
判斷
求和 平均數
輸出
``System.out代表標準輸出流
順序結構
選擇結構
多選擇結構
if,else,else if
switch case語句
case穿透
當沒有break語句時,會將下面的語句全部輸出,而不是可選模式
反編譯
資料夾 複製檔案
反編譯檔案
中文時透過雜湊值來比較
判斷引用型別相等
-
判斷引用型別的變數是否相等用
==
-
判斷引用型別的變數內容是否相等用
equals()
方法
迴圈結構
while迴圈
如果不滿足條件,則不能進入迴圈
先判斷後執行
do...while
即使不滿足while迴圈條件,至少也會執行一次迴圈
先執行後判斷
while和do..while迴圈的區別
for迴圈
for(初始化;布林表示式;更新){
//程式碼
}
計算1-100之間的奇數和,偶數和
計算1-1000之間的能被5整除的數,並且3個數一換行
注:
println
輸出完 會換行
print
輸出完 不會換行
九九乘法表
增強for迴圈
語句更簡便
break
和 continue
break
是強制退出迴圈,不執行剩下的語句
continue
用於終止某次迴圈過程,跳過迴圈體中尚未執行的語句,接著進行下一次是否執行迴圈的判定(再次回到尋魂開始的地方,從新開始迴圈)
標籤
列印三角形
方法
Java方法是語句的集合,他們在一起執行一個功能
- 方法是解決一類問題的步驟的有序組合
- 方法包含於類或物件中
- 方法在程式中被建立,在其他地方被引用
- 方法的本意是功能塊
- 一個方法只完成一個功能
void
表示 空
main方法要時刻保持簡介乾淨,儘量將公共模組都提取到外面,通方法呼叫來實現功能
方法的定義
Java的方法類似於其他語言的函式,是一段用來完成特定功能的程式碼片段
定義方法的語句
方法包含一個方法頭和一個方法體
形參和實參
方法呼叫
呼叫方法:物件名.方法名(實參列表)
-
當方法返回一個值得時候,方法呼叫通常被當作一個值
int larger = max(30,40);
-
當方法返回值是void,方法呼叫一定是一條語句
System.out.println("Hello,Yolo!")
方法過載
過載就是在一個類中,有相同的函式名稱,但形參不同的函式
方法的過載的規則:
- 方法名稱必須相同
- 引數列表必須不同(個數不同,或型別不同,引數排列順序不同等)
- 方法的返回型別可以相同也可以不同
- 僅僅返回型別不同不足以成為方法的過載
可變引數(不定項引數)
遞迴
自己呼叫自己
遞迴的兩部分
- 遞迴頭:定義什麼時候不呼叫自身方法。如果沒有頭,將陷入死迴圈
- 遞迴體:什麼時候需要呼叫自身方法
基數大的不要用遞迴
計算器
陣列
陣列是相同型別資料的有序集合,是相同型別的若干個資料,按照一定的先後次序排雷組合而成
其中的每一個資料稱作一個陣列元素,每個陣列元素可以透過一個下標來訪問他們
格式
dataType[] arrayRefVar;
用 new 來建立陣列
定義了什麼型別的陣列,就new什麼型別的陣列
dataType[] arrayRefVar = new dataType[arraySize];
eg:
nums = new int [10]; #可以存放10個int型別的數字
記憶體分析
陣列邊界
注意下標的合法區間 [0,length-1]
超出區間會報錯
陣列的使用
for迴圈
反轉陣列
多維陣列
二維陣列
int a[][] = new int[2][5];
氣泡排序
-
比較陣列中,兩個相鄰的元素,如果第一個數比第二個數大,我們就交換他們的位置
-
每一次比較,都會產生出一個最大,或者最小的數字;
-
下一輪則可以少一次排序!
-
依次迴圈,直到結束!
自動排序
Arrays.sort(n);
稀疏陣列
- 當一個陣列中大部分元素為0,或者為同一值的陣列時,可以用稀疏陣列來儲存陣列
- 稀疏陣列的處理方式
- 記錄陣列一共有幾行幾列,有多少個不同值
- 把具有不同值的元素而後行列及值記錄愛意額小規模陣列中,從而縮小程式的規模
轉換為稀疏陣列
獲取有效值個數
稀疏陣列還原
物件導向程式設計 和 程序導向程式設計 的區別
程序導向程式設計是 將任務一步步拆分,第一步幹啥,第二步幹啥,最後幹啥
物件導向程式設計是 先有物件 然後與其進行互動
GirlFriend gf = new GirlFriend();
gf.name = "Alice";
gf.send("flowers");
建立物件,賦值,呼叫物件,並傳遞了個引數 Alice傳送了一些 花
物件導向
本質
以類的方式組織程式碼,以物件的組織(封裝)資料
基本概念
- 類
- 例項
- 方法
三大特性
(物件導向的實現方式)
-
封裝
-
繼承
-
多型
物件導向基礎
Person zhang = new Person();
建立了Person型別的例項,透過變數zhang來指向它
Person zhang
是定義Person
是定義Person
型別的變數zhang
,new Person()
是建立Person
例項
方法
public
變成private
外部程式碼呼叫方法setName()
和setAge()
來間接修改private
欄位
setAge()
就會檢查傳入的引數
注:類透過定義方法,可以給外部程式碼暴露一些操作的介面
定義方法
修飾符 方法返回型別 方法名(方法引數列表) {
若干方法語句;
return 方法返回值;
}
private方法
只有內部方法可以呼叫private
方法
以上程式碼沒有定義age欄位,獲取age時,透過方法getAge()
返回的是一個實時計算的值,並非儲存在某個欄位的值。這說明方法可以封裝一個類的對外介面,呼叫方不需要知道也不關心Person
例項在內部到底有沒有age
欄位
this變數
在方法內部呼叫,始終指向當前例項
沒有命名衝突時可以省略
class Person {
private String name;
public String getName() {
return name; // 相當於this.name
}
}
class Person {
private String name;
public void setName(String name) {
this.name = name; // 前面的this不可少,少了就變成區域性變數name了
}
}
方法引數
class Person {
...
public void setNameAndAge(String name, int age) {
...
}
}
當呼叫以上方法時,必須呼叫兩個引數, string
和 int
Person zhang = new Person();
zhang.steNameAndAge("zhangsan",18)
可變引數
可變引數跟陣列型別類似
引數繫結
呼叫方把引數傳遞給例項方法時,呼叫時傳遞的值會按引數位置一一繫結
基本型別的引數傳遞
以上,setAge
方法是將傳入的值賦給Person
例項的 age
屬性,變數 n
本身與 age
屬性並沒有繫結,所以 當 n
值改變時,p
的 age
屬性保持不變
故 基本型別的引數傳遞 時區域性變數和n
互不影響
傳遞引用引數
以上 引數是以一個陣列,修改其內容,例項 p
的欄位 name
的內容 也會被修改
引用型別引數的傳遞,呼叫方的變數,和接收方的引數變數,指向的是同一個物件。雙方任意一方對這個物件的修改,都會影響對方(因為指向同一個物件)
呼叫方法
例項變數.方法名("引數")
zhang.setName("李華")
構造方法
建立例項時,透過構造方法實現將例項的值初始化完成
構造方法名是類名,對引數沒有限制,在方法內部(跟普通方法象不沒有返回值【包括void】)
注:
當我們定義了一個類而沒有自定義構造方法時,編譯器會自動生成一個預設的構造方法,預設構造方法裡 沒有引數和執行語句
class Person {
public Person() {
}
}
我們還可以定義兩個構造方法 比如帶引數的和不帶引數的
public class Main {
public static void main(String[] args) {
Person p1 = new Person("Xiao Ming", 15); // 既可以呼叫帶引數的構造方法
Person p2 = new Person(); // 也可以呼叫無引數構造方法
}
}
class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
}
由於先執行初始化程式碼 在執行建構函式的程式碼 ,所以 new Person
的值由構造方法確定
多個構造方法
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name) {
this.name = name;
this.age = 12;
}
public Person() {
}
}
如果呼叫new Person("Xiao Ming", 20);
,會自動匹配到構造方法public Person(String, int)
。
如果呼叫new Person("Xiao Ming");
,會自動匹配到構造方法public Person(String)
。
如果呼叫new Person();
,會自動匹配到構造方法public Person()
。
構造方法呼叫另一個構造方法
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name) {
this(name, 18); // 呼叫另一個構造方法Person(String, int)
}
public Person() {
this("Unnamed"); // 呼叫另一個構造方法Person(String)
}
}
方法過載
方法名相同,但引數不同,叫方法過載(Overload)
功能類似的方法,使用同一方法名,呼叫起來方便
class Hello {
public void hello() {
System.out.println("Hello, world!");
}
public void hello(String name) {
System.out.println("Hello, " + name + "!");
}
public void hello(String name, int age) {
if (age < 18) {
System.out.println("Hi, " + name + "!");
} else {
System.out.println("Hello, " + name + "!");
}
}
}
可以有多個過載方法
繼承
繼承機制,可以複用程式碼
當我們在person
類的基礎上新增student
類 student
類包含了person
類已有的欄位和方法並且多了sorce
欄位
class Person {
private String name;
private int age;
public String getName() {...}
public void setName(String name) {...}
public int getAge() {...}
public void setAge(int age) {...}
}
class Student {
private String name;
private int age;
private int score;
public String getName() {...}
public void setName(String name) {...}
public int getAge() {...}
public void setAge(int age) {...}
public int getScore() { … }
public void setScore(int score) { … }
}
根據繼承機制 以上程式碼可以用 extends
關鍵字來實現繼承
不需要重新定義age
和name
欄位 只需要重新定義score
欄位
class Person {
private String name;
private int age;
public String getName() {...}
public void setName(String name) {...}
public int getAge() {...}
public void setAge(int age) {...}
}
class Student extends Person {
private int score;
public int getScore() { … }
public void setScore(int score) { … }
注:子類自動獲得了父類的所有欄位,嚴禁定義與父類重名的欄位!
在OOP的術語中,我們把Person
稱為超類(super class),父類(parent class),基類(base class),把Student
稱為子類(subclass),擴充套件類(extended class
感覺跟ssti的繼承類似 每個類都會繼承自某個類
也可以 某兩個類繼承於同一個類
protected
關鍵字
- 子類無法訪問父類的
private
欄位 或者private
方法 - 但是 只要將
private
修改為protected
就能被子類訪問到 - 子類的子類 也可以訪問其父類的
protected
protected
關鍵字所修飾的欄位和防範 能夠保證訪問許可權在繼承樹的內部
super
(父類)
super
表示父類,當子類引用父類的欄位時,可以用 super.fileName
class Student extends Person {
public String hello() {
return "Hello, " + super.name;
}
}
除必要情況 也可以直接使用 this.anme
或者name
效果是一樣的
當父類沒有預設的構造方法時 子類就必須呼叫super();
public class Main {
public static void main(String[] args) {
Student s = new Student("Xiao Ming", 12, 89);
}
}
class Person {
protected String name;
protected int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
class Student extends Person {
protected int score;
public Student(String name, int age, int score) {
super(name, age); // 呼叫父類的構造方法Person(String, int)
this.score = score;
}
}
子類不會繼承任何父類的構造方法。子類預設的構造方法是編譯器自動生成的,不是繼承的
使用sealed
修飾class,並透過permits
明確寫出能夠從該class繼承的子類名稱
public sealed class Shape permits Rect, Circle, Triangle {
...
}
向上轉型
當 student
繼承了 person
之後 student
就有了 perosn
的所有功能 可以實現一個引用型別為 person
的變數指向 student
型別的例項
Person p = new Student();
透過以上例項 可以發現 子類型別可以轉換為更高層次的父類甚至是 object
向下轉型
將父類型別強制轉換成子型別
Person p1 = new Student();
Student s1 (Student) p1;
但是如果 p2一開始是指向Person的將無法轉換
Person p2 = new Person();
Student s2 (Student) p2;
instanceof
運算子
Person p = new Person();
System.out.println(p instanceof Person); // true
System.out.println(p instanceof Student); // false
Student s = new Student();
System.out.println(s instanceof Person); // true
System.out.println(s instanceof Student); // true
Student n = null;
System.out.println(n instanceof Student); // false
判斷instanceof
public static void main(String[] args) {
Object obj = "hello";
if (obj instanceof String s) {
// 可以直接使用變數s:
System.out.println(s.toUpperCase());
}
}
}
組合
student
和 person
是is
關係, student
和 book
是has
關係
is
關係是繼承 has
關係是組合
class Student extends Person {
protected Book book;
protected int score;
}
多型
在繼承關係中,子類如果定義了一個與父類方法簽名完全相同的方法,被稱為覆寫(Override)
class Person {
public void run() {
System.out.println("Person.run");
}
}
在子類Student中,覆寫這個run()方法:
class Student extends Person {
@Override //編譯器會幫助檢查是否覆寫成功
public void run() {
System.out.println("Student.run");
}
}
計算稅收的例項
// Polymorphic
public class Main {
public static void main(String[] args) {
// 給一個有普通收入、工資收入和享受國務院特殊津貼的小夥伴算稅:
Income[] incomes = new Income[] {
new Income(3000),
new Salary(7500),
new StateCouncilSpecialAllowance(15000)
};
System.out.println(totalTax(incomes));
}
public static double totalTax(Income... incomes) {
double total = 0;
for (Income income: incomes) {
total = total + income.getTax();
}
return total;
}
}
class Income {
protected double income;
public Income(double income) {
this.income = income;
}
public double getTax() {
return income * 0.1; // 稅率10%
}
}
class Salary extends Income {
public Salary(double income) {
super(income);
}
@Override
public double getTax() {
if (income <= 5000) {
return 0;
}
return (income - 5000) * 0.2;
}
}
class StateCouncilSpecialAllowance extends Income {
public StateCouncilSpecialAllowance(double income) {
super(income);
}
@Override
public double getTax() {
return 0;
}
}
在必要的情況下,我們可以覆寫Object
的這幾個方法。例如:
class Person {
...
// 顯示更有意義的字串:
@Override
public String toString() {
return "Person:name=" + name;
}
// 比較是否相等:
@Override
public boolean equals(Object o) {
// 當且僅當o為Person型別:
if (o instanceof Person) {
Person p = (Person) o;
// 並且name欄位相同時,返回true:
return this.name.equals(p.name);
}
return false;
}
// 計算hash:
@Override
public int hashCode() {
return this.name.hashCode();
}
}
在子類的覆寫方法中,如果要呼叫父類的被覆寫的方法,可以透過super
來呼叫
繼承可以允許子類覆寫父類的方法。如果一個父類不允許子類對它的某個方法進行覆寫,可以把該方法標記為final
。用final
修飾的方法不能被Override
class Person {
protected String name;
public final String hello() {
return "Hello, " + name;
}
}
class Student extends Person {
// compile error: 不允許覆寫
@Override
public String hello() {
}
}
如果一個類不希望任何其他類繼承自它,那麼可以把這個類本身標記為final
。用final
修飾的類不能被繼承:
final class Person {
protected String name;
}
// compile error: 不允許繼承自Person
class Student extends Person {
}
欄位同理
class Person {
public final String name = "Unamed";
}
給final欄位重新賦值會報錯
如果父類的方法本身不需要實現任何功能,僅僅是為了定義方法簽名,目的是讓子類去覆寫它,那麼,可以把父類的方法宣告為抽象方法
抽象方法
如果一個class
定義了方法,但沒有具體執行程式碼,這個方法就是抽象方法,抽象方法用abstract
修飾。
因為無法執行抽象方法,因此這個類也必須申明為抽象類(abstract class)。
介面
interface
用 它來宣告一個介面
所謂interface
,就是比抽象類還要抽象的純抽象介面,因為它連欄位都不能有。因為介面定義的所有方法預設都是public abstract
的
當一個具體的class
去實現一個interface
時,需要使用implements
關鍵字。舉個例子:
class Student implements Person {
private String name;
public Student(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(this.name + " run");
}
@Override
public String getName() {
return this.name;
}
}
介面繼承
一個interface
可以繼承自另一個interface
。interface
繼承自interface
使用extends
,它相當於擴充套件了介面的方法。例如:
interface Hello {
void hello();
}
interface Person extends Hello {
void run();
String getName();
}
此時,Person
介面繼承自Hello
介面,因此,Person
介面現在實際上有3個抽象方法簽名,其中一個來自繼承的Hello
介面
靜態欄位和靜態方法
靜態欄位
public class Main {
public static void main(String[] args) {
Person ming = new Person("Xiao Ming", 12);
Person hong = new Person("Xiao Hong", 15);
ming.number = 88;
System.out.println(hong.number);
hong.number = 99;
System.out.println(ming.number);
}
}
class Person {
public String name;
public int age;
public static int number;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
推薦用類名來訪問靜態欄位
Person.number = 99;
System.out.println(Person.number);
靜態方法
靜態方法需透過類名呼叫
靜態方法屬於class不屬於例項
包
包沒有父子關係 沒有繼承關係
解決包衝突的問題包名.類名
,如
小明的Person
類存放在包ming
下面,因此,完整類名是ming.Person
;
JDK的Arrays
類存放在包java.util
下面,因此,完整類名是java.util.Arrays
在定義class
的時候,我們需要在第一行宣告這個class
屬於哪個包
小明的Person.java
檔案:
package ming; // 申明包名ming
public class Person {
}
包作用域
包作用域是指,一個類允許訪問同一個 package
的沒有 public
和 private
修飾的 class
,以及沒有public
protected
private
修飾的欄位和方法
位於同一個包的類,可以訪問包作用域的欄位和方法。不用public
、protected
、private
修飾的欄位和方法就是包作用域。例如,Person
類定義在hello
包下面:
package hello;
public class Person {
// 包作用域:
void hello() {
System.out.println("Hello!");
}
}
當小明要引用小軍的類時
package ming;
// 匯入完整類名:
import mr.jun.Arrays;
public class Person {
public void run() {
// 寫簡單類名: Arrays
Arrays arrays = new Arrays();
}
}
定義為public
的類或者方法可以被其它類呼叫,前提是要有訪問的權力
定義為private
的方法無法被其他類訪問:
巢狀
定義在 class
內部的 class
就是巢狀類
用 final
可以阻止區域性變數、方法被重新賦值,方法被子類覆寫,class
被覆寫
內部類
有一種類被定義在另一個類的內部,稱為內部類(Inner Class)
class Outer {
class Inner {
// 定義了一個Inner Class
}
}
上述定義的Outer
是一個普通類,而Inner
是一個Inner Class,它與普通類有個最大的不同,就是Inner Class的例項不能單獨存在,必須依附於一個Outer Class的例項。示例程式碼如下:
// inner class
public class Main {
public static void main(String[] args) {
Outer outer = new Outer("Nested"); // 例項化一個Outer
Outer.Inner inner = outer.new Inner(); // 例項化一個Inner
inner.hello();
}
}
class Outer {
private String name;
Outer(String name) {
this.name = name;
}
class Inner {
void hello() {
System.out.println("Hello, " + Outer.this.name);
}
}
}
Outer.Inner inner = outer.new Inner();
想要例項化Inner
,我們必須首先建立一個Outer
的例項,然後,呼叫Outer
例項的new
來建立Inner
例項
觀察Java編譯器編譯後的.class
檔案可以發現,Outer
類被編譯為Outer.class
,而Inner
類被編譯為Outer$Inner.class
。
Static Nested Class
最後一種內部類和Inner Class類似,但是使用static
修飾,稱為靜態內部類(Static Nested Class):
// Static Nested Class
public class Main {
public static void main(String[] args) {
Outer.StaticNested sn = new Outer.StaticNested();
sn.hello();
}
}
class Outer {
private static String NAME = "OUTER";
private String name;
Outer(String name) {
this.name = name;
}
static class StaticNested {
void hello() {
System.out.println("Hello, " + Outer.NAME);
}
}
}
用static
修飾的內部類和Inner Class有很大的不同,它不再依附於Outer
的例項,而是一個完全獨立的類,因此無法引用Outer.this
,但它可以訪問Outer
的private
靜態欄位和靜態方法。如果把StaticNested
移到Outer
之外,就失去了訪問private
的許可權。
classpath
classpath
是JVM用到的一個環境變數,它用來指示JVM如何搜尋class
Jar包
將目錄打包
字串和編碼
String
是一個引用型別
String s1 = "Hello";
實際上字串在String
內部是透過一個char[]
陣列表示的,因此,按下面的寫法也是可以的:
String s2 = new String(new char[] {'H', 'e', 'l', 'l', 'o', '!'});
字串比較
比較兩個字串的內容是否相等 要用equals()方法
public class Main {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
}
}
索引從零開始
搜尋子串的更多的例子:
"Hello".indexOf("l"); // 2
"Hello".lastIndexOf("l"); // 3
"Hello".startsWith("He"); // true
"Hello".endsWith("lo"); // true
提取子串的例子:
"Hello".substring(2); // "llo"
"Hello".substring(2, 4); "ll"
去除首尾空白字元
使用trim()
方法可以移除字串首尾空白字元。空白字元包括空格,\t
,\r
,\n
" \tHello\r\n ".trim();
使用 isEmpty()
和 isBlank()
來判斷字串是否為空和空白字串
替換字串
要在字串中替換子串,有兩種方法。一種是根據字元或字串替換:
String s = "hello";
s.replace('l', 'w'); // "hewwo",所有字元'l'被替換為'w'
s.replace("ll", "~~"); // "he~~o",所有子串"ll"被替換為"~~"
另一種是透過正規表示式替換:
String s = "A,,B;C ,D";
s.replaceAll("[\\,\\;\\s]+", ","); // "A,B,C,D"
格式化字串
字串提供了formatted()
方法和format()
靜態方法,可以傳入其他引數,替換佔位符,然後生成新的字串:
// String
public class Main {
public static void main(String[] args) {
String s = "Hi %s, your score is %d!";
System.out.println(s.formatted("Alice", 80));
System.out.println(String.format("Hi %s, your score is %.2f!", "Bob", 59.5));
}
}
有幾個佔位符,後面就傳入幾個引數。引數型別要和佔位符一致。我們經常用這個方法來格式化資訊。常用的佔位符有:
%s
:顯示字串;%d
:顯示整數;%x
:顯示十六進位制整數;%f
:顯示浮點數。
型別轉換
使用 valueof
String.valueOf(123); // "123"
String.valueOf(45.67); // "45.67"
String.valueOf(true); // "true"
String.valueOf(new Object()); // 類似java.lang.Object@636be97c
參考連結