web-dev-qa-db-ja.com

javaの可変文字列と不変文字列の違いは何ですか

私の知る限りでは、

可変文字列は変更でき、不変文字列は変更できません。

ここで、このようにStringの値を変更します。

String str="Good";
str=str+" Morning";

他の方法は、

StringBuffer str= new StringBuffer("Good");
str.append(" Morning");

どちらの場合でも、strの値を変更しようとしています。誰も私に、両方の場合の違いは何ですか、可変オブジェクトと不変オブジェクトの明確な画像を教えてくれますか?.

45
Raghu

事例1:

String str = "Good";
str = str + " Morning";

上記のコードでは、3つのStringオブジェクトを作成します。

  1. 「良い」それは文字列プールに入ります。
  2. 「朝」はString Poolにも入ります。
  3. 「おはよう」と「おはよう」を連結して作成された「おはよう」。この男はHeapに進みます。

注:文字列は常に不変です。 mutable Stringのようなものはありません。 strreferenceであり、最終的には「おはよう」を指します。実際、あなたはnot1オブジェクトで作業しています。 3 distinct Stringオブジェクトがあります。


ケース2:

StringBuffer str = new StringBuffer("Good"); 
str.append(" Morning");

StringBufferには文字の配列が含まれます。 Stringと同じnotです。上記のコードは、既存の配列に文字を追加します。事実上、StringBufferは可変ですが、そのString表現は可変ではありません。

84
TheLostMind

Javaの可変文字列と不変文字列の違いは何ですか

不変は存在しますが、不変は存在しません。

11
Philipp Sander

Javaでは、すべての文字列は不変です。 Stringを変更しようとしているとき、あなたが本当にしていることは新しいものを作成することです。ただし、StringBuilderを使用すると、新しいコンテンツを作成するのではなく、実際にコンテンツを変更します。

8
Balduz

Java Stringsは不変です。

最初の例では、referenceStringに変更し、他の2つのStringsを組み合わせた値に割り当てます:str + " Morning"

それどころか、StringBuilderまたはStringBufferはそのメソッドを介して変更できます。

5
Mena

Stringin Java isimmutable。ただし、プログラミングコンテキストでmutableとはどういう意味ですか?次のクラスを検討してください。

public class Dimension {
    private int height;

    private int width;

    public Dimenstion() {
    }

    public void setSize(int height, int width) {
        this.height = height;
        this.width = width;
    }

    public getHeight() {
        return height;
    }

    public getWidth() {
        return width;
    }
}

これで、Dimensionのインスタンスを作成した後、その属性をいつでも更新できます。他の意味の状態で、クラスのインスタンスの属性のいずれかを更新できる場合、それは可変であると言われることに注意してください。いつでもフォローできますが、

Dimension d = new Dimension();
d.setSize(10, 20);// Dimension changed
d.setSize(10, 200);// Dimension changed
d.setSize(100, 200);// Dimension changed

Javaで文字列を作成できるさまざまな方法を見てみましょう。

String str1 = "Hey!";
String str2 = "Jack";
String str3 = new String("Hey Jack!");
String str4 = new String(new char[] {'H', 'e', 'y', '!'});
String str5 = str1 + str2;
str1 = "Hi !";
// ...

そう、

  1. str1およびstr2は、文字列定数プールで作成される文字列リテラルです
  2. str3str4、およびstr5は、ヒープメモリに配置される文字列オブジェクトです。
  3. str1 = "Hi!";は、文字列定数プールに"Hi!"を作成します。これは、以前に"Hey!"が参照していたstr1とはまったく異なる参照です。

ここでは、文字列リテラルまたは文字列オブジェクトを作成しています。両方とも異なります。次の投稿を読んで、それについてさらに理解することをお勧めします。

String宣言では、1つのことが一般的です。変更はされませんが、作成されるか、または他にシフトされます。

String str = "Good"; // Create the String literal in String pool
str = str + " Morning"; // Create String with concatenation of str + "Morning"
|_____________________|
       |- Step 1 : Concatenate "Good"  and " Morning" with StringBuilder
       |- Step 2 : assign reference of created "Good Morning" String Object to str

Stringが不変になった方法は?

振る舞いは変わらないので、一度割り当てられた値は他の方法で更新することはできません。文字列クラスは、文字配列のデータを内部的に保持します。さらに、クラスは不変に作成されます。不変クラスを定義するためのこの戦略を見てください。

参照をシフトしても、値を変更したわけではありません。 Stringクラスの背後にある文字配列を更新できる場合は変更可能です。しかし、実際にはその配列は一度初期化され、プログラム全体で初期化されます。

StringBufferが可変なのはなぜですか?

既に推測したように、StringBufferクラスはそれ自体が変更可能ですstateを直接更新できます。文字列と同様に、文字配列の値も保持し、文字列を直接変更するさまざまな方法i.e。の追加、削除、挿入などによってその配列を操作できます。

3
CoderCroc

strと言うときは、次の意味に注意する必要があります。

  • variablestrを意味しますか?

  • または、strによって参照されるobjectを意味しますか?

StringBufferの例では、strの値を変更していません。また、Stringの例では、Stringオブジェクトの状態を変更していません。

違いを経験する最も痛烈な方法は、次のようなものになります。

static void change(String in) { 
  in = in + " changed";
}

static void change(StringBuffer in) {
  in.append(" changed");
}

public static void main(String[] args) {
   StringBuffer sb = new StringBuffer("value");
   String str = "value";
   change(sb);
   change(str);
   System.out.println("StringBuffer: "+sb);
   System.out.println("String: "+str);
}
3

