Javaには文字列プールがあるため、新しい文字列が実際に作成される前に、同じ文字列が既に存在するかどうかを確認するチェックがあると思います.この呼び出しのコストはいくらですか?
プールはハッシュまたはツリー ベースの構造ですか?
どちらの場合も、検索ツリーはハッシュ コードをキーとして使用するため、文字列ハッシュ コードのパフォーマンスに帰着すると思います。
n は現在ヒープ上にある文字列の数です。
JVM が実行されている場合、文字列プールには定数文字列 (つまり、ハードコードされたもの) のみが含まれます。
public class StringExample{
private static final String CONSTANT = "Cannon Ball!!!"; // <- In the pool
public void processStrings(String[] args){
// ^--Assumed contents are variables, not in the pool
String temp = "I'll wade in."; // <- In the pool
StringBuilder sb = new StringBuilder(100);
sb.append("I").append(" hate").append(" water.");
String dynamic = sb.toString(); // <- Not in the pool.
dynamic.intern(); // <- Now it's in the pool.
}
}
すべての動的文字列は文字列プールの外部にあります。を呼び出して、プログラムでプールに文字列を追加できますString.intern()
。
public class StringExample{
public static final String CONSTANT = "Just me.";
}
public class Foo{
private String value = StringExample.CONSTANT;
}
コンパイル時に、コンパイラは参照をハードコードされた文字列に置き換えるだけなので、次のようにするのと同じです。
public class StringExample{
public static final String CONSTANT = "Just me.";
}
public class Foo{
private String value = "Just me.";
}
Javaには文字列プールがあるため、新しい文字列が実際に作成される前に、同じ文字列が既に存在するかどうかを確認するチェックがあると思います.この呼び出しのコストはいくらですか?
これは、作成した文字列ではなく、文字列リテラルに対してのみ発生します。String.intern() を呼び出してプールに追加できますが、作成された後でのみ可能です。
プールはハッシュまたはツリー ベースの構造ですか?
衝突のためのリンクされたリストを持つ固定サイズのハッシュ マップです。これを使いすぎないことをお勧めします。スケールしないから。
どちらの場合も、検索ツリーはハッシュ コードをキーとして使用するため、文字列ハッシュ コードのパフォーマンスに帰着すると思います。
String プールが必要な場合は、自分で作成することをお勧めします。byte[]
私は、またはそのような StringBuilderを取りCharSequence
、String をプールするものを持っているので、約 90% の時間 (それがターゲットです) オブジェクトを作成しません。
n は現在ヒープ上にある文字列の数です。
実際には容量である約10,000まではO(1)であり、その後はO(n)であり、それほど大きくはありません。
リテラルをどのようにプール/キャッシュしますか?コンパイラはリテラルを静的への参照に置き換えますか? –
コンパイラは文字列リテラルを特定のクラス ファイルに結合しますが、JVM はそれを取得して JVM 全体に結合します。
==
新しい文字列が既に文字列プールにあるかどうかのチェックは行われません。これが、文字列の比較に を使用すべきではない理由の 1 つです。
文字列プールは、コンパイル時に認識される文字列に使用されます。または、返されたインスタンスを手動で使用intern()
して使用する場合。
実行時に String が動的に作成されるたびに、新しい String インスタンスが返されます。String プールには、String リテラルと String コンパイル時定数、または を呼び出して明示的にプールに追加された String のみが含まれますString.intern()
。