|Java| StreamAPI アトミックでない処理での注意
下記の処理は結果が実行毎に異なる。
parallel()により並列でラムダ式内の処理が実行されるが、インクリメント/デクリメントがアトミックで無いため足し引きのタイミングによって結果(p.x)が異なってしまう。
import java.util.stream.IntStream; public class Test01 { public static void main(String[] args) { Person p1 = new Person(); IntStream.range(0, 100000).parallel().forEach(i -> { if (i % 2 == 0) { p1.x++; } else { p1.x--;} ; }); System.out.println(p1.x); // 結果がランダム Person p2 = new Person(); IntStream.range(0, 100000).parallel().forEach(i -> { if (i % 2 == 0) { p2.inc(); } else { p2.dec();} ; }); System.out.println(p2.x); // 結果は常にゼロ } } class Person { int x; synchronized void inc() { x++; } synchronized void dec() { x--; } }
|その他| PCでKindle本を読む
1. Bluestacks をインストールして、Kindleアプリをインストール
http://www.bluestacks.com/
2. レジストリエディタ(regedit)で、height/width を調整。
HKEY_LOCAL_MACHINE
└SOFTWARE
└BLUESTACKS
└FrameBuffer
→Kindle for PC が登場したのでBlustacksは現在利用していない。
|HTML5| フレームワーク?メモ
|Java| Java7 Gold 取得に向けてメモ
忘れそうな事柄をメモ
列挙型
イニシャライザの呼び出し順序
super……親クラス
sub……子クラス
static { } …… static イニシャライザ
{ } …… イニシャライザ
() …… コンストラクタ
- super static { }
- sub static { }
- super { }
- super ()
- sub { }
- sub ()
- super { }
- super ()
- sub { }
- sub ()
可変長引数
- メソッド呼出時の引数が明確なメソッドが優先的に実行される.
// x.method(1, 2); の場合 void method(int... a) {} void method(int a, int b) {} // こっちが実行される
- 引数に null
// m(null); public static void m(int... ary) { System.out.println(ary); } // 正常にコンパイル -> null public static void m(String... ary) { System.out.println(ary); } // コンパイルで警告 -> null タイプ null の引数は、タイプ InitializerSub からの 可変引数メソッド m(String...) の呼び出しに対しては String[] へ 明示的にキャストする必要があります。 あるいは、可変引数呼び出しに対しては String へキャストすることもできます →回避するには、m((String) null); or m((String[]) null);
|Java| フレームワーク選別
随時、追記していきます。
2015/05/24 現在、自分の中での組み合わせは
SpringMVC + Spring4 + DBFlute + Lombok + Thymeleaf
です。(但し、SpringMVC周りは拡張)
(自分の中で) 今後使ってみたい、興味のあるフレームワーク
テンプレートエンジン
フロント・コントローラ周り
- Play Framework …… フロントに限らないフルスタック。大規模PJでも使えるか、まだ判断できないので見送り中
(自分の中で) 使いたくないフレームワーク
フロント・コントローラ周り
|JavaScript| コーディング規約
1. 「==」は使わず「===」を使う
[改善前] var a = 1; var b = "1"; if (a == b) { // 暗黙の型変換が行われるため、通る }
[改善後] var a = 1; var b = "1"; if (a === b) { // 暗黙の型変換が行われないため、通らない }
暗黙の型変換に頼らず、型を合わせるときは明示的に型変換をすること。
2. 変数の宣言には必ず「var」を利用する
[改善前] a = 1;
[改善後] var a = 1;
暗黙の変数定義はグローバル変数となる。グローバル変数は悪と考え、変数の定義は全て「var」を利用すること。(また、strict モードでは改善前のコードは「Uncaught ReferenceError: a is not defined」となり利用できない。)
3. 早期リターン
[改善前] function func(x) { if (x === 1) { // ここに処理 } }
[改善後] function func(x) { if (x !== 1) { return; } // ここに処理 }
インデントが深いと見づらい。ので、特定条件の場合に処理をするのではなく、その反対の条件で早期にリターンし、その後に処理を記述する。
4. 子コンストラクタでは親コンストラクタを呼ぶ、かつprototypeに親を紐付けること
[改善前] function Animal(x) { this.x = x; } function Person(h, w) { this.h = h; this.w = w; } Person.prototype = new Animal(10); // 継承時点で値が必要
[改善後] function Animal(x) { this.x = x; } function Person(x, h, w) { Animal.call(this, x); this.h = h; this.w = w; } Person.prototype = Object.create(Animal.prototype);
|Java| コーディング規約
自分の中でのコーディング規約を追記していきます。
一般的なコーディング規約(boolean は is にしろなど)は省きます。
1. setter より getter
[改善前] public int x; public void process() { setXxx(); } public void setXxx() { this.x = x * x * x; }
[改善後] public int x; public void process() { this.x = getXxx(); } public void getXxx(int x) { return x * x * x; }
フィールドに対して業務処理結果を、メソッド内部で代入(setter)するのではなく、処理結果を呼び出し元で受け取り(getter)代入する。
複雑なシステムになると、呼び出したメソッド内でいつの間にか状態が変わり、バグの温床となる。