Javaでコマンドライン引数とか

クイックハックなんだけど、諸事情でGNUのコード(GPL)を使えないので車輪の再発明

import java.lang.*;
import java.util.*;

class GetOpt{
   public static void main(String [] args){
      GetOpt getopt = new GetOpt(args);
   }
   private HashMap map;
   GetOpt(String [] s){
      map = new HashMap();
      for(int i=0; i<s.length; i++){
         if((s[i].charAt(0) == '-')){
            if(i == s.length-1 || s[i+1].charAt(0) == '-'){ // array boundary or no argument
               map.put(s[i].substring(1), Boolean.valueOf(true));
            }
            else{
               map.put(s[i].substring(1), s[++i]);
            }
         }
      }
      Iterator keys = map.keySet().iterator();
      Object o;
      System.out.println("Commandline Options:");
      while(keys.hasNext()){
         o = keys.next();
         System.out.println(o + ":" + map.get(o));
      }
   }
}
$ java GetOpt -aaaa bbb ccc -ddd -eee
Commandline Options:
aaaa:bbb
eee:true
ddd:true

Javaのお作法にあってるのかはよく分からないが・・・とりあえず期待通りに動いているのでOKかな。Javaは思想の割には制限が厳しい言語なので、というかオブジェクトとプリミティブな型がヘンに混じってて、charとStringなんかが典型だと思うんだけど、その辺がどうにも好きになれないなあ。
HashMap#putにプリミティブ型*1を直接入れられなかったりとか。Iteratorも、C++みたいに

while((o = keys.next()) != keys.end())

という書き方はできないのかな。まあ、結局は慣れの問題なのだろうけど。組み込み?でスレッドとかネットワークとか同期とかGUIとかの機能が充実しているJavaは便利だと思うし。

思い出した

Objectクラスをダウンキャスト*2しなきゃいけないのもとってもキモチワルイ・・・。C++では基本的にダウンキャストはしない方が望ましかったような・・・?

追記

Java 1.3.x系ではBoolean.valueOf(true))という書き方はできないらしい。うぐぅ

Boolean.valueOf("true"));

と文字列にするとOKっぽい。

*1:どうやらbooleanもプリミティブらしい?

*2:キーワードにないのか。スーパークラスからサブクラスへのキャスト、だと思う。Javaだとナローイングというのかな?