- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2019-11-14T15:11:44+09:00","ocha","ocha")
#author("2019-11-28T15:46:57+09:00","ocha","ocha")
[[Lecture]]
*Java プログラミング入門 [#de53d4fb]
このページは、学部2年生向け授業である、「マルチメディアプログラミング実習」
のために用意しました。
(Wikiの仕様で大文字小文字が混在した英単語に疑問符?が追加されるところがありますが、無視してください。)
**第9章 エラーと例外処理 [#gd4f8eae]
C言語では、エラーが出そうな処理をする場合は、エラーが発生するかどうかをステップごとにif文でチェックして、対処していました。プログラムが読みにくく煩雑になりがちです。
現代的な言語では、プログラムの処理をブロックでまとめて、その部分から発生したエラーを別の部分で受け取って処理をする書き方ができます。
Javaの多くのメソッドが標準的なエラー処理をサポートしています。また、自分でエラー処理を設計することも可能です。ただ、この授業の範囲では、自分でエラー処理を設計することはないと思います。標準的な機能の利用を練習しておきます。
次のプログラムを作って試してください。
引数が2個あることを前提としています。
なので、引数が少ないとエラーが出ます。確認してください。
public class TestException {
public static void main(String argv[]){
System.out.println(argv[0]+" "+argv[1]);
System.out.println("Nice to meet you.");
}
}
エラーが出る可能性のある場所をtryでくくっておき、
エラーが出たらそれを捕捉する処置をcatchで指定します。
public class TestException {
public static void main(String argv[]){
try{
System.out.println(argv[0]+" "+argv[1]);
System.out.println("Nice to meet you.");
}
catch (Exception e) {
System.out.println("please input 2 words.");
}
}
}
**第10章 Stringクラスとコレクションフレームワーク [#w938c6ce]
以下のリンクからStringクラスを選択して、何ができるかざっと見ておきましょう。
https://docs.oracle.com/javase/jp/8/docs/api/index.html
***最初の引数(文字列)を表示するプログラムを作る。クラス名はTestString [#xb389032]
public class TestString {
***Stringのメソッドをいくつか使ってみましょう [#v7994c3d]
public class TestString {
public static void main (String argue[]) {
String str = "Hello Java World";
//このstrを表示してください(System out.printlnを使う)
//strの長さを表示してください(.lengthを使う))
//strの3要素目の文字を表示してください
//最初にaが現れる位置を表示してください
//最後の文字aが現れる位置を表示してください
//辞書式で比較してstrと次のstr2をcompareToを使って比較してください。順番を変えるとcompareToが返す値はどうなるでしょう?
String str2="Have World";
//strの6要素目から始まる部分文字列を作り表示して表示してください。
//int型をString型に変換してください。
int v2020=2020;
String s2020 = String.valueOf(v2020);
}
}
解答例:
public class TestString{
public static void main(String args[]){
String str = "Hello Java World";
System.out.println(str);
System.out.println(str.length());
System.out.println(str.charAt(3));
System.out.println(str.indexOf('a'));
String str2 = "Hello World";
System.out.println(str.compareTo(str2));
System.out.println(str2.compareTo(str));
System.out.println(str.substring(6));
int v2020=2020;
String s2020 = String.valueOf(v2020);
System.out.println(s2020);
}
}
***演習:引数の文字列を逆に表示するプログラムを作る [#nc1414b9]
最初の引数(文字列)を表示するプログラムは、以下です。クラス名はTestStringにしました。
public class TestString {
public static void main(String argv[]) {
System.out.println(argv[0]);
}
}
}
***演習10.1改:最初の引数(文字列)を逆に出力するプログラムを作る [#k9b3a112]
これを元に、最初の引数(文字列)を逆に出力するプログラムを作ってください。例えば、ochanomizuと入力すると、以下のように表示されるプログラムを作ります。
[e100:?/Documents/java] siio% java TestString ochanomizu
ochanomizu
uzimonahco
[e100:?/Documents/java] siio%
さらには、引数がない場合は引数入力を促すことを表示してみよう。
[e100:?/Documents/java] siio% java TestString
please input a word
[e100:?/Documents/java] siio%
解答例:
このソースは、
public class TestString {
public static void main (String argv[]) {
try{
System.out.println(argv[0]);
int len = argv[0].length();
for(int i = len - 1; i>=0; i--) {
System.out.print(argv[0].charAt(i));
}
System.out.println();
}
catch (Exception e) {
System.out.println("please input a word");
}
}
}
である。
***Linked List の練習 [#d2a5cbd0]
***Linked List [#n28a2bc2]
サンプルプログラムを実行するときは、
https://docs.oracle.com/javase/jp/8/docs/api/index.html
LinkedList<String> list = new LinkedList<String>();
要素があって、次の要素へのポインターを持っているような、リスト構造です。
などと定義すると良い。
(element 1) ---> (element 2) ---> (element 3) ---> ... ---> (element n)
次のプログラムを作ってLinked Listのメソッドを使ってみましょう。
定義とコンストラクタで<String>と書くのは、要素がStringのインスタンスだという宣言です。
昔のJavaでは不要だったのですが、今のバージョンではこのような形式で明示的に書かないといけないようです。
***program 10.2 改造 [#j2f946c0]
Alice --> Bob --> Cindy --> DaveというLinkedListをつくって、
それからtoArray()メソッドでString配列を作ってfor each文で要素を印刷する
import java.util.*;
public class LinkedListTest{
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<String>();
String name1="ALICE";
String name2="BOB";
public static void main(String[] argv) {
//listにname1をaddしてください
//listにname2をaddしてください
//listの要素数を取得して表示してください
//listから最初の要素をgetFirstで取り出して表示してください
//listからget(1)してその結果を表示してください
LinkedList<String> list = new LinkedList<String>();
list.add("Alice");
list.add("Bob");
list.add("Dave");
list.add("Cindy");
String name3="CINDY";
String name4="DAVE";
//listにname3をaddしてください。
//listからname1を削除してください(remove)
//listにname4をaddFirstしてください。
//この結果、"DAVE" --> "BOB" --> "CINDY"となると思います。
Object[] names = list.toArray();
//listの全要素にアクセスするには、Iteratorインスタンスを作ると便利です。
//以下のようにして全要素を表示してください。
for(Object s: names ) System.out.println(s);
Iterator it = list.iterator();
while(it.hasNext()) {
String st = (String)it.next();
System.out.println(st);
}
}
//toArrayメソッドで配列を作ることもできます
//以下のようにして全要素を表示してください。
Object[] names = list.toArray();
for(Object s: names) System.out.println(s);
}
}
***Hash Mapの練習 [#jf7eb616]
解答例:
プログラム10.4を参考にして、
以下のように動作する英語ー日本語単語変換プログラムを作れ。
[e100:?/Documents/java] siio% java EtoJ banana
バナナ
[e100:?/Documents/java] siio% java EtoJ apple
りんご
[e100:?/Documents/java] siio% java EtoJ
Please input an English word
ヒント:
import java.util.*;
Import java.util.*;
public class EtoJ{
public class LinkedListTest{
public static void main(String args[]) {
HashMap<String,String> map = new HashMap<String,String>();
map.put("apple","りんご");
map.put("banana","バナナ");
map.put("orange","みかん");
map.put("pineapple","パイナップル");
map.put("grape","ぶどう");
map.put("peach","もも");
map.put("melon","メロン");
map.put("lemon","レモン");
try {
System.out.println(map.get(args[0]));
}
catch(Exception e) {
System.out.println("Please input an English word");
}
public static void main(String args[]){
}
}
**第11章 入出力 [#hb3a05b8]
***一番簡単なファイル書き出し [#y92c37db]
import java.io.*;
LinkedList<String> list = new LinkedList<String>();
public class FoutTest {
public static void main(String[] args) {
try {
FileOutputStream fout = new FileOutputStream("fout.dat");
fout.write(1234);
fout.close();
}
catch (IOException e) {
System.out.println(e);
}
}
}
これでfout.datという名前のファイルができあがるはずです。 作ったファイルを
od -h fout.dat
String name1 = "ALICE";
String name2 = "BOB";
または
hexdump fout.dat
してみてください
$ hexdump fout.dat
0000000 d2
0000001
1234は0x4d2だったのでその下1バイトが書き込まれました。
***整数を出力する例 [#j899e2e7]
import java.io.*;
list.add(name1);
list.add(name2);
System.out.println(list.size());
System.out.println(list.getFirst());
System.out.println(list.get(1));
public class DoutTest {
public static void main (String[] args) {
try {
FileOutputStream fout = new FileOutputStream("dout.dat");
DataOutputStream dout = new DataOutputStream(fout);
dout.writeInt(100);
dout.close();
}catch (Exception e) {
System.out.println(e);
}
}
}
これでdout.datという名前のファイルができあがるはずです。 作ったファイルを
od -h dout.dat
String name3 = "CINDY";
String name4 = "DAVE";
または
hexdump dout.dat
してみてください
e100:java siio$ hexdump dout.dat
0000000 00 00 00 64
0000004
***整数を入出力する例 [#j899e2e7]
import java.io.*;
list.add(name3);
list.remove(name1);
list.addFirst(name4);
public class DoutTest {
public static void main (String[] args) {
try {
FileOutputStream fout = new FileOutputStream("dout.dat");
DataOutputStream dout = new DataOutputStream(fout);
dout.writeInt(100);
dout.close();
FileInputStream finput = new FileInputStream("dout.dat");
DataInputStream dinput = new DataInputStream(finput);
System.out.println(dinput.readInt());
dinput.close();
}catch (Exception e) {
System.out.println(e);
}
}
}
***演習11.1 をやってください [#z72d00c6]
作ったファイルを
od -h dout.dat
または
hexdump dout.dat
してみてください
解答例
import java.io.*;
Iterator it = list.iterator();
while(it.hasNext()) System.out.println(it.next());
public class En111 {
public static void main (String[] args) {
int i;
try {
FileOutputStream fout = new FileOutputStream ("dout.dat");
DataOutputStream dout = new DataOutputStream(fout);
for(i=1;i<101;i++) dout.writeInt(i);
dout.close();
FileInputStream fin = new FileInputStream ("dout.dat");
DataInputStream din = new DataInputStream(fin);
for(i=1;i<101;i++) System.out.println(din.readInt());
din.close();
} catch (FileNotFoundException e) {
System.out.println(e);
} catch (IOException e) {
System.out.println(e);
}
}
}
***プログラム11.3をやってみてください [#h15edee7]
作ったファイルを
od -h
または
hexdump
してみてください
http://gyazo.com/74c061dfe2fcd6b72885878f867c78ba.png
import java.io.*;
Object[] names = list.toArray();
for(Object s: names) System.out.println(s);
public class PrintWriterTest{
public static void main(String[] args) {
try {
//writer.txtというファイルを作って文字を書き込む
FileWriter fwriter = new FileWriter("writer.txt");
PrintWriter pwriter = new PrintWriter(fwriter);
pwriter.println(2006);
pwriter.println("Java教科書");
//fwriter.write("Java教科書");
pwriter.close();
}
catch (IOException e) {
System.out.println(e);
}
}
}
つぎに、プログラム11.4を参考にして、
このPrint Writer Testに書き足して、
書き込んだデータを読み出して画面に表示するプログラムを作ってください。
ヒント:
import java.io.*;
public class PrintWriterTest{
public static void main(String[] args) {
try {
//writer.txtというファイルを作って文字を書き込む
FileWriter fwriter = new FileWriter("writer.txt");
PrintWriter pwriter = new PrintWriter(fwriter);
pwriter.println(2006);
pwriter.println("Java教科書");
//fwriter.write("Java教科書");
pwriter.close();
ここに書き足す
}
catch (IOException e) {
System.out.println(e);
}
}
}
解答例(丁寧版):
***文字ストリームをファイルに書いて読み込むプログラム [#bed8144f]
import java.io.*;
import java.util.*;
public class PrintWriterTest{
public static void main(String[] args) {
try {
//writer.txtというファイルを作って文字を書き込む
FileWriter fwriter = new FileWriter("writer.txt");
PrintWriter pwriter = new PrintWriter(fwriter);
pwriter.println("java 教科書" + 2001 );
pwriter.close();
//writer.txtのファイルの中身をSystem.out.printlnで表示する
FileReader freader = new FileReader("writer.txt");
BufferedReader breader = new BufferedReader(freader);
String tmp;
while( (tmp=breader.readLine() ) != null) {
System.out.println(tmp);
}
breader.close();
}
catch (IOException e) {
System.out.println(e);
}
}
}
***プログラム11.5をやってこれを拡張して演習11.2をやってください [#ya1ca508]
キーボードから1行入力された文字列によるテキストファイルを作る
http://gyazo.com/f9aee7f492d574f870e85e2022df374c.png
ヒント
import java.io.*;
public class En112 {
public static void main(String[] args) {
try {
public class LinkedListTest{
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<String>();
String name1="ALICE";
String name2="BOB";
list.add(name1);
list.add(name2);
String firstname=list.getFirst();
String secondname=list.get(1);
System.out.println("listの要素数は" + list.size());
System.out.println("listの最初の要素は" + firstname + "2番目の要素は" + secondname);
String name3="CINDY";
String name4="DAVE";
list.add(name3);
list.remove(name1);
list.addFirst(name4);
Iterator it = list.iterator();
System.out.println("要素の走査");
while(it.hasNext()){
String st = (String)it.next();
System.out.println(st);
}
System.out.println("要素の走査 by toArray()");
Object[] names = list.toArray();
for(Object s: names) System.out.println(s);
ここにプログラムを書く
}
catch(IOException e) {
System.out.println(e);
}
}
}
解答例
import java.io.*;
public class En112 {
public static void main(String[] args) {
try {
InputStreamReader ireader = new InputStreamReader (System.in);
BufferedReader breaderK = new BufferedReader(ireader);
String line = breaderK.readLine();
FileWriter fwriter = new FileWriter("writer.txt");
PrintWriter pwriter = new PrintWriter(fwriter);
pwriter.println(line);
pwriter.close();
FileReader freader = new FileReader("writer.txt");
BufferedReader breaderF = new BufferedReader(freader);
String tmp=null;
while( (tmp=breaderF.readLine()) != null)
System.out.println(tmp);
breaderF.close();
}
catch(IOException e) {
System.out.println(e);
}
}
}
}
***http://www.ocha.ac.jp/の内容を表示するプログラムを書いてみよう [#kf0c5bf6]
***Hash Set [#h59a37b5]
http://gyazo.com/13044fdd9d372118a1f6fe93896eadb3.png
https://docs.oracle.com/javase/jp/8/docs/api/index.html
Linked Listと同様にインスタンスの集まりを保持するデータ構造です。
ヒント1
(element 1) ---> (element 2) ---> (element 3) ---> ... (element n)
import java.net.*;
だだし、同一要素を重複して保持しません。
が必要です。
URL targetURL = new URL("http://www.ocha.ac.jp/");
でURLクラスのインスタンスが得られる。
InputStream istream = targetURL.openStream();
でこれからInputStreamのインスタンスが得られる。
InputStreamReader isreader = new InputStreamReader(istream);
でこれからInputStreamReaderのインスタンスが得られる。
BufferedReader breader = new BufferedReader( isreader );
でこれからBufferedReader のインスタンスが得られる。
ヒント2
import java.io.*;
import java.net.*;
import java.util.*;
public class URLTest {
public static void main (String argv[]) {
try {
ここにプログラムを書く
} catch (IOException e) {
System.out.println("error...");
}
}
}
ヒント3:
import java.io.*;
import java.net.*;
public class HashSetTest{
public static void main(String args[]){
HashSet<String> set = new HashSet<String>();
String name1="Alice";
String name2="Bob";
String name3="Cindy";
public class URLTest {
public static void main (String argv[]) {
try {
URL targetURL = new URL("http://www.ocha.ac.jp/");
InputStream istream = targetURL.openStream();
InputStreamReader isreader = new InputStreamReader(istream);
BufferedReader breader = new BufferedReader( isreader );
ここで一行ずつ読み込む
//setにname1をaddしてください
//setにname2をaddしてください
//setにname3をaddしてください
//setに再びname1をaddしてみてください。その時の戻り値 (booleanです)の状態を表示してください。
//setの内容をIteratorを使って全部表示してください。
} catch (IOException e) {
System.out.println("error...");
}
}
}
}
解答例:
import java.io.*;
import java.net.*;
public class URLTest {
public static void main (String argv[]) {
try {
URL targetURL = new URL("http://www.ocha.ac.jp/");
InputStream istream = targetURL.openStream();
InputStreamReader isreader = new InputStreamReader(istream);
BufferedReader breader = new BufferedReader( isreader );
String line;
while((line=breader.readLine()) != null) System.out.println(line);
} catch (IOException e) {
System.out.println("error...");
}
}
}
import java.util.*;
public class HashSetTest{
public static void main(String args[]){
HashSet<String> set = new HashSet<String>();
String name1="Alice";
String name2="Bob";
String name3="Cindy";
//name1,2,3を追加
set.add(name1);
set.add(name2);
set.add(name3);
//name1の再度追加を試みる。失敗
System.out.println(set.add(name1));
Iterator it = set.iterator();
while(it.hasNext())
System.out.println(it.next());
}
}
***写真ファイルのダウンロード [#edb3e256]
http://siio.jp/cat.jpg
***Hash Map [#ac67b323]
をダウンロードして、cat.jpgというファイルを作るプログラムを作ってください。
データはテキストじゃなくて、バイナリーです。
https://docs.oracle.com/javase/jp/8/docs/api/index.html
ヒント1:
2つのインスタンスのマッッピング(対応付け)の集まりを保持するクラスです。2つのインスタンスをキー(key)と値(value)と言います。例えば、keyもvalueもどちらもStringインスタンスの場合、以下のようにして要素を追加していきます。
InputStreamのインスタンスに対してread()メソッドを使うと1バイトのデータが得られます。読み終わると-1になります。
1バイトのデータを書き出すなら、FileOutputStreamだけで可能です。
ヒント2:
import java.io.*;
import java.net.*;
import java.util.*;
public class URLJpeg {
public static void main (String argv[]) {
try {
URL targetURL = new URL("http://siio.jp/cat.jpg");
InputStream istream = targetURL.openStream();
FileOutputStream fout = new FileOutputStream("cat.jpg");
というインスタンスを作って、
istream.read()
で読んで、
fout.write(1バイト)
で書き出します。
解答例
import java.io.*;
import java.net.*;
public class EtoJ{
//http://siio.jp/cat.jpg
//をダウンロードして、cat.jpgというファイルを作るプログラム
public static void main(String args[]) {
HashMap<String,String> map = new HashMap<String,String>();
map.put("apple","りんご");
map.put("banana","バナナ");
...
public class URLJpeg {
public static void main (String argv[]) {
try {
URL targetURL = new URL("http://siio.jp/cat.jpg");
InputStream istream = targetURL.openStream();
FileOutputStream fout = new FileOutputStream("cat.jpg");
int aData;
while((aData = istream.read()) != -1) fout.write(aData);
istream.close();
fout.close();
} catch (IOException e) {
System.out.println("error...");
}
}
}
}
このプログラムで、mapインスタンスからkeyに対応するvalueを取り出すためには、
map.get("apple");
***本日のレポート [#o4524903]
などとします。
上記のプログラム(URLJpeg.java, URLJpeg.class) を、出席番号+名前のフォルダにいれて、ZIP圧縮して提出してください。`
このプログラムを拡張して、以下のように動作する英語ー日本語単語変換プログラムを作ってください。
***写真読み込みの高速化 [#ia7ce1f8]
[e100:?/Documents/java] siio% java EtoJ banana
バナナ
[e100:?/Documents/java] siio% java EtoJ apple
りんご
[e100:?/Documents/java] siio% java EtoJ
Please input an English word
上記の例では写真データを1バイトずつ読み書きしていました。
InputStreamのメソッドを調べると、複数バイト単位で読み込むメソッドがあります。
たとえば、1024バイトずつ読み書きすることで、処理速度が向上すると期待できます。
そこで、複数バイト読み書きするよう、上記のプログラムを変更して、
実際にどの程度(実行速度にして何倍くらい)性能向上するか確認してみましょう。
解答例:
read
import java.util.*;
public int read(byte[] b)
throws IOException
入力ストリームから配列長さだけのバイト数を読み込もうとし、それをバッファ配列 b に格納します。
実際に読み込まれたバイト数は整数として返されます。
戻り値は、バッファに読み込まれたバイトの合計数。ストリームの終わりに達してデータがない場合は -1
を使って読みこみ、
write
public class EtoJ{
public void write(byte[] b,
int off,
int len)
throws IOException
指定された byte 配列の、オフセット位置 off から始まる len バイトを出力ストリームに書き込みます。
を使ってください。
-ヒント
byte[] data = new byte[1024];
という配列を用意して、
int datalength;
while(( datalength=istream.read(data)) != -1) fout.write(data, 0, datalength);
とします。
-解答例
import java.io.*;
import java.net.*;
public static void main(String args[]) {
HashMap<String,String> map = new HashMap<String,String>();
map.put("apple","りんご");
map.put("banana","バナナ");
map.put("orange","みかん");
map.put("pineapple","パイナップル");
map.put("grape","ぶどう");
map.put("peach","もも");
map.put("melon","メロン");
map.put("lemon","レモン");
try {
System.out.println(map.get(args[0]));
}
catch(Exception e) {
System.out.println("Please input an English word");
}
//http://siio.jp/cat.jpg
//をダウンロードして、cat.jpgというファイルを作るプログラムを作ってください。
//データはテキストじゃなくて、バイナリーです。
public class URLJpeg2 {
public static void main (String argv[]) {
byte[] data = new byte[1024];
try {
URL targetURL = new URL("http://siio.jp/cat.jpg");
InputStream istream = targetURL.openStream();
FileOutputStream fout = new FileOutputStream("cat.jpg");
int datalength;
while(( datalength=istream.read(data)) != -1) fout.write(data, 0, datalength);
istream.close();
fout.close();
} catch (IOException e) {
System.out.println("error...");
}
}
}
ここでは1024バイトを読み込むことにしました。でも、InputStreamのメソッドを見ると、available()というのがあります。
available()
この入力ストリームのメソッドの次の呼出しによって、ブロックせずにこの入力ストリームから読み込むことができる(またはスキップできる)推定バイト数を返します。
これを使えば、適切な長さを見積もれるかもしれません。
***引数のURLをファイルにするプログラムを考えてみましょう [#mc747214]
curlというコマンドがあります。
curl http://ocha.ac.jp/
などとすると、htmlが見られますし、
curl http://siio.jp/cat.jpg > cat.jpg
などとすると、ファイルとして保存できます。これに近いプログラムを作ってみましょう。
***宿題 [#wb66142e]
上記の引数のURLをファイルにするプログラムを作ってください。
また、cat.jpgのファイル取得でまとめて読むことでどれくらい速度が改善したかを、
レポートにしてください。レポートの書式は任意です。(テキストファイルでかまいません)
これらのjava, class, レポートのファイルをまとめて、出席番号+名前のフォルダに入れて、圧縮して、12月10日の授業の開始時間に提出してください。