一、Java比較器
Java中的物件,正常情況下,只能進行比較:==或!=,不能使用>或<的
但是在開發場景中,我們需要對多個物件進行排序,言外之意,就需要比較物件的大小,
如何實作?使用兩個介面中的任何一個:Comparable或Comparator,
1.自然排序:使用Comparable介面
- 像String、包裝類等實作了Comparable介面,重寫了compareTo(obj)方法,給出了比較兩個物件大小的方式,
- 像String、包裝類重寫compareTo()方法以后,進行了從小到大的排列
- 重寫compareTo(obj)的規則:
- 如果當前物件this大于形參物件obj,則回傳正整數,
- 如果當前物件this小于形參物件obj,則回傳負整數,
- 如果當前物件this等于形參物件obj,則回傳零,
- 對于自定義類來說,如果需要排序,我們可以讓自定義類實作Comparable介面,重寫compareTo(obj)方法,在compareTo(obj)方法中指明如何排序
自定義類代碼舉例:
public class Goods implements Comparable{
private String name;
private double price;
//指明商品比較大小的方式:照價格從低到高排序,再照產品名稱從高到低排序
@Override
public int compareTo(Object o){
//System.out.println("**************");
if(o instanceof Goods){
Goods goods=(Goods)o;
//方式一:
if(this.price > goods.price){
return 1;
}else if(this.price < goods.price){
return -1;
}else{
//return 0;
return -this.name.compareTo(goods.name);
}
//方式二:
//return Double.compare(this.price,goods.price);
}
//return 0;
throw new RuntimeException("傳入的資料型別不一致!");
}
//getter、setter、toString()、構造器:省略
}
2.定制排序:使用Comparator介面
背景:當元素的型別沒實作java.lang.Comparable介面而又不方便修改代碼,或者實作了java.lang.Comparable介面的排序規則不適合當前的操作,那么可以考慮使用Comparator的物件來排序
重寫:compare(Object o1,Object o2)方法,比較o1和o2的大小:
如果方法回傳正整數,則表示o1大于o2;
如果回傳0,表示相等;
回傳負整數,表示o1小于o2,
代碼舉例:
Comparator com=new Comparator(){
//指明商品比較大小的方式:照產品名稱從低到高排序,再照價格從高到低排序
@Override
public int compare(Object o1,Object o2){
if(o1 instanceof Goods && o2 instanceof Goods){
Goods g1=(Goods)o1;
Goods g2=(Goods)o2;
if(g1.getName().equals(g2.getName())){
return -Double.compare(g1.getPrice(),g2.getPrice());
}else{
return g1.getName().compareTo(g2.getName());
}
}
throw new RuntimeException("輸入的資料型別不一致");
}
}
使用:
Arrays.sort(goods,com);
Collections.sort(coll,com);
new TreeSet(com);
兩種排序方式對比:
-
Comparable介面的方式一旦一定,保證Comparable介面實作類的物件在任何位置都可以比較大小,
-
Comparator介面屬于臨時性的比較,
二、JDK8之前日期時間API
1.獲取系統當前時間
//System類中的currentTimeMillis()
long time=System.currentTimeMillis();
//回傳當前時間與1970年1月1日0時0分0秒之間以毫秒為單位的時間差,
//稱為時間戳
System.out.println(time);
2.java.util.Date類與java.sql.Date類
/*
java.util.Date類
|---java.sql.Date類
1.兩個構造器的使用
>構造器一:Date():創建一個對應當前時間的Date物件
>構造器二:創建指定毫秒數的Date物件
2.兩個方法的使用
>toString():顯示當前的年、月、日、時、分、秒
>getTime():獲取當前Date物件對應的毫秒數,(時間戳)
3.java.sql.Date對應著資料庫中的日期型別的變數
>如何實體化
>如何將java.util.Date物件轉換為java.sql.Date物件
*/
@Test
public void test2(){
//構造器一:Date():創建一個對應當前時間的Date物件
Date date1=new Date();
System.out.println(date1.toString());//SatFeb1616:35:31GMT+08:002019
System.out.println(date1.getTime());//1550306204104
//構造器二:創建指定毫秒數的Date物件
Date date2=new Date(155030620410L);
System.out.println(date2.toString());
//創建java.sql.Date物件
java.sql.Date date3=new java.sql.Date(35235325345L);
System.out.println(date3);//1971-02-13
//如何將java.util.Date物件轉換為java.sql.Date物件
//情況一:
//Date date4=new java.sql.Date(2343243242323L);
//java.sql.Date date5=(java.sql.Date)date4;
//情況二:
Date date6=new Date();
java.sql.Date date7=new java.sql.Date(date6.getTime());
}
3.java.text.SimpleDataFormat類
SimpleDateFormat對日期Date類的格式化和決議
SimpleDateFormat的實體化:new+構造器
兩個操作:
格式化:日期--->字串
決議:格式化的逆程序,字串--->日期
//*************照指定的方式格式化和決議:呼叫帶參的構造器*****************
//SimpleDateFormat sdf1=new SimpleDateFormat("yyyyy.MMMMM.ddGGGhh:mmaaa");
SimpleDateFormat sdf1=new SimpleDateFormat("yyyy-MM-ddhh:mm:ss");
//格式化
String format1=sdf1.format(date);
System.out.println(format1);//2019-02-1811:48:27
//決議:要求字串必須是符合SimpleDateFormat識別的格式(通過構造器引數體現),
//否則,拋例外
Date date2=sdf1.parse("2020-02-1811:48:27");
System.out.println(date2);
練習:
/*
練習一:字串"2020-09-08"轉換為java.sql.Date
練習二:"三天打漁兩天曬網"1990-01-01xxxx-xx-xx打漁?曬網?
舉例:2020-09-08?總天數
總天數%5==1,2,3:打漁
總天數%5==4,0:曬網
總天數的計算?
方式一:(date2.getTime()-date1.getTime())/(1000*60*60*24)+1
方式二:1990-01-01-->2019-12-31+2020-01-01-->2020-09-08
*/
@Test
public void testExer()throws ParseException{
String birth="2020-09-08";
SimpleDateFormat sdf1=new SimpleDateFormat("yyyy-MM-dd");
Date date=sdf1.parse(birth);
//System.out.println(date);
java.sql.Date birthDate=new java.sql.Date(date.getTime());
System.out.println(birthDate);
}
4.Calendar類:日歷類、抽象類
//1.實體化
//方式一:創建其子類(GregorianCalendar的物件
//方式二:呼叫其靜態方法getInstance()
Calendar calendar=Calendar.getInstance();
//System.out.println(calendar.getClass());
//2.常用方法
//get()
int days=calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);
System.out.println(calendar.get(Calendar.DAY_OF_YEAR));
//set()
//calendar可變性
calendar.set(Calendar.DAY_OF_MONTH,22);
days=calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);
//add()
calendar.add(Calendar.DAY_OF_MONTH,-3);
days=calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);
//getTime():日歷類--->Date
Date date=calendar.getTime();
System.out.println(date);
//setTime():Date--->日歷類
Date date1=newDate();
calendar.setTime(date1);
days=calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);
三、JDK8中新日期時間API
1.日期時間API的迭代
第一代:jdk1.0Date類
第二代:jdk1.1Calendar類,一定程度上替換Date類
第三代:jdk1.8提出了新的一套API
2.前兩代存在的問題舉例
可變性:像日期和時間這樣的類應該是不可變的,
偏移性:Date中的年份是從1900開始的,而月份都從0開始,
格式化:格式化只對Date用,Calendar則不行,
此外,它們也不是執行緒安全的;不能處理閏秒等,
3.java8中新的日期時間API涉及到的包
java.time:包含值物件的基礎包
java.time.chrono:提供對不同的日歷系統的訪問
java.time.format:格式化和決議時間和日期
java.time.temporal:包括底層框架和擴展特性
java.time.zone:包含時區支持的類
說明:大多數開發者只會用到基礎包和format包,也可能會用到temporal包,因此,盡管有68個新的公開型別,大多數開發者,大概將只會用到其中的三分之一,
4.本地日期、本地時間、本地日期時間
對應使用:LocalDate/LocalTime/LocalDateTime
說明:
①分別表示使用ISO-8601日歷系統的日期、時間、日期和時間,它們提供了簡單的本地日期或時間,并不包含當前的時間資訊,也不包含與時區相關的資訊,
②LocalDateTime相較于LocalDate、LocalTime,使用頻率要高
③類似于Calendar
常用方法:
| 方法 | 描述 |
|---|---|
| now()/now(ZoneIdzone) | 靜態方法,根據當前時間創建物件脂定時區的物件 |
| of() | 靜態方法,根據指定日期間創建物件 |
| getDayOfMonth()/getDayOfYear() | 獲得月份天數(1-31)/獲得年份天(1-366) |
| getDayOfWeek() | 獲得星期幾(回傳一個DayOfWeek列舉值) |
| getMonth() | 獲得月份,回傳一個Month列舉值 |
| getMonthValue()/getYear() | 獲得月份(1-12)/獲得年份 |
| getHour()/getMinute()/getSecond() | 獲得當前物件對應的小時、分鐘、秒 |
| withDayOfMonth()/withDayOfYear()/withMonth/withYear() | 將月份天數、年份天數、月份、年份修改為指定的值并回傳新的物件 |
| plusDays(),plusWeeks(),plusMonths(),plusYeaers(),plusHours() | 向當前物件添加幾天、幾周、幾個月、幾年、幾小時 |
| minusMonths(),minusWeeks(),minusDays(),minusYear(),minusHours() | 從當前物件減去幾月、幾周、幾天、幾年、幾小時 |
5.時間點:Instant
時間線上的一個瞬時點,概念上講,它只是簡單的表示自1970年1月1日0時0分0秒(UTC開始的秒數,)
類似于java.util.Date類
常用方法:
| 方法 | 描述 |
|---|---|
| now() | 靜態方法,回傳默認UTC時區的的物件 |
| OfEpochMilli(longepochMilli) | 靜態方法,回傳在1970-01-0100:00:00基礎上加上指定毫秒數之后的Instant類的物件 |
| atOffset(ZoneOftsetoffset) | 結合即時的偏移來創建一個OffsetDateTime |
| toEpochMilli() | 回傳1970-01-0100:00:00到當前時間的毫秒數,即為時間戳 |
時間戳是指格林威治時間1970年01月01日00時00分00秒(北京時間1970年01月01日08時00分00秒)起至現在的總秒數,
6.日期時間格式化類:DateTimeFormatter
格式化或決議日期、時間
類似于SimpleDateFormat
常用方法:
實體化方式:
預定義的標準格式,如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
本地化相關的格式,如:ofLocalizedDateTime(FormatStyle.LONG)
自定義的格式,如:ofPattern(“yyyy-MM-ddhh:mm:ss”)
//重點:自定義的格式,如:ofPattern(“yyyy-MM-ddhh:mm:ss”)
DateTimeFormatter formatter3=DateTimeFormatter.ofPattern("yyyy-MM-ddhh:mm:ss");
//格式化
String str4=formatter3.format(LocalDateTime.now());
System.out.println(str4);//2019-02-1803:52:09
//決議
TemporalAccessor accessor=formatter3.parse("2019-02-1803:52:09");
System.out.println(accessor);
| 方法 | 描述 |
|---|---|
| ofPattern(String pattern) | 靜態方法,回傳一個指定字串格式的DateTimeFormatter |
| format(TemporalAccessort) | 格式化一個日期、時間,回傳字串 |
| parse(CharSequencetext) | 將指定格式的字符序列決議為一個日期、時間 |
7.其它API的使用
帶時區的日期時間:ZonedDateTime/ZoneId
舉例:
//ZoneId:類中包含了所的時區資訊
@Test
public void test1(){
//getAvailableZoneIds():獲取所的ZoneId
Set<String> zoneIds=ZoneId.getAvailableZoneIds();
for(Strings:zoneIds){
System.out.println(s);
}
System.out.println();
//獲取“Asia/Tokyo”時區對應的時間
LocalDateTimelocal DateTime=LocalDateTime.now(ZoneId.of("Asia/Tokyo"));
System.out.println(localDateTime);
}
//ZonedDateTime:帶時區的日期時間
@Test
public void test2(){
//now():獲取本時區的ZonedDateTime物件
ZonedDateTime zonedDateTime=ZonedDateTime.now();
System.out.println(zonedDateTime);
//now(ZoneIdid):獲取指定時區的ZonedDateTime物件
ZonedDateTime zonedDateTime1=ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
System.out.println(zonedDateTime1);
}
時間間隔:Duration:
用于計算兩個“時間”間隔,以秒和納秒為基準
| 方法 | 描述 |
|---|---|
| between(Temporalstart,Temporalend) | 靜態方法,回傳Duration物件,表示兩個時間的間隔 |
| getNano()/getSeconds() | 回傳時間間隔的納秒數/回傳時間間隔的秒數 |
| toDays()/toHours()/toMinutes()/toMillis()/toNanos() | 回傳時間間隔的天數、小時數、分鐘數、毫秒數、納秒數 |
舉例:
@Test
public void test3(){
LocalTime localTime=LocalTime.now();
LocalTime localTime1=LocalTime.of(15,23,32);
//between():靜態方法,回傳Duration物件,表示兩個時間的間隔
Duration duration=Duration.between(localTime1,localTime);
System.out.println(duration);
System.out.println(duration.getSeconds());
System.out.println(duration.getNano());
LocalDateTime localDateTime=LocalDateTime.of(2016,6,12,15,23,32);
LocalDateTime localDateTime1=LocalDateTime.of(2017,6,12,15,23,32);
Duration duration1=Duration.between(localDateTime1,localDateTime);
System.out.println(duration1.toDays());
}
日期間隔:Period:
用于計算兩個“日期”間隔,以年、月、日衡量
| 方法 | 描述 |
|---|---|
| between(LocalDatestart,LocalDateend) | 靜態方法,回傳Period物件,表示兩個本地日期的間隔 |
| getYears()/getMonths()/getDays() | 回傳此期間的年數、月數、天數 |
| withYears(intyears)/withMonths(intmonths)/withDays(intdays) | 回傳設定間隔定年、月、日數以后的Period物件 |
舉例:
@Test
public void test4(){
LocalDate localDate=LocalDate.now();
LocalDate localDate1=LocalDate.of(2028,3,18);
Period period=Period.between(localDate,localDate1);
System.out.println(period);
System.out.println(period.getYears());
System.out.println(period.getMonths());
System.out.println(period.getDays());
Period period1 = period.withYears(2);
System.out.println(period1);
}
日期時間校正器:TemporalAdjuster
舉例:
@Test
public void test5(){
//獲取當前日期的下一個周日是哪天?
TemporalAdjuster temporalAdjuster=TemporalAdjusters.next(DayOfWeek.SUNDAY);
LocalDateTime localDateTime=LocalDateTime.now().with(temporalAdjuster);
System.out.println(localDateTime);
//獲取下一個作業日是哪天?
LocalDate localDate=LocalDate.now().with(new TemporalAdjuster(){
@Override
public Temporaladjust Into(Temporal temporal){
LocalDate date=(LocalDate)temporal;
if(date.getDayOfWeek().equals(DayOfWeek.FRIDAY)){
return date.plusDays(3);
}elseif(date.getDayOfWeek().equals(DayOfWeek.SATURDAY)){
return date.plusDays(2);
}else{
return date.plusDays(1);
}
}
});
System.out.println("下一個作業日是:"+localDate);
}
四、String類
String:字串,使用一對""引起來表示,
-
String宣告為final的,不可被繼承
-
String實作了Serializable介面:表示字串是支持序列化的,實作了Comparable介面:表示String可以比較大小
-
String內部定義了finalchar[]value用于存盤字串資料
-
通過字面量的方式(區別于new給一個字串賦值,此時的字串值宣告在字串常量池中),
-
字串常量池中是不會存盤相同內容(使用String類的equals()比較,回傳true)的字串的,
1.String的不可變性
當對字串重新賦值時,需要重寫指定記憶體區域賦值,不能使用原有的value進行賦值,
當對現的字串進行連接操作時,也需要重新指定記憶體區域賦值,不能使用原有的value進行賦值,
當呼叫String的replace()方法修改指定字符或字串時,也需要重新指定記憶體區域賦值,不能使用原有的value進行賦值,
舉例:
String s1="abc";//字面量的定義方式
String s2="abc";
s1="hello";
System.out.println(s1==s2);//比較s1和s2的地址值
System.out.println(s1);//hello
System.out.println(s2);//abc
System.out.println("*****************");
String s3="abc";
s3+="def";
System.out.println(s3);//abcdef
System.out.println(s2);
System.out.println("*****************");
String s4="abc";
String s5=s4.replace('a','m');
System.out.println(s4);//abc
System.out.println(s5);//mbc
String str1 = "hello";
String str2 = "hello";
str1 = "world";
System.out.println(str1 == str2);//比較str1和str2的地址值
圖示

