俺のためのお仕事メモ(仮) > Javaの小技メモ

Java開発で頻繁に使うであろうプログラミング技術をメモしておきます。


【目次】


文字列操作


正規表現

Perlやシェルスクリプトを使ったことがある人にはお馴染みの正規表現です。
正規表現とは文字列のパターンを表現する手法です。
これが使えるとかなり便利ですよね。

正規表現早見表

^     行の先頭
$    行の末尾
.    改行以外の任意の1文字
[]    []でくくられた中にある任意の1文字
[^]   []でくくられた中にない任意の1文字
*    直前の文字の0個以上の並び
+    直前の文字の1個以上の並び
?    直前の文字が0個または1個
{x}   直前の文字のx個の並び
{x,}   直前の文字のx個以上の並び
{x,y}  直前の文字のx個以上、y個以下の並び
|    2者択一の演算子
【豆知識】 Perlを使った正規表現の例: RSAアルゴリズム
print pack"C*",split/\D+/,`echo "16iII*o\U@{$/=$z;[(pop,pop,unpack"H*",<> )]}\EsMsKsN0[lN*1lK[d2%Sa2/d0<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<J]dsJxp"|dc`

※正規表現用クラスはjava.util.regexパッケージに入っています。

パターンマッチ

正規表現を利用したパターンマッチです。
検索文字列にヒットすればTrueを返します。
/* パターンマッチのコーディング例 */

import java.util.regex.*;

public class ClassPatternmatch {
  public static void main(String[] args) {

    Pattern p;
    Matcher m;
    String str = "ABCDEF";

    //1.先頭が"ABC"で始まっていればTrueを返します。
    p = Pattern.compile("^ABC.*"); 
    m = p.matcher(str);
    boolean b = m.matches(); //bの中にはTrueが入ります。

    //2.A〜Zまでの文字列の0個以上の並びならTrueを返します。
    p = Pattern.compile("[A-Z]*"); 
    m = p.matcher(str);
    boolean b = m.matches(); //bの中にはTrueが入ります。

    //3.末尾が"DEF"で終わっていればTrueを返します。
    p = Pattern.compile("DEF$"); 
    m = p.matcher(str);
    boolean b = m.matches(); //bの中にはTrueが入ります。 

    //4."ABCDEF"か"abcdef"のどちらかならTrueを返します。
    p = Pattern.compile("ABCDEF|abcdef"); 
    m = p.matcher(str);
    boolean b = m.matches(); //bの中にはTrueが入ります。    
  }
}

分割

文字列の分割です。
指定した区切り文字で文字列を分割し、配列で返します。
/* 文字列分割のコーディング例 */

import java.util.regex.*;

public class ClassSplit {
  public static void main(String[] args) {

    Pattern p;
    Matcher m;
    String str = "AA,BB,CC";

    p = Pattern.compile(","); //区切り文字を指定
    String[] arr = p.split(str); //splitメソッドで分割し、配列arrに格納
    for (int i=0;i<arr.length;i++) {
      System.out.println(arr[i]);  //"AA","BB","CC"が出力されます。
    }  
  }
}

置換

文字列の置換です。
検索文字を指定した文字で置き換えます。
/* 文字列置換のコーディング例 */

import java.util.regex.*;

public class ClassReplace {
  public static void main(String[] args) {

    Pattern p;
    Matcher m;
    String str = "BABABAB";

    // 最初にマッチした文字列だけを置換
    p = Pattern.compile("AB");
    m = p.matcher(str);
    System.out.println(m.replaceFirst("ZZ")); //"BZZABAB"と出力されます。

    // マッチした文字列全てを置換
    p = Pattern.compile("AB");
    m = p.matcher(str);
    System.out.println(m.replaceAll("ZZ")); //"BZZZZZZ"と出力されます。

  }
}

連想配列

便利な連想配列です。
任意のキー名で値を呼び出すことができる配列です。
/* 連想配列のコーディング例 */

import java.util.Hashtable;
import java.util.Enumeration;

class ClassHash {

  public static void main(String args[]) {

    //価格リストを作成
    Hashtable price = new Hashtable();
    price.put("banana","50");
    price.put("apple","80");
    price.put("orange","120");

    //"banana"の値段を表示
    System.out.println( (String)price.get("banana") );

    //価格リストを表示
    Enumeration e = price.elements();
    while (e.hasMoreElements()){
      System.out.println(e.nextElement());
    }
  }

}

※連想配列操作用クラスはjava.util.Hashtable,java.util.Enumerationパッケージに入っています。

ファイル入出力


ファイル出力

ファイルにデータを出力するにはBufferedWriterを使います。
/* ファイル出力 */
import java.io.*;

public class ClassBufferWriter {
  public static void main(String[] args) {
    try {

      BufferedWriter bw =
         new BufferedWriter(
             new OutputStreamWriter(
                new FileOutputStream("test.txt"),"MS932")); //"test.txt"は出力先ファイル名、
                                                                //"MS932"は文字エンコーディング方法です。

      String msg = "ファイル出力のてすとです。";
      bw.write(msg); //書き込み!
      bw.close(); //ファイルクローズ

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

※ファイル入出力用クラスはjava.ioパッケージに入っています。

ファイル入力

ファイルからデータを読み込むにはBufferedReaderを使います。
/* ファイル入力(読み込み) */
import java.io.*;

public class ClassBufferedReader {
  public static void main(String[] args) {
    try {

      BufferedReader br =
         new BufferedReader (
             new InputStreamReader(
                new FileInputStream("test.txt"),"MS932")); //"test.txt"は読み込むファイル名、
                                                               //"MS932"は文字エンコーディング方法です。

      String msg;

      msg = br.readLine(); //ファイルから一行目読み込み!
      System.out.println(msg);  //一行目表示

      msg = br.readLine(); //ファイルから二行目読み込み!
      System.out.println(msg);  //二行目表示

      br.close();  //ファイルクローズ

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

※ファイル入出力用クラスはjava.ioパッケージに入っています。

文字のエンコード

文字のエンコードです。
ここではEUCJP.txtというEUCJP形式で保存されたテキストファイルをSJIS形式に変換し、SJIS.txtに保存しています。
あらかじめEUCJP.txtというEUCJP形式のテキストファイルをこのクラスと同じパスに作成しておいてください。
/* 文字のエンコード */
import java.io.*;
public class ClassEncoding{
  public static void main(String[] args){
    try{

      //入力用ストリームの生成
      FileInputStream fis = new FileInputStream("EUCJP.txt");
      InputStreamReader isr = new InputStreamReader(fis,"EUCJP"); //EUCJP形式としてEUCJP.txtを読み込みます。
      BufferedReader br = new BufferedReader(isr);

      //出力用ストリームの生成
      FileOutputStream fos = new FileOutputStream("SJIS.txt");
      OutputStreamWriter osr = new OutputStreamWriter(fos,"SJIS"); //SJIS形式でSJIS.txtに書き込み保存します。
      BufferedWriter bw = new BufferedWriter(osr);
   
      String line;

      //書き込み
      while((line = br.readLine()) != null){
        bw.write(line);
        bw.newLine();
      }

      //ストリームを閉じる
      br.close();
      bw.flush();
      bw.close();

    }catch(FileNotFoundException e){
      System.out.println("ファイルが見つかりません。");
    }catch(IOException e){
      System.out.println("入出力エラーが発生しました。");
    }
  }
}

※ファイル入出力用クラスはjava.ioパッケージに入っています。

データベース操作


PostgreSQL編

PostgreSQL用のJDBCドライバ(jdbc***.jar)をJavaのホームフォルダのlibフォルダにコピーし、CLASSPATHを追加しておきます。
/* データベース操作(PostgreSQL) */
import java.sql.*;

public class ClassJDBC {
  public static void main(String[] args) {
    try {

      //ドライバをロード
      Class.forName("org.postgresql.Driver"); 

      //パラメータを設定し、DBサーバへ接続
      Connection cn =
		DriverManager.getConnection(
			"jdbc:postgresql://hostname:port/databasename",
			"user", "password"); 

      //ステートメント作成
      Statement stmt = cn.createStatement(); 

      // ----- DELETE,INSERT,UPDATEを行う場合 -----
      String sql = "DELETE FROM tablename";
      // クエリーを実行
      int count = stmt.executeUpdate(sql); //DELETE,INSERT,UPDATE文は"executeUpdate"で実行します。
                                                 //戻り値は実行されたレコード数。

      // ----- SELECT(検索)を行う場合 -----
      sql = "SELECT * FROM tablename";
      // クエリーを実行
      ResultSet rs = stmt.executeQuery(sql); //SELECTは"executeQuery"で実行します。
                                                           //戻り値はResultSetオブジェクトです。

      // 検索された行数分ループ
      while(rs.next()){
        int f1 = rs.getInt("F1"); // Field名"F1"データ型整数のデータを取得します。
        String f2 = rs.getString("F2"); // Field名"F2"データ型文字列のデータを取得します。
      }
      
      // データベースから切断
      stmt.close();
      cn.close();

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

※データベース操作用クラスはjava.sqlパッケージに入っています。

MySQL編

MySQL用のJDBCドライバ(jdbc***.jar)をJavaのホームフォルダのlibフォルダにコピーし、CLASSPATHを追加しておきます。
PostgreSQL用コードのはじめの方にある2行(DB接続パラメータ設定部分)をMySQL用に修正すれば、それ以外はまったく同じソースコードでOKです。
      //ドライバをロード
      Class.forName("org.gjt.mm.mysql.Driver");

      //パラメータを設定し、DBサーバへ接続
      Connection cn =
		DriverManager.getConnection("jdbc:mysql://hostname:port/databasename",
			           "user", "password"); 

※データベース操作用クラスはjava.sqlパッケージに入っています。

ODBC編

あらかじめJDBCで利用するODBCドライバを設定しておきます。
PostgreSQL用コードのはじめの方にある2行(DB接続パラメータ設定部分)をODBC用に修正すれば、それ以外はまったく同じソースコードでOKです。
      //ドライバをロード
      Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

      //パラメータを設定し、DBサーバへ接続
      Connection cn =
		DriverManager.getConnection("jdbc:odbc:helloworld",
			           "user", "password"); 

※データベース操作用クラスはjava.sqlパッケージに入っています。

通信


ソケット通信

サーバとクライアント間でのソケット通信です。
サンプルはクライアントから送られてきたデータをそのまま返す単純なプログラムです。
/* ソケット通信(サーバ側) */
import java.net.*;
import java.io.*;

public class ClassSocketServer {
  public static void main(String[] args) {
    try{
      // サーバーソケットの生成(ポート番号12345)
      ServerSocket ss = new ServerSocket(12345);
      //クライアントからの接続をポート12345で待受け・・・
      Socket s = ss.accept();
      System.out.println(s.getInetAddress() + "から接続がありました!");

      // 出力ストリームを取得
      PrintWriter o = new PrintWriter(s.getOutputStream(), true);
      // 入力ストリームを取得
      BufferedReader i = new BufferedReader(
                              new InputStreamReader(
                              s.getInputStream()));

      // クライアントからの受信データをそのままクライアントへ返信)
      String inputLine;
      while ((inputLine = i.readLine()) != null) {
        o.println(inputLine); //送信(返信)
      }

      // 入出力ストリームを閉じる
      o.close();
      i.close();
      // ソケットを閉じる
      s.close();
      // サーバーソケットを閉じる
      ss.close();

    } catch(IOException e){
      e.printStackTrace();
    }
  }
}
/* ソケット通信(クライアント側) */
import java.net.*;
import java.io.*;

public class ClassSocketClient {
  public static void main(String[] args){
    try{
      // ソケットを生成(ポート番号12345)
      Socket s = new Socket("localhost", 12345);

      // 出力ストリームを取得
      PrintWriter o = new PrintWriter(s.getOutputStream(), true);
      // 入力ストリームを取得
      BufferedReader i = new BufferedReader(
                              new InputStreamReader(
                              s.getInputStream()));

      // "こんにちわ。"をサーバーに送信
      o.println("こんにちわ。");
      // サーバから受信したデータを表示
      System.out.println(i.readLine()); //"こんにちわ。"と表示されます

      // 入出力ストリームを閉じる
      o.close();
      i.close();
      // ソケットを閉じる
      s.close();

    } catch(IOException e){
      e.printStackTrace();
    }
  }
}

※ソケット通信用クラスはjava.netjava.ioパッケージに入っています。

HTTP通信(GET)

コマンドプロンプトから引数から渡されたURLのWebサーバにGET送信し、サーバからのレスポンスを表示します。
/* HTTP通信(GET) */
import java.net.*;
import java.io.*;
public class ClassHttpGet {
  public static void main(String[] args) {
    try {
      // 引数からURLを取得
      String url = args[0];

      // URLクラスのインスタンスを生成
      URL u = 
         new URL(url);

      // 入力ストリームを生成
      BufferedReader i = new BufferedReader(
                                new InputStreamReader(
                                u.openStream()));

      // サーバからのレスポンスを一行ずつ読み込みます
      String line;
      while ((line = i.readLine()) != null) {
        // 表示します
        System.out.println(line);
      }
    
      // 入力ストリームを閉じます
      i.close();

    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}
実行方法

% java ClassHttpGet http://ウェブサーバのURL/ ↓

※HTTP通信用クラスはjava.netjava.ioパッケージに入っています。

XMLファイル操作


XMLファイルの読み込み(DOM)

XMLの操作にはSAXを使う方法とDOMを使う方法がありますが、今回はDOMを利用してみます。
XMLファイルを読み込み、情報を取り出し、画面に表示してみます。
まずは適当なXMLファイルを作ってみます。

XMLファイル名: chemistry.xml

<?xml version="1.0" encoding="Shift_JIS" ?>
<album>
  <artist>CHEMISTRY</artist>
  <music id="001">
    <title>SOLID DREAM</title>
    <estimation>★★★★★</estimation>
  </music>
  <music id="002">
    <title>Point Of No Retern</title>
    <estimation>★★★</estimation>
  </music>
  <music id="003">
    <title>PIECES OF A DREAM</title>
    <estimation>★★★★</estimation>
  </music>
</album>

ソースコード: ClassXMLDOM.java

/* DOMを利用したXMLファイルの読み込み */
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;
public class ClassXMLDOM {
  public static void main(String[] args) {
    try {
      // ドキュメントビルダーファクトリを生成
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      // ドキュメントビルダーを生成
      DocumentBuilder db = dbf.newDocumentBuilder();
      // パースを実行してDocumentオブジェクトを取得
      Document doc = db.parse(new File("chemistry.xml"));
      // ルート要素を取得(タグ名:album)
      Element root = doc.getDocumentElement();
      System.out.println("ルート要素のタグ名:" + root.getTagName());

      // artist要素のリストを取得(アーティストなのでデータは一個)
      NodeList artistLst = root.getElementsByTagName("artist");
      // artist要素を取得
      Element artistEle = (Element)artistLst.item(0);
      // artist要素の最初の子ノード(テキストノード)の値を取得
      String artist = artistEle.getFirstChild().getNodeValue();
      System.out.println("アーティスト:" + artist + "\n"); //出力

      // music要素のリストを取得
      NodeList musicLst = root.getElementsByTagName("music");
      // music要素の数だけループ
      for (int i=0; i < musicLst.getLength() ; i++) {
        // music要素を取得
        Element musicEle = (Element)musicLst.item(i);
        // id属性の値を取得
        String id = musicEle.getAttribute("id");
        // title要素のリストを取得
        NodeList titleLst = musicEle.getElementsByTagName("title");
        // title要素を取得
        Element titleEle = (Element)titleLst.item(0);
        // title要素の最初の子ノード(テキストノード)の値を取得
        String title = titleEle.getFirstChild().getNodeValue();
        // estimation要素のリストを取得
        NodeList estimationLst = musicEle.getElementsByTagName("estimation");
        // estimation要素を取得
        Element estimationEle = (Element)estimationLst.item(0);
        // estimation要素の最初の子ノード(テキストノード)の値を取得
        String estimation = estimationEle.getFirstChild().getNodeValue();

        // 画面にリスト出力
        System.out.println("I  D:" + id + "\n" +
                           "タイトル:" + title + "\n" +
                           "評  価:" + estimation + "\n" +
                           "-----------------------------------------------------");
      }

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

実行結果
ルート要素のタグ名:album
アーティスト:CHEMISTRY

I  D:001
タイトル:SOLID DREAM
評  価:★★★★★
-----------------------------------------------------
I  D:002
タイトル:Point Of No Retern
評  価:★★★
-----------------------------------------------------
I  D:003
タイトル:PIECES OF A DREAM
評  価:★★★★
-----------------------------------------------------

【DOMの操作手順】

1.ドキュメントビルダーファクトリを生成
2.ドキュメントビルダーを生成
3.パースを実行してDocumentオブジェクトを取得
4.ルート要素を取得
5.ノードリストを取得
6.要素を取得
7.要素の値を取得

1〜4はXMLファイル1枚につき必ず一回行い、5〜7は取り出したい要素ごとに行います。

※XMLファイル操作用クラスはjavax.xml.parsersorg.w3c.domjava.ioパッケージに入っています。

その他


オブジェクトのシリアライズ

オブジェクトのシリアライズを行うことにより、オブジェクトの中身をファイルに保存しておいて再利用できます。
/* シリアライズされるクラス */
import java.io.*;
public class Person implements Serializable{
  private String name;
  private int age;
  // Personオブジェクトにデータをセットするメソッド
  public Person(String name,int age){
    this.name = name;
    this.age = age;
  }
  // Personオブジェクトの情報を出力するメソッド
  public String getInfo(){
    return ("Personの情報 name:" + name + " age:" + age);  
  }
}
/* オブジェクトファイルにシリアライズされたオブジェクトを出力 */
import java.io.*;
public class ClassWriteObject{
  public static void main(String[] args){
    try{
      //オブジェクト出力ストリームの作成
      ObjectOutputStream oos = 
        new ObjectOutputStream(
          new FileOutputStream("objectfile"));

      //オブジェクトにパラメータをセット
      Person p = new Person("AKIRA",26);
      
      //オブジェクトファイルに書き込む
      oos.writeObject(p);

      //オブジェクト出力ストリームを閉じる
      oos.close();

    }catch(IOException e){
      System.out.println("入出力エラーが発生しました。");
    }
  }
}
/* オブジェクトファイルからシリアライズされたオブジェクトを読み込む */
import java.io.*;
public class ClassReadObject{
  public static void main(String[] args){
    try{
      //オブジェクト入力ストリームの作成
      ObjectInputStream ois = 
        new ObjectInputStream(
          new FileInputStream("objectfile"));

      //オブジェクトを読み込む
      Person p = (Person)ois.readObject();
      
      //読み込まれたオブジェクトの情報を出力
      System.out.println(p.getInfo());

      //オブジェクト出力ストリームを閉じる
      ois.close();

    }catch(ClassNotFoundException e){
      System.out.println("クラスが見つかりません。");

    }catch(IOException e){
      System.out.println("入出力エラーが発生しました。");
    }
  }
}
ClassWriteObjectを実行し、次にClassReadObjectを実行すると、以下のような結果が出力されます。

Personの情報 name:AKIRA age:26

※シリアライズ用クラスはjava.ioパッケージに入っています。

今後もこまめに追加予定。。。


Copyright (C) 2004 tanaka akira. All Rights Reserved.