java字元串編程
㈠ 用java編寫一程序:從鍵盤輸入多個字元串到程序中,並將它們按逆序輸出在屏幕上。
代碼如下:
import java.util.Scanner;
public class ScannerDemo{
public static void main(String[] args) throws Exception{
Scanner scan=new Scanner(System.in);
System.out.println("請輸入內容:");
String str=scan.nextLine();
char[] s=str.toCharArray();
for(int i=s.length-1;i>=0;i--){
System.out.print(s[i]);}}}
(1)java字元串編程擴展閱讀
字元串
通常以串的整體作為操作對象,如:在串中查找某個子串、求取一個子串、在串的某個位置上插入一個子串以及刪除一個子串等。
兩個字元串相等的充要條件是:長度相等,並且各個對應位置上的字元都相等。設p、q是兩個串,求q在p中首次出現的位置的運算叫做模式匹配。串的兩種最基本的存儲方式是順序存儲方式和鏈接存儲方式。
基本數據結構
在Java中有8種數據類型來存儲數值、字元和布爾值。
整數類型
整數型用來存儲整數數值,即沒有小數部分的數值。可以是正數,也可以是負數。整數數據在Java程序中有3種表示形式,分別為十進制、八進制和十六進制。
㈡ Java工具類(一)Guava操作字元串
在Java編程中,處理字元串是一個常見任務,從簡單的空值判斷到復雜的拆分和連接操作,都需要高效、簡便的解決方案。為簡化這類任務,Google開發了Guava庫,提供豐富的集合工具和高效字元串處理功能。本文將深入探討Guava庫的字元串操作能力,重點關注連接器、拆分器、字元匹配器、字元集和大小寫格式工具。
Guava連接器(Joiner)是一個強大的字元串連接工具,能夠優雅地處理空值問題。其使用方式分為三步:使用`on`方法設置連接符,調用`useForNull`方法為`null`值設定默認處理,最後使用`join`方法處理集合。例如:
java
Joiner joiner = Joiner.on(", ");
String result = joiner.join(Arrays.asList("apple", null, "banana"));
Guava拆分器(Splitter)允許以模式、字元、字元串或字元匹配器進行復雜拆分,返回`Iterable`對象。其創建和配置過程同樣遵循不可變設計原則,確保線程安全。
字元匹配器(CharMatcher)則提供了一種簡單而強大的方式來處理特定類型的字元,如數字或空白字元。它實現了一個布爾判斷介面,並提供了多種方法來操作匹配字元,如修剪、折疊、移除、保留等。
Charsets為Java平台提供的六種標准字元集提供了常量引用,確保了跨平台兼容性。使用這些常量而非名稱獲取實例能避免潛在的不兼容性問題。
大小寫格式(CaseFormat)工具用於方便地在不同ASCII大小寫規范間轉換字元串,支持多種格式。例如,轉換字元串以適應編程語言的命名規范。
總結而言,Guava的字元串處理工具集不僅簡化了常見字元串操作,還提供了高性能、靈活的解決方案,適用於大規模數據處理。在使用時,需根據具體需求和場景合理選擇工具和參數,以實現性能優化。Guava庫的高效設計和豐富功能,為Java開發者提供了強大的支持,有助於提高開發效率和代碼質量。
㈢ 淺談Java中字元串的初始化(詳細圖解)
前言在深入學習字元串類之前,我們先搞懂JVM是怎樣處理新生字元串的。當你知道字元串的初始化細節後,再去寫Strings="hello"或Strings=newString("hello")等代碼時,就能做到心中有數。
首先得搞懂字元串常量池的概念,下面進入正文吧。
常量池把經常用到的數據存放在某塊內存中,避免頻繁的數據創建與銷毀,實現數據共享,提高系統性能。
八種基礎數據類型除了float和double都實現了常量池技術。在近代的JDK版本中(1.7後),字元串常量池被實現在Java堆內存中。
下面通過三行代碼讓大家對字元串常量池建立初步認識:
publicstaticvoidmain(String[]args){Strings1="hello";Strings2=newString("hello");System.out.println(s1==s2);//false}先來看看第一行代碼Strings1="hello";
直接通過雙引號(Strings1="hello")聲明字元串的方式,虛擬機首先會到字元串常量池中查找該字元串是否已經存在。如果存在會直接返回該引用,如果不存在則會在堆內存中創建該字元串對象,然後到字元串常量池中注冊該字元串。
上面的代碼中(Strings1="hello")虛擬機首先會到字元串常量池中查找是否有存在hello字元串對應的引用。發現沒有後會在堆內存創建hello字元串對象(內存地址0x0001),然後到字元串常量池中注冊地址為0x0001的hello對象,也就是添加指向0x0001的引用。最後把字元串對象返回給s1。
下面看Strings2=newString("hello");
當我們使用new關鍵字創建字元串對象的時候,JVM將不會查詢字元串常量池,它將會直接在堆內存中創建一個字元串對象,並返回給所屬變數。
所以s1和s2指向的是兩個完全不同的對象,判斷s1==s2的時候會返回false。
再來看下面的示例:
publicstaticvoidmain(String[]args){Strings1=newString("hello")+newString("world");s1.intern();Strings2="helloworld";System.out.println(s1==s2);//true}第一行代碼Strings1=newString("hello")+newString("world");的執行過程是這樣子的:
依次在堆內存中創建hello和world兩個字元串對象;
然後把它們拼接起來(底層使用StringBuilder實現);
在拼接完成後會產生新的helloworld對象,這時變數s1指向新對象helloworld。
執行完第一行代碼後,內存是這樣子的:
第二行代碼s1.intern();
當調用intern()方法時,首先會去常量池中查找是否有該字元串對應的引用,如果有就直接返回該字元串;
如果沒有,就會在常量池中注冊該字元串的引用,然後返回該字元串。
由於第一行代碼採用的是new的方式創建字元串,所以在字元串常量池中沒有保存helloworld對應的引用,虛擬機會在常量池中進行注冊,注冊完後的內存示意圖如下:
第三行代碼Strings2="helloworld";
首先虛擬機會去檢查字元串常量池,發現有指向helloworld的引用。然後把該引用所指向的字元串直接返回給所屬變數。
執行完第三行代碼後,內存示意圖如下:
如圖所示,s1和s2指向的是相同的對象,所以當判斷s1==s2時返回true。
總結:
當用new關鍵字創建字元串對象時,不會查詢字元串常量池;
當用雙引號直接聲明字元串對象時,虛擬機將會查詢字元串常量池。
說白了就是:字元串常量池提供了字元串的復用功能,除非我們要顯式創建新的字元串對象,否則對同一個字元串虛擬機只會維護一份拷貝。
反編譯代碼驗證字元串初始化操作下面我們再來看一個示例:
publicclassMain{publicstaticvoidmain(String[]args){Strings1="hello";Strings2="world";Strings3=s1+s2;Strings4="helloworld";System.out.println(s3==s4);}}首先第一行和第二行是常規的字元串對象聲明,它們分別會在堆內存創建字元串對象,並會在字元串常量池中進行注冊。
影響我們做出判斷的是第三行代碼Strings3=s1+s2;,我們不知道s1+s2在創建完新字元串helloworld後是否會在字元串常量池進行注冊。
簡單點說:我們不知道這行代碼是以雙引號形式聲明字元串,還是用new關鍵字創建字元串。
那麼我們看下這端代碼的反編譯後的代碼:
PSD:codejavaSE argetclassesdemo>javap-c.Main.classCompiledfrom"Main.java"publicclassdemo.Main{publicdemo.Main();Code:0:aload_01:invokespecial#1//Methodjava/lang/Object."<init>":()V4:returnpublicstaticvoidmain(java.lang.String[]);Code:0:ldc#2//Stringhello2:astore_13:ldc#3//Stringworld5:astore_26:new#4//classjava/lang/StringBuilder9:p10:invokespecial#5//Methodjava/lang/StringBuilder."<init>":()V13:aload_114:invokevirtual#6//Methodjava/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;17:aload_218:invokevirtual#6//Methodjava/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;21:invokevirtual#7//Methodjava/lang/StringBuilder.toString:()Ljava/lang/String;24:astore_325:ldc#8//Stringhelloworld27:astore429:getstatic#9//Fieldjava/lang/System.out:Ljava/io/PrintStream;32:aload_333:aload435:if_acmpne4238:iconst_139:goto4342:iconst_043:invokevirtual#10//Methodjava/io/PrintStream.println:(Z)V46:return}直接看重點:
21:invokevirtual#7//Methodjava/lang/StringBuilder.toString:()Ljava/lang/String;
24:astore_3
虛擬機調用StringBuilder的toString()方法獲得字元串helloworld,並存放至s3。
下面是我們追蹤StringBuilder的toString()方法源碼:
@OverridepublicStringtoString(){//Createa,don'tsharethearrayreturnnewString(value,0,count);}通過以上源碼可以看出:s3是通過new關鍵字獲得字元串對象的。
回到題目,也就是說字元串常量表中沒有存儲helloworld的引用,當s4以引號的形式聲明字元串時,由於在字元串常量池中查不到相應的引用,所以會在堆內存中新創建一個字元串對象。所以s3和s4指向的不是同一個字元串對象,結果為false。
總結閱讀完本文,相信你對於字元串的初始化的了解又更上一層了。關注我,一個專注分享Java知識的新時代農民工。
作者:初念初戀