日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java学习笔记(二):String

發布時間:2023/11/29 java 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java学习笔记(二):String 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

String

在Java中String是作為引用對象存在的一種數據類型,用來保存字符串。

實例化和賦值

//直接聲明 String s1 = "Hello world!"; //通過構造函數創建, 提供了 11 種不同參數創建的方法 char[] c = { 'h', 'e', 'l', 'l', 'o', '.'}; String s2 = new String(c);

String類是不可改變的,所以你一旦創建了String對象,那它的值就無法改變了。如果需要對字符串做很多修改,那么應該選擇使用StringBuffer或StringBuilder類。

我們來看下面的另一種創建方法:

使用這種方式來創建字符串,在堆內存中會創建兩個字符串對象,因為當使用""符號是就表示創建了一個新的字符串,而str只指向了第二個對象,導致第一個對象沒有引用,處于等待回收的狀態,除了加大內存使用外,還增加了GC的負擔,所以直接使用""來創建字符串是更好的方式。

連接字符串

String類提供了連接兩個字符串的方法:

string1.concat(string2);

返回string2連接string1的新字符串。也可以對字符串常量使用concat()方法,如:

"My name is ".concat("Zara");

更常用的是使用'+'操作符來連接字符串,如:

"Hello," + " world" + "!"

結果如下:

"Hello, world!"

下面是一個例子:

1 public class StringDemo { 2 public static void main(String args[]) { 3 String string1 = "saw I was "; 4 System.out.println("Dot " + string1 + "Tod"); 5 } 6 }

以上實例編譯運行結果如下:

Dot saw I was Tod

比較字符串

判斷字符串內容是否相等,Java和大部分語言不一樣,Java中==是比較兩個字符串引用的地址是否相同,即是否指向同一個對象,而equals方法則比較字符串的內容是否相同。

String a = "abc"; String b = new String("abc");

a == b返回false,a.equals(b)返回true。這時創建b時不管"abc"是否存在都會new一個新的"abc",從而a和b指向的字符創對象是不同的,因此返回false。

我們來看下面的情況,容易混淆:

String a = "abc"; String b = "abc";

a == b返回true,a.equals(b)同樣返回true,這是為什么呢?

原來程序在運行時有一個字符串池,創建字符串時會先查找池中是否有相應的字符串,如果已經存在的話只需把引用指向它即可,如果沒有則新建一個。

上例中創建a時,會在字符串池中首先創建一個"abc",然后a指向它;創建b時,由于"abc"已經存在,b直接指向它即可。

格式化字符串

String類的format()方法用于創建格式化的字符串以及連接多個字符串對象,

format()方法有兩種重載形式:

  • format(String format, Object... args) 新字符串使用本地語言環境,制定字符串格式和參數生成格式化的新字符串。
  • format(Locale locale, String format, Object... args) 使用指定的語言環境,制定字符串格式和參數生成格式化的字符串。

顯示不同轉換符實現不同數據類型到字符串的轉換,如圖所示:

轉? 換? 符

說??? 明?

示??? 例

%s

字符串類型

"mingrisoft"

%c

字符類型

'm'

%b

布爾類型

true

%d

整數類型(十進制)

99

%x

整數類型(十六進制)

FF

%o

整數類型(八進制)

77

%f

浮點類型

99.99

%a

十六進制浮點類型

FF.35AE

%e

指數類型

9.38e+5

%g

通用浮點類型(f和e類型中較短的)

?

%h

散列碼

?

%%

百分比類型

%n

換行符

?

%tx

