從頭開始學JDK String

2021-10-17 14:10:36 字數 4640 閱讀 3570

目錄

* string #倒序

* string #建構函式

* string #equals

* string #記憶體

* string #hashcode

* string #startswith

* string #endwith

* string #indexof

* string #lastindexof

* string #substring(int beginindex)

* string static#join(string separator , string... elements)

* string #split(string regex)

* string #replace(char,char)

* string #replacefirst(string regex , string replacement)

* string #matches(string regex) 

* string #contains

public static boolean reverseequals(string str)
下面的**是不允許使用任何其它類的實現,前後分別建立了乙個指標。

}string字串內部維護了乙個char陣列。不管是哪個建構函式,最終都是解析成char陣列。

public string(string original) 

public string()

public string(char value)

public string(stringbuilder builder)

*  衍生arrays.copyof(陣列,新長度)arrays.copyof(基本型別,新長度) ,這個方法過載了很多種,就是把乙個基本型別的陣列的值,複製乙個新的長度的陣列,如果長度大於以前的陣列,則用預設值填充。

如果是引用資料型別的話,那麼就是重新建立乙個容器,但是裡面的元素是淺複製,指向的與源陣列是同乙個物件。

*  衍生arrays.equals(a,b)比較的是每個陣列對應的角標上的元素,呼叫它們的equals()方法。     

class arrays  

public static boolean equals(object a, object a2)

string類重寫了equals方法,與另外乙個字串類中char陣列(引用名為value),比較的是它們的value陣列是否每個成員都一樣。

ps:寫到這裡的時候,我突然想,為什麼jdk大佬不直接用arrays#equals方法直接比較,原來arrays是jdk1.2開始使用的。。水一下

class string

public boolean equals(object anobject)

if (anobject instanceof string)

return true;}}

return false;

}

如果直接使用 == ,比較的是字串物件的記憶體位址。

string a = new string("abc");建立了兩個字串物件,乙個是在字串常量池裡,另外乙個在堆記憶體裡。

建構函式中有乙個 new string(源字串),把源字串的 char value(基本資料型別)直接賦值給這個新構造的字串物件。

它們兩個使用" == "比較的話,返回false,因為記憶體不同。

如果使用 #quals(object)方法比較的話,返回true。因為內部的char陣列是一樣的。

string a = "abc";

string b = new string(a);

system.out.println(a == b);//記憶體位址不一樣false

system.out.println(a.equals(b));//char陣列一樣true

system.out.println(a == b.intern());返回了字串常量池的a,true

對char陣列的每個元素進行運算,近似理解成對每個字元的ascii碼 與 31做運算,並求和。

a的ascii碼是97,b的是98。

為什麼使用31作為乘子,是因為31作為乙個既不太大又不太小的乘子,計算出來的hashcode值範圍處於乙個「適中」的區間,能夠很好的降低雜湊衝突

* 衍生 為什麼我們在使用hashmap的時候總是用string做key?

因為字串是不可變的,當建立字串時,它的它的hashcode被快取下來,不需要再次計算。因為hashmap內部實現是通過key的hashcode來確定value的儲存位置,所以相比於其他物件更快。這也是為什麼我們平時都使用string作為hashmap物件。

本質上比較的是char陣列的前幾個字元是否相同。原始碼中果然也是建立了兩個指標。

endwith從另外乙個角度看就是startswith。指標從 【value.length - suffix.value.length】開始。

如果是乙個字串,找到這個字串第一次出現的地方。匹配的還是char value。

string a = "abcabcadef";

//找到ca第一次出現的位置,並且擷取它後面的字串

string s = "ca";

system.out.println(a.indexof(s));

system.out.println(a.substring(a.indexof(s) + s.length()));

int fromindex = 3;

system.out.println(a.substring( a.indexof(s,fromindex) + s.length()));//def

從右向左遍歷char

建立乙個新的物件,原始碼上首先通過beginindex確定了要擷取的子字串長度是多少,然後使用arrays.copyofrange方法複製char

public string substring(int beginindex) 

string(char,int beginindex,int count)

第乙個是分隔符,第二個是可變引數。源**中使用的是jdk1.8出現得stringjoiner類,該類是物件導向編碼的典範。

public static string join(charsequence delimiter, charsequence... elements) 

return joiner.tostring();

}public final class stringjoiner ...

private final string prefix;

private final string delimiter;

private final string suffix;

private string emptyvalue;

public stringjoiner(charsequence delimiter,

charsequence prefix,

charsequence suffix)

按照指定正則分割,返回string

string a = "a,b,c,d,e";

//[a, b, c, d, e]

system.out.println(arrays.tostring(a.split(",")));

把源字串的char中的所有字元替換成另外乙個,並且返回乙個新的字串物件。

public string replace(char oldchar, char newchar)
把符合正則的第一處,替換成replacement。當然還有replaceall(string regex,string replacement)

是否符合指定正則

是否包含,原始碼思路:indexof指定字串,看是否返回 大於 -1 。 -1代表沒找到

從頭開始學MFC

一 win32專案設計 類似於console控制台程式,win32視窗程式的入口函式類似於main 函式,稱之為winmain函式 int winapi wwinmain hinstance hinstance,例項控制代碼 hinstance hprevinstance,前乙個例項控制代碼 pws...

從頭開始學Redis

第一章 概述 1.1 redis之簡介 1.2 redis之安裝 第二章 api 2.1 redisapi之簡介 2.2 redisapi之string 2.3 redisapi之hash 2.4 redisapi之list 2.5 redisapi之set 2.6 redisapi之zset 第三...

從頭開始學演算法 快速排序

需求 給定陣列從小到大排序快速排序 思路 1 選定第乙個數字為標識flag,將陣列分成兩部分,一部分比flag大,一部分比flag小,2 再將得到的兩部分分別進行1,直到完成 第一步實現 1 從後向前,找到比flag小的,放到空中,自身空出來 2 從前向後,找到比flag大的,放到空中,自身空出來 ...