Javaでは、すべての文字列は 不変 (変更不可)です。 文字列を変更しようとしているとき、実際にやっているのは新しい文字列を作成することです

次の方法で文字列オブジェクトを作成できます

  1. 文字列リテラルを使用する

    String str="Java";
    
  2. 新しいキーワードを使用する

    String str = new String("Java");
    
  3. 文字配列を使用する

    char[] helloArray = { 'h', 'e', 'l', 'l', 'o', '.' };
    
    String helloString = new String(helloArray);   
    

文字列の不変性に来て、単に変更不可能または変更不可能を意味します

一例を見てみましょう

値を文字列リテラルに初期化しています

String s="kumar";

以下では、hashcode()を使用してロケーションアドレスの10進数表現を表示します。

System.out.println(s.hashCode());

Stringの値を単に印刷する

System.out.println("value "+s);

さて、今回は値「kumar」をs1に初期化しています

String s1="kumar";   // what you think is this line, takes new location in the memory ??? 

では、作成したs1オブジェクトのハッシュコードを表示して確認しましょう

System.out.println(s1.hashCode());

さて、以下のコードをチェックしましょう

String s2=new String("Kumar");
    System.out.println(s2.hashCode());  // why this gives the different address ??

さて、最後に以下のコードを確認してください

String s3=new String("KUMAR");
    System.out.println(s3.hashCode());  // again different address ???

はい、「s」と「s1」の値が「kumar」と同じであるため、文字列「s」と「s1」が同じハッシュコードを持つ場合

文字列 's2'と 's3'を考えてみましょう。これら2つの文字列ハッシュコードは意味が異なるように見えます。値が異なるため、両方とも異なる場所に格納されています。

sとs1ハッシュコードは同じであるため、これらの値は同じであり、同じ場所に保存されているためです。

例1:以下のコードを試して、行ごとに分析します

public class StringImmutable {
public static void main(String[] args) {

    String s="Java";
    System.out.println(s.hashCode());
    String s1="Java";
    System.out.println(s1.hashCode());
    String s2=new String("Java");
    System.out.println(s2.hashCode());
    String s3=new String("Java");
    System.out.println(s3.hashCode());
}
}

例2:以下のコードを試して、行ごとに分析します

public class StringImmutable {
    public static void main(String[] args) {

        String s="Java";
        s.concat(" programming");  // s can not be changed "immutablity"
        System.out.println("value of s "+s);
        System.out.println(" hashcode of s "+s.hashCode());

        String s1="Java";
        String s2=s.concat(" programming");   // s1 can not be changed "immutablity" rather creates object s2
        System.out.println("value of s1 "+s1);
        System.out.println(" hashcode of s1 "+s1.hashCode());  

        System.out.println("value of s2 "+s2);
        System.out.println(" hashcode of s2 "+s2.hashCode());

    }
}

さて、可変と不変の違いを見てみましょう。

可変(変更)対不変(変更不可)

public class StringMutableANDimmutable {
    public static void main(String[] args) {


        // it demonstrates immutable concept
        String s="Java";
        s.concat(" programming");  // s can not be changed (immutablity)
        System.out.println("value of s ==  "+s); 
        System.out.println(" hashcode of s == "+s.hashCode()+"\n\n");


        // it demonstrates mutable concept
        StringBuffer s1= new StringBuffer("Java");
        s1.append(" programming");  // s can be changed (mutablity)
        System.out.println("value of s1 ==  "+s1); 
        System.out.println(" hashcode of s1 == "+s1.hashCode());


    }
}

さらに質問はありますか?書いてください...

1
atishr

可変とは、同じ参照を保存変数に変更してその内容を変更することを意味しますが、不変では内容を変更できませんが、新しい参照を宣言には新しい値と古い値が含まれます変数

不変->文字列

String x = "value0ne";// adresse one x += "valueTwo"; //an other adresse {adresse two}ヒープメモリの変更を処理します。

Mutable-> StringBuffer-StringBuilder StringBuilder sb = new StringBuilder(); sb.append("valueOne"); // adresse One sb.append("valueTwo"); // adresse One

まだ同じアドレスにsbこのコメントが役立つことを願っています

0
Said BAHAOUARY

よりわかりやすくするために、出力コメントでウィリアムのコードを修正しました

   static void changeStr(String in) { 
      in = in+" changed";
      System.out.println("fun:"+in); //value changed 
    }
    static void changeStrBuf(StringBuffer in) {
      in.append(" changed");   //value changed
    }

    public static void main(String[] args) {
       StringBuffer sb = new StringBuffer("value");
       String str = "value";
       changeStrBuf(sb);
       changeStr(str);
       System.out.println("StringBuffer: "+sb); //value changed
       System.out.println("String: "+str);       // value 
    }

上記のコードでは、main()とchangeStr()の両方でstrの値を見てください。changeStr()でstrの値を変更しても、その関数のみに影響しますが、main関数では値は変更されません。ただし、StringBufferの場合はそうではありません。

StringBufferでは、変更された値はグローバルとして影響を受けます。

したがって、Stringは不変であり、StringBufferは可変です...

Simpleでは、文字列オブジェクトに変更されたものはすべて、文字列プールに移動することにより、その関数にのみ影響します。変更されていない...

0
Vinay Shanubhag

可変変数とは、その値がその場で変化する可能性がある変数ですが、不変の変数では、値の変化はその場では起こりません。不変変数を変更すると、同じ変数が再構築されます。

0
Amit Upadhyay