2.String實體化的不同方式
方式一:通過字面量定義的方式
方式二:通過new+構造器的方式
舉例
//通過字面量定義的方式:此時的s1和s2的資料javaEE宣告在方法區中的字串常量池中,
String s1="javaEE";
String s2="javaEE";
//通過new+構造器的方式:此時的s3和s4保存的地址值,是資料在堆空間中開辟空間以后對應的地址值,
String s3=newString("javaEE");
String s4=newString("javaEE");
System.out.println(s1==s2);//true
System.out.println(s1==s3);//false
System.out.println(s1==s4);//false
System.out.println(s3==s4);//false
面試題
問:String str1=new String("hello");方式創建物件,在記憶體中創建了幾個物件?
答:兩個:一個是堆空間中new結構,另一個是char[]對應的常量池中的資料:"hello"
圖示
String str1 = "hello";
String str2 = new String("hello");
//它們們的區別

3.字串拼接方式賦值的對比
常量與常量的拼接結果在常量池,且常量池中不會存在相同內容的常量,
只要其中一個是變數,結果就在堆中,
如果拼接的結果呼叫intern()方法,回傳值就在常量池中
舉例
String s1="javaEE";
String s2="hadoop";
String s3="javaEEhadoop";
String s4="javaEE"+"hadoop";
String s5=s1+"hadoop";
String s6="javaEE"+s2;
String s7=s1+s2;
System.out.println(s3==s4);//true
System.out.println(s3==s5);//false
System.out.println(s3==s6);//false
System.out.println(s3==s7);//false
System.out.println(s5==s6);//false
System.out.println(s5==s7);//false
System.out.println(s6==s7);//false
String s8=s6.intern();//回傳值得到的s8使用的常量值中已經存在的“javaEEhadoop”
System.out.println(s3==s8);//true
//****************************
String s1="javaEEhadoop";
String s2="javaEE";
String s3=s2+"hadoop";
System.out.println(s1==s3);//false
final String s4="javaEE";//s4:常量
String s5=s4+"hadoop";
System.out.println(s1==s5);//true
4.常用方法
| 方法 | 描述 |
|---|---|
| int length() | 回傳字串的長度:return value.length |
| char charAt(int index) | 回傳某索引處的字符return value[index] |
| boolean isEmpty() | 判斷是否是空字串:return value.length==0 |
| String toLowerCase() | 使用默認語言環境,將String中的所有字符轉換為小寫 |
| String toUpperCase() | 使用默認語言環境,將String中的所有字符轉換為大寫 |
| String trim() | 回傳字串的副本,忽略前導空白和尾部空白 |
| boolean equals(Object obj) | 比較字串的內容是否相同 |
| boolean equalsIgnoreCase(String anotherString) | 與equals方法類似,忽略大小寫 |
| String concat(String str) | 將指定字串連接到此字串的結尾,等價于用“+” |
| int compareTo(String anotherString) | 比較兩個字串的大小 |
| String substring(int beginIndex) | 回傳一個新的字串,它是此字串的從beginIndex開始截取到最后的一個子字串, |
| String substring(int beginIndex,int endIndex) | 回傳一個新字串,它是此字串從beginIndex開始截取到endIndex(不包含)的一個子字串, |
| 方法 | 描述 |
|---|---|
| boolean endsWith(String suffix) | 測驗此字串是否以指定的后綴結束 |
| boolean startsWith(String prefix) | 測驗此字串是否以指定的前綴開始 |
| boolean startsWith(String prefix, int toffset) | 測驗此字串從指定索引開始的子字串是否以指定前綴開始 |
| 方法 | 描述 |
|---|---|
| boolean contains(CharSequence s) | 當且僅當此字串包含指定的 char 值序列時,回傳 true |
| int indexOf(String str) | 回傳指定子字串在此字串中第一次出現處的索引 |
| int indexOf(String str, int fromIndex) | 回傳指定子字串在此字串中第一次出現處的索引,從指定的索引開始 |
| int lastIndexOf(String str) | 回傳指定子字串在此字串中最右邊出現處的索引 |
| int lastIndexOf(String str, int fromIndex) | 回傳指定子字串在此字串中最后一次出現處的索引,從指定的索引開始反向搜索 |
注意:indexOf和lastIndexOf方法如果未找到都是回傳-1
替換:
| 方法 | 描述 |
|---|---|
| String replace(char oldChar, char newChar) | 回傳一個新的字串,它是通過用 newChar 替換此字串中出現的所 oldChar 得到的, |
| String replace(CharSequence target, CharSequence replacement) | 使用指定的字面值替換序列替換此字串所匹配字面值目標序列的子字串, |
| String replaceAll(String regex, String replacement) | 使用給定的 replacement 替換此字串所匹配給定的正則運算式的子字串, |
| String replaceFirst(String regex, String replacement) | 使用給定的 replacement 替換此字串匹配給定的正則運算式的第一個子字串, |
匹配:
| 方法 | 描述 |
|---|---|
| boolean matches(String regex) | 告知此字串是否匹配給定的正則運算式, |
切片:
| 方法 | 描述 |
|---|---|
| String[] split(String regex) | 根據給定正則運算式的匹配拆分此字串, |
| String[] split(String regex, int limit) | 根據匹配給定的正則運算式來拆分此字串,最多不超過limit個,如果超過了,剩下的全部都放到最后一個元素中, |
5.String與其它結構的轉換
與基本資料型別、包裝類之間的轉換
String --> 基本資料型別、包裝類:呼叫包裝類的靜態方法:parseXxx(str)
基本資料型別、包裝類 --> String:呼叫String多載的valueOf(xxx)
@Test
public void test1(){
String str1 = "123";
// int num = (int)str1;//錯誤的
int num = Integer.parseInt(str1);
String str2 = String.valueOf(num);//"123"
String str3 = num + "";
System.out.println(str1 == str3);
}
與字符陣列之間的轉換
String --> char[]:呼叫String的toCharArray()
char[] --> String:呼叫String的構造器
@Test
public void test2(){
String str1 = "abc123"; //題目: a21cb3
char[] charArray = str1.toCharArray();
for (int i = 0; i < charArray.length; i++) {
System.out.println(charArray[i]);
}
char[] arr = new char[]{'h','e','l','l','o'};
String str2 = new String(arr);
System.out.println(str2);
}
與位元組陣列之間的轉換
編碼:String --> byte[]:呼叫String的getBytes()
解碼:byte[] --> String:呼叫String的構造器
編碼:字串 -->位元組 (看得懂 --->看不懂的二進制資料)
解碼:編碼的逆程序,位元組 --> 字串 (看不懂的二進制資料 ---> 看得懂
說明:解碼時,要求解碼使用的字符集必須與編碼時使用的字符集一致,否則會出現亂碼,
@Test
public void test3() throws UnsupportedEncodingException {
String str1 = "abc123中國";
byte[] bytes = str1.getBytes();//使用默認的字符集,進行編碼,
System.out.println(Arrays.toString(bytes));
byte[] gbks = str1.getBytes("gbk");//使用gbk字符集進行編碼,
System.out.println(Arrays.toString(gbks));
System.out.println("******************");
String str2 = new String(bytes);//使用默認的字符集,進行解碼,
System.out.println(str2);
String str3 = new String(gbks);
System.out.println(str3);//出現亂碼,原因:編碼集和解碼集不一致!
String str4 = new String(gbks, "gbk");
System.out.println(str4);//沒出現亂碼,原因:編碼集和解碼集一致!
}
與StringBuffer、StringBuilder之間的轉換
String -->StringBuffer、StringBuilder:呼叫StringBuffer、StringBuilder構造器
StringBuffer、StringBuilder -->String:①呼叫String構造器;②StringBuffer、StringBuilder的toString()
6.JVM中字串常量池存放位置說明
jdk 1.6 (jdk 6.0 ,java 6.0):字串常量池存盤在方法區(永久區)
jdk 1.7:字串常量池存盤在堆空間
jdk 1.8:字串常量池存盤在方法區(元空間)
7.常見演算法題目的考查:
-
模擬一個trim方法,去除字串兩端的空格,
-
將+一個字串進行反轉,將字串中指定部分進行反轉,比如“abcdefg”反轉為”abfedcg”
-
獲取一個字串在另一個字串中出現的次數,
比如:獲取“ ab”在 “abkkcadkabkebfkabkskab” 中出現的次數
- 獲取兩個字串中最大相同子串,比如:
str1 = "abcwerthelloyuiodef“;str2 = "cvhellobnm"
提示:將短的那個串進行長度依次遞減的子串與較長的串比較,
- 對字串中字符進行自然順序排序,
提示:
①字串變成字符陣列,
②對陣列排序,選擇,冒泡,Arrays.sort();
③將排序后的陣列變成字串,
五、StringBuffer、StringBuilder
1.String、StringBuffer、StringBuilder三者的對比
String:不可變的字符序列;底層使用char[]存盤
StringBuffer:可變的字符序列;執行緒安全的,效率低;底層使用char[]存盤
StringBuilder:可變的字符序列;jdk5.0新增的,執行緒不安全的,效率高;底層使用char[]存盤
2.StringBuffer與StringBuilder的記憶體決議
以StringBuffer為例:
String str = new String();//char[] value = https://www.cnblogs.com/java-blogs/p/new char[0];
String str1 = new String("abc");//char[] value = https://www.cnblogs.com/java-blogs/p/new char[]{'a','b','c'};
StringBuffer sb1 = new StringBuffer();//char[] value = https://www.cnblogs.com/java-blogs/p/new char[16];底層創建了一個長度是16的陣列,
System.out.println(sb1.length());//0
sb1.append('a');//value[0] = 'a';
sb1.append('b');//value[1] = 'b';
StringBuffer sb2 = new StringBuffer("abc");//char[] value = https://www.cnblogs.com/java-blogs/p/new char["abc".length() + 16];
//問題1. System.out.println(sb2.length());//3
//問題2. 擴容問題:如果要添加的資料底層陣列盛不下了,那就需要擴容底層的陣列,
//默認情況下,擴容為原來容量的2倍 + 2,同時將原陣列中的元素復制到新的陣列中,
//指導意義:開發中建議大家使用:StringBuffer(int capacity) 或 StringBuilder(int capacity)
3.對比String、StringBuffer、StringBuilder三者的執行效率
從高到低排列:StringBuilder > StringBuffer > String
4.StringBuffer、StringBuilder中的常用方法
| 作用 | 方法 |
|---|---|
| 增: | append(xxx) |
| 刪: | delete(int start,int end) |
| 改: | setCharAt(int n ,char ch) / replace(int start, int end, String str) |
| 查: | charAt(int n ) |
| 插: | insert(int offset, xxx) |
| 長度: | length(); |
| 遍歷: | for() + charAt() / toString() |
| 截取: | subString(int start,int end) |
六、其他類
1.System類
System類代表系統,系統級的很多屬性和控制方法都放置在該類的內部,該類位于java.lang包,
由于該類的構造器是private的,所以無法創建該類的物件,也就是無法實體化該類,其內部的成員變數和成員方法都是static的,所以也可以很方便的進行呼叫,
方法:
native long currentTimeMillis();
void exit(int status);
void gc();
String getProperty(String key);
2.Math類
java.lang.Math提供了一系列靜態方法用于科學計算,其方法的引數和回傳值型別一般為double型,
3.BigInteger類、BigDecimal類
說明:
① java.math包的BigInteger可以表示不可變的任意精度的整數,
② 要求數字精度比較高,用到java.math.BigDecimal類
代碼舉例:
Public void testBigInteger(){
BigInteger bi = new BigInteger("12433241123");
BigInteger bd = new BigDecimal("12435.351");
BigDecimal bd2 = new BigDecmal("11");
System.out.println(bi);
//System.out.println(bd.divide(bd2));
System.out.println(bd.divide(bd2,BigDecimal.ROUND_HALF_UP));
System.out.println(bd.divide(bd2,15,BigDecimal.ROUND_HALF_UP));
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/433276.html
標籤:Java
上一篇:Java基礎語法(二)
