javaアプリの実行時のファイルロードで、ファイルパスを相対パスで指定したい時、ウェブアプリや環境(OS)等によってどこにクラスパスが通っているのかが解らなくなる時がある。そんな時に実行時プログラムでjavaのクラスパスを取得したい時は下の通り。

String classpath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
System.out.println("classpath : " + classpath);

ただこれだと実行時のカレントディレクトリのみ。jarファイルがあるクラスパスもすべて見たい場合は下の通り。

System.out.println("classpath : " + System.getProperty("java.class.path"));

■参考
クラスパス(wiki)
⇒コマンドラインからクラスパスを指定してコンパイルとか


javaの計算誤差についてのメモ書き。

あるint型の変数i1に対して、int型の変数pで割り、int型の変数tを掛ける。この時、pとtは同じ値。結果iAns1はi1と等しいはずだが誤差が出る。下に計算例を書く。

int i1 = 165000;
int p = 23;
int t = 23;

double dbAns1;
int iAns1;
int iAns2;

dbAns1 = i1 / p * t;

iAns1 = i1 / p * t; //誤差あり
//iAns1 = i1 * (t / p ); //誤差なし
iAns2 = (int) dbAns1;

System.out.println("dbAns1:" + dbAns1);
System.out.println("iAns1:" + iAns1);
System.out.println("iAns2:" + iAns2);

■計算結果
dbAns1:164979.0
iAns1:164979
iAns2:164979

問題の計算例は、「iAns1 = i1 / p * t; //誤差あり」の部分。最初にi1/pを計算してint型の変数だと桁落ちしているんだろう。計算の順序を変更して「iAns1 = i1 * (t / p ); //誤差なし」を有効にすると、誤差はなくなる。

■計算結果
dbAns1:164979.0
iAns1:165000
iAns2:164979

BigDecimalを使ってもダメ。

BigDecimal bd1;
BigDecimal bdPass = new BigDecimal(p);
BigDecimal bdTarget = new BigDecimal(t);

bd1 = new BigDecimal(i1);
bd1 = bd1.divide(bdPass,1,BigDecimal.ROUND_HALF_UP).multiply(bdTarget);

System.out.println("bd1" + bd1);
System.out.println("bd1:" + bd1.doubleValue());

■計算結果
bd1164999.7
bd1:164999.7

変数i1をdouble型に変更すれば誤差は出ない。

double db1 = 165000;

double dbAns2;
int iAns3;
int iAns4;

dbAns2 = db1 / p * t;
iAns3 = (int)db1 / p * t;
iAns4 = (int) dbAns1;

System.out.println("dbAns2:" + dbAns2);
System.out.println("iAns3:" + iAns3);
System.out.println("iAns4:" + iAns4);

■計算結果
dbAns2:165000.0
iAns3:164979
iAns4:164979
mysqlのgroup by with rollup, group by with cubeについて。

tableの地区,手商品の二つのカラムでgroup byだけ書いた場合、もっとも低いレベル(この場合は地区と商品
)のみの集計値となる。上位グループの地区毎の集計値も欲しい場合、また別のsqlを書く必要がある。

けど、group by with roll upを使えば、上位グループと総計値も求めてくれるらしい。

・地区と商品、地区の2つのレベルで数量の合計を集計するsql
select 地区,商品, sum(数量) from 売上
group bu with rollup(地区,商品);

知らなかった。sqlを二つ書いたり、on memoryでやってた。気づきの世界だ。

あと、group by with cubeは、異なるグループの小計と総計が求められる。

・地区と商品、地区、商品の3つのレベルで数量の合計を集計するsql
select 地区,商品, sum(数量) from 売上
group bu with cube(地区,商品);

参考本
SQL実践リファレンス/九天社
¥2,625
Amazon.co.jp