【Java】Mapへの初期代入について
JavaでMapを作成して最初に何か値を代入したい場合、通常は以下のようにすると思います。
Java8でのHashMapの生成と代入例:
Map<String, String> map = new HashMap<>(); map.put("hoge", "fuga"); map.put("foo", "bar");
ただ、他の言語を触っている人だと、Mapの作成と同時に値を設定して置きたいと感じるのではないでしょうか。
例えば下のコードのような形です。
my %map = ('hoge' => 'fuga', 'foo' => 'bar');
これをJavaでやろうとすると以下のようにすることで実現できます。
Java8でのHashMapの生成と初期代入例:
Map<String, String> map = new HashMap<String, String>() {{ put("hoge", "fuga"); put("foo", "bar"); }};
ただしJavaでこの方法を使う場合、一点だけ注意が必要です。
それは、mapのインスタンスの実クラスがHashMapではなくHashMapを継承した匿名クラスになってしまうということ。
どういうことかを説明するために、上記のコードを匿名クラスを使わない書き方に変更すると次のようになります。
Java8でのHashMapの生成と初期代入例(匿名クラスを使わない):
class ExtendedHashMap extends HashMap<String, String> { { put("hoge", "fuga"); put("foo", "bar"); } }; Map<String, String> map = new ExtendedHashMap();
ではこれで何か不都合が起こるかという話なのですが、map.getClass()などでクラスの情報を取るような場合に思った通りのクラス名が取得できないというデメリットがあります。
実際に「Java8でのHashMapの生成と初期代入例」のプログラム実行後に、map.getClass().getName()を取得してみると「プログラム名$1」という結果が返ってくるはずです。
自分の組んだプログラム内では問題がなくても、フレームワークや外部モジュールの作りによっては、もしかしたらここが落とし穴になるかもしれませんね。
【Ruby】RMagickで画像を一括リサイズ
大量の画像を一気に同一サイズにリサイズしたいときってありますよね。
僕も前にある大量のサムネイル画像をブログに掲載する際にそれが必要になり、いろんなツールを試した記憶があります。
今回はRubyでRMagickを使った一括リサイズ処理を書いたのでこちらに載せておきます。
あ、RMagickが動作する環境が必要なので注意してくださいね。
コード: resizer.rb
#!/usr/bin/ruby require 'RMagick' require 'optparse' input = "./input" output = "./output" scale = 1.0 width = 0 height = 0 opt = OptionParser.new opt.on('-w', '--width VALUE', 'リサイズする横幅(px)') { |v| width = v.to_i } opt.on('-f', '--height VALUE', 'リサイズする縦幅(px)') { |v| height = v.to_i } opt.on('-s', '--scale VALUE', '倍率') { |v| scale = v.to_f } opt.on('-i', '--input DIR OR FILE', '処理対象のディレクトリ') { |v| input = v.to_s } opt.on('-o', '--output DIR', '出力先のディレクトリ') { |v| output = v.to_s } begin opt.parse(ARGV) rescue OptionParser::InvalidOption => e abort "無効なオプション指定が含まれています" end files = [] if FileTest.directory? input files = Dir.glob(input + "/*") elsif FileTest.file? input files[0] = input else abort "無効なinput指定です.[ input = #{input} ]" end # 出力先がなければ作成 unless FileTest.directory? output Dir.mkdir(output, 0755) end files.each do |file| begin original = Magick::ImageList.new(file) rescue => error puts "ファイルを読み込めないためスキップ.[ file = #{file} ]" next end # 倍率指定をもとにwidthとheightを決定 if scale resizedWidth = (original.columns * scale).to_i resizedHeight = (original.rows * scale).to_i end if width != 0 resizedWidth = width.to_i end if height != 0 resizedHeight = height.to_i end if resizedWidth == 0 or resizedHeight == 0 puts "サイズ指定が不正なためスキップ.[ file = #{file}, width = #{width}, height = #{height}, scale = #{scale} ]" next end image = original.scale(resizedWidth, resizedHeight) file_parts = file.split("/") image.write("#{output}/#{file_parts.last}") end
使い方:(widthとheightを指定)
以下のようにして入力元、出力先、サイズを指定して実行します。
ruby resizer.rb -i ./input -o ./output -w 320 -h 240
これでinputディレクトリ配下の画像ファイルが320x240にリサイズされてoutputディレクトリに出力されます。
※アスペクト比は維持されないので注意して下さい。
(アスペクト比を維持したい場合は、original.scaleの行をoriginal.resizeへ変更すると良いです)
使い方:(scaleを指定)
ruby resizer.rb -i ./input -o ./output -w 0.5
これでinputディレクトリ配下の画像ファイルが元のサイズの縦横それぞれ0.5倍にリサイズされてoutputディレクトリに出力されます。
注意
-i(--input)、及び-o(--output)を省略した場合はデフォルトでそれぞれ./inputと./outputが指定されます。
-i(--input)に指定したディレクトリが存在しない場合は、エラーになります。
-o(--output)に指定したディレクトリが存在しない場合は、新たに生成します。