日期與時間類型(x代表不同的日期與時間轉換符

?

測試用例:

1 public static void main(String[] args) { 2 String str=null; 3 str=String.format("Hi,%s", "王力"); 4 System.out.println(str); 5 str=String.format("Hi,%s:%s.%s", "王南","王力","王張"); 6 System.out.println(str); 7 System.out.printf("字母a的大寫是:%c %n", 'A'); 8 System.out.printf("3>7的結果是:%b %n", 3>7); 9 System.out.printf("100的一半是:%d %n", 100/2); 10 System.out.printf("100的16進制數是:%x %n", 100); 11 System.out.printf("100的8進制數是:%o %n", 100); 12 System.out.printf("50元的書打8.5折扣是:%f 元%n", 50*0.85); 13 System.out.printf("上面價格的16進制數是:%a %n", 50*0.85); 14 System.out.printf("上面價格的指數表示:%e %n", 50*0.85); 15 System.out.printf("上面價格的指數和浮點數結果的長度較短的是:%g %n", 50*0.85); 16 System.out.printf("上面的折扣是%d%% %n", 85); 17 System.out.printf("字母A的散列碼是:%h %n", 'A'); 18 }

輸出結果:

1 Hi,王力 2 Hi,王南:王力.王張 3 字母a的大寫是:A 4 3>7的結果是:false 5 100的一半是:50 6 100的16進制數是:64 7 100的8進制數是:144 8 50元的書打8.5折扣是:42.500000 9 上面價格的16進制數是:0x1.54p5 10 上面價格的指數表示:4.250000e+01 11 上面價格的指數和浮點數結果的長度較短的是:42.5000 12 上面的折扣是85% 13 字母A的散列碼是:41

String、StringBuffer和StringBuider

首先,通過閱讀Java源碼我們可以發現String類是被final標記為不能繼承的類,其內部是使用一個char數組來記錄整個字符串的值,而String類的大部分改變數據的方法(如substring、concat和replace等),都是直接創建一個新的String對象改變后返回,所以我們說String的數據是不能更改的,實際上Java也沒有為String設計更改其內部char數組的方法。

在這里要永遠記住一點:“對String對象的任何改變都不影響到原對象,相關的任何change操作都會生成新的對象”。

看個例子

1 public class Main { 2 ????????? 3 ????public static void main(String[] args) { 4 ????????String str1 = "hello world"; 5 ????????String str2 = new String("hello world"); 6 ????????String str3 = "hello world"; 7 ????????String str4 = new String("hello world"); 8 ????????? 9 ????????System.out.println(str1==str2); 10 ????????System.out.println(str1==str3); 11 ????????System.out.println(str2==str4); 12 ????} 13 }

輸出的結果是:

1 false 2 true 3 false

為什么會出現這樣的結果?下面解釋一下原因:

對于JVM內存機制,在class文件中有一部分 來存儲編譯期間生成的 字面常量以及符號引用,這部分叫做class文件常量池,在運行期間對應著方法區的運行時常量池。

因此在上述代碼中,String str1 = "hello world";和String str3 = "hello world"; 都在編譯期間生成了字面常量和符號引用,運行期間字面常量"hello world"被存儲在運行時常量池(當然只保存了一份)。通過這種方式來將String對象跟引用綁定的話,JVM執行引擎會先在運行時常量池查找是否存在相同的字面常量,如果存在,則直接將引用指向已經存在的字面常量;否則在運行時常量池開辟一個空間來存儲該字面常量,并將引用指向該字面常量。

總所周知,通過new關鍵字來生成對象是在堆區進行的,而在堆區進行對象生成的過程是不會去檢測該對象是否已經存在的。因此通過new來創建對象,創建出的一定是不同的對象,即使字符串的內容是相同的。

StringBuilder

我們看一下下面的例子:

1 public class Main { 2 ????public static void main(String[] args) { 3 ????????String string = ""; 4 ????????for(int i=0;i<10000;i++){ 5 ????????????string += "hello"; 6 ????????} 7 ????} 8 }

我們知道,每次對String進行連接操作都是重新生成一個新的String,那么這段代碼運行后會創建10001個String對象,而存在引用的僅1個String對象,其他對象會被當做垃圾回收,造成了內存和CPU的浪費。

Java為了解決這種情況,設計了StringBuilder,StringBuilder可以直接修改其內部記錄的char數組,在改變字符串時不會生成多余的對象,如下:

1 public class Main { 2 ????public static void main(String[] args) { 3 ????????StringBuilder stringBuilder = new StringBuilder(); 4 ????????for(int i=0;i<10000;i++){ 5 ????????????stringBuilder.append("hello"); 6 ????????} 7 ????} 8 }

得到的結果和上面使用String的方法一致,但避免了內存和CPU資源的浪費。

StringBuffer

實際上StringBuffer提供的功能和StringBuilder是一樣的,唯一的不同就是StringBuilder是線程不安全的,只能在單線程中使用,而StringBuffer是線程安全的,可以在多線程中使用。

總結

以上是生活随笔為你收集整理的Java学习笔记(二):String的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。