StringBuilder

JDK1.5から、StringBuilderが追加された。
使い方は、StringBufferとほぼ変わらない。
違いがあるとすると、スレッドセーフでない分高速であるということぐらいらしい。

StringBuffer (Java Platform SE 6)
Java文字列メモ(Hishidama's Java String Memo)

といっても、その比較サンプルはめんどいので、

と差し替えただけ。

sb.toString() = ABC
sb.toString() = ABCDEF
sb.toString() = ABCDEFGHI

変わらない。

Sample/java/StringBuilder/StringBuilder/src/StringBuilder at master · bg1bgst333/Sample · GitHub

StringBuffer

Stringオブジェクトは、変更不可の文字列を保持するものなので、本来は変更や連結などをする場合は、StringBufferを使うべき。

StringBuffer (Java Platform SE 6)
Java文字列メモ(Hishidama's Java String Memo)
【Javaの基本】なぜStringBufferを使うのか - Qiita

文字列連結には、appendを使う。

StringBuffer (Java Platform SE 6)

とすると、

sb.toString() = ABC
sb.toString() = ABCDEF
sb.toString() = ABCDEFGHI

連結できた。

Sample/java/StringBuffer/StringBuffer/src/StringBuffer at master · bg1bgst333/Sample · GitHub

String.length

String.lengthで、文字列の長さを取得できる。

String (Java Platform SE 6)
Java文字列メモ(Hishidama's Java String Memo)

16ビットなので、基本的には半角英数でも日本語でも、文字数を返すが、サロゲートが含まれている場合は、charの個数を返す。

実行すると、

len = 5
len2 = 5

どちらも5文字。

Sample/java/String/length/src/String at master · bg1bgst333/Sample · GitHub

if文

if文は、おなじみ条件分岐に使うわけだが、これはif文というよりPHPの特徴だが、PHPはHTMLと混在させることが出来るので、phpタグでif文を分割して使うことが出来る。

PHP入門 - 構文 - とほほのWWW入門

<html>
  <head>
    <title>echo</title>
  </head>
  <body>
    <?php
      $var = 0;
    ?>
    <?php
      if ($var == 1){
    ?>
    One!
    <?php
      }
    ?>
  </body>
</html>

$varが0なら、if文の中の"One!"をHTMLとして書き込む条件を満たさない。

”One!&quot;は表示されない
”One!"は表示されない

”One!"は表示されない。

$varが1だと、

表示される
表示される

表示される。

Sample/php/if/if/src/if at master · bg1bgst333/Sample · GitHub

Cloneable.clone

これまでのcloneの実装だと、浅いコピーになるため、正しい深いコピーの実装をする。

Cloneable (Java Platform SE 6)
Javaのcloneメソッドの正しい実装方法 - Qiita

厳密には、Cloneableにはcloneメソッドが含まれない模様。
(なのでタイトルはおかしいが、実質そういうような感じなので。)

SubObjectを追加し、

// サブオブジェクト
class SubObject{

	// フィールド
	int data;	// int型フィールドdata

	// メソッド
	public void setData(int data) {	// dataをセットするメソッドsetData.
		this.data = data;	// メンバに引数をセット.
	}
	@Override
	public String toString(){	// オーバーライドメソッドtoString.
		String retStr = "SubObject[data = " + data + "]";	// retStrにメンバフィールドの値をセット.
		return retStr;	// retStrを返す.
	}

}

新たにint型のdataを持つ。

// カスタムオブジェクト
class CustomObject implements Cloneable{	// Objectの派生クラスCustomObject(Cloneableを実装.)

	// フィールド
	String str;	// Stringクラスフィールドstr.
	int value;	// int型フィールドvalue.
	SubObject subObj;	// SubObjectクラスフィールドsubObj.

	// メソッド
	public void setStr(String str) {	// strをセットするメソッドsetStr.
		this.str = str;	// メンバに引数をセット.
	}
	public void setValue(int value) {	// valueをセットするメソッドsetValue.
		this.value = value;	// メンバに引数をセット.
	}
	public void setSubObj(SubObject subObj){	// subObjをセットするメソッドsetSubObj.
		this.subObj = subObj;	// メンバに引数をセット.
	}
	public void setData(int data){	// subObjのdataをセットするメソッドsetData.
		this.subObj.data = data;	// メンバのメンバに引数をセット.
	}
	@Override
	public String toString(){	// オーバーライドメソッドtoString.
		String retStr = "CustomObject[str = " + str + ", " + "value = " + value + ", subObj.data = " + subObj.data + "]";	// retStrにメンバフィールドの値をセット.
		return retStr;	// retStrを返す.
	}
	@Override
	public Object clone(){	// オブジェクトのクローンをするオーバーライドメソッドclone.
		try{
			return (CustomObject)super.clone();	// 親クラス(Object)のcloneを呼ぶ.
		}
		catch (CloneNotSupportedException e){
			throw new InternalError(e.getMessage());	// InternalErrorに投げる.
		}
	}

}

これをCustomObjectのメンバに追加。

//メインクラス
class MainClass {	// MainClassクラスの定義

	// Javaのエントリポイント
	public static void main(String[] args) {	// mainメソッドの定義

		// CustomObjectを1つ生成.
		CustomObject obj1 = new CustomObject();	// CustomObjectオブジェクトobj1を生成.

		// 文字列をセット.
		obj1.setStr("ABC");	// obj1.setStrで"ABC"をセット.

		// 整数値をセット.
		obj1.setValue(123);	// obj1.setValueで123をセット.

		// サブオブジェクトの生成.
		SubObject subObj1 = new SubObject();	// SubObjectオブジェクトsubObj1を生成.
		subObj1.setData(100);	// subObj1.setDataで100をセット.

		// subObj1のセット.
		obj1.setSubObj(subObj1);	// obj1.setSubObjでsubObj1をセット.

		// obj1の中身を出力.
		System.out.println("obj1.toString() = " + obj1.toString());	// obj1.toString()を出力.

		// CustomObjectオブジェクトをもうひとつ用意.
		CustomObject obj2;	// obj2を用意.

		// クローン.
		obj2 = (CustomObject)obj1.clone();	// obj1.cloneでobj2にクローン.

		// obj2の内容を変更.
		obj2.setStr("XYZ");	// obj2.setStrで"XYZ"をセット.
		obj2.setValue(789);	// obj2.setValueで789をセット.
		obj2.setData(200);	// obj2.setDataで200をセット.

		// obj2の中身を出力.
		System.out.println("obj2.toString() = " + obj2.toString());	// obj2.toString()を出力.

		// obj1の中身を出力.
		System.out.println("obj1.toString() = " + obj1.toString());	// obj1.toString()を出力.

	}

}

これでクローンをすると、

obj1.toString() = CustomObject[str = ABC, value = 123, subObj.data = 100]
obj2.toString() = CustomObject[str = XYZ, value = 789, subObj.data = 200]
obj1.toString() = CustomObject[str = ABC, value = 123, subObj.data = 200]

subObjのほうは、クローンしても参照をコピーしてるので、obj2の変更の影響がobj1に出てしまう。

Cloneableでcloneを実装し、

自身をクローンした後、subObj分もクローンしてもらって、それを返すようにする。

obj1.toString() = CustomObject[str = ABC, value = 123, subObj.data = 100]
obj2.toString() = CustomObject[str = XYZ, value = 789, subObj.data = 200]
obj1.toString() = CustomObject[str = ABC, value = 123, subObj.data = 100]

obj2の変更が、obj1には影響しないようになった。

Sample/java/Cloneable/clone/src/Cloneable at master · bg1bgst333/Sample · GitHub

タプル

タプルも複数の値をまとめたものだが、リストと違うのは、値の変更など様々な操作が出来ない点である。

とほほのPython入門 - リスト・タプル・辞書 - とほほのWWW入門

値をカンマで区切って、括弧"()"で括るとタプルになる。

#!/usr/bin/python

lst = [10, 20, 30]

print "lst = %s" % lst

lst[1] = 15

print "lst = %s" % lst

tpl = (100, 200, 300)

print tpl[0]
print tpl[1]
print tpl[2]

tpl[1] = 150

としても、

$ vi tuple.py
$ python tuple.py
lst = [10, 20, 30]
lst = [10, 15, 30]
100
200
300
Traceback (most recent call last):
  File "tuple.py", line 17, in <module>
    tpl[1] = 150
TypeError: 'tuple' object does not support item assignment
$

エラーになる。

で、

$ vi tuple.py
$ python tuple.py
lst = [10, 20, 30]
lst = [10, 15, 30]
100
200
300
$ ls

諦めた。
まあリストに変換できるので、そうすれば変更できるらしい。

Sample/python/tuple/tuple/src/tuple at master · bg1bgst333/Sample · GitHub

Cloneable

Cloneableは、複製可能を示すインターフェース。

Cloneable (Java Platform SE 6)
Javaクローンメモ(Hishidama's Java Cloneable Memo)

ちょっと書き方が正しくなかったので修正。

Cloneableが無い状態で、super.clone(Object.clone)を呼ぶと、CloneNotSupportedExceptionが発生するのが前提。
その上で、Cloneableを付けて、その代わりthrowsを外した。
ただし、super.cloneの外はtryで囲み、例外はInternalError。

これで、MainClassでtryは必要なくなった。

obj1.toString() = CustomObject[str = ABC, value = 123]
obj2.toString() = CustomObject[str = XYZ, value = 789]
obj1.toString() = CustomObject[str = ABC, value = 123]

変わらない。

Sample/java/Cloneable/Cloneable/src/Cloneable at master · bg1bgst333/Sample · GitHub