Object.clone

Object.cloneは、オブジェクトのコピーを作成して返す。

Object (Java Platform SE 6)
オブジェクトのクローン - Java の基本 - Java 入門

派生クラスで、Cloneableインターフェースのcloneを実装して、オーバーライドしないといけない。

// カスタムオブジェクト
class CustomObject {	// Objectの派生クラスCustomObject

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

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

}

前回の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をセット.

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

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

		// 代入
		obj2 = obj1;	// obj2にobj1を代入.(参照渡しになる.)

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

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

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

	}

}

obj2に代入するという場合、Javaは参照渡しなので、データコピーされるわけではない。

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

このように、obj2で変更した内容がobj1にも反映される。おなじオブジェクトを参照しているからである。

Cloneableを継承し、cloneでsuper.clone(つまりObject.clone)を呼ぶ。

Cloneable (Java Platform SE 6)

という感じで、cloneにすると、

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

obj2の変更がobj1には影響しない。別のオブジェクトだからである。

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

Hash

ハッシュも組み込みライブラリHashとして用意されている。

class Hash (Ruby 2.7.0 リファレンスマニュアル)
Ruby入門 - 配列・ハッシュ・範囲 - とほほのWWW入門

Rubyだと、文字列だけでなく、シンボル(Perlでいうシンボリックリファレンス?)もキーに出来るが、まずは文字列で。

文字列の場合は、ファットアロー("=>")で繋げないといけないらしい。

$ ruby Hash.rb
aaa
hash["a"] = aaa
hash = {"a"=>"aaa", "b"=>"bbb", "c"=>"ccc"}
$

こうなる。

Sample/ruby/Hash/Hash/src/Hash at master · bg1bgst333/Sample · GitHub

Thread.CurrentThread

Thread.CurrentThreadは、現在のスレッドオブジェクトを返すスタティックメソッド。

Thread.CurrentThread プロパティ (System.Threading) | Microsoft Docs

デリゲートとBeginInvokeなどを使った非同期処理において、UIスレッドとワーカースレッドが違うスレッドであることを確認するには、呼び出した時点でのCurrentThreadを取得して、ManagedThreadIdが違えば、スレッドが違うことがわかる。
Control.BeginInvokeで作ったプログラムをベースに、スレッドIDを確認していく。

Windowsアプリ
Windowsアプリ

Windowsアプリ。

Buttonを選択
Buttonを選択

Buttonを選択。

以前のより小さく配置
以前のより小さく配置

以前のより小さく配置。

フォントサイズは以前と同じ
フォントサイズは以前と同じ

フォントサイズは以前と同じ。

こんな感じ
こんな感じ

こんな感じ。

開始に変えておくか
開始に変えておくか

開始に変えておくか。

今度はLabelを追加
今度はLabelを追加

今度はLabelを追加。

フォントは少し大きく
フォントは少し大きく

フォントは少し大きく。

配置したら
配置したら

配置したら、

テキストを仮に"-"としておく
テキストを仮に"-"としておく

テキストを仮に"-"としておく。

小さいのでFormを引き延ばして巨大化して、Labelもコピーで縦に5個並べた。
小さいのでFormを引き延ばして巨大化して、Labelもコピーで縦に5個並べた。

小さいのでFormを引き延ばして巨大化して、Labelもコピーで縦に5個並べた。
button1をダブルクリックして、イベントハンドラなどいろんな処理を書く。

まずコンストラクタで、Thread.CurrentThread.ManagedThreadIdでスレッドIDを取得し、label1.Textにセット。

button1が押された時の非同期処理。
ここで、Thread.CurrentThread.ManagedThreadIdを呼んでるので、ワーカースレッドのIDが取得できる。
それを非同期処理メソッドのRunningが格納されたrunningとともに、label2.BeginInvokeの引数として渡している。

Runningで、渡されたスレッドIDをlabel2にセット。
RunningはUIスレッドなので、Thread.CurrentThread.ManagedThreadIdを呼べば、UIスレッドのIDが取得できるので、それをlabel3にセット。

Finishも同様。

StartじゃなくてAfterに変えてるぐらい。

Afterはメッセージボックスのみ。

起動時のUIスレッドID
起動時のUIスレッドID

起動時のUIスレッドIDはこちら。
開始を押すと、

RunningでのワーカースレッドIDは違うけど、UIスレッドIDは同じ。
RunningでのワーカースレッドIDは違うけど、UIスレッドIDは同じ。

RunningでのワーカースレッドIDは違うけど、UIスレッドIDは同じ。

Finishでも、ワーカースレッドは違い、UIスレッドは同じ。
Finishでも、ワーカースレッドは違い、UIスレッドは同じ。

Finishでも、ワーカースレッドは違い、UIスレッドは同じ。

終わった
終わった

ということで、ワーカースレッドIDとUIスレッドIDは違い、UIスレッドのデリゲートの中ならコントロールを操作できるのがわかった。

Sample/dotnet/Thread/CurrentThread/src/Thread_ at master · bg1bgst333/Sample · GitHub

Object.toString

toStringは、すべてのオブジェクトに用意されているもので、オブジェクトの文字列表現を返す。

Object (Java Platform SE 7)
Java クラスにtoStringメソッドを追加する意味とサンプル | ITSakura

デフォルトのものを使ってもいいが、どうやってオーバーライドしていくかというのもちょっとやってみる。

CustomObject.javaで、

// カスタムオブジェクト
class CustomObject {	// Objectの派生クラスCustomObject
	// 最初は何も定義しない.
}

何も定義しない。
MainClass.javaで、

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

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

		// CustomObjectの生成.
		CustomObject obj = new CustomObject();	// CustomObjectオブジェクトobjを生成.

		// obj.toStringを出力.
		System.out.println("obj.toString() = " + obj.toString());	// obj.toString()を出力.

	}

}

そのままtoString。

obj.toString() = CustomObject@659e0bfd

デフォルト動作は、クラス名とオブジェクトのハッシュコード。

// カスタムオブジェクト
class CustomObject {	// Objectの派生クラスCustomObject

	// フィールド
	String str;	// Stringクラスフィールドstr.

	// メソッド
	public void setStr(String str) {	// StrをセットするメソッドsetStr.
		this.str = str;	// メンバに引数をセット.
	}
	@Override
	public String toString(){	// オーバーライドメソッドtoString.
		return str;	// シンプルにstrを返す.
	}

}

文字列をセットできるようにし、その文字列をtoStringで返すようにした。

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

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

		// CustomObjectの生成.
		CustomObject obj = new CustomObject();	// CustomObjectオブジェクトobjを生成.

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

		// obj.toStringを出力.
		System.out.println("obj.toString() = " + obj.toString());	// obj.toString()を出力.

	}

}

"ABC"をセットすると、

obj.toString() = ABC

シンプルに"ABC"が返ってくる。
メンバが1つなら、これでもいいけど、2つ以上の場合はどうだろうか。

整数値もセットできるようにした。
toStringは、大括弧を使って、それぞれのフィールドの値を出力するようにした。
ちょっとJSONっぽい感じ・・・。

数値もセットするようにして、

obj.toString() = CustomObject[str = ABC, value = 123]

こんな感じに出力されるようになった。

Sample/java/Object/toString/src/Object at master · bg1bgst333/Sample · GitHub

grep

grepは、指定した配列から、指定の条件を満たす要素を取り出す。

grep関数 - 特定の条件を満たす配列要素のみ取得 - Perlプログラミング入門ゼミ - Perlでテキスト処理・Linuxサーバー管理・Webシステム開発

最初に条件式、その次以降に配列やリストを指定。
1以上の整数を取り出す。

$ vi grep.pl
$ perl grep.pl
5
12
4
33
100
$

取り出せた。

Sample/perl/grep/grep/src/grep at master · bg1bgst333/Sample · GitHub

DialogFragment

DialogFragmentで、ダイアログを表示する。

DialogFragment  |  Android Developers
http://android-note.open-memo.net/sub/fragment__show_dialog_with_fragment.html
[Android] DialogFragmentを使ってダイアログを表示する - Qiita
DialogFragment - Qiita

activity_main.xmlで、

Buttonを配置し、MainActivity.javaで、

Buttonが押されたら、DialogFragmentを生成。
onCreateDialogで、アラートダイアログビルダーの設定、ダイアログの生成。
今回は、匿名クラスでDialogFragmentをオーバーライド。
dialogFragment.showで表示。

button1を押すと
button1を押すと

button1を押すと、

ダイアログが表示される
ダイアログが表示される

ダイアログが表示される。

OKを押してダイアログは消えた
OKを押してダイアログは消えた

OKを押してダイアログは消えた。

Sample/android/DialogFragment/DialogFragment/src/DialogFragment at master · bg1bgst333/Sample · GitHub

Object

Javaでは、すべてのクラスが、Objectクラスを継承している。

Object (Java Platform SE 6)

独自にCustomObjectクラスを定義する。

中身は何も定義しなくても、Objectを継承する。
MainClass.javaでは、

StringはObjectを継承してるので、アップキャスト問題なし。
CustomObjectもObjectを継承してるので、アップキャスト問題なし。
ObjectはtoStringメソッドを持っているので、どちらも呼び出せる。

str = ABC
obj = ABC
custom.toString() = CustomObject@15136019
obj2.toString() = CustomObject@15136019

中身は同じ。

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