diff --git a/collectiontopics/QueueBehavior.java b/collectiontopics/QueueBehavior.java index b1873325..923eab61 100644 --- a/collectiontopics/QueueBehavior.java +++ b/collectiontopics/QueueBehavior.java @@ -2,36 +2,49 @@ // (c)2017 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. // Visit http://OnJava8.com for more book information. -// Compares the behavior of some of the queues -import java.util.concurrent.*; +// Compares basic behavior import java.util.*; +import java.util.stream.*; +import java.util.concurrent.*; public class QueueBehavior { - private static String[] s = - ("one two three four five six seven " + - "eight nine ten").split(" "); - static void test(Queue queue) { - for(String ss : s) - queue.offer(ss); + static Stream strings() { + return Arrays.stream( + ("one two three four five six seven " + + "eight nine ten").split(" ")); + } + static void test(int id, Queue queue) { + System.out.print(id + ": "); + strings().map(queue::offer).count(); while(queue.peek() != null) System.out.print(queue.remove() + " "); System.out.println(); } public static void main(String[] args) { - int count = 10; - test(new LinkedList<>()); - test(new PriorityQueue<>()); - test(new ArrayBlockingQueue<>(count)); - test(new ConcurrentLinkedQueue<>()); - test(new LinkedBlockingQueue<>()); - test(new PriorityBlockingQueue<>()); + int count = 10; + test(1, new LinkedList<>()); + test(2, new PriorityQueue<>()); + test(3, new ArrayBlockingQueue<>(count)); + test(4, new ConcurrentLinkedQueue<>()); + test(5, new LinkedBlockingQueue<>()); + test(6, new PriorityBlockingQueue<>()); + test(7, new ArrayDeque<>()); + test(8, new ConcurrentLinkedDeque<>()); + test(9, new LinkedBlockingDeque<>()); + test(10, new LinkedTransferQueue<>()); + test(11, new SynchronousQueue<>()); } } /* Output: -one two three four five six seven eight nine ten -eight five four nine one seven six ten three two -one two three four five six seven eight nine ten -one two three four five six seven eight nine ten -one two three four five six seven eight nine ten -eight five four nine one seven six ten three two +1: one two three four five six seven eight nine ten +2: eight five four nine one seven six ten three two +3: one two three four five six seven eight nine ten +4: one two three four five six seven eight nine ten +5: one two three four five six seven eight nine ten +6: eight five four nine one seven six ten three two +7: one two three four five six seven eight nine ten +8: one two three four five six seven eight nine ten +9: one two three four five six seven eight nine ten +10: one two three four five six seven eight nine ten +11: */ diff --git a/collectiontopics/SimpleDeques.java b/collectiontopics/SimpleDeques.java index ead6bc1a..1600178e 100644 --- a/collectiontopics/SimpleDeques.java +++ b/collectiontopics/SimpleDeques.java @@ -3,8 +3,8 @@ // We make no guarantees that this code is fit for any purpose. // Visit http://OnJava8.com for more book information. // Very basic test of Deques -import java.util.concurrent.*; import java.util.*; +import java.util.concurrent.*; import java.util.function.*; class CountString implements Supplier { @@ -12,7 +12,9 @@ class CountString implements Supplier { public CountString() {} public CountString(int start) { n = start; } @Override - public String get() { return Integer.toString(n++); } + public String get() { + return Integer.toString(n++); + } } public class SimpleDeques { diff --git a/collectiontopics/SortedSetDemo.java b/collectiontopics/SortedSetDemo.java index eccd56ad..837978d4 100644 --- a/collectiontopics/SortedSetDemo.java +++ b/collectiontopics/SortedSetDemo.java @@ -2,15 +2,16 @@ // (c)2017 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. // Visit http://OnJava8.com for more book information. -// What you can do with a TreeSet import java.util.*; +import static java.util.stream.Collectors.*; public class SortedSetDemo { public static void main(String[] args) { - SortedSet sortedSet = new TreeSet<>(); - Collections.addAll(sortedSet, - "one two three four five six seven eight" - .split(" ")); + SortedSet sortedSet = + Arrays.stream( + "one two three four five six seven eight" + .split(" ")) + .collect(toCollection(TreeSet::new)); System.out.println(sortedSet); String low = sortedSet.first(); String high = sortedSet.last(); diff --git a/collectiontopics/ToDoList.java b/collectiontopics/ToDoList.java index 870f7a7d..17e668cc 100644 --- a/collectiontopics/ToDoList.java +++ b/collectiontopics/ToDoList.java @@ -5,44 +5,42 @@ // A more complex use of PriorityQueue import java.util.*; -class ToDoList extends PriorityQueue { - static class ToDoItem implements Comparable { - private char primary; - private int secondary; - private String item; - public ToDoItem(String td, char pri, int sec) { - primary = pri; - secondary = sec; - item = td; - } - @Override - public int compareTo(ToDoItem arg) { - if(primary > arg.primary) +class ToDoItem implements Comparable { + private char primary; + private int secondary; + private String item; + public ToDoItem(String td, char pri, int sec) { + primary = pri; + secondary = sec; + item = td; + } + @Override + public int compareTo(ToDoItem arg) { + if(primary > arg.primary) + return +1; + if(primary == arg.primary) + if(secondary > arg.secondary) return +1; - if(primary == arg.primary) - if(secondary > arg.secondary) - return +1; - else if(secondary == arg.secondary) - return 0; - return -1; - } - @Override - public String toString() { - return Character.toString(primary) + - secondary + ": " + item; - } + else if(secondary == arg.secondary) + return 0; + return -1; } - public void add(String td, char pri, int sec) { - super.add(new ToDoItem(td, pri, sec)); + @Override + public String toString() { + return Character.toString(primary) + + secondary + ": " + item; } +} + +class ToDoList { public static void main(String[] args) { - ToDoList toDo = new ToDoList(); - toDo.add("Empty trash", 'C', 4); - toDo.add("Feed dog", 'A', 2); - toDo.add("Feed bird", 'B', 7); - toDo.add("Mow lawn", 'C', 3); - toDo.add("Water lawn", 'A', 1); - toDo.add("Feed cat", 'B', 1); + PriorityQueue toDo = new PriorityQueue<>(); + toDo.add(new ToDoItem("Empty trash", 'C', 4)); + toDo.add(new ToDoItem("Feed dog", 'A', 2)); + toDo.add(new ToDoItem("Feed bird", 'B', 7)); + toDo.add(new ToDoItem("Mow lawn", 'C', 3)); + toDo.add(new ToDoItem("Water lawn", 'A', 1)); + toDo.add(new ToDoItem("Feed cat", 'B', 1)); while(!toDo.isEmpty()) System.out.println(toDo.remove()); } diff --git a/collectiontopics/TypesForSets.java b/collectiontopics/TypesForSets.java index 49929500..cd672c9d 100644 --- a/collectiontopics/TypesForSets.java +++ b/collectiontopics/TypesForSets.java @@ -6,9 +6,10 @@ import java.util.*; import java.util.function.*; import java.util.Objects; +import onjava.CountMap; class SetType { - int i; + protected int i; public SetType(int n) { i = n; } @Override public boolean equals(Object o) { @@ -16,13 +17,17 @@ class SetType { Objects.equals(i, ((SetType)o).i); } @Override - public int hashCode() { return Objects.hash(i); } - @Override - public String toString() { return Integer.toString(i); } + public String toString() { + return Integer.toString(i); + } } class HashType extends SetType { public HashType(int n) { super(n); } + @Override + public int hashCode() { + return Objects.hashCode(i); + } } class TreeType extends SetType @@ -30,16 +35,19 @@ implements Comparable { public TreeType(int n) { super(n); } @Override public int compareTo(TreeType arg) { - return (arg.i < i ? -1 : (arg.i == i ? 0 : 1)); + return Integer.compare(arg.i, i); + // Equivalent to: + // return arg.i < i ? -1 : (arg.i == i ? 0 : 1); } } public class TypesForSets { - static Set + static void fill(Set set, Function type) { - for(int i = 0; i < 10; i++) - set.add(type.apply(i)); - return set; + for(int i = 10; i >= 5; i--) // Descending + set.add(type.apply(i)); + for(int i = 0; i < 5; i++) // Ascending + set.add(type.apply(i)); } static void test(Set set, Function type) { @@ -60,23 +68,27 @@ public class TypesForSets { try { test(new TreeSet<>(), SetType::new); } catch(Exception e) { - System.out.println("Expected: " + e.getMessage()); + System.out.println(e.getMessage()); } try { test(new TreeSet<>(), HashType::new); } catch(Exception e) { - System.out.println("Expected: " + e.getMessage()); + System.out.println(e.getMessage()); } } } /* Output: -[1, 2, 3, 4, 5, 6, 7, 8, 9, 0] -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -[9, 8, 7, 6, 5, 4, 3, 2, 1, 0] -[1, 2, 3, 4, 5, 6, 7, 8, 9, 0] -[1, 2, 3, 4, 5, 6, 7, 8, 9, 0] -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -Expected: SetType cannot be cast to java.lang.Comparable -Expected: HashType cannot be cast to java.lang.Comparable +[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +[10, 9, 8, 7, 6, 5, 0, 1, 2, 3, 4] +[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] +[1, 6, 8, 6, 2, 7, 8, 9, 4, 10, 7, 5, 1, 3, 4, 9, 9, +10, 5, 3, 2, 0, 4, 1, 2, 0, 8, 3, 0, 10, 6, 5, 7] +[3, 1, 4, 8, 7, 6, 9, 5, 3, 0, 10, 5, 5, 10, 7, 8, 8, +9, 1, 4, 10, 2, 6, 9, 1, 6, 0, 3, 2, 0, 7, 2, 4] +[10, 9, 8, 7, 6, 5, 0, 1, 2, 3, 4, 10, 9, 8, 7, 6, 5, +0, 1, 2, 3, 4, 10, 9, 8, 7, 6, 5, 0, 1, 2, 3, 4] +[10, 9, 8, 7, 6, 5, 0, 1, 2, 3, 4, 10, 9, 8, 7, 6, 5, +0, 1, 2, 3, 4, 10, 9, 8, 7, 6, 5, 0, 1, 2, 3, 4] +SetType cannot be cast to java.lang.Comparable +HashType cannot be cast to java.lang.Comparable */ diff --git a/onjava/CountMap.java b/onjava/CountMap.java index 31bc8632..9f087e44 100644 --- a/onjava/CountMap.java +++ b/onjava/CountMap.java @@ -19,8 +19,7 @@ extends AbstractMap { Integer.toString(key / chars.length); } public CountMap(int size) { - if(size < 0) this.size = 0; - else this.size = size; + this.size = size < 0 ? 0 : size; } @Override public String get(Object key) { @@ -57,9 +56,17 @@ extends AbstractMap { Collectors.toCollection(LinkedHashSet::new)); } public static void main(String[] args) { + final int LIM = 6; CountMap cm = new CountMap(60); System.out.println(cm); System.out.println(cm.get(500)); + cm.values().stream() + .limit(LIM) + .forEach(System.out::println); + System.out.println(); + new Random().ints(LIM, 0, 1000) + .mapToObj(cm::get) + .forEach(System.out::println); } } /* Output: @@ -72,4 +79,17 @@ extends AbstractMap { 49=X1, 50=Y1, 51=Z1, 52=A2, 53=B2, 54=C2, 55=D2, 56=E2, 57=F2, 58=G2, 59=H2} G19 +A0 +B0 +C0 +D0 +E0 +F0 + +E4 +X33 +P15 +L28 +M24 +Y36 */ diff --git a/patterns/PaperScissorsRock.java b/patterns/PaperScissorsRock.java index 963da941..f5c5e614 100644 --- a/patterns/PaperScissorsRock.java +++ b/patterns/PaperScissorsRock.java @@ -86,7 +86,8 @@ class ItemFactory { Arrays.asList( Scissors::new, Paper::new, Rock::new); static final int SZ = items.size(); - private static SplittableRandom rand = new SplittableRandom(47); + private static SplittableRandom rand = + new SplittableRandom(47); public static Item newItem() { return items.get(rand.nextInt(SZ)).get(); } diff --git a/patterns/ShapeFactory1.java b/patterns/ShapeFactory1.java index 55403315..2a410887 100644 --- a/patterns/ShapeFactory1.java +++ b/patterns/ShapeFactory1.java @@ -7,8 +7,8 @@ import java.util.*; import java.util.stream.*; import patterns.shapes.*; -class StaticFactory { - static Shape create(String type) { +public class ShapeFactory1 implements FactoryMethod { + public Shape create(String type) { switch(type) { case "Circle": return new Circle(); case "Square": return new Square(); @@ -17,16 +17,8 @@ class StaticFactory { throw new BadShapeCreation(type); } } -} - -public class ShapeFactory1 { public static void main(String[] args) { - Stream.of("Circle", "Square", "Triangle", - "Square", "Circle", "Circle", "Triangle") - .map(StaticFactory::create) - .peek(Shape::draw) - .peek(Shape::erase) - .count(); // Terminal operation + FactoryTest.test(new ShapeFactory1()); } } /* Output: diff --git a/patterns/ShapeFactory2.java b/patterns/ShapeFactory2.java index 6670c0d3..0253fc86 100644 --- a/patterns/ShapeFactory2.java +++ b/patterns/ShapeFactory2.java @@ -7,37 +7,32 @@ import java.lang.reflect.*; import java.util.stream.*; import patterns.shapes.*; -class DynamicFactory { - static Map factories = +public class ShapeFactory2 implements FactoryMethod { + Map factories = new HashMap<>(); static Constructor load(String id) { System.out.println("loading " + id); try { return Class.forName("patterns.shapes." + id) .getConstructor(); - } catch(Exception e) { + } catch(ClassNotFoundException | + NoSuchMethodException e) { throw new BadShapeCreation(id); } } - static Shape create(String id) { + public Shape create(String id) { try { return (Shape)factories - .computeIfAbsent(id, DynamicFactory::load) + .computeIfAbsent(id, ShapeFactory2::load) .newInstance(); - } catch(Exception e) { + } catch(InstantiationException | + IllegalAccessException | + InvocationTargetException e) { throw new BadShapeCreation(id); } } -} - -public class ShapeFactory2 { public static void main(String[] args) { - Stream.of("Circle", "Square", "Triangle", - "Square", "Circle", "Circle", "Triangle") - .map(DynamicFactory::create) - .peek(Shape::draw) - .peek(Shape::erase) - .count(); + FactoryTest.test(new ShapeFactory2()); } } /* Output: diff --git a/patterns/doubledispatch/TypedBinMember.java b/patterns/doubledispatch/TypedBinMember.java index 72b11b75..456d02c0 100644 --- a/patterns/doubledispatch/TypedBinMember.java +++ b/patterns/doubledispatch/TypedBinMember.java @@ -8,7 +8,7 @@ package patterns.doubledispatch; import java.util.*; -interface TypedBinMember { +public interface TypedBinMember { // The new method: boolean addToBin(List bins); } diff --git a/patterns/shapes/FactoryMethod.java b/patterns/shapes/FactoryMethod.java new file mode 100644 index 00000000..b03c8239 --- /dev/null +++ b/patterns/shapes/FactoryMethod.java @@ -0,0 +1,9 @@ +// patterns/shapes/FactoryMethod.java +// (c)2017 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +package patterns.shapes; + +public interface FactoryMethod { + Shape create(String type); +} diff --git a/patterns/shapes/FactoryTest.java b/patterns/shapes/FactoryTest.java new file mode 100644 index 00000000..2a9e671e --- /dev/null +++ b/patterns/shapes/FactoryTest.java @@ -0,0 +1,17 @@ +// patterns/shapes/FactoryTest.java +// (c)2017 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +package patterns.shapes; +import java.util.stream.*; + +public class FactoryTest { + public static void test(FactoryMethod factory) { + Stream.of("Circle", "Square", "Triangle", + "Square", "Circle", "Circle", "Triangle") + .map(factory::create) + .peek(Shape::draw) + .peek(Shape::erase) + .count(); // Terminal operation + } +} diff --git a/patterns/trash/Trash.java b/patterns/trash/Trash.java index 297144ee..e8d9d351 100644 --- a/patterns/trash/Trash.java +++ b/patterns/trash/Trash.java @@ -66,8 +66,8 @@ public abstract class Trash { try { // Get the dynamic constructor method // that takes a double argument: - Constructor ctor = trashType.getConstructor( - double.class); + Constructor ctor = + trashType.getConstructor(double.class); // Call the constructor to create a // new object: return (T)ctor.newInstance(info.data); diff --git a/patterns/trashvisitor/Visitable.java b/patterns/trashvisitor/Visitable.java index 040dec17..7d736b3e 100644 --- a/patterns/trashvisitor/Visitable.java +++ b/patterns/trashvisitor/Visitable.java @@ -6,7 +6,7 @@ // Trash hierarchy without modifying the base class package patterns.trashvisitor; -interface Visitable { +public interface Visitable { // The new method: void accept(Visitor v); } diff --git a/patterns/trashvisitor/Visitor.java b/patterns/trashvisitor/Visitor.java index f098440c..0a97e3a2 100644 --- a/patterns/trashvisitor/Visitor.java +++ b/patterns/trashvisitor/Visitor.java @@ -5,7 +5,7 @@ // The base interface for visitors package patterns.trashvisitor; -interface Visitor { +public interface Visitor { void visit(Aluminum a); void visit(Paper p); void visit(Glass g); diff --git a/patterns/visitor/BeeAndFlowers.java b/patterns/visitor/BeeAndFlowers.java index 6ba97f11..3f05cd5e 100644 --- a/patterns/visitor/BeeAndFlowers.java +++ b/patterns/visitor/BeeAndFlowers.java @@ -75,7 +75,8 @@ class FlowerFactory { Arrays.asList(Gladiolus::new, Renuculus::new, Chrysanthemum::new); static final int SZ = flowers.size(); - private static SplittableRandom rand = new SplittableRandom(47); + private static SplittableRandom rand = + new SplittableRandom(47); public static Flower newFlower() { return flowers.get(rand.nextInt(SZ)).get(); }