Codegym University コースの一部としてのメンターによる講義の抜粋。フルコースにお申し込みください。


「こんにちは、アミーゴ! 今日は、文字列の操作に関連するさらにいくつかの一般的なシナリオを分析します。たとえば、文字列をいくつかの部分に分割する方法を知っていますか?」

「すぐには言わないよ、エリー。でも、言ってくれるよね?」

split()方法

"これを行うにはいくつかの方法があります。文字列を複数の部分に分割する最初の方法は、 メソッドを使用することです。split()特別な区切り文字列を定義する正規表現をパラメータとして渡す必要があります。正規表現が何であるかを学習します。 Javaコレクションクエスト。

例:

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

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

「そうですね。それが読みにくいと、変更するのも難しくなります。

StringTokenizerクラス

Codegym University コースの一部としてのメンターによる講義の抜粋。フルコースにお申し込みください。


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

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

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

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

nextLine()「このクラスは、どういうわけか、とメソッドを持つ Scanner クラスを思い出させますhashNextLine()

「それは良い観察ですね。次のコマンドを使用してオブジェクトを作成できますStringTokenizer

StringTokenizer name = new StringTokenizer(string, delimiters);

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

コード コンソール出力
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区切り文字と見なされることに注意してください。

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

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

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

コード コンソール出力
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.}");

「コードがあまり読みにくいということには同意していただけるでしょう。そして、変数名が長ければ、コードはさらに難しくなります。

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

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

文字列プール

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

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

StringPool「第 2 に、すべての同一の文字列リテラルは、一度だけメモリに格納する必要があります。これがまさにその仕組みです。クラス コードが Java マシンによってロードされるとき、すべての文字列リテラルがまだ存在しない場合は追加されます。すでにそこにある場合は、 からの文字列参照を単純に使用しますStringPool

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

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

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

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

「すべてを正しく理解できたと思います。

intern()方法。

「そして最も良い点は、プログラムで任意の文字列を に追加できることです。これを行うには、変数のメソッドStringPoolを呼び出すだけです。Stringintern()

「この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

この方法を頻繁に使用する可能性は低いでしょう。そうは言っても、人々は就職面接でそれについて尋ねたがります。

「だから、知らないよりは知っていた方がいいのよ。ありがとう、エリー!」