綱要
(1)String、StringBuffer and StringBuilder
(2)基本數據類型對應的八個包裝類
(3)日期相關類
(4)數字相關類
(5)Random
(6)Enum 枚舉類
一、String
String 被聲明爲 final,因此它不可被繼承。(Integer 等包裝類也不能被繼承)
在 Java 8 中,String 內部使用 char 數組存儲數據。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
}
在 Java 9 之後,String 類的實現改用 byte 數組存儲字符串,同時使用 coder 來標識使用了哪種編碼。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final byte[] value;
/** The identifier of the encoding used to encode the bytes in {@code value}. */
private final byte coder;
}
value 數組被聲明爲 final,這意味着 value 數組初始化之後就不能再引用其它數組。並且 String 內部沒有改變 value 數組的方法,因此可以保證 String 不可變。
public class StringTest01 {
public static void main(String[] args) {
String s1 = "a";
String s2 = "b";
s1=s1 + s2; //ab
//new String(“a”);
System.out.println(s1);
}
}
從以上內存圖,大家可以看到,String 對象賦值後不能再修改,這就是不可變對象,如果對字
符串修改,那麼將會創建新的對象
注意: 只要採用雙引號賦值字符串,那麼在編譯期將會放到方法區中的字符串的常量池裏,如
果是運行時對字符串相加或相減會放到堆中(放之前會先驗證方法區中是否含有相同的字符
串常量,如果存在,把地址返回,如果不存在,先將字符串常量放到池中,然後再返回該對
象的地址)
public class StringTest02 {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
System.out.println("s1==s2, " + (s1==s2)); // true
System.out.println("s2==s3, " + (s2==s3)); // false
System.out.println("s2 equlas s3," + (s2.equals(s3))); // true
}
}
• 如果是採用雙引號引起來的字符串常量,首先會到常量池中去查找,如果存在就不再分配,
如果不存在就分配,常量池中的數據是在編譯期賦值的,也就是生成 class 文件時就把它
放到常量池裏了,所以 s1 和 s2 都指向常量池中的同一個字符串“abc”
• 關於 s3,s3 採用的是 new 的方式,在 new 的時候存在雙引號,所以他會到常量區中查找
“abc”,而常量區中存在“abc”,所以常量區中將不再放置字符串,而 new 關鍵子會在
堆中分配內存,所以在堆中會創建一個對象 abc,s3 會指向 abc
• 如果比較 s2 和 s3 的值必須採用 equals,String 已經對 eqauls 方法進行了覆蓋
String常用方法簡介
- endsWith:判斷字符串是否以指定的後綴結束
- startsWith,判斷字符串是否以指定的前綴開始
- equals,字符串相等比較,不忽略大小寫
- equalsIgnoreCase,字符串相等比較,忽略大小寫
- indexOf,取得指定字符在字符串的位置
- lastIndexOf,返回最後一次字符串出現的位置
- length,取得字符串的長度
- replaceAll,替換字符串中指定的內容
- split,根據指定的表達式拆分字符串
- substring,截子串
- trim,去前尾空格
- valueOf,將其他類型轉換成字符串
使用String時的注意事項
因爲 String 是不可變對象,如果多個字符串進行拼接,將會形成多個對象,這樣可能會造成內
存溢出,會給垃圾回收帶來工作量,如若涉及大量對象創建,建議使用StringBuffer
或StringBuilder
StringBuffer and StringBuilder
StringBuffer 稱爲字符串緩衝區,它的工作原理是:預先申請一塊內存,存放字符序列,如果字符序列滿了,會重新改變緩存區的大小,以容納更多的字符序列。StringBuffer 是可變對象,這個是與 String 最大的不同
StringBuilder用法同 StringBuffer,StringBuilder 和 StringBuffer 的區別是 StringBuffer 中所有的方法都是同步的,是線程安全的,但速度慢,StringBuilder 的速度快,但不是線程安全的
public class StringBufferTest01 {
public static void main(String[] args) {
StringBuffer sbStr = new StringBuffer();
for (int i=0; i<100; i++) {
//sbStr.append(i);
//sbStr.append(",");
//方法鏈的編程風格
sbStr.append(i).append(",");
//拼串去除逗號
//sbStr.append(i);
//if (i != 99) {
// sbStr.append(",");
//}
}
//可以輸出
System.out.println(sbStr);
System.out.println("");
System.out.println(sbStr.toString());
System.out.println("");
//去除逗號
System.out.println(sbStr.toString().substring(0,sbStr.toString().length()-1));
System.out.println("");
System.out.println(sbStr.substring(0, sbStr.length()-1));
}
}
總結:
①可變性
String 不可變
StringBuffer 和 StringBuilder 可變
② 線程安全
String 不可變,因此是線程安全的
StringBuilder 不是線程安全的
StringBuffer 是線程安全的,內部使用 synchronized 進行同步
二、基本類型對應的包裝類
基本類型都有對應的包裝類型,基本類型與其對應的包裝類型之間的賦值使用自動裝箱與拆箱完成。基本類型的包裝類主要提供了更多的實用操作,這樣更容易處理基本類型。所有的包裝類都是final 的,所以不能創建其子類,包裝類都是不可變對象
基本類型 | 包裝類 |
---|---|
byte | Byte |
short | Short |
int |
Integer |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
char |
Character |
類層次結構
除了 boolean 和 Character 外,其它的包裝類都有 valueOf()和 parseXXX 方法,並且還具有
byteVaue(),shortVaue(),intValue(),longValue(),floatValue()和 doubleValue()方法,這些方法是最
常用的方法
public class IntegerTest01 {
public static void main(String[] args) {
int i1 = 100;
Integer i2 = new Integer(i1);
double i3 = i2.doubleValue();
String s = "123";
int i4 = Integer.parseInt(s);
Integer i5 = new Integer(s);
Integer i6 = Integer.valueOf(s);
}
}
JDK5.0的新特性
在 JDK5.0 以前,包裝類和基本類型做運算時,必須將包裝類轉換成基本類型纔可以,而 JDK5.0
提供 Auto-boxing/unboxing(自動裝箱和拆箱)即:
•自動將基礎類型轉換爲對象
•自動將對象轉換爲基礎類型
public class IntegerTest01 {
public static void main(String[] args) {
//jdk1.5 以前版本,必須按如下方式賦值
Integer i1 = new Integer(100);
//jdk1.5 及以後版本支持
//自動裝箱
Integer i2 = 100;
//jdk1.5 以前版本,必須按如下方式賦值
int i3 = i2.intValue();
//jdk1.5 及以後版本支持
//自動拆箱
int i4 = i2;
}
}
三、日期類
常用日期類:
java.util.Date
java.text.SimpleDateFormat
java.util.Calendar
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class DateTest01 {
public static void main(String[] args) throws Exception{
//取得今天的日期
Date today = new Date();
System.out.println(today);
//格式化日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(today));
Calendar c = Calendar.getInstance();
System.out.println(c.get(Calendar.DAY_OF_MONTH));
//取得 2020-05-04 爲星期幾
Date d = new SimpleDateFormat("yyyy-MM-dd").parse("2000-10-01");
c.setTime(d);
System.out.println(c.get(Calendar.DAY_OF_WEEK));
}
}
四、數字類
常用數字類:
java.text.DecimalFormat
java.math.BigDecimal
import java.text.DecimalFormat;
public class DecimalTest01 {
public static void main(String[] args) throws Exception{
//加入千分位,保留兩位小數
DecimalFormat df = new DecimalFormat("###,###.##");
System.out.println(df.format(1234.23452));
//加入千分位保留 4 位小數,不夠補零
System.out.println(new DecimalFormat("###,###.0000").format(12345.12));
}
}
import java.math.BigDecimal;
public class BigDecimalTest01 {
public static void main(String[] args) throws Exception{
BigDecimal v1 = new BigDecimal(10);
BigDecimal v2 = new BigDecimal(20);
//相加運算
BigDecimal v3 = v1.add(v2);
System.out.println(v3);
}
}
五、Random
java.util.Random 可以產生隨機數
生成五個0~100的隨機數
import java.util.Random;
public class RandomTest01 {
public static void main(String[] args) throws Exception{
Random r = new Random();
for (int i=0; i<5; i++) {
System.out.println(r.nextInt(100));
}
}
}
六、Enum 枚舉類
常用方法:
static Enum valueOf(Class enumClass,String name)
返回指定名字、給定類的枚舉常量
String toString()
返回枚舉常量名
int ordinal()
返回枚舉常量在Enum聲明中的位置,位置從0開始計數
int compareTo(E other)
如果枚舉常量出現在other之前,返回一個負值;如果this==other,則返回0;否則,返回正值。枚舉常量的出現次序在Enum聲明中給出
public class EnumTest01 {
public static void main(String[] args) throws Exception{
Result r = method1(10, 2);
if (r == Result.SUCCESS) {
System.out.println("成功!");
}
if (r == Result.FAILURE) {
System.out.println("失敗!");
}
}
//正確返回 SUCCESS,失敗返回:FAILURE
private static Result method1(int value1, int value2) {
try {
int v = value1/value2;
return Result.SUCCESS;
}catch(Exception e) {
return Result.FAILURE;
}
}
}
enum Result {
SUCCESS,FAILURE
}
寫在最後:新手上路,如有問題,歡迎大家指出,給意見。如果這篇文章對你有幫助,麻煩幫忙點一下贊,你們小小的舉動能給我無限大的動力。拒絕白嫖,從我做起,從現在做起。Thank you for watching!