一慰丛、字符串相關(guān)類
1.String的特性
String類:代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作 為此類的實(shí)例實(shí)現(xiàn)罢防。
String是一個(gè)final類敬扛,不可被繼承粥诫,代表不可變的字符序列。
?字符串是常量蔑水,用雙引號(hào)引起來表示邢锯。它們的值在創(chuàng)建之后不能更改。
String對(duì)象的字符內(nèi)容是存儲(chǔ)在一個(gè)字符數(shù)組value[]中的搀别。
public final class String
? implements java.io.Serializable, Comparable<String>, CharSequence {
? /** The value is used for character storage. */
? private final char value[];
? /** Cache the hash code for the string */
? private int hash; // Default to 0
String:字符串丹擎,使用一對(duì)""引起來表示。
1.String聲明為final的歇父,不可被繼承
2.String實(shí)現(xiàn)了Serializable接口:表示字符串是支持序列化的蒂培。
? ? ? ? 實(shí)現(xiàn)了Comparable接口:表示String可以比較大小
3.String內(nèi)部定義了final char[] value用于存儲(chǔ)字符串?dāng)?shù)據(jù)
4.String:代表不可變的字符序列。簡稱:不可變性庶骄。
? ? 體現(xiàn):(1).當(dāng)對(duì)字符串重新賦值時(shí)毁渗,需要重寫指定內(nèi)存區(qū)域賦值,不能使用原有的value進(jìn)行賦值单刁。
? ? ? ? (2). 當(dāng)對(duì)現(xiàn)有的字符串進(jìn)行連接操作時(shí)灸异,也需要重新指定內(nèi)存區(qū)域賦值,不能使用原有的value進(jìn)行賦值羔飞。
? ? ? ? (3). 當(dāng)調(diào)用String的replace()方法修改指定字符或字符串時(shí)肺樟,也需要重新指定內(nèi)存區(qū)域賦值,不能使用原有的value進(jìn)行賦值逻淌。
5.通過字面量的方式(區(qū)別于new)給一個(gè)字符串賦值么伯,此時(shí)的字符串值聲明在字符串常量池中。
6.字符串常量池中是不會(huì)存儲(chǔ)相同內(nèi)容的字符串的卡儒。
2.String的實(shí)例化方式
方式一:通過字面量定義的方式
方式二:通過new + 構(gòu)造器的方式
3.String常用方法
int length():返回字符串的長度: return value.length
char charAt(int index): 返回某索引處的字符return value[index]
boolean isEmpty():判斷是否是空字符串:return value.length == 0
String toLowerCase():使用默認(rèn)語言環(huán)境田柔,將 String 中的所有字符轉(zhuǎn)換為小寫
String toUpperCase():使用默認(rèn)語言環(huán)境俐巴,將 String 中的所有字符轉(zhuǎn)換為大寫
String trim():返回字符串的副本,忽略前導(dǎo)空白和尾部空白
boolean equals(Object obj):比較字符串的內(nèi)容是否相同
boolean equalsIgnoreCase(String anotherString):與equals方? ? ? ? ? ? ? ? 法類似硬爆,忽略大小寫
String concat(String str):將指定字符串連接到此字符串的結(jié)尾欣舵。 等價(jià)于用“+”
int compareTo(String anotherString):比較兩個(gè)字符串的大小。返回0兩字符串相等缀磕。
String substring(int beginIndex):返回一個(gè)新的字符串缘圈,它是此字符串的從beginIndex開始截取到最后的一個(gè)子字符串。
String substring(int beginIndex, int endIndex) :返回一個(gè)新字符串袜蚕,它是此字符串從beginIndex開始截取到endIndex(不包含)的一個(gè)子字符串糟把。
boolean endsWith(String suffix):測試此字符串是否以指定的后綴結(jié)束
boolean startsWith(String prefix):測試此字符串是否以指定的前綴開始
boolean startsWith(String prefix, int toffset):測試此字符串從指定索引開始的子字符串是否以指定前綴開始
boolean contains(CharSequence s):當(dāng)且僅當(dāng)此字符串包含指定的 char 值序列時(shí),返回 true
int indexOf(String str):返回指定子字符串在此字符串中第一次出現(xiàn)處的索引
int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出現(xiàn)處的索引牲剃,從指定的索引開始
int lastIndexOf(String str):返回指定子字符串在此字符串中最右邊出現(xiàn)處的索引
int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出現(xiàn)處的索引遣疯,從指定的索引開始反向搜索
注:indexOf和lastIndexOf方法如果未找到都是返回-1
替換:
String replace(char oldChar, char newChar):返回一個(gè)新的字符串,它是通過用 newChar 替換此字符串中出現(xiàn)的所有 oldChar 得到的凿傅。
String replace(CharSequence target, CharSequence replacement):使用指定的字面值替換序列替換此字符串所有匹配字面值目標(biāo)序列的子字符串另锋。
String replaceAll(String regex, String replacement):使用給定的 replacement 替換此字符串所有匹配給定的正則表達(dá)式的子字符串。
String replaceFirst(String regex, String replacement):使用給定的 replacement 替換此字符串匹配給定的正則表達(dá)式的第一個(gè)子字符串狭归。
匹配:
boolean matches(String regex):告知此字符串是否匹配給定的正則表達(dá)式夭坪。
切片:
String[] split(String regex):根據(jù)給定正則表達(dá)式的匹配拆分此字符串。
String[] split(String regex, int limit):根據(jù)匹配給定的正則表達(dá)式來拆分此字符串过椎,最多不超過limit個(gè)室梅,如果超過了,剩下的全部都放到最后一個(gè)元素中疚宇。
4.String與基本數(shù)據(jù)類型亡鼠、包裝類之間的轉(zhuǎn)換
String --> 基本數(shù)據(jù)類型、包裝類? ? ?
? ? ? 調(diào)用包裝類的靜態(tài)方法:parseXxx(str)
基本數(shù)據(jù)類型敷待、包裝類 --> String? ? ?
? ? ? 調(diào)用String重載的valueOf(xxx)
public void test1(){
? ? ? ? String str1 = "123";
//? ? ? ? int num = (int)str1;//錯(cuò)誤的
? ? ? ? int num = Integer.parseInt(str1);
? ? ? ? String str2 = String.valueOf(num);//"123"
? ? ? ? String str3 = num + "";
? ? ? ? System.out.println(str1 == str3);//false
? ? }
5.String與char[]之間的轉(zhuǎn)換
String --> char[]
? ? 調(diào)用String的toCharArray()
char[] --> String
? ? 調(diào)用String的構(gòu)造器
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);
? ? }
?6.String與byte[](字節(jié)數(shù)組)之間的轉(zhuǎn)換
編碼:String --> byte[]
? ? 調(diào)用String的getBytes()
解碼:byte[] --> String
? ? 調(diào)用String的構(gòu)造器
編碼:字符串 -->字節(jié)? (看得懂 --->看不懂的二進(jìn)制數(shù)據(jù))
解碼:編碼的逆過程间涵,字節(jié) --> 字符串 (看不懂的二進(jìn)制數(shù)據(jù) ---> 看得懂)
說明:解碼時(shí),要求解碼使用的字符集必須與編碼時(shí)使用的字符集一致榜揖,否則會(huì)出現(xiàn)亂碼勾哩。
public void test3() throws UnsupportedEncodingException {
? ? ? ? String str1 = "abc123中國";
? ? ? ? byte[] bytes = str1.getBytes();//使用默認(rèn)的字符集,進(jìn)行編碼举哟。
? ? ? ? System.out.println(Arrays.toString(bytes));//遍歷
? ? ? ? byte[] gbks = str1.getBytes("gbk");//使用gbk字符集進(jìn)行編碼思劳。
? ? ? ? System.out.println(Arrays.toString(gbks));
? ? ? ? System.out.println("******************");
? ? ? ? String str2 = new String(bytes);//使用默認(rèn)的字符集,進(jìn)行解碼妨猩。
? ? ? ? System.out.println(str2);
? ? ? ? String str3 = new String(gbks);
? ? ? ? System.out.println(str3);//出現(xiàn)亂碼潜叛。原因:編碼集和解碼集不一致!
? ? ? ? String str4 = new String(gbks, "gbk");
? ? ? ? System.out.println(str4);//沒有出現(xiàn)亂碼。原因:編碼集和解碼集一致威兜!
? ? }
7.String销斟、StringBuffer、StringBuilder的異同
String:不可變的字符序列椒舵;底層使用char[]存儲(chǔ)
StringBuffer:可變的字符序列票堵;線程安全的,效率低逮栅;底層使用char[]存儲(chǔ)
StringBuilder:可變的字符序列;jdk5.0新增的窗宇,線程不安全的措伐,效率高;底層使用char[]存儲(chǔ)
源碼分析:
String str = new String();//char[] value = new char[0];
String str1 = new String("abc");//char[] value = new char[]{'a','b','c'};
StringBuffer sb1 = new StringBuffer();//char[] value = new char[16];底層創(chuàng)建了一個(gè)長度是16的數(shù)組军俊。
System.out.println(sb1.length());//
sb1.append('a');//value[0] = 'a';
sb1.append('b');//value[1] = 'b';
StringBuffer sb2 = new StringBuffer("abc");//char[] value = new char["abc".length() + 16];
//問題1. System.out.println(sb2.length());//3
? ? ? ? ? ? public synchronized int length() {
? ? ? ? ? ? ? ? ? ? ? return count;
? ? ? ? ? ? ? ? ? }
//問題2. 擴(kuò)容問題:如果要添加的數(shù)據(jù)底層數(shù)組盛不下了侥加,那就需要擴(kuò)容底層的數(shù)組。
? ? ? ? 默認(rèn)情況下粪躬,擴(kuò)容為原來容量的2倍 + 2担败,同時(shí)將原有數(shù)組中的元素復(fù)制到新的數(shù)組中。
? ? ? ? 指導(dǎo)意義:開發(fā)中建議大家使用:StringBuffer(int capacity) 或 StringBuilder(int capacity),避免擴(kuò)容問題镰官。
對(duì)比String提前、StringBuffer、StringBuilder三者的效率:
從高到低排列:StringBuilder > StringBuffer > String
8.StringBuffer類的常用方法泳唠。
StringBuffer append(xxx):提供了很多的append()方法狈网,用于進(jìn)行字符串拼接
StringBuffer delete(int start,int end):刪除指定位置[start,end)的內(nèi)容
StringBuffer replace(int start, int end, String str):把[start,end)位置替換為str
StringBuffer insert(int offset, xxx):在指定位置插入xxx
StringBuffer reverse() :把當(dāng)前字符序列逆轉(zhuǎn)
public int indexOf(String str)返回str在當(dāng)前字符串首次出現(xiàn)的位置
public String substring(int start,int end):返回一個(gè)從start開始到end索引結(jié)束的左閉右開區(qū)間的子字符串,當(dāng)前字符串不改變
public int length():返回字符串的長度
public char charAt(int n ):返回某索引處的字符
public void setCharAt(int n ,char ch):把某索引處的字符換成ch字符
總結(jié):
增: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()
9.StringBuilder類的常用方法
與StringBuffer方法類似笨腥。
二拓哺、Java比較器
1.Java比較器的概述
Java中的對(duì)象,正常情況下脖母,只能進(jìn)行比較:==? 或? != 士鸥。不能使用 > 或 < 的。但是在開發(fā)場景中谆级,我們需要對(duì)多個(gè)對(duì)象進(jìn)行排序烤礁,言外之意,就需要比較對(duì)象的大小肥照。
如何實(shí)現(xiàn)鸽凶?使用兩個(gè)接口中的任何一個(gè):Comparable 或 Comparator。
2.Comparable接口的使用(默認(rèn)都是從小到大排列的)
Comparable接口的使用舉例:? 自然排序(默認(rèn)都是從小到大排列的)
1.像String建峭、包裝類等實(shí)現(xiàn)了Comparable接口玻侥,重寫了compareTo(obj)方法,給出了比較兩個(gè)對(duì)象大小的方式亿蒸。
2.像String凑兰、包裝類重寫compareTo()方法以后掌桩,進(jìn)行了從小到大的排列
3. 重寫compareTo(obj)的規(guī)則:
? ? 如果當(dāng)前對(duì)象this大于形參對(duì)象obj,則返回正整數(shù)姑食,
? ? 如果當(dāng)前對(duì)象this小于形參對(duì)象obj波岛,則返回負(fù)整數(shù),
? ? 如果當(dāng)前對(duì)象this等于形參對(duì)象obj音半,則返回零则拷。
4.實(shí)現(xiàn)Comparable接口的對(duì)象列表(和數(shù)組)可以通過 Collections.sort 或 Arrays.sort進(jìn)行自動(dòng)排序。實(shí)現(xiàn)此接口的對(duì)象可以用作有序映射中的鍵或有 序集合中的元素曹鸠,無需指定比較器煌茬。?
5. 對(duì)于自定義類來說,如果需要排序彻桃,我們可以讓自定義類實(shí)現(xiàn)Comparable接口坛善,重寫compareTo(obj)方法。
? 在compareTo(obj)方法中指明如何排序
public class Goods implements? Comparable{
? ? private String name;
? ? private double price;
? ? public Goods() {
? ? }
? ? public Goods(String name, double price) {
? ? ? ? this.name = name;
? ? ? ? this.price = price;
? ? }
? ? public String getName() {
? ? ? ? return name;
? ? }
? ? public void setName(String name) {
? ? ? ? this.name = name;
? ? }
? ? public double getPrice() {
? ? ? ? return price;
? ? }
? ? public void setPrice(double price) {
? ? ? ? this.price = price;
? ? }
? ? @Override
? ? public String toString() {
? ? ? ? return "Goods{" +
? ? ? ? ? ? ? ? "name='" + name + '\'' +
? ? ? ? ? ? ? ? ", price=" + price +
? ? ? ? ? ? ? ? '}';
? ? }
? ? //指明商品比較大小的方式:按照價(jià)格從低到高排序,再按照產(chǎn)品名稱從高到低排序
? ? @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("傳入的數(shù)據(jù)類型不一致邻眷!");
? ? }
}
@Test
? ? public void test1(){
? ? ? ? String[] arr = new String[]{"AA","CC","KK","MM","GG","JJ","DD"};
? ? ? ? //
? ? ? ? Arrays.sort(arr);
? ? ? ? System.out.println(Arrays.toString(arr));
? ? }
? ? @Test
? ? public void test2(){
? ? ? ? Goods[] arr = new Goods[5];
? ? ? ? arr[0] = new Goods("lenovoMouse",34);
? ? ? ? arr[1] = new Goods("dellMouse",43);
? ? ? ? arr[2] = new Goods("xiaomiMouse",12);
? ? ? ? arr[3] = new Goods("huaweiMouse",65);
? ? ? ? arr[4] = new Goods("microsoftMouse",43);
? ? ? ? Arrays.sort(arr);
? ? ? ? System.out.println(Arrays.toString(arr));
? ? }
3.Comparator接口的使用
Comparator接口的使用:定制排序
1.背景:
當(dāng)元素的類型沒有實(shí)現(xiàn)java.lang.Comparable接口而又不方便修改代碼眠屎,
或者實(shí)現(xiàn)了java.lang.Comparable接口的排序規(guī)則不適合當(dāng)前的操作,
那么可以考慮使用 Comparator 的對(duì)象來排序
2.重寫compare(Object o1,Object o2)方法肆饶,比較o1和o2的大懈鸟谩:
? ? ? 如果方法返回正整數(shù),則表示o1大于o2驯镊;
? ? ? 如果返回0燎字,表示相等;
? ? ? 返回負(fù)整數(shù)阿宅,表示o1小于o2候衍。
3.可以將 Comparator 傳遞給 sort 方法(如 Collections.sort 或 Arrays.sort), 從而允許在排序順序上實(shí)現(xiàn)精確控制洒放。
@Test
? ? public void test3(){
? ? ? ? String[] arr = new String[]{"AA","CC","KK","MM","GG","JJ","DD"};
? ? ? ? Arrays.sort(arr,new Comparator(){
? ? ? ? ? ? //按照字符串從大到小的順序排列
? ? ? ? ? ? @Override
? ? ? ? ? ? public int compare(Object o1, Object o2) {
? ? ? ? ? ? ? ? if(o1 instanceof String && o2 instanceof? String){
? ? ? ? ? ? ? ? ? ? String s1 = (String) o1;
? ? ? ? ? ? ? ? ? ? String s2 = (String) o2;
? ? ? ? ? ? ? ? ? ? return -s1.compareTo(s2);
? ? ? ? ? ? ? ? }
//? ? ? ? ? ? ? ? return 0;
? ? ? ? ? ? ? ? throw new RuntimeException("輸入的數(shù)據(jù)類型不一致");
? ? ? ? ? ? }
? ? ? ? });
? ? ? ? System.out.println(Arrays.toString(arr));
? ? }
? ? @Test
? ? public void test4(){
? ? ? ? Goods[] arr = new Goods[6];
? ? ? ? arr[0] = new Goods("lenovoMouse",34);
? ? ? ? arr[1] = new Goods("dellMouse",43);
? ? ? ? arr[2] = new Goods("xiaomiMouse",12);
? ? ? ? arr[3] = new Goods("huaweiMouse",65);
? ? ? ? arr[4] = new Goods("huaweiMouse",224);
? ? ? ? arr[5] = new Goods("microsoftMouse",43);
? ? ? ? Arrays.sort(arr, new Comparator() {
? ? ? ? ? ? //指明商品比較大小的方式:按照產(chǎn)品名稱從低到高排序,再按照價(jià)格從高到低排序
? ? ? ? ? ? @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("輸入的數(shù)據(jù)類型不一致");
? ? ? ? ? ? }
? ? ? ? });
? ? ? ? System.out.println(Arrays.toString(arr));
? ? }
?4.總結(jié)
Comparable接口與Comparator的使用的對(duì)比:
? ? ? ? Comparable接口的方式一旦一定蛉鹿,保證Comparable接口實(shí)現(xiàn)類的對(duì)象在任何位置都可以比較大小。
? ? ? ? Comparator接口屬于臨時(shí)性的比較往湿。