DATE : 2006/07/28 (Fri)
便利な割には忘れやすいメソッドなので、ここにメモしておきます。
java.util.Arrays#asList(T...) は、配列をリスト(java.util.List)に変換するメソッドです。
詳しくは上記の javadoc に書いてありますが、このメソッド、Java SE 5 になってからはとても便利になりました。というのも、総称(Generics)や可変引数、Autoboxing / Auto-Unboxing が Java SE 5 から使えるようになったので、次のようにリストを簡単に生成できるようになったのです。(import 文などは省略)
List<String> stringList = Arrays.asList("abc", "def");
int 型を格納するリストも作れます。
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
正確には、java.lang.Integer 型ですが、Autoboxing / Auto-Unboxing によって int 型と Integer 型は特に区別することなく使えます。
この java.util.Arrays#asList(T...) と java.util.Collections#unmodifiableList(java.util.List) を組み合わせれば、変更不可能なリストを手軽に作れてしまいます(配列の場合は、final 宣言をしても中身は書き換え可能です)。
List<Integer> integerList = Collections.unmodifiableList(
Arrays.asList(1, 2, 3, 4, 5));
ちなみに、Java SE 1.4 で asList メソッドを使用する場合は、次のようになります。
List stringList = Arrays.asList(new String[]{"abc", "def"});
List integerList = Arrays.asList(new Integer[]{
new Integer(0), new Integer(1), new Integer(2),
new Integer(3), new Integer(4), new Integer(5)});
String 型を格納するリストはまだしも、Integer 型は……('A`)
DATE : 2006/07/27 (Thu)
今日、NTT の関連会社から電話がかかってきました。
帰宅する前にもかかってきたそうですが、家のネットワークを管理していることもあって、私が話を聞くことになりました。
どうも、光回線関連の話らしいです。私の家は NTT の光回線を使っているので、どのような話なのかと電話の前で待っていると、電話がかかってきました。
(*゚ー゚)「もしもし、NTT 関連会社の※※※※※の※※※※※と申します。○○様でしょうか?」
( ^ω^)「はい。そうです」
(*゚ー゚)「○○様の地域で光回線が全面開通しましたので、お知らせいたします」
( ^ω^)「それはどうも」
(*゚ー゚)「ところで、○○様はどのような回線をお使いですか? ADSL とか……」
(;^ω^)「いえ、すでに NTT の光回線を使っております」
(; ゚ー゚)「あ、それはどうも。これからもよろしくお願いいたします」
(;^ω^)「あ、はい。どうも」
(*゚ー゚)「それでは失礼いたします」
(;^ω^)……
……と、細部は忘れましたが、大まかにはこんな会話でした。
(;´Д`)光回線を使っているところに光回線開通のお知らせが来てしまいました。
(;^ω^)同じ NTT グループのはずですが、回線使用者の情報は共有されていないんでしょうか……
(;^ω^)もっとも、個人情報保護法か社内のセキュリティ上の関係で連携に制限があるのかもしれませんが。
と、まあ、不思議な電話がかかってきた一日でした。
DATE : 2006/07/26 (Wed)
Java Advanced Imaging は、先日の記事のように簡単に使えます。
しかし、細かいところを操作しようとすると、Java 2D の知識が欠かせなくなってきます(例えば、画像にアルファ成分を追加するなどといった操作です)。
そこで、Java 2D のイメージングについてメモしようと思います。
イメージの構造
ここでは、RenderedImage などの、Java 2D での構造についてメモします。
Java 2D でのイメージは、次のような構成となっています。
- ラスター
- サンプルモデル
- データバッファ
- カラーモデル
- カラー領域
ラスター
ラスター(Raster)とは、ピクセルの値を集めたものです。ピクセルの「値」を集めたものなので、そこに色の概念は関係しません。ただ単に、ビット列としての画素値を扱います。
サンプルモデルとデータバッファ
データバッファ(DataBuffer)は、データを納めるもの、サンプルモデル(SampleModel)は、画素値をどのようにしてデータバッファに納めているかを表すものです。
データバッファは、1つのデータを表す形式(整数、浮動小数点数、符号なしなど)やビット幅を指定します。例えば、DataBuffer.BYTE を使用すると、8ビットでデータひとつを表現することになります。また、値を別々の配列に格納するバンクという仕組みもあります。
サンプルモデルは、イメージの大きさやバンド数を決めます。バンド数とは、各色成分のことをいいます。例えば、RGB で表現される色は赤成分・緑成分・青成分に分けられるので3バンド、ARGB ではアルファ成分が加わるので4バンド、グレイスケールは1つの成分しかないので1バンドとなります。
なお、データバッファに格納されるのはあくまでも「データ」であって、「画素値」ではありません。画素値をどのようなデータにして、どこのバンクに格納するかも、サンプルモデルが定めます。例えば、SinglePixelPackedSampleModel の場合は、1画素の全バンドを1つのデータ格納します。また、MultiPixelPackedSampleModel では、1バンドの複数画素を1つのデータに格納します。ComponentSampleModel では、1バンド1画素を1つのデータに格納します。このサブクラスには、異なるバンドを同じバンクに格納するか、別々のバンクに格納するかといった指定を行うものもあります。
カラーモデル
カラーモデル(ColorModel)は、画素値を色として解釈する方法を表します。例えば、 IndexColorModel は、1バンドの画素値を特定の色と対応付けます。例えば、0は黒、1は赤という具合です。また、PackedColorModel は、1バンドの画素値ひとつの中に複数成分の画素値があると見なします。例えば、0xffffff を、0xff, 0xff, 0xff と3成分に分けるようにです。ComponentColorModel は、1つの画素値には1つの成分があると見なします。
カラーモデルには、ラスターで表現された画素値を解釈するという機能上、扱えるサンプルモデルには制限があります。そのため、java.awt.image.ColorModel には、そのカラーモデルと互換性のあるサンプルモデルを生成するメソッドや、互換性を確かめるメソッドがあります。
カラー領域
カラーモデルで解釈される画素値が、RGB や HSV などのどの色空間に属するかといった情報は、カラー領域(ColorSpace)が管理します。
参考文献
DATE : 2006/07/24 (Mon)
いつも、型制限の強い言語を使っているので、次のようなミスをしてしまいました orz
まず、次のように、特定の整数が入った変数(num)を2で割るとします。
var result = num / 2;
型制限の強い言語を使っていると、num に整数が入っている場合、2で割った結果も整数となるように期待してしまいます。例えば、Javaで int 型変数 num の値を2で割れば、結果も int 型となります。
int result = num / 2;
JavaScript は型制限のゆるい言語なので、num の中が整数であっても、2で割った結果が整数になるとは限りません。
むしろ JavaScript では、全ての数(Number 型)が浮動小数点数で扱われているので、結果は全て
例えば、次の計算の結果は、0.5になります。
var result = 1 / 2;
整数値を強制するには、Math.ceil 関数や Math.floor 関数を使います。簡単に言えば、前者は小数点第1位で切り上げ、後者は切り捨てで整数値に変換します。
例えば、Java の int 型同士の計算を JavaScript で行うには、次のようにします。
var result = Math.floor(num / 2);
DATE : 2006/07/23 (Sun)
今日やってしまったミスをメモしておきます orz
例えば、次のようなオブジェクトを定義したとします。
function MyObject() {
this.a = 100;
}
MyObject.prototype = {
call : function() {
alert(this.a);
}
}
このコードでは、メソッドとして call 関数(引数なし)をもつ MyObject を定義しています。
そして、次のコードを実行すると、「100」と書かれたダイアログが表示されます。
var myObject = new MyObject();
myObject.call();
これは、call 関数の中の「this」キーワードが、生成された MyObject を表しているためです。
ここで、次のような関数を用意します。この関数は、他の関数(Function オブジェクト)を受け取って呼び出す関数です。
function callFunction(callback) {
callback();
}
次のコードを実行すれば、myObject の call 関数が呼び出されるはずです。
var myObject = new MyObject();
callFunction(myObject.call);
しかし、表示されるダイアログには「undefined」と出てしまいます。つまり、call 関数の中にある「this.a」が定義されていないということになります。
実際には、JavaScript の「this」は、呼び出し元を表します。つまり、「myObject.call()」で call 関数を呼び出した場合には、myObject 経由で call 関数が呼び出されるので「this」は myObject を指します。しかし、「callFunction(myObject.call)」(実際の呼び出しは「callback()」)では、myObject を経由せずに直接 call 関数が呼び出されるので、「this」は myObject を指しません(Firefox での実行では、Window オブジェクトを指しました)。そのため、「undefined」となったわけです。
ついつい Java と同じつもりでコードを書いていて、見事に失敗してしまいました orz
(;^ω^)まあ、言語の使い初めにはよくあることですね。