目次 | 索引 |
---|---|
これまで、変数名、メソッド名、クラス名、フィールド名など、色々なものに名前をつけてきました。 これらの名前をまとめて 識別子 ( identifier )とよびます。
識別子の約束は、変数名のときに説明した約束と同じです。
識別子は、アルファベットから始まり、アルファベットか数字かアンダースコア(
_
)が並んだ単語です。
また、
new
や
this
などのキーワードは識別子としては使えません。
キーワードをもう一度リストアップします。
abstract
,boolean
,break
,byte
,byvalue
,case
,cast
,catch
,char
,class
,const
,continue
,default
,do
,double
,else
,extends
,final
,finally
,float
,for
,future
,generic
,goto
,if
,implements
,import
,inner
,instanceof
,int
,interface
,long
,native
,new
,operator
,outer
,package
,private
,protected
,public
,rest
,return
,short
,static
,super
,switch
,synchronized
,this
,throw
,throws
,transient
,try
,var
,void
,volatile
,while
識別子は、そのものをよく表す分かりやすい名前にしてください。
プログラムが理解しやすくなります。
また、慣習も利用してください。
例えば、
for
文のループ変数は、
i
や
j
がよく用いられます。
識別子の大文字小文字は、次のように使い分ける場合が多いです。
種類 | 使い分け | 例 |
---|---|---|
定数名 | 全て大文字 | PI ,MAX_VALUE |
クラス名 | 先頭が大文字 | Time ,MyWallet |
その他 | 先頭が小文字 | hour ,clearAll |
論理型
(
logical type
)とは、真理値を表わすデータ型です。
ここで
真理値
(
truth-value
)とは、真を表わす記号 true と偽を表わす記号 false のことだと思ってください。
Java では、型名
boolean
で論理型を表わします。
値が論理型である式を、
ブール式
(
Boolean expression
)とよびます。
これまで「条件が成り立つ」、「条件が成り立たない」と言ってきたことは、正確にはブール式の値が true になること、false になることです。
変数には、整数の他に 文字 ( character )を格納するすることもできます。 次のプログラムは、変数を宣言し、そこに文字を格納し、それを画面に出力するものです。
/* 1*/ class CharacterTest { /* 2*/ public static void main (String[] args) { /* 3*/ char x; /* 4*/ x = 'A'; /* 5*/ System.out.println(x); /* 6*/ } /* 7*/ }
b00a001@Ampere:~/java% java CharacterTest A b00a001@Ampere:~/java%
整数のときには
int
型と宣言しました。
文字のときには
char
型と宣言します。
また、整数を表す場合は数字を並べました。
文字を表す場合はその文字をシングルクオート(
'
)で囲みます。
ただし、シングルクオート自身、およびダブルクオート(
"
)、バックスラッシュ(
\
)については、それぞれ
'\''
,
'\"'
,
'\\'
とします。
文字どうしが等しいかどうかは、
==
で比較します。
例えば、変数
x
が文字 a と等しいかどうかは、条件
x == 'a'
で確かめられます。
Javaでは大文字と小文字は区別されますので、
x
に文字 A が格納されていましたら、この条件は成り立たない(false)となります。
文字に関するメソッドは、組み込みのクラスである
Character
クラスで提供されています。
この中で重要なものは以下の通りです。
isDigit
(char c)isLowerCase
(char c)isSpace
(char c)isUpperCase
(char c)toLowerCase
(char c)toUpperCase
(char c)
例えば、変数
x
の値がアルファベットの大文字ならば、…という
if
文でしたら、
... char x; ... if (Character.isUpperCase(x)) { ... } ...
と書きます。
これまで文字列は、
int result = 12345679 * 9; System.out.println("result: " + result);
のように画面出力のときのみ使ってきました。
実は、文字列は組み込みのクラスである
String
クラスのインスタンスです。
文字列はよく使われますので、便利な機能がいくつか用意されています。
まず、コンストラクタを使わなくてもインスタンスが生成できます。 コンストラクタを用いて
String s = new String(); s = "Good";
や
String s = new String("Good");
などと書かなくても、
String s = "Good";
でよいのです。
また、演算子
+
が使えます。
これは、文字列を連接します。
String s1 = "Good"; String s2 = "morning!"; String s3 = s1 + " " + s2;
としますと、
s3
には文字列 "Good morning!" が格納されます。
文字列と数を演算子
+
で結びますと、数が文字列に変換されてから連接されます。
int result = 12345679 * 9; String s1 = "result = "; String s2 = s1 + result;
としますと、
s2
には文字列 "result = 111111111" が格納されます。
文字列、すなわち
String
クラスのインスタンスは、一度生成されますとその内容は変更できません。
文字列 "Good morning!" の mor を eve に置き換えることができないのです。
内容を変更するには、文字列ではなく文字列バッファというものを用います。
文字列バッファとは、組み込みのクラス
StringBuffer
のインスタンスのことです。
文字列バッファに対しては、文字の置き換え、追加、挿入などができます。
文字列を加工するには、いったん文字列バッファに変換し、処理のあと再び文字列に変換すればよいのです。
文字列を文字列バッファに変換するには、
StringBuffer
クラスのコンストラクタを用います。
逆に、文字列バッファを文字列に変換するには、インスタンスメソッド
toString()
を呼び出します。
String s1 = "Good morning!"; StringBuffer s2 = new StringBuffer(s1); s2.setCharAt(5, 'e'); s2.setCharAt(6, 'v'); s2.setCharAt(7, 'e'); String s3 = s2.toString();
としますと、
s3
には文字列 "Good evening!" が格納されます。
ここで、メソッド
void
setCharAt
(int
i
, char
c
)
は、そのインスタンスの i 番目の文字を c に置き換えるものです。
String
クラスのメソッドで重要なものは以下の通りです。
charAt
(int i)equals
(String s)length
()valueOf
(boolean b)valueOf
(char c)valueOf
(int i)
また、
StringBuffer
クラスについては以下の通りです。
append
(String s)append
(char c)charAt
(int i)insert
(int i, String s)insert
(int i, char c)length
()setCharAt
(int i, char c)toString
()
Integer
クラスでは、整数(
int
型)の変換に関するメソッドがいくつか提供されています。
その中では、以下のものが重要です。
parseInt
(String s)int
型)に変換して返す。
toString
(int i)int
型)を文字列に変換して返す。
ここで、コマンドライン引数から整数を一つ取り出すプログラム
/* 1*/ class FirstArgument /* 2*/ public static void main (String[] args) { /* 3*/ int x = Integer.parseInt(args[0]); /* 4*/ System.out.println(x); /* 5*/ } /* 6*/ }
b00a001@Ampere:~/java% java FirstArgument 100 100 b00a001@Ampere:~/java%
を思い出してください。 このプログラムの3行目の意味が、ここでやっと明らかになります。
このプログラムを実行しますと、変数
args
には文字列の配列が格納されます。
この配列は、添字0の要素がはじめのコマンドライン引数、添字1の要素が次のコマンドライン引数、…となるものです。
上記の場合では、
args[0]
に文字列 "100" が格納されます。
そして、クラスメソッド
parseInt
によって文字列 "100" が整数 100 に変換されます。
最後に、この整数 100 が変数
x
に格納されるのです。
ランレングス符号を復号して、もとのイメージを画面に出力するJavaアプリケーションを作成してください。 ここで、 ランレングス符号 ( run-length coding )とはデータ圧縮の一手法です。 また、 復号 ( decode )するとは 符号化 ( encode )されたデータを元に戻すことです。 ランレングス符号は、ファックス伝送の基本にもなっています。 ファックス伝送の仕組みを簡単に紹介し、その中でランレングス符号について説明します。
ファックス伝送は、はじめに送信側が紙面イメージを読み込みます。 このとき、紙面イメージを75分の1インチ程度の単位で格子状に分割します。 そして、光学的な方法でそれぞれの升を白か黒かに決定します。 升を横にたどっていき、右端に達したら左端に戻るということを、紙面がつきるまで繰り返し、白黒の列を作ります。 最後に、この白黒データを受信側に送信します。
受信側では、まずこの白黒データを受け取ります。 そして、白黒データと一緒に紙面の升をたどっていき、データが黒ならばその部分を黒く記録します。 これを繰り返しますと、もとの紙面イメージができあがるのです。
ここで、白と黒をそれぞれ
W
と
B
で表わすことにしまして、送信側が白黒データ
WWWWWBBBBBBBWWWWWWWWWWWWWWWWWWWWWWWWWWWBBBBBWWWWWW
を構成したとします。
白黒データが長ければ長いほど、伝送に時間がかかりますので、なるべく短くしたいです。
そこで、5個の
W
、7個の
B
、27個の
W
、…、すなわち
5W7B27W5B6W
という符号化データを送ることにします。
これがランレングス符号です。
受信側では、
5W
を
WWWWW
に置き換え、
7B
を
BBBBBBB
に置き換え、…という復号操作を行ないますと、データを元に戻すことができます。
ランレングス符号は、同じ文字が何度も繰り返されるデータほど効果を発揮します。 なお、実際に圧縮する場合には、数の表現に工夫が必要です。
今、受信側がランレングス符号
64WE64WE33W3B28WE33W6B25WE33W9B2 2WE33W12B19WE33W15B16WE33W18B13W E1W53B10WE1W56B7WE1W59B4WE1W62B1 WE1W59B4WE1W56B7WE1W53B10WE33W18 B13WE33W15B16WE33W12B19WE33W9B22 WE33W6B25WE33W3B28WE64WE64WE64WE
を受け取ったとします。
これを復号して、元の紙面イメージを画面に出力するのがこの演習の目的です。
画面では、例えば白を
.
で、黒を
*
で表してください。
なお、符号が6行なのは印刷の都合によるもので、実際は1行につながっています。
また、文字
E
は紙の右端を表しています。
画面では改行してください。
プログラミングの方針は特に指定しません。
方針が思いつかない人は、以下のプログラムの穴埋めを行なってください。
このプログラムの
System.err.println
は、エラーメッセージを画面出力するときに使うものです。
なお、
3E
などの誤った符号はないものと仮定してください。
class RunLength { public static void main (String[] args) { int i; char c; String s; StringBuffer number = new StringBuffer(""); String code = "64WE64WE33W3B28WE33W6B25WE33W9B2" + "2WE33W12B19WE33W15B16WE33W18B13W" + "E1W53B10WE1W56B7WE1W59B4WE1W62B1" + "WE1W59B4WE1W56B7WE1W53B10WE33W18" + "B13WE33W15B16WE33W12B19WE33W9B22" + "WE33W6B25WE33W3B28WE64WE64WE64WE"; for (i = 0; i < code.length(); i++) { ??? // ランレングス符号 code の i 番目の文字を ??? // c とおく。もし c が数字ならば、整数を表 ??? // す文字列バッファ number にその数字を追加 ??? // する。そうでなくて c が文字 W ならば、 ??? // number を文字列に変換し、整数に変換し、 ??? // その数だけ文字 . が並ぶ文字列をクラスメ ??? // ソッド charTimes を用いて構成し、その文 ??? // 字列を画面に出力する。number は数字のな ??? // い状態に戻す。c が文字 B ならば、同様に ??? // 文字 * が並ぶ文字列を構成する。c が文字 ??? // E ならば、画面で改行を行なう。c がどれで ??? // もなければ、エラーメッセージを画面出力す ??? // る。 } System.out.println(); } static String charTimes (char c, int times) { if (times < 0) { System.err.println("Under zero characters."); return ""; } else if (times > 100) { System.err.println("Too many characters."); return ""; } else { int i; StringBuffer s = new StringBuffer(""); for (i = 0; i < times; i++) { s = s.append(c); } return s.toString(); } } }
今日の演習11に従ってJavaプログラムを作成し、そのプログラムをkonishi@twcu.ac.jpあてにメールで提出してください。 メールには、学生番号、氏名、科目名、授業日(11/29)を明記してください。