Item 6、不要なオブジェクトの作成を避ける


不要なオブジェクトを作成しない


同じ機能を持つオブジェクトを毎回生成するよりも、オブジェクトを再使用することが多い.
再使用すると速くて洗練されていますか?

文字列オブジェクトの作成


できないコードString s = new String("bikini");このコードは、実行するたびに新しいStringインスタンスを作成します.したがって,繰り返し検査を行うと,数百万個のインスタンスを生成することができる.
改良されたコードString s = "bikini";インスタンスを使用して、JVMに同じ文字列テキストがある場合は、そのテキストを再使用します.

静的ファクトリメソッドの使用


Booleanはjava 9で廃棄されたBoolean(String)に取って代わった.ValueOf(String)のような静的プラント法を使用することができる.ジェネレータは新しいオブジェクトを作成する必要がありますが、ファクトリメソッドではありません.

高価なオブジェクト

static boolean isRomanNumeral(String s) {
        return s.matches("^(?=.)M*(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
    }
String.matchesは、正規表現を使用して文字列形式を決定する最も簡単な方法であるが、パフォーマンスが重要な場合に繰り返し使用するのに適していない.String.matches内部にPatternオブジェクトが生成され、そのオブジェクトを生成するには、正規表現で有限状態機械にコンパイルするプロセスが必要である.すなわち高価な客体である.Patternオブジェクトを作成して再使用することが望ましい.
public class RomanNumber {

    private static final Pattern ROMAN = Pattern.compile("^(?=.)M*(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");

    static boolean isRomanNumeral(String s) {
        return ROMAN.matcher(s).matches();
    }

}
最適化は、怠惰初期化(lazily initiating)(物品83)を用いて行うことができるが、推奨されない.通常、遅延初期化は、測定可能な性能の改善なしに実装を複雑にする.(アイテム67)

アダプタ(ビュー)


実際の操作はバックエンドオブジェクトに委任され、自身は2番目のインタフェースとして機能するオブジェクトです.
バックエンドオブジェクト以外に管理可能な状態はないので、バックエンドオブジェクトごとにアダプタを1つ作成するだけで十分です.Mapインタフェースによって提供されるKeySetメソッドは、Mapオブジェクト内のすべての鍵を含むSetビューを返す.keySetが呼び出されるたびに、新しいオブジェクトが表示される場合がありますが、返されるオブジェクトは事実と同じであるため、返されるSetタイプのオブジェクトを変更すると、最終的には後のMapオブジェクトが変更されます.
public class UsingKeySet {

    public static void main(String[] args) {
        Map<String, Integer> menu = new HashMap<>();
        menu.put("Burger", 8);
        menu.put("Pizza", 9);

        Set<String> names1 = menu.keySet();
        Set<String> names2 = menu.keySet();

        names1.remove("Burger");
        System.out.println(names2.size()); // 1
        System.out.println(menu.size()); // 1
    }
}

じどうくみたて


プログラマが基本タイプと埋め込まれた基本タイプを混合して使用するときに自動的に相互変換する技術.
基本タイプと箱タイプの境界が見えない自動運転方式ですが、この境界は解消されません.
public class AutoBoxingExample {

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        Long sum = 0l;
        for (long i = 0 ; i <= Integer.MAX_VALUE ; i++) {
            sum += i;
        }
        System.out.println(sum);
        System.out.println(System.currentTimeMillis() - start);
    }
}
sumの変数をLongに設定するので、不要なLongオブジェクトを2^31に設定するには6秒以上かかります.だからlongに変えると、10倍以上減らすことができます.
不要な自動運転を避けるには、箱型ではなく基本型を使うべきです

整理する


オブジェクトの作成は高いので避けるべきです.誤解しないでください.防御的な複製が必要な場合、オブジェクトを繰り返し使用する場合のダメージは、オブジェクトを繰り返し作成する場合のダメージよりもずっと大きいです.失敗すると、エラーとセキュリティ・ホールが発生します.不要なオブジェクトを生成すると、コードの形式とパフォーマンスにのみ影響します.