@booklib/skills 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +105 -0
  3. package/animation-at-work/SKILL.md +246 -0
  4. package/animation-at-work/assets/example_asset.txt +1 -0
  5. package/animation-at-work/references/api_reference.md +369 -0
  6. package/animation-at-work/references/review-checklist.md +79 -0
  7. package/animation-at-work/scripts/example.py +1 -0
  8. package/bin/skills.js +85 -0
  9. package/clean-code-reviewer/SKILL.md +292 -0
  10. package/clean-code-reviewer/evals/evals.json +67 -0
  11. package/data-intensive-patterns/SKILL.md +204 -0
  12. package/data-intensive-patterns/assets/example_asset.txt +1 -0
  13. package/data-intensive-patterns/references/api_reference.md +34 -0
  14. package/data-intensive-patterns/references/patterns-catalog.md +551 -0
  15. package/data-intensive-patterns/references/review-checklist.md +193 -0
  16. package/data-intensive-patterns/scripts/example.py +1 -0
  17. package/data-pipelines/SKILL.md +252 -0
  18. package/data-pipelines/assets/example_asset.txt +1 -0
  19. package/data-pipelines/references/api_reference.md +301 -0
  20. package/data-pipelines/references/review-checklist.md +181 -0
  21. package/data-pipelines/scripts/example.py +1 -0
  22. package/design-patterns/SKILL.md +245 -0
  23. package/design-patterns/assets/example_asset.txt +1 -0
  24. package/design-patterns/references/api_reference.md +1 -0
  25. package/design-patterns/references/patterns-catalog.md +726 -0
  26. package/design-patterns/references/review-checklist.md +173 -0
  27. package/design-patterns/scripts/example.py +1 -0
  28. package/domain-driven-design/SKILL.md +221 -0
  29. package/domain-driven-design/assets/example_asset.txt +1 -0
  30. package/domain-driven-design/references/api_reference.md +1 -0
  31. package/domain-driven-design/references/patterns-catalog.md +545 -0
  32. package/domain-driven-design/references/review-checklist.md +158 -0
  33. package/domain-driven-design/scripts/example.py +1 -0
  34. package/effective-java/SKILL.md +195 -0
  35. package/effective-java/assets/example_asset.txt +1 -0
  36. package/effective-java/references/api_reference.md +1 -0
  37. package/effective-java/references/items-catalog.md +955 -0
  38. package/effective-java/references/review-checklist.md +216 -0
  39. package/effective-java/scripts/example.py +1 -0
  40. package/effective-kotlin/SKILL.md +225 -0
  41. package/effective-kotlin/assets/example_asset.txt +1 -0
  42. package/effective-kotlin/references/api_reference.md +1 -0
  43. package/effective-kotlin/references/practices-catalog.md +1228 -0
  44. package/effective-kotlin/references/review-checklist.md +126 -0
  45. package/effective-kotlin/scripts/example.py +1 -0
  46. package/kotlin-in-action/SKILL.md +251 -0
  47. package/kotlin-in-action/assets/example_asset.txt +1 -0
  48. package/kotlin-in-action/references/api_reference.md +1 -0
  49. package/kotlin-in-action/references/practices-catalog.md +436 -0
  50. package/kotlin-in-action/references/review-checklist.md +204 -0
  51. package/kotlin-in-action/scripts/example.py +1 -0
  52. package/lean-startup/SKILL.md +250 -0
  53. package/lean-startup/assets/example_asset.txt +1 -0
  54. package/lean-startup/references/api_reference.md +319 -0
  55. package/lean-startup/references/review-checklist.md +137 -0
  56. package/lean-startup/scripts/example.py +1 -0
  57. package/microservices-patterns/SKILL.md +179 -0
  58. package/microservices-patterns/references/patterns-catalog.md +391 -0
  59. package/microservices-patterns/references/review-checklist.md +169 -0
  60. package/package.json +17 -0
  61. package/refactoring-ui/SKILL.md +236 -0
  62. package/refactoring-ui/assets/example_asset.txt +1 -0
  63. package/refactoring-ui/references/api_reference.md +355 -0
  64. package/refactoring-ui/references/review-checklist.md +114 -0
  65. package/refactoring-ui/scripts/example.py +1 -0
  66. package/storytelling-with-data/SKILL.md +238 -0
  67. package/storytelling-with-data/assets/example_asset.txt +1 -0
  68. package/storytelling-with-data/references/api_reference.md +379 -0
  69. package/storytelling-with-data/references/review-checklist.md +111 -0
  70. package/storytelling-with-data/scripts/example.py +1 -0
  71. package/system-design-interview/SKILL.md +213 -0
  72. package/system-design-interview/assets/example_asset.txt +1 -0
  73. package/system-design-interview/references/api_reference.md +582 -0
  74. package/system-design-interview/references/review-checklist.md +201 -0
  75. package/system-design-interview/scripts/example.py +1 -0
  76. package/using-asyncio-python/SKILL.md +242 -0
  77. package/using-asyncio-python/assets/example_asset.txt +1 -0
  78. package/using-asyncio-python/references/api_reference.md +267 -0
  79. package/using-asyncio-python/references/review-checklist.md +149 -0
  80. package/using-asyncio-python/scripts/example.py +1 -0
  81. package/web-scraping-python/SKILL.md +259 -0
  82. package/web-scraping-python/assets/example_asset.txt +1 -0
  83. package/web-scraping-python/references/api_reference.md +393 -0
  84. package/web-scraping-python/references/review-checklist.md +163 -0
  85. package/web-scraping-python/scripts/example.py +1 -0
@@ -0,0 +1,955 @@
1
+ # Effective Java Items Catalog
2
+
3
+ Complete reference for all 90 items from Joshua Bloch's *Effective Java* (3rd Edition),
4
+ organized by chapter. Use this catalog when generating or reviewing Java code to identify
5
+ which items apply.
6
+
7
+ ---
8
+
9
+ ## Chapter 2: Creating and Destroying Objects
10
+
11
+ ### Item 1: Consider static factory methods instead of constructors
12
+
13
+ Static factory methods have advantages over constructors: they have names, don't require
14
+ creating a new object on each invocation, can return subtypes, and the returned type can
15
+ vary based on input parameters.
16
+
17
+ **Naming conventions**: `from`, `of`, `valueOf`, `instance`/`getInstance`, `create`/`newInstance`, `getType`, `newType`, `type`
18
+
19
+ **Anti-pattern**:
20
+ ```java
21
+ // Direct constructor — no name, always creates new instance
22
+ BigInteger prime = new BigInteger("7");
23
+ ```
24
+
25
+ **Correct**:
26
+ ```java
27
+ // Named, can cache, can return subtype
28
+ BigInteger prime = BigInteger.valueOf(7);
29
+ List<String> empty = List.of();
30
+ Optional<String> opt = Optional.empty();
31
+ ```
32
+
33
+ ---
34
+
35
+ ### Item 2: Consider a builder when faced with many constructor parameters
36
+
37
+ The Builder pattern simulates named optional parameters. Use it when constructors would
38
+ need 4+ parameters, especially if many are optional or of the same type.
39
+
40
+ **Anti-pattern** (telescoping constructors):
41
+ ```java
42
+ NutritionFacts nf = new NutritionFacts(240, 8, 100, 0, 35, 27);
43
+ ```
44
+
45
+ **Correct** (Builder):
46
+ ```java
47
+ NutritionFacts nf = new NutritionFacts.Builder(240, 8)
48
+ .calories(100)
49
+ .sodium(35)
50
+ .carbohydrate(27)
51
+ .build();
52
+ ```
53
+
54
+ **Key points**: Builder can enforce invariants in `build()`. Builder works well with class hierarchies using recursive type parameters (covariant return typing).
55
+
56
+ ---
57
+
58
+ ### Item 3: Enforce the singleton property with a private constructor or an enum type
59
+
60
+ For singletons, prefer a single-element enum which provides serialization for free and
61
+ guarantees against multiple instantiation even in the face of reflection attacks.
62
+
63
+ **Preferred**:
64
+ ```java
65
+ public enum Elvis {
66
+ INSTANCE;
67
+ public void leaveTheBuilding() { ... }
68
+ }
69
+ ```
70
+
71
+ **Alternative** (when you need to extend a superclass):
72
+ ```java
73
+ public class Elvis {
74
+ private static final Elvis INSTANCE = new Elvis();
75
+ private Elvis() { }
76
+ public static Elvis getInstance() { return INSTANCE; }
77
+ }
78
+ ```
79
+
80
+ ---
81
+
82
+ ### Item 4: Enforce noninstantiability with a private constructor
83
+
84
+ Utility classes (collections of static methods) should not be instantiable.
85
+
86
+ ```java
87
+ public class UtilityClass {
88
+ private UtilityClass() {
89
+ throw new AssertionError(); // Prevents internal instantiation
90
+ }
91
+ }
92
+ ```
93
+
94
+ ---
95
+
96
+ ### Item 5: Prefer dependency injection to hardwiring resources
97
+
98
+ Don't use a singleton or static utility class to implement a class that depends on
99
+ underlying resources. Pass the resource (or a factory) into the constructor.
100
+
101
+ **Anti-pattern**:
102
+ ```java
103
+ public class SpellChecker {
104
+ private static final Lexicon dictionary = new EnglishLexicon(); // Hardwired
105
+ }
106
+ ```
107
+
108
+ **Correct**:
109
+ ```java
110
+ public class SpellChecker {
111
+ private final Lexicon dictionary;
112
+ public SpellChecker(Lexicon dictionary) {
113
+ this.dictionary = Objects.requireNonNull(dictionary);
114
+ }
115
+ }
116
+ ```
117
+
118
+ ---
119
+
120
+ ### Item 6: Avoid creating unnecessary objects
121
+
122
+ Reuse immutable objects. Prefer primitives to boxed primitives. Watch out for unintentional autoboxing in loops.
123
+
124
+ **Anti-pattern**:
125
+ ```java
126
+ Long sum = 0L;
127
+ for (long i = 0; i <= Integer.MAX_VALUE; i++) {
128
+ sum += i; // Creates ~2^31 unnecessary Long instances
129
+ }
130
+ ```
131
+
132
+ **Correct**:
133
+ ```java
134
+ long sum = 0L; // primitive
135
+ for (long i = 0; i <= Integer.MAX_VALUE; i++) {
136
+ sum += i;
137
+ }
138
+ ```
139
+
140
+ Also: prefer `String s = "literal"` over `new String("literal")`. Cache expensive objects like `Pattern`.
141
+
142
+ ---
143
+
144
+ ### Item 7: Eliminate obsolete object references
145
+
146
+ Null out references when they become obsolete, especially in classes that manage their own
147
+ memory (stacks, caches, pools). Use `WeakHashMap` for caches, `LinkedHashMap.removeEldestEntry` for bounded caches.
148
+
149
+ **Key situations**: stack pop (null out popped element), cache entries, listener/callback registrations.
150
+
151
+ ---
152
+
153
+ ### Item 8: Avoid finalizers and cleaners
154
+
155
+ Finalizers are unpredictable, dangerous, and generally unnecessary. Cleaners (Java 9) are
156
+ less dangerous but still unpredictable. Use `try-with-resources` and `AutoCloseable` instead.
157
+
158
+ **Exception**: Safety net for native resources, and `Cleaner` as backup only.
159
+
160
+ ---
161
+
162
+ ### Item 9: Prefer try-with-resources to try-finally
163
+
164
+ Always use try-with-resources for any object that implements `AutoCloseable`.
165
+
166
+ **Anti-pattern**:
167
+ ```java
168
+ InputStream in = new FileInputStream(src);
169
+ try {
170
+ // use in
171
+ } finally {
172
+ in.close(); // Can mask original exception
173
+ }
174
+ ```
175
+
176
+ **Correct**:
177
+ ```java
178
+ try (InputStream in = new FileInputStream(src);
179
+ OutputStream out = new FileOutputStream(dst)) {
180
+ // use in and out
181
+ }
182
+ ```
183
+
184
+ ---
185
+
186
+ ## Chapter 3: Methods Common to All Objects
187
+
188
+ ### Item 10: Obey the general contract when overriding equals
189
+
190
+ The `equals` contract: reflexive, symmetric, transitive, consistent, non-null.
191
+ Don't override `equals` unless you need logical equality. Use `instanceof` (not `getClass`) for type checking when the class is not designed for subclassing.
192
+
193
+ **Key recipe**: Check `this == obj`, check `instanceof`, cast, compare significant fields.
194
+
195
+ ---
196
+
197
+ ### Item 11: Always override hashCode when you override equals
198
+
199
+ If two objects are equal according to `equals`, they must have the same `hashCode`.
200
+ Use `Objects.hash(field1, field2, ...)` for simple cases; compute manually for performance-critical code.
201
+
202
+ ---
203
+
204
+ ### Item 12: Always override toString
205
+
206
+ Provide a useful `toString` for debugging. Include all interesting information.
207
+ Document the format (or state that it's unspecified).
208
+
209
+ ---
210
+
211
+ ### Item 13: Override clone judiciously
212
+
213
+ Prefer copy constructors or copy factory methods to `Cloneable`. The `Cloneable` interface
214
+ is deeply flawed — it modifies `Object.clone()` behavior via an extralinguistic mechanism.
215
+
216
+ **Prefer**:
217
+ ```java
218
+ public Yum(Yum yum) { ... } // Copy constructor
219
+ public static Yum newInstance(Yum yum) { ... } // Copy factory
220
+ ```
221
+
222
+ ---
223
+
224
+ ### Item 14: Consider implementing Comparable
225
+
226
+ Implement `Comparable` for value classes with natural ordering. Use `Comparator.comparing`
227
+ with chained `thenComparing` for clean, type-safe comparisons.
228
+
229
+ ```java
230
+ private static final Comparator<PhoneNumber> COMPARATOR =
231
+ Comparator.comparingInt((PhoneNumber pn) -> pn.areaCode)
232
+ .thenComparingInt(pn -> pn.prefix)
233
+ .thenComparingInt(pn -> pn.lineNum);
234
+ ```
235
+
236
+ **Never** use difference-based comparators (e.g., `return o1.x - o2.x`) — they can overflow.
237
+
238
+ ---
239
+
240
+ ## Chapter 4: Classes and Interfaces
241
+
242
+ ### Item 15: Minimize the accessibility of classes and members
243
+
244
+ Make each class or member as inaccessible as possible. Top-level classes: package-private or public.
245
+ Members: private → package-private → protected → public (use the most restrictive that works).
246
+ Instance fields should never be public. Public static final fields are OK only for immutable objects.
247
+
248
+ ---
249
+
250
+ ### Item 16: In public classes, use accessor methods, not public fields
251
+
252
+ Don't expose fields directly — use getters (and setters only if mutable).
253
+ Exception: package-private or private nested classes can expose fields.
254
+
255
+ ---
256
+
257
+ ### Item 17: Minimize mutability
258
+
259
+ Immutable classes are simpler, thread-safe, and can be shared freely. Rules:
260
+ 1. Don't provide mutators
261
+ 2. Ensure class can't be extended (make it final or use static factories with private constructor)
262
+ 3. Make all fields final
263
+ 4. Make all fields private
264
+ 5. Ensure exclusive access to mutable components (defensive copies)
265
+
266
+ ---
267
+
268
+ ### Item 18: Favor composition over inheritance
269
+
270
+ Inheritance across package boundaries is fragile. Use the decorator pattern:
271
+ a forwarding class that wraps the existing class and delegates all method calls.
272
+
273
+ **Anti-pattern**: `class InstrumentedHashSet<E> extends HashSet<E>` — breaks if `HashSet.addAll` calls `add`.
274
+
275
+ **Correct**: `class InstrumentedSet<E> extends ForwardingSet<E>` wrapping any `Set<E>`.
276
+
277
+ ---
278
+
279
+ ### Item 19: Design and document for inheritance or else prohibit it
280
+
281
+ Classes designed for subclassing must document self-use of overridable methods.
282
+ If you don't design for inheritance, make the class final or make constructors private with static factories.
283
+
284
+ ---
285
+
286
+ ### Item 20: Prefer interfaces to abstract classes
287
+
288
+ Interfaces enable mixins, non-hierarchical type frameworks, and default methods.
289
+ Use skeletal implementation classes (e.g., `AbstractList`) as optional companions.
290
+
291
+ ---
292
+
293
+ ### Item 21: Design interfaces for posterity
294
+
295
+ Default methods can break existing implementations. Think carefully before adding
296
+ default methods to existing interfaces — they may violate invariants of existing implementations.
297
+
298
+ ---
299
+
300
+ ### Item 22: Use interfaces only to define types
301
+
302
+ Don't use constant interfaces (interfaces with only `static final` fields).
303
+ Use enum types or utility classes for constants instead.
304
+
305
+ ---
306
+
307
+ ### Item 23: Prefer class hierarchies to tagged classes
308
+
309
+ Tagged classes (a class with a `type` field and switch statements) are verbose, error-prone,
310
+ and inefficient. Refactor into a class hierarchy with an abstract root class.
311
+
312
+ ---
313
+
314
+ ### Item 24: Favor static member classes over nonstatic
315
+
316
+ Four kinds of nested classes: static member, nonstatic member, anonymous, local.
317
+ If a member class doesn't need a reference to the enclosing instance, make it static.
318
+ Non-static member classes retain a hidden reference to the enclosing instance (memory leak risk).
319
+
320
+ ---
321
+
322
+ ### Item 25: Limit source files to a single top-level class
323
+
324
+ Never put multiple top-level classes in a single source file. Use static member classes
325
+ if the classes are closely related.
326
+
327
+ ---
328
+
329
+ ## Chapter 5: Generics
330
+
331
+ ### Item 26: Don't use raw types
332
+
333
+ Raw types lose type safety. Use `List<Object>` if you want a list that can hold any object,
334
+ `List<?>` if you want a list of some unknown type.
335
+
336
+ **Anti-pattern**: `List list = new ArrayList();`
337
+ **Correct**: `List<String> list = new ArrayList<>();`
338
+
339
+ ---
340
+
341
+ ### Item 27: Eliminate unchecked warnings
342
+
343
+ Every unchecked warning represents a potential `ClassCastException` at runtime.
344
+ Eliminate every warning you can. If you can prove the code is typesafe but can't
345
+ eliminate the warning, suppress it with `@SuppressWarnings("unchecked")` on the
346
+ smallest possible scope, and add a comment explaining why it's safe.
347
+
348
+ ---
349
+
350
+ ### Item 28: Prefer lists to arrays
351
+
352
+ Arrays are covariant and reified; generics are invariant and erased. These differences
353
+ make arrays and generics poor mixmates. Prefer `List<E>` to `E[]`.
354
+
355
+ ---
356
+
357
+ ### Item 29: Favor generic types
358
+
359
+ Generify your classes. It's not much harder than using raw types and provides compile-time safety.
360
+
361
+ ---
362
+
363
+ ### Item 30: Favor generic methods
364
+
365
+ Generic methods are especially useful for static utility methods.
366
+ Use type inference: `Set<String> union = union(s1, s2);`
367
+
368
+ **Recursive type bounds** for mutual comparability:
369
+ ```java
370
+ public static <E extends Comparable<E>> E max(Collection<E> c)
371
+ ```
372
+
373
+ ---
374
+
375
+ ### Item 31: Use bounded wildcards to increase API flexibility
376
+
377
+ PECS: Producer-Extends, Consumer-Super.
378
+ - If a parameter is a **producer** of `T`, use `<? extends T>`
379
+ - If a parameter is a **consumer** of `T`, use `<? super T>`
380
+ - Do not use wildcards on return types
381
+
382
+ ```java
383
+ public void pushAll(Iterable<? extends E> src) { ... } // src produces E
384
+ public void popAll(Collection<? super E> dst) { ... } // dst consumes E
385
+ ```
386
+
387
+ ---
388
+
389
+ ### Item 32: Combine generics and varargs judiciously
390
+
391
+ Heap pollution can occur with generic varargs parameters. Use `@SafeVarargs`
392
+ on every method with a varargs parameter of a generic or parameterized type,
393
+ provided the method is truly safe (doesn't store into the varargs array or
394
+ expose it to untrusted code).
395
+
396
+ ---
397
+
398
+ ### Item 33: Consider typesafe heterogeneous containers
399
+
400
+ Use `Class<T>` as a key to store and retrieve values of different types safely.
401
+ Pattern: `Map<Class<?>, Object>` with runtime type checking on put/get.
402
+
403
+ ```java
404
+ public <T> void putFavorite(Class<T> type, T instance);
405
+ public <T> T getFavorite(Class<T> type);
406
+ ```
407
+
408
+ ---
409
+
410
+ ## Chapter 6: Enums and Annotations
411
+
412
+ ### Item 34: Use enums instead of int constants
413
+
414
+ Enums provide compile-time type safety, namespaces, and can have behavior.
415
+ Use constant-specific method implementations for behavior that varies by constant.
416
+ Use the strategy enum pattern for shared behaviors.
417
+
418
+ ---
419
+
420
+ ### Item 35: Use instance fields instead of ordinals
421
+
422
+ Never derive a value from `ordinal()`. Store the value in an instance field.
423
+
424
+ **Anti-pattern**: `public int numberOfMusicians() { return ordinal() + 1; }`
425
+ **Correct**: Store the count as a constructor parameter.
426
+
427
+ ---
428
+
429
+ ### Item 36: Use EnumSet instead of bit fields
430
+
431
+ `EnumSet` provides the performance of bit fields with the readability and type safety of enums.
432
+
433
+ ```java
434
+ text.applyStyles(EnumSet.of(Style.BOLD, Style.ITALIC));
435
+ ```
436
+
437
+ ---
438
+
439
+ ### Item 37: Use EnumMap instead of ordinal indexing
440
+
441
+ Use `EnumMap` instead of `array[enum.ordinal()]` for enum-keyed maps. Also applicable
442
+ for multi-dimensional mappings: use nested `EnumMap<..., EnumMap<..., V>>`.
443
+
444
+ ---
445
+
446
+ ### Item 38: Emulate extensible enums with interfaces
447
+
448
+ Enums can't extend other enums, but they can implement interfaces.
449
+ Use this for extensible operation codes (opcode pattern).
450
+
451
+ ---
452
+
453
+ ### Item 39: Prefer annotations to naming patterns
454
+
455
+ Annotations (like `@Test`) are superior to naming conventions (like `testXxx`).
456
+ Use meta-annotations to create custom annotations.
457
+
458
+ ---
459
+
460
+ ### Item 40: Consistently use the Override annotation
461
+
462
+ Use `@Override` on every method declaration intended to override a superclass or
463
+ interface method. The compiler will catch errors if the method doesn't actually override.
464
+
465
+ ---
466
+
467
+ ### Item 41: Use marker interfaces to define types
468
+
469
+ Marker interfaces (like `Serializable`) define a type that instances of marked classes
470
+ have. Use them when you need compile-time type checking. Use marker annotations when
471
+ you don't need the type.
472
+
473
+ ---
474
+
475
+ ## Chapter 7: Lambdas and Streams
476
+
477
+ ### Item 42: Prefer lambdas to anonymous classes
478
+
479
+ Lambdas are more concise than anonymous classes for functional interface implementations.
480
+ Keep lambdas short (1-3 lines). If a lambda is long, extract it to a method.
481
+ Lambdas lack names and documentation — if a computation isn't self-explanatory, don't use one.
482
+
483
+ ---
484
+
485
+ ### Item 43: Prefer method references to lambdas
486
+
487
+ Method references are more concise and clearer when they don't need parameter renaming.
488
+
489
+ | Method Ref Type | Example | Lambda Equivalent |
490
+ |----------------|---------|-------------------|
491
+ | Static | `Integer::parseInt` | `str -> Integer.parseInt(str)` |
492
+ | Bound | `Instant.now()::isAfter` | `t -> Instant.now().isAfter(t)` |
493
+ | Unbound | `String::toLowerCase` | `str -> str.toLowerCase()` |
494
+ | Constructor | `TreeMap<K,V>::new` | `() -> new TreeMap<K,V>()` |
495
+
496
+ ---
497
+
498
+ ### Item 44: Favor the use of standard functional interfaces
499
+
500
+ Use the 43 interfaces in `java.util.function` before creating your own.
501
+ Six basic ones: `UnaryOperator<T>`, `BinaryOperator<T>`, `Predicate<T>`,
502
+ `Function<T,R>`, `Supplier<T>`, `Consumer<T>`.
503
+
504
+ ---
505
+
506
+ ### Item 45: Use streams judiciously
507
+
508
+ Don't overuse streams. Overusing streams makes code hard to read and maintain.
509
+ Good for: transforming sequences, filtering, combining, accumulating into collections,
510
+ searching. Bad for: accessing corresponding elements from multiple stages simultaneously,
511
+ modifying local variables from enclosing scope.
512
+
513
+ ---
514
+
515
+ ### Item 46: Prefer side-effect-free functions in streams
516
+
517
+ The most important part of the streams paradigm is to structure your computation as
518
+ a sequence of transformations where each stage's result is as close as possible to a
519
+ pure function. The `forEach` operation should only be used to report the result of a
520
+ stream computation, not to perform computation.
521
+
522
+ **Key collectors**: `toList()`, `toSet()`, `toMap()`, `groupingBy()`, `joining()`.
523
+
524
+ ---
525
+
526
+ ### Item 47: Prefer Collection to Stream as a return type
527
+
528
+ `Collection` is a subtype of both `Iterable` and `Stream`, making it the best return
529
+ type for public APIs. If the values aren't stored in memory, consider returning a custom
530
+ collection backed by computation.
531
+
532
+ ---
533
+
534
+ ### Item 48: Use caution when making streams parallel
535
+
536
+ Parallelizing a stream is easy to do but can cause incorrect results or poor performance.
537
+ Performance gains are best with `ArrayList`, `HashMap`, `HashSet`, `ConcurrentHashMap`,
538
+ arrays, `int` ranges, and `long` ranges — data structures that can be cheaply split.
539
+ Avoid parallelizing pipelines backed by `Stream.iterate` or `limit`.
540
+
541
+ ---
542
+
543
+ ## Chapter 8: Methods
544
+
545
+ ### Item 49: Check parameters for validity
546
+
547
+ Validate parameters at the start of methods. Use `Objects.requireNonNull` for null checks.
548
+ Use `assert` for non-public methods. Document restrictions with `@throws` Javadoc.
549
+
550
+ ---
551
+
552
+ ### Item 50: Make defensive copies when needed
553
+
554
+ When receiving mutable objects from clients, make defensive copies in the constructor
555
+ (before validation). When returning mutable internal state, return copies.
556
+
557
+ **Critical**: Copy first, validate the copy — prevents TOCTOU attacks.
558
+
559
+ ```java
560
+ public Period(Date start, Date end) {
561
+ this.start = new Date(start.getTime()); // Defensive copy
562
+ this.end = new Date(end.getTime());
563
+ if (this.start.compareTo(this.end) > 0) // Validate copy
564
+ throw new IllegalArgumentException();
565
+ }
566
+ ```
567
+
568
+ ---
569
+
570
+ ### Item 51: Design method signatures carefully
571
+
572
+ - Choose method names carefully (consistent, understandable)
573
+ - Don't go overboard with convenience methods
574
+ - Avoid long parameter lists (max 4) — use helper classes, Builder, or break into multiple methods
575
+ - Prefer interfaces over classes for parameter types
576
+ - Prefer two-element enum types to boolean parameters
577
+
578
+ ---
579
+
580
+ ### Item 52: Use overloading judiciously
581
+
582
+ Overloading selection is static (compile-time), not dynamic (runtime). Avoid overloading
583
+ methods with the same number of parameters. Use different method names instead.
584
+
585
+ **Dangerous**: `List.remove(int)` vs `List.remove(Object)` — autoboxing creates confusion.
586
+
587
+ ---
588
+
589
+ ### Item 53: Use varargs judiciously
590
+
591
+ Require at least one argument pattern:
592
+ ```java
593
+ static int min(int firstArg, int... remainingArgs) { ... }
594
+ ```
595
+
596
+ Performance concern: varargs allocates an array. For performance-critical methods,
597
+ provide overloads for 0-3 args plus varargs fallback.
598
+
599
+ ---
600
+
601
+ ### Item 54: Return empty collections or arrays, not nulls
602
+
603
+ Never return null from a collection-returning method. Use `Collections.emptyList()`,
604
+ `Collections.emptySet()`, `Collections.emptyMap()`, or empty arrays.
605
+
606
+ ---
607
+
608
+ ### Item 55: Return optionals judiciously
609
+
610
+ Use `Optional<T>` for methods that might not return a result. Never return `null`
611
+ from an Optional-returning method. Never use Optional for collection return types
612
+ (return empty collection instead). Don't use Optional in fields, parameters, or map keys/values.
613
+
614
+ ---
615
+
616
+ ### Item 56: Write doc comments for all exposed API elements
617
+
618
+ Document every exported class, interface, method, constructor, and field.
619
+ The doc comment should describe the contract: what the method does (not how),
620
+ preconditions, postconditions, side effects, and thread safety.
621
+
622
+ Use `@param`, `@return`, `@throws`, `{@code}`, `{@literal}`, `{@index}`, `@implSpec`.
623
+
624
+ ---
625
+
626
+ ## Chapter 9: General Programming
627
+
628
+ ### Item 57: Minimize the scope of local variables
629
+
630
+ Declare variables where they are first used. Prefer for-loop to while-loop when
631
+ the loop variable isn't needed afterward. Keep methods small and focused.
632
+
633
+ ---
634
+
635
+ ### Item 58: Prefer for-each loops to traditional for loops
636
+
637
+ Use enhanced for-each wherever possible. Three situations where you can't:
638
+ destructive filtering, transforming, and parallel iteration.
639
+
640
+ ---
641
+
642
+ ### Item 59: Know and use the libraries
643
+
644
+ Don't reinvent the wheel. Use `java.util`, `java.util.concurrent`, `java.util.stream`,
645
+ `java.time`, etc. Example: `ThreadLocalRandom.current().nextInt(bound)` instead of
646
+ hand-rolled random number generation.
647
+
648
+ ---
649
+
650
+ ### Item 60: Avoid float and double if exact answers are required
651
+
652
+ Use `BigDecimal`, `int`, or `long` for monetary calculations. `float` and `double`
653
+ are designed for scientific computation, not exact decimal values.
654
+
655
+ ---
656
+
657
+ ### Item 61: Prefer primitive types to boxed primitives
658
+
659
+ Prefer `int` over `Integer`, `long` over `Long`. Unintentional autoboxing causes
660
+ performance issues. Applying `==` to boxed primitives is almost always wrong.
661
+
662
+ ---
663
+
664
+ ### Item 62: Avoid strings where other types are more appropriate
665
+
666
+ Don't use strings as substitutes for enums, aggregates, or capabilities.
667
+ Use proper types: enums for enumerated values, classes for aggregates, keys for capabilities.
668
+
669
+ ---
670
+
671
+ ### Item 63: Beware the performance of string concatenation
672
+
673
+ Use `StringBuilder` when concatenating many strings in a loop.
674
+ The `+` operator is fine for a fixed number of strings.
675
+
676
+ ---
677
+
678
+ ### Item 64: Refer to objects by their interfaces
679
+
680
+ If appropriate interface types exist, parameters, return values, variables, and fields
681
+ should all be declared as interface types.
682
+
683
+ ```java
684
+ Set<Son> sonSet = new LinkedHashSet<>(); // Good
685
+ LinkedHashSet<Son> sonSet = new LinkedHashSet<>(); // Bad
686
+ ```
687
+
688
+ ---
689
+
690
+ ### Item 65: Prefer interfaces to reflection
691
+
692
+ Reflection is powerful but has many disadvantages: no compile-time checking, verbose code,
693
+ poor performance. Use reflection only to instantiate classes, then access via interfaces.
694
+
695
+ ---
696
+
697
+ ### Item 66: Use native methods judiciously
698
+
699
+ Rarely need JNI for performance anymore. Use only for accessing platform-specific
700
+ facilities not available in Java.
701
+
702
+ ---
703
+
704
+ ### Item 67: Optimize judiciously
705
+
706
+ Don't optimize prematurely. Write good programs first, then profile. Avoid architectural
707
+ decisions that limit performance (like making a public API return mutable internal state
708
+ requiring defensive copies on every call).
709
+
710
+ ---
711
+
712
+ ### Item 68: Adhere to generally accepted naming conventions
713
+
714
+ Follow Java naming conventions:
715
+ - Packages: `com.google.common.collect`
716
+ - Classes/Interfaces: `BigDecimal`, `Comparator`
717
+ - Methods: `ensureCapacity`, `getCrc`
718
+ - Constants: `MIN_VALUE`, `NEGATIVE_INFINITY`
719
+ - Type parameters: `T`, `E`, `K`, `V`, `X`, `R`, `T1`, `T2`
720
+
721
+ ---
722
+
723
+ ## Chapter 10: Exceptions
724
+
725
+ ### Item 69: Use exceptions only for exceptional conditions
726
+
727
+ Never use exceptions for ordinary control flow. A well-designed API must not force
728
+ its clients to use exceptions for ordinary control flow (provide state-testing methods
729
+ or Optional-returning methods).
730
+
731
+ ---
732
+
733
+ ### Item 70: Use checked exceptions for recoverable conditions and runtime exceptions for programming errors
734
+
735
+ Checked exceptions: caller can reasonably recover.
736
+ Runtime exceptions: programming errors (precondition violations).
737
+ Errors: reserved for JVM. Don't subclass `Error`.
738
+
739
+ ---
740
+
741
+ ### Item 71: Avoid unnecessary use of checked exceptions
742
+
743
+ If the caller can't recover, use unchecked. If there's only one checked exception on
744
+ a method and it's the sole reason for the `throws` clause, consider returning `Optional`
745
+ instead or splitting the method.
746
+
747
+ ---
748
+
749
+ ### Item 72: Favor the use of standard exceptions
750
+
751
+ Common reusable exceptions:
752
+ - `IllegalArgumentException` — non-null parameter value is inappropriate
753
+ - `IllegalStateException` — object state is inappropriate for invocation
754
+ - `NullPointerException` — parameter is null where prohibited
755
+ - `IndexOutOfBoundsException` — index parameter out of range
756
+ - `UnsupportedOperationException` — object doesn't support method
757
+ - `ConcurrentModificationException` — concurrent modification detected
758
+ - `ArithmeticException` — arithmetic error
759
+
760
+ ---
761
+
762
+ ### Item 73: Throw exceptions appropriate to the abstraction
763
+
764
+ Higher layers should catch lower-level exceptions and throw exceptions appropriate to
765
+ their abstraction (exception translation). Use exception chaining to preserve the cause.
766
+
767
+ ```java
768
+ try {
769
+ // Lower-level abstraction
770
+ } catch (LowerLevelException e) {
771
+ throw new HigherLevelException(e); // Exception chaining
772
+ }
773
+ ```
774
+
775
+ ---
776
+
777
+ ### Item 74: Document all exceptions thrown by each method
778
+
779
+ Document every exception with `@throws` Javadoc. Declare checked exceptions individually.
780
+ Don't declare that a method `throws Exception` or `throws Throwable`.
781
+
782
+ ---
783
+
784
+ ### Item 75: Include failure-capture information in detail messages
785
+
786
+ Exception detail messages should include the values of all parameters and fields that
787
+ contributed to the exception. Don't include passwords or encryption keys.
788
+
789
+ ---
790
+
791
+ ### Item 76: Strive for failure atomicity
792
+
793
+ A failed method invocation should leave the object in the state it was in prior to
794
+ the invocation. Approaches: immutable objects, parameter validation before operation,
795
+ temporary copy, recovery code.
796
+
797
+ ---
798
+
799
+ ### Item 77: Don't ignore exceptions
800
+
801
+ An empty catch block defeats the purpose of exceptions. If you choose to ignore,
802
+ document why and name the variable `ignored`.
803
+
804
+ ```java
805
+ try { ... }
806
+ catch (SomeException ignored) {
807
+ // Safe to ignore because [reason]
808
+ }
809
+ ```
810
+
811
+ ---
812
+
813
+ ## Chapter 11: Concurrency
814
+
815
+ ### Item 78: Synchronize access to shared mutable data
816
+
817
+ Synchronization is required for reliable communication between threads, not just mutual
818
+ exclusion. Use `volatile` for simple communication (e.g., stop flags). Use `synchronized`
819
+ or `java.util.concurrent.atomic` for compound actions.
820
+
821
+ ---
822
+
823
+ ### Item 79: Avoid excessive synchronization
824
+
825
+ Don't call alien methods from within synchronized regions (risk of deadlock or data corruption).
826
+ Do as little work as possible inside synchronized regions. Prefer `CopyOnWriteArrayList`
827
+ for observable lists with rare modifications.
828
+
829
+ ---
830
+
831
+ ### Item 80: Prefer executors, tasks, and streams to threads
832
+
833
+ Use `ExecutorService` instead of managing threads directly. Use `Executors.newCachedThreadPool`
834
+ for lightly loaded servers, `Executors.newFixedThreadPool` for heavily loaded servers.
835
+ Use `ForkJoinPool` for compute-intensive parallel tasks.
836
+
837
+ ---
838
+
839
+ ### Item 81: Prefer concurrency utilities to wait and notify
840
+
841
+ Use `ConcurrentHashMap`, `BlockingQueue`, `CountDownLatch`, `Semaphore`, and `Phaser`
842
+ instead of `wait`/`notify`. Use `ConcurrentHashMap.computeIfAbsent` for thread-safe lazy init.
843
+ Always use the wait loop idiom if you must use `wait`:
844
+
845
+ ```java
846
+ synchronized (obj) {
847
+ while (!condition) obj.wait();
848
+ }
849
+ ```
850
+
851
+ ---
852
+
853
+ ### Item 82: Document thread safety
854
+
855
+ Document the thread safety level of every class:
856
+ - **Immutable** — Instances are constant (`String`, `Long`, `BigInteger`)
857
+ - **Unconditionally thread-safe** — Mutable but with internal synchronization (`AtomicLong`, `ConcurrentHashMap`)
858
+ - **Conditionally thread-safe** — Some methods require external synchronization (`Collections.synchronized` wrappers)
859
+ - **Not thread-safe** — Must surround each method invocation with external sync (`ArrayList`, `HashMap`)
860
+ - **Thread-hostile** — Unsafe even with external sync (rare)
861
+
862
+ Use `@ThreadSafe`, `@NotThreadSafe`, `@Immutable` annotations (JSR 305).
863
+
864
+ ---
865
+
866
+ ### Item 83: Use lazy initialization judiciously
867
+
868
+ Most fields should be initialized normally (eagerly). Use lazy init only if needed
869
+ for performance or to break circular dependencies.
870
+
871
+ - **For instance fields**: double-check idiom
872
+ - **For static fields**: lazy initialization holder class idiom
873
+ - **For fields that can tolerate repeated init**: single-check idiom
874
+
875
+ ```java
876
+ // Lazy initialization holder class idiom for static fields
877
+ private static class FieldHolder {
878
+ static final FieldType field = computeFieldValue();
879
+ }
880
+ private static FieldType getField() { return FieldHolder.field; }
881
+ ```
882
+
883
+ ---
884
+
885
+ ### Item 84: Don't depend on the thread scheduler
886
+
887
+ Programs that rely on thread scheduling for correctness or performance are non-portable.
888
+ Don't use `Thread.yield`. Don't use thread priorities. If threads aren't doing useful work,
889
+ restructure the application so they don't run.
890
+
891
+ ---
892
+
893
+ ## Chapter 12: Serialization
894
+
895
+ ### Item 85: Prefer alternatives to Java serialization
896
+
897
+ Java serialization is dangerous — it enables remote code execution attacks via gadget chains.
898
+ Prefer cross-platform structured-data representations: JSON or protobuf.
899
+ Never deserialize untrusted data. If you must use serialization, use object deserialization
900
+ filtering (`java.io.ObjectInputFilter`).
901
+
902
+ ---
903
+
904
+ ### Item 86: Implement Serializable with great caution
905
+
906
+ Implementing `Serializable` decreases the flexibility to change a class's implementation,
907
+ increases the likelihood of bugs and security holes, and increases the testing burden.
908
+ Classes designed for inheritance should rarely implement `Serializable`.
909
+
910
+ ---
911
+
912
+ ### Item 87: Consider using a custom serialized form
913
+
914
+ Don't accept the default serialized form without considering whether it's appropriate.
915
+ The default form is reasonable only if the physical representation is identical to the
916
+ logical content. Otherwise, write `writeObject`/`readObject` methods.
917
+
918
+ Mark fields that are derivable from other state as `transient`.
919
+
920
+ ---
921
+
922
+ ### Item 88: Write readObject methods defensively
923
+
924
+ `readObject` is effectively a public constructor — it must validate parameters and make
925
+ defensive copies of mutable components, just like any other constructor.
926
+
927
+ ---
928
+
929
+ ### Item 89: For instance control, prefer enum types to readResolve
930
+
931
+ If a singleton class implements `Serializable`, add a `readResolve` method or,
932
+ better yet, use a single-element enum. With `readResolve`, all instance fields
933
+ with object reference types must be declared `transient`.
934
+
935
+ ---
936
+
937
+ ### Item 90: Consider serialization proxies instead of serialized instances
938
+
939
+ The serialization proxy pattern: write a private static nested class that represents
940
+ the logical state, implement `writeReplace` and `readResolve`. This is the most robust
941
+ approach when you must implement `Serializable`.
942
+
943
+ ```java
944
+ private static class SerializationProxy implements Serializable {
945
+ private final Date start;
946
+ private final Date end;
947
+ SerializationProxy(Period p) {
948
+ this.start = p.start;
949
+ this.end = p.end;
950
+ }
951
+ private Object readResolve() {
952
+ return new Period(start, end); // Uses public constructor
953
+ }
954
+ }
955
+ ```