package com.rayNotes;
import org.junit.Test;
/**
* - 字符串是一個特殊的對象。 - 字符串一旦初始化就不可以被改變。
*
* @author liujun
* @since 2018.1
*/
public class StringTest {
/**
* - str在內存中只有一個對象,str1在內存中有兩個對象。 - test01()
* :String類複寫了Object類中的equals(),該方法用於判斷字符串的內容是否相同。
*/
public static void main(String[] args) {
String str1 = "abcd"; // str是一個類類型變量,"abcd"是一個對象
String str2 = new String("abcd");
System.out.println("----------test01---------start---------");
StringTest st = new StringTest();
st.test01(str1, str2);// 比較
System.out.println("----------test02---------start---------");
String str3 = "abacddd";
st.test02(str3);// 獲取
System.out.println("----------test03---------start---------");
st.test03(str3, str2);// 拼接
System.out.println("----------test04---------start---------");
st.test04();// 判斷
System.out.println("----------test05---------start---------");
st.test05();// 轉換
System.out.println("----------test06---------start---------");
st.test06();// 替換
System.out.println("----------test07---------start---------");
st.test07();// 切割
System.out.println("----------test08---------start---------");
st.test08();// 子串
System.out.println("----------test09---------start---------");
st.test09();//字符串內部轉換、比較
}
/**
* TODO:字符串內部轉換、比較
*/
// @Test
public void test09() {
String str = "a b c d e f g h ij k l m n";
System.out.println("str.toUpperCase():" + str.toUpperCase());
String str1 = " c d e f ";
System.out.println("str1:" + str1.toString());
System.out.println("str1.trim():" + str1.trim());
System.out.println("CompareTo()--------");
String s1 = "abc";
String s2 = "abcd";
String s3 = "abcdfg";
String s4 = "1bcdfg";
String s5 = "cdfg";
System.out.println(s1.compareTo(s2)); // -1 (前面相等,s1長度小1)
System.out.println(s1.compareTo(s3)); // -3 (前面相等,s1長度小3)
System.out.println(s1.compareTo(s4)); // 48 ("a"的ASCII碼是97,"1"的的ASCII碼是49,所以返回48)
System.out.println(s1.compareTo(s5)); // -2 ("a"的ASCII碼是97,"c"的ASCII碼是99,所以返回-2)
}
/**
* TODO : 子串
*/
// @Test
public void test08() {
String str = "a b c d e f g h ij k l m n";
System.out.println("原來的字符串:" + str);
System.out.println("str.substring(10,12):" + str.substring(10, 12));// 從11 開始,到12結束; 如果超出長度則: 越界異常.
System.out.println("str.substring(0, str.length()):" + str.substring(0, str.length()));// 從頭到尾
}
/**
* TODO:切割
*/
// @Test
public void test07() {
String str = "a b c d e f g h ij k l m n ";// 最後還有一個空格
String[] strs = str.split(" ");
for (String ss : strs) {
System.out.print(ss + ",");
}
System.out.println();
/**
* - 如果該限制 n 大於 0,則模式將被最多應用 n - 1 次,數組的長度將不會大於 n。 - 如果 n
* 爲非正,那麼模式將被應用盡可能多的次數,而且數組可以是任何長度。 - 如果 n 爲
* 0,那麼模式將被應用盡可能多的次數,數組可以是任何長度,並且結尾空字符串將被丟棄。
*/
String[] strs1 = str.split(" ", -1);
for (String ss : strs1) {
System.out.print(ss + ",");
}
}
/**
* TODO:替換 String replace(oldchar, newchar);
*/
// @Test
public void test06() {
String s = "hello java";
// String s1 = s.replace('q', 'n'); // 如果要替換的字符不存在,返回的還是原串
String oldworld = "java";
String newWorld = "world";
String s1 = s.replace(oldworld, newWorld);
System.out.println("s1.toString():" + s1.toString());
}
/**
* TODO: 轉換
*/
// @Test
public void test05() {
/**
* - 1. 將 字符數組 轉換成 字符串
*/
char[] cr = { 'i', 'm', 'a', 'c', 'h', 'a', 'r' };
String str = "imaString";
byte[] bt = { 'i', 'm', 'a', 'b', 'y', 't', 'e' };
/**
* - 1.1 構造方法:
*/
String schar = new String(cr);// 底層通過Arrays.copyof()實現
System.out.println("schar.toString():" + schar.toString());
final int offset = 2;
final int count = 3;
String partChar = new String(cr, offset, count);// cr數據,從offset開始,到count 結束
System.out.println("partChar.toString():" + partChar.toString());
/**
* - 1.2 靜態方法:
*/
String schar1 = String.copyValueOf(cr, offset, count);
System.out.println("schar1.toString():" + schar1.toString());
String scharValue1 = String.valueOf(cr, offset, count);
System.out.println("scharValue1.toString():" + scharValue1.toString());
/**
* - 2. 將字符串轉換成字符數組
*/
char[] strValue = str.toCharArray();
System.out.println("strValue.length:" + strValue.length);
/**
* - 3. 將字節數組轉成字符串 - 再轉回來
*/
String strbyte = new String(bt);
System.out.println("strbyte.toString():" + strbyte.toString());
System.out.println("str.getBytes():" + str.getBytes());
/**
* - 4. 基本數據類型轉成字符串 - 通過 valueOf() - 10 +"" == String.valueOf(10); int--->String
*/
}
/**
* TODO:判斷
*
* @param str
* @param str2
*/
// @Test
public void test04() {
String str = "StringTest.java";
System.out.println("str.isEmpty():" + str.isEmpty());// 原理就是判斷長度是否爲0,是否空
// 特殊之處:indexOf(str):可以索引str第一次出現的位置,如果返回-1,表示該str不在字符串中存在,
// 所以,也可以用於對指定字符串判斷是否包含,而且該方法既可以判斷,又可以獲取出現的位置。
System.out.println("str.contains(\"Test\") :" + str.contains("Test"));// 是否包含該String
int toffset = 0;
String strPart = "String";
System.out.println("str.startsWith(strPart, toffset): " + str.startsWith(strPart, toffset));// 從 toffset 開始,是否以
// strPart 開頭
String strEnd = ".java";
System.out.println("str.endsWith(strEnd):" + str.endsWith(strEnd));// 字符串是否是以指定內容結尾
String str2 = "stringtest.java";
System.out.println("str.equals(str2):" + str.equals(str2));// 比較 值 是否 same
System.out.println("str.equalsIgnoreCase(str2):" + str.equalsIgnoreCase(str2));// 同上,忽略大小寫
}
/**
* TODO: 拼接
*
* @param str,str2
*/
// @Test
public void test03(String str, String str2) {
/**
* - 1、+ - 2、concat - 當兩個量都爲String類型且值不爲null時,可以用concat方式。 - 3、append -
* 當需要拼接至少三個量的時候,StringBuffer#append() 以避免臨時字符串的產生
*
* - StringBuffer大多數情況(包括append操作)線程安全。 -
* 若不會出現多線程同時對一實例併發進行append操作,建議使用非線程安全的StringBuilder以獲得更好性能 StringBuffer
* buf=new StringBuffer() buf.append("a"); if(someCondition){ buf.append("b"); }
* buf.append("c"); String d=buf.toString();
*/
//
System.out.println(str + str2);
System.out.println(str.concat(str2));
StringBuffer strb = new StringBuffer();
System.out.println(strb.append(str2).append(str).toString());
StringBuilder strd = new StringBuilder();
System.out.println(strd.append(str2).append(str).toString());
/**
* 引用 <https://www.cnblogs.com/Wfei/p/3248922.html>
* StringBuffer.append()所改變的是源引用的值,不會依賴於方法返回值,
* 而String.concat()在進行字符串拼接的時候,會產生很多的臨時對象來保存
*
* - 最後在拼接結束後,需要把這個結果臨時對象進行返回給接收值進行再指向, 需要依賴於方法的返回值,執行的效率也會隨着字符數的增加而降低,不是真正的引用源
* 總結: - 在所使用的字符串需要經常變更的情況下,使用StringBuffer效率更高,
* 可以使用StringBuffer進行字符串的變更操作,操作完成後再還給String, - 操作方法:String -> StringBuffer ->
* 更改字符串 -> String
*/
forTest03Change(str, strb);
System.out.println(str);
System.out.println(strb);
/**
* 拓展: 字符串拼接共五種方法: 1. 加號 “+”
*
* 2. String contact() 方法
*
* 3. StringUtils.join() 方法
*
* 4. StringBuffer append() 方法
*
* 5. StringBuilder append() 方法
*
*
* 1. 方法1 加號 “+” 拼接 和 方法2 String contact() 方法 適用於小數據量的操作,代碼簡潔方便,加號“+”
* 更符合我們的編碼和閱讀習慣;
*
* 2. 方法3 StringUtils.join() 方法
* 適用於將ArrayList轉換成字符串,就算90萬條數據也只需68ms,可以省掉循環讀取ArrayList的代碼;
*
* 3. 方法4 StringBuffer append() 方法 和 方法5 StringBuilder append() 方法
* 其實他們的本質是一樣的,都是繼承自AbstractStringBuilder,效率最高,大批量的數據處理最好選擇這兩種方法。
*
* 4. 方法1 加號 “+” 拼接 和 方法2 String contact() 方法 的時間和空間成本都很高(分析在本文末尾),不能用來做批量數據的處理。
*
*
* 1、其實每次調用contact()方法就是一次數組的拷貝,雖然在內存中是處理都是原子性操作,速度非常快, -
* 但是,最後的return語句會創建一個新String對象,限制了concat方法的速度。
*
* 2、StringBuffer 和 StringBuilder 的append方法都繼承自AbstractStringBuilder,
* 整個邏輯都只做字符數組的加長,拷貝,到最後也不會創建新的String對象,所以速度很快,
* 完成拼接處理後在程序中用strBuffer.toString()來得到最終的字符串。
*
*
* 3、 字符串的加號“+” 方法, 雖然編譯器對其做了優化,使用StringBuilder的append方法進行追加,
* 但是每循環一次都會創建一個StringBuilder對象,且都會調用toString方法轉換成字符串,所以開銷很大。 - 注:執行一次字符串“+”,相當於
* str = new StringBuilder(str).append("a").toString(); - 循環使用則 直接使用builder
* ,其餘情況 +
*
* 4、 本文開頭的地方統計了時間開銷,根據上述分析再想想空間的開銷。常說拿空間換時間,反過來是不是拿時間換到了空間呢,
* 但是在這裏,其實時間是消耗在了重複的不必要的工作上(生成新的對象,toString方法), 所以對大批量數據做處理時,加號“+” 和 contact
* 方法絕對不能用,時間和空間成本都很高。
*
*
* String:適用於少量的字符串操作的情況
*
* StringBuilder:適用於單線程下在字符緩衝區進行大量操作的情況
*
* StringBuffer:適用多線程下在字符緩衝區進行大量操作的情況(99.99999%情況下不用)
*/
}
public void forTest03Change(String str, StringBuffer str2) {
str.concat("contact");
str2.append("append");
}
/**
* TODO: 獲取
*
* @param str
*/
@Test
public void test02(String str) {
// abacddd
int localAt = 2;
int fromIndex = 1;
String strLocalAt = "a";
System.out.println(str.charAt(localAt));// 根據位置獲取位置上某個字符 ,從0 開始計數
// 索引,即使越界也沒事,找不到返回 -1(也可藉此來直接用來判斷),不存在該位置 則略過
// System.out.println(str.contains("a"));//字符串中是否包含某一個子串:boolean
System.out.println(str.indexOf(strLocalAt, fromIndex));// 返回的是 從fromIndex指定位置開始 ,strLocalAt/localAt
// 在字符串中第一次出現的位置
System.out.println(str.lastIndexOf(strLocalAt, fromIndex));// 反向
}
// @Test
public void test01(String str1, String str2) {
System.out.println(str1 == str2);// false,比較的對象
System.out.println(str1.equals(str2));// true,比較的值
}
}
API之String類
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.