X(Twitter) Zenn GitHub RSS 共有

Java

作成日時:2024-08-01以前
更新日時:2024-08-26

列挙型とファクトリー

値オブジェクトによる普遍性
関心事を纏めておけば修正箇所はわかりやすい
修正するとき何処を直せばいいかすぐわかるような。

リフレクションはキャッシュする

Math.ceil(1/2)が1にならない

1/2が0に評価されるから。
どちらかをdoubleにキャストする。

Enum

Stream

マルチスレッド

基本的にはFuture#getとCallableでスレッドの完了を待てばいいが、
各スレッドが終わった直後に何かをしたければ、CompletableFutureで
JavaScriptのPromiseみたいなことができる。

モジュール

Javaのモジュールに関して。
モジュールは下記の認識。

Javaプロジェクト内に下記のパッケージが存在するとする。

module com.example {
exports com.example.a.util,org.example.b.util
}

として単一のjarを生成した場合、
末尾utilのパッケージのみが外部から参照される認識

みたいに考えればよろし

requiresで本当に必要なモジュールを明示できる
それ以前は関係ないものを読み込んだりする可能性があった

でもmavenやgradleがあればあんまり恩恵はない

インターフェイス

Optionalでnull合体演算子

Optional.ofNullable(obj).orElse(default)

Gradle

Springを使わずに構築するのが久々だから、そこそこ詰まった。
Eclipseから作成すると、デフォでマルチプロジェクトになるよう変わっていた。
シングルプロジェクトが作りたかったので、下記の手法でプロジェクトを作成した。

導入からプロジェクト作成

  1. Gradle Build Toolからzipをダウンロード
  2. zipを解凍し、任意の場所に配置
  3. binフォルダにpathを通す。
  4. gradle initでプロジェクト作成。対話形式。
    • タイプは4のBasicを選ぶ
  5. 出来たプロジェクトをeclipseにインポート

Gradleの同期が終わらない

15%前後から進まなくなった。
設定 > Gradleから「ビルド・スキャン」のチェックを外す。

可視性

ラムダ

forEachの中のラムダ式が検査例外出す奴だと、try-catchで囲まなければならないからめんどくさい。
これに限らず、いろいろとforの方がよい。
ラムダは単純なstream処理と、関数インターフェイスとかで使用すべき。

ジェネリック

import java.util.ArrayList;
import java.util.List;
import java.io.Serializable;

public class Sample {
    
    public static void main(String args[]) {
        List<GenericClass> list = new ArrayList<GenericClass>();
        list.add(new GenericClass<Integer>(1));
        list.add(new GenericClass<String>("2"));
        //list.add(new GenericClass<Object>(null)); // エラー
        list.forEach(item -> item.output());
    }
    // 多数の境界
    private static class GenericClass<T extends Serializable & Comparable<T>> {
        public T value;
        public GenericClass(T value) {
            this.value = value;
        }
        public void output() {
            System.out.println(value.toString());
        }
        // 境界ワイルドカード
        public void method(List<? extends T> list) {
          List<Integer> IntegerList = new ArrayList<>();
          List<? extends Number> longList = list;
        }
    }
}

共変

総称型G(T)において型Xを型Yに変換できる際、G(X)がG(Y)に変換できる場合、
G(T)は共変性を持つという。

配列は共変性を持つ。

Object[] o = new Integer[3];

総称型は基本的には持たない。不変(invariant)
境界ワイルドカードで共変性を持たせる。

共変性と反変性 (計算機科学) - Wikipedia

コレクション変換

Listから特定の項目をキーにMapを生成

かつ、最初の要素を適用する方法。

// 元のリストから重複を除いてMapにする
Map<String, Person> map = personList.stream()
    .collect(Collectors.toMap(
        Person::getId,           // キーとしてidを使用
        person -> person,        // 値としてPersonオブジェクトを使用
        (first, second) -> first // 重複時は最初の要素を保持
    ));

// Mapの値をリストに変換
List<Person> uniqueList = new ArrayList<>(map.values());

並列処理/マルチスレッド

色々種類はある。
Threadよりかは、ThreadPoolExecutorかCompletableFutureを使った方がいいか。

前者は複数タスクを並列で処理したい時。
後者は単一の処理を非同期で行いたいときとか。(JavaScriptのPromiseっぽい感じ)

使い分けは上記の通りでなくともよいし、組み合わせて使うこともできる。

仮想スレッドを指定できる。

その他