1.StringTokenizerクラス

次に、文字列の操作を伴う一般的なシナリオをいくつか紹介します。文字列を複数の部分に分割するにはどうすればよいでしょうか? これを行うにはいくつかの方法があります。

split()方法

文字列を複数の部分に分割する最初の方法は、split()メソッドを使用することです。特別な区切り文字列を定義する正規表現を引数として渡す必要があります。Java マルチスレッドのクエストで正規表現とは何かを学びます。

例:

コード 結果
String str = "Good news everyone!";
String[] strings = str.split("ne");
System.out.println(Arrays.toString(strings));
結果は 3 つの文字列の配列になります。
["Good ", "ws everyo", "!"]

シンプルですが、このアプローチは過剰になる場合があります。多数の区切り文字 (スペース、改行文字、タブ、ピリオドなど) がある場合は、かなり複雑な正規表現を作成する必要があります。読みにくいため、変更するのも困難です。

StringTokenizerクラス

Java には、文字列を部分文字列に分割するという特別なクラスがあります。

このクラスは正規表現を使用しません。代わりに、単に区切り文字で構成される文字列を渡します。このアプローチの利点は、文字列全体を一度に断片に分割するのではなく、最初から最後まで一度に 1 ステップずつ移動することです。

このクラスには、コンストラクターと 2 つの重要なメソッドがあります。コンストラクターに、複数の部分に分割した文字列と、一連の区切り文字で構成される文字列を渡します。

メソッド 説明
String nextToken()
次の部分文字列を返します
boolean hasMoreTokens()
さらに部分文字列があるかどうかを確認します。

このクラスは、どこか Scanner クラスを彷彿とさせます。Scanner クラスにはnextLine()hasNextLine()メソッドもあります。

次のコマンドを使用してオブジェクトを作成できますStringTokenizer

StringTokenizer name = new StringTokenizer(string, delimiters);

string部分に分割する文字列はどこですか。Anddelimitersは文字列であり、その中の各文字は区切り文字として扱われます。例:

コード コンソール出力
String str = "Good news everyone!";

StringTokenizer tokenizer = new StringTokenizer(str,"ne");
while (tokenizer.hasMoreTokens())
{
   String token = tokenizer.nextToken();
   System.out.println(token);
}
Good 
ws 
v
ryo
!

2 番目の文字列としてコンストラクターに渡される文字列内の各文字はStringTokenizer区切り文字と見なされることに注意してください。



2.String.format()メソッドとStringFormatterクラス

String クラスのもう 1 つの興味深いメソッドは ですformat()

データを保存するさまざまな変数があるとします。どうすれば画面上に一行で表示できるのでしょうか?たとえば、いくつかのデータ (左の列) と必要な出力 (右の列) があります。

コード コンソール出力
String name = "Amigo";
int age = 12;
String friend = "Diego";
int weight = 200;
User = {name: Amigo, age: 12 years, friend: Diego, weight: 200 kg.}

コードはおそらく次のようになります。

プログラムコード
String name = "Amigo";
int age = 12;
String friend = "Diego";
int weight = 200;

System.out.println("User = {name: " + name + ", age:" + age + " years, friend: " + friend+", weight: " + weight + " kg.}");

このようなコードはあまり読みにくくなります。変数名が長ければ、コードはさらに難しくなります。

プログラムコード

class User {
    ......
    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public List<String> getFriends() {
        return friends;
    }

    public ExtraInformation getExtraInformation() {
        return extraInformation;
    }
}

User user = new User();

System.out.println("User = {name: " + user.getName() + ", age:" + user.getAge() + " years, friend: " + user.getFriends().get(0) + ", weight: " + user.getExtraInformation().getWeight() + " kg.}");

あまり読みにくいですね。

しかし、これは実際のプログラムではよくある状況なので、このコードをより簡単かつ簡潔に記述する方法について説明したいと思います。

String.format

String クラスには静的format()メソッドがあり、文字列とデータを組み合わせるパターンを指定できます。コマンドの一般的な外観は次のとおりです。

String name = String.format(pattern, parameters);

例:

コード 結果
String.format("Age=%d, Name=%s", age, name);
Age=12, Name=Amigo
String.format("Width=%d, Height=%d", width, height);
Width=20, Height=10
String.format("Fullname=%s", name);
Fullname=Diego

メソッドの最初のパラメーターは、データを挿入する必要がある場所に必要format()なすべてのテキストと書式指定子 ( や など%d)と呼ばれる特殊文字を含む書式指定文字列です。%s

このformat()メソッドは、これらの指定子%s%d形式指定子を、パラメータ リスト内の形式文字列に続くパラメータに置き換えます。文字列を挿入したい場合は、 と書きます%s。数値を挿入する場合、形式指定子は です%d。例:

コード 結果
String s = String.format("a=%d, b=%d, c=%d", 1, 4, 3);
sに等しい"a=1, b=4, c=3"

以下は、書式文字列内で使用できる書式指定子の短いリストです。

指定子 意味
%s
String
%d
整数: byteshortintlong
%f
実数: floatdouble
%b
boolean
%c
char
%t
Date
%%
%キャラクター

これらの指定子はデータの種類を示しますが、データの順序を示す指定子もあります。引数をその番号 (番号は 1 から始まります) で取得するには、「 」の代わりに「 」を書く必要があります。例:%1$d%d

コード 結果
String s = String.format("a=%3$d, b=%2$d, c=%d", 11, 12, 13);
sに等しい"a=13, b=12, c=11"

%3$d3 番目の引数を取得し、%2$d2 番目の引数を取得し、%d最後に最初の引数を取得します。%sおよび形式指定子は、や の%dような指定子に関係なく引数を参照します。%3$d%2$s



3. 文字列プール

StringPoolコード内で文字列リテラルとして指定されたすべての文字列は、プログラムの実行中にと呼ばれるメモリ領域に格納されます。StringPool文字列を格納するための特別な配列です。その目的は、文字列ストレージを最適化することです。

まず、コードで指定された文字列をどこかに保存する必要がありますよね。コードはコマンドで構成されますが、データ (特に大きな文字列) はコードとは別にメモリに保存する必要があります。コードには文字列オブジェクトへの参照のみが表示されます。

次に、すべての同一の文字列リテラルは、メモリに 1 回だけ保存する必要があります。それがまさにそのように機能するのです。クラス コードが Java マシンによってロードされるとき、すべての文字列リテラルがStringPoolまだ存在しない場合は追加されます。すでに存在する場合は、 からの文字列参照を単純に使用しますStringPool

Stringしたがって、コード内の複数の変数に同じリテラルを割り当てると、これらの変数には同じ参照が含まれることになります。リテラルはStringPool一度だけ追加されます。それ以外の場合はすべて、コードは にすでにロードされている文字列への参照を取得しますStringPool

おおよその仕組みは次のとおりです。

コード StringPool の操作
String a = "Hello";
String b = "Hello";
String c = "Bye";
String[] pool = {"Hello", "Bye"};
a = pool[0];
b = pool[0];
c = pool[1];

そのため、 変数ab変数には同じ参照が格納されます。

intern()方法

そして最も優れている点は、プログラムで任意の文字列を .html ファイルに追加できることですStringPoolStringこれを行うには、変数のメソッドを呼び出すだけですintern()

このintern()メソッドは、文字列StringPoolがまだ存在しない場合は文字列を追加し、文字列への参照を に返しますStringPool

StringPoolメソッドを使用して2 つの同一の文字列が に追加された場合intern()、メソッドは同じ参照を返します。これは、文字列を参照によって比較するために使用できます。例:

コード ノート
String a = new String("Hello");
String b = new String("Hello");
System.out.println(a == b);


false
String a = new String("Hello");
String b = new String("Hello");

String t1 = a.intern();
String t2 = b.intern();
System.out.println(a == b);
System.out.println(t1 == t2);





false
true

この方法を頻繁に使用することはほとんどありませんが、人々はインタビューでこの方法について尋ねることを好みます。ですから、知らないよりは知っていた方が良いのです。