Java常用類 1.字元串相關類練習 1.1StringBuilder練習 package li.normalclass.stringbuilder; public class TestBuffer { public static void main(String[] args) { StringB ...
Java常用類
1.字元串相關類練習
1.1StringBuilder練習
package li.normalclass.stringbuilder;
public class TestBuffer {
public static void main(String[] args) {
StringBuffer a = new StringBuffer("A");
StringBuffer b = new StringBuffer("B");
mb_operate(a,b);
System.out.println(a+"."+b);
}
private static void mb_operate(StringBuffer x, StringBuffer y) {
x.append(y);
y=x;
}
}
問: System.out.println(a+"."+b);
的輸出結果是?
答:AB.B
原因如下:
當運行main方法時,在棧中開闢了兩個記憶體空間,分別是a和b,指向在堆中創建的兩個對象,對象又分別指向了兩個字元數組,數組中存儲的就是新建對象時傳入的參數。
接著運行mb_operate方法,在棧中另外開闢兩個記憶體空間,命名為x和y。其中x指向的是a指向的對象,y指向的是b指向的對象。 x.append(y);
就是在a對象指向的數組中追加b對象指向的數組中的值,此時a對象指向的數組值為AB;y=x;
就是將x中存儲的地址賦值給y,之後y就指向了x指向的對象,即a指向的對象。
System.out.println(a+"."+b);
輸出a對象和b對象的值,此時a對象中的值為AB,b對象中的值為B,因此輸出的內容為AB.B
1.2String和字元數組練習
package li.normalclass.stringbuilder;
public class Example {
String str = new String("good");
char[] ch = {'a','b','c'};
public static void main(String[] args) {
Example ex = new Example();
ex.change(ex.str,ex.ch);
System.out.print(ex.str+"and");
System.out.print(ex.ch);
}
public void change(String str,char ch[]){
str = "test ok";
ch[0] = 'g';
}
}
問:
System.out.print(ex.str+"and");
``System.out.print(ex.ch);`
的輸出結果是?
答:goodandgbc
原因如下:
首先,當main方法創建ex對象,ex指向的對象中的str會再創建一個String類型對象,str指向這個String對象,然後String對象又指向good字元串的地址。
ex指向的對象中的ch則會創建一個位元組數組,該數組中存儲了abc三個字元。
當運行change()方法時,又在棧中開闢了兩個局部變數空間,分別為str和ch,然後傳入參數。將ex.str指向的地址0x2012賦給局部變數str,將ex.ch指向的地址0x4012賦給局部變數ch。在change方法體中,str = "test ok";
則是在常量池中新建了一個字元串,將新建字元串的地址賦給了局部變數str,因此此時局部變數str指向的地址為0x5012;而 ch[0] = 'g';
,則是將局部變數ch指向的字元數組中的ch[0]數據改變為g。
此時,運行語句System.out.print(ex.str+"and");
則輸出的是仍ex.str指向的String對象指向的字元串good
運行語句 System.out.print(ex.ch);
,輸出的是被局部變數改變的數組gbc,因為ex.ch和局部變數ch指向的地址相同。
1.3再次理解String和StringBuilder的不同之處
1.3.1String
package li.normalclass.stringbuilder;
public class TestStringAndBuilder {
public static void main(String[] args) {
String str5 = new String("北京");
str5 = str5.concat("故宮");
str5 = str5.concat("博物院");
System.out.println(str5);//北京故宮博物院
}
}
採用字面值的方式創建一個字元串時,JVM首先會去字元串池中查找是否存在"北京"這個對象,如果不存在,則在字元串池中創建"北京"這個對象,然後將池中"北京"這個對象的引用地址返回給"北京"對象的引用str5。使用concat()方法可以追加子字元串,但是String是不可變長序列,所以是實際上是在常量池重新創建了一個對象,並把追加的字元串連同原字元串一同賦值給新的對象,然後將新對象的引用地址返回給str5,這樣str5就指向了一個新的地址空間。每次使用concat()方法追加子串都會經歷上述過程,str5的指向不斷改變,最終會指向最後一次開闢的對象地址。
因此使用concat()追加子串的方法效率無疑是很低的,那麼有沒有一種辦法可以直接在創建的對象里添加子串呢?這就是我們要涉及到的StringBuilder類
1.3.2StringBuilder
package li.normalclass.stringbuilder;
public class TestStringAndBuilder {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("北京");
builder.append("故宮");
builder.append("地址為北京市東城區景山前街4號");
System.out.println(builder.toString());
}
}
StringBuilder對象指向的字元數組是可變的,在創建時的長度為創建時傳入的字元長度+16,之後每次增加字元進去,直到要增加的字元長度超過當前字元數組的記憶體空間容量,就會重新開闢一塊地址空間,容量為當前容量的兩倍再加上2,然後將StringBuilder對象指向新開闢的記憶體地址,而在棧記憶體中的builder存儲的地址保持不變,指向StringBuilder對象。
2.JDK8新日期類
針對JDK8以前的時間日期類設計的不足,比如不支持時區,線程不安全等,JDK8引入了java.time包來作為新的日期時間處理類。
類 | 描述 |
---|---|
Instant | 時間戳(瞬時時間,帶時區) |
LocalDate | 日期(比如:2018-09-24,不帶時區) |
LocalTime | 時間(比如:10:32:10,不帶時區) |
LocalDateTime | 日期時間(比如:2018-09-24 10:32:10,不帶時區) |
Duration | 兩個時間的差,精確到秒或納秒 |
Peroid | 兩個日期的差(精確到日) |
DateTimeFormatter | 日期時間格式化類(日期和字元串格式轉換) |
ZoneId | 時區 |
ZoneOffset | 時區偏移量(比如:+8:00) |
ZonedDateTime | 帶時區的日期時間 |
ChronoUnit | 日期枚舉類(在時間加減操作可用到) |
MonthDay | 月日 |
YearMonth | 年月 |
Clock | 代表時鐘(比如:獲取當前美國紐約的時間) |
例子:
package li.normalclass.date;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class TestNewDate {
public static void main(String[] args) {
//獲取當前的時間
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime);//2022-08-07T19:08:14.571
System.out.println(localDateTime.getDayOfWeek());//SUNDAY
//獲取指定的時間
LocalDateTime localDateTime1 = LocalDateTime.of(1111,11,11,11,11,11);
System.out.println(localDateTime1);//1111-11-11T11:11:11
System.out.println(localDateTime1.getDayOfYear());//315
System.out.println(localDateTime1.getDayOfWeek());//SATURDAY
//字元串轉換為日期類
String str = "1999年12月23日";
DateTimeFormatter dtfr = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
//String--->Date Parse
LocalDate localDate = LocalDate.parse(str,dtfr);
System.out.println(localDate);//1999-12-23
//Date--->String format
String datestr = localDate.format(dtfr);
System.out.println(datestr);//1999年12月23日
}
}