実践編 1~3

第1章
・toStringのオーバーライドの必要性
・equalsのオーバーライド
・trim()
(・フィールドにおいてpublicは書いても書かなくても同じだが明示的に外部アクセスを許可する意味を持たせる)
・配列の等価判定はjava.util.Arraysの静的メソッドArrays.equals(①, ②);
・二次元以上の配列の等価判定にはArrays.deepEquals()
java.util.Collections コレクション操作関連の便利なメソッド集
java.util.Arrays 配列操作関連の便利なメソッド集
・hashCode()を基本すべてのフィールドを引数にオーバーライドする
・自然順序付けのComparableインターフェース compareTo()メソッド
・Collections.sort()の2つの使い方 ①自然順序で並び替える ②第2引数で指定されたコンパレータのインスタンス通りに並び変え
・equals()とcompareTo()の2つを実装する場合一貫性が重要
インスタンスの複製にはclone() protectedで宣言されているのでpublicでオーバーライドする
・マーカーインターフェース clone()を実装することによって複製に対応していることを表明するためだけのようなインターフェース
・子クラスにおけるオーバーライドのアクセス修飾は親クラスにおけるそれと同じか、より緩いアクセス修飾に限定される
・浅いコピー そのインスタンスのみを複製する
・深いコピー そのインスタンスが参照しているインスタンスを含めて複製する
・clone()をオーバーライドしていないクラスを複製するときはキャストが必要である(例)Date

・子クラスでオーバーライドされているかでふるまいが変わるので要確認
・Dateの使い方

第2章
(・文字から数値へのキャストはIntegerクラスのparseIntなどをつかう)
・型を指定して制限するからこそ想定していない型を受け付けないので安全
ジェネリクスはクラス定義時にはEやKやTという「仮の型名」を使っておき、クラス利用時にそれを実際の型に置換する
ジェネリクスの制約
ジェネリクスの型にintなどの基本データ型は利用できない
ジェネリクスを用いたクラスの配列をつくることができない
③Throwableの子孫であるクラス(例外クラス)ではジェネリクスを用いることができない
ArrayList list = new ArrayLIst();のようなジェネリクスを使わない方法はraw型と呼ばれ非推奨
ジェネリクスの制限 public class Pocket<E extends Character>などと宣言するとCharacterクラスを継承している子孫クラスのみを受け付ける
・実引数のワイルドカード指定 「?」記号を用いて Pocket<?> p; p = new Pocket<String>();やPocket<? extends T> p;やpocket<? super T> p;など
・共変性(covariance)フレームワーク設計に関わる 専門書などを読んで理解を深めるといい
ジェネリックメソッド(静的メソッドのみ) アクセス修飾子 static <T> 戻り値 メソッド名(引用リスト) {メソッドの処理内容} メソッドの処理内容にも仮型引数が使える

・列挙型の定義 アクセス修飾子 enum 列挙型名 {列挙子1, 列挙子2, ..., 列挙子n;}
・「列挙型名.列挙子1」が書き方だがソースコードの先頭でstaticインポート宣言をすることで列挙子型名を省略できる
・列挙型のインスタンスはswitch分の分岐にも利用できる
・インナークラス ①メンバクラス ②ローカルクラス ③匿名クラス あるクラスの内部で宣言される。外側クラスのメンバや変数に対して特別にアクセスできる
・メンバクラス クラスブロックの中でメンバとして宣言する、protectedやprivateといったアクセス修飾も利用可能である
・static付きのメンバクラス宣言はjava言語仕様上インナークラスの範囲には含まれない
・static付きメンバクラスの特徴 独立したInnerインスタンスを生成可能、基本的に「外部クラス名.メンバクラス名」で利用する、外部クラスのメンバにアクセスできるがstaticなものに限られる
・static無しのメンバクラスの特徴 外部クラスのインスタンス(外部インスタンス)がなければnewできない、結びついている外部インスタンスの非staticメンバにもアクセスできる(p83)
・static無しメンバクラスのインスタンス化 外部クラス名.メンバクラス名 メンバクラスのインスタンス変数名 = 外部クラスのインスタンス変数名.new メンバクラス名()
・ローカルクラスの特徴 宣言したメソッド内でのみ有効で他のクラスやメソッドからは利用できない、finalとabstract以外の修飾は行えない(必要がない)、外部クラスのメンバにはアクセス可能、
自身を取り囲むメソッド内のローカル変数についてはfinalが付いたものにのみアクセスが可能(再代入されていないなら暗黙的にfinalとみなされてエラーにならない)、
あるメソッドの中で定義したらメソッド終了までに利用しなければならない
・匿名クラスの特異性 1回しか使わない使い捨てのクラス、「宣言と利用」を同時に行う
・匿名クラスの宣言兼利用 new 匿名クラスの親クラス指定() {匿名クラスの内容 (メンバ)定義}
・クラス宣言と同時にインスタンス化も行うため匿名クラス自身の名前を指定する必要はなく、その代わりどのクラスを継承して匿名クラスを作るかを指定する決まり、
new 匿名クラス名 extends 匿名クラスの親クラス() の 匿名クラス名 extends が省略された形と考えると分かりやすい
・第1章のコンパレータや第17章のGUI制御で便利
・インナークラスまとめ図(p88)
java.util.Optionalクラス 1つのインスタンスを格納するだけのシンプルなクラス ①new不可、静的メソッドofNullable()で生成、nullを格納しない場合静的メソッドof()でnull格納を防ぐ
②isPresent()で中身がnullか検証できる ③get()で内容を取得できるがnullなら例外が発生する ④orElse()でnullを置換して内容を取得できる
・null安全 nullが格納される余地があると不具合の元なので、nullの格納を防いだり、nullの格納を考慮した設計にする
・Optionalクラス nullが格納されている可能性を考慮した処理の記述を呼び出し元に強制する効果がある、基本データ型を格納することはできない、
ラッパークラスの指定は不可能ではないが処理効率が悪いので代表的な基本データ型を格納するための専用クラスが準備されている
格納する基本データ型 | 対応するOptionalクラス
int        |OptionalInt
long   |OptionalLong
double | OptionalDouble

・データ格納専用型Record getter/setter/equals()/hashCode()/toString()を簡単に自動定義

 

第3章
javaの第1級オブジェクト プログラムの実行中に実体を生み出したり、変数に代入できるもの、引数として渡せる ①データ ②データ構造(配列や構造体) ③インスタンス (他)関数オブジェクト

・関数名.apply()で呼び出し
・変数へのメソッド参照の格納(代入するのは参照、メソッド名の後ろに()をつけない)
①変数名 = クラス名::そのクラスの静的メソッド名(staticである)
②変数名 = インスタンス変数名::そのインスタンスのメソッド名(staticではない)

・標準関数インターフェース
java.util.function.Consumerインターフェース 戻り値がない関数を格納する(由来は引数を受け取るけど消費する(consume)だけだから)
java.util.function.Supplierインターフェース 引数がなく戻り値のみを返す関数(基本データ型の戻り値を返す関数には、IntSupplier, LongSupplier, DoubleSupplier)
java.util.function.Bifunctionインターフェース 同じ型の2つの引数に対応する(2つの同じ基本データ型を受ける取る関数には、ToIntBiFunction, ToLongBiFunction, ToDoubleBiFunction)
・標準関数の命名法則(p108)
・関数インターフェースの利用 抽象メソッド宣言に記述した引数と型が一致する関数オブジェクトを格納できる、抽象メソッド名で呼び出すことができる
ラムダ式 (型 引数名1, 型 引数名2, ・・・) -> { 処理; ・・・ return 戻り値;}
クロージャ 自身が評価され関数の実体が生み出される際、その時点で可能なすべての変数の情報を記憶し、ラムダ式の中で参照できる
・関数オブジェクトがもたらした大変革 メソッド間の呼び出しで「情報」(データ)しか渡せなかったが「処理」(アルゴリズム)も渡せるようになった
・コンパレータも匿名クラスよりラムダ式の方がエレガントに書ける
高階関数 引数として関数を受け取る関数のこと
・ストリーム 宣言的に処理を行うためのデータの並び、java.util.stream.Streamインターフェースで扱う

/* 要検証
・ストリームの生成 コレクションの場合→Stream<T> st = コレクション<T>.stream(); 配列の場合→Stream<T> st = Arrays.stream(T型の配列); (基本データ型のためのIntStream, LongStream, DoubleStream)

*/
・Streamの主なデータ処理メソッド(p123)
・collect()によるリスト取り出し List<T> list = ストリーム.collect(Collectors.toList()); ※Collectorはjava.util.streamパッケージに属するAPIクラス
Streamの主な中間処理メソッド
メソッド名    | 引数                     | 意味
distinct() | 無し                     | 重複を排除したストリームを返す
filter()  | Predicate<T>  | Predicateを適用した結果がtrueである要素のストリームを返す
limit()    | long           | 先頭から指定された要素数までのストリームを返す
sorted()  | Comparator<T> | Comparatorを用いて並び変えたストリームを返す
map()     | Function<T, R>| Functionを適用した戻り値を要素とするR型のストリームを返す
・中間処理 ストリームに対してさまざまな処理を続けて行うことのできるメソッド
・終端処理 ストリーム処理で加工/フィルタされた値を最終的に出力したり集計する
・手続き型プログラミング 順に実行される命令文の集まり
オブジェクト指向プログラミング 責務を持つ部品の集まり
関数型プログラミング 高階関数の集まり