未来エンジニア養成所Blog

プログラミングを皆に楽しんでもらうための情報をお届けします。

【Java】基本パッケージ Part1

title


java.langパッケージとObjectクラス

前の記事ででパッケージを解説しましたが、今まで使用してきたStringクラスは完全修飾名も使っていませんし、import文もありませんでした。

Stringクラスはjava.langパッケージのクラスです。

このjava.langパッケージはJavaプログラム言語の設計にあたり基本的なクラスを持ちます。

ObjectクラスやSystemクラスもこのパッケージに属します。

非常によく使用する重要なクラスが多いため、このパッケージだけは何も記述しなくても自動的にimportされます。

よってクラス名だけで利用できていたのです。

javadocで左上の[パッケージ]欄から「java.lang」を選択すると、左下にjava.langパッケージに含まれるインターフェースやクラスが表示されます。

クラスのカテゴリから「String」クラスを探してみましょう。

langパッケージ


主なクラス


java.langパッケージの中で頻繁に利用されるのがObjectクラスです。

Objectクラスはすべてのクラスのスーパークラスです。

言いかえると、すべてのクラスはObjectクラスのサブクラスです。

Objectクラスに定義されたメソッドはサブクラスに継承されるので、サブクラスでそれらを定義することなく使用することができます。


【Objectクラスのメソッドの利用】

public class ObjectSample {
    public static void main(String[] args) {
        ObjectSample obj = new ObjectSample();
        System.out.println(obj.hashCode());
    }
}


実行結果

366712642


hashCode()メソッドはObjectクラスに定義されているので、1行目のクラス定義で「extends Object」を省略しても使用できることがわかります。


Stringクラス

Stringクラスもjava.langパッケージのクラスです。

+演算子で連結できるなど、特別な機能もあります。

しかし一般のクラスのようにメソッドを用いることでさまざまな機能を利用できます。

例えば、次のようなメソッドがあります。

public String replace(char oldChar, char newChar)

"Hello"という文字列があったとき、lをすべてxに変える(HelloがHexxoになる)など、文字列中での文字を置き換えることができるメソッドです。


Stringオブジェクトは内部に文字列を持っていますが、これを通常のデータ型と同様の考え方を用いてはいけません。

通常のデータ型は持つデータを違う値などに置き換えることが出来ますが、Stringオブジェクトは持っている文字列を変更するという事が出来ないのです。

よって文字列結合などによって持つ文字列が変更されるという事は、内部に持っている文字列を書き換えているのではなく、結合した結果の文字列を内部データとして持つ新たなオブジェクトを作成し、そのオブジェクトを利用するように変わっているだけです。

Stringオブジェクトは、文字列を操作するたびにオブジェクトを作り直しているのです。

このように持っている情報を変更する事が出来ないことを「イミュータブル(不変)」といいます。


【Stringクラスの利用Ⅰ】

public class StrReplace1{
    public static void main(String[ ] args){
        String str = "it's a beautiful day!";
        str.replace('a', 'z');
        System.out.println(str);
    }
}


実行結果

it's a beautiful day!


文字列の内容はまったく変更されていません。

Stringクラスのオブジェクトは1度作られたインスタンスの中身は変更されることはありません。

そのため、どんなメソッドを呼び出してもstrの持つ文字列はそのままです。


ではreplace( )メソッドはどのように使うのでしょうか?

replace( )メソッドのようなメソッドはstrの中身を変更しませんが、その代わり新しいStringオブジェクトをもう1つ作ります。

そちらに変更が反映されています。

もちろんこの文字列もイミュータブルなので、また変更するようなメソッドを呼び出したときは他の文字列が生成されます。


【Stringクラスの利用Ⅱ】

public class StrReplace2{
    public static void main(String[ ] args){
        String str = "it's a beautiful day!";
        String str2 = str.replace('a', 'z');
        System.out.println(str);
        System.out.println(str2);
    }
}


実行結果

it's a beautiful day!
it's z bezutiful dzy!


オブジェクトstrの内容はまったく変更されていません。

それに対して新しく作られたstr2の方はreplace( )メソッドによる変更が反映されています。

Stringクラスで文字列操作する際には、文字列はイミュータブルである事を覚えておきましょう。


StringBufferクラス

Stringはイミュータブルですので、文字列オブジェクトを変更したい場合は新しいオブジェクトが作られます。

しかし、これは実行効率が良くありません。

最初の文字列を少し操作した新しい文字列を作ると、内部的にnewが行われます。

そのため、その操作が何度も行われるとオーバーヘッドが大きくなります。


そのため、StringBufferクラスが用意されています。

このクラスにはさまざまな文字列操作メソッドが実装されています。

そして、これらのメソッドを呼び出しても新しいインスタンスを生成しません。


また、StringBufferではバッファ容量を指定します。

これは新しく領域を確保せずに保持することのできる文字列のサイズを表します。

文字列が加えられるごとにバッファの大きさが自動的に増やされます。

しかし、何度もこの操作が行われるのは効率が悪いので、毎回容量をどのくらい取るのかを設定することもできます。


オーバーヘッドとは
コンピュータで何ならかの処理を行う際の負荷の事を指します。


StringBuffer


【StringBufferクラスの利用】
一定の長さの文字列を格納できるバッファをもったStringBufferクラスを利用して、文字列を効率よく操作するためのStringBufferクラスの使用方法について確認しましょう。


また、出力結果をもとにStringBufferクラスではどのように文字列を効率よく管理しているのか考察しましょう。

public class BufferSample{
    public static void main(String[ ] args){
        StringBuffer buffer = new StringBuffer( );
        System.out.println("buffer : " + buffer.toString( ));
        System.out.println("capacity : " + buffer.capacity( ));

        buffer.append("Hello");
        buffer.append("World!");
        System.out.println("buffer : " + buffer.toString( ));
        System.out.println("capacity : " + buffer.capacity( ));

        buffer.append(" This is me!");
        System.out.println("buffer : " + buffer.toString( ));
        System.out.println("capacity : " + buffer.capacity( ));

        buffer.ensureCapacity(64);
        System.out.println("buffer : " + buffer.toString( ));
        System.out.println("capacity : " + buffer.capacity( ));

        buffer.insert(5, ", ");
        System.out.println("buffer : " + buffer.toString( ));
        System.out.println("capacity : " + buffer.capacity( ));
    }
}


実行結果

buffer :
capacity : 16
buffer : HelloWorld!
capacity : 16
buffer : HelloWorld! This is me!
capacity : 34
buffer : HelloWorld! This is me!
capacity : 70
buffer : Hello, World! This is me!
capacity : 70


StringBufferのデフォルトコンストラクタを呼び出すと、バッファのサイズは自動的に16文字分となります。

16文字分で収まらなくなると自動的にサイズが増えますが、こちらからensureCapacity( )メソッドで指定することもできます。

ensureCapacity( )メソッドでは64文字分という大きさを与えたのですが、このプログラムの実行結果では70文字分となっています。

これはensureCapacity( )メソッドの仕様によるもので、次の2つのどちらか大きい方と決められています。


基本パッケージ Part2 へ続きます。
phoeducation.work


参考図書



独学で挫折しそうになったら、オンラインプログラミングスクール
未来エンジニア養成所Logo



あわせて学習したい

phoeducation.work