つまり、 String オブジェクトがメモリ内に作成されると、そのオブジェクトは不変になります。 String クラスのすべてのメソッドは String オブジェクト自体を変更しませんが、新しい String オブジェクトを再作成します
。
例:
String s="dcm";String s="ddccmm"
s の値が変更されると、ddccmm の値は dcm をカバーせず、ddccmm を格納するための新しい領域が開発され、s がそこを指すだけです。
実際の開発において、大量の文字を含む文字列をトラバース、代入、変更すると、解放できない文字列オブジェクトがメモリ内に多数生成され、メモリのゴミが発生します。
String オブジェクトは不変であるため、文字列に多数の変更、文字の追加、文字の削除などを行う必要がある場合は、String オブジェクトを使用しないようにしてください。新しいオブジェクトが作成され、プログラムが実行されるため、効率が低下します。
現時点では、Java で別の文字列クラス StringBuilder を使用できます。
質問をする場合、文字列には String クラスを使用することが多いですが、StringBuilder クラスを使用することもあることを考慮して、StringBuilder クラスについてもう少し詳しく説明します。
2.StringBuilder クラス
StringBuilder
は variable 文字列クラスで、ここでは変数である コンテナ と考えることができます。 StringBuilde
r オブジェクトのコンテンツが可変であることを意味します。
2.1 StringBuilder クラスの一般的に使用されるメソッド
StringBuilder
のオブジェクトを構築するには、次のことがわかります。 String s= "123"
を使用して直接作成できる
String とは異なり、Construct メソッドを使用してのみ構築できます。 # クラス オブジェクトは variable なので、文字列に多くの変更を加える必要がある場合、通常は StringBuilder
クラスとして定義されます。
2.2 String と StringBuilder の違い
String オブジェクトは不変です。 String
クラスのメソッドのいずれかを使用するたびに、新しい文字列オブジェクトがメモリ内に作成され、新しいオブジェクトに新しい領域を割り当てる必要があります。
StringBuilder このオブジェクトは、カプセル化する文字列の文字数を拡張できる動的オブジェクトですが、保持できる最大文字数の値を指定できます。 StringBuilder
を変更すると、容量に達するまでスペースを再割り当てしません。容量に達すると、新しいスペースが自動的に割り当てられ、容量が 2 倍になります。つまり、文字列が変更されると、現在のオブジェクトの状態が更新されます。
StringBuilder クラスの容量は、オーバーロードされたコンストラクターの 1 つを使用して指定できます。
2.3 String クラスと StringBuilder クラス間の変換
String クラスから StringBuilder クラスへの変換public class String{
public static void main(String[] args){
String s = "baibai";
StringBuilder s1 = new StringBuilder(s);
System.out.println(s1);
}}
StringBuilderクラスを String クラスに変換しますpublic class String {
public static void main(String[] args){
StringBuilder s1 = new StringBuilder();
//连续连接
s1.append("abc").append("efg");
String s = s1.toString();
System.out.println(s);
}}
3. String クラスを初期化します
3.1 String オブジェクトを初期化する 2 つの方法://方法一:直接创建
String s1= "大聪明 超牛的";
//方法二:对象创建
String s2 = new String("大聪明 超牛的");
String s3 = new String();//也可以创建一个空串
両方ともメソッドは同じように見えますが、本質的には異なります。
String によって作成された文字列はパブリック プールに保存されますが、new によって作成された文字列オブジェクトはヒープ上に保存されます。パブリックプール(定数プール)とヒープに保存する場合に違いはありますか?
例を挙げてみましょう: String s1 = "大聪明 超牛的"; // String 直接创建
String s2 = "大聪明 超牛的"; // String 直接创建
String s3 = s1; // 相同引用
String s4 = new String("大聪明 超牛的"); // String 对象创建
String s5 = new String("大聪明 超牛的"); // String 对象创建
System.out.println(System.identityHashCode(s1));
System.out.println(System.identityHashCode(s2));
System.out.println(System.identityHashCode(s3));
System.out.println(System.identityHashCode(s4));
System.out.println(System.identityHashCode(s5));
出力:
最初の 3 つの文字列のアドレスが同じであることがわかります。 、最後の 2 つのアドレスは同じですが、同じではありません。
これは、文字列を直接作成する場合、まずパブリック プールにそのような文字列があるかどうかを確認し、存在する場合は、新しいスペースを開発せずに、その文字列への参照を直接指定するためです。ここで、s1、s2、および s3 の 3 つの参照は、パブリック プール内の同じメモリを指します。
オブジェクトが作成されると、毎回文字列を格納するためにヒープ上に新しいスペースが開かれます。つまり、s4 と s5 はそれぞれヒープ上の 2 つの異なるメモリを指しますが、これら 2 つのメモリの内部には記憶の断片はすべて同じものを保存します。
4. String クラスで一般的に使用される API
質問をする際に文字列関連の質問に遭遇した場合、ほとんどの場合、問題を解決するために String クラスを使用することをもう一度強調しておきます。文字列に大量の変更を加える場合、一時的に StringBuilder クラスを使用することがあります。
ここで一時的なことは、通常、文字列の変更などの操作の後に文字列を String クラスに変換する必要があるということです。
したがって、学習したい API は主に String クラス API です。 StringBuilder の API に対応すると、上記の 2 つを学習するだけで済みます。
String クラスは java.lang パッケージの下にあるため、使用時にパッケージをインポートする必要はありません。 4.1 基本データ型を文字列に変換する
方法は 3 つあります:
(1)基本类型数据的值+“” (最常用,最简单);
(2)使用包装类中的静态方法 static String toString(int i)
返回一个表示指定整数的String 对象。如:在Integer中:Integer.toString(6)
;
(3)使用String类中的静态方法 static String valueOf(int i)
返回int 参数的字符串表示形式。如:String.valueOf(6)
;
String 类别中已经提供了将基本数据型态转换成String 的 static 方法也就是 String.valueOf() 这个参数多载的方法 :
String.valueOf(boolean b)
//将 boolean 变量 b 转换成字符串
String.valueOf(char c)
//将 char 变量 c 转换成字符串
String.valueOf(char[] data)
//将 char 数组 data 转换成字符串
String.valueOf(char[] data, int offset, int count)
//将char数组data中由data[offset]开始取 count个元素转换成字符串
String.valueOf(double d)
//将 double 变量 d 转换成字符串
String.valueOf(float f)
//将 float 变量 f 转换成字符串
String.valueOf(int i)
//将 int 变量 i 转换成字符串
String.valueOf(long l)
//将 long 变量 l 转换成字符串
String.valueOf(Object obj)
//将 obj 对象转换成 字符串, 等于 obj.toString()
因为是静态方法所以不需要实例化。
4.2 字符串转换为基本数据类型
一般使用包装类的静态方法parseXX("字符串")
要将 String 转换成基本数据类型大多需要使用基本数据型态的包装类别,如:String 转换成 byte可以使用 Byte.parseByte(String s)
Byte.parseByte(String s)
//将 s 转换成 byte
Byte.parseByte(String s, int radix)
//以 radix 为基底 将 s 转换为 byte
Double.parseDouble(String s)
//将 s 转换成 double
Float.parseFloat(String s)
//将 s 转换成 float
Integer.parseInt(String s)
//将 s 转换成 int
Long.parseLong(String s)
//将 s 转换成 long
注意这里也是静态方法,只不过都是对应包装类的静态方法
4.3 使用length()
得到一个字符串的字符个数
int len = String.length();
4.4 使用toCharArray()
将一个字符串转换成字符数组
Char[] arr = String.toCharArray();
4.5 判断两个字符串的内容是否相等返回true/false
String1.equals(String2);//区分大小写
String1.equalsIgnoreCase(String2);//不区分大小写
4.6 与位置相关的字符串
charAt(int)//得到指定下标位置对应的字符
indexOf(String)//得到指定内容第一次出现的下标
lastIndexOf(String)//得到指定内容最后一次出现的下标
4.7 将一个字符串按照指定内容劈开split(String)
,返回字符串数组。
String s = "wa,dcm,nb!";
String[] str = s.split(",");//返回结果中str[1]=dcm
4.8 contains(String)
判断一个字符串里面是否包含指定的内容,返回true/false
Boolean a = String1.contains(String2)
4.9 使用substring()
截取字符串,返回子串
String.substring(int)//从指定下标开始一直截取到字符串的最后
String.substring(int,int)//从下标x截取到下标y-1对应的元素
4.10 字符串大小写转换
String.toUpperCase()
//将一个字符串全部转换成大写
String.toLowerCase()//将一个字符串全部转换成小写
4.11 使用replace()
进行字符串内容替换
String.replace(String,String)
//将某个内容全部替换成指定内容
String.replaceAll(String,String)
//将某个内容全部替换成指定内容,支持正则
String.repalceFirst(String,String)
//将第一次出现的某个内容替换成指定的内容
5.字符串进阶练习
387. 字符串中的第一个唯一字符
题解:
把字符串的单个字符转化为对应数组下标,遍历一遍字符串获得26个字母分别出现几次。然后在遍历一遍字符串看哪个字符先出现次数为1,就输出对应下标。
class Solution {
public int firstUniqChar(String s) {
int len = s.length();
int[] vis = new int[26];
int temp = -1;
for(int i = 0; i <p>或者我们也可以把字符串先转换为字符数组来解题,原理都是一样的!</p><pre class="brush:php;toolbar:false">class Solution {
public int firstUniqChar(String s) {
int[] arr = new int[26];
char[] chars = s.toCharArray();
for (int i = 0; i <p>推荐学习:《<a href="https://www.php.cn/course/list/36.html" target="_blank">java视频教程</a>》</p>