Java本格入門 ~モダンスタイルによる基礎からオブジェクト指向・実用ライブラリまで12~14
12-1-1 デザインパターンとは
- オブジェクトの「生成」に関するパターン
- プログラムの「構造」に関するパターン
- オブジェクトの「振る舞い」に関するパターン
12-2 生成に関するパターン
- AbstractFactory 関連する一連のインスタンスを状況に応じて適切に生成する方法を提供する
- Builder 複合化されたインスタンスの生成過程を隠ぺいする
- Singleton あるクラスについて、インスタンスが単一であることを保証する
12-3 構造に関するパターン
- Adapter インターフェースに互換性のないクラスどうしを組み合わせる
- Composite 再帰的な構造の取り扱いを容易にする
12-4 振る舞いに関するパターン
13-1-2 Mavenの基本的な利用方法
- M2_HOME
- Path
13-2-3 知っておくと便利な記述方法
- {@inheritDoc}
13-5-2 テストコードを実装する
- テストメソッド名には日本語で試験条件を記述するようにしています
14-1-1 Commons Lang
14-1-2 Commons BeanUtils
14-4-2 SLF4J+Logbackでロギングをおこなう
14-4-5 変数を出力する
- logger.debug("employee={}, department={}", employee, department);
14-4-7 動的に設定を変更する
Java本格入門 ~モダンスタイルによる基礎からオブジェクト指向・実用ライブラリまで10~11
10-1-1 プリミティブ型と参照型の値の渡し方
- 原則として、引数オブジェクトの修正は避ける
- 戻り値がvoidの場合は、引数オブジェクトを修正してもいい
- 戻り値がvoid以外の場合は、引数オブジェクトを変更してはならない
10-2-2 可視性のグッドプラクティス
- (1)原則、最も範囲が狭い可視性にする
- クラスで宣言するフィールドは、privateとする
- 外部からアクセスするメソッドのみ、publicにする
- (2)拡張性をあげるためにprotectedにする
- (3)テストの容易性を上げるためにprotectedにする
10-3-2 ライフサイクルのグッドプラクティス
- ライフサイクルを短くして事故を防ぐ
- ライフサイクルを長くして性能を上げる
- ユーティリティクラス自体は非staticメソッドで構成して、インスタンスをstaticにする手法を採用しています
10-4-2 インタフェースと抽象クラスの性質と違い
- インターフェイスは「定義」に使う
- 抽象クラスは「ひな形」や「共通処理」に使う
10-4-4 インタフェースのstaticメソッド
- staticメソッドで実装クラスの初期化を行う
11-1-2 マルチスレッドにするメリット
- なるべく各スレッドの処理が同時に終わるようにデータを分割する
- スレッド間でお互いを待たせるような処理がない/少ない
11-1-3 マルチスレッドで困ること
- (1)メモリの使用量が増える
- (2)スループットが低下する
- (3)同時に作業する場合、特有の問題が発生する
11-1-4 同時に作業する場合に起こる問題
- (1)データの上書きが発生する
- (2)デッドロックが発生して、処理が停止する
- (3)例外が発生する
- (4)無限ループが発生する
11-2-1 スレッドセーフとは
- 複数のスレッドから読み書きをおこなっても、データが破損しない
- 複数のスレッドから読み書きをおこなっても、エラー処理が発生しない
- 複数のスレッドから読み書きをおこなっても、デッドロック/停止処理が発生しない
11-2-2 ステートレスにする
- (1)属性は処理するメソッドの引数に変更して、削除する
- (2)ロジックで処理した結果をインスタンス変数に保存し、アクセッサメソッドを使って取得させる
Java本格入門 ~モダンスタイルによる基礎からオブジェクト指向・実用ライブラリまで7~9
7-1-2 文字列を結合する3つの方法
- ローカル変数など、複数のスレッドからアクセスされない → StringBuilderクラス
- 複数のスレッドから使われる場合 → StringBufferクラス
7-1-4 複数の文字列を連結する
- String.joinメソッド
7-2-4 Stringクラスのメソッドで正規表現を使う
- 1回だけ文字列処理をおこなう場合(アプリケーションを起動するときの引数処理など) → Stringクラスを使って簡潔に書く
- 大量の文字列を繰り返し処理する場合(ログファイルの処理など) → 自分でPatternクラスのオブジェクトを生成し、オブジェクトを使いまわす
7-3-2 MessageFormatについて
7-4-4 文字化けの原因と対策
- デフォルトエンコーディングを使わない事を徹底する
- Stringコンストラクタ(引数なしのもの)
- StringクラスのgetBytesメソッド(引数なしのもの)
- FileReaderクラス
- FileWriterクラス
- InputStreamReaderコンストラクタ(引数なしのもの)
- OutputStreamWriterコンストラクタ(引数なしのもの)
- 対策
- FileReaderクラス、FileWriterクラスは使わずに、FileInputStreamクラスとInputStreamReaderクラスで代用する
- それ以外のメソッドやコンストラクタでは、必ずエンコーディングやcharsetを指定する
- サロゲートペアをどう扱うか
8-1-1 Fileクラスで初期化する
- File.separator
8-1-2 Pathクラスで初期化する
- Pathクラスを用いたソースコードを書くようにし、既存のライブラリを扱うなどの必要に応じてFileクラスに変換する
- Pathsより生成する
9-2-1 Date and Time APIのメリット
- 日付・時間・日時をそれぞれ別クラスで扱うため、必要に応じて使い分けできる
- 年月日などを指定してインスタンスを生成できる
- 年月日の各フィールドの値を個別に取得できる
- 年月日の計算ができる
- イミュータブルである
9-2-2 日付・時間・日時をそれぞれ別クラスで扱う
9-3-3 SimpleDateFormatクラスはスレッドセーフではない
9-4-3 DateTimeFormatterクラスはスレッドセーフ
9-5-1 西暦を和暦に変換する
Java本格入門 ~モダンスタイルによる基礎からオブジェクト指向・実用ライブラリまで6
6-1-1 例外の3つの種類
- 検査例外(Exception)おもにプログラム作成時に想定できる異常を通知するために使用します try catch 必要
- 実行時例外(RuntimeException)おもにプログラム作成時に想定されないエラーを通知するために使用します try catch 不要
- エラー(Error)例外とは異なり、システムの動作を継続できない「致命的なエラー」を示します
6-1-3 例外処理の3つの構文を使いこなす
- tryブロックの開始時に記述する宣言は、複数の文を記述できます
6-2-1 エラーコードをreturnするコードは古い
- エラーが発生したら例外を発生させるべきです
6-2-3 恐怖のthrows Exception感染
- (1)呼び出し元でExceptionを捕捉しなければならなくなる
- (2)途中でIOExceptionなど具体的な例外が発生するとしても、Exceptionに巻き込まれる
- (3)途中でRuntimeExceptionが発生しても、Exceptionに巻き込まれる
6-2-4 どの階層で例外を捕捉して処理するべきか
- 例外が発生する(可能性がある)箇所
- 末端の処理では「例外を発生されるだけ」に留めるが良いでしょう
- 処理の流れを判断する箇所
6-2-5 独自例外を作成する
- (1)アプリケーション例外(例:ApplicationExceptionクラス)
- (2)システム例外(例:SystemExceptionクラス)
- 業務に特化した処理である(少なくとも、広く再利用するものではない)
- フレームワークやシステムで共通的な例外処理をする
- 筆者のおすすめは、メッセージの替わりに、エラーIDとパラメータを指定するというものです
6-2-6 例外のトレンド
- (1)検査例外よりも実行時例外を使う
- (2)ラムダ式のなかで発生した例外の扱い
- (3)Optionalクラスの導入によるメリット
Java本格入門 ~モダンスタイルによる基礎からオブジェクト指向・実用ライブラリまで5
5.1.1 Stream APIでコレクションの操作はどう変わるか
- StreamAPIは「作成」「中間操作」「終端操作」の3つの操作からできています
5.1.2 ラムダ式の書き方をマスターする
5.1.3 メソッド参照
5.3.1 要素を置き換える中間操作
- メソッド名に「map」が入っている中間操作は、要素を置き換えることを目的としています
- flatMap 要素のStreamを結合する
5.3.2 要素を絞り込む中間操作
- filter 条件に合致した要素のみに絞り込む
- limit 指定した件数に絞り込む
- distinct ユニークな要素のみに絞り込む(重複を排除)
5.3.3 要素を並べ替える中間操作
- Comparaterは戻り値のint値によって次のように挙動が変わります
- 0より小さい値の場合 → 第一引数のオブジェクトが前方になる
- 0より大きい値の場合 → 第二引数のオブジェクトが前方になる
- 0の場合 → 並び順は変わらない
5.4.1 繰り返し処理をおこなう終端操作
- forEach このストリームの要素に対してアクションを実行する
5.4.2 結果をまとめて取り出す終端操作
- collect 要素を走査し、結果を作成する
- toList
- toSet
- joining
- groupingBy
- toArray 全要素を配列に変換する
- reduce 値を集約する
5.4.3 結果を1つだけ取り出す終端操作
- findFirst 先頭の要素を返す
- findAny いずれかの要素を返す
- min 最小の要素を返す
- max 最大の要素を返す
5.5.1 王道はmap,filter,collect
5.5.2 n回の繰り返しをするIntStream
5.5.3 ListやMapに対して効率的に処理をおこなう
- List
- removeIf 引数に与えた関数がtrueを返す要素のすべてをListから削除する
- replaceAll 引数に与えた関数を通した結果で、Listの全要素を置き換える
- Map
- compute 引数に与えた関数の結果をMapに再設定する
- computeIfPresent キーがあるときだけ、引数に与えた関数の結果をMapに再設定する
- computeIfAbsent キーがないときだけ、引数に与えた関数の結果をMapに設定する