総当りのアルゴリズム

(0,0)(0,1)(1,1)は出現するが(1,0)は出現しない組み合わせを作るアルゴリズムは難しそうだが意外に簡単に出来る

for i in 0..2
  for j in 0..i
    for k in 0..j
      for m in 0..k
        p [i,j,k,m]
      end
    end
  end
end


出力結果

[0, 0, 0, 0]
[1, 0, 0, 0]
[1, 1, 0, 0]
[1, 1, 1, 0]
[1, 1, 1, 1]
[2, 0, 0, 0]
[2, 1, 0, 0]
[2, 1, 1, 0]
[2, 1, 1, 1]
[2, 2, 0, 0]
[2, 2, 1, 0]
[2, 2, 1, 1]
[2, 2, 2, 0]
[2, 2, 2, 1]
[2, 2, 2, 2]

JavaのCSVライブラリ

JavaCSVライブラリにはこれといった標準のものがないので困る。
opencsv、SuperCsv、OrangeSingnalCsvなど一応あるにはあるがどれもいまいち。


その中ではSuperCsvがよさそうなんだけど、CSV→Bean変換に致命的な問題がある。
CSVのカラムが空の場合CsvBeanReaderでNullPointerExceptionが発生してしまう。
仕方ないのでCsvListReaderを使うことになる。


そんなこんなでおすすめできるCSVライブラリがJavaにはない。
他にApache CommonsのSandboxにもあったかもしれないが、どこか有名どころが品質のいいものを作ってくれないだろうか・・・

バッチファイルの引数の情報を取得する

バッチファイルの引数(パラメータ)を取得する際には、一部の情報だけを取得することができる。
たとえば、引数の中からドライブ名だけ取得するなんてことができる。


以下のようなバッチファイルでどうなるか試してみる。

@echo off
echo %%0 = %0
echo %%~0 = %~0
echo %%f0 = %f0

echo %%~f0 = %~f0
echo %%~d0 = %~d0
echo %%~p0 = %~p0
echo %%~n0 = %~n0
echo %%~x0 = %~x0
echo %%~s0 = %~s0
echo %%~a0 = %~a0
echo %%~t0 = %~t0
echo %%~z0 = %~z0

echo %%~dp0 = %~dp0
echo %%~nx0 = %~nx0
echo %%~dpnx0 = %~dpnx0
echo %%~ftza0 = %~ftza0

echo %%~pd0 = %~pd0
echo %%~aztf0 = %~aztf0
echo %%~fdpnxatz0 = %~fdpnxatz0

pause

出力結果

%0 = "E:\research\bat\parameter-test.bat"
%~0 = E:\research\bat\parameter-test.bat
%f0 = f0
%~f0 = E:\research\bat\parameter-test.bat
%~d0 = E:
%~p0 = \research\bat\
%~n0 = parameter-test
%~x0 = .bat
%~s0 = E:\research\bat\PARAME~1.BAT
%~a0 = --a------
%~t0 = 2010/09/26 22:55
%~z0 = 417
%~dp0 = E:\research\bat\
%~nx0 = parameter-test.bat
%~dpnx0 = E:\research\bat\parameter-test.bat
%~ftza0 = --a------ 2010/09/26 22:55 417 E:\research\bat\parameter-test.bat
%~pd0 = E:\research\bat\
%~aztf0 = --a------ 2010/09/26 22:55 417 E:\research\bat\parameter-test.bat
%~fdpnxatz0 = --a------ 2010/09/26 22:55 417 E:\research\bat\parameter-test.bat

順番を入れ替えても(%~dp0でも%~pd0でも)結果は変わらないようだ。


詳細はMicrosoftのページなど参照。
http://technet.microsoft.com/ja-jp/library/cc755880%28WS.10%29.aspx
http://technet.microsoft.com/ja-jp/library/cc758944%28WS.10%29.aspx

バッチファイルで環境変数の文字列を置換する

Windowsのバッチファイルのコマンドで、環境変数の文字列は簡単に置き換られる。

今日の日付をファイル名の一部にしたいなんて場合、環境変数の%DATE%に日付が入ってるんだけど
2010/09/24のようにスラッシュが入ってるのでそのままではファイル名に使えなくて困る。


そういうときは%DATE:/=-%のようにすれば、/を-に変換できる。(→ 2010-09-24)
%DATE:/=%にすれば、/を消すこともできる。(→ 20100924)


文字の置換ではなくて、文字列の置換であることに注意。
%DATE:20=ab%とするとab10/09/24になる。

JRubyでJavaのclassオブジェクトへのアクセス

JRubyJavaのClassクラスのメソッドを元の名前(getMethodsなど)で
使いたいときなどに、Javaのclassオブジェクトに直接アクセスしたいことがある。
その場合は.java_class.to_javaか.getClassを用いればいい。

jirbで実行した結果

irb(main):001:0> include Java
=> Object
irb(main):002:0> d = java.util.Date.new
=> #<Java::JavaUtil::Date:0x24a09e41>
irb(main):003:0> d.class
=> Java::JavaUtil::Date
irb(main):004:0> d.java_class
=> class java.util.Date
irb(main):005:0> d.java_class.to_java
=> #<Java::JavaLang::Class:0x372943ac>
irb(main):006:0> d.getClass
=> #<Java::JavaLang::Class:0x372943ac>

Java to Ruby 変換表

JRubyで呼び出したJavaメソッドからの戻り値が、Rubyのどの型に変換されるか調べた

Java戻り値 Ruby
boolean true, false
char Fixnum
byte Fixnum
short Fixnum
int Fixnum
long Fixnum
float Float
double Float
String String
BigInteger Bignum

Wrapperクラスのときも型変換はされた。
Collectionや配列は変換されなかった。
Javaのメソッドで戻り値型をNumberにしたところ、実際の中身の型で変換された。

Rubyのオブジェクトを返したい場合

JavaからRubyのArrayを返したい場合はorg.jruby.RubyArray#newArray(org.jruby.Ruby)を使用できる

	public List getList(org.jruby.Ruby runtime){
		List list = org.jruby.RubyArray.newArray(runtime);
・・・

ただしArrayを作成するためにはRubyランタイムを渡す必要がある。
(このメソッドをJRubyから使用する場合はobj.getList(JRuby.runtime)のようにする)

Ruby Hash to Java Map Conversion Bug

一度、型変換に失敗すると同一オブジェクトでの型変換ができなくなることがあるようです。

include Java

hash = {"a"=>"b"}
hash2 = {"a"=>"b"}

begin
java.util.Collections.fill(hash, "a")
rescue; end
java.util.HashMap.new.putAll(hash)
#java.util.HashMap.new.putAll(hash2) #ok
map.rb:9: cannot convert instance of class org.jruby.RubyHash to interface java.
util.Map (TypeError)