diff --git a/.gitignore b/.gitignore index af9c1434..5361ec59 100644 --- a/.gitignore +++ b/.gitignore @@ -63,3 +63,7 @@ fabric.properties # Editor-based Rest Client # .idea/httpRequests +/bin/ +/.classpath +/.project +/effective-java-3e-source-code.eml diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..64cc097e --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,15 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=14 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=14 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=enabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=14 diff --git a/README.md b/README.md index aba26664..d4ae7b59 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,18 @@ +The source code have been updated to use new constructs available since Java 9, +the version used by the 3rd edition. + +In particular, the examples are using the constructs available in Java 14: +- `var`: [type inference of local variable](https://openjdk.java.net/jeps/286) +- `expression switch`: [exhaustive switch + more concise syntax](https://openjdk.java.net/jeps/361). +- `record`: [our bean killer](https://openjdk.java.net/jeps/359) +- `instanceof` with the [type test pattern](https://openjdk.java.net/jeps/305) + +I've also added some API calls, mostly List.of/List.copyOf (I think the later was added in 10). + +Some edits may be surprising to you but I stand by them until you prove me wrong :) + +--- + # Effective Java, Third Edition ![EJ3e Book Cover](https://www.pearsonhighered.com/assets/bigcovers/0/1/3/4/0134685997.jpg) ## Hot News! Source code finally available on GitHub. Happy Hacking! diff --git a/src/effectivejava/chapter11/item78/brokenstopthread/StopThread.java b/src/effectivejava/chapter11/item78/brokenstopthread/StopThread.java index d5bc6659..0a4fb4ca 100644 --- a/src/effectivejava/chapter11/item78/brokenstopthread/StopThread.java +++ b/src/effectivejava/chapter11/item78/brokenstopthread/StopThread.java @@ -7,8 +7,8 @@ public class StopThread { public static void main(String[] args) throws InterruptedException { - Thread backgroundThread = new Thread(() -> { - int i = 0; + var backgroundThread = new Thread(() -> { + var i = 0; while (!stopRequested) i++; }); diff --git a/src/effectivejava/chapter11/item78/fixedstopthread1/StopThread.java b/src/effectivejava/chapter11/item78/fixedstopthread1/StopThread.java index c20c62b6..eafb540e 100644 --- a/src/effectivejava/chapter11/item78/fixedstopthread1/StopThread.java +++ b/src/effectivejava/chapter11/item78/fixedstopthread1/StopThread.java @@ -15,8 +15,8 @@ private static synchronized boolean stopRequested() { public static void main(String[] args) throws InterruptedException { - Thread backgroundThread = new Thread(() -> { - int i = 0; + var backgroundThread = new Thread(() -> { + var i = 0; while (!stopRequested()) i++; }); diff --git a/src/effectivejava/chapter11/item78/fixedstopthread2/StopThread.java b/src/effectivejava/chapter11/item78/fixedstopthread2/StopThread.java index 3a11ab2a..3542c2a2 100644 --- a/src/effectivejava/chapter11/item78/fixedstopthread2/StopThread.java +++ b/src/effectivejava/chapter11/item78/fixedstopthread2/StopThread.java @@ -7,8 +7,8 @@ public class StopThread { public static void main(String[] args) throws InterruptedException { - Thread backgroundThread = new Thread(() -> { - int i = 0; + var backgroundThread = new Thread(() -> { + var i = 0; while (!stopRequested) i++; }); diff --git a/src/effectivejava/chapter11/item79/ObservableSet.java b/src/effectivejava/chapter11/item79/ObservableSet.java index 82ffb00f..376c8e75 100644 --- a/src/effectivejava/chapter11/item79/ObservableSet.java +++ b/src/effectivejava/chapter11/item79/ObservableSet.java @@ -39,7 +39,7 @@ public class ObservableSet extends ForwardingSet { // } // Thread-safe observable set with CopyOnWriteArrayList - private final List> observers = + private final CopyOnWriteArrayList> observers = new CopyOnWriteArrayList<>(); public void addObserver(SetObserver observer) { @@ -51,20 +51,20 @@ public boolean removeObserver(SetObserver observer) { } private void notifyElementAdded(E element) { - for (SetObserver observer : observers) + for (var observer : observers) observer.added(this, element); } @Override public boolean add(E element) { - boolean added = super.add(element); + var added = super.add(element); if (added) notifyElementAdded(element); return added; } @Override public boolean addAll(Collection c) { - boolean result = false; - for (E element : c) + var result = false; + for (var element : c) result |= add(element); // Calls notifyElementAdded return result; } diff --git a/src/effectivejava/chapter11/item79/Test1.java b/src/effectivejava/chapter11/item79/Test1.java index ea1ae9ea..dcfffb53 100644 --- a/src/effectivejava/chapter11/item79/Test1.java +++ b/src/effectivejava/chapter11/item79/Test1.java @@ -4,12 +4,12 @@ // Simple test of ObservableSet - Page 318 public class Test1 { public static void main(String[] args) { - ObservableSet set = - new ObservableSet<>(new HashSet<>()); + var set = + new ObservableSet<>(new HashSet()); set.addObserver((s, e) -> System.out.println(e)); - for (int i = 0; i < 100; i++) + for (var i = 0; i < 100; i++) set.add(i); } } diff --git a/src/effectivejava/chapter11/item79/Test2.java b/src/effectivejava/chapter11/item79/Test2.java index 275f092c..91085094 100644 --- a/src/effectivejava/chapter11/item79/Test2.java +++ b/src/effectivejava/chapter11/item79/Test2.java @@ -4,8 +4,8 @@ // More complex test of ObservableSet - Page 318-9 public class Test2 { public static void main(String[] args) { - ObservableSet set = - new ObservableSet<>(new HashSet<>()); + var set = + new ObservableSet<>(new HashSet()); set.addObserver(new SetObserver<>() { public void added(ObservableSet s, Integer e) { @@ -15,7 +15,7 @@ public void added(ObservableSet s, Integer e) { } }); - for (int i = 0; i < 100; i++) + for (var i = 0; i < 100; i++) set.add(i); } } diff --git a/src/effectivejava/chapter11/item79/Test3.java b/src/effectivejava/chapter11/item79/Test3.java index d7534224..45f9e8bd 100644 --- a/src/effectivejava/chapter11/item79/Test3.java +++ b/src/effectivejava/chapter11/item79/Test3.java @@ -7,16 +7,15 @@ // Simple test of ObservableSet - Page 319 public class Test3 { public static void main(String[] args) { - ObservableSet set = - new ObservableSet<>(new HashSet<>()); + var set = + new ObservableSet<>(new HashSet()); // Observer that uses a background thread needlessly set.addObserver(new SetObserver<>() { public void added(ObservableSet s, Integer e) { System.out.println(e); if (e == 23) { - ExecutorService exec = - Executors.newSingleThreadExecutor(); + var exec = Executors.newSingleThreadExecutor(); try { exec.submit(() -> s.removeObserver(this)).get(); } catch (ExecutionException | InterruptedException ex) { @@ -28,7 +27,7 @@ public void added(ObservableSet s, Integer e) { } }); - for (int i = 0; i < 100; i++) + for (var i = 0; i < 100; i++) set.add(i); } } \ No newline at end of file diff --git a/src/effectivejava/chapter11/item81/ConcurrentTimer.java b/src/effectivejava/chapter11/item81/ConcurrentTimer.java index c9f2304c..f751273d 100644 --- a/src/effectivejava/chapter11/item81/ConcurrentTimer.java +++ b/src/effectivejava/chapter11/item81/ConcurrentTimer.java @@ -7,11 +7,11 @@ private ConcurrentTimer() { } // Noninstantiable public static long time(Executor executor, int concurrency, Runnable action) throws InterruptedException { - CountDownLatch ready = new CountDownLatch(concurrency); - CountDownLatch start = new CountDownLatch(1); - CountDownLatch done = new CountDownLatch(concurrency); + var ready = new CountDownLatch(concurrency); + var start = new CountDownLatch(1); + var done = new CountDownLatch(concurrency); - for (int i = 0; i < concurrency; i++) { + for (var i = 0; i < concurrency; i++) { executor.execute(() -> { ready.countDown(); // Tell timer we're ready try { @@ -26,7 +26,7 @@ public static long time(Executor executor, int concurrency, } ready.await(); // Wait for all workers to be ready - long startNanos = System.nanoTime(); + var startNanos = System.nanoTime(); start.countDown(); // And they're off! done.await(); // Wait for all workers to finish return System.nanoTime() - startNanos; diff --git a/src/effectivejava/chapter11/item81/Intern.java b/src/effectivejava/chapter11/item81/Intern.java index 0e422c94..8dfdc029 100644 --- a/src/effectivejava/chapter11/item81/Intern.java +++ b/src/effectivejava/chapter11/item81/Intern.java @@ -8,13 +8,13 @@ public class Intern { new ConcurrentHashMap<>(); // public static String intern(String s) { -// String previousValue = map.putIfAbsent(s, s); +// var previousValue = map.putIfAbsent(s, s); // return previousValue == null ? s : previousValue; // } // Concurrent canonicalizing map atop ConcurrentMap - faster! public static String intern(String s) { - String result = map.get(s); + var result = map.get(s); if (result == null) { result = map.putIfAbsent(s, s); if (result == null) diff --git a/src/effectivejava/chapter11/item83/Initialization.java b/src/effectivejava/chapter11/item83/Initialization.java index 83f05e0c..58d2ef28 100644 --- a/src/effectivejava/chapter11/item83/Initialization.java +++ b/src/effectivejava/chapter11/item83/Initialization.java @@ -27,7 +27,7 @@ private static class FieldHolder { // NOTE: The code for this method in the first printing had a serious error (see errata for details)! private FieldType getField4() { - FieldType result = field4; + var result = field4; if (result != null) // First check (no locking) return result; @@ -44,7 +44,7 @@ private FieldType getField4() { private volatile FieldType field5; private FieldType getField5() { - FieldType result = field5; + var result = field5; if (result == null) field5 = result = computeFieldValue(); return result; diff --git a/src/effectivejava/chapter12/Util.java b/src/effectivejava/chapter12/Util.java index 0cfb2c91..5f879080 100644 --- a/src/effectivejava/chapter12/Util.java +++ b/src/effectivejava/chapter12/Util.java @@ -4,7 +4,7 @@ public class Util { public static byte[] serialize(Object o) { - ByteArrayOutputStream ba = new ByteArrayOutputStream(); + var ba = new ByteArrayOutputStream(); try { new ObjectOutputStream(ba).writeObject(o); } catch (IOException e) { diff --git a/src/effectivejava/chapter12/item85/DeserializationBomb.java b/src/effectivejava/chapter12/item85/DeserializationBomb.java index 7a5de631..17e5ba54 100644 --- a/src/effectivejava/chapter12/item85/DeserializationBomb.java +++ b/src/effectivejava/chapter12/item85/DeserializationBomb.java @@ -12,12 +12,12 @@ public static void main(String[] args) throws Exception { } static byte[] bomb() { - Set root = new HashSet<>(); - Set s1 = root; - Set s2 = new HashSet<>(); - for (int i = 0; i < 100; i++) { - Set t1 = new HashSet<>(); - Set t2 = new HashSet<>(); + var root = new HashSet<>(); + var s1 = root; + var s2 = new HashSet<>(); + for (var i = 0; i < 100; i++) { + var t1 = new HashSet<>(); + var t2 = new HashSet<>(); t1.add("foo"); // make it not equal to t2 s1.add(t1); s1.add(t2); diff --git a/src/effectivejava/chapter12/item87/StringList.java b/src/effectivejava/chapter12/item87/StringList.java index b50989c2..8bf705aa 100644 --- a/src/effectivejava/chapter12/item87/StringList.java +++ b/src/effectivejava/chapter12/item87/StringList.java @@ -7,14 +7,13 @@ public final class StringList implements Serializable { private transient Entry head = null; // No longer Serializable! - private static class Entry { - String data; - Entry next; - Entry previous; + private record Entry(String data, Entry next) { } // Appends the specified string to the list - public final void add(String s) { } + public void add(String s) { + head = new Entry(s, head); + } /** * Serialize this {@code StringList} instance. @@ -30,17 +29,17 @@ private void writeObject(ObjectOutputStream s) s.writeInt(size); // Write out all elements in the proper order. - for (Entry e = head; e != null; e = e.next) - s.writeObject(e.data); + for (var entry = head; entry != null; entry = entry.next) + s.writeObject(entry.data); } private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); - int numElements = s.readInt(); + var numElements = s.readInt(); // Read in all elements and insert them in list - for (int i = 0; i < numElements; i++) + for (var i = 0; i < numElements; i++) add((String) s.readObject()); } diff --git a/src/effectivejava/chapter12/item89/enumsingleton/Elvis.java b/src/effectivejava/chapter12/item89/enumsingleton/Elvis.java index 2f1a24be..64a5dcaf 100644 --- a/src/effectivejava/chapter12/item89/enumsingleton/Elvis.java +++ b/src/effectivejava/chapter12/item89/enumsingleton/Elvis.java @@ -5,7 +5,7 @@ // Enum singleton - the preferred approach - Page 311 public enum Elvis { INSTANCE; - private String[] favoriteSongs = + private final String[] favoriteSongs = { "Hound Dog", "Heartbreak Hotel" }; public void printFavorites() { System.out.println(Arrays.toString(favoriteSongs)); diff --git a/src/effectivejava/chapter12/item90/Period.java b/src/effectivejava/chapter12/item90/Period.java index 71aaf712..283b626f 100644 --- a/src/effectivejava/chapter12/item90/Period.java +++ b/src/effectivejava/chapter12/item90/Period.java @@ -32,17 +32,10 @@ public Period(Date start, Date end) { // Serialization proxy for Period class - private static class SerializationProxy implements Serializable { - private final Date start; - private final Date end; - - SerializationProxy(Period p) { - this.start = p.start; - this.end = p.end; + private record SerializationProxy(Date start, Date end) implements Serializable { + private SerializationProxy(Period p) { + this(p.start, p.end); } - - private static final long serialVersionUID = - 234098243823485285L; // Any number will do (Item 87) } // writeReplace method for the serialization proxy pattern diff --git a/src/effectivejava/chapter2/item2/builder/NutritionFacts.java b/src/effectivejava/chapter2/item2/builder/NutritionFacts.java index 0c630099..2c76d77e 100644 --- a/src/effectivejava/chapter2/item2/builder/NutritionFacts.java +++ b/src/effectivejava/chapter2/item2/builder/NutritionFacts.java @@ -1,14 +1,7 @@ package effectivejava.chapter2.item2.builder; // Builder Pattern (Page 13) -public class NutritionFacts { - private final int servingSize; - private final int servings; - private final int calories; - private final int fat; - private final int sodium; - private final int carbohydrate; - +public record NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium, int carbohydrate) { public static class Builder { // Required parameters private final int servingSize; @@ -40,16 +33,11 @@ public NutritionFacts build() { } private NutritionFacts(Builder builder) { - servingSize = builder.servingSize; - servings = builder.servings; - calories = builder.calories; - fat = builder.fat; - sodium = builder.sodium; - carbohydrate = builder.carbohydrate; + this(builder.servingSize, builder.servings, builder.calories, builder.fat, builder.sodium, builder.carbohydrate); } public static void main(String[] args) { - NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8) + var cocaCola = new NutritionFacts.Builder(240, 8) .calories(100).sodium(35).carbohydrate(27).build(); } } \ No newline at end of file diff --git a/src/effectivejava/chapter2/item2/hierarchicalbuilder/Calzone.java b/src/effectivejava/chapter2/item2/hierarchicalbuilder/Calzone.java index b26ab600..1e5bfec0 100644 --- a/src/effectivejava/chapter2/item2/hierarchicalbuilder/Calzone.java +++ b/src/effectivejava/chapter2/item2/hierarchicalbuilder/Calzone.java @@ -1,9 +1,10 @@ package effectivejava.chapter2.item2.hierarchicalbuilder; -// Subclass with hierarchical builder (Page 15) -public class Calzone extends Pizza { - private final boolean sauceInside; +import java.util.Collections; +import java.util.Set; +// Subtype with hierarchical builder (Page 15) +public record Calzone(Settoppings, boolean sauceInside) implements Pizza { public static class Builder extends Pizza.Builder { private boolean sauceInside = false; // Default @@ -16,16 +17,14 @@ public Builder sauceInside() { return new Calzone(this); } - @Override protected Builder self() { return this; } + @Override Builder self() { return this; } } private Calzone(Builder builder) { - super(builder); - sauceInside = builder.sauceInside; + this(builder.toppings.clone(), builder.sauceInside); } - @Override public String toString() { - return String.format("Calzone with %s and sauce on the %s", - toppings, sauceInside ? "inside" : "outside"); + public Set toppings() { + return Collections.unmodifiableSet(toppings); } } diff --git a/src/effectivejava/chapter2/item2/hierarchicalbuilder/NyPizza.java b/src/effectivejava/chapter2/item2/hierarchicalbuilder/NyPizza.java index 3e8c04f8..84de314b 100644 --- a/src/effectivejava/chapter2/item2/hierarchicalbuilder/NyPizza.java +++ b/src/effectivejava/chapter2/item2/hierarchicalbuilder/NyPizza.java @@ -1,11 +1,11 @@ package effectivejava.chapter2.item2.hierarchicalbuilder; import java.util.Objects; +import java.util.Set; -// Subclass with hierarchical builder (Page 15) -public class NyPizza extends Pizza { +// Subtype with hierarchical builder (Page 15) +public record NyPizza(Settoppings, Size size) implements Pizza { public enum Size { SMALL, MEDIUM, LARGE } - private final Size size; public static class Builder extends Pizza.Builder { private final Size size; @@ -18,15 +18,10 @@ public Builder(Size size) { return new NyPizza(this); } - @Override protected Builder self() { return this; } + @Override Builder self() { return this; } } private NyPizza(Builder builder) { - super(builder); - size = builder.size; - } - - @Override public String toString() { - return "New York Pizza with " + toppings; + this(builder.toppings.clone(), builder.size); } } diff --git a/src/effectivejava/chapter2/item2/hierarchicalbuilder/Pizza.java b/src/effectivejava/chapter2/item2/hierarchicalbuilder/Pizza.java index 77925cda..0cb73ac9 100644 --- a/src/effectivejava/chapter2/item2/hierarchicalbuilder/Pizza.java +++ b/src/effectivejava/chapter2/item2/hierarchicalbuilder/Pizza.java @@ -5,24 +5,22 @@ // Note that the underlying "simulated self-type" idiom allows for arbitrary fluid hierarchies, not just builders -public abstract class Pizza { +public interface Pizza { public enum Topping { HAM, MUSHROOM, ONION, PEPPER, SAUSAGE } - final Set toppings; - abstract static class Builder> { - EnumSet toppings = EnumSet.noneOf(Topping.class); + /*private*/ abstract static class Builder> { + final EnumSet toppings = EnumSet.noneOf(Topping.class); public T addTopping(Topping topping) { - toppings.add(Objects.requireNonNull(topping)); + Objects.requireNonNull(topping); + toppings.add(topping); return self(); } abstract Pizza build(); // Subclasses must override this method to return "this" - protected abstract T self(); - } - - Pizza(Builder builder) { - toppings = builder.toppings.clone(); // See Item 50 + abstract T self(); } + + Set toppings(); } diff --git a/src/effectivejava/chapter2/item2/hierarchicalbuilder/PizzaTest.java b/src/effectivejava/chapter2/item2/hierarchicalbuilder/PizzaTest.java index 191fd094..b1d78584 100644 --- a/src/effectivejava/chapter2/item2/hierarchicalbuilder/PizzaTest.java +++ b/src/effectivejava/chapter2/item2/hierarchicalbuilder/PizzaTest.java @@ -6,9 +6,9 @@ // Using the hierarchical builder (Page 16) public class PizzaTest { public static void main(String[] args) { - NyPizza pizza = new NyPizza.Builder(SMALL) + var pizza = new NyPizza.Builder(SMALL) .addTopping(SAUSAGE).addTopping(ONION).build(); - Calzone calzone = new Calzone.Builder() + var calzone = new Calzone.Builder() .addTopping(HAM).sauceInside().build(); System.out.println(pizza); diff --git a/src/effectivejava/chapter2/item2/telescopingconstructor/NutritionFacts.java b/src/effectivejava/chapter2/item2/telescopingconstructor/NutritionFacts.java index 230e33cd..b2156d42 100644 --- a/src/effectivejava/chapter2/item2/telescopingconstructor/NutritionFacts.java +++ b/src/effectivejava/chapter2/item2/telescopingconstructor/NutritionFacts.java @@ -1,14 +1,7 @@ package effectivejava.chapter2.item2.telescopingconstructor; // Telescoping constructor pattern - does not scale well! (Pages 10-11) -public class NutritionFacts { - private final int servingSize; // (mL) required - private final int servings; // (per container) required - private final int calories; // (per serving) optional - private final int fat; // (g/serving) optional - private final int sodium; // (mg/serving) optional - private final int carbohydrate; // (g/serving) optional - +public record NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium, int carbohydrate) { public NutritionFacts(int servingSize, int servings) { this(servingSize, servings, 0); } @@ -27,18 +20,9 @@ public NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium) { this(servingSize, servings, calories, fat, sodium, 0); } - public NutritionFacts(int servingSize, int servings, - int calories, int fat, int sodium, int carbohydrate) { - this.servingSize = servingSize; - this.servings = servings; - this.calories = calories; - this.fat = fat; - this.sodium = sodium; - this.carbohydrate = carbohydrate; - } public static void main(String[] args) { - NutritionFacts cocaCola = + var cocaCola = new NutritionFacts(240, 8, 100, 0, 35, 27); } diff --git a/src/effectivejava/chapter2/item3/enumtype/Elvis.java b/src/effectivejava/chapter2/item3/enumtype/Elvis.java index b78507e3..b91b16b4 100644 --- a/src/effectivejava/chapter2/item3/enumtype/Elvis.java +++ b/src/effectivejava/chapter2/item3/enumtype/Elvis.java @@ -10,7 +10,7 @@ public void leaveTheBuilding() { // This code would normally appear outside the class! public static void main(String[] args) { - Elvis elvis = Elvis.INSTANCE; + var elvis = Elvis.INSTANCE; elvis.leaveTheBuilding(); } } diff --git a/src/effectivejava/chapter2/item3/field/Elvis.java b/src/effectivejava/chapter2/item3/field/Elvis.java index d5a3d020..291c38f9 100644 --- a/src/effectivejava/chapter2/item3/field/Elvis.java +++ b/src/effectivejava/chapter2/item3/field/Elvis.java @@ -12,7 +12,7 @@ public void leaveTheBuilding() { // This code would normally appear outside the class! public static void main(String[] args) { - Elvis elvis = Elvis.INSTANCE; + var elvis = Elvis.INSTANCE; elvis.leaveTheBuilding(); } } \ No newline at end of file diff --git a/src/effectivejava/chapter2/item3/staticfactory/Elvis.java b/src/effectivejava/chapter2/item3/staticfactory/Elvis.java index 1f767166..34d17e3c 100644 --- a/src/effectivejava/chapter2/item3/staticfactory/Elvis.java +++ b/src/effectivejava/chapter2/item3/staticfactory/Elvis.java @@ -12,7 +12,7 @@ public void leaveTheBuilding() { // This code would normally appear outside the class! public static void main(String[] args) { - Elvis elvis = Elvis.getInstance(); + var elvis = Elvis.getInstance(); elvis.leaveTheBuilding(); } } diff --git a/src/effectivejava/chapter2/item8/Room.java b/src/effectivejava/chapter2/item8/Room.java index a52a2d45..851a1e85 100644 --- a/src/effectivejava/chapter2/item8/Room.java +++ b/src/effectivejava/chapter2/item8/Room.java @@ -8,9 +8,9 @@ public class Room implements AutoCloseable { // Resource that requires cleaning. Must not refer to Room! private static class State implements Runnable { - int numJunkPiles; // Number of junk piles in this room + private int numJunkPiles; // Number of junk piles in this room - State(int numJunkPiles) { + private State(int numJunkPiles) { this.numJunkPiles = numJunkPiles; } diff --git a/src/effectivejava/chapter2/item9/tryfinally/Copy.java b/src/effectivejava/chapter2/item9/tryfinally/Copy.java index 19b2e469..1470e5a8 100644 --- a/src/effectivejava/chapter2/item9/tryfinally/Copy.java +++ b/src/effectivejava/chapter2/item9/tryfinally/Copy.java @@ -1,20 +1,17 @@ package effectivejava.chapter2.item9.tryfinally; import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; public class Copy { - private static final int BUFFER_SIZE = 8 * 1024; - // try-finally is ugly when used with more than one resource! (Page 34) - static void copy(String src, String dst) throws IOException { - InputStream in = new FileInputStream(src); + static void copy(Path src, Path dst) throws IOException { + var in = Files.newInputStream(src); try { - OutputStream out = new FileOutputStream(dst); + var out = Files.newOutputStream(dst); try { - byte[] buf = new byte[BUFFER_SIZE]; - int n; - while ((n = in.read(buf)) >= 0) - out.write(buf, 0, n); + in.transferTo(out); } finally { out.close(); } @@ -24,8 +21,8 @@ static void copy(String src, String dst) throws IOException { } public static void main(String[] args) throws IOException { - String src = args[0]; - String dst = args[1]; + var src = Path.of(args[0]); + var dst = Path.of(args[1]); copy(src, dst); } } diff --git a/src/effectivejava/chapter2/item9/tryfinally/TopLine.java b/src/effectivejava/chapter2/item9/tryfinally/TopLine.java index deb5a73f..8ade2eb5 100644 --- a/src/effectivejava/chapter2/item9/tryfinally/TopLine.java +++ b/src/effectivejava/chapter2/item9/tryfinally/TopLine.java @@ -3,20 +3,22 @@ import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; public class TopLine { // try-finally - No longer the best way to close resources! (page 34) - static String firstLineOfFile(String path) throws IOException { - BufferedReader br = new BufferedReader(new FileReader(path)); + static String firstLineOfFile(Path path) throws IOException { + var reader = Files.newBufferedReader(path); try { - return br.readLine(); + return reader.readLine(); } finally { - br.close(); + reader.close(); } } public static void main(String[] args) throws IOException { - String path = args[0]; + var path = Path.of(args[0]); System.out.println(firstLineOfFile(path)); } } diff --git a/src/effectivejava/chapter2/item9/trywithresources/Copy.java b/src/effectivejava/chapter2/item9/trywithresources/Copy.java index 15a77dfb..49a64ef0 100644 --- a/src/effectivejava/chapter2/item9/trywithresources/Copy.java +++ b/src/effectivejava/chapter2/item9/trywithresources/Copy.java @@ -1,24 +1,21 @@ package effectivejava.chapter2.item9.trywithresources; import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; public class Copy { - private static final int BUFFER_SIZE = 8 * 1024; - // try-with-resources on multiple resources - short and sweet (Page 35) - static void copy(String src, String dst) throws IOException { - try (InputStream in = new FileInputStream(src); - OutputStream out = new FileOutputStream(dst)) { - byte[] buf = new byte[BUFFER_SIZE]; - int n; - while ((n = in.read(buf)) >= 0) - out.write(buf, 0, n); + static void copy(Path src, Path dst) throws IOException { + try (var in = Files.newInputStream(src); + var out = Files.newOutputStream(dst)) { + in.transferTo(out); } } public static void main(String[] args) throws IOException { - String src = args[0]; - String dst = args[1]; + var src = Path.of(args[0]); + var dst = Path.of(args[1]); copy(src, dst); } } diff --git a/src/effectivejava/chapter2/item9/trywithresources/TopLine.java b/src/effectivejava/chapter2/item9/trywithresources/TopLine.java index ea714ac7..e244a7b0 100644 --- a/src/effectivejava/chapter2/item9/trywithresources/TopLine.java +++ b/src/effectivejava/chapter2/item9/trywithresources/TopLine.java @@ -4,18 +4,19 @@ import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; public class TopLine { // try-with-resources - the the best way to close resources! (Page 35) - static String firstLineOfFile(String path) throws IOException { - try (BufferedReader br = new BufferedReader( - new FileReader(path))) { - return br.readLine(); + static String firstLineOfFile(Path path) throws IOException { + try (var reader = Files.newBufferedReader(path)) { + return reader.readLine(); } } public static void main(String[] args) throws IOException { - String path = args[0]; + var path = Path.of(args[0]); System.out.println(firstLineOfFile(path)); } } diff --git a/src/effectivejava/chapter2/item9/trywithresources/TopLineWithDefault.java b/src/effectivejava/chapter2/item9/trywithresources/TopLineWithDefault.java index f51334c0..812b279e 100644 --- a/src/effectivejava/chapter2/item9/trywithresources/TopLineWithDefault.java +++ b/src/effectivejava/chapter2/item9/trywithresources/TopLineWithDefault.java @@ -4,20 +4,22 @@ import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Optional; public class TopLineWithDefault { // try-with-resources with a catch clause (Page 36) - static String firstLineOfFile(String path, String defaultVal) { - try (BufferedReader br = new BufferedReader( - new FileReader(path))) { - return br.readLine(); + static Optional firstLineOfFile(Path path) { + try (var reader = Files.newBufferedReader(path)) { + return Optional.of(reader.readLine()); } catch (IOException e) { - return defaultVal; + return Optional.empty(); } } public static void main(String[] args) throws IOException { - String path = args[0]; - System.out.println(firstLineOfFile(path, "Toppy McTopFace")); + var path = Path.of(args[0]); + System.out.println(firstLineOfFile(path).orElse("Toppy McTopFace")); } } diff --git a/src/effectivejava/chapter3/item10/CaseInsensitiveString.java b/src/effectivejava/chapter3/item10/CaseInsensitiveString.java index dcb0c228..6dbd340a 100644 --- a/src/effectivejava/chapter3/item10/CaseInsensitiveString.java +++ b/src/effectivejava/chapter3/item10/CaseInsensitiveString.java @@ -14,28 +14,26 @@ public CaseInsensitiveString(String s) { // Broken - violates symmetry! @Override public boolean equals(Object o) { - if (o instanceof CaseInsensitiveString) - return s.equalsIgnoreCase( - ((CaseInsensitiveString) o).s); - if (o instanceof String) // One-way interoperability! - return s.equalsIgnoreCase((String) o); + if (o instanceof CaseInsensitiveString cis) + return s.equalsIgnoreCase(cis.s); + if (o instanceof String s2) // One-way interoperability! + return s.equalsIgnoreCase(s2); return false; } // Demonstration of the problem (Page 40) public static void main(String[] args) { - CaseInsensitiveString cis = new CaseInsensitiveString("Polish"); - String s = "polish"; + var cis = new CaseInsensitiveString("Polish"); + var string = "polish"; - List list = new ArrayList<>(); - list.add(cis); + var list = List.of(cis); - System.out.println(list.contains(s)); + System.out.println(list.contains(string)); } // // Fixed equals method (Page 40) // @Override public boolean equals(Object o) { -// return o instanceof CaseInsensitiveString && -// ((CaseInsensitiveString) o).s.equalsIgnoreCase(s); +// return o instanceof CaseInsensitiveString cis && +// cis.s.equalsIgnoreCase(s); // } } diff --git a/src/effectivejava/chapter3/item10/PhoneNumber.java b/src/effectivejava/chapter3/item10/PhoneNumber.java index 244d78f6..26b6d2bf 100644 --- a/src/effectivejava/chapter3/item10/PhoneNumber.java +++ b/src/effectivejava/chapter3/item10/PhoneNumber.java @@ -17,12 +17,8 @@ private static short rangeCheck(int val, int max, String arg) { } @Override public boolean equals(Object o) { - if (o == this) - return true; - if (!(o instanceof PhoneNumber)) - return false; - PhoneNumber pn = (PhoneNumber)o; - return pn.lineNum == lineNum && pn.prefix == prefix + return o instanceof PhoneNumber pn + && pn.lineNum == lineNum && pn.prefix == prefix && pn.areaCode == areaCode; } diff --git a/src/effectivejava/chapter3/item10/Point.java b/src/effectivejava/chapter3/item10/Point.java index d3acd2e9..c40b1756 100644 --- a/src/effectivejava/chapter3/item10/Point.java +++ b/src/effectivejava/chapter3/item10/Point.java @@ -1,6 +1,7 @@ package effectivejava.chapter3.item10; // Simple immutable two-dimensional integer point class (Page 37) +// Can not be a record because ColorPoint inherits of Point public class Point { private final int x; private final int y; @@ -11,10 +12,7 @@ public Point(int x, int y) { } @Override public boolean equals(Object o) { - if (!(o instanceof Point)) - return false; - Point p = (Point)o; - return p.x == x && p.y == y; + return o instanceof Point point && point.x == x && point.y == y; } // // Broken - violates Liskov substitution principle (page 43) diff --git a/src/effectivejava/chapter3/item10/composition/ColorPoint.java b/src/effectivejava/chapter3/item10/composition/ColorPoint.java index 7bcf2bc2..6a1f5e7a 100644 --- a/src/effectivejava/chapter3/item10/composition/ColorPoint.java +++ b/src/effectivejava/chapter3/item10/composition/ColorPoint.java @@ -6,13 +6,14 @@ import java.util.Objects; // Adds a value component without violating the equals contract (page 44) -public class ColorPoint { - private final Point point; - private final Color color; +public record ColorPoint(Point point, Color color) { + public ColorPoint { + Objects.requireNonNull(point); + Objects.requireNonNull(color); + } public ColorPoint(int x, int y, Color color) { - point = new Point(x, y); - this.color = Objects.requireNonNull(color); + this(new Point(x, y), color); } /** @@ -22,13 +23,12 @@ public Point asPoint() { return point; } + // not necessary, it's a record @Override public boolean equals(Object o) { - if (!(o instanceof ColorPoint)) - return false; - ColorPoint cp = (ColorPoint) o; - return cp.point.equals(point) && cp.color.equals(color); + return o instanceof ColorPoint cp && cp.point.equals(point) && cp.color == color; } + // not necessary, it's a record @Override public int hashCode() { return 31 * point.hashCode() + color.hashCode(); } diff --git a/src/effectivejava/chapter3/item10/inheritance/ColorPoint.java b/src/effectivejava/chapter3/item10/inheritance/ColorPoint.java index 5aa30419..6c39ffce 100644 --- a/src/effectivejava/chapter3/item10/inheritance/ColorPoint.java +++ b/src/effectivejava/chapter3/item10/inheritance/ColorPoint.java @@ -14,9 +14,7 @@ public ColorPoint(int x, int y, Color color) { // Broken - violates symmetry! (Page 41) @Override public boolean equals(Object o) { - if (!(o instanceof ColorPoint)) - return false; - return super.equals(o) && ((ColorPoint) o).color == color; + return o instanceof ColorPoint colorPoint && super.equals(o) && ((ColorPoint) o).color == color; } // // Broken - violates transitivity! (page 42) diff --git a/src/effectivejava/chapter3/item10/inheritance/CounterPoint.java b/src/effectivejava/chapter3/item10/inheritance/CounterPoint.java index 74771dbe..d258be37 100644 --- a/src/effectivejava/chapter3/item10/inheritance/CounterPoint.java +++ b/src/effectivejava/chapter3/item10/inheritance/CounterPoint.java @@ -5,12 +5,12 @@ // Trivial subclass of Point - doesn't add a value component (Page 43) public class CounterPoint extends Point { - private static final AtomicInteger counter = + private static final AtomicInteger COUNTER = new AtomicInteger(); public CounterPoint(int x, int y) { super(x, y); - counter.incrementAndGet(); + COUNTER.incrementAndGet(); } - public static int numberCreated() { return counter.get(); } + public static int numberCreated() { return COUNTER.get(); } } diff --git a/src/effectivejava/chapter3/item10/inheritance/CounterPointTest.java b/src/effectivejava/chapter3/item10/inheritance/CounterPointTest.java index 7e72d262..cd132923 100644 --- a/src/effectivejava/chapter3/item10/inheritance/CounterPointTest.java +++ b/src/effectivejava/chapter3/item10/inheritance/CounterPointTest.java @@ -6,17 +6,17 @@ // Test program that uses CounterPoint as Point public class CounterPointTest { // Initialize unitCircle to contain all Points on the unit circle (Page 43) - private static final Set unitCircle = Set.of( + private static final Set UNIT_CIRCLE = Set.of( new Point( 1, 0), new Point( 0, 1), new Point(-1, 0), new Point( 0, -1)); public static boolean onUnitCircle(Point p) { - return unitCircle.contains(p); + return UNIT_CIRCLE.contains(p); } public static void main(String[] args) { - Point p1 = new Point(1, 0); - Point p2 = new CounterPoint(1, 0); + var p1 = new Point(1, 0); + var p2 = new CounterPoint(1, 0); // Prints true System.out.println(onUnitCircle(p1)); diff --git a/src/effectivejava/chapter3/item11/PhoneNumber.java b/src/effectivejava/chapter3/item11/PhoneNumber.java index 084f1e95..651bfe87 100644 --- a/src/effectivejava/chapter3/item11/PhoneNumber.java +++ b/src/effectivejava/chapter3/item11/PhoneNumber.java @@ -20,10 +20,8 @@ private static short rangeCheck(int val, int max, String arg) { @Override public boolean equals(Object o) { if (o == this) return true; - if (!(o instanceof PhoneNumber)) - return false; - PhoneNumber pn = (PhoneNumber)o; - return pn.lineNum == lineNum && pn.prefix == prefix + return o instanceof PhoneNumber pn + && pn.lineNum == lineNum && pn.prefix == prefix && pn.areaCode == areaCode; } @@ -32,7 +30,7 @@ private static short rangeCheck(int val, int max, String arg) { // // Typical hashCode method (Page 52) // @Override public int hashCode() { -// int result = Short.hashCode(areaCode); +// var result = Short.hashCode(areaCode); // result = 31 * result + Short.hashCode(prefix); // result = 31 * result + Short.hashCode(lineNum); // return result; @@ -47,7 +45,7 @@ private static short rangeCheck(int val, int max, String arg) { // private int hashCode; // Automatically initialized to 0 // // @Override public int hashCode() { -// int result = hashCode; +// var result = hashCode; // if (result == 0) { // result = Short.hashCode(areaCode); // result = 31 * result + Short.hashCode(prefix); @@ -58,8 +56,7 @@ private static short rangeCheck(int val, int max, String arg) { // } public static void main(String[] args) { - Map m = new HashMap<>(); - m.put(new PhoneNumber(707, 867, 5309), "Jenny"); - System.out.println(m.get(new PhoneNumber(707, 867, 5309))); + var map = Map.of(new PhoneNumber(707, 867, 5309), "Jenny"); + System.out.println(map.get(new PhoneNumber(707, 867, 5309))); } } diff --git a/src/effectivejava/chapter3/item12/PhoneNumber.java b/src/effectivejava/chapter3/item12/PhoneNumber.java index ccc3206c..fa77f85d 100644 --- a/src/effectivejava/chapter3/item12/PhoneNumber.java +++ b/src/effectivejava/chapter3/item12/PhoneNumber.java @@ -19,15 +19,13 @@ private static short rangeCheck(int val, int max, String arg) { @Override public boolean equals(Object o) { if (o == this) return true; - if (!(o instanceof effectivejava.chapter3.item11.PhoneNumber)) - return false; - PhoneNumber pn = (PhoneNumber)o; - return pn.lineNum == lineNum && pn.prefix == prefix + return o instanceof PhoneNumber pn + && pn.lineNum == lineNum && pn.prefix == prefix && pn.areaCode == areaCode; } @Override public int hashCode() { - int result = Short.hashCode(areaCode); + var result = Short.hashCode(areaCode); result = 31 * result + Short.hashCode(prefix); result = 31 * result + Short.hashCode(lineNum); return result; @@ -51,7 +49,7 @@ private static short rangeCheck(int val, int max, String arg) { // } public static void main(String[] args) { - PhoneNumber jenny = new PhoneNumber(707, 867, 5309); + var jenny = new PhoneNumber(707, 867, 5309); System.out.println("Jenny's number: " + jenny); } } diff --git a/src/effectivejava/chapter3/item13/PhoneNumber.java b/src/effectivejava/chapter3/item13/PhoneNumber.java index 27b3b4c6..df182569 100644 --- a/src/effectivejava/chapter3/item13/PhoneNumber.java +++ b/src/effectivejava/chapter3/item13/PhoneNumber.java @@ -22,15 +22,13 @@ private static short rangeCheck(int val, int max, String arg) { @Override public boolean equals(Object o) { if (o == this) return true; - if (!(o instanceof PhoneNumber)) - return false; - PhoneNumber pn = (PhoneNumber)o; - return pn.lineNum == lineNum && pn.prefix == prefix + return o instanceof PhoneNumber pn + && pn.lineNum == lineNum && pn.prefix == prefix && pn.areaCode == areaCode; } @Override public int hashCode() { - int result = Short.hashCode(areaCode); + var result = Short.hashCode(areaCode); result = 31 * result + Short.hashCode(prefix); result = 31 * result + Short.hashCode(lineNum); return result; @@ -63,9 +61,8 @@ private static short rangeCheck(int val, int max, String arg) { } public static void main(String[] args) { - PhoneNumber pn = new PhoneNumber(707, 867, 5309); - Map m = new HashMap<>(); - m.put(pn, "Jenny"); - System.out.println(m.get(pn.clone())); + var pn = new PhoneNumber(707, 867, 5309); + var map = Map.of(pn, "Jenny"); + System.out.println(map.get(pn.clone())); } } diff --git a/src/effectivejava/chapter3/item14/PhoneNumber.java b/src/effectivejava/chapter3/item14/PhoneNumber.java index 22d5ee95..79b107d9 100644 --- a/src/effectivejava/chapter3/item14/PhoneNumber.java +++ b/src/effectivejava/chapter3/item14/PhoneNumber.java @@ -1,7 +1,12 @@ package effectivejava.chapter3.item14; import java.util.*; import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + import static java.util.Comparator.*; +import static java.util.stream.Collectors.toCollection; +import static java.util.stream.IntStream.range; // Making PhoneNumber comparable (Pages 69-70) public final class PhoneNumber implements Cloneable, Comparable { @@ -22,15 +27,13 @@ private static short rangeCheck(int val, int max, String arg) { @Override public boolean equals(Object o) { if (o == this) return true; - if (!(o instanceof effectivejava.chapter3.item11.PhoneNumber)) - return false; - PhoneNumber pn = (PhoneNumber)o; - return pn.lineNum == lineNum && pn.prefix == prefix + return o instanceof PhoneNumber pn + && pn.lineNum == lineNum && pn.prefix == prefix && pn.areaCode == areaCode; } @Override public int hashCode() { - int result = Short.hashCode(areaCode); + var result = Short.hashCode(areaCode); result = 31 * result + Short.hashCode(prefix); result = 31 * result + Short.hashCode(lineNum); return result; @@ -55,7 +58,7 @@ private static short rangeCheck(int val, int max, String arg) { // // Multiple-field Comparable with primitive fields (page 69) // public int compareTo(PhoneNumber pn) { -// int result = Short.compare(areaCode, pn.areaCode); +// var result = Short.compare(areaCode, pn.areaCode); // if (result == 0) { // result = Short.compare(prefix, pn.prefix); // if (result == 0) @@ -75,16 +78,14 @@ public int compareTo(PhoneNumber pn) { } private static PhoneNumber randomPhoneNumber() { - Random rnd = ThreadLocalRandom.current(); + var rnd = ThreadLocalRandom.current(); return new PhoneNumber((short) rnd.nextInt(1000), (short) rnd.nextInt(1000), (short) rnd.nextInt(10000)); } public static void main(String[] args) { - NavigableSet s = new TreeSet(); - for (int i = 0; i < 10; i++) - s.add(randomPhoneNumber()); - System.out.println(s); + var set = range(0, 10).mapToObj(__ -> randomPhoneNumber()).collect(toCollection(TreeSet::new)); + System.out.println(set); } } diff --git a/src/effectivejava/chapter3/item14/WordList.java b/src/effectivejava/chapter3/item14/WordList.java index 1ed82e17..ee3054a0 100644 --- a/src/effectivejava/chapter3/item14/WordList.java +++ b/src/effectivejava/chapter3/item14/WordList.java @@ -4,8 +4,8 @@ // The benefits of implementing Comparable (Page 66) public class WordList { public static void main(String[] args) { - Set s = new TreeSet<>(); - Collections.addAll(s, args); - System.out.println(s); + var set = new TreeSet(); + Collections.addAll(set, args); + System.out.println(set); } } diff --git a/src/effectivejava/chapter4/item17/Complex.java b/src/effectivejava/chapter4/item17/Complex.java index 49d33d81..1df61a2e 100644 --- a/src/effectivejava/chapter4/item17/Complex.java +++ b/src/effectivejava/chapter4/item17/Complex.java @@ -1,24 +1,13 @@ package effectivejava.chapter4.item17; // Immutable complex number class (Pages 81-82) -public final class Complex { - private final double re; - private final double im; - +public record Complex(double realPart/*realPart*/, double imaginaryPart) { public static final Complex ZERO = new Complex(0, 0); public static final Complex ONE = new Complex(1, 0); public static final Complex I = new Complex(0, 1); - public Complex(double re, double im) { - this.re = re; - this.im = im; - } - - public double realPart() { return re; } - public double imaginaryPart() { return im; } - public Complex plus(Complex c) { - return new Complex(re + c.re, im + c.im); + return new Complex(realPart + c.realPart, imaginaryPart + c.imaginaryPart); } // Static factory, used in conjunction with private constructor (Page 85) @@ -27,36 +16,34 @@ public static Complex valueOf(double re, double im) { } public Complex minus(Complex c) { - return new Complex(re - c.re, im - c.im); + return new Complex(realPart - c.realPart, imaginaryPart - c.imaginaryPart); } public Complex times(Complex c) { - return new Complex(re * c.re - im * c.im, - re * c.im + im * c.re); + return new Complex(realPart * c.realPart - imaginaryPart * c.imaginaryPart, + realPart * c.imaginaryPart + imaginaryPart * c.realPart); } public Complex dividedBy(Complex c) { - double tmp = c.re * c.re + c.im * c.im; - return new Complex((re * c.re + im * c.im) / tmp, - (im * c.re - re * c.im) / tmp); + var tmp = c.realPart * c.realPart + c.imaginaryPart * c.imaginaryPart; + return new Complex((realPart * c.realPart + imaginaryPart * c.imaginaryPart) / tmp, + (imaginaryPart * c.realPart - realPart * c.imaginaryPart) / tmp); } + /* Unnecessary it's a record @Override public boolean equals(Object o) { if (o == this) return true; - if (!(o instanceof Complex)) - return false; - Complex c = (Complex) o; - // See page 47 to find out why we use compare instead of == - return Double.compare(c.re, re) == 0 - && Double.compare(c.im, im) == 0; + return o instanceof Complex c + && Double.compare(c.realPart, realPart) == 0 + && Double.compare(c.imaginaryPart, imaginaryPart) == 0; } @Override public int hashCode() { - return 31 * Double.hashCode(re) + Double.hashCode(im); - } + return 31 * Double.hashCode(realPart) + Double.hashCode(imaginaryPart); + }*/ @Override public String toString() { - return "(" + re + " + " + im + "i)"; + return "(" + realPart + " + " + imaginaryPart + "i)"; } } diff --git a/src/effectivejava/chapter4/item18/InstrumentedHashSet.java b/src/effectivejava/chapter4/item18/InstrumentedHashSet.java index 7533c7f2..dad21edb 100644 --- a/src/effectivejava/chapter4/item18/InstrumentedHashSet.java +++ b/src/effectivejava/chapter4/item18/InstrumentedHashSet.java @@ -28,8 +28,8 @@ public int getAddCount() { } public static void main(String[] args) { - InstrumentedHashSet s = new InstrumentedHashSet<>(); - s.addAll(List.of("Snap", "Crackle", "Pop")); - System.out.println(s.getAddCount()); + var set = new InstrumentedHashSet(); + set.addAll(List.of("Snap", "Crackle", "Pop")); + System.out.println(set.getAddCount()); } } diff --git a/src/effectivejava/chapter4/item18/InstrumentedSet.java b/src/effectivejava/chapter4/item18/InstrumentedSet.java index 920fd3f2..2fec3cb6 100644 --- a/src/effectivejava/chapter4/item18/InstrumentedSet.java +++ b/src/effectivejava/chapter4/item18/InstrumentedSet.java @@ -22,8 +22,8 @@ public int getAddCount() { } public static void main(String[] args) { - InstrumentedSet s = new InstrumentedSet<>(new HashSet<>()); - s.addAll(List.of("Snap", "Crackle", "Pop")); - System.out.println(s.getAddCount()); + var set = new InstrumentedSet<>(new HashSet()); + set.addAll(List.of("Snap", "Crackle", "Pop")); + System.out.println(set.getAddCount()); } } diff --git a/src/effectivejava/chapter4/item19/Sub.java b/src/effectivejava/chapter4/item19/Sub.java index 90b9f007..c348fa19 100644 --- a/src/effectivejava/chapter4/item19/Sub.java +++ b/src/effectivejava/chapter4/item19/Sub.java @@ -17,7 +17,7 @@ public final class Sub extends Super { } public static void main(String[] args) { - Sub sub = new Sub(); + var sub = new Sub(); sub.overrideMe(); } } diff --git a/src/effectivejava/chapter4/item20/AbstractMapEntry.java b/src/effectivejava/chapter4/item20/AbstractMapEntry.java index 97f4cf44..9f2cb13c 100644 --- a/src/effectivejava/chapter4/item20/AbstractMapEntry.java +++ b/src/effectivejava/chapter4/item20/AbstractMapEntry.java @@ -13,10 +13,9 @@ public abstract class AbstractMapEntry @Override public boolean equals(Object o) { if (o == this) return true; - if (!(o instanceof Map.Entry)) + if (!(o instanceof Map.Entry e)) return false; - Map.Entry e = (Map.Entry) o; - return Objects.equals(e.getKey(), getKey()) + return Objects.equals(e.getKey(), getKey()) && Objects.equals(e.getValue(), getValue()); } diff --git a/src/effectivejava/chapter4/item20/IntArrays.java b/src/effectivejava/chapter4/item20/IntArrays.java index 46a367c4..e0bca2b4 100644 --- a/src/effectivejava/chapter4/item20/IntArrays.java +++ b/src/effectivejava/chapter4/item20/IntArrays.java @@ -26,11 +26,11 @@ static List intArrayAsList(int[] a) { } public static void main(String[] args) { - int[] a = new int[10]; - for (int i = 0; i < a.length; i++) - a[i] = i; + var array = new int[10]; + for (var i = 0; i < array.length; i++) + array[i] = i; - List list = intArrayAsList(a); + var list = intArrayAsList(array); Collections.shuffle(list); System.out.println(list); } diff --git a/src/effectivejava/chapter4/item23/hierarchy/Circle.java b/src/effectivejava/chapter4/item23/hierarchy/Circle.java index 6b7017a5..1fd84ad3 100644 --- a/src/effectivejava/chapter4/item23/hierarchy/Circle.java +++ b/src/effectivejava/chapter4/item23/hierarchy/Circle.java @@ -1,10 +1,6 @@ package effectivejava.chapter4.item23.hierarchy; // Class hierarchy replacement for a tagged class (Page 110-11) -class Circle extends Figure { - final double radius; - - Circle(double radius) { this.radius = radius; } - - @Override double area() { return Math.PI * (radius * radius); } +record Circle(double radius) implements Figure { + @Override public double area() { return Math.PI * (radius * radius); } } diff --git a/src/effectivejava/chapter4/item23/hierarchy/Figure.java b/src/effectivejava/chapter4/item23/hierarchy/Figure.java index 1ab39fa0..209c158c 100644 --- a/src/effectivejava/chapter4/item23/hierarchy/Figure.java +++ b/src/effectivejava/chapter4/item23/hierarchy/Figure.java @@ -1,6 +1,6 @@ package effectivejava.chapter4.item23.hierarchy; // Class hierarchy replacement for a tagged class (Page 110-11) -abstract class Figure { +interface Figure { abstract double area(); } diff --git a/src/effectivejava/chapter4/item23/hierarchy/Rectangle.java b/src/effectivejava/chapter4/item23/hierarchy/Rectangle.java index 090ed053..10922c31 100644 --- a/src/effectivejava/chapter4/item23/hierarchy/Rectangle.java +++ b/src/effectivejava/chapter4/item23/hierarchy/Rectangle.java @@ -1,7 +1,7 @@ package effectivejava.chapter4.item23.hierarchy; // Class hierarchy replacement for a tagged class (Page 110-11) -class Rectangle extends Figure { +class Rectangle implements Figure { final double length; final double width; @@ -9,5 +9,5 @@ class Rectangle extends Figure { this.length = length; this.width = width; } - @Override double area() { return length * width; } + @Override public double area() { return length * width; } } \ No newline at end of file diff --git a/src/effectivejava/chapter4/item23/taggedclass/Figure.java b/src/effectivejava/chapter4/item23/taggedclass/Figure.java index efb7b789..763b3b59 100644 --- a/src/effectivejava/chapter4/item23/taggedclass/Figure.java +++ b/src/effectivejava/chapter4/item23/taggedclass/Figure.java @@ -28,13 +28,9 @@ enum Shape { RECTANGLE, CIRCLE }; } double area() { - switch(shape) { - case RECTANGLE: - return length * width; - case CIRCLE: - return Math.PI * (radius * radius); - default: - throw new AssertionError(shape); - } + return switch(shape) { + case RECTANGLE -> length * width; + case CIRCLE -> Math.PI * (radius * radius); + }; } } diff --git a/src/effectivejava/chapter5/item26/Raw.java b/src/effectivejava/chapter5/item26/Raw.java index 5cb1d909..a74f7238 100644 --- a/src/effectivejava/chapter5/item26/Raw.java +++ b/src/effectivejava/chapter5/item26/Raw.java @@ -4,7 +4,7 @@ // Fails at runtime - unsafeAdd method uses a raw type (List)! (Page 119) public class Raw { public static void main(String[] args) { - List strings = new ArrayList<>(); + var strings = new ArrayList(); unsafeAdd(strings, Integer.valueOf(42)); String s = strings.get(0); // Has compiler-generated cast } diff --git a/src/effectivejava/chapter5/item28/Chooser.java b/src/effectivejava/chapter5/item28/Chooser.java index 259ab264..d497003c 100644 --- a/src/effectivejava/chapter5/item28/Chooser.java +++ b/src/effectivejava/chapter5/item28/Chooser.java @@ -11,20 +11,20 @@ public class Chooser { private final List choiceList; public Chooser(Collection choices) { - choiceList = new ArrayList<>(choices); + choiceList = List.copyOf(choices); } public T choose() { - Random rnd = ThreadLocalRandom.current(); + var rnd = ThreadLocalRandom.current(); return choiceList.get(rnd.nextInt(choiceList.size())); } public static void main(String[] args) { - List intList = List.of(1, 2, 3, 4, 5, 6); + var intList = List.of(1, 2, 3, 4, 5, 6); - Chooser chooser = new Chooser<>(intList); + var chooser = new Chooser<>(intList); - for (int i = 0; i < 10; i++) { + for (var i = 0; i < 10; i++) { Number choice = chooser.choose(); System.out.println(choice); } diff --git a/src/effectivejava/chapter5/item29/technqiue1/Stack.java b/src/effectivejava/chapter5/item29/technqiue1/Stack.java index fbaa60b7..a43ee229 100644 --- a/src/effectivejava/chapter5/item29/technqiue1/Stack.java +++ b/src/effectivejava/chapter5/item29/technqiue1/Stack.java @@ -25,7 +25,7 @@ public void push(E e) { public E pop() { if (size == 0) throw new EmptyStackException(); - E result = elements[--size]; + var result = elements[--size]; elements[size] = null; // Eliminate obsolete reference return result; } @@ -41,8 +41,8 @@ private void ensureCapacity() { // Little program to exercise our generic Stack public static void main(String[] args) { - Stack stack = new Stack<>(); - for (String arg : args) + var stack = new Stack(); + for (var arg : args) stack.push(arg); while (!stack.isEmpty()) System.out.println(stack.pop().toUpperCase()); diff --git a/src/effectivejava/chapter5/item29/technqiue2/Stack.java b/src/effectivejava/chapter5/item29/technqiue2/Stack.java index bf1632d3..e327a795 100644 --- a/src/effectivejava/chapter5/item29/technqiue2/Stack.java +++ b/src/effectivejava/chapter5/item29/technqiue2/Stack.java @@ -24,7 +24,7 @@ public E pop() { throw new EmptyStackException(); // push requires elements to be of type E, so cast is correct - @SuppressWarnings("unchecked") E result = + @SuppressWarnings("unchecked") var result = (E) elements[--size]; elements[size] = null; // Eliminate obsolete reference @@ -42,8 +42,8 @@ private void ensureCapacity() { // Little program to exercise our generic Stack public static void main(String[] args) { - Stack stack = new Stack<>(); - for (String arg : args) + var stack = new Stack(); + for (var arg : args) stack.push(arg); while (!stack.isEmpty()) System.out.println(stack.pop().toUpperCase()); diff --git a/src/effectivejava/chapter5/item30/GenericSingletonFactory.java b/src/effectivejava/chapter5/item30/GenericSingletonFactory.java index 6f27af8b..5cb61604 100644 --- a/src/effectivejava/chapter5/item30/GenericSingletonFactory.java +++ b/src/effectivejava/chapter5/item30/GenericSingletonFactory.java @@ -5,7 +5,7 @@ // Generic singleton factory pattern (Page 136-7) public class GenericSingletonFactory { // Generic singleton factory pattern - private static UnaryOperator IDENTITY_FN = (t) -> t; + private static UnaryOperator IDENTITY_FN = t -> t; @SuppressWarnings("unchecked") public static UnaryOperator identityFunction() { @@ -14,14 +14,14 @@ public static UnaryOperator identityFunction() { // Sample program to exercise generic singleton public static void main(String[] args) { - String[] strings = { "jute", "hemp", "nylon" }; + var strings = new String[] { "jute", "hemp", "nylon" }; UnaryOperator sameString = identityFunction(); - for (String s : strings) + for (var s : strings) System.out.println(sameString.apply(s)); - Number[] numbers = { 1, 2.0, 3L }; + var numbers = new Number[] { 1, 2.0, 3L }; UnaryOperator sameNumber = identityFunction(); - for (Number n : numbers) + for (var n : numbers) System.out.println(sameNumber.apply(n)); } } \ No newline at end of file diff --git a/src/effectivejava/chapter5/item30/RecursiveTypeBound.java b/src/effectivejava/chapter5/item30/RecursiveTypeBound.java index e3419dfc..1704e9b7 100644 --- a/src/effectivejava/chapter5/item30/RecursiveTypeBound.java +++ b/src/effectivejava/chapter5/item30/RecursiveTypeBound.java @@ -9,7 +9,7 @@ public static > E max(Collection c) { throw new IllegalArgumentException("Empty collection"); E result = null; - for (E e : c) + for (var e : c) if (result == null || e.compareTo(result) > 0) result = Objects.requireNonNull(e); @@ -17,7 +17,7 @@ public static > E max(Collection c) { } public static void main(String[] args) { - List argList = Arrays.asList(args); + var argList = List.of(args); System.out.println(max(argList)); } } \ No newline at end of file diff --git a/src/effectivejava/chapter5/item30/Union.java b/src/effectivejava/chapter5/item30/Union.java index 5ecb202f..de35e61e 100644 --- a/src/effectivejava/chapter5/item30/Union.java +++ b/src/effectivejava/chapter5/item30/Union.java @@ -6,16 +6,16 @@ public class Union { // Generic method public static Set union(Set s1, Set s2) { - Set result = new HashSet<>(s1); + var result = new HashSet(s1); result.addAll(s2); return result; } // Simple program to exercise generic method public static void main(String[] args) { - Set guys = Set.of("Tom", "Dick", "Harry"); - Set stooges = Set.of("Larry", "Moe", "Curly"); - Set aflCio = union(guys, stooges); + var guys = Set.of("Tom", "Dick", "Harry"); + var stooges = Set.of("Larry", "Moe", "Curly"); + var aflCio = union(guys, stooges); System.out.println(aflCio); } } diff --git a/src/effectivejava/chapter5/item31/Chooser.java b/src/effectivejava/chapter5/item31/Chooser.java index bb8443d0..002402d7 100644 --- a/src/effectivejava/chapter5/item31/Chooser.java +++ b/src/effectivejava/chapter5/item31/Chooser.java @@ -11,7 +11,7 @@ public class Chooser { private final Random rnd = new Random(); public Chooser(Collection choices) { - choiceList = new ArrayList<>(choices); + choiceList = List.copyOf(choices); } public T choose() { diff --git a/src/effectivejava/chapter5/item31/RecursiveTypeBound.java b/src/effectivejava/chapter5/item31/RecursiveTypeBound.java index d50aa1cf..d77a8d0f 100644 --- a/src/effectivejava/chapter5/item31/RecursiveTypeBound.java +++ b/src/effectivejava/chapter5/item31/RecursiveTypeBound.java @@ -9,7 +9,7 @@ public static > E max( throw new IllegalArgumentException("Empty list"); E result = null; - for (E e : list) + for (var e : list) if (result == null || e.compareTo(result) > 0) result = e; @@ -17,7 +17,7 @@ public static > E max( } public static void main(String[] args) { - List argList = Arrays.asList(args); + var argList = List.of(args); System.out.println(max(argList)); } } \ No newline at end of file diff --git a/src/effectivejava/chapter5/item31/Stack.java b/src/effectivejava/chapter5/item31/Stack.java index a5abe59d..3e31a1d3 100644 --- a/src/effectivejava/chapter5/item31/Stack.java +++ b/src/effectivejava/chapter5/item31/Stack.java @@ -23,7 +23,7 @@ public void push(E e) { public E pop() { if (size==0) throw new EmptyStackException(); - E result = elements[--size]; + var result = elements[--size]; elements[size] = null; // Eliminate obsolete reference return result; } @@ -45,7 +45,7 @@ private void ensureCapacity() { // Wildcard type for parameter that serves as an E producer public void pushAll(Iterable src) { - for (E e : src) + for (var e : src) push(e); } @@ -63,8 +63,8 @@ public void popAll(Collection dst) { // Little program to exercise our generic Stack public static void main(String[] args) { - Stack numberStack = new Stack<>(); - Iterable integers = Arrays.asList(3, 1, 4, 1, 5, 9); + var numberStack = new Stack(); + Iterable integers = List.of(3, 1, 4, 1, 5, 9); numberStack.pushAll(integers); Collection objects = new ArrayList<>(); diff --git a/src/effectivejava/chapter5/item31/Swap.java b/src/effectivejava/chapter5/item31/Swap.java index 776f886f..e99ff536 100644 --- a/src/effectivejava/chapter5/item31/Swap.java +++ b/src/effectivejava/chapter5/item31/Swap.java @@ -14,7 +14,7 @@ private static void swapHelper(List list, int i, int j) { public static void main(String[] args) { // Swap the first and last argument and print the resulting list - List argList = Arrays.asList(args); + var argList = Arrays.asList(args); swap(argList, 0, argList.size() - 1); System.out.println(argList); } diff --git a/src/effectivejava/chapter5/item31/Union.java b/src/effectivejava/chapter5/item31/Union.java index 71cc58b8..b1691516 100644 --- a/src/effectivejava/chapter5/item31/Union.java +++ b/src/effectivejava/chapter5/item31/Union.java @@ -5,19 +5,19 @@ public class Union { public static Set union(Set s1, Set s2) { - Set result = new HashSet(s1); + var result = new HashSet(s1); result.addAll(s2); return result; } // Simple program to exercise flexible generic staticfactory public static void main(String[] args) { - Set integers = new HashSet<>(); + var integers = new HashSet(); integers.add(1); integers.add(3); integers.add(5); - Set doubles = new HashSet<>(); + var doubles = new HashSet(); doubles.add(2.0); doubles.add(4.0); doubles.add(6.0); @@ -27,6 +27,9 @@ public static void main(String[] args) { // // Explicit type parameter - required prior to Java 8 // Set numbers = Union.union(integers, doubles); +// // Using var since Java 10 +// var numbers = union(integers, doubles); + System.out.println(numbers); } } diff --git a/src/effectivejava/chapter5/item32/FlattenWithList.java b/src/effectivejava/chapter5/item32/FlattenWithList.java index b9cbaa71..8a53a7b0 100644 --- a/src/effectivejava/chapter5/item32/FlattenWithList.java +++ b/src/effectivejava/chapter5/item32/FlattenWithList.java @@ -3,17 +3,22 @@ import java.util.ArrayList; import java.util.List; +import static java.util.stream.Collectors.toList; + // List as a typesafe alternative to a generic varargs parameter (page 149) public class FlattenWithList { - static List flatten(List> lists) { - List result = new ArrayList<>(); - for (List list : lists) - result.addAll(list); - return result; + static List flatten(List> lists) { + //var result = new ArrayList(); + //for (var list : lists) + // result.addAll(list); + //return result; + + // using a stream + return lists.stream().flatMap(List::stream).collect(toList()); } public static void main(String[] args) { - List flatList = flatten(List.of( + var flatList = flatten(List.of( List.of(1, 2), List.of(3, 4, 5), List.of(6,7))); System.out.println(flatList); } diff --git a/src/effectivejava/chapter5/item32/FlattenWithVarargs.java b/src/effectivejava/chapter5/item32/FlattenWithVarargs.java index e33f4472..379a004e 100644 --- a/src/effectivejava/chapter5/item32/FlattenWithVarargs.java +++ b/src/effectivejava/chapter5/item32/FlattenWithVarargs.java @@ -1,20 +1,26 @@ package effectivejava.chapter5.item32; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import static java.util.stream.Collectors.toList; + // Safe method with a generic varargs parameter (page 149) public class FlattenWithVarargs { @SafeVarargs static List flatten(List... lists) { - List result = new ArrayList<>(); - for (List list : lists) - result.addAll(list); - return result; + // var result = new ArrayList(); + // for (var list : lists) + // result.addAll(list); + // return result; + + // using a stream + return Arrays.stream(lists).flatMap(List::stream).collect(toList()); } public static void main(String[] args) { - List flatList = flatten( + var flatList = flatten( List.of(1, 2), List.of(3, 4, 5), List.of(6,7)); System.out.println(flatList); } diff --git a/src/effectivejava/chapter5/item32/PickTwo.java b/src/effectivejava/chapter5/item32/PickTwo.java index 297bea62..a12e2f6a 100644 --- a/src/effectivejava/chapter5/item32/PickTwo.java +++ b/src/effectivejava/chapter5/item32/PickTwo.java @@ -11,16 +11,16 @@ static T[] toArray(T... args) { } static T[] pickTwo(T a, T b, T c) { - switch(ThreadLocalRandom.current().nextInt(3)) { - case 0: return toArray(a, b); - case 1: return toArray(a, c); - case 2: return toArray(b, c); - } - throw new AssertionError(); // Can't get here + return switch(ThreadLocalRandom.current().nextInt(3)) { + case 0 -> toArray(a, b); + case 1 -> toArray(a, c); + case 2 -> toArray(b, c); + default -> throw new AssertionError(); // Can't get here + }; } public static void main(String[] args) { - String[] attributes = pickTwo("Good", "Fast", "Cheap"); + var attributes = pickTwo("Good", "Fast", "Cheap"); System.out.println(Arrays.toString(attributes)); } } diff --git a/src/effectivejava/chapter5/item32/SafePickTwo.java b/src/effectivejava/chapter5/item32/SafePickTwo.java index b8d864bf..b8146959 100644 --- a/src/effectivejava/chapter5/item32/SafePickTwo.java +++ b/src/effectivejava/chapter5/item32/SafePickTwo.java @@ -1,22 +1,21 @@ package effectivejava.chapter5.item32; -import java.util.Arrays; import java.util.List; import java.util.concurrent.ThreadLocalRandom; // Safe version of PickTwo using lists instead of arrays (Page 150) public class SafePickTwo { static List pickTwo(T a, T b, T c) { - switch(ThreadLocalRandom.current().nextInt(3)) { - case 0: return List.of(a, b); - case 1: return List.of(a, c); - case 2: return List.of(b, c); - } - throw new AssertionError(); + return switch(ThreadLocalRandom.current().nextInt(3)) { + case 0 -> List.of(a, b); + case 1 -> List.of(a, c); + case 2 -> List.of(b, c); + default -> throw new AssertionError(); + }; } public static void main(String[] args) { - List attributes = pickTwo("Good", "Fast", "Cheap"); + var attributes = pickTwo("Good", "Fast", "Cheap"); System.out.println(attributes); } } diff --git a/src/effectivejava/chapter5/item33/Favorites.java b/src/effectivejava/chapter5/item33/Favorites.java index 4e3385f7..6166a70a 100644 --- a/src/effectivejava/chapter5/item33/Favorites.java +++ b/src/effectivejava/chapter5/item33/Favorites.java @@ -3,7 +3,7 @@ // Typesafe heterogeneous container pattern (Pages 151-4) public class Favorites { - private Map, Object> favorites = new HashMap<>(); + private final HashMap, Object> favorites = new HashMap<>(); public void putFavorite(Class type, T instance) { favorites.put(Objects.requireNonNull(type), instance); @@ -19,13 +19,13 @@ public T getFavorite(Class type) { // } public static void main(String[] args) { - Favorites f = new Favorites(); + var f = new Favorites(); f.putFavorite(String.class, "Java"); f.putFavorite(Integer.class, 0xcafebabe); f.putFavorite(Class.class, Favorites.class); - String favoriteString = f.getFavorite(String.class); - int favoriteInteger = f.getFavorite(Integer.class); - Class favoriteClass = f.getFavorite(Class.class); + var favoriteString = f.getFavorite(String.class); + var favoriteInteger = f.getFavorite(Integer.class); + var favoriteClass = f.getFavorite(Class.class); System.out.printf("%s %x %s%n", favoriteString, favoriteInteger, favoriteClass.getName()); } diff --git a/src/effectivejava/chapter5/item33/PrintAnnotation.java b/src/effectivejava/chapter5/item33/PrintAnnotation.java index bbd3d13c..c47907ab 100644 --- a/src/effectivejava/chapter5/item33/PrintAnnotation.java +++ b/src/effectivejava/chapter5/item33/PrintAnnotation.java @@ -6,10 +6,10 @@ public class PrintAnnotation { static Annotation getAnnotation(AnnotatedElement element, String annotationTypeName) { - Class annotationType = null; // Unbounded type token + Class annotationType; // Unbounded type token try { annotationType = Class.forName(annotationTypeName); - } catch (Exception ex) { + } catch (ClassNotFoundException ex) { throw new IllegalArgumentException(ex); } return element.getAnnotation( @@ -23,9 +23,9 @@ public static void main(String[] args) throws Exception { "Usage: java PrintAnnotation "); System.exit(1); } - String className = args[0]; - String annotationTypeName = args[1]; - Class klass = Class.forName(className); + var className = args[0]; + var annotationTypeName = args[1]; + var klass = Class.forName(className); System.out.println(getAnnotation(klass, annotationTypeName)); } } diff --git a/src/effectivejava/chapter6/item34/Inverse.java b/src/effectivejava/chapter6/item34/Inverse.java index cced1080..da2c8d0c 100644 --- a/src/effectivejava/chapter6/item34/Inverse.java +++ b/src/effectivejava/chapter6/item34/Inverse.java @@ -3,21 +3,19 @@ // Switch on an enum to simulate a missing method (Page 167) public class Inverse { public static Operation inverse(Operation op) { - switch(op) { - case PLUS: return Operation.MINUS; - case MINUS: return Operation.PLUS; - case TIMES: return Operation.DIVIDE; - case DIVIDE: return Operation.TIMES; - - default: throw new AssertionError("Unknown op: " + op); - } + return switch(op) { + case PLUS -> Operation.MINUS; + case MINUS -> Operation.PLUS; + case TIMES -> Operation.DIVIDE; + case DIVIDE -> Operation.TIMES; + }; } public static void main(String[] args) { - double x = Double.parseDouble(args[0]); - double y = Double.parseDouble(args[1]); - for (Operation op : Operation.values()) { - Operation invOp = inverse(op); + var x = Double.parseDouble(args[0]); + var y = Double.parseDouble(args[1]); + for (var op : Operation.values()) { + var invOp = inverse(op); System.out.printf("%f %s %f %s %f = %f%n", x, op, y, invOp, y, invOp.apply(op.apply(x, y), y)); } diff --git a/src/effectivejava/chapter6/item34/Operation.java b/src/effectivejava/chapter6/item34/Operation.java index ba89c8f9..9a799652 100644 --- a/src/effectivejava/chapter6/item34/Operation.java +++ b/src/effectivejava/chapter6/item34/Operation.java @@ -38,9 +38,9 @@ public static Optional fromString(String symbol) { } public static void main(String[] args) { - double x = Double.parseDouble(args[0]); - double y = Double.parseDouble(args[1]); - for (Operation op : Operation.values()) + var x = Double.parseDouble(args[0]); + var y = Double.parseDouble(args[1]); + for (var op : Operation.values()) System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y)); } diff --git a/src/effectivejava/chapter6/item34/PayrollDay.java b/src/effectivejava/chapter6/item34/PayrollDay.java index 54a89c12..9048c11f 100644 --- a/src/effectivejava/chapter6/item34/PayrollDay.java +++ b/src/effectivejava/chapter6/item34/PayrollDay.java @@ -40,7 +40,7 @@ int pay(int minsWorked, int payRate) { } public static void main(String[] args) { - for (PayrollDay day : values()) + for (var day : values()) System.out.printf("%-10s%d%n", day, day.pay(8 * 60, 1)); } } diff --git a/src/effectivejava/chapter6/item34/WeightTable.java b/src/effectivejava/chapter6/item34/WeightTable.java index 948c2e37..010e8841 100644 --- a/src/effectivejava/chapter6/item34/WeightTable.java +++ b/src/effectivejava/chapter6/item34/WeightTable.java @@ -3,10 +3,10 @@ // Takes earth-weight and prints table of weights on all planets (Page 160) public class WeightTable { public static void main(String[] args) { - double earthWeight = Double.parseDouble(args[0]); - double mass = earthWeight / Planet.EARTH.surfaceGravity(); - for (Planet p : Planet.values()) + var earthWeight = Double.parseDouble(args[0]); + var mass = earthWeight / Planet.EARTH.surfaceGravity(); + for (var planet : Planet.values()) System.out.printf("Weight on %s is %f%n", - p, p.surfaceWeight(mass)); + planet, planet.surfaceWeight(mass)); } } diff --git a/src/effectivejava/chapter6/item36/Text.java b/src/effectivejava/chapter6/item36/Text.java index 9f8aa6cd..595e2ee0 100644 --- a/src/effectivejava/chapter6/item36/Text.java +++ b/src/effectivejava/chapter6/item36/Text.java @@ -14,7 +14,7 @@ public void applyStyles(Set