From d88c9042d8fb6b7fecad67ac0fd325ecacc08f73 Mon Sep 17 00:00:00 2001 From: "jim.deng" Date: Thu, 19 Nov 2020 14:48:57 +0800 Subject: [PATCH 01/12] 1 --- code/.gitattributes | 17 + code/.gitignore | 111 +++++ code/.travisXX.yml | 8 + code/CI.txt | 5 + code/Copyright.txt | 72 +++ code/README.md | 43 ++ code/annotations/AUComposition.java | 30 ++ code/annotations/AUExternalTest.java | 29 ++ code/annotations/AtUnitExample1.java | 48 ++ code/annotations/AtUnitExample2.java | 57 +++ code/annotations/AtUnitExample3.java | 42 ++ code/annotations/AtUnitExample4.java | 83 ++++ code/annotations/AtUnitExample5.java | 63 +++ code/annotations/DemoProcessFiles.java | 43 ++ code/annotations/HashSetTest.java | 36 ++ code/annotations/PasswordUtils.java | 24 + code/annotations/SimulatingNull.java | 12 + code/annotations/StackL.java | 14 + code/annotations/StackLStringTst.java | 42 ++ code/annotations/Testable.java | 14 + code/annotations/UseCase.java | 12 + code/annotations/UseCaseTracker.java | 37 ++ code/annotations/database/Constraints.java | 14 + code/annotations/database/DBTable.java | 12 + code/annotations/database/Member.java | 22 + code/annotations/database/SQLInteger.java | 13 + code/annotations/database/SQLString.java | 14 + code/annotations/database/TableCreator.java | 106 +++++ code/annotations/database/Uniqueness.java | 11 + code/annotations/ifx/ExtractInterface.java | 13 + .../ifx/IfaceExtractorProcessor.java | 91 ++++ code/annotations/ifx/Multiplier.java | 34 ++ code/annotations/simplest/Simple.java | 20 + .../annotations/simplest/SimpleProcessor.java | 47 ++ code/annotations/simplest/SimpleTest.java | 32 ++ code/appveyorXX.yml | 4 + code/arrays/AlphabeticSearch.java | 29 ++ code/arrays/ArrayCopying.java | 81 ++++ code/arrays/ArrayOfGenericType.java | 16 + code/arrays/ArrayOfGenerics.java | 33 ++ code/arrays/ArrayOptions.java | 79 ++++ code/arrays/ArraySearching.java | 33 ++ .../AssemblingMultidimensionalArrays.java | 22 + code/arrays/AutoboxingArrays.java | 22 + code/arrays/CollectionComparison.java | 53 +++ code/arrays/CompType.java | 56 +++ code/arrays/ComparatorTest.java | 39 ++ code/arrays/ComparingArrays.java | 62 +++ code/arrays/CountUpward.java | 24 + code/arrays/FillingArrays.java | 55 +++ code/arrays/IceCreamFlavors.java | 45 ++ code/arrays/ModifyExisting.java | 22 + code/arrays/MultiDimWrapperArray.java | 38 ++ code/arrays/MultidimensionalObjectArrays.java | 25 ++ .../MultidimensionalPrimitiveArray.java | 18 + code/arrays/ParallelPrefix1.java | 27 ++ code/arrays/ParallelPrefix2.java | 20 + code/arrays/ParallelPrefix3.java | 23 + code/arrays/ParallelSetAll.java | 24 + code/arrays/ParameterizedArrayType.java | 25 ++ code/arrays/PythonLists.py | 36 ++ code/arrays/RaggedArray.java | 26 ++ code/arrays/Reverse.java | 32 ++ code/arrays/SimpleSetAll.java | 56 +++ code/arrays/StreamFromArray.java | 51 +++ code/arrays/StringSorting.java | 39 ++ code/arrays/TestConvertTo.java | 87 ++++ code/arrays/TestCount.java | 167 +++++++ code/arrays/TestRand.java | 192 ++++++++ code/arrays/ThreeDWithNew.java | 17 + code/arrays/jmh/ParallelSort.java | 25 ++ code/build.gradle | 23 + code/checkstyle.xml | 179 ++++++++ code/chkstyle.bat | 2 + code/collections/AdapterMethodIdiom.java | 48 ++ code/collections/AddingGroups.java | 24 + .../ApplesAndOrangesWithGenerics.java | 23 + .../ApplesAndOrangesWithoutGenerics.java | 38 ++ code/collections/ArrayIsNotIterable.java | 23 + code/collections/AsListInference.java | 34 ++ code/collections/CollectionDifferences.java | 71 +++ code/collections/CollectionSequence.java | 40 ++ .../collections/CrossCollectionIteration.java | 36 ++ .../CrossCollectionIteration2.java | 37 ++ code/collections/EnvironmentVariables.java | 15 + code/collections/ForInCollections.java | 19 + code/collections/GenericsAndUpcasting.java | 28 ++ code/collections/InterfaceVsIterator.java | 55 +++ code/collections/IterableClass.java | 35 ++ code/collections/LinkedListFeatures.java | 54 +++ code/collections/ListFeatures.java | 93 ++++ code/collections/ListIteration.java | 37 ++ code/collections/MapOfList.java | 65 +++ code/collections/ModifyingArraysAsList.java | 32 ++ code/collections/MultiIterableClass.java | 53 +++ code/collections/NonCollectionSequence.java | 37 ++ code/collections/PetMap.java | 27 ++ code/collections/PrintingCollections.java | 44 ++ code/collections/PriorityQueueDemo.java | 53 +++ code/collections/QueueDemo.java | 29 ++ code/collections/SetOfInteger.java | 19 + code/collections/SetOfString.java | 25 ++ code/collections/SetOperations.java | 40 ++ code/collections/SimpleCollection.java | 18 + code/collections/SimpleIteration.java | 36 ++ code/collections/SortedSetOfString.java | 25 ++ code/collections/StackCollision.java | 25 ++ code/collections/StackTest.java | 18 + code/collections/StackTest2.java | 18 + code/collections/Statistics.java | 25 ++ code/collections/UniqueWords.java | 29 ++ code/collections/UniqueWordsAlphabetic.java | 30 ++ code/collectiontopics/AssociativeArray.java | 64 +++ code/collectiontopics/Bits.java | 79 ++++ code/collectiontopics/CanonicalMapping.java | 56 +++ code/collectiontopics/CollectionMethods.java | 135 ++++++ code/collectiontopics/Enumerations.java | 24 + code/collectiontopics/FailFast.java | 22 + code/collectiontopics/FillMapTest.java | 32 ++ code/collectiontopics/FillingLists.java | 35 ++ code/collectiontopics/FunctionalMap.java | 38 ++ code/collectiontopics/HTMLColorTest.java | 103 +++++ code/collectiontopics/LinkedHashMapDemo.java | 31 ++ code/collectiontopics/ListOps.java | 167 +++++++ code/collectiontopics/ListSortSearch.java | 57 +++ code/collectiontopics/MapOps.java | 76 ++++ code/collectiontopics/NavMap.java | 96 ++++ code/collectiontopics/QueueBehavior.java | 50 +++ code/collectiontopics/ReadOnly.java | 56 +++ code/collectiontopics/References.java | 92 ++++ code/collectiontopics/SetOrder.java | 92 ++++ code/collectiontopics/SimpleDeques.java | 70 +++ code/collectiontopics/SortedMapDemo.java | 42 ++ code/collectiontopics/SortedSetDemo.java | 42 ++ code/collectiontopics/Stacks.java | 61 +++ code/collectiontopics/StreamFillMaps.java | 55 +++ .../SuppliersCollectionTest.java | 67 +++ code/collectiontopics/Synchronization.java | 24 + code/collectiontopics/ToDoList.java | 56 +++ code/collectiontopics/TypesForSets.java | 93 ++++ code/collectiontopics/Unsupported.java | 60 +++ code/collectiontopics/Utilities.java | 88 ++++ code/com/mindviewinc/simple/List.java | 12 + code/com/mindviewinc/simple/Vector.java | 12 + code/compression/GZIPcompress.java | 45 ++ code/compression/ZipCompress.java | 83 ++++ code/concurrent/Baked.java | 31 ++ code/concurrent/Batter.java | 34 ++ code/concurrent/Breakable.java | 29 ++ code/concurrent/CachedThreadPool.java | 29 ++ code/concurrent/CachedThreadPool2.java | 29 ++ code/concurrent/CachedThreadPool3.java | 47 ++ .../CatchCompletableExceptions.java | 81 ++++ code/concurrent/CollectionIntoStream.java | 36 ++ code/concurrent/CompletableApply.java | 27 ++ code/concurrent/CompletableApplyAsync.java | 31 ++ code/concurrent/CompletableApplyChained.java | 27 ++ code/concurrent/CompletableExceptions.java | 75 ++++ code/concurrent/CompletableOperations.java | 74 ++++ code/concurrent/CompletablePizza.java | 87 ++++ code/concurrent/CompletableUtilities.java | 27 ++ code/concurrent/CompletedMachina.java | 19 + code/concurrent/CountingStream.java | 32 ++ code/concurrent/CountingTask.java | 19 + code/concurrent/DiningPhilosophers.java | 33 ++ .../concurrent/DualCompletableOperations.java | 115 +++++ code/concurrent/FrostedCake.java | 32 ++ code/concurrent/Futures.java | 23 + code/concurrent/GuardedIDField.java | 18 + code/concurrent/HasID.java | 8 + code/concurrent/IDChecker.java | 41 ++ code/concurrent/InterferingTask.java | 17 + .../LambdasAndMethodReferences.java | 40 ++ code/concurrent/Machina.java | 31 ++ code/concurrent/MoreTasksAfterShutdown.java | 27 ++ code/concurrent/NapTask.java | 20 + code/concurrent/OnePizza.java | 26 ++ code/concurrent/ParallelPrime.java | 35 ++ code/concurrent/ParallelStreamPuzzle.java | 28 ++ code/concurrent/ParallelStreamPuzzle2.java | 38 ++ code/concurrent/ParallelStreamPuzzle3.java | 33 ++ code/concurrent/Philosopher.java | 30 ++ code/concurrent/Pizza.java | 49 +++ code/concurrent/PizzaParallelSteps.java | 69 +++ code/concurrent/PizzaStreams.java | 60 +++ code/concurrent/QuittableTask.java | 20 + code/concurrent/QuittingCompletable.java | 35 ++ code/concurrent/QuittingTasks.java | 35 ++ .../concurrent/SharedConstructorArgument.java | 44 ++ code/concurrent/SingleThreadExecutor.java | 49 +++ code/concurrent/SingleThreadExecutor2.java | 30 ++ code/concurrent/SingleThreadExecutor3.java | 30 ++ code/concurrent/StaticIDField.java | 10 + code/concurrent/StickHolder.java | 27 ++ code/concurrent/StreamExceptions.java | 40 ++ code/concurrent/Summing.java | 47 ++ code/concurrent/Summing2.java | 44 ++ code/concurrent/Summing3.java | 42 ++ code/concurrent/Summing4.java | 23 + code/concurrent/SynchronizedConstructor.java | 29 ++ code/concurrent/SynchronizedFactory.java | 29 ++ code/concurrent/TestStaticIDField.java | 13 + code/concurrent/ThrowsChecked.java | 42 ++ code/concurrent/Workable.java | 32 ++ code/control/BreakAndContinue.java | 38 ++ code/control/CommaOperator.java | 18 + code/control/ForInFloat.java | 28 ++ code/control/ForInInt.java | 28 ++ code/control/ForInString.java | 14 + code/control/IfElse.java | 29 ++ code/control/LabeledFor.java | 65 +++ code/control/LabeledWhile.java | 51 +++ code/control/ListCharacters.java | 27 ++ code/control/RandomBounds.java | 30 ++ code/control/StringSwitch.java | 44 ++ code/control/TestWithReturn.java | 24 + code/control/TrueFalse.java | 15 + code/control/VowelsAndConsonants.java | 44 ++ code/control/WhileTest.java | 31 ++ code/enums/AlarmPoints.java | 9 + code/enums/BigEnumSet.java | 29 ++ code/enums/Burrito2.java | 28 ++ code/enums/CarWash.java | 88 ++++ code/enums/Competitor.java | 10 + code/enums/ConstantSpecificMethod.java | 41 ++ code/enums/EnumClass.java | 51 +++ code/enums/EnumMaps.java | 37 ++ code/enums/EnumSets.java | 39 ++ code/enums/Input.java | 33 ++ code/enums/NonEnum.java | 19 + code/enums/NotClasses.java | 50 +++ code/enums/Outcome.java | 6 + code/enums/OverrideConstantSpecific.java | 28 ++ code/enums/OzWitch.java | 32 ++ code/enums/PostOffice.java | 197 +++++++++ code/enums/RandomTest.java | 21 + code/enums/Reflection.java | 71 +++ code/enums/RoShamBo.java | 21 + code/enums/RoShamBo1.java | 104 +++++ code/enums/RoShamBo2.java | 55 +++ code/enums/RoShamBo3.java | 71 +++ code/enums/RoShamBo4.java | 57 +++ code/enums/RoShamBo5.java | 59 +++ code/enums/RoShamBo6.java | 46 ++ code/enums/SecurityCategory.java | 46 ++ code/enums/SpaceShip.java | 28 ++ code/enums/SpicinessEnum.java | 9 + code/enums/TrafficLight.java | 44 ++ code/enums/UpcastEnum.java | 21 + code/enums/VendingMachine.java | 183 ++++++++ code/enums/VendingMachineInput.txt | 8 + code/enums/cartoons/EnumImplementation.java | 37 ++ code/enums/menu/Course.java | 20 + code/enums/menu/Food.java | 24 + code/enums/menu/Meal.java | 45 ++ code/enums/menu/Meal2.java | 74 ++++ code/enums/menu/TypeOfFood.java | 16 + code/equalshashcode/ComposedEquality.java | 66 +++ code/equalshashcode/CountedString.java | 72 +++ code/equalshashcode/DefaultComparison.java | 24 + code/equalshashcode/Equality.java | 77 ++++ code/equalshashcode/EqualityFactory.java | 9 + code/equalshashcode/Groundhog.java | 14 + code/equalshashcode/Groundhog2.java | 19 + code/equalshashcode/IndividualTest.java | 31 ++ code/equalshashcode/MapEntry.java | 42 ++ code/equalshashcode/Prediction.java | 15 + code/equalshashcode/SimpleHashMap.java | 90 ++++ code/equalshashcode/SlowMap.java | 64 +++ code/equalshashcode/SpringDetector.java | 62 +++ code/equalshashcode/SpringDetector2.java | 25 ++ code/equalshashcode/StringHashCode.java | 16 + code/equalshashcode/SubtypeEquality.java | 60 +++ code/equalshashcode/SubtypeEquality2.java | 40 ++ code/equalshashcode/SuccinctEquality.java | 46 ++ code/exceptions/AlwaysFinally.java | 33 ++ code/exceptions/AutoCloseableDetails.java | 33 ++ code/exceptions/BodyException.java | 32 ++ code/exceptions/Cleanup.java | 30 ++ code/exceptions/CleanupIdiom.java | 72 +++ code/exceptions/CloseExceptions.java | 48 ++ code/exceptions/ConstructorException.java | 33 ++ code/exceptions/DynamicFields.java | 130 ++++++ code/exceptions/ExceptionMethods.java | 32 ++ code/exceptions/ExceptionSilencer.java | 16 + code/exceptions/ExtraFeatures.java | 72 +++ code/exceptions/FinallyWorks.java | 32 ++ code/exceptions/FullConstructors.java | 44 ++ code/exceptions/Human.java | 31 ++ code/exceptions/InheritingExceptions.java | 28 ++ code/exceptions/InputFile.java | 47 ++ code/exceptions/InputFile2.java | 28 ++ code/exceptions/LoggingExceptions.java | 48 ++ code/exceptions/LoggingExceptions2.java | 32 ++ code/exceptions/LostMessage.java | 44 ++ code/exceptions/MainException.java | 17 + code/exceptions/MessyExceptions.java | 27 ++ code/exceptions/MultiCatch.java | 16 + code/exceptions/MultiCatch2.java | 19 + code/exceptions/MultipleReturns.java | 47 ++ code/exceptions/NeverCaught.java | 26 ++ code/exceptions/OnOffException1.java | 5 + code/exceptions/OnOffException2.java | 5 + code/exceptions/OnOffSwitch.java | 29 ++ code/exceptions/PreciseRethrow.java | 17 + code/exceptions/RethrowNew.java | 47 ++ code/exceptions/Rethrowing.java | 70 +++ code/exceptions/SameHandler.java | 31 ++ code/exceptions/StormyInning.java | 83 ++++ code/exceptions/StreamsAreAutoCloseable.java | 24 + code/exceptions/Switch.java | 21 + code/exceptions/TryAnything.java | 16 + code/exceptions/TryWithResources.java | 19 + code/exceptions/TurnOffChecking.java | 64 +++ code/exceptions/WhoCalled.java | 39 ++ code/exceptions/WithFinally.java | 26 ++ code/files/AddAndSubtractPaths.java | 87 ++++ code/files/Directories.java | 94 ++++ code/files/FileSystemDemo.java | 41 ++ code/files/Find.java | 60 +++ code/files/ListOfLines.java | 26 ++ code/files/PartsOfPaths.java | 45 ++ code/files/PathAnalysis.java | 56 +++ code/files/PathInfo.java | 102 +++++ code/files/PathWatcher.java | 61 +++ code/files/ReadLineStream.java | 18 + code/files/StreamInAndOut.java | 24 + code/files/TreeWatcher.java | 51 +++ code/files/Writing.java | 31 ++ code/functional/AnonymousClosure.java | 17 + code/functional/BiConsumerPermutations.java | 24 + code/functional/ClassFunctionals.java | 45 ++ code/functional/Closure1.java | 12 + code/functional/Closure2.java | 12 + code/functional/Closure3.java | 14 + code/functional/Closure4.java | 12 + code/functional/Closure5.java | 15 + code/functional/Closure6.java | 16 + code/functional/Closure7.java | 14 + code/functional/Closure8.java | 32 ++ code/functional/Closure9.java | 15 + code/functional/ConsumeFunction.java | 17 + code/functional/CtorReference.java | 36 ++ code/functional/CurriedIntAdd.java | 17 + code/functional/Curry3Args.java | 23 + code/functional/CurryingAndPartials.java | 35 ++ code/functional/FunctionComposition.java | 24 + code/functional/FunctionVariants.java | 65 +++ code/functional/FunctionWithWrapped.java | 12 + code/functional/FunctionalAnnotation.java | 40 ++ code/functional/IntCall.java | 8 + code/functional/LambdaExpressions.java | 48 ++ code/functional/MethodConversion.java | 31 ++ code/functional/MethodReferences.java | 53 +++ code/functional/MultiUnbound.java | 36 ++ code/functional/PredicateComposition.java | 23 + code/functional/ProduceFunction.java | 21 + code/functional/RecursiveFactorial.java | 26 ++ code/functional/RecursiveFibonacci.java | 32 ++ code/functional/RunnableMethodReference.java | 33 ++ code/functional/SharedStorage.java | 22 + code/functional/Strategize.java | 58 +++ code/functional/TransformFunction.java | 35 ++ code/functional/TriFunction.java | 9 + code/functional/TriFunctionTest.java | 13 + code/functional/UnboundMethodReference.java | 31 ++ code/generics/Amphibian.java | 5 + code/generics/Apply.java | 21 + code/generics/ApplyFunctional.java | 49 +++ code/generics/ApplyTest.java | 65 +++ code/generics/ArrayMaker.java | 24 + code/generics/ArrayOfGeneric.java | 28 ++ code/generics/ArrayOfGenericReference.java | 10 + code/generics/BankTeller.java | 71 +++ code/generics/BasicBounds.java | 63 +++ code/generics/BasicHolder.java | 14 + code/generics/BasicSupplierDemo.java | 22 + code/generics/ByteSet.java | 14 + code/generics/CRGWithBasicHolder.java | 20 + code/generics/CaptureConversion.java | 62 +++ code/generics/CheckedList.java | 35 ++ code/generics/ClassCasting.java | 18 + code/generics/ClassTypeCapture.java | 33 ++ code/generics/ComparablePet.java | 12 + code/generics/CompilerIntelligence.java | 15 + code/generics/CountedObject.java | 14 + code/generics/CovariantArrays.java | 30 ++ code/generics/CovariantReturnTypes.java | 23 + code/generics/CreatorGeneric.java | 31 ++ code/generics/CuriouslyRecurringGeneric.java | 9 + code/generics/Diamond.java | 13 + .../DogsAndRobotMethodReferences.java | 45 ++ code/generics/DogsAndRobots.cpp | 38 ++ code/generics/DogsAndRobots.java | 41 ++ code/generics/DogsAndRobots.py | 36 ++ code/generics/DynamicProxyMixin.java | 66 +++ code/generics/EpicBattle.java | 74 ++++ code/generics/Erased.java | 24 + code/generics/ErasedTypeEquivalence.java | 16 + code/generics/ErasureAndInheritance.java | 28 ++ code/generics/FactoryConstraint.java | 62 +++ code/generics/Fibonacci.java | 27 ++ code/generics/FilledList.java | 28 ++ code/generics/GenericArray.java | 32 ++ code/generics/GenericArray2.java | 39 ++ code/generics/GenericArrayWithTypeToken.java | 27 ++ code/generics/GenericCast.java | 47 ++ code/generics/GenericHolder.java | 19 + code/generics/GenericHolder2.java | 16 + code/generics/GenericMethods.java | 27 ++ code/generics/GenericReading.java | 46 ++ code/generics/GenericVarargs.java | 30 ++ code/generics/GenericsAndCovariance.java | 19 + code/generics/GenericsAndReturnTypes.java | 17 + code/generics/HasF.java | 10 + code/generics/HijackedInterface.java | 16 + code/generics/Holder.java | 42 ++ code/generics/Holder1.java | 12 + code/generics/InheritBounds.java | 40 ++ code/generics/InstantiateGenericType.cpp | 20 + code/generics/InstantiateGenericType.java | 46 ++ code/generics/IterableFibonacci.java | 36 ++ code/generics/LatentReflection.java | 65 +++ code/generics/LinkedStack.java | 43 ++ code/generics/ListMaker.java | 13 + code/generics/ListOfGenerics.java | 11 + code/generics/ListOfInt.java | 20 + code/generics/LostInformation.java | 33 ++ code/generics/Manipulation.java | 21 + code/generics/Manipulator2.java | 10 + code/generics/Manipulator3.java | 10 + code/generics/Mixins.cpp | 47 ++ code/generics/Mixins.java | 71 +++ code/generics/MultipleInterfaceVariants.java | 13 + code/generics/NeedCasting.java | 15 + code/generics/NonCovariantGenerics.java | 11 + code/generics/NotSelfBounded.java | 24 + code/generics/ObjectHolder.java | 20 + code/generics/OrdinaryArguments.java | 31 ++ code/generics/Performs.java | 9 + code/generics/PlainGenericInheritance.java | 30 ++ code/generics/PrimitiveGenericTest.java | 42 ++ code/generics/RandomList.java | 26 ++ code/generics/RestrictedComparablePets.java | 19 + code/generics/ReturnGenericType.java | 10 + code/generics/SelfBounding.java | 40 ++ .../SelfBoundingAndCovariantArguments.java | 31 ++ code/generics/SelfBoundingMethods.java | 13 + code/generics/Shape.java | 19 + code/generics/SimpleDogsAndRobots.java | 25 ++ code/generics/SimpleHolder.java | 15 + code/generics/SimpleQueue.java | 16 + code/generics/Square.java | 5 + code/generics/Store.java | 90 ++++ code/generics/SuperTypeWildcards.java | 13 + code/generics/Templates.cpp | 27 ++ code/generics/ThrowGenericException.java | 82 ++++ code/generics/TupleList.java | 23 + code/generics/TupleTest.java | 42 ++ code/generics/TupleTest2.java | 42 ++ code/generics/UnboundedWildcards1.java | 58 +++ code/generics/UnboundedWildcards2.java | 35 ++ code/generics/Unconstrained.java | 20 + code/generics/UseList.java | 11 + code/generics/UseList2.java | 10 + code/generics/Vehicle.java | 5 + code/generics/WatercolorSets.java | 54 +++ code/generics/Wildcards.java | 285 ++++++++++++ code/generics/coffee/Americano.java | 6 + code/generics/coffee/Breve.java | 6 + code/generics/coffee/Cappuccino.java | 6 + code/generics/coffee/Coffee.java | 14 + code/generics/coffee/CoffeeSupplier.java | 72 +++ code/generics/coffee/Latte.java | 6 + code/generics/coffee/Mocha.java | 6 + code/generics/decorator/Decoration.java | 51 +++ code/generics/dogsandrobots.go | 32 ++ code/generics/watercolors/Watercolors.java | 15 + code/gradle.properties | 1 + code/gradle/checkstyle.gradle | 14 + code/gradle/findbugs.gradle | 15 + code/gradle/java.gradle | 39 ++ code/gradle/jmh.gradle | 17 + code/gradle/junit-jupiter.gradle | 72 +++ code/gradle/subprojects.gradle | 67 +++ code/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes code/gradle/wrapper/gradle-wrapper.properties | 5 + code/gradlew | 185 ++++++++ code/gradlew.bat | 89 ++++ code/hiding/Cake.java | 15 + code/hiding/ChocolateChip.java | 23 + code/hiding/ChocolateChip2.java | 21 + code/hiding/CreatePackageAccessObject.java | 12 + code/hiding/Dinner.java | 16 + code/hiding/FullQualification.java | 11 + code/hiding/IceCream.java | 19 + code/hiding/ImportedMyClass.java | 11 + code/hiding/LibTest.java | 17 + code/hiding/Lunch.java | 36 ++ code/hiding/OrganizedByAccess.java | 15 + code/hiding/Pie.java | 9 + code/hiding/QualifiedMyClass.java | 11 + code/hiding/SingleImport.java | 11 + code/hiding/cookie2/Cookie.java | 14 + code/hiding/dessert/Cookie.java | 13 + code/hiding/mypackage/MyClass.java | 9 + .../packageaccess/PublicConstructor.java | 9 + code/housekeeping/Apricot.java | 8 + code/housekeeping/ArrayClassObj.java | 22 + code/housekeeping/ArrayInit.java | 25 ++ code/housekeeping/ArrayNew.java | 20 + code/housekeeping/ArraysOfPrimitives.java | 23 + code/housekeeping/AutoboxingVarargs.java | 22 + code/housekeeping/BananaPeel.java | 15 + code/housekeeping/Burrito.java | 39 ++ code/housekeeping/Counter.java | 9 + code/housekeeping/DefaultConstructor.java | 12 + code/housekeeping/Demotion.java | 43 ++ code/housekeeping/DynamicArray.java | 21 + code/housekeeping/EnumOrder.java | 19 + code/housekeeping/ExplicitStatic.java | 41 ++ code/housekeeping/Flower.java | 46 ++ code/housekeeping/InitialValues.java | 44 ++ code/housekeeping/InitialValues2.java | 16 + code/housekeeping/Leaf.java | 23 + code/housekeeping/Measurement.java | 10 + code/housekeeping/MethodInit.java | 8 + code/housekeeping/MethodInit2.java | 10 + code/housekeeping/MethodInit3.java | 10 + code/housekeeping/Mugs.java | 47 ++ code/housekeeping/NewVarArgs.java | 30 ++ code/housekeeping/NoSynthesis.java | 17 + .../OptionalTrailingArguments.java | 23 + code/housekeeping/OrderOfInitialization.java | 40 ++ code/housekeeping/Overloading.java | 56 +++ code/housekeeping/OverloadingOrder.java | 22 + code/housekeeping/OverloadingVarargs.java | 37 ++ code/housekeeping/OverloadingVarargs2.java | 18 + code/housekeeping/OverloadingVarargs3.java | 21 + code/housekeeping/PassingThis.java | 31 ++ code/housekeeping/PrimitiveOverloading.java | 120 +++++ code/housekeeping/SimpleConstructor.java | 21 + code/housekeeping/SimpleConstructor2.java | 21 + code/housekeeping/SimpleEnumUse.java | 14 + code/housekeeping/Spiciness.java | 8 + code/housekeeping/Spoon.java | 10 + code/housekeeping/StaticInitialization.java | 73 ++++ code/housekeeping/TerminationCondition.java | 41 ++ code/housekeeping/VarArgs.java | 26 ++ code/housekeeping/VarargType.java | 30 ++ code/innerclasses/AnonymousConstructor.java | 34 ++ code/innerclasses/BigEgg.java | 33 ++ code/innerclasses/BigEgg2.java | 44 ++ code/innerclasses/Callbacks.java | 84 ++++ code/innerclasses/ClassInInterface.java | 21 + code/innerclasses/Contents.java | 7 + code/innerclasses/Destination.java | 7 + code/innerclasses/DotNew.java | 13 + code/innerclasses/DotThis.java | 24 + code/innerclasses/GreenhouseController.java | 54 +++ code/innerclasses/GreenhouseControls.java | 150 +++++++ code/innerclasses/InheritInner.java | 20 + code/innerclasses/LocalInnerClass.java | 67 +++ code/innerclasses/MultiImplementation.java | 25 ++ code/innerclasses/MultiNestingAccess.java | 28 ++ code/innerclasses/Parcel1.java | 33 ++ code/innerclasses/Parcel10.java | 31 ++ code/innerclasses/Parcel11.java | 40 ++ code/innerclasses/Parcel2.java | 41 ++ code/innerclasses/Parcel3.java | 25 ++ code/innerclasses/Parcel5.java | 23 + code/innerclasses/Parcel6.java | 28 ++ code/innerclasses/Parcel7.java | 19 + code/innerclasses/Parcel7b.java | 20 + code/innerclasses/Parcel8.java | 21 + code/innerclasses/Parcel9.java | 20 + code/innerclasses/Sequence.java | 48 ++ code/innerclasses/TestBed.java | 19 + code/innerclasses/TestParcel.java | 37 ++ code/innerclasses/Wrapping.java | 9 + code/innerclasses/controller/Controller.java | 24 + code/innerclasses/controller/Event.java | 23 + code/innerclasses/mui/MultiInterfaces.java | 32 ++ code/interfaces/AbstractAccess.java | 15 + code/interfaces/AbstractWithoutAbstracts.java | 14 + code/interfaces/AdaptedRandomDoubles.java | 35 ++ code/interfaces/Adventure.java | 41 ++ code/interfaces/AnImplementation.java | 22 + code/interfaces/AnInterface.java | 9 + code/interfaces/Applicator.java | 58 +++ code/interfaces/AttemptToUseBasic.java | 10 + code/interfaces/Basic.java | 8 + code/interfaces/Basic2.java | 10 + code/interfaces/Factories.java | 67 +++ code/interfaces/Games.java | 59 +++ code/interfaces/HorrorShow.java | 57 +++ code/interfaces/Implementation2.java | 26 ++ code/interfaces/ImplementingAnInterface.java | 14 + code/interfaces/Instantiable.java | 19 + code/interfaces/InterfaceCollision.java | 31 ++ code/interfaces/InterfaceWithDefault.java | 12 + code/interfaces/Jim.java | 28 ++ code/interfaces/MICollision.java | 60 +++ code/interfaces/Machine.java | 36 ++ code/interfaces/Months.java | 13 + code/interfaces/MultipleInheritance.java | 35 ++ code/interfaces/PureInterface.java | 11 + code/interfaces/RandVals.java | 15 + code/interfaces/RandomDoubles.java | 21 + code/interfaces/RandomStrings.java | 50 +++ code/interfaces/TestRandVals.java | 19 + code/interfaces/filters/BandPass.java | 17 + code/interfaces/filters/Filter.java | 14 + code/interfaces/filters/HighPass.java | 16 + code/interfaces/filters/LowPass.java | 16 + code/interfaces/filters/Waveform.java | 14 + .../interfaceprocessor/Applicator.java | 12 + .../interfaceprocessor/FilterProcessor.java | 40 ++ .../interfaceprocessor/Processor.java | 12 + .../interfaceprocessor/StringProcessor.java | 50 +++ code/interfaces/music4/Music4.java | 105 +++++ code/interfaces/music5/Music5.java | 74 ++++ .../interfaces/nesting/NestingInterfaces.java | 105 +++++ code/iostreams/BasicFileOutput.java | 26 ++ code/iostreams/BufferedInputFile.java | 23 + code/iostreams/FileOutputShortcut.java | 24 + code/iostreams/FormattedMemoryInput.java | 25 ++ code/iostreams/MemoryInput.java | 17 + code/iostreams/StoringAndRecoveringData.java | 42 ++ code/iostreams/TestEOF.java | 22 + code/iostreams/UsingRandomAccessFile.java | 65 +++ code/javadoc/Documentation1.java | 11 + code/javadoc/Documentation2.java | 9 + code/javadoc/Documentation3.java | 12 + code/javadoc/HelloDateDoc.java | 26 ++ code/lowlevel/AtomicEvenProducer.java | 21 + code/lowlevel/AtomicIntegerTest.java | 20 + code/lowlevel/AtomicSerialNumbers.java | 21 + code/lowlevel/Atomicity.java | 20 + code/lowlevel/AttemptLocking.java | 57 +++ code/lowlevel/CaptureUncaughtException.java | 56 +++ code/lowlevel/CircularSet.java | 29 ++ code/lowlevel/DelayQueueDemo.java | 99 +++++ code/lowlevel/EvenChecker.java | 41 ++ code/lowlevel/EvenProducer.java | 26 ++ code/lowlevel/ExceptionThread.java | 30 ++ code/lowlevel/IntGenerator.java | 15 + code/lowlevel/IntTestable.java | 15 + code/lowlevel/MutexEvenProducer.java | 30 ++ code/lowlevel/NaiveExceptionHandling.java | 32 ++ code/lowlevel/NotAtomic.java | 49 +++ code/lowlevel/NumberOfProcessors.java | 14 + code/lowlevel/PriorityBlockingQueueDemo.java | 139 ++++++ code/lowlevel/ReOrdering.java | 19 + code/lowlevel/SafeReturn.java | 20 + code/lowlevel/SerialNumberChecker.java | 32 ++ code/lowlevel/SerialNumberTest.java | 13 + code/lowlevel/SerialNumbers.java | 11 + code/lowlevel/SettingDefaultHandler.java | 19 + code/lowlevel/SwallowedException.java | 17 + code/lowlevel/SyncOnObject.java | 70 +++ code/lowlevel/SynchronizedComparison.java | 89 ++++ code/lowlevel/SynchronizedEvenProducer.java | 24 + code/lowlevel/SynchronizedSerialNumbers.java | 19 + code/lowlevel/TestAbort.java | 17 + code/lowlevel/ThreadSize.java | 31 ++ code/lowlevel/UnsafeReturn.java | 20 + code/lowlevel/WorkStealingPool.java | 41 ++ code/newio/AvailableCharSets.java | 43 ++ code/newio/BufferToText.java | 93 ++++ code/newio/ChannelCopy.java | 35 ++ code/newio/Endians.java | 28 ++ code/newio/FileLocking.java | 30 ++ code/newio/GetChannel.java | 53 +++ code/newio/GetData.java | 56 +++ code/newio/IntBufferDemo.java | 35 ++ code/newio/LargeMappedFiles.java | 31 ++ code/newio/LockingMappedFiles.java | 60 +++ code/newio/MappedIO.java | 145 ++++++ code/newio/TransferTo.java | 30 ++ code/newio/UsingBuffers.java | 35 ++ code/newio/ViewBuffers.java | 69 +++ code/objects/HelloDate.java | 12 + code/objects/ShowProperties.java | 39 ++ code/onjava/ArrayShow.java | 73 ++++ code/onjava/BasicSupplier.java | 31 ++ code/onjava/CollectionMethodDifferences.java | 117 +++++ code/onjava/ConvertTo.java | 105 +++++ code/onjava/Count.java | 220 ++++++++++ code/onjava/CountMap.java | 97 +++++ code/onjava/CountingIntegerList.java | 34 ++ code/onjava/Countries.java | 351 +++++++++++++++ code/onjava/Enums.java | 17 + code/onjava/FillMap.java | 38 ++ code/onjava/HTMLColors.java | 236 ++++++++++ code/onjava/MouseClick.java | 19 + code/onjava/Nap.java | 20 + code/onjava/Null.java | 6 + code/onjava/OSExecute.java | 37 ++ code/onjava/OSExecuteException.java | 12 + code/onjava/Operations.java | 17 + code/onjava/Pair.java | 19 + code/onjava/ProcessFiles.java | 48 ++ code/onjava/Rand.java | 248 +++++++++++ code/onjava/Range.java | 34 ++ code/onjava/Repeat.java | 12 + code/onjava/RmDir.java | 31 ++ code/onjava/Sets.java | 32 ++ code/onjava/Stack.java | 20 + code/onjava/Suppliers.java | 36 ++ code/onjava/TimedAbort.java | 30 ++ code/onjava/Timer.java | 19 + code/onjava/Tuple.java | 24 + code/onjava/Tuple2.java | 16 + code/onjava/Tuple3.java | 17 + code/onjava/Tuple4.java | 18 + code/onjava/Tuple5.java | 18 + code/onjava/TypeCounter.java | 41 ++ code/onjava/atunit/AtUnit.java | 177 ++++++++ code/onjava/atunit/ClassNameFinder.java | 180 ++++++++ code/onjava/atunit/Test.java | 11 + code/onjava/atunit/TestObjectCleanup.java | 11 + code/onjava/atunit/TestObjectCreate.java | 11 + code/onjava/atunit/TestProperty.java | 12 + code/operators/AllOps.java | 411 ++++++++++++++++++ code/operators/Assignment.java | 31 ++ code/operators/AutoInc.java | 27 ++ code/operators/BitManipulation.java | 98 +++++ code/operators/Bool.java | 42 ++ code/operators/Casting.java | 16 + code/operators/CastingNumbers.java | 23 + code/operators/EqualsMethod.java | 15 + code/operators/EqualsMethod2.java | 21 + code/operators/Equivalence.java | 17 + code/operators/Exponents.java | 21 + code/operators/Literals.java | 61 +++ code/operators/MathOps.java | 75 ++++ code/operators/Overflow.java | 18 + code/operators/PassObject.java | 27 ++ code/operators/Precedence.java | 18 + code/operators/RoundingNumbers.java | 26 ++ code/operators/ShortCircuit.java | 34 ++ code/operators/StringOperators.java | 24 + code/operators/TernaryIfElse.java | 28 ++ code/operators/URShift.java | 42 ++ code/operators/Underscores.java | 22 + code/patterns/BoxObserver.java | 94 ++++ code/patterns/CommandPattern.java | 19 + code/patterns/Facade.java | 24 + code/patterns/PaperScissorsRock.java | 135 ++++++ code/patterns/ProxyDemo.java | 51 +++ code/patterns/ShapeFactory1.java | 39 ++ code/patterns/ShapeFactory2.java | 54 +++ code/patterns/ShapeFactory3.java | 52 +++ code/patterns/SingletonPattern.java | 58 +++ code/patterns/StateDemo.java | 87 ++++ code/patterns/TemplateMethod.java | 44 ++ .../abstractfactory/GameEnvironment.java | 96 ++++ code/patterns/adapt/Adapter.java | 85 ++++ .../patterns/chain/ChainOfResponsibility.java | 90 ++++ code/patterns/doubledispatch/Aluminum.java | 18 + code/patterns/doubledispatch/Cardboard.java | 18 + .../doubledispatch/DoubleDispatch.java | 96 ++++ code/patterns/doubledispatch/Glass.java | 18 + code/patterns/doubledispatch/Paper.java | 18 + code/patterns/doubledispatch/TypedBin.java | 28 ++ .../doubledispatch/TypedBinMember.java | 14 + code/patterns/dynatrash/DynaTrash.java | 74 ++++ code/patterns/observer/ObservedFlower.java | 125 ++++++ code/patterns/recyclea/RecycleA.java | 127 ++++++ code/patterns/recycleb/RecycleB.java | 56 +++ code/patterns/recyclec/RecycleC.java | 84 ++++ code/patterns/shapes/BadShapeCreation.java | 12 + code/patterns/shapes/Circle.java | 7 + code/patterns/shapes/FactoryMethod.java | 9 + code/patterns/shapes/FactoryTest.java | 17 + code/patterns/shapes/Shape.java | 21 + code/patterns/shapes/Square.java | 7 + code/patterns/shapes/Triangle.java | 7 + code/patterns/state/StateMachineDemo.java | 80 ++++ code/patterns/strategy/StrategyPattern.java | 64 +++ code/patterns/strategy/StrategyPattern2.java | 43 ++ code/patterns/trash/Aluminum.java | 15 + code/patterns/trash/Cardboard.java | 15 + code/patterns/trash/Fillable.java | 10 + code/patterns/trash/FillableList.java | 17 + code/patterns/trash/Glass.java | 15 + code/patterns/trash/Paper.java | 15 + code/patterns/trash/ParseTrash.java | 91 ++++ code/patterns/trash/Trash.dat | 35 ++ code/patterns/trash/Trash.java | 92 ++++ code/patterns/trashvisitor/Aluminum.java | 16 + code/patterns/trashvisitor/Cardboard.java | 16 + code/patterns/trashvisitor/Glass.java | 16 + code/patterns/trashvisitor/Paper.java | 16 + code/patterns/trashvisitor/TrashVisitor.java | 127 ++++++ code/patterns/trashvisitor/Visitable.java | 12 + code/patterns/trashvisitor/Visitor.java | 14 + code/patterns/visitor/BeeAndFlowers.java | 122 ++++++ code/polymorphism/CovariantReturn.java | 38 ++ code/polymorphism/FieldAccess.java | 36 ++ code/polymorphism/Frog.java | 122 ++++++ code/polymorphism/PolyConstructors.java | 41 ++ code/polymorphism/PrivateOverride.java | 24 + code/polymorphism/PrivateOverride2.java | 22 + code/polymorphism/RTTI.java | 43 ++ code/polymorphism/ReferenceCounting.java | 71 +++ code/polymorphism/Sandwich.java | 54 +++ code/polymorphism/Shapes.java | 26 ++ code/polymorphism/StaticPolymorphism.java | 36 ++ code/polymorphism/Transmogrify.java | 43 ++ code/polymorphism/music/Instrument.java | 11 + code/polymorphism/music/Music.java | 21 + code/polymorphism/music/Music2.java | 46 ++ code/polymorphism/music/Note.java | 10 + code/polymorphism/music/Wind.java | 15 + code/polymorphism/music3/Music3.java | 108 +++++ code/polymorphism/shape/Circle.java | 16 + code/polymorphism/shape/RandomShapes.java | 26 ++ code/polymorphism/shape/Shape.java | 10 + code/polymorphism/shape/Square.java | 16 + code/polymorphism/shape/Triangle.java | 16 + code/references/AddingClone.java | 67 +++ code/references/Alias1.java | 27 ++ code/references/Alias2.java | 25 ++ code/references/CheckCloneable.java | 113 +++++ code/references/CloneArrayList.java | 38 ++ code/references/Compete.java | 89 ++++ code/references/CopyConstructor.java | 188 ++++++++ code/references/DepthReading.java | 29 ++ code/references/HorrorFlick.java | 35 ++ code/references/Immutable1.java | 34 ++ code/references/Immutable2.java | 71 +++ code/references/ImmutableInteger.java | 22 + code/references/ImmutableStrings.java | 25 ++ code/references/LocalCopy.java | 57 +++ code/references/MutableInteger.java | 34 ++ code/references/OceanReading.java | 48 ++ code/references/PassReferences.java | 19 + code/references/SimplerMutableInteger.java | 30 ++ code/references/Snake.java | 51 +++ code/references/Stringer.java | 22 + code/references/TemperatureReading.java | 33 ++ code/references/tests/DeepCopyTest.java | 28 ++ code/reuse/Bath.java | 61 +++ code/reuse/Beetle.java | 43 ++ code/reuse/BlankFinal.java | 29 ++ code/reuse/CADSystem.java | 116 +++++ code/reuse/Car.java | 43 ++ code/reuse/Cartoon.java | 31 ++ code/reuse/Chess.java | 33 ++ code/reuse/DerivedSpaceShip.java | 19 + code/reuse/Detergent.java | 48 ++ code/reuse/FinalArguments.java | 27 ++ code/reuse/FinalData.java | 57 +++ code/reuse/FinalOverridingIllusion.java | 56 +++ code/reuse/Hide.java | 41 ++ code/reuse/Jurassic.java | 26 ++ code/reuse/Lisa.java | 11 + code/reuse/Orc.java | 41 ++ code/reuse/PlaceSetting.java | 82 ++++ code/reuse/SpaceShipControls.java | 14 + code/reuse/SpaceShipDelegation.java | 40 ++ code/reuse/SprinklerSystem.java | 41 ++ code/reuse/Wind.java | 22 + code/serialization/APerson.java | 83 ++++ code/serialization/AStoreCADState.java | 120 +++++ code/serialization/Alien.java | 7 + code/serialization/Blip3.java | 75 ++++ code/serialization/Blips.java | 80 ++++ code/serialization/FreezeAlien.java | 19 + code/serialization/Logon.java | 62 +++ code/serialization/MyWorld.java | 100 +++++ code/serialization/People.java | 28 ++ code/serialization/RecoverCADState.java | 42 ++ code/serialization/SerialCtl.java | 60 +++ code/serialization/Worm.java | 102 +++++ code/serialization/xfiles/ThawAlien.java | 22 + code/settings.gradle | 13 + code/standardio/ChangeSystemOut.java | 17 + code/standardio/Echo.java | 20 + code/standardio/OSExecuteDemo.java | 16 + code/standardio/Redirecting.java | 31 ++ code/staticchecking/DogsAndRobots.cpp | 33 ++ code/staticchecking/DogsAndRobots.py | 26 ++ code/staticchecking/NoBasePetSpeak.py | 35 ++ code/staticchecking/PetSpeak.py | 28 ++ code/staticchecking/dogsandrobots.go | 27 ++ code/staticchecking/dr/DogsAndRobots.java | 42 ++ .../drc/DogAndRobotCollections.java | 58 +++ code/staticchecking/latent/Latent.java | 60 +++ code/staticchecking/petspeak.go | 51 +++ code/staticchecking/petspeak/PetSpeak.java | 36 ++ code/streams/ArrayStreams.java | 31 ++ code/streams/Bubble.java | 18 + code/streams/Bubbles.java | 20 + code/streams/Cheese.dat | 6 + code/streams/CollectionToStream.java | 39 ++ code/streams/CreatingOptionals.java | 37 ++ code/streams/Duplicator.java | 18 + code/streams/Fibonacci.java | 34 ++ code/streams/FileToWords.java | 17 + code/streams/FileToWordsBuilder.java | 31 ++ code/streams/FileToWordsRegexp.java | 39 ++ code/streams/FileToWordsTest.java | 23 + code/streams/FlatMap.java | 25 ++ code/streams/ForEach.java | 28 ++ code/streams/FunctionMap.java | 60 +++ code/streams/FunctionMap2.java | 32 ++ code/streams/FunctionMap3.java | 28 ++ code/streams/Generator.java | 25 ++ code/streams/ImperativeRandoms.java | 21 + code/streams/Informational.java | 27 ++ code/streams/LastElement.java | 24 + code/streams/Looping.java | 20 + code/streams/Machine2.java | 23 + code/streams/MapCollector.java | 48 ++ code/streams/Matching.java | 38 ++ code/streams/NumericStreamInfo.java | 24 + code/streams/OptionalBasics.java | 23 + code/streams/OptionalFilter.java | 72 +++ code/streams/OptionalFlatMap.java | 73 ++++ code/streams/OptionalMap.java | 74 ++++ code/streams/Optionals.java | 63 +++ code/streams/OptionalsFromEmptyStreams.java | 31 ++ code/streams/Peeking.java | 22 + code/streams/Prime.java | 31 ++ code/streams/RandInts.java | 15 + code/streams/RandomGenerators.java | 86 ++++ code/streams/RandomWords.java | 41 ++ code/streams/Randoms.java | 25 ++ code/streams/Ranges.java | 29 ++ code/streams/Reduce.java | 44 ++ code/streams/SelectElement.java | 24 + code/streams/Signal.java | 29 ++ code/streams/SortedComparator.java | 20 + code/streams/SpecialCollector.java | 24 + code/streams/StreamOf.java | 28 ++ code/streams/StreamOfOptionals.java | 37 ++ code/streams/StreamOfRandoms.java | 20 + code/streams/StreamOfStreams.java | 19 + code/streams/TreeSetOfWords.java | 31 ++ code/strings/ArrayListDisplay.java | 22 + code/strings/BetterRead.java | 37 ++ code/strings/Concatenation.java | 15 + code/strings/Conversion.java | 113 +++++ code/strings/DatabaseException.java | 22 + code/strings/Finding.java | 27 ++ code/strings/Groups.java | 40 ++ code/strings/Hex.java | 44 ++ code/strings/Immutable.java | 22 + code/strings/InfiniteRecursion.java | 22 + code/strings/IntegerMatch.java | 19 + code/strings/JGrep.java | 36 ++ code/strings/ReFlags.java | 23 + code/strings/ReceiptBuilder.java | 48 ++ code/strings/Replacing.java | 21 + code/strings/ReplacingStringTokenizer.java | 26 ++ code/strings/Resetting.java | 23 + code/strings/Rudolph.java | 21 + code/strings/ScannerDelimiter.java | 21 + code/strings/SimpleFormat.java | 22 + code/strings/SimpleRead.java | 43 ++ code/strings/SplitDemo.java | 22 + code/strings/Splitting.java | 32 ++ code/strings/StartEnd.java | 82 ++++ code/strings/TestRegularExpression.java | 44 ++ code/strings/TheReplacements.java | 57 +++ code/strings/ThreatAnalyzer.java | 36 ++ code/strings/Turtle.java | 40 ++ code/strings/UsingStringBuilder.java | 37 ++ code/strings/WhitherStringBuilder.java | 21 + code/typeinfo/AnonymousImplementation.java | 50 +++ code/typeinfo/BoundedClassReferences.java | 13 + code/typeinfo/ClassCasts.java | 16 + code/typeinfo/ClassInitialization.java | 57 +++ code/typeinfo/DynamicSupplier.java | 42 ++ code/typeinfo/FamilyVsExactType.java | 62 +++ code/typeinfo/GenericClassReferences.java | 14 + code/typeinfo/HiddenImplementation.java | 44 ++ code/typeinfo/InnerImplementation.java | 49 +++ code/typeinfo/InterfaceViolation.java | 27 ++ code/typeinfo/ModifyingPrivateFields.java | 49 +++ code/typeinfo/NullRobot.java | 63 +++ code/typeinfo/Operation.java | 15 + code/typeinfo/Person.java | 49 +++ code/typeinfo/PetCount.java | 65 +++ code/typeinfo/PetCount2.java | 18 + code/typeinfo/PetCount3.java | 53 +++ code/typeinfo/PetCount4.java | 26 ++ code/typeinfo/Position.java | 51 +++ code/typeinfo/RegisteredFactories.java | 95 ++++ code/typeinfo/Robot.java | 22 + code/typeinfo/SelectingMethods.java | 69 +++ code/typeinfo/Shapes.java | 39 ++ code/typeinfo/ShowMethods.java | 71 +++ code/typeinfo/SimpleDynamicProxy.java | 53 +++ code/typeinfo/SimpleProxyDemo.java | 57 +++ code/typeinfo/SnowRemovalRobot.java | 42 ++ code/typeinfo/Staff.java | 63 +++ code/typeinfo/SweetShop.java | 42 ++ code/typeinfo/WildcardClassReferences.java | 11 + code/typeinfo/interfacea/A.java | 9 + code/typeinfo/packageaccess/HiddenC.java | 29 ++ code/typeinfo/pets/Cat.java | 10 + code/typeinfo/pets/Cymric.java | 10 + code/typeinfo/pets/Dog.java | 10 + code/typeinfo/pets/EgyptianMau.java | 10 + code/typeinfo/pets/ForNameCreator.java | 37 ++ code/typeinfo/pets/Hamster.java | 10 + code/typeinfo/pets/Individual.java | 46 ++ code/typeinfo/pets/LiteralPetCreator.java | 39 ++ code/typeinfo/pets/Manx.java | 10 + code/typeinfo/pets/Mouse.java | 10 + code/typeinfo/pets/Mutt.java | 10 + code/typeinfo/pets/Person.java | 9 + code/typeinfo/pets/Pet.java | 10 + code/typeinfo/pets/PetCreator.java | 28 ++ code/typeinfo/pets/Pets.java | 30 ++ code/typeinfo/pets/Pug.java | 10 + code/typeinfo/pets/Rat.java | 10 + code/typeinfo/pets/Rodent.java | 10 + code/typeinfo/toys/GenericToyTest.java | 23 + code/typeinfo/toys/ToyTest.java | 78 ++++ code/validating/Assert1.java | 19 + code/validating/Assert2.java | 20 + code/validating/BadMicroBenchmark.java | 29 ++ code/validating/BadMicroBenchmark2.java | 35 ++ code/validating/CircularQueue.java | 91 ++++ code/validating/CircularQueueException.java | 12 + code/validating/CountedList.java | 16 + code/validating/GuavaAssertions.java | 49 +++ code/validating/GuavaPreconditions.java | 125 ++++++ code/validating/Inverter1.java | 9 + code/validating/Inverter2.java | 19 + code/validating/Inverter3.java | 21 + code/validating/Inverter4.java | 26 ++ code/validating/LoaderAssertions.java | 28 ++ code/validating/NonNullConstruction.java | 18 + code/validating/SLF4JLevels.java | 29 ++ code/validating/SLF4JLogging.java | 17 + code/validating/SimpleDebugging.java | 40 ++ code/validating/StringInverter.java | 9 + code/validating/jmh/JMH1.java | 31 ++ code/validating/jmh/JMH2.java | 44 ++ code/validating/jmh/JMH3.java | 48 ++ code/validating/logback.xml | 15 + code/validating/tests/CircularQueueTest.java | 150 +++++++ code/validating/tests/CountedListTest.java | 101 +++++ .../tests/DynamicStringInverterTests.java | 122 ++++++ .../validating/tests/StringInverterTests.java | 65 +++ 1051 files changed, 40784 insertions(+) create mode 100644 code/.gitattributes create mode 100644 code/.gitignore create mode 100644 code/.travisXX.yml create mode 100644 code/CI.txt create mode 100644 code/Copyright.txt create mode 100644 code/README.md create mode 100644 code/annotations/AUComposition.java create mode 100644 code/annotations/AUExternalTest.java create mode 100644 code/annotations/AtUnitExample1.java create mode 100644 code/annotations/AtUnitExample2.java create mode 100644 code/annotations/AtUnitExample3.java create mode 100644 code/annotations/AtUnitExample4.java create mode 100644 code/annotations/AtUnitExample5.java create mode 100644 code/annotations/DemoProcessFiles.java create mode 100644 code/annotations/HashSetTest.java create mode 100644 code/annotations/PasswordUtils.java create mode 100644 code/annotations/SimulatingNull.java create mode 100644 code/annotations/StackL.java create mode 100644 code/annotations/StackLStringTst.java create mode 100644 code/annotations/Testable.java create mode 100644 code/annotations/UseCase.java create mode 100644 code/annotations/UseCaseTracker.java create mode 100644 code/annotations/database/Constraints.java create mode 100644 code/annotations/database/DBTable.java create mode 100644 code/annotations/database/Member.java create mode 100644 code/annotations/database/SQLInteger.java create mode 100644 code/annotations/database/SQLString.java create mode 100644 code/annotations/database/TableCreator.java create mode 100644 code/annotations/database/Uniqueness.java create mode 100644 code/annotations/ifx/ExtractInterface.java create mode 100644 code/annotations/ifx/IfaceExtractorProcessor.java create mode 100644 code/annotations/ifx/Multiplier.java create mode 100644 code/annotations/simplest/Simple.java create mode 100644 code/annotations/simplest/SimpleProcessor.java create mode 100644 code/annotations/simplest/SimpleTest.java create mode 100644 code/appveyorXX.yml create mode 100644 code/arrays/AlphabeticSearch.java create mode 100644 code/arrays/ArrayCopying.java create mode 100644 code/arrays/ArrayOfGenericType.java create mode 100644 code/arrays/ArrayOfGenerics.java create mode 100644 code/arrays/ArrayOptions.java create mode 100644 code/arrays/ArraySearching.java create mode 100644 code/arrays/AssemblingMultidimensionalArrays.java create mode 100644 code/arrays/AutoboxingArrays.java create mode 100644 code/arrays/CollectionComparison.java create mode 100644 code/arrays/CompType.java create mode 100644 code/arrays/ComparatorTest.java create mode 100644 code/arrays/ComparingArrays.java create mode 100644 code/arrays/CountUpward.java create mode 100644 code/arrays/FillingArrays.java create mode 100644 code/arrays/IceCreamFlavors.java create mode 100644 code/arrays/ModifyExisting.java create mode 100644 code/arrays/MultiDimWrapperArray.java create mode 100644 code/arrays/MultidimensionalObjectArrays.java create mode 100644 code/arrays/MultidimensionalPrimitiveArray.java create mode 100644 code/arrays/ParallelPrefix1.java create mode 100644 code/arrays/ParallelPrefix2.java create mode 100644 code/arrays/ParallelPrefix3.java create mode 100644 code/arrays/ParallelSetAll.java create mode 100644 code/arrays/ParameterizedArrayType.java create mode 100644 code/arrays/PythonLists.py create mode 100644 code/arrays/RaggedArray.java create mode 100644 code/arrays/Reverse.java create mode 100644 code/arrays/SimpleSetAll.java create mode 100644 code/arrays/StreamFromArray.java create mode 100644 code/arrays/StringSorting.java create mode 100644 code/arrays/TestConvertTo.java create mode 100644 code/arrays/TestCount.java create mode 100644 code/arrays/TestRand.java create mode 100644 code/arrays/ThreeDWithNew.java create mode 100644 code/arrays/jmh/ParallelSort.java create mode 100644 code/build.gradle create mode 100644 code/checkstyle.xml create mode 100644 code/chkstyle.bat create mode 100644 code/collections/AdapterMethodIdiom.java create mode 100644 code/collections/AddingGroups.java create mode 100644 code/collections/ApplesAndOrangesWithGenerics.java create mode 100644 code/collections/ApplesAndOrangesWithoutGenerics.java create mode 100644 code/collections/ArrayIsNotIterable.java create mode 100644 code/collections/AsListInference.java create mode 100644 code/collections/CollectionDifferences.java create mode 100644 code/collections/CollectionSequence.java create mode 100644 code/collections/CrossCollectionIteration.java create mode 100644 code/collections/CrossCollectionIteration2.java create mode 100644 code/collections/EnvironmentVariables.java create mode 100644 code/collections/ForInCollections.java create mode 100644 code/collections/GenericsAndUpcasting.java create mode 100644 code/collections/InterfaceVsIterator.java create mode 100644 code/collections/IterableClass.java create mode 100644 code/collections/LinkedListFeatures.java create mode 100644 code/collections/ListFeatures.java create mode 100644 code/collections/ListIteration.java create mode 100644 code/collections/MapOfList.java create mode 100644 code/collections/ModifyingArraysAsList.java create mode 100644 code/collections/MultiIterableClass.java create mode 100644 code/collections/NonCollectionSequence.java create mode 100644 code/collections/PetMap.java create mode 100644 code/collections/PrintingCollections.java create mode 100644 code/collections/PriorityQueueDemo.java create mode 100644 code/collections/QueueDemo.java create mode 100644 code/collections/SetOfInteger.java create mode 100644 code/collections/SetOfString.java create mode 100644 code/collections/SetOperations.java create mode 100644 code/collections/SimpleCollection.java create mode 100644 code/collections/SimpleIteration.java create mode 100644 code/collections/SortedSetOfString.java create mode 100644 code/collections/StackCollision.java create mode 100644 code/collections/StackTest.java create mode 100644 code/collections/StackTest2.java create mode 100644 code/collections/Statistics.java create mode 100644 code/collections/UniqueWords.java create mode 100644 code/collections/UniqueWordsAlphabetic.java create mode 100644 code/collectiontopics/AssociativeArray.java create mode 100644 code/collectiontopics/Bits.java create mode 100644 code/collectiontopics/CanonicalMapping.java create mode 100644 code/collectiontopics/CollectionMethods.java create mode 100644 code/collectiontopics/Enumerations.java create mode 100644 code/collectiontopics/FailFast.java create mode 100644 code/collectiontopics/FillMapTest.java create mode 100644 code/collectiontopics/FillingLists.java create mode 100644 code/collectiontopics/FunctionalMap.java create mode 100644 code/collectiontopics/HTMLColorTest.java create mode 100644 code/collectiontopics/LinkedHashMapDemo.java create mode 100644 code/collectiontopics/ListOps.java create mode 100644 code/collectiontopics/ListSortSearch.java create mode 100644 code/collectiontopics/MapOps.java create mode 100644 code/collectiontopics/NavMap.java create mode 100644 code/collectiontopics/QueueBehavior.java create mode 100644 code/collectiontopics/ReadOnly.java create mode 100644 code/collectiontopics/References.java create mode 100644 code/collectiontopics/SetOrder.java create mode 100644 code/collectiontopics/SimpleDeques.java create mode 100644 code/collectiontopics/SortedMapDemo.java create mode 100644 code/collectiontopics/SortedSetDemo.java create mode 100644 code/collectiontopics/Stacks.java create mode 100644 code/collectiontopics/StreamFillMaps.java create mode 100644 code/collectiontopics/SuppliersCollectionTest.java create mode 100644 code/collectiontopics/Synchronization.java create mode 100644 code/collectiontopics/ToDoList.java create mode 100644 code/collectiontopics/TypesForSets.java create mode 100644 code/collectiontopics/Unsupported.java create mode 100644 code/collectiontopics/Utilities.java create mode 100644 code/com/mindviewinc/simple/List.java create mode 100644 code/com/mindviewinc/simple/Vector.java create mode 100644 code/compression/GZIPcompress.java create mode 100644 code/compression/ZipCompress.java create mode 100644 code/concurrent/Baked.java create mode 100644 code/concurrent/Batter.java create mode 100644 code/concurrent/Breakable.java create mode 100644 code/concurrent/CachedThreadPool.java create mode 100644 code/concurrent/CachedThreadPool2.java create mode 100644 code/concurrent/CachedThreadPool3.java create mode 100644 code/concurrent/CatchCompletableExceptions.java create mode 100644 code/concurrent/CollectionIntoStream.java create mode 100644 code/concurrent/CompletableApply.java create mode 100644 code/concurrent/CompletableApplyAsync.java create mode 100644 code/concurrent/CompletableApplyChained.java create mode 100644 code/concurrent/CompletableExceptions.java create mode 100644 code/concurrent/CompletableOperations.java create mode 100644 code/concurrent/CompletablePizza.java create mode 100644 code/concurrent/CompletableUtilities.java create mode 100644 code/concurrent/CompletedMachina.java create mode 100644 code/concurrent/CountingStream.java create mode 100644 code/concurrent/CountingTask.java create mode 100644 code/concurrent/DiningPhilosophers.java create mode 100644 code/concurrent/DualCompletableOperations.java create mode 100644 code/concurrent/FrostedCake.java create mode 100644 code/concurrent/Futures.java create mode 100644 code/concurrent/GuardedIDField.java create mode 100644 code/concurrent/HasID.java create mode 100644 code/concurrent/IDChecker.java create mode 100644 code/concurrent/InterferingTask.java create mode 100644 code/concurrent/LambdasAndMethodReferences.java create mode 100644 code/concurrent/Machina.java create mode 100644 code/concurrent/MoreTasksAfterShutdown.java create mode 100644 code/concurrent/NapTask.java create mode 100644 code/concurrent/OnePizza.java create mode 100644 code/concurrent/ParallelPrime.java create mode 100644 code/concurrent/ParallelStreamPuzzle.java create mode 100644 code/concurrent/ParallelStreamPuzzle2.java create mode 100644 code/concurrent/ParallelStreamPuzzle3.java create mode 100644 code/concurrent/Philosopher.java create mode 100644 code/concurrent/Pizza.java create mode 100644 code/concurrent/PizzaParallelSteps.java create mode 100644 code/concurrent/PizzaStreams.java create mode 100644 code/concurrent/QuittableTask.java create mode 100644 code/concurrent/QuittingCompletable.java create mode 100644 code/concurrent/QuittingTasks.java create mode 100644 code/concurrent/SharedConstructorArgument.java create mode 100644 code/concurrent/SingleThreadExecutor.java create mode 100644 code/concurrent/SingleThreadExecutor2.java create mode 100644 code/concurrent/SingleThreadExecutor3.java create mode 100644 code/concurrent/StaticIDField.java create mode 100644 code/concurrent/StickHolder.java create mode 100644 code/concurrent/StreamExceptions.java create mode 100644 code/concurrent/Summing.java create mode 100644 code/concurrent/Summing2.java create mode 100644 code/concurrent/Summing3.java create mode 100644 code/concurrent/Summing4.java create mode 100644 code/concurrent/SynchronizedConstructor.java create mode 100644 code/concurrent/SynchronizedFactory.java create mode 100644 code/concurrent/TestStaticIDField.java create mode 100644 code/concurrent/ThrowsChecked.java create mode 100644 code/concurrent/Workable.java create mode 100644 code/control/BreakAndContinue.java create mode 100644 code/control/CommaOperator.java create mode 100644 code/control/ForInFloat.java create mode 100644 code/control/ForInInt.java create mode 100644 code/control/ForInString.java create mode 100644 code/control/IfElse.java create mode 100644 code/control/LabeledFor.java create mode 100644 code/control/LabeledWhile.java create mode 100644 code/control/ListCharacters.java create mode 100644 code/control/RandomBounds.java create mode 100644 code/control/StringSwitch.java create mode 100644 code/control/TestWithReturn.java create mode 100644 code/control/TrueFalse.java create mode 100644 code/control/VowelsAndConsonants.java create mode 100644 code/control/WhileTest.java create mode 100644 code/enums/AlarmPoints.java create mode 100644 code/enums/BigEnumSet.java create mode 100644 code/enums/Burrito2.java create mode 100644 code/enums/CarWash.java create mode 100644 code/enums/Competitor.java create mode 100644 code/enums/ConstantSpecificMethod.java create mode 100644 code/enums/EnumClass.java create mode 100644 code/enums/EnumMaps.java create mode 100644 code/enums/EnumSets.java create mode 100644 code/enums/Input.java create mode 100644 code/enums/NonEnum.java create mode 100644 code/enums/NotClasses.java create mode 100644 code/enums/Outcome.java create mode 100644 code/enums/OverrideConstantSpecific.java create mode 100644 code/enums/OzWitch.java create mode 100644 code/enums/PostOffice.java create mode 100644 code/enums/RandomTest.java create mode 100644 code/enums/Reflection.java create mode 100644 code/enums/RoShamBo.java create mode 100644 code/enums/RoShamBo1.java create mode 100644 code/enums/RoShamBo2.java create mode 100644 code/enums/RoShamBo3.java create mode 100644 code/enums/RoShamBo4.java create mode 100644 code/enums/RoShamBo5.java create mode 100644 code/enums/RoShamBo6.java create mode 100644 code/enums/SecurityCategory.java create mode 100644 code/enums/SpaceShip.java create mode 100644 code/enums/SpicinessEnum.java create mode 100644 code/enums/TrafficLight.java create mode 100644 code/enums/UpcastEnum.java create mode 100644 code/enums/VendingMachine.java create mode 100644 code/enums/VendingMachineInput.txt create mode 100644 code/enums/cartoons/EnumImplementation.java create mode 100644 code/enums/menu/Course.java create mode 100644 code/enums/menu/Food.java create mode 100644 code/enums/menu/Meal.java create mode 100644 code/enums/menu/Meal2.java create mode 100644 code/enums/menu/TypeOfFood.java create mode 100644 code/equalshashcode/ComposedEquality.java create mode 100644 code/equalshashcode/CountedString.java create mode 100644 code/equalshashcode/DefaultComparison.java create mode 100644 code/equalshashcode/Equality.java create mode 100644 code/equalshashcode/EqualityFactory.java create mode 100644 code/equalshashcode/Groundhog.java create mode 100644 code/equalshashcode/Groundhog2.java create mode 100644 code/equalshashcode/IndividualTest.java create mode 100644 code/equalshashcode/MapEntry.java create mode 100644 code/equalshashcode/Prediction.java create mode 100644 code/equalshashcode/SimpleHashMap.java create mode 100644 code/equalshashcode/SlowMap.java create mode 100644 code/equalshashcode/SpringDetector.java create mode 100644 code/equalshashcode/SpringDetector2.java create mode 100644 code/equalshashcode/StringHashCode.java create mode 100644 code/equalshashcode/SubtypeEquality.java create mode 100644 code/equalshashcode/SubtypeEquality2.java create mode 100644 code/equalshashcode/SuccinctEquality.java create mode 100644 code/exceptions/AlwaysFinally.java create mode 100644 code/exceptions/AutoCloseableDetails.java create mode 100644 code/exceptions/BodyException.java create mode 100644 code/exceptions/Cleanup.java create mode 100644 code/exceptions/CleanupIdiom.java create mode 100644 code/exceptions/CloseExceptions.java create mode 100644 code/exceptions/ConstructorException.java create mode 100644 code/exceptions/DynamicFields.java create mode 100644 code/exceptions/ExceptionMethods.java create mode 100644 code/exceptions/ExceptionSilencer.java create mode 100644 code/exceptions/ExtraFeatures.java create mode 100644 code/exceptions/FinallyWorks.java create mode 100644 code/exceptions/FullConstructors.java create mode 100644 code/exceptions/Human.java create mode 100644 code/exceptions/InheritingExceptions.java create mode 100644 code/exceptions/InputFile.java create mode 100644 code/exceptions/InputFile2.java create mode 100644 code/exceptions/LoggingExceptions.java create mode 100644 code/exceptions/LoggingExceptions2.java create mode 100644 code/exceptions/LostMessage.java create mode 100644 code/exceptions/MainException.java create mode 100644 code/exceptions/MessyExceptions.java create mode 100644 code/exceptions/MultiCatch.java create mode 100644 code/exceptions/MultiCatch2.java create mode 100644 code/exceptions/MultipleReturns.java create mode 100644 code/exceptions/NeverCaught.java create mode 100644 code/exceptions/OnOffException1.java create mode 100644 code/exceptions/OnOffException2.java create mode 100644 code/exceptions/OnOffSwitch.java create mode 100644 code/exceptions/PreciseRethrow.java create mode 100644 code/exceptions/RethrowNew.java create mode 100644 code/exceptions/Rethrowing.java create mode 100644 code/exceptions/SameHandler.java create mode 100644 code/exceptions/StormyInning.java create mode 100644 code/exceptions/StreamsAreAutoCloseable.java create mode 100644 code/exceptions/Switch.java create mode 100644 code/exceptions/TryAnything.java create mode 100644 code/exceptions/TryWithResources.java create mode 100644 code/exceptions/TurnOffChecking.java create mode 100644 code/exceptions/WhoCalled.java create mode 100644 code/exceptions/WithFinally.java create mode 100644 code/files/AddAndSubtractPaths.java create mode 100644 code/files/Directories.java create mode 100644 code/files/FileSystemDemo.java create mode 100644 code/files/Find.java create mode 100644 code/files/ListOfLines.java create mode 100644 code/files/PartsOfPaths.java create mode 100644 code/files/PathAnalysis.java create mode 100644 code/files/PathInfo.java create mode 100644 code/files/PathWatcher.java create mode 100644 code/files/ReadLineStream.java create mode 100644 code/files/StreamInAndOut.java create mode 100644 code/files/TreeWatcher.java create mode 100644 code/files/Writing.java create mode 100644 code/functional/AnonymousClosure.java create mode 100644 code/functional/BiConsumerPermutations.java create mode 100644 code/functional/ClassFunctionals.java create mode 100644 code/functional/Closure1.java create mode 100644 code/functional/Closure2.java create mode 100644 code/functional/Closure3.java create mode 100644 code/functional/Closure4.java create mode 100644 code/functional/Closure5.java create mode 100644 code/functional/Closure6.java create mode 100644 code/functional/Closure7.java create mode 100644 code/functional/Closure8.java create mode 100644 code/functional/Closure9.java create mode 100644 code/functional/ConsumeFunction.java create mode 100644 code/functional/CtorReference.java create mode 100644 code/functional/CurriedIntAdd.java create mode 100644 code/functional/Curry3Args.java create mode 100644 code/functional/CurryingAndPartials.java create mode 100644 code/functional/FunctionComposition.java create mode 100644 code/functional/FunctionVariants.java create mode 100644 code/functional/FunctionWithWrapped.java create mode 100644 code/functional/FunctionalAnnotation.java create mode 100644 code/functional/IntCall.java create mode 100644 code/functional/LambdaExpressions.java create mode 100644 code/functional/MethodConversion.java create mode 100644 code/functional/MethodReferences.java create mode 100644 code/functional/MultiUnbound.java create mode 100644 code/functional/PredicateComposition.java create mode 100644 code/functional/ProduceFunction.java create mode 100644 code/functional/RecursiveFactorial.java create mode 100644 code/functional/RecursiveFibonacci.java create mode 100644 code/functional/RunnableMethodReference.java create mode 100644 code/functional/SharedStorage.java create mode 100644 code/functional/Strategize.java create mode 100644 code/functional/TransformFunction.java create mode 100644 code/functional/TriFunction.java create mode 100644 code/functional/TriFunctionTest.java create mode 100644 code/functional/UnboundMethodReference.java create mode 100644 code/generics/Amphibian.java create mode 100644 code/generics/Apply.java create mode 100644 code/generics/ApplyFunctional.java create mode 100644 code/generics/ApplyTest.java create mode 100644 code/generics/ArrayMaker.java create mode 100644 code/generics/ArrayOfGeneric.java create mode 100644 code/generics/ArrayOfGenericReference.java create mode 100644 code/generics/BankTeller.java create mode 100644 code/generics/BasicBounds.java create mode 100644 code/generics/BasicHolder.java create mode 100644 code/generics/BasicSupplierDemo.java create mode 100644 code/generics/ByteSet.java create mode 100644 code/generics/CRGWithBasicHolder.java create mode 100644 code/generics/CaptureConversion.java create mode 100644 code/generics/CheckedList.java create mode 100644 code/generics/ClassCasting.java create mode 100644 code/generics/ClassTypeCapture.java create mode 100644 code/generics/ComparablePet.java create mode 100644 code/generics/CompilerIntelligence.java create mode 100644 code/generics/CountedObject.java create mode 100644 code/generics/CovariantArrays.java create mode 100644 code/generics/CovariantReturnTypes.java create mode 100644 code/generics/CreatorGeneric.java create mode 100644 code/generics/CuriouslyRecurringGeneric.java create mode 100644 code/generics/Diamond.java create mode 100644 code/generics/DogsAndRobotMethodReferences.java create mode 100644 code/generics/DogsAndRobots.cpp create mode 100644 code/generics/DogsAndRobots.java create mode 100644 code/generics/DogsAndRobots.py create mode 100644 code/generics/DynamicProxyMixin.java create mode 100644 code/generics/EpicBattle.java create mode 100644 code/generics/Erased.java create mode 100644 code/generics/ErasedTypeEquivalence.java create mode 100644 code/generics/ErasureAndInheritance.java create mode 100644 code/generics/FactoryConstraint.java create mode 100644 code/generics/Fibonacci.java create mode 100644 code/generics/FilledList.java create mode 100644 code/generics/GenericArray.java create mode 100644 code/generics/GenericArray2.java create mode 100644 code/generics/GenericArrayWithTypeToken.java create mode 100644 code/generics/GenericCast.java create mode 100644 code/generics/GenericHolder.java create mode 100644 code/generics/GenericHolder2.java create mode 100644 code/generics/GenericMethods.java create mode 100644 code/generics/GenericReading.java create mode 100644 code/generics/GenericVarargs.java create mode 100644 code/generics/GenericsAndCovariance.java create mode 100644 code/generics/GenericsAndReturnTypes.java create mode 100644 code/generics/HasF.java create mode 100644 code/generics/HijackedInterface.java create mode 100644 code/generics/Holder.java create mode 100644 code/generics/Holder1.java create mode 100644 code/generics/InheritBounds.java create mode 100644 code/generics/InstantiateGenericType.cpp create mode 100644 code/generics/InstantiateGenericType.java create mode 100644 code/generics/IterableFibonacci.java create mode 100644 code/generics/LatentReflection.java create mode 100644 code/generics/LinkedStack.java create mode 100644 code/generics/ListMaker.java create mode 100644 code/generics/ListOfGenerics.java create mode 100644 code/generics/ListOfInt.java create mode 100644 code/generics/LostInformation.java create mode 100644 code/generics/Manipulation.java create mode 100644 code/generics/Manipulator2.java create mode 100644 code/generics/Manipulator3.java create mode 100644 code/generics/Mixins.cpp create mode 100644 code/generics/Mixins.java create mode 100644 code/generics/MultipleInterfaceVariants.java create mode 100644 code/generics/NeedCasting.java create mode 100644 code/generics/NonCovariantGenerics.java create mode 100644 code/generics/NotSelfBounded.java create mode 100644 code/generics/ObjectHolder.java create mode 100644 code/generics/OrdinaryArguments.java create mode 100644 code/generics/Performs.java create mode 100644 code/generics/PlainGenericInheritance.java create mode 100644 code/generics/PrimitiveGenericTest.java create mode 100644 code/generics/RandomList.java create mode 100644 code/generics/RestrictedComparablePets.java create mode 100644 code/generics/ReturnGenericType.java create mode 100644 code/generics/SelfBounding.java create mode 100644 code/generics/SelfBoundingAndCovariantArguments.java create mode 100644 code/generics/SelfBoundingMethods.java create mode 100644 code/generics/Shape.java create mode 100644 code/generics/SimpleDogsAndRobots.java create mode 100644 code/generics/SimpleHolder.java create mode 100644 code/generics/SimpleQueue.java create mode 100644 code/generics/Square.java create mode 100644 code/generics/Store.java create mode 100644 code/generics/SuperTypeWildcards.java create mode 100644 code/generics/Templates.cpp create mode 100644 code/generics/ThrowGenericException.java create mode 100644 code/generics/TupleList.java create mode 100644 code/generics/TupleTest.java create mode 100644 code/generics/TupleTest2.java create mode 100644 code/generics/UnboundedWildcards1.java create mode 100644 code/generics/UnboundedWildcards2.java create mode 100644 code/generics/Unconstrained.java create mode 100644 code/generics/UseList.java create mode 100644 code/generics/UseList2.java create mode 100644 code/generics/Vehicle.java create mode 100644 code/generics/WatercolorSets.java create mode 100644 code/generics/Wildcards.java create mode 100644 code/generics/coffee/Americano.java create mode 100644 code/generics/coffee/Breve.java create mode 100644 code/generics/coffee/Cappuccino.java create mode 100644 code/generics/coffee/Coffee.java create mode 100644 code/generics/coffee/CoffeeSupplier.java create mode 100644 code/generics/coffee/Latte.java create mode 100644 code/generics/coffee/Mocha.java create mode 100644 code/generics/decorator/Decoration.java create mode 100644 code/generics/dogsandrobots.go create mode 100644 code/generics/watercolors/Watercolors.java create mode 100644 code/gradle.properties create mode 100644 code/gradle/checkstyle.gradle create mode 100644 code/gradle/findbugs.gradle create mode 100644 code/gradle/java.gradle create mode 100644 code/gradle/jmh.gradle create mode 100644 code/gradle/junit-jupiter.gradle create mode 100644 code/gradle/subprojects.gradle create mode 100644 code/gradle/wrapper/gradle-wrapper.jar create mode 100644 code/gradle/wrapper/gradle-wrapper.properties create mode 100644 code/gradlew create mode 100644 code/gradlew.bat create mode 100644 code/hiding/Cake.java create mode 100644 code/hiding/ChocolateChip.java create mode 100644 code/hiding/ChocolateChip2.java create mode 100644 code/hiding/CreatePackageAccessObject.java create mode 100644 code/hiding/Dinner.java create mode 100644 code/hiding/FullQualification.java create mode 100644 code/hiding/IceCream.java create mode 100644 code/hiding/ImportedMyClass.java create mode 100644 code/hiding/LibTest.java create mode 100644 code/hiding/Lunch.java create mode 100644 code/hiding/OrganizedByAccess.java create mode 100644 code/hiding/Pie.java create mode 100644 code/hiding/QualifiedMyClass.java create mode 100644 code/hiding/SingleImport.java create mode 100644 code/hiding/cookie2/Cookie.java create mode 100644 code/hiding/dessert/Cookie.java create mode 100644 code/hiding/mypackage/MyClass.java create mode 100644 code/hiding/packageaccess/PublicConstructor.java create mode 100644 code/housekeeping/Apricot.java create mode 100644 code/housekeeping/ArrayClassObj.java create mode 100644 code/housekeeping/ArrayInit.java create mode 100644 code/housekeeping/ArrayNew.java create mode 100644 code/housekeeping/ArraysOfPrimitives.java create mode 100644 code/housekeeping/AutoboxingVarargs.java create mode 100644 code/housekeeping/BananaPeel.java create mode 100644 code/housekeeping/Burrito.java create mode 100644 code/housekeeping/Counter.java create mode 100644 code/housekeeping/DefaultConstructor.java create mode 100644 code/housekeeping/Demotion.java create mode 100644 code/housekeeping/DynamicArray.java create mode 100644 code/housekeeping/EnumOrder.java create mode 100644 code/housekeeping/ExplicitStatic.java create mode 100644 code/housekeeping/Flower.java create mode 100644 code/housekeeping/InitialValues.java create mode 100644 code/housekeeping/InitialValues2.java create mode 100644 code/housekeeping/Leaf.java create mode 100644 code/housekeeping/Measurement.java create mode 100644 code/housekeeping/MethodInit.java create mode 100644 code/housekeeping/MethodInit2.java create mode 100644 code/housekeeping/MethodInit3.java create mode 100644 code/housekeeping/Mugs.java create mode 100644 code/housekeeping/NewVarArgs.java create mode 100644 code/housekeeping/NoSynthesis.java create mode 100644 code/housekeeping/OptionalTrailingArguments.java create mode 100644 code/housekeeping/OrderOfInitialization.java create mode 100644 code/housekeeping/Overloading.java create mode 100644 code/housekeeping/OverloadingOrder.java create mode 100644 code/housekeeping/OverloadingVarargs.java create mode 100644 code/housekeeping/OverloadingVarargs2.java create mode 100644 code/housekeeping/OverloadingVarargs3.java create mode 100644 code/housekeeping/PassingThis.java create mode 100644 code/housekeeping/PrimitiveOverloading.java create mode 100644 code/housekeeping/SimpleConstructor.java create mode 100644 code/housekeeping/SimpleConstructor2.java create mode 100644 code/housekeeping/SimpleEnumUse.java create mode 100644 code/housekeeping/Spiciness.java create mode 100644 code/housekeeping/Spoon.java create mode 100644 code/housekeeping/StaticInitialization.java create mode 100644 code/housekeeping/TerminationCondition.java create mode 100644 code/housekeeping/VarArgs.java create mode 100644 code/housekeeping/VarargType.java create mode 100644 code/innerclasses/AnonymousConstructor.java create mode 100644 code/innerclasses/BigEgg.java create mode 100644 code/innerclasses/BigEgg2.java create mode 100644 code/innerclasses/Callbacks.java create mode 100644 code/innerclasses/ClassInInterface.java create mode 100644 code/innerclasses/Contents.java create mode 100644 code/innerclasses/Destination.java create mode 100644 code/innerclasses/DotNew.java create mode 100644 code/innerclasses/DotThis.java create mode 100644 code/innerclasses/GreenhouseController.java create mode 100644 code/innerclasses/GreenhouseControls.java create mode 100644 code/innerclasses/InheritInner.java create mode 100644 code/innerclasses/LocalInnerClass.java create mode 100644 code/innerclasses/MultiImplementation.java create mode 100644 code/innerclasses/MultiNestingAccess.java create mode 100644 code/innerclasses/Parcel1.java create mode 100644 code/innerclasses/Parcel10.java create mode 100644 code/innerclasses/Parcel11.java create mode 100644 code/innerclasses/Parcel2.java create mode 100644 code/innerclasses/Parcel3.java create mode 100644 code/innerclasses/Parcel5.java create mode 100644 code/innerclasses/Parcel6.java create mode 100644 code/innerclasses/Parcel7.java create mode 100644 code/innerclasses/Parcel7b.java create mode 100644 code/innerclasses/Parcel8.java create mode 100644 code/innerclasses/Parcel9.java create mode 100644 code/innerclasses/Sequence.java create mode 100644 code/innerclasses/TestBed.java create mode 100644 code/innerclasses/TestParcel.java create mode 100644 code/innerclasses/Wrapping.java create mode 100644 code/innerclasses/controller/Controller.java create mode 100644 code/innerclasses/controller/Event.java create mode 100644 code/innerclasses/mui/MultiInterfaces.java create mode 100644 code/interfaces/AbstractAccess.java create mode 100644 code/interfaces/AbstractWithoutAbstracts.java create mode 100644 code/interfaces/AdaptedRandomDoubles.java create mode 100644 code/interfaces/Adventure.java create mode 100644 code/interfaces/AnImplementation.java create mode 100644 code/interfaces/AnInterface.java create mode 100644 code/interfaces/Applicator.java create mode 100644 code/interfaces/AttemptToUseBasic.java create mode 100644 code/interfaces/Basic.java create mode 100644 code/interfaces/Basic2.java create mode 100644 code/interfaces/Factories.java create mode 100644 code/interfaces/Games.java create mode 100644 code/interfaces/HorrorShow.java create mode 100644 code/interfaces/Implementation2.java create mode 100644 code/interfaces/ImplementingAnInterface.java create mode 100644 code/interfaces/Instantiable.java create mode 100644 code/interfaces/InterfaceCollision.java create mode 100644 code/interfaces/InterfaceWithDefault.java create mode 100644 code/interfaces/Jim.java create mode 100644 code/interfaces/MICollision.java create mode 100644 code/interfaces/Machine.java create mode 100644 code/interfaces/Months.java create mode 100644 code/interfaces/MultipleInheritance.java create mode 100644 code/interfaces/PureInterface.java create mode 100644 code/interfaces/RandVals.java create mode 100644 code/interfaces/RandomDoubles.java create mode 100644 code/interfaces/RandomStrings.java create mode 100644 code/interfaces/TestRandVals.java create mode 100644 code/interfaces/filters/BandPass.java create mode 100644 code/interfaces/filters/Filter.java create mode 100644 code/interfaces/filters/HighPass.java create mode 100644 code/interfaces/filters/LowPass.java create mode 100644 code/interfaces/filters/Waveform.java create mode 100644 code/interfaces/interfaceprocessor/Applicator.java create mode 100644 code/interfaces/interfaceprocessor/FilterProcessor.java create mode 100644 code/interfaces/interfaceprocessor/Processor.java create mode 100644 code/interfaces/interfaceprocessor/StringProcessor.java create mode 100644 code/interfaces/music4/Music4.java create mode 100644 code/interfaces/music5/Music5.java create mode 100644 code/interfaces/nesting/NestingInterfaces.java create mode 100644 code/iostreams/BasicFileOutput.java create mode 100644 code/iostreams/BufferedInputFile.java create mode 100644 code/iostreams/FileOutputShortcut.java create mode 100644 code/iostreams/FormattedMemoryInput.java create mode 100644 code/iostreams/MemoryInput.java create mode 100644 code/iostreams/StoringAndRecoveringData.java create mode 100644 code/iostreams/TestEOF.java create mode 100644 code/iostreams/UsingRandomAccessFile.java create mode 100644 code/javadoc/Documentation1.java create mode 100644 code/javadoc/Documentation2.java create mode 100644 code/javadoc/Documentation3.java create mode 100644 code/javadoc/HelloDateDoc.java create mode 100644 code/lowlevel/AtomicEvenProducer.java create mode 100644 code/lowlevel/AtomicIntegerTest.java create mode 100644 code/lowlevel/AtomicSerialNumbers.java create mode 100644 code/lowlevel/Atomicity.java create mode 100644 code/lowlevel/AttemptLocking.java create mode 100644 code/lowlevel/CaptureUncaughtException.java create mode 100644 code/lowlevel/CircularSet.java create mode 100644 code/lowlevel/DelayQueueDemo.java create mode 100644 code/lowlevel/EvenChecker.java create mode 100644 code/lowlevel/EvenProducer.java create mode 100644 code/lowlevel/ExceptionThread.java create mode 100644 code/lowlevel/IntGenerator.java create mode 100644 code/lowlevel/IntTestable.java create mode 100644 code/lowlevel/MutexEvenProducer.java create mode 100644 code/lowlevel/NaiveExceptionHandling.java create mode 100644 code/lowlevel/NotAtomic.java create mode 100644 code/lowlevel/NumberOfProcessors.java create mode 100644 code/lowlevel/PriorityBlockingQueueDemo.java create mode 100644 code/lowlevel/ReOrdering.java create mode 100644 code/lowlevel/SafeReturn.java create mode 100644 code/lowlevel/SerialNumberChecker.java create mode 100644 code/lowlevel/SerialNumberTest.java create mode 100644 code/lowlevel/SerialNumbers.java create mode 100644 code/lowlevel/SettingDefaultHandler.java create mode 100644 code/lowlevel/SwallowedException.java create mode 100644 code/lowlevel/SyncOnObject.java create mode 100644 code/lowlevel/SynchronizedComparison.java create mode 100644 code/lowlevel/SynchronizedEvenProducer.java create mode 100644 code/lowlevel/SynchronizedSerialNumbers.java create mode 100644 code/lowlevel/TestAbort.java create mode 100644 code/lowlevel/ThreadSize.java create mode 100644 code/lowlevel/UnsafeReturn.java create mode 100644 code/lowlevel/WorkStealingPool.java create mode 100644 code/newio/AvailableCharSets.java create mode 100644 code/newio/BufferToText.java create mode 100644 code/newio/ChannelCopy.java create mode 100644 code/newio/Endians.java create mode 100644 code/newio/FileLocking.java create mode 100644 code/newio/GetChannel.java create mode 100644 code/newio/GetData.java create mode 100644 code/newio/IntBufferDemo.java create mode 100644 code/newio/LargeMappedFiles.java create mode 100644 code/newio/LockingMappedFiles.java create mode 100644 code/newio/MappedIO.java create mode 100644 code/newio/TransferTo.java create mode 100644 code/newio/UsingBuffers.java create mode 100644 code/newio/ViewBuffers.java create mode 100644 code/objects/HelloDate.java create mode 100644 code/objects/ShowProperties.java create mode 100644 code/onjava/ArrayShow.java create mode 100644 code/onjava/BasicSupplier.java create mode 100644 code/onjava/CollectionMethodDifferences.java create mode 100644 code/onjava/ConvertTo.java create mode 100644 code/onjava/Count.java create mode 100644 code/onjava/CountMap.java create mode 100644 code/onjava/CountingIntegerList.java create mode 100644 code/onjava/Countries.java create mode 100644 code/onjava/Enums.java create mode 100644 code/onjava/FillMap.java create mode 100644 code/onjava/HTMLColors.java create mode 100644 code/onjava/MouseClick.java create mode 100644 code/onjava/Nap.java create mode 100644 code/onjava/Null.java create mode 100644 code/onjava/OSExecute.java create mode 100644 code/onjava/OSExecuteException.java create mode 100644 code/onjava/Operations.java create mode 100644 code/onjava/Pair.java create mode 100644 code/onjava/ProcessFiles.java create mode 100644 code/onjava/Rand.java create mode 100644 code/onjava/Range.java create mode 100644 code/onjava/Repeat.java create mode 100644 code/onjava/RmDir.java create mode 100644 code/onjava/Sets.java create mode 100644 code/onjava/Stack.java create mode 100644 code/onjava/Suppliers.java create mode 100644 code/onjava/TimedAbort.java create mode 100644 code/onjava/Timer.java create mode 100644 code/onjava/Tuple.java create mode 100644 code/onjava/Tuple2.java create mode 100644 code/onjava/Tuple3.java create mode 100644 code/onjava/Tuple4.java create mode 100644 code/onjava/Tuple5.java create mode 100644 code/onjava/TypeCounter.java create mode 100644 code/onjava/atunit/AtUnit.java create mode 100644 code/onjava/atunit/ClassNameFinder.java create mode 100644 code/onjava/atunit/Test.java create mode 100644 code/onjava/atunit/TestObjectCleanup.java create mode 100644 code/onjava/atunit/TestObjectCreate.java create mode 100644 code/onjava/atunit/TestProperty.java create mode 100644 code/operators/AllOps.java create mode 100644 code/operators/Assignment.java create mode 100644 code/operators/AutoInc.java create mode 100644 code/operators/BitManipulation.java create mode 100644 code/operators/Bool.java create mode 100644 code/operators/Casting.java create mode 100644 code/operators/CastingNumbers.java create mode 100644 code/operators/EqualsMethod.java create mode 100644 code/operators/EqualsMethod2.java create mode 100644 code/operators/Equivalence.java create mode 100644 code/operators/Exponents.java create mode 100644 code/operators/Literals.java create mode 100644 code/operators/MathOps.java create mode 100644 code/operators/Overflow.java create mode 100644 code/operators/PassObject.java create mode 100644 code/operators/Precedence.java create mode 100644 code/operators/RoundingNumbers.java create mode 100644 code/operators/ShortCircuit.java create mode 100644 code/operators/StringOperators.java create mode 100644 code/operators/TernaryIfElse.java create mode 100644 code/operators/URShift.java create mode 100644 code/operators/Underscores.java create mode 100644 code/patterns/BoxObserver.java create mode 100644 code/patterns/CommandPattern.java create mode 100644 code/patterns/Facade.java create mode 100644 code/patterns/PaperScissorsRock.java create mode 100644 code/patterns/ProxyDemo.java create mode 100644 code/patterns/ShapeFactory1.java create mode 100644 code/patterns/ShapeFactory2.java create mode 100644 code/patterns/ShapeFactory3.java create mode 100644 code/patterns/SingletonPattern.java create mode 100644 code/patterns/StateDemo.java create mode 100644 code/patterns/TemplateMethod.java create mode 100644 code/patterns/abstractfactory/GameEnvironment.java create mode 100644 code/patterns/adapt/Adapter.java create mode 100644 code/patterns/chain/ChainOfResponsibility.java create mode 100644 code/patterns/doubledispatch/Aluminum.java create mode 100644 code/patterns/doubledispatch/Cardboard.java create mode 100644 code/patterns/doubledispatch/DoubleDispatch.java create mode 100644 code/patterns/doubledispatch/Glass.java create mode 100644 code/patterns/doubledispatch/Paper.java create mode 100644 code/patterns/doubledispatch/TypedBin.java create mode 100644 code/patterns/doubledispatch/TypedBinMember.java create mode 100644 code/patterns/dynatrash/DynaTrash.java create mode 100644 code/patterns/observer/ObservedFlower.java create mode 100644 code/patterns/recyclea/RecycleA.java create mode 100644 code/patterns/recycleb/RecycleB.java create mode 100644 code/patterns/recyclec/RecycleC.java create mode 100644 code/patterns/shapes/BadShapeCreation.java create mode 100644 code/patterns/shapes/Circle.java create mode 100644 code/patterns/shapes/FactoryMethod.java create mode 100644 code/patterns/shapes/FactoryTest.java create mode 100644 code/patterns/shapes/Shape.java create mode 100644 code/patterns/shapes/Square.java create mode 100644 code/patterns/shapes/Triangle.java create mode 100644 code/patterns/state/StateMachineDemo.java create mode 100644 code/patterns/strategy/StrategyPattern.java create mode 100644 code/patterns/strategy/StrategyPattern2.java create mode 100644 code/patterns/trash/Aluminum.java create mode 100644 code/patterns/trash/Cardboard.java create mode 100644 code/patterns/trash/Fillable.java create mode 100644 code/patterns/trash/FillableList.java create mode 100644 code/patterns/trash/Glass.java create mode 100644 code/patterns/trash/Paper.java create mode 100644 code/patterns/trash/ParseTrash.java create mode 100644 code/patterns/trash/Trash.dat create mode 100644 code/patterns/trash/Trash.java create mode 100644 code/patterns/trashvisitor/Aluminum.java create mode 100644 code/patterns/trashvisitor/Cardboard.java create mode 100644 code/patterns/trashvisitor/Glass.java create mode 100644 code/patterns/trashvisitor/Paper.java create mode 100644 code/patterns/trashvisitor/TrashVisitor.java create mode 100644 code/patterns/trashvisitor/Visitable.java create mode 100644 code/patterns/trashvisitor/Visitor.java create mode 100644 code/patterns/visitor/BeeAndFlowers.java create mode 100644 code/polymorphism/CovariantReturn.java create mode 100644 code/polymorphism/FieldAccess.java create mode 100644 code/polymorphism/Frog.java create mode 100644 code/polymorphism/PolyConstructors.java create mode 100644 code/polymorphism/PrivateOverride.java create mode 100644 code/polymorphism/PrivateOverride2.java create mode 100644 code/polymorphism/RTTI.java create mode 100644 code/polymorphism/ReferenceCounting.java create mode 100644 code/polymorphism/Sandwich.java create mode 100644 code/polymorphism/Shapes.java create mode 100644 code/polymorphism/StaticPolymorphism.java create mode 100644 code/polymorphism/Transmogrify.java create mode 100644 code/polymorphism/music/Instrument.java create mode 100644 code/polymorphism/music/Music.java create mode 100644 code/polymorphism/music/Music2.java create mode 100644 code/polymorphism/music/Note.java create mode 100644 code/polymorphism/music/Wind.java create mode 100644 code/polymorphism/music3/Music3.java create mode 100644 code/polymorphism/shape/Circle.java create mode 100644 code/polymorphism/shape/RandomShapes.java create mode 100644 code/polymorphism/shape/Shape.java create mode 100644 code/polymorphism/shape/Square.java create mode 100644 code/polymorphism/shape/Triangle.java create mode 100644 code/references/AddingClone.java create mode 100644 code/references/Alias1.java create mode 100644 code/references/Alias2.java create mode 100644 code/references/CheckCloneable.java create mode 100644 code/references/CloneArrayList.java create mode 100644 code/references/Compete.java create mode 100644 code/references/CopyConstructor.java create mode 100644 code/references/DepthReading.java create mode 100644 code/references/HorrorFlick.java create mode 100644 code/references/Immutable1.java create mode 100644 code/references/Immutable2.java create mode 100644 code/references/ImmutableInteger.java create mode 100644 code/references/ImmutableStrings.java create mode 100644 code/references/LocalCopy.java create mode 100644 code/references/MutableInteger.java create mode 100644 code/references/OceanReading.java create mode 100644 code/references/PassReferences.java create mode 100644 code/references/SimplerMutableInteger.java create mode 100644 code/references/Snake.java create mode 100644 code/references/Stringer.java create mode 100644 code/references/TemperatureReading.java create mode 100644 code/references/tests/DeepCopyTest.java create mode 100644 code/reuse/Bath.java create mode 100644 code/reuse/Beetle.java create mode 100644 code/reuse/BlankFinal.java create mode 100644 code/reuse/CADSystem.java create mode 100644 code/reuse/Car.java create mode 100644 code/reuse/Cartoon.java create mode 100644 code/reuse/Chess.java create mode 100644 code/reuse/DerivedSpaceShip.java create mode 100644 code/reuse/Detergent.java create mode 100644 code/reuse/FinalArguments.java create mode 100644 code/reuse/FinalData.java create mode 100644 code/reuse/FinalOverridingIllusion.java create mode 100644 code/reuse/Hide.java create mode 100644 code/reuse/Jurassic.java create mode 100644 code/reuse/Lisa.java create mode 100644 code/reuse/Orc.java create mode 100644 code/reuse/PlaceSetting.java create mode 100644 code/reuse/SpaceShipControls.java create mode 100644 code/reuse/SpaceShipDelegation.java create mode 100644 code/reuse/SprinklerSystem.java create mode 100644 code/reuse/Wind.java create mode 100644 code/serialization/APerson.java create mode 100644 code/serialization/AStoreCADState.java create mode 100644 code/serialization/Alien.java create mode 100644 code/serialization/Blip3.java create mode 100644 code/serialization/Blips.java create mode 100644 code/serialization/FreezeAlien.java create mode 100644 code/serialization/Logon.java create mode 100644 code/serialization/MyWorld.java create mode 100644 code/serialization/People.java create mode 100644 code/serialization/RecoverCADState.java create mode 100644 code/serialization/SerialCtl.java create mode 100644 code/serialization/Worm.java create mode 100644 code/serialization/xfiles/ThawAlien.java create mode 100644 code/settings.gradle create mode 100644 code/standardio/ChangeSystemOut.java create mode 100644 code/standardio/Echo.java create mode 100644 code/standardio/OSExecuteDemo.java create mode 100644 code/standardio/Redirecting.java create mode 100644 code/staticchecking/DogsAndRobots.cpp create mode 100644 code/staticchecking/DogsAndRobots.py create mode 100644 code/staticchecking/NoBasePetSpeak.py create mode 100644 code/staticchecking/PetSpeak.py create mode 100644 code/staticchecking/dogsandrobots.go create mode 100644 code/staticchecking/dr/DogsAndRobots.java create mode 100644 code/staticchecking/drc/DogAndRobotCollections.java create mode 100644 code/staticchecking/latent/Latent.java create mode 100644 code/staticchecking/petspeak.go create mode 100644 code/staticchecking/petspeak/PetSpeak.java create mode 100644 code/streams/ArrayStreams.java create mode 100644 code/streams/Bubble.java create mode 100644 code/streams/Bubbles.java create mode 100644 code/streams/Cheese.dat create mode 100644 code/streams/CollectionToStream.java create mode 100644 code/streams/CreatingOptionals.java create mode 100644 code/streams/Duplicator.java create mode 100644 code/streams/Fibonacci.java create mode 100644 code/streams/FileToWords.java create mode 100644 code/streams/FileToWordsBuilder.java create mode 100644 code/streams/FileToWordsRegexp.java create mode 100644 code/streams/FileToWordsTest.java create mode 100644 code/streams/FlatMap.java create mode 100644 code/streams/ForEach.java create mode 100644 code/streams/FunctionMap.java create mode 100644 code/streams/FunctionMap2.java create mode 100644 code/streams/FunctionMap3.java create mode 100644 code/streams/Generator.java create mode 100644 code/streams/ImperativeRandoms.java create mode 100644 code/streams/Informational.java create mode 100644 code/streams/LastElement.java create mode 100644 code/streams/Looping.java create mode 100644 code/streams/Machine2.java create mode 100644 code/streams/MapCollector.java create mode 100644 code/streams/Matching.java create mode 100644 code/streams/NumericStreamInfo.java create mode 100644 code/streams/OptionalBasics.java create mode 100644 code/streams/OptionalFilter.java create mode 100644 code/streams/OptionalFlatMap.java create mode 100644 code/streams/OptionalMap.java create mode 100644 code/streams/Optionals.java create mode 100644 code/streams/OptionalsFromEmptyStreams.java create mode 100644 code/streams/Peeking.java create mode 100644 code/streams/Prime.java create mode 100644 code/streams/RandInts.java create mode 100644 code/streams/RandomGenerators.java create mode 100644 code/streams/RandomWords.java create mode 100644 code/streams/Randoms.java create mode 100644 code/streams/Ranges.java create mode 100644 code/streams/Reduce.java create mode 100644 code/streams/SelectElement.java create mode 100644 code/streams/Signal.java create mode 100644 code/streams/SortedComparator.java create mode 100644 code/streams/SpecialCollector.java create mode 100644 code/streams/StreamOf.java create mode 100644 code/streams/StreamOfOptionals.java create mode 100644 code/streams/StreamOfRandoms.java create mode 100644 code/streams/StreamOfStreams.java create mode 100644 code/streams/TreeSetOfWords.java create mode 100644 code/strings/ArrayListDisplay.java create mode 100644 code/strings/BetterRead.java create mode 100644 code/strings/Concatenation.java create mode 100644 code/strings/Conversion.java create mode 100644 code/strings/DatabaseException.java create mode 100644 code/strings/Finding.java create mode 100644 code/strings/Groups.java create mode 100644 code/strings/Hex.java create mode 100644 code/strings/Immutable.java create mode 100644 code/strings/InfiniteRecursion.java create mode 100644 code/strings/IntegerMatch.java create mode 100644 code/strings/JGrep.java create mode 100644 code/strings/ReFlags.java create mode 100644 code/strings/ReceiptBuilder.java create mode 100644 code/strings/Replacing.java create mode 100644 code/strings/ReplacingStringTokenizer.java create mode 100644 code/strings/Resetting.java create mode 100644 code/strings/Rudolph.java create mode 100644 code/strings/ScannerDelimiter.java create mode 100644 code/strings/SimpleFormat.java create mode 100644 code/strings/SimpleRead.java create mode 100644 code/strings/SplitDemo.java create mode 100644 code/strings/Splitting.java create mode 100644 code/strings/StartEnd.java create mode 100644 code/strings/TestRegularExpression.java create mode 100644 code/strings/TheReplacements.java create mode 100644 code/strings/ThreatAnalyzer.java create mode 100644 code/strings/Turtle.java create mode 100644 code/strings/UsingStringBuilder.java create mode 100644 code/strings/WhitherStringBuilder.java create mode 100644 code/typeinfo/AnonymousImplementation.java create mode 100644 code/typeinfo/BoundedClassReferences.java create mode 100644 code/typeinfo/ClassCasts.java create mode 100644 code/typeinfo/ClassInitialization.java create mode 100644 code/typeinfo/DynamicSupplier.java create mode 100644 code/typeinfo/FamilyVsExactType.java create mode 100644 code/typeinfo/GenericClassReferences.java create mode 100644 code/typeinfo/HiddenImplementation.java create mode 100644 code/typeinfo/InnerImplementation.java create mode 100644 code/typeinfo/InterfaceViolation.java create mode 100644 code/typeinfo/ModifyingPrivateFields.java create mode 100644 code/typeinfo/NullRobot.java create mode 100644 code/typeinfo/Operation.java create mode 100644 code/typeinfo/Person.java create mode 100644 code/typeinfo/PetCount.java create mode 100644 code/typeinfo/PetCount2.java create mode 100644 code/typeinfo/PetCount3.java create mode 100644 code/typeinfo/PetCount4.java create mode 100644 code/typeinfo/Position.java create mode 100644 code/typeinfo/RegisteredFactories.java create mode 100644 code/typeinfo/Robot.java create mode 100644 code/typeinfo/SelectingMethods.java create mode 100644 code/typeinfo/Shapes.java create mode 100644 code/typeinfo/ShowMethods.java create mode 100644 code/typeinfo/SimpleDynamicProxy.java create mode 100644 code/typeinfo/SimpleProxyDemo.java create mode 100644 code/typeinfo/SnowRemovalRobot.java create mode 100644 code/typeinfo/Staff.java create mode 100644 code/typeinfo/SweetShop.java create mode 100644 code/typeinfo/WildcardClassReferences.java create mode 100644 code/typeinfo/interfacea/A.java create mode 100644 code/typeinfo/packageaccess/HiddenC.java create mode 100644 code/typeinfo/pets/Cat.java create mode 100644 code/typeinfo/pets/Cymric.java create mode 100644 code/typeinfo/pets/Dog.java create mode 100644 code/typeinfo/pets/EgyptianMau.java create mode 100644 code/typeinfo/pets/ForNameCreator.java create mode 100644 code/typeinfo/pets/Hamster.java create mode 100644 code/typeinfo/pets/Individual.java create mode 100644 code/typeinfo/pets/LiteralPetCreator.java create mode 100644 code/typeinfo/pets/Manx.java create mode 100644 code/typeinfo/pets/Mouse.java create mode 100644 code/typeinfo/pets/Mutt.java create mode 100644 code/typeinfo/pets/Person.java create mode 100644 code/typeinfo/pets/Pet.java create mode 100644 code/typeinfo/pets/PetCreator.java create mode 100644 code/typeinfo/pets/Pets.java create mode 100644 code/typeinfo/pets/Pug.java create mode 100644 code/typeinfo/pets/Rat.java create mode 100644 code/typeinfo/pets/Rodent.java create mode 100644 code/typeinfo/toys/GenericToyTest.java create mode 100644 code/typeinfo/toys/ToyTest.java create mode 100644 code/validating/Assert1.java create mode 100644 code/validating/Assert2.java create mode 100644 code/validating/BadMicroBenchmark.java create mode 100644 code/validating/BadMicroBenchmark2.java create mode 100644 code/validating/CircularQueue.java create mode 100644 code/validating/CircularQueueException.java create mode 100644 code/validating/CountedList.java create mode 100644 code/validating/GuavaAssertions.java create mode 100644 code/validating/GuavaPreconditions.java create mode 100644 code/validating/Inverter1.java create mode 100644 code/validating/Inverter2.java create mode 100644 code/validating/Inverter3.java create mode 100644 code/validating/Inverter4.java create mode 100644 code/validating/LoaderAssertions.java create mode 100644 code/validating/NonNullConstruction.java create mode 100644 code/validating/SLF4JLevels.java create mode 100644 code/validating/SLF4JLogging.java create mode 100644 code/validating/SimpleDebugging.java create mode 100644 code/validating/StringInverter.java create mode 100644 code/validating/jmh/JMH1.java create mode 100644 code/validating/jmh/JMH2.java create mode 100644 code/validating/jmh/JMH3.java create mode 100644 code/validating/logback.xml create mode 100644 code/validating/tests/CircularQueueTest.java create mode 100644 code/validating/tests/CountedListTest.java create mode 100644 code/validating/tests/DynamicStringInverterTests.java create mode 100644 code/validating/tests/StringInverterTests.java diff --git a/code/.gitattributes b/code/.gitattributes new file mode 100644 index 00000000..bdb0cabc --- /dev/null +++ b/code/.gitattributes @@ -0,0 +1,17 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/code/.gitignore b/code/.gitignore new file mode 100644 index 00000000..48292956 --- /dev/null +++ b/code/.gitignore @@ -0,0 +1,111 @@ +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# ========================= +# Operating System Files +# ========================= + +# OSX +# ========================= + +.DS_Store +.AppleDouble +.LSOverride + +# Thumbnails +._* + +# Files that might appear on external disk +.Spotlight-V100 +.Trashes + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +*.class +*output.txt +Generated.txt +*-control.txt +*-results.txt +*-out.txt +OutputErrors.txt +report.txt +failures +People.xml +annotations/Test0.txt +annotations/Test1.txt +annotations/Test2.txt +io/*.out +io/*.txt +io/*.dat +io/*.tmp +io/test.zip +io/test.gz +io/X.file +*.pyc + +*.out +*.err +/files/bytes.dat +/files/test/ +/exceptions/Results.txt +/files/Cheese.txt +/files/StreamInAndOut.txt + +.gradle +/*.iml +/.idea/ + +/serialization/Blip3.serialized +/serialization/Blips.serialized + +build/ +buildSrc/ + +/compression/test.gz +/compression/test.zip +/iostreams/BasicFileOutput.dat +/iostreams/Data.txt +/iostreams/FileOutputShortcut.dat +/iostreams/rtest.dat +/logging/LogToFile.xml +/logging/LogToFile2.txt +/logging/MultipleHandlers.xml +/logging/MultipleHandlers2.xml +/logging/java0.log +/logging/java1.log +/logging/java2.log +/newio/TransferTo.txt +/newio/data2.txt +/newio/file.txt +/newio/test.dat +/newio/test.txt +/serialization/CADState.dat +/serialization/worm.dat +/serialization/Logon.dat +/serialization/X.file +/standardio/Redirecting.txt +/threads/PSP2.txt +/threads/primes.txt +_* +config.py diff --git a/code/.travisXX.yml b/code/.travisXX.yml new file mode 100644 index 00000000..54fee659 --- /dev/null +++ b/code/.travisXX.yml @@ -0,0 +1,8 @@ +language: java +jdk: + - oraclejdk11 +install: true +script: + - ./gradlew --no-daemon --stacktrace run +# - ./gradlew --parallel --stacktrace run +# - ./gradlew --parallel --stacktrace :validating:jmh diff --git a/code/CI.txt b/code/CI.txt new file mode 100644 index 00000000..524ee206 --- /dev/null +++ b/code/CI.txt @@ -0,0 +1,5 @@ +Links formerly in the README. Both of these mysteriously started breaking. + +[![](https://travis-ci.org/BruceEckel/OnJava8-Examples.svg?branch=master)](https://travis-ci.org/BruceEckel/OnJava8-Examples) + +[![](https://ci.appveyor.com/api/projects/status/github/BruceEckel/OnJava8-Examples)](https://ci.appveyor.com/project/BruceEckel/onjava-examples) diff --git a/code/Copyright.txt b/code/Copyright.txt new file mode 100644 index 00000000..f0d35035 --- /dev/null +++ b/code/Copyright.txt @@ -0,0 +1,72 @@ +// Copyright.txt +This computer source code is Copyright �2020 MindView LLC. +All Rights Reserved. + +Permission to use, copy, modify, and distribute this +computer source code (Source Code) and its documentation +without fee and without a written agreement for the +purposes set forth below is hereby granted, provided that +the above copyright notice, this paragraph and the +following five numbered paragraphs appear in all copies. + +1. Permission is granted to compile the Source Code and to +include the compiled code, in executable format only, in +personal and commercial software programs. + +2. Permission is granted to use the Source Code without +modification in classroom situations, including in +presentation materials, provided that the book "On +Java 8" is cited as the origin. + +3. Permission to incorporate the Source Code into printed +media may be obtained by contacting: + +MindView LLC, PO Box 969, Crested Butte, CO 81224 +MindViewInc@gmail.com + +4. The Source Code and documentation are copyrighted by +MindView LLC. The Source code is provided without express +or implied warranty of any kind, including any implied +warranty of merchantability, fitness for a particular +purpose or non-infringement. MindView LLC does not +warrant that the operation of any program that includes the +Source Code will be uninterrupted or error-free. MindView +LLC makes no representation about the suitability of the +Source Code or of any software that includes the Source +Code for any purpose. The entire risk as to the quality +and performance of any program that includes the Source +Code is with the user of the Source Code. The user +understands that the Source Code was developed for research +and instructional purposes and is advised not to rely +exclusively for any reason on the Source Code or any +program that includes the Source Code. Should the Source +Code or any resulting software prove defective, the user +assumes the cost of all necessary servicing, repair, or +correction. + +5. IN NO EVENT SHALL MINDVIEW LLC, OR ITS PUBLISHER BE +LIABLE TO ANY PARTY UNDER ANY LEGAL THEORY FOR DIRECT, +INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, +INCLUDING LOST PROFITS, BUSINESS INTERRUPTION, LOSS OF +BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS, OR FOR +PERSONAL INJURIES, ARISING OUT OF THE USE OF THIS SOURCE +CODE AND ITS DOCUMENTATION, OR ARISING OUT OF THE INABILITY +TO USE ANY RESULTING PROGRAM, EVEN IF MINDVIEW LLC, OR +ITS PUBLISHER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. MINDVIEW LLC SPECIFICALLY DISCLAIMS ANY +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE SOURCE CODE AND DOCUMENTATION PROVIDED +HEREUNDER IS ON AN "AS IS" BASIS, WITHOUT ANY ACCOMPANYING +SERVICES FROM MINDVIEW LLC, AND MINDVIEW LLC HAS NO +OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, +ENHANCEMENTS, OR MODIFICATIONS. + +Please note that MindView LLC maintains a Web site which +is the sole distribution point for electronic copies of the +Source Code, https://github.com/BruceEckel/OnJava8-examples, +where it is freely available under the terms stated above. + +If you think you've found an error in the Source Code, +please submit a correction at: +https://github.com/BruceEckel/OnJava8-examples/issues diff --git a/code/README.md b/code/README.md new file mode 100644 index 00000000..985dbbe4 --- /dev/null +++ b/code/README.md @@ -0,0 +1,43 @@ +# Example Source Code for the Book "On Java 8" by Bruce Eckel + +Download release from [here](https://github.com/BruceEckel/OnJava8-Examples/releases/tag/v1.0). + +To compile and run these programs, you only need JDK 8 installed. +Invoking `gradlew` will automatically download and install Gradle. +Gradle will also install all additional libraries necessary to compile +and run the Java examples in the book. + +To compile and run everything, the command is: + +`gradlew run` + +If you are on a Unix/Linux based system, you must select the local directory for all commands, for example: + +`./gradlew run` + +To only compile everything, the command is: + +`gradlew compileJava` + +To compile only a single chapter (including dependencies), use for example: + +`gradlew :strings:compileJava` + +To run only a single chapter, say: + +`gradlew :strings:run` + +Gradle can also be used to run a single program. Here, we run the **ReplacingStringTokenizer.java** +program in the **strings** chapter subdirectory: + +`gradlew :strings:ReplacingStringTokenizer` + +However, if the file name is unique throughout the book (the majority are), you can just give the +program name, like this: + +`gradlew ReplacingStringTokenizer` + +Note that all commands are run from the base directory where the example code is installed, and where you find the +`gradlew` script. + +You can learn about other options by just typing `gradlew` with no arguments. diff --git a/code/annotations/AUComposition.java b/code/annotations/AUComposition.java new file mode 100644 index 00000000..ee43e88d --- /dev/null +++ b/code/annotations/AUComposition.java @@ -0,0 +1,30 @@ +// annotations/AUComposition.java +// (c)2020 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. +// Creating non-embedded tests +// {java onjava.atunit.AtUnit +// build/classes/java/main/annotations/AUComposition.class} +package annotations; +import onjava.atunit.*; +import onjava.*; + +public class AUComposition { + AtUnitExample1 testObject = new AtUnitExample1(); + @Test + boolean tMethodOne() { + return testObject.methodOne() + .equals("This is methodOne"); + } + @Test + boolean tMethodTwo() { + return testObject.methodTwo() == 2; + } +} +/* Output: +annotations.AUComposition + . tMethodTwo This is methodTwo + + . tMethodOne +OK (2 tests) +*/ diff --git a/code/annotations/AUExternalTest.java b/code/annotations/AUExternalTest.java new file mode 100644 index 00000000..cce5c429 --- /dev/null +++ b/code/annotations/AUExternalTest.java @@ -0,0 +1,29 @@ +// annotations/AUExternalTest.java +// (c)2020 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. +// Creating non-embedded tests +// {java onjava.atunit.AtUnit +// build/classes/java/main/annotations/AUExternalTest.class} +package annotations; +import onjava.atunit.*; +import onjava.*; + +public class +AUExternalTest extends AtUnitExample1 { + @Test + boolean tMethodOne() { + return methodOne().equals("This is methodOne"); + } + @Test + boolean tMethodTwo() { + return methodTwo() == 2; + } +} +/* Output: +annotations.AUExternalTest + . tMethodOne + . tMethodTwo This is methodTwo + +OK (2 tests) +*/ diff --git a/code/annotations/AtUnitExample1.java b/code/annotations/AtUnitExample1.java new file mode 100644 index 00000000..3b1f6fec --- /dev/null +++ b/code/annotations/AtUnitExample1.java @@ -0,0 +1,48 @@ +// annotations/AtUnitExample1.java +// (c)2020 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. +// {java onjava.atunit.AtUnit +// build/classes/java/main/annotations/AtUnitExample1.class} +package annotations; +import onjava.atunit.*; +import onjava.*; + +public class AtUnitExample1 { + public String methodOne() { + return "This is methodOne"; + } + public int methodTwo() { + System.out.println("This is methodTwo"); + return 2; + } + @Test + boolean methodOneTest() { + return methodOne().equals("This is methodOne"); + } + @Test + boolean m2() { return methodTwo() == 2; } + @Test + private boolean m3() { return true; } + // Shows output for failure: + @Test + boolean failureTest() { return false; } + @Test + boolean anotherDisappointment() { + return false; + } +} +/* Output: +annotations.AtUnitExample1 + . m3 + . methodOneTest + . m2 This is methodTwo + + . failureTest (failed) + . anotherDisappointment (failed) +(5 tests) + +>>> 2 FAILURES <<< + annotations.AtUnitExample1: failureTest + annotations.AtUnitExample1: anotherDisappointment +*/ diff --git a/code/annotations/AtUnitExample2.java b/code/annotations/AtUnitExample2.java new file mode 100644 index 00000000..bf3f1d5c --- /dev/null +++ b/code/annotations/AtUnitExample2.java @@ -0,0 +1,57 @@ +// annotations/AtUnitExample2.java +// (c)2020 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. +// Assertions and exceptions can be used in @Tests +// {java onjava.atunit.AtUnit +// build/classes/java/main/annotations/AtUnitExample2.class} +package annotations; +import java.io.*; +import onjava.atunit.*; +import onjava.*; + +public class AtUnitExample2 { + public String methodOne() { + return "This is methodOne"; + } + public int methodTwo() { + System.out.println("This is methodTwo"); + return 2; + } + @Test + void assertExample() { + assert methodOne().equals("This is methodOne"); + } + @Test + void assertFailureExample() { + assert 1 == 2: "What a surprise!"; + } + @Test + void exceptionExample() throws IOException { + try(FileInputStream fis = + new FileInputStream("nofile.txt")) {} // Throws + } + @Test + boolean assertAndReturn() { + // Assertion with message: + assert methodTwo() == 2: "methodTwo must equal 2"; + return methodOne().equals("This is methodOne"); + } +} +/* Output: +annotations.AtUnitExample2 + . exceptionExample java.io.FileNotFoundException: +nofile.txt (The system cannot find the file specified) +(failed) + . assertExample + . assertAndReturn This is methodTwo + + . assertFailureExample java.lang.AssertionError: What +a surprise! +(failed) +(4 tests) + +>>> 2 FAILURES <<< + annotations.AtUnitExample2: exceptionExample + annotations.AtUnitExample2: assertFailureExample +*/ diff --git a/code/annotations/AtUnitExample3.java b/code/annotations/AtUnitExample3.java new file mode 100644 index 00000000..02092591 --- /dev/null +++ b/code/annotations/AtUnitExample3.java @@ -0,0 +1,42 @@ +// annotations/AtUnitExample3.java +// (c)2020 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. +// {java onjava.atunit.AtUnit +// build/classes/java/main/annotations/AtUnitExample3.class} +package annotations; +import onjava.atunit.*; +import onjava.*; + +public class AtUnitExample3 { + private int n; + public AtUnitExample3(int n) { this.n = n; } + public int getN() { return n; } + public String methodOne() { + return "This is methodOne"; + } + public int methodTwo() { + System.out.println("This is methodTwo"); + return 2; + } + @TestObjectCreate + static AtUnitExample3 create() { + return new AtUnitExample3(47); + } + @Test + boolean initialization() { return n == 47; } + @Test + boolean methodOneTest() { + return methodOne().equals("This is methodOne"); + } + @Test + boolean m2() { return methodTwo() == 2; } +} +/* Output: +annotations.AtUnitExample3 + . initialization + . m2 This is methodTwo + + . methodOneTest +OK (3 tests) +*/ diff --git a/code/annotations/AtUnitExample4.java b/code/annotations/AtUnitExample4.java new file mode 100644 index 00000000..6b644b17 --- /dev/null +++ b/code/annotations/AtUnitExample4.java @@ -0,0 +1,83 @@ +// annotations/AtUnitExample4.java +// (c)2020 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. +// {java onjava.atunit.AtUnit +// build/classes/java/main/annotations/AtUnitExample4.class} +// {VisuallyInspectOutput} +package annotations; +import java.util.*; +import onjava.atunit.*; +import onjava.*; + +public class AtUnitExample4 { + static String theory = "All brontosauruses " + + "are thin at one end, much MUCH thicker in the " + + "middle, and then thin again at the far end."; + private String word; + private Random rand = new Random(); // Time-based seed + public AtUnitExample4(String word) { + this.word = word; + } + public String getWord() { return word; } + public String scrambleWord() { + List chars = Arrays.asList( + ConvertTo.boxed(word.toCharArray())); + Collections.shuffle(chars, rand); + StringBuilder result = new StringBuilder(); + for(char ch : chars) + result.append(ch); + return result.toString(); + } + @TestProperty + static List input = + Arrays.asList(theory.split(" ")); + @TestProperty + static Iterator words = input.iterator(); + @TestObjectCreate + static AtUnitExample4 create() { + if(words.hasNext()) + return new AtUnitExample4(words.next()); + else + return null; + } + @Test + boolean words() { + System.out.println("'" + getWord() + "'"); + return getWord().equals("are"); + } + @Test + boolean scramble1() { + // Use specific seed to get verifiable results: + rand = new Random(47); + System.out.println("'" + getWord() + "'"); + String scrambled = scrambleWord(); + System.out.println(scrambled); + return scrambled.equals("lAl"); + } + @Test + boolean scramble2() { + rand = new Random(74); + System.out.println("'" + getWord() + "'"); + String scrambled = scrambleWord(); + System.out.println(scrambled); + return scrambled.equals("tsaeborornussu"); + } +} +/* Output: +annotations.AtUnitExample4 + . words 'All' +(failed) + . scramble1 'brontosauruses' +ntsaueorosurbs +(failed) + . scramble2 'are' +are +(failed) +(3 tests) + +>>> 3 FAILURES <<< + annotations.AtUnitExample4: words + annotations.AtUnitExample4: scramble1 + annotations.AtUnitExample4: scramble2 +*/ diff --git a/code/annotations/AtUnitExample5.java b/code/annotations/AtUnitExample5.java new file mode 100644 index 00000000..d7cf95df --- /dev/null +++ b/code/annotations/AtUnitExample5.java @@ -0,0 +1,63 @@ +// annotations/AtUnitExample5.java +// (c)2020 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. +// {java onjava.atunit.AtUnit +// build/classes/java/main/annotations/AtUnitExample5.class} +package annotations; +import java.io.*; +import onjava.atunit.*; +import onjava.*; + +public class AtUnitExample5 { + private String text; + public AtUnitExample5(String text) { + this.text = text; + } + @Override + public String toString() { return text; } + @TestProperty + static PrintWriter output; + @TestProperty + static int counter; + @TestObjectCreate + static AtUnitExample5 create() { + String id = Integer.toString(counter++); + try { + output = new PrintWriter("Test" + id + ".txt"); + } catch(IOException e) { + throw new RuntimeException(e); + } + return new AtUnitExample5(id); + } + @TestObjectCleanup + static void cleanup(AtUnitExample5 tobj) { + System.out.println("Running cleanup"); + output.close(); + } + @Test + boolean test1() { + output.print("test1"); + return true; + } + @Test + boolean test2() { + output.print("test2"); + return true; + } + @Test + boolean test3() { + output.print("test3"); + return true; + } +} +/* Output: +annotations.AtUnitExample5 + . test1 +Running cleanup + . test3 +Running cleanup + . test2 +Running cleanup +OK (3 tests) +*/ diff --git a/code/annotations/DemoProcessFiles.java b/code/annotations/DemoProcessFiles.java new file mode 100644 index 00000000..6e250537 --- /dev/null +++ b/code/annotations/DemoProcessFiles.java @@ -0,0 +1,43 @@ +// annotations/DemoProcessFiles.java +// (c)2020 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. +import onjava.ProcessFiles; + +public class DemoProcessFiles { + public static void main(String[] args) { + new ProcessFiles(file -> System.out.println(file), + "java").start(args); + } +} +/* Output: +.\AtUnitExample1.java +.\AtUnitExample2.java +.\AtUnitExample3.java +.\AtUnitExample4.java +.\AtUnitExample5.java +.\AUComposition.java +.\AUExternalTest.java +.\database\Constraints.java +.\database\DBTable.java +.\database\Member.java +.\database\SQLInteger.java +.\database\SQLString.java +.\database\TableCreator.java +.\database\Uniqueness.java +.\DemoProcessFiles.java +.\HashSetTest.java +.\ifx\ExtractInterface.java +.\ifx\IfaceExtractorProcessor.java +.\ifx\Multiplier.java +.\PasswordUtils.java +.\simplest\Simple.java +.\simplest\SimpleProcessor.java +.\simplest\SimpleTest.java +.\SimulatingNull.java +.\StackL.java +.\StackLStringTst.java +.\Testable.java +.\UseCase.java +.\UseCaseTracker.java +*/ diff --git a/code/annotations/HashSetTest.java b/code/annotations/HashSetTest.java new file mode 100644 index 00000000..8dfa8a9c --- /dev/null +++ b/code/annotations/HashSetTest.java @@ -0,0 +1,36 @@ +// annotations/HashSetTest.java +// (c)2020 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. +// {java onjava.atunit.AtUnit +// build/classes/java/main/annotations/HashSetTest.class} +package annotations; +import java.util.*; +import onjava.atunit.*; +import onjava.*; + +public class HashSetTest { + HashSet testObject = new HashSet<>(); + @Test + void initialization() { + assert testObject.isEmpty(); + } + @Test + void tContains() { + testObject.add("one"); + assert testObject.contains("one"); + } + @Test + void tRemove() { + testObject.add("one"); + testObject.remove("one"); + assert testObject.isEmpty(); + } +} +/* Output: +annotations.HashSetTest + . initialization + . tRemove + . tContains +OK (3 tests) +*/ diff --git a/code/annotations/PasswordUtils.java b/code/annotations/PasswordUtils.java new file mode 100644 index 00000000..74a6df78 --- /dev/null +++ b/code/annotations/PasswordUtils.java @@ -0,0 +1,24 @@ +// annotations/PasswordUtils.java +// (c)2020 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. +import java.util.*; + +public class PasswordUtils { + @UseCase(id = 47, description = + "Passwords must contain at least one numeric") + public boolean validatePassword(String passwd) { + return (passwd.matches("\\w*\\d\\w*")); + } + @UseCase(id = 48) + public String encryptPassword(String passwd) { + return new StringBuilder(passwd) + .reverse().toString(); + } + @UseCase(id = 49, description = + "New passwords can't equal previously used ones") + public boolean checkForNewPassword( + List prevPasswords, String passwd) { + return !prevPasswords.contains(passwd); + } +} diff --git a/code/annotations/SimulatingNull.java b/code/annotations/SimulatingNull.java new file mode 100644 index 00000000..8166802b --- /dev/null +++ b/code/annotations/SimulatingNull.java @@ -0,0 +1,12 @@ +// annotations/SimulatingNull.java +// (c)2020 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. +import java.lang.annotation.*; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface SimulatingNull { + int id() default -1; + String description() default ""; +} diff --git a/code/annotations/StackL.java b/code/annotations/StackL.java new file mode 100644 index 00000000..6ff806af --- /dev/null +++ b/code/annotations/StackL.java @@ -0,0 +1,14 @@ +// annotations/StackL.java +// (c)2020 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. +// A stack built on a LinkedList +package annotations; +import java.util.*; + +public class StackL { + private LinkedList list = new LinkedList<>(); + public void push(T v) { list.addFirst(v); } + public T top() { return list.getFirst(); } + public T pop() { return list.removeFirst(); } +} diff --git a/code/annotations/StackLStringTst.java b/code/annotations/StackLStringTst.java new file mode 100644 index 00000000..49aef9b7 --- /dev/null +++ b/code/annotations/StackLStringTst.java @@ -0,0 +1,42 @@ +// annotations/StackLStringTst.java +// (c)2020 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. +// Applying @Unit to generics +// {java onjava.atunit.AtUnit +// build/classes/java/main/annotations/StackLStringTst.class} +package annotations; +import onjava.atunit.*; +import onjava.*; + +public class +StackLStringTst extends StackL { + @Test + void tPush() { + push("one"); + assert top().equals("one"); + push("two"); + assert top().equals("two"); + } + @Test + void tPop() { + push("one"); + push("two"); + assert pop().equals("two"); + assert pop().equals("one"); + } + @Test + void tTop() { + push("A"); + push("B"); + assert top().equals("B"); + assert top().equals("B"); + } +} +/* Output: +annotations.StackLStringTst + . tTop + . tPush + . tPop +OK (3 tests) +*/ diff --git a/code/annotations/Testable.java b/code/annotations/Testable.java new file mode 100644 index 00000000..bc48f416 --- /dev/null +++ b/code/annotations/Testable.java @@ -0,0 +1,14 @@ +// annotations/Testable.java +// (c)2020 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 annotations; +import onjava.atunit.*; + +public class Testable { + public void execute() { + System.out.println("Executing.."); + } + @Test + void testExecute() { execute(); } +} diff --git a/code/annotations/UseCase.java b/code/annotations/UseCase.java new file mode 100644 index 00000000..dfce3149 --- /dev/null +++ b/code/annotations/UseCase.java @@ -0,0 +1,12 @@ +// annotations/UseCase.java +// (c)2020 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. +import java.lang.annotation.*; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface UseCase { + int id(); + String description() default "no description"; +} diff --git a/code/annotations/UseCaseTracker.java b/code/annotations/UseCaseTracker.java new file mode 100644 index 00000000..5489b762 --- /dev/null +++ b/code/annotations/UseCaseTracker.java @@ -0,0 +1,37 @@ +// annotations/UseCaseTracker.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import java.lang.reflect.*; + +public class UseCaseTracker { + public static void + trackUseCases(List useCases, Class cl) { + for(Method m : cl.getDeclaredMethods()) { + UseCase uc = m.getAnnotation(UseCase.class); + if(uc != null) { + System.out.println("Found Use Case " + + uc.id() + "\n " + uc.description()); + useCases.remove(Integer.valueOf(uc.id())); + } + } + useCases.forEach(i -> + System.out.println("Missing use case " + i)); + } + public static void main(String[] args) { + List useCases = IntStream.range(47, 51) + .boxed().collect(Collectors.toList()); + trackUseCases(useCases, PasswordUtils.class); + } +} +/* Output: +Found Use Case 48 + no description +Found Use Case 47 + Passwords must contain at least one numeric +Found Use Case 49 + New passwords can't equal previously used ones +Missing use case 50 +*/ diff --git a/code/annotations/database/Constraints.java b/code/annotations/database/Constraints.java new file mode 100644 index 00000000..4e4e40fc --- /dev/null +++ b/code/annotations/database/Constraints.java @@ -0,0 +1,14 @@ +// annotations/database/Constraints.java +// (c)2020 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 annotations.database; +import java.lang.annotation.*; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Constraints { + boolean primaryKey() default false; + boolean allowNull() default true; + boolean unique() default false; +} diff --git a/code/annotations/database/DBTable.java b/code/annotations/database/DBTable.java new file mode 100644 index 00000000..9aa5562f --- /dev/null +++ b/code/annotations/database/DBTable.java @@ -0,0 +1,12 @@ +// annotations/database/DBTable.java +// (c)2020 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 annotations.database; +import java.lang.annotation.*; + +@Target(ElementType.TYPE) // Applies to classes only +@Retention(RetentionPolicy.RUNTIME) +public @interface DBTable { + String name() default ""; +} diff --git a/code/annotations/database/Member.java b/code/annotations/database/Member.java new file mode 100644 index 00000000..d722a3b1 --- /dev/null +++ b/code/annotations/database/Member.java @@ -0,0 +1,22 @@ +// annotations/database/Member.java +// (c)2020 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 annotations.database; + +@DBTable(name = "MEMBER") +public class Member { + @SQLString(30) String firstName; + @SQLString(50) String lastName; + @SQLInteger Integer age; + @SQLString(value = 30, + constraints = @Constraints(primaryKey = true)) + String reference; + static int memberCount; + public String getReference() { return reference; } + public String getFirstName() { return firstName; } + public String getLastName() { return lastName; } + @Override + public String toString() { return reference; } + public Integer getAge() { return age; } +} diff --git a/code/annotations/database/SQLInteger.java b/code/annotations/database/SQLInteger.java new file mode 100644 index 00000000..635a907c --- /dev/null +++ b/code/annotations/database/SQLInteger.java @@ -0,0 +1,13 @@ +// annotations/database/SQLInteger.java +// (c)2020 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 annotations.database; +import java.lang.annotation.*; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface SQLInteger { + String name() default ""; + Constraints constraints() default @Constraints; +} diff --git a/code/annotations/database/SQLString.java b/code/annotations/database/SQLString.java new file mode 100644 index 00000000..dac9919f --- /dev/null +++ b/code/annotations/database/SQLString.java @@ -0,0 +1,14 @@ +// annotations/database/SQLString.java +// (c)2020 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 annotations.database; +import java.lang.annotation.*; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface SQLString { + int value() default 0; + String name() default ""; + Constraints constraints() default @Constraints; +} diff --git a/code/annotations/database/TableCreator.java b/code/annotations/database/TableCreator.java new file mode 100644 index 00000000..53322fc7 --- /dev/null +++ b/code/annotations/database/TableCreator.java @@ -0,0 +1,106 @@ +// annotations/database/TableCreator.java +// (c)2020 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. +// Reflection-based annotation processor +// {java annotations.database.TableCreator +// annotations.database.Member} +package annotations.database; +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.util.*; + +public class TableCreator { + public static void + main(String[] args) throws Exception { + if(args.length < 1) { + System.out.println( + "arguments: annotated classes"); + System.exit(0); + } + for(String className : args) { + Class cl = Class.forName(className); + DBTable dbTable = cl.getAnnotation(DBTable.class); + if(dbTable == null) { + System.out.println( + "No DBTable annotations in class " + + className); + continue; + } + String tableName = dbTable.name(); + // If the name is empty, use the Class name: + if(tableName.length() < 1) + tableName = cl.getName().toUpperCase(); + List columnDefs = new ArrayList<>(); + for(Field field : cl.getDeclaredFields()) { + String columnName = null; + Annotation[] anns = + field.getDeclaredAnnotations(); + if(anns.length < 1) + continue; // Not a db table column + if(anns[0] instanceof SQLInteger) { + SQLInteger sInt = (SQLInteger) anns[0]; + // Use field name if name not specified + if(sInt.name().length() < 1) + columnName = field.getName().toUpperCase(); + else + columnName = sInt.name(); + columnDefs.add(columnName + " INT" + + getConstraints(sInt.constraints())); + } + if(anns[0] instanceof SQLString) { + SQLString sString = (SQLString) anns[0]; + // Use field name if name not specified. + if(sString.name().length() < 1) + columnName = field.getName().toUpperCase(); + else + columnName = sString.name(); + columnDefs.add(columnName + " VARCHAR(" + + sString.value() + ")" + + getConstraints(sString.constraints())); + } + StringBuilder createCommand = new StringBuilder( + "CREATE TABLE " + tableName + "("); + for(String columnDef : columnDefs) + createCommand.append( + "\n " + columnDef + ","); + // Remove trailing comma + String tableCreate = createCommand.substring( + 0, createCommand.length() - 1) + ");"; + System.out.println("Table Creation SQL for " + + className + " is:\n" + tableCreate); + } + } + } + private static + String getConstraints(Constraints con) { + String constraints = ""; + if(!con.allowNull()) + constraints += " NOT NULL"; + if(con.primaryKey()) + constraints += " PRIMARY KEY"; + if(con.unique()) + constraints += " UNIQUE"; + return constraints; + } +} +/* Output: +Table Creation SQL for annotations.database.Member is: +CREATE TABLE MEMBER( + FIRSTNAME VARCHAR(30)); +Table Creation SQL for annotations.database.Member is: +CREATE TABLE MEMBER( + FIRSTNAME VARCHAR(30), + LASTNAME VARCHAR(50)); +Table Creation SQL for annotations.database.Member is: +CREATE TABLE MEMBER( + FIRSTNAME VARCHAR(30), + LASTNAME VARCHAR(50), + AGE INT); +Table Creation SQL for annotations.database.Member is: +CREATE TABLE MEMBER( + FIRSTNAME VARCHAR(30), + LASTNAME VARCHAR(50), + AGE INT, + REFERENCE VARCHAR(30) PRIMARY KEY); +*/ diff --git a/code/annotations/database/Uniqueness.java b/code/annotations/database/Uniqueness.java new file mode 100644 index 00000000..1aa1a36c --- /dev/null +++ b/code/annotations/database/Uniqueness.java @@ -0,0 +1,11 @@ +// annotations/database/Uniqueness.java +// (c)2020 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. +// Sample of nested annotations +package annotations.database; + +public @interface Uniqueness { + Constraints constraints() + default @Constraints(unique = true); +} diff --git a/code/annotations/ifx/ExtractInterface.java b/code/annotations/ifx/ExtractInterface.java new file mode 100644 index 00000000..70a94bf5 --- /dev/null +++ b/code/annotations/ifx/ExtractInterface.java @@ -0,0 +1,13 @@ +// annotations/ifx/ExtractInterface.java +// (c)2020 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. +// javac-based annotation processing +package annotations.ifx; +import java.lang.annotation.*; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.SOURCE) +public @interface ExtractInterface { + String interfaceName() default "-!!-"; +} diff --git a/code/annotations/ifx/IfaceExtractorProcessor.java b/code/annotations/ifx/IfaceExtractorProcessor.java new file mode 100644 index 00000000..d17156f8 --- /dev/null +++ b/code/annotations/ifx/IfaceExtractorProcessor.java @@ -0,0 +1,91 @@ +// annotations/ifx/IfaceExtractorProcessor.java +// (c)2020 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. +// javac-based annotation processing +package annotations.ifx; +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.*; +import javax.lang.model.util.*; +import java.util.*; +import java.util.stream.*; +import java.io.*; + +@SupportedAnnotationTypes( + "annotations.ifx.ExtractInterface") +@SupportedSourceVersion(SourceVersion.RELEASE_8) +public class IfaceExtractorProcessor +extends AbstractProcessor { + private ArrayList + interfaceMethods = new ArrayList<>(); + Elements elementUtils; + private ProcessingEnvironment processingEnv; + @Override + public void init( + ProcessingEnvironment processingEnv) { + this.processingEnv = processingEnv; + elementUtils = processingEnv.getElementUtils(); + } + @Override + public boolean process( + Set annotations, + RoundEnvironment env) { + for(Element elem:env.getElementsAnnotatedWith( + ExtractInterface.class)) { + String interfaceName = elem.getAnnotation( + ExtractInterface.class).interfaceName(); + for(Element enclosed : + elem.getEnclosedElements()) { + if(enclosed.getKind() + .equals(ElementKind.METHOD) && + enclosed.getModifiers() + .contains(Modifier.PUBLIC) && + !enclosed.getModifiers() + .contains(Modifier.STATIC)) { + interfaceMethods.add(enclosed); + } + } + if(interfaceMethods.size() > 0) + writeInterfaceFile(interfaceName); + } + return false; + } + private void + writeInterfaceFile(String interfaceName) { + try( + Writer writer = processingEnv.getFiler() + .createSourceFile(interfaceName) + .openWriter() + ) { + String packageName = elementUtils + .getPackageOf(interfaceMethods + .get(0)).toString(); + writer.write( + "package " + packageName + ";\n"); + writer.write("public interface " + + interfaceName + " {\n"); + for(Element elem : interfaceMethods) { + ExecutableElement method = + (ExecutableElement)elem; + String signature = " public "; + signature += method.getReturnType() + " "; + signature += method.getSimpleName(); + signature += createArgList( + method.getParameters()); + System.out.println(signature); + writer.write(signature + ";\n"); + } + writer.write("}"); + } catch(Exception e) { + throw new RuntimeException(e); + } + } + private String createArgList( + List parameters) { + String args = parameters.stream() + .map(p -> p.asType() + " " + p.getSimpleName()) + .collect(Collectors.joining(", ")); + return "(" + args + ")"; + } +} diff --git a/code/annotations/ifx/Multiplier.java b/code/annotations/ifx/Multiplier.java new file mode 100644 index 00000000..b5b99a1b --- /dev/null +++ b/code/annotations/ifx/Multiplier.java @@ -0,0 +1,34 @@ +// annotations/ifx/Multiplier.java +// (c)2020 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. +// javac-based annotation processing +// {java annotations.ifx.Multiplier} +package annotations.ifx; + +@ExtractInterface(interfaceName="IMultiplier") +public class Multiplier { + public boolean flag = false; + private int n = 0; + public int multiply(int x, int y) { + int total = 0; + for(int i = 0; i < x; i++) + total = add(total, y); + return total; + } + public int fortySeven() { return 47; } + private int add(int x, int y) { + return x + y; + } + public double timesTen(double arg) { + return arg * 10; + } + public static void main(String[] args) { + Multiplier m = new Multiplier(); + System.out.println( + "11 * 16 = " + m.multiply(11, 16)); + } +} +/* Output: +11 * 16 = 176 +*/ diff --git a/code/annotations/simplest/Simple.java b/code/annotations/simplest/Simple.java new file mode 100644 index 00000000..0dc555ce --- /dev/null +++ b/code/annotations/simplest/Simple.java @@ -0,0 +1,20 @@ +// annotations/simplest/Simple.java +// (c)2020 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. +// A bare-bones annotation +package annotations.simplest; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +@Retention(RetentionPolicy.SOURCE) +@Target({ElementType.TYPE, ElementType.METHOD, + ElementType.CONSTRUCTOR, + ElementType.ANNOTATION_TYPE, + ElementType.PACKAGE, ElementType.FIELD, + ElementType.LOCAL_VARIABLE}) +public @interface Simple { + String value() default "-default-"; +} diff --git a/code/annotations/simplest/SimpleProcessor.java b/code/annotations/simplest/SimpleProcessor.java new file mode 100644 index 00000000..a85d8987 --- /dev/null +++ b/code/annotations/simplest/SimpleProcessor.java @@ -0,0 +1,47 @@ +// annotations/simplest/SimpleProcessor.java +// (c)2020 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. +// A bare-bones annotation processor +package annotations.simplest; +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.*; +import java.util.*; + +@SupportedAnnotationTypes( + "annotations.simplest.Simple") +@SupportedSourceVersion(SourceVersion.RELEASE_8) +public class SimpleProcessor +extends AbstractProcessor { + @Override + public boolean process( + Set annotations, + RoundEnvironment env) { + for(TypeElement t : annotations) + System.out.println(t); + for(Element el : + env.getElementsAnnotatedWith(Simple.class)) + display(el); + return false; + } + private void display(Element el) { + System.out.println("==== " + el + " ===="); + System.out.println(el.getKind() + + " : " + el.getModifiers() + + " : " + el.getSimpleName() + + " : " + el.asType()); + if(el.getKind().equals(ElementKind.CLASS)) { + TypeElement te = (TypeElement)el; + System.out.println(te.getQualifiedName()); + System.out.println(te.getSuperclass()); + System.out.println(te.getEnclosedElements()); + } + if(el.getKind().equals(ElementKind.METHOD)) { + ExecutableElement ex = (ExecutableElement)el; + System.out.print(ex.getReturnType() + " "); + System.out.print(ex.getSimpleName() + "("); + System.out.println(ex.getParameters() + ")"); + } + } +} diff --git a/code/annotations/simplest/SimpleTest.java b/code/annotations/simplest/SimpleTest.java new file mode 100644 index 00000000..689d12fd --- /dev/null +++ b/code/annotations/simplest/SimpleTest.java @@ -0,0 +1,32 @@ +// annotations/simplest/SimpleTest.java +// (c)2020 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. +// Test the "Simple" annotation +// {java annotations.simplest.SimpleTest} +package annotations.simplest; + +@Simple +public class SimpleTest { + @Simple + int i; + @Simple + public SimpleTest() {} + @Simple + public void foo() { + System.out.println("SimpleTest.foo()"); + } + @Simple + public void bar(String s, int i, float f) { + System.out.println("SimpleTest.bar()"); + } + @Simple + public static void main(String[] args) { + @Simple + SimpleTest st = new SimpleTest(); + st.foo(); + } +} +/* Output: +SimpleTest.foo() +*/ diff --git a/code/appveyorXX.yml b/code/appveyorXX.yml new file mode 100644 index 00000000..5e586b07 --- /dev/null +++ b/code/appveyorXX.yml @@ -0,0 +1,4 @@ +build_script: + - gradlew.bat --no-daemon --stacktrace run + +test: off diff --git a/code/arrays/AlphabeticSearch.java b/code/arrays/AlphabeticSearch.java new file mode 100644 index 00000000..70adc8ff --- /dev/null +++ b/code/arrays/AlphabeticSearch.java @@ -0,0 +1,29 @@ +// arrays/AlphabeticSearch.java +// (c)2020 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. +// Searching with a Comparator import +import java.util.*; +import onjava.*; +import static onjava.ArrayShow.*; + +public class AlphabeticSearch { + public static void main(String[] args) { + String[] sa = new Rand.String().array(30); + Arrays.sort(sa, String.CASE_INSENSITIVE_ORDER); + show(sa); + int index = Arrays.binarySearch(sa, + sa[10], String.CASE_INSENSITIVE_ORDER); + System.out.println( + "Index: "+ index + "\n"+ sa[index]); + } +} +/* Output: +[anmkkyh, bhmupju, btpenpc, cjwzmmr, cuxszgv, eloztdv, +ewcippc, ezdeklu, fcjpthl, fqmlgsh, gmeinne, hyoubzl, +jbvlgwc, jlxpqds, ljlbynx, mvducuj, qgekgly, skddcat, +taprwxz, uybypgp, vjsszkn, vniyapk, vqqakbm, vwodhcf, +ydpulcq, ygpoalk, yskvett, zehpfmm, zofmmvm, zrxmclh] +Index: 10 +gmeinne +*/ diff --git a/code/arrays/ArrayCopying.java b/code/arrays/ArrayCopying.java new file mode 100644 index 00000000..c68c2a0d --- /dev/null +++ b/code/arrays/ArrayCopying.java @@ -0,0 +1,81 @@ +// arrays/ArrayCopying.java +// (c)2020 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. +// Demonstrate Arrays.copy() and Arrays.copyOf() +import java.util.*; +import onjava.*; +import static onjava.ArrayShow.*; + +class Sup { // Superclass + private int id; + Sup(int n) { id = n; } + @Override + public String toString() { + return getClass().getSimpleName() + id; + } +} + +class Sub extends Sup { // Subclass + Sub(int n) { super(n); } +} + +public class ArrayCopying { + public static final int SZ = 15; + public static void main(String[] args) { + int[] a1 = new int[SZ]; + Arrays.setAll(a1, new Count.Integer()::get); + show("a1", a1); + int[] a2 = Arrays.copyOf(a1, a1.length); // [1] + // Prove they are distinct arrays: + Arrays.fill(a1, 1); + show("a1", a1); + show("a2", a2); + + // Create a shorter result: + a2 = Arrays.copyOf(a2, a2.length/2); // [2] + show("a2", a2); + // Allocate more space: + a2 = Arrays.copyOf(a2, a2.length + 5); + show("a2", a2); + + // Also copies wrapped arrays: + Integer[] a3 = new Integer[SZ]; // [3] + Arrays.setAll(a3, new Count.Integer()::get); + Integer[] a4 = Arrays.copyOfRange(a3, 4, 12); + show("a4", a4); + + Sub[] d = new Sub[SZ/2]; + Arrays.setAll(d, Sub::new); + // Produce Sup[] from Sub[]: + Sup[] b = + Arrays.copyOf(d, d.length, Sup[].class); // [4] + show(b); + + // This "downcast" works fine: + Sub[] d2 = + Arrays.copyOf(b, b.length, Sub[].class); // [5] + show(d2); + + // Bad "downcast" compiles but throws exception: + Sup[] b2 = new Sup[SZ/2]; + Arrays.setAll(b2, Sup::new); + try { + Sub[] d3 = Arrays.copyOf( + b2, b2.length, Sub[].class); // [6] + } catch(Exception e) { + System.out.println(e); + } + } +} +/* Output: +a1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] +a1: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] +a2: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] +a2: [0, 1, 2, 3, 4, 5, 6] +a2: [0, 1, 2, 3, 4, 5, 6, 0, 0, 0, 0, 0] +a4: [4, 5, 6, 7, 8, 9, 10, 11] +[Sub0, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6] +[Sub0, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6] +java.lang.ArrayStoreException +*/ diff --git a/code/arrays/ArrayOfGenericType.java b/code/arrays/ArrayOfGenericType.java new file mode 100644 index 00000000..68f9e8de --- /dev/null +++ b/code/arrays/ArrayOfGenericType.java @@ -0,0 +1,16 @@ +// arrays/ArrayOfGenericType.java +// (c)2020 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. + +public class ArrayOfGenericType { + T[] array; // OK + @SuppressWarnings("unchecked") + public ArrayOfGenericType(int size) { + // error: generic array creation: + //- array = new T[size]; + array = (T[])new Object[size]; // unchecked cast + } + // error: generic array creation: + //- public U[] makeArray() { return new U[10]; } +} diff --git a/code/arrays/ArrayOfGenerics.java b/code/arrays/ArrayOfGenerics.java new file mode 100644 index 00000000..79971d7a --- /dev/null +++ b/code/arrays/ArrayOfGenerics.java @@ -0,0 +1,33 @@ +// arrays/ArrayOfGenerics.java +// (c)2020 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. +import java.util.*; + +public class ArrayOfGenerics { + @SuppressWarnings("unchecked") + public static void main(String[] args) { + List[] ls; + List[] la = new List[10]; + ls = (List[])la; // Unchecked cast + ls[0] = new ArrayList<>(); + + //- ls[1] = new ArrayList(); + // error: incompatible types: ArrayList + // cannot be converted to List + // ls[1] = new ArrayList(); + // ^ + + // The problem: List is a subtype of Object + Object[] objects = ls; // So assignment is OK + // Compiles and runs without complaint: + objects[1] = new ArrayList<>(); + + // However, if your needs are straightforward it is + // possible to create an array of generics, albeit + // with an "unchecked cast" warning: + List[] spheres = + (List[])new List[10]; + Arrays.setAll(spheres, n -> new ArrayList<>()); + } +} diff --git a/code/arrays/ArrayOptions.java b/code/arrays/ArrayOptions.java new file mode 100644 index 00000000..bb6cbfbb --- /dev/null +++ b/code/arrays/ArrayOptions.java @@ -0,0 +1,79 @@ +// arrays/ArrayOptions.java +// (c)2020 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. +// Initialization & re-assignment of arrays +import java.util.*; +import static onjava.ArrayShow.*; + +public class ArrayOptions { + public static void main(String[] args) { + // Arrays of objects: + BerylliumSphere[] a; // Uninitialized local + BerylliumSphere[] b = new BerylliumSphere[5]; + + // The references inside the array are + // automatically initialized to null: + show("b", b); + BerylliumSphere[] c = new BerylliumSphere[4]; + for(int i = 0; i < c.length; i++) + if(c[i] == null) // Can test for null reference + c[i] = new BerylliumSphere(); + + // Aggregate initialization: + BerylliumSphere[] d = { + new BerylliumSphere(), + new BerylliumSphere(), + new BerylliumSphere() + }; + + // Dynamic aggregate initialization: + a = new BerylliumSphere[]{ + new BerylliumSphere(), new BerylliumSphere(), + }; + // (Trailing comma is optional) + + System.out.println("a.length = " + a.length); + System.out.println("b.length = " + b.length); + System.out.println("c.length = " + c.length); + System.out.println("d.length = " + d.length); + a = d; + System.out.println("a.length = " + a.length); + + // Arrays of primitives: + int[] e; // Null reference + int[] f = new int[5]; + + // The primitives inside the array are + // automatically initialized to zero: + show("f", f); + int[] g = new int[4]; + for(int i = 0; i < g.length; i++) + g[i] = i*i; + int[] h = { 11, 47, 93 }; + + // Compile error: variable e not initialized: + //- System.out.println("e.length = " + e.length); + System.out.println("f.length = " + f.length); + System.out.println("g.length = " + g.length); + System.out.println("h.length = " + h.length); + e = h; + System.out.println("e.length = " + e.length); + e = new int[]{ 1, 2 }; + System.out.println("e.length = " + e.length); + } +} +/* Output: +b: [null, null, null, null, null] +a.length = 2 +b.length = 5 +c.length = 4 +d.length = 3 +a.length = 3 +f: [0, 0, 0, 0, 0] +f.length = 5 +g.length = 4 +h.length = 3 +e.length = 3 +e.length = 2 +*/ diff --git a/code/arrays/ArraySearching.java b/code/arrays/ArraySearching.java new file mode 100644 index 00000000..fb4085e9 --- /dev/null +++ b/code/arrays/ArraySearching.java @@ -0,0 +1,33 @@ +// arrays/ArraySearching.java +// (c)2020 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. +// Using Arrays.binarySearch() +import java.util.*; +import onjava.*; +import static onjava.ArrayShow.*; + +public class ArraySearching { + public static void main(String[] args) { + Rand.Pint rand = new Rand.Pint(); + int[] a = new Rand.Pint().array(25); + Arrays.sort(a); + show("Sorted array", a); + while(true) { + int r = rand.getAsInt(); + int location = Arrays.binarySearch(a, r); + if(location >= 0) { + System.out.println( + "Location of " + r + " is " + location + + ", a[" + location + "] is " + a[location]); + break; // Out of while loop + } + } + } +} +/* Output: +Sorted array: [125, 267, 635, 650, 1131, 1506, 1634, +2400, 2766, 3063, 3768, 3941, 4720, 4762, 4948, 5070, +5682, 5807, 6177, 6193, 6656, 7021, 8479, 8737, 9954] +Location of 635 is 2, a[2] is 635 +*/ diff --git a/code/arrays/AssemblingMultidimensionalArrays.java b/code/arrays/AssemblingMultidimensionalArrays.java new file mode 100644 index 00000000..e79302b3 --- /dev/null +++ b/code/arrays/AssemblingMultidimensionalArrays.java @@ -0,0 +1,22 @@ +// arrays/AssemblingMultidimensionalArrays.java +// (c)2020 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. +// Creating multidimensional arrays +import java.util.*; + +public class AssemblingMultidimensionalArrays { + public static void main(String[] args) { + Integer[][] a; + a = new Integer[3][]; + for(int i = 0; i < a.length; i++) { + a[i] = new Integer[3]; + for(int j = 0; j < a[i].length; j++) + a[i][j] = i * j; // Autoboxing + } + System.out.println(Arrays.deepToString(a)); + } +} +/* Output: +[[0, 0, 0], [0, 1, 2], [0, 2, 4]] +*/ diff --git a/code/arrays/AutoboxingArrays.java b/code/arrays/AutoboxingArrays.java new file mode 100644 index 00000000..25b3a0e8 --- /dev/null +++ b/code/arrays/AutoboxingArrays.java @@ -0,0 +1,22 @@ +// arrays/AutoboxingArrays.java +// (c)2020 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. +import java.util.*; + +public class AutoboxingArrays { + public static void main(String[] args) { + Integer[][] a = { // Autoboxing: + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, + { 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }, + { 51, 52, 53, 54, 55, 56, 57, 58, 59, 60 }, + { 71, 72, 73, 74, 75, 76, 77, 78, 79, 80 }, + }; + System.out.println(Arrays.deepToString(a)); + } +} +/* Output: +[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [21, 22, 23, 24, 25, +26, 27, 28, 29, 30], [51, 52, 53, 54, 55, 56, 57, 58, +59, 60], [71, 72, 73, 74, 75, 76, 77, 78, 79, 80]] +*/ diff --git a/code/arrays/CollectionComparison.java b/code/arrays/CollectionComparison.java new file mode 100644 index 00000000..fc703c0a --- /dev/null +++ b/code/arrays/CollectionComparison.java @@ -0,0 +1,53 @@ +// arrays/CollectionComparison.java +// (c)2020 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. +import java.util.*; +import onjava.*; +import static onjava.ArrayShow.*; + +class BerylliumSphere { + private static long counter; + private final long id = counter++; + @Override + public String toString() { + return "Sphere " + id; + } +} + +public class CollectionComparison { + public static void main(String[] args) { + BerylliumSphere[] spheres = + new BerylliumSphere[10]; + for(int i = 0; i < 5; i++) + spheres[i] = new BerylliumSphere(); + show(spheres); + System.out.println(spheres[4]); + + List sphereList = Suppliers.create( + ArrayList::new, BerylliumSphere::new, 5); + System.out.println(sphereList); + System.out.println(sphereList.get(4)); + + int[] integers = { 0, 1, 2, 3, 4, 5 }; + show(integers); + System.out.println(integers[4]); + + List intList = new ArrayList<>( + Arrays.asList(0, 1, 2, 3, 4, 5)); + intList.add(97); + System.out.println(intList); + System.out.println(intList.get(4)); + } +} +/* Output: +[Sphere 0, Sphere 1, Sphere 2, Sphere 3, Sphere 4, +null, null, null, null, null] +Sphere 4 +[Sphere 5, Sphere 6, Sphere 7, Sphere 8, Sphere 9] +Sphere 9 +[0, 1, 2, 3, 4, 5] +4 +[0, 1, 2, 3, 4, 5, 97] +4 +*/ diff --git a/code/arrays/CompType.java b/code/arrays/CompType.java new file mode 100644 index 00000000..621b33d1 --- /dev/null +++ b/code/arrays/CompType.java @@ -0,0 +1,56 @@ +// arrays/CompType.java +// (c)2020 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. +// Implementing Comparable in a class +import java.util.*; +import java.util.function.*; +import onjava.*; +import static onjava.ArrayShow.*; + +public class CompType implements Comparable { + int i; + int j; + private static int count = 1; + public CompType(int n1, int n2) { + i = n1; + j = n2; + } + @Override + public String toString() { + String result = "[i = " + i + ", j = " + j + "]"; + if(count++ % 3 == 0) + result += "\n"; + return result; + } + @Override + public int compareTo(CompType rv) { + return (i < rv.i ? -1 : (i == rv.i ? 0 : 1)); + } + private static SplittableRandom r = + new SplittableRandom(47); + public static CompType get() { + return new CompType(r.nextInt(100), r.nextInt(100)); + } + public static void main(String[] args) { + CompType[] a = new CompType[12]; + Arrays.setAll(a, n -> get()); + show("Before sorting", a); + Arrays.sort(a); + show("After sorting", a); + } +} +/* Output: +Before sorting: [[i = 35, j = 37], [i = 41, j = 20], [i += 77, j = 79] +, [i = 56, j = 68], [i = 48, j = 93], [i = 70, j = 7] +, [i = 0, j = 25], [i = 62, j = 34], [i = 50, j = 82] +, [i = 31, j = 67], [i = 66, j = 54], [i = 21, j = 6] +] +After sorting: [[i = 0, j = 25], [i = 21, j = 6], [i = +31, j = 67] +, [i = 35, j = 37], [i = 41, j = 20], [i = 48, j = 93] +, [i = 50, j = 82], [i = 56, j = 68], [i = 62, j = 34] +, [i = 66, j = 54], [i = 70, j = 7], [i = 77, j = 79] +] +*/ diff --git a/code/arrays/ComparatorTest.java b/code/arrays/ComparatorTest.java new file mode 100644 index 00000000..68f7e380 --- /dev/null +++ b/code/arrays/ComparatorTest.java @@ -0,0 +1,39 @@ +// arrays/ComparatorTest.java +// (c)2020 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. +// Implementing a Comparator for a class +import java.util.*; +import onjava.*; +import static onjava.ArrayShow.*; + +class CompTypeComparator +implements Comparator { + public int compare(CompType o1, CompType o2) { + return (o1.j < o2.j ? -1 : (o1.j == o2.j ? 0 : 1)); + } +} + +public class ComparatorTest { + public static void main(String[] args) { + CompType[] a = new CompType[12]; + Arrays.setAll(a, n -> CompType.get()); + show("Before sorting", a); + Arrays.sort(a, new CompTypeComparator()); + show("After sorting", a); + } +} +/* Output: +Before sorting: [[i = 35, j = 37], [i = 41, j = 20], [i += 77, j = 79] +, [i = 56, j = 68], [i = 48, j = 93], [i = 70, j = 7] +, [i = 0, j = 25], [i = 62, j = 34], [i = 50, j = 82] +, [i = 31, j = 67], [i = 66, j = 54], [i = 21, j = 6] +] +After sorting: [[i = 21, j = 6], [i = 70, j = 7], [i = +41, j = 20] +, [i = 0, j = 25], [i = 62, j = 34], [i = 35, j = 37] +, [i = 66, j = 54], [i = 31, j = 67], [i = 56, j = 68] +, [i = 77, j = 79], [i = 50, j = 82], [i = 48, j = 93] +] +*/ diff --git a/code/arrays/ComparingArrays.java b/code/arrays/ComparingArrays.java new file mode 100644 index 00000000..9ddad69d --- /dev/null +++ b/code/arrays/ComparingArrays.java @@ -0,0 +1,62 @@ +// arrays/ComparingArrays.java +// (c)2020 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. +// Using Arrays.equals() +import java.util.*; +import onjava.*; + +public class ComparingArrays { + public static final int SZ = 15; + static String[][] twoDArray() { + String[][] md = new String[5][]; + Arrays.setAll(md, n -> new String[n]); + for(int i = 0; i < md.length; i++) + Arrays.setAll(md[i], new Rand.String()::get); + return md; + } + public static void main(String[] args) { + int[] a1 = new int[SZ], a2 = new int[SZ]; + Arrays.setAll(a1, new Count.Integer()::get); + Arrays.setAll(a2, new Count.Integer()::get); + System.out.println( + "a1 == a2: " + Arrays.equals(a1, a2)); + a2[3] = 11; + System.out.println( + "a1 == a2: " + Arrays.equals(a1, a2)); + + Integer[] a1w = new Integer[SZ], + a2w = new Integer[SZ]; + Arrays.setAll(a1w, new Count.Integer()::get); + Arrays.setAll(a2w, new Count.Integer()::get); + System.out.println( + "a1w == a2w: " + Arrays.equals(a1w, a2w)); + a2w[3] = 11; + System.out.println( + "a1w == a2w: " + Arrays.equals(a1w, a2w)); + + String[][] md1 = twoDArray(), md2 = twoDArray(); + System.out.println(Arrays.deepToString(md1)); + System.out.println("deepEquals(md1, md2): " + + Arrays.deepEquals(md1, md2)); + System.out.println( + "md1 == md2: " + Arrays.equals(md1, md2)); + md1[4][1] = "#$#$#$#"; + System.out.println(Arrays.deepToString(md1)); + System.out.println("deepEquals(md1, md2): " + + Arrays.deepEquals(md1, md2)); + } +} +/* Output: +a1 == a2: true +a1 == a2: false +a1w == a2w: true +a1w == a2w: false +[[], [btpenpc], [btpenpc, cuxszgv], [btpenpc, cuxszgv, +gmeinne], [btpenpc, cuxszgv, gmeinne, eloztdv]] +deepEquals(md1, md2): true +md1 == md2: false +[[], [btpenpc], [btpenpc, cuxszgv], [btpenpc, cuxszgv, +gmeinne], [btpenpc, #$#$#$#, gmeinne, eloztdv]] +deepEquals(md1, md2): false +*/ diff --git a/code/arrays/CountUpward.java b/code/arrays/CountUpward.java new file mode 100644 index 00000000..bbeb02ba --- /dev/null +++ b/code/arrays/CountUpward.java @@ -0,0 +1,24 @@ +// arrays/CountUpward.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import static onjava.ArrayShow.*; + +public class CountUpward { + static long[] fillCounted(int size) { + return LongStream.iterate(0, i -> i + 1) + .limit(size).toArray(); + } + public static void main(String[] args) { + long[] l1 = fillCounted(20); // No problem + show(l1); + // On my machine, this runs out of heap space: + //- long[] l2 = fillCounted(10_000_000); + } +} +/* Output: +[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, +16, 17, 18, 19] +*/ diff --git a/code/arrays/FillingArrays.java b/code/arrays/FillingArrays.java new file mode 100644 index 00000000..df54e62f --- /dev/null +++ b/code/arrays/FillingArrays.java @@ -0,0 +1,55 @@ +// arrays/FillingArrays.java +// (c)2020 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. +// Using Arrays.fill() +import java.util.*; +import static onjava.ArrayShow.*; + +public class FillingArrays { + public static void main(String[] args) { + int size = 6; + boolean[] a1 = new boolean[size]; + byte[] a2 = new byte[size]; + char[] a3 = new char[size]; + short[] a4 = new short[size]; + int[] a5 = new int[size]; + long[] a6 = new long[size]; + float[] a7 = new float[size]; + double[] a8 = new double[size]; + String[] a9 = new String[size]; + Arrays.fill(a1, true); + show("a1", a1); + Arrays.fill(a2, (byte)11); + show("a2", a2); + Arrays.fill(a3, 'x'); + show("a3", a3); + Arrays.fill(a4, (short)17); + show("a4", a4); + Arrays.fill(a5, 19); + show("a5", a5); + Arrays.fill(a6, 23); + show("a6", a6); + Arrays.fill(a7, 29); + show("a7", a7); + Arrays.fill(a8, 47); + show("a8", a8); + Arrays.fill(a9, "Hello"); + show("a9", a9); + // Manipulating ranges: + Arrays.fill(a9, 3, 5, "World"); + show("a9", a9); + } +} +/* Output: +a1: [true, true, true, true, true, true] +a2: [11, 11, 11, 11, 11, 11] +a3: [x, x, x, x, x, x] +a4: [17, 17, 17, 17, 17, 17] +a5: [19, 19, 19, 19, 19, 19] +a6: [23, 23, 23, 23, 23, 23] +a7: [29.0, 29.0, 29.0, 29.0, 29.0, 29.0] +a8: [47.0, 47.0, 47.0, 47.0, 47.0, 47.0] +a9: [Hello, Hello, Hello, Hello, Hello, Hello] +a9: [Hello, Hello, Hello, World, World, Hello] +*/ diff --git a/code/arrays/IceCreamFlavors.java b/code/arrays/IceCreamFlavors.java new file mode 100644 index 00000000..5e9d2b61 --- /dev/null +++ b/code/arrays/IceCreamFlavors.java @@ -0,0 +1,45 @@ +// arrays/IceCreamFlavors.java +// (c)2020 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. +// Returning arrays from methods +import java.util.*; +import static onjava.ArrayShow.*; + +public class IceCreamFlavors { + private static SplittableRandom rand = + new SplittableRandom(47); + static final String[] FLAVORS = { + "Chocolate", "Strawberry", "Vanilla Fudge Swirl", + "Mint Chip", "Mocha Almond Fudge", "Rum Raisin", + "Praline Cream", "Mud Pie" + }; + public static String[] flavorSet(int n) { + if(n > FLAVORS.length) + throw new IllegalArgumentException("Set too big"); + String[] results = new String[n]; + boolean[] picked = new boolean[FLAVORS.length]; + for(int i = 0; i < n; i++) { + int t; + do + t = rand.nextInt(FLAVORS.length); + while(picked[t]); + results[i] = FLAVORS[t]; + picked[t] = true; + } + return results; + } + public static void main(String[] args) { + for(int i = 0; i < 7; i++) + show(flavorSet(3)); + } +} +/* Output: +[Praline Cream, Mint Chip, Vanilla Fudge Swirl] +[Strawberry, Vanilla Fudge Swirl, Mud Pie] +[Chocolate, Strawberry, Vanilla Fudge Swirl] +[Rum Raisin, Praline Cream, Chocolate] +[Mint Chip, Rum Raisin, Mocha Almond Fudge] +[Mocha Almond Fudge, Mud Pie, Vanilla Fudge Swirl] +[Mocha Almond Fudge, Mud Pie, Mint Chip] +*/ diff --git a/code/arrays/ModifyExisting.java b/code/arrays/ModifyExisting.java new file mode 100644 index 00000000..d74df78e --- /dev/null +++ b/code/arrays/ModifyExisting.java @@ -0,0 +1,22 @@ +// arrays/ModifyExisting.java +// (c)2020 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. +import java.util.*; +import onjava.*; +import static onjava.ArrayShow.*; + +public class ModifyExisting { + public static void main(String[] args) { + double[] da = new double[7]; + Arrays.setAll(da, new Rand.Double()::get); + show(da); + Arrays.setAll(da, n -> da[n] / 100); // [1] + show(da); + } +} +/* Output: +[4.83, 2.89, 2.9, 1.97, 3.01, 0.18, 0.99] +[0.0483, 0.028900000000000002, 0.028999999999999998, +0.0197, 0.0301, 0.0018, 0.009899999999999999] +*/ diff --git a/code/arrays/MultiDimWrapperArray.java b/code/arrays/MultiDimWrapperArray.java new file mode 100644 index 00000000..1185d0f9 --- /dev/null +++ b/code/arrays/MultiDimWrapperArray.java @@ -0,0 +1,38 @@ +// arrays/MultiDimWrapperArray.java +// (c)2020 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. +// Multidimensional arrays of "wrapper" objects +import java.util.*; + +public class MultiDimWrapperArray { + public static void main(String[] args) { + Integer[][] a1 = { // Autoboxing + { 1, 2, 3, }, + { 4, 5, 6, }, + }; + Double[][][] a2 = { // Autoboxing + { { 1.1, 2.2 }, { 3.3, 4.4 } }, + { { 5.5, 6.6 }, { 7.7, 8.8 } }, + { { 9.9, 1.2 }, { 2.3, 3.4 } }, + }; + String[][] a3 = { + { "The", "Quick", "Sly", "Fox" }, + { "Jumped", "Over" }, + { "The", "Lazy", "Brown", "Dog", "&", "friend" }, + }; + System.out.println( + "a1: " + Arrays.deepToString(a1)); + System.out.println( + "a2: " + Arrays.deepToString(a2)); + System.out.println( + "a3: " + Arrays.deepToString(a3)); + } +} +/* Output: +a1: [[1, 2, 3], [4, 5, 6]] +a2: [[[1.1, 2.2], [3.3, 4.4]], [[5.5, 6.6], [7.7, +8.8]], [[9.9, 1.2], [2.3, 3.4]]] +a3: [[The, Quick, Sly, Fox], [Jumped, Over], [The, +Lazy, Brown, Dog, &, friend]] +*/ diff --git a/code/arrays/MultidimensionalObjectArrays.java b/code/arrays/MultidimensionalObjectArrays.java new file mode 100644 index 00000000..998e7c99 --- /dev/null +++ b/code/arrays/MultidimensionalObjectArrays.java @@ -0,0 +1,25 @@ +// arrays/MultidimensionalObjectArrays.java +// (c)2020 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. +import java.util.*; + +public class MultidimensionalObjectArrays { + public static void main(String[] args) { + BerylliumSphere[][] spheres = { + { new BerylliumSphere(), new BerylliumSphere() }, + { new BerylliumSphere(), new BerylliumSphere(), + new BerylliumSphere(), new BerylliumSphere() }, + { new BerylliumSphere(), new BerylliumSphere(), + new BerylliumSphere(), new BerylliumSphere(), + new BerylliumSphere(), new BerylliumSphere(), + new BerylliumSphere(), new BerylliumSphere() }, + }; + System.out.println(Arrays.deepToString(spheres)); + } +} +/* Output: +[[Sphere 0, Sphere 1], [Sphere 2, Sphere 3, Sphere 4, +Sphere 5], [Sphere 6, Sphere 7, Sphere 8, Sphere 9, +Sphere 10, Sphere 11, Sphere 12, Sphere 13]] +*/ diff --git a/code/arrays/MultidimensionalPrimitiveArray.java b/code/arrays/MultidimensionalPrimitiveArray.java new file mode 100644 index 00000000..8ed5884f --- /dev/null +++ b/code/arrays/MultidimensionalPrimitiveArray.java @@ -0,0 +1,18 @@ +// arrays/MultidimensionalPrimitiveArray.java +// (c)2020 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. +import java.util.*; + +public class MultidimensionalPrimitiveArray { + public static void main(String[] args) { + int[][] a = { + { 1, 2, 3, }, + { 4, 5, 6, }, + }; + System.out.println(Arrays.deepToString(a)); + } +} +/* Output: +[[1, 2, 3], [4, 5, 6]] +*/ diff --git a/code/arrays/ParallelPrefix1.java b/code/arrays/ParallelPrefix1.java new file mode 100644 index 00000000..e180d019 --- /dev/null +++ b/code/arrays/ParallelPrefix1.java @@ -0,0 +1,27 @@ +// arrays/ParallelPrefix1.java +// (c)2020 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. +import java.util.*; +import onjava.*; +import static onjava.ArrayShow.*; + +public class ParallelPrefix1 { + public static void main(String[] args) { + int[] nums = new Count.Pint().array(10); + show(nums); + System.out.println(Arrays.stream(nums) + .reduce(Integer::sum).getAsInt()); + Arrays.parallelPrefix(nums, Integer::sum); + show(nums); + System.out.println(Arrays.stream( + new Count.Pint().array(6)) + .reduce(Integer::sum).getAsInt()); + } +} +/* Output: +[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +45 +[0, 1, 3, 6, 10, 15, 21, 28, 36, 45] +15 +*/ diff --git a/code/arrays/ParallelPrefix2.java b/code/arrays/ParallelPrefix2.java new file mode 100644 index 00000000..5288d3ce --- /dev/null +++ b/code/arrays/ParallelPrefix2.java @@ -0,0 +1,20 @@ +// arrays/ParallelPrefix2.java +// (c)2020 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. +import java.util.*; +import onjava.*; +import static onjava.ArrayShow.*; + +public class ParallelPrefix2 { + public static void main(String[] args) { + String[] strings = new Rand.String(1).array(8); + show(strings); + Arrays.parallelPrefix(strings, (a, b) -> a + b); + show(strings); + } +} +/* Output: +[b, t, p, e, n, p, c, c] +[b, bt, btp, btpe, btpen, btpenp, btpenpc, btpenpcc] +*/ diff --git a/code/arrays/ParallelPrefix3.java b/code/arrays/ParallelPrefix3.java new file mode 100644 index 00000000..ed2751dc --- /dev/null +++ b/code/arrays/ParallelPrefix3.java @@ -0,0 +1,23 @@ +// arrays/ParallelPrefix3.java +// (c)2020 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. +// {ExcludeFromTravisCI} +import java.util.*; + +public class ParallelPrefix3 { + static final int SIZE = 10_000_000; + public static void main(String[] args) { + long[] nums = new long[SIZE]; + Arrays.setAll(nums, n -> n); + Arrays.parallelPrefix(nums, Long::sum); + System.out.println("First 20: " + nums[19]); + System.out.println("First 200: " + nums[199]); + System.out.println("All: " + nums[nums.length-1]); + } +} +/* Output: +First 20: 190 +First 200: 19900 +All: 49999995000000 +*/ diff --git a/code/arrays/ParallelSetAll.java b/code/arrays/ParallelSetAll.java new file mode 100644 index 00000000..f6c47ff5 --- /dev/null +++ b/code/arrays/ParallelSetAll.java @@ -0,0 +1,24 @@ +// arrays/ParallelSetAll.java +// (c)2020 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. +import java.util.*; +import onjava.*; + +public class ParallelSetAll { + static final int SIZE = 10_000_000; + static void intArray() { + int[] ia = new int[SIZE]; + Arrays.setAll(ia, new Rand.Pint()::get); + Arrays.parallelSetAll(ia, new Rand.Pint()::get); + } + static void longArray() { + long[] la = new long[SIZE]; + Arrays.setAll(la, new Rand.Plong()::get); + Arrays.parallelSetAll(la, new Rand.Plong()::get); + } + public static void main(String[] args) { + intArray(); + longArray(); + } +} diff --git a/code/arrays/ParameterizedArrayType.java b/code/arrays/ParameterizedArrayType.java new file mode 100644 index 00000000..06c1021c --- /dev/null +++ b/code/arrays/ParameterizedArrayType.java @@ -0,0 +1,25 @@ +// arrays/ParameterizedArrayType.java +// (c)2020 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. + +class ClassParameter { + public T[] f(T[] arg) { return arg; } +} + +class MethodParameter { + public static T[] f(T[] arg) { return arg; } +} + +public class ParameterizedArrayType { + public static void main(String[] args) { + Integer[] ints = { 1, 2, 3, 4, 5 }; + Double[] doubles = { 1.1, 2.2, 3.3, 4.4, 5.5 }; + Integer[] ints2 = + new ClassParameter().f(ints); + Double[] doubles2 = + new ClassParameter().f(doubles); + ints2 = MethodParameter.f(ints); + doubles2 = MethodParameter.f(doubles); + } +} diff --git a/code/arrays/PythonLists.py b/code/arrays/PythonLists.py new file mode 100644 index 00000000..910daf18 --- /dev/null +++ b/code/arrays/PythonLists.py @@ -0,0 +1,36 @@ +# arrays/PythonLists.py +# (c)2020 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. + +aList = [1, 2, 3, 4, 5] +print(type(aList)) # +print(aList) # [1, 2, 3, 4, 5] +print(aList[4]) # 5 Basic list indexing +aList.append(6) # lists can be resized +aList += [7, 8] # Add a list to a list +print(aList) # [1, 2, 3, 4, 5, 6, 7, 8] +aSlice = aList[2:4] +print(aSlice) # [3, 4] + +class MyList(list): # Inherit from list + # Define a method; 'this' pointer is explicit: + def getReversed(self): + reversed = self[:] # Copy list using slices + reversed.reverse() # Built-in list method + return reversed + +# No 'new' necessary for object creation: +list2 = MyList(aList) +print(type(list2)) # +print(list2.getReversed()) # [8, 7, 6, 5, 4, 3, 2, 1] + +output = """ + +[1, 2, 3, 4, 5] +5 +[1, 2, 3, 4, 5, 6, 7, 8] +[3, 4] + +[8, 7, 6, 5, 4, 3, 2, 1] +""" diff --git a/code/arrays/RaggedArray.java b/code/arrays/RaggedArray.java new file mode 100644 index 00000000..bd7d625b --- /dev/null +++ b/code/arrays/RaggedArray.java @@ -0,0 +1,26 @@ +// arrays/RaggedArray.java +// (c)2020 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. +import java.util.*; + +public class RaggedArray { + static int val = 1; + public static void main(String[] args) { + SplittableRandom rand = new SplittableRandom(47); + // 3-D array with varied-length vectors: + int[][][] a = new int[rand.nextInt(7)][][]; + for(int i = 0; i < a.length; i++) { + a[i] = new int[rand.nextInt(5)][]; + for(int j = 0; j < a[i].length; j++) { + a[i][j] = new int[rand.nextInt(5)]; + Arrays.setAll(a[i][j], n -> val++); // [1] + } + } + System.out.println(Arrays.deepToString(a)); + } +} +/* Output: +[[[1], []], [[2, 3, 4, 5], [6]], [[7, 8, 9], [10, 11, +12], []]] +*/ diff --git a/code/arrays/Reverse.java b/code/arrays/Reverse.java new file mode 100644 index 00000000..9a7de678 --- /dev/null +++ b/code/arrays/Reverse.java @@ -0,0 +1,32 @@ +// arrays/Reverse.java +// (c)2020 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. +// The Collections.reverseOrder() Comparator +import java.util.*; +import onjava.*; +import static onjava.ArrayShow.*; + +public class Reverse { + public static void main(String[] args) { + CompType[] a = new CompType[12]; + Arrays.setAll(a, n -> CompType.get()); + show("Before sorting", a); + Arrays.sort(a, Collections.reverseOrder()); + show("After sorting", a); + } +} +/* Output: +Before sorting: [[i = 35, j = 37], [i = 41, j = 20], [i += 77, j = 79] +, [i = 56, j = 68], [i = 48, j = 93], [i = 70, j = 7] +, [i = 0, j = 25], [i = 62, j = 34], [i = 50, j = 82] +, [i = 31, j = 67], [i = 66, j = 54], [i = 21, j = 6] +] +After sorting: [[i = 77, j = 79], [i = 70, j = 7], [i = +66, j = 54] +, [i = 62, j = 34], [i = 56, j = 68], [i = 50, j = 82] +, [i = 48, j = 93], [i = 41, j = 20], [i = 35, j = 37] +, [i = 31, j = 67], [i = 21, j = 6], [i = 0, j = 25] +] +*/ diff --git a/code/arrays/SimpleSetAll.java b/code/arrays/SimpleSetAll.java new file mode 100644 index 00000000..70336e79 --- /dev/null +++ b/code/arrays/SimpleSetAll.java @@ -0,0 +1,56 @@ +// arrays/SimpleSetAll.java +// (c)2020 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. +import java.util.*; +import static onjava.ArrayShow.*; + +class Bob { + final int id; + Bob(int n) { id = n; } + @Override + public String toString() { return "Bob" + id; } +} + +public class SimpleSetAll { + public static final int SZ = 8; + static int val = 1; + static char[] chars = "abcdefghijklmnopqrstuvwxyz" + .toCharArray(); + static char getChar(int n) { return chars[n]; } + public static void main(String[] args) { + int[] ia = new int[SZ]; + long[] la = new long[SZ]; + double[] da = new double[SZ]; + Arrays.setAll(ia, n -> n); // [1] + Arrays.setAll(la, n -> n); + Arrays.setAll(da, n -> n); + show(ia); + show(la); + show(da); + Arrays.setAll(ia, n -> val++); // [2] + Arrays.setAll(la, n -> val++); + Arrays.setAll(da, n -> val++); + show(ia); + show(la); + show(da); + + Bob[] ba = new Bob[SZ]; + Arrays.setAll(ba, Bob::new); // [3] + show(ba); + + Character[] ca = new Character[SZ]; + Arrays.setAll(ca, SimpleSetAll::getChar); // [4] + show(ca); + } +} +/* Output: +[0, 1, 2, 3, 4, 5, 6, 7] +[0, 1, 2, 3, 4, 5, 6, 7] +[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] +[1, 2, 3, 4, 5, 6, 7, 8] +[9, 10, 11, 12, 13, 14, 15, 16] +[17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0] +[Bob0, Bob1, Bob2, Bob3, Bob4, Bob5, Bob6, Bob7] +[a, b, c, d, e, f, g, h] +*/ diff --git a/code/arrays/StreamFromArray.java b/code/arrays/StreamFromArray.java new file mode 100644 index 00000000..69628703 --- /dev/null +++ b/code/arrays/StreamFromArray.java @@ -0,0 +1,51 @@ +// arrays/StreamFromArray.java +// (c)2020 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. +import java.util.*; +import onjava.*; + +public class StreamFromArray { + public static void main(String[] args) { + String[] s = new Rand.String().array(10); + Arrays.stream(s) + .skip(3) + .limit(5) + .map(ss -> ss + "!") + .forEach(System.out::println); + + int[] ia = new Rand.Pint().array(10); + Arrays.stream(ia) + .skip(3) + .limit(5) + .map(i -> i * 10) + .forEach(System.out::println); + + Arrays.stream(new long[10]); + Arrays.stream(new double[10]); + + // Only int, long and double work: + //- Arrays.stream(new boolean[10]); + //- Arrays.stream(new byte[10]); + //- Arrays.stream(new char[10]); + //- Arrays.stream(new short[10]); + //- Arrays.stream(new float[10]); + + // For the other types you must use wrapped arrays: + float[] fa = new Rand.Pfloat().array(10); + Arrays.stream(ConvertTo.boxed(fa)); + Arrays.stream(new Rand.Float().array(10)); + } +} +/* Output: +eloztdv! +ewcippc! +ygpoalk! +ljlbynx! +taprwxz! +47200 +61770 +84790 +66560 +37680 +*/ diff --git a/code/arrays/StringSorting.java b/code/arrays/StringSorting.java new file mode 100644 index 00000000..0da5c733 --- /dev/null +++ b/code/arrays/StringSorting.java @@ -0,0 +1,39 @@ +// arrays/StringSorting.java +// (c)2020 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. +// Sorting an array of Strings +import java.util.*; +import onjava.*; +import static onjava.ArrayShow.*; + +public class StringSorting { + public static void main(String[] args) { + String[] sa = new Rand.String().array(20); + show("Before sort", sa); + Arrays.sort(sa); + show("After sort", sa); + Arrays.sort(sa, Collections.reverseOrder()); + show("Reverse sort", sa); + Arrays.sort(sa, String.CASE_INSENSITIVE_ORDER); + show("Case-insensitive sort", sa); + } +} +/* Output: +Before sort: [btpenpc, cuxszgv, gmeinne, eloztdv, +ewcippc, ygpoalk, ljlbynx, taprwxz, bhmupju, cjwzmmr, +anmkkyh, fcjpthl, skddcat, jbvlgwc, mvducuj, ydpulcq, +zehpfmm, zrxmclh, qgekgly, hyoubzl] +After sort: [anmkkyh, bhmupju, btpenpc, cjwzmmr, +cuxszgv, eloztdv, ewcippc, fcjpthl, gmeinne, hyoubzl, +jbvlgwc, ljlbynx, mvducuj, qgekgly, skddcat, taprwxz, +ydpulcq, ygpoalk, zehpfmm, zrxmclh] +Reverse sort: [zrxmclh, zehpfmm, ygpoalk, ydpulcq, +taprwxz, skddcat, qgekgly, mvducuj, ljlbynx, jbvlgwc, +hyoubzl, gmeinne, fcjpthl, ewcippc, eloztdv, cuxszgv, +cjwzmmr, btpenpc, bhmupju, anmkkyh] +Case-insensitive sort: [anmkkyh, bhmupju, btpenpc, +cjwzmmr, cuxszgv, eloztdv, ewcippc, fcjpthl, gmeinne, +hyoubzl, jbvlgwc, ljlbynx, mvducuj, qgekgly, skddcat, +taprwxz, ydpulcq, ygpoalk, zehpfmm, zrxmclh] +*/ diff --git a/code/arrays/TestConvertTo.java b/code/arrays/TestConvertTo.java new file mode 100644 index 00000000..8ecb72a6 --- /dev/null +++ b/code/arrays/TestConvertTo.java @@ -0,0 +1,87 @@ +// arrays/TestConvertTo.java +// (c)2020 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. +import java.util.*; +import onjava.*; +import static onjava.ArrayShow.*; +import static onjava.ConvertTo.*; + +public class TestConvertTo { + static final int SIZE = 6; + public static void main(String[] args) { + Boolean[] a1 = new Boolean[SIZE]; + Arrays.setAll(a1, new Rand.Boolean()::get); + boolean[] a1p = primitive(a1); + show("a1p", a1p); + Boolean[] a1b = boxed(a1p); + show("a1b", a1b); + + Byte[] a2 = new Byte[SIZE]; + Arrays.setAll(a2, new Rand.Byte()::get); + byte[] a2p = primitive(a2); + show("a2p", a2p); + Byte[] a2b = boxed(a2p); + show("a2b", a2b); + + Character[] a3 = new Character[SIZE]; + Arrays.setAll(a3, new Rand.Character()::get); + char[] a3p = primitive(a3); + show("a3p", a3p); + Character[] a3b = boxed(a3p); + show("a3b", a3b); + + Short[] a4 = new Short[SIZE]; + Arrays.setAll(a4, new Rand.Short()::get); + short[] a4p = primitive(a4); + show("a4p", a4p); + Short[] a4b = boxed(a4p); + show("a4b", a4b); + + Integer[] a5 = new Integer[SIZE]; + Arrays.setAll(a5, new Rand.Integer()::get); + int[] a5p = primitive(a5); + show("a5p", a5p); + Integer[] a5b = boxed(a5p); + show("a5b", a5b); + + Long[] a6 = new Long[SIZE]; + Arrays.setAll(a6, new Rand.Long()::get); + long[] a6p = primitive(a6); + show("a6p", a6p); + Long[] a6b = boxed(a6p); + show("a6b", a6b); + + Float[] a7 = new Float[SIZE]; + Arrays.setAll(a7, new Rand.Float()::get); + float[] a7p = primitive(a7); + show("a7p", a7p); + Float[] a7b = boxed(a7p); + show("a7b", a7b); + + Double[] a8 = new Double[SIZE]; + Arrays.setAll(a8, new Rand.Double()::get); + double[] a8p = primitive(a8); + show("a8p", a8p); + Double[] a8b = boxed(a8p); + show("a8b", a8b); + } +} +/* Output: +a1p: [true, false, true, true, true, false] +a1b: [true, false, true, true, true, false] +a2p: [123, 33, 101, 112, 33, 31] +a2b: [123, 33, 101, 112, 33, 31] +a3p: [b, t, p, e, n, p] +a3b: [b, t, p, e, n, p] +a4p: [635, 8737, 3941, 4720, 6177, 8479] +a4b: [635, 8737, 3941, 4720, 6177, 8479] +a5p: [635, 8737, 3941, 4720, 6177, 8479] +a5b: [635, 8737, 3941, 4720, 6177, 8479] +a6p: [6882, 3765, 692, 9575, 4439, 2638] +a6b: [6882, 3765, 692, 9575, 4439, 2638] +a7p: [4.83, 2.89, 2.9, 1.97, 3.01, 0.18] +a7b: [4.83, 2.89, 2.9, 1.97, 3.01, 0.18] +a8p: [4.83, 2.89, 2.9, 1.97, 3.01, 0.18] +a8b: [4.83, 2.89, 2.9, 1.97, 3.01, 0.18] +*/ diff --git a/code/arrays/TestCount.java b/code/arrays/TestCount.java new file mode 100644 index 00000000..a77e00f7 --- /dev/null +++ b/code/arrays/TestCount.java @@ -0,0 +1,167 @@ +// arrays/TestCount.java +// (c)2020 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. +// Test counting generators +import java.util.*; +import java.util.stream.*; +import onjava.*; +import static onjava.ArrayShow.*; + +public class TestCount { + static final int SZ = 5; + public static void main(String[] args) { + System.out.println("Boolean"); + Boolean[] a1 = new Boolean[SZ]; + Arrays.setAll(a1, new Count.Boolean()::get); + show(a1); + a1 = Stream.generate(new Count.Boolean()) + .limit(SZ + 1).toArray(Boolean[]::new); + show(a1); + a1 = new Count.Boolean().array(SZ + 2); + show(a1); + boolean[] a1b = + new Count.Pboolean().array(SZ + 3); + show(a1b); + + System.out.println("Byte"); + Byte[] a2 = new Byte[SZ]; + Arrays.setAll(a2, new Count.Byte()::get); + show(a2); + a2 = Stream.generate(new Count.Byte()) + .limit(SZ + 1).toArray(Byte[]::new); + show(a2); + a2 = new Count.Byte().array(SZ + 2); + show(a2); + byte[] a2b = new Count.Pbyte().array(SZ + 3); + show(a2b); + + System.out.println("Character"); + Character[] a3 = new Character[SZ]; + Arrays.setAll(a3, new Count.Character()::get); + show(a3); + a3 = Stream.generate(new Count.Character()) + .limit(SZ + 1).toArray(Character[]::new); + show(a3); + a3 = new Count.Character().array(SZ + 2); + show(a3); + char[] a3b = new Count.Pchar().array(SZ + 3); + show(a3b); + + System.out.println("Short"); + Short[] a4 = new Short[SZ]; + Arrays.setAll(a4, new Count.Short()::get); + show(a4); + a4 = Stream.generate(new Count.Short()) + .limit(SZ + 1).toArray(Short[]::new); + show(a4); + a4 = new Count.Short().array(SZ + 2); + show(a4); + short[] a4b = new Count.Pshort().array(SZ + 3); + show(a4b); + + System.out.println("Integer"); + int[] a5 = new int[SZ]; + Arrays.setAll(a5, new Count.Integer()::get); + show(a5); + Integer[] a5b = + Stream.generate(new Count.Integer()) + .limit(SZ + 1).toArray(Integer[]::new); + show(a5b); + a5b = new Count.Integer().array(SZ + 2); + show(a5b); + a5 = IntStream.generate(new Count.Pint()) + .limit(SZ + 1).toArray(); + show(a5); + a5 = new Count.Pint().array(SZ + 3); + show(a5); + + System.out.println("Long"); + long[] a6 = new long[SZ]; + Arrays.setAll(a6, new Count.Long()::get); + show(a6); + Long[] a6b = Stream.generate(new Count.Long()) + .limit(SZ + 1).toArray(Long[]::new); + show(a6b); + a6b = new Count.Long().array(SZ + 2); + show(a6b); + a6 = LongStream.generate(new Count.Plong()) + .limit(SZ + 1).toArray(); + show(a6); + a6 = new Count.Plong().array(SZ + 3); + show(a6); + + System.out.println("Float"); + Float[] a7 = new Float[SZ]; + Arrays.setAll(a7, new Count.Float()::get); + show(a7); + a7 = Stream.generate(new Count.Float()) + .limit(SZ + 1).toArray(Float[]::new); + show(a7); + a7 = new Count.Float().array(SZ + 2); + show(a7); + float[] a7b = new Count.Pfloat().array(SZ + 3); + show(a7b); + + System.out.println("Double"); + double[] a8 = new double[SZ]; + Arrays.setAll(a8, new Count.Double()::get); + show(a8); + Double[] a8b = + Stream.generate(new Count.Double()) + .limit(SZ + 1).toArray(Double[]::new); + show(a8b); + a8b = new Count.Double().array(SZ + 2); + show(a8b); + a8 = DoubleStream.generate(new Count.Pdouble()) + .limit(SZ + 1).toArray(); + show(a8); + a8 = new Count.Pdouble().array(SZ + 3); + show(a8); + } +} +/* Output: +Boolean +[false, true, false, true, false] +[false, true, false, true, false, true] +[false, true, false, true, false, true, false] +[false, true, false, true, false, true, false, true] +Byte +[0, 1, 2, 3, 4] +[0, 1, 2, 3, 4, 5] +[0, 1, 2, 3, 4, 5, 6] +[0, 1, 2, 3, 4, 5, 6, 7] +Character +[b, c, d, e, f] +[b, c, d, e, f, g] +[b, c, d, e, f, g, h] +[b, c, d, e, f, g, h, i] +Short +[0, 1, 2, 3, 4] +[0, 1, 2, 3, 4, 5] +[0, 1, 2, 3, 4, 5, 6] +[0, 1, 2, 3, 4, 5, 6, 7] +Integer +[0, 1, 2, 3, 4] +[0, 1, 2, 3, 4, 5] +[0, 1, 2, 3, 4, 5, 6] +[0, 1, 2, 3, 4, 5] +[0, 1, 2, 3, 4, 5, 6, 7] +Long +[0, 1, 2, 3, 4] +[0, 1, 2, 3, 4, 5] +[0, 1, 2, 3, 4, 5, 6] +[0, 1, 2, 3, 4, 5] +[0, 1, 2, 3, 4, 5, 6, 7] +Float +[0.0, 1.0, 2.0, 3.0, 4.0] +[0.0, 1.0, 2.0, 3.0, 4.0, 5.0] +[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0] +[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] +Double +[0.0, 1.0, 2.0, 3.0, 4.0] +[0.0, 1.0, 2.0, 3.0, 4.0, 5.0] +[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0] +[0.0, 1.0, 2.0, 3.0, 4.0, 5.0] +[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] +*/ diff --git a/code/arrays/TestRand.java b/code/arrays/TestRand.java new file mode 100644 index 00000000..17e0718f --- /dev/null +++ b/code/arrays/TestRand.java @@ -0,0 +1,192 @@ +// arrays/TestRand.java +// (c)2020 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. +// Test random generators +import java.util.*; +import java.util.stream.*; +import onjava.*; +import static onjava.ArrayShow.*; + +public class TestRand { + static final int SZ = 5; + public static void main(String[] args) { + System.out.println("Boolean"); + Boolean[] a1 = new Boolean[SZ]; + Arrays.setAll(a1, new Rand.Boolean()::get); + show(a1); + a1 = Stream.generate(new Rand.Boolean()) + .limit(SZ + 1).toArray(Boolean[]::new); + show(a1); + a1 = new Rand.Boolean().array(SZ + 2); + show(a1); + boolean[] a1b = + new Rand.Pboolean().array(SZ + 3); + show(a1b); + + System.out.println("Byte"); + Byte[] a2 = new Byte[SZ]; + Arrays.setAll(a2, new Rand.Byte()::get); + show(a2); + a2 = Stream.generate(new Rand.Byte()) + .limit(SZ + 1).toArray(Byte[]::new); + show(a2); + a2 = new Rand.Byte().array(SZ + 2); + show(a2); + byte[] a2b = new Rand.Pbyte().array(SZ + 3); + show(a2b); + + System.out.println("Character"); + Character[] a3 = new Character[SZ]; + Arrays.setAll(a3, new Rand.Character()::get); + show(a3); + a3 = Stream.generate(new Rand.Character()) + .limit(SZ + 1).toArray(Character[]::new); + show(a3); + a3 = new Rand.Character().array(SZ + 2); + show(a3); + char[] a3b = new Rand.Pchar().array(SZ + 3); + show(a3b); + + System.out.println("Short"); + Short[] a4 = new Short[SZ]; + Arrays.setAll(a4, new Rand.Short()::get); + show(a4); + a4 = Stream.generate(new Rand.Short()) + .limit(SZ + 1).toArray(Short[]::new); + show(a4); + a4 = new Rand.Short().array(SZ + 2); + show(a4); + short[] a4b = new Rand.Pshort().array(SZ + 3); + show(a4b); + + System.out.println("Integer"); + int[] a5 = new int[SZ]; + Arrays.setAll(a5, new Rand.Integer()::get); + show(a5); + Integer[] a5b = + Stream.generate(new Rand.Integer()) + .limit(SZ + 1).toArray(Integer[]::new); + show(a5b); + a5b = new Rand.Integer().array(SZ + 2); + show(a5b); + a5 = IntStream.generate(new Rand.Pint()) + .limit(SZ + 1).toArray(); + show(a5); + a5 = new Rand.Pint().array(SZ + 3); + show(a5); + + System.out.println("Long"); + long[] a6 = new long[SZ]; + Arrays.setAll(a6, new Rand.Long()::get); + show(a6); + Long[] a6b = Stream.generate(new Rand.Long()) + .limit(SZ + 1).toArray(Long[]::new); + show(a6b); + a6b = new Rand.Long().array(SZ + 2); + show(a6b); + a6 = LongStream.generate(new Rand.Plong()) + .limit(SZ + 1).toArray(); + show(a6); + a6 = new Rand.Plong().array(SZ + 3); + show(a6); + + System.out.println("Float"); + Float[] a7 = new Float[SZ]; + Arrays.setAll(a7, new Rand.Float()::get); + show(a7); + a7 = Stream.generate(new Rand.Float()) + .limit(SZ + 1).toArray(Float[]::new); + show(a7); + a7 = new Rand.Float().array(SZ + 2); + show(a7); + float[] a7b = new Rand.Pfloat().array(SZ + 3); + show(a7b); + + System.out.println("Double"); + double[] a8 = new double[SZ]; + Arrays.setAll(a8, new Rand.Double()::get); + show(a8); + Double[] a8b = + Stream.generate(new Rand.Double()) + .limit(SZ + 1).toArray(Double[]::new); + show(a8b); + a8b = new Rand.Double().array(SZ + 2); + show(a8b); + a8 = DoubleStream.generate(new Rand.Pdouble()) + .limit(SZ + 1).toArray(); + show(a8); + a8 = new Rand.Pdouble().array(SZ + 3); + show(a8); + + System.out.println("String"); + String[] s = new String[SZ - 1]; + Arrays.setAll(s, new Rand.String()::get); + show(s); + s = Stream.generate(new Rand.String()) + .limit(SZ).toArray(String[]::new); + show(s); + s = new Rand.String().array(SZ + 1); + show(s); + + Arrays.setAll(s, new Rand.String(4)::get); + show(s); + s = Stream.generate(new Rand.String(4)) + .limit(SZ).toArray(String[]::new); + show(s); + s = new Rand.String(4).array(SZ + 1); + show(s); + } +} +/* Output: +Boolean +[true, false, true, true, true] +[true, false, true, true, true, false] +[true, false, true, true, true, false, false] +[true, false, true, true, true, false, false, true] +Byte +[123, 33, 101, 112, 33] +[123, 33, 101, 112, 33, 31] +[123, 33, 101, 112, 33, 31, 0] +[123, 33, 101, 112, 33, 31, 0, -72] +Character +[b, t, p, e, n] +[b, t, p, e, n, p] +[b, t, p, e, n, p, c] +[b, t, p, e, n, p, c, c] +Short +[635, 8737, 3941, 4720, 6177] +[635, 8737, 3941, 4720, 6177, 8479] +[635, 8737, 3941, 4720, 6177, 8479, 6656] +[635, 8737, 3941, 4720, 6177, 8479, 6656, 3768] +Integer +[635, 8737, 3941, 4720, 6177] +[635, 8737, 3941, 4720, 6177, 8479] +[635, 8737, 3941, 4720, 6177, 8479, 6656] +[635, 8737, 3941, 4720, 6177, 8479] +[635, 8737, 3941, 4720, 6177, 8479, 6656, 3768] +Long +[6882, 3765, 692, 9575, 4439] +[6882, 3765, 692, 9575, 4439, 2638] +[6882, 3765, 692, 9575, 4439, 2638, 4011] +[6882, 3765, 692, 9575, 4439, 2638] +[6882, 3765, 692, 9575, 4439, 2638, 4011, 9610] +Float +[4.83, 2.89, 2.9, 1.97, 3.01] +[4.83, 2.89, 2.9, 1.97, 3.01, 0.18] +[4.83, 2.89, 2.9, 1.97, 3.01, 0.18, 0.99] +[4.83, 2.89, 2.9, 1.97, 3.01, 0.18, 0.99, 8.28] +Double +[4.83, 2.89, 2.9, 1.97, 3.01] +[4.83, 2.89, 2.9, 1.97, 3.01, 0.18] +[4.83, 2.89, 2.9, 1.97, 3.01, 0.18, 0.99] +[4.83, 2.89, 2.9, 1.97, 3.01, 0.18] +[4.83, 2.89, 2.9, 1.97, 3.01, 0.18, 0.99, 8.28] +String +[btpenpc, cuxszgv, gmeinne, eloztdv] +[btpenpc, cuxszgv, gmeinne, eloztdv, ewcippc] +[btpenpc, cuxszgv, gmeinne, eloztdv, ewcippc, ygpoalk] +[btpe, npcc, uxsz, gvgm, einn, eelo] +[btpe, npcc, uxsz, gvgm, einn] +[btpe, npcc, uxsz, gvgm, einn, eelo] +*/ diff --git a/code/arrays/ThreeDWithNew.java b/code/arrays/ThreeDWithNew.java new file mode 100644 index 00000000..7aaef069 --- /dev/null +++ b/code/arrays/ThreeDWithNew.java @@ -0,0 +1,17 @@ +// arrays/ThreeDWithNew.java +// (c)2020 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. +import java.util.*; + +public class ThreeDWithNew { + public static void main(String[] args) { + // 3-D array with fixed length: + int[][][] a = new int[2][2][4]; + System.out.println(Arrays.deepToString(a)); + } +} +/* Output: +[[[0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, +0]]] +*/ diff --git a/code/arrays/jmh/ParallelSort.java b/code/arrays/jmh/ParallelSort.java new file mode 100644 index 00000000..fe0b505b --- /dev/null +++ b/code/arrays/jmh/ParallelSort.java @@ -0,0 +1,25 @@ +// arrays/jmh/ParallelSort.java +// (c)2020 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 arrays.jmh; +import java.util.*; +import onjava.*; +import org.openjdk.jmh.annotations.*; + +@State(Scope.Thread) +public class ParallelSort { + private long[] la; + @Setup + public void setup() { + la = new Rand.Plong().array(100_000); + } + @Benchmark + public void sort() { + Arrays.sort(la); + } + @Benchmark + public void parallelSort() { + Arrays.parallelSort(la); + } +} diff --git a/code/build.gradle b/code/build.gradle new file mode 100644 index 00000000..b4feb13d --- /dev/null +++ b/code/build.gradle @@ -0,0 +1,23 @@ +buildscript { + repositories { + maven { + url 'https://plugins.gradle.org/m2/' + } + } + dependencies { + classpath 'me.champeau.gradle:jmh-gradle-plugin:0.5.2' + } +} + +apply plugin: 'com.mindviewinc.example-output-verification' + +subprojects { + apply from: "$rootProject.projectDir/gradle/java.gradle" + apply from: "$rootProject.projectDir/gradle/junit-jupiter.gradle" + apply from: "$rootProject.projectDir/gradle/jmh.gradle" + // apply from: "$rootProject.projectDir/gradle/checkstyle.gradle" + apply from: "$rootProject.projectDir/gradle/findbugs.gradle" + apply plugin: 'com.mindviewinc.tagging' +} + +apply from: 'gradle/subprojects.gradle' diff --git a/code/checkstyle.xml b/code/checkstyle.xml new file mode 100644 index 00000000..aabea2c4 --- /dev/null +++ b/code/checkstyle.xml @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code/chkstyle.bat b/code/chkstyle.bat new file mode 100644 index 00000000..24838fc0 --- /dev/null +++ b/code/chkstyle.bat @@ -0,0 +1,2 @@ +@echo run gradlew clean first! +gradlew checkstyleMain 1> checkstyleout.txt 2>&1 diff --git a/code/collections/AdapterMethodIdiom.java b/code/collections/AdapterMethodIdiom.java new file mode 100644 index 00000000..a97abb41 --- /dev/null +++ b/code/collections/AdapterMethodIdiom.java @@ -0,0 +1,48 @@ +// collections/AdapterMethodIdiom.java +// (c)2020 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. +// The "Adapter Method" idiom uses for-in +// with additional kinds of Iterables +import java.util.*; + +class ReversibleArrayList extends ArrayList { + ReversibleArrayList(Collection c) { + super(c); + } + public Iterable reversed() { + return new Iterable() { + public Iterator iterator() { + return new Iterator() { + int current = size() - 1; + public boolean hasNext() { + return current > -1; + } + public T next() { return get(current--); } + public void remove() { // Not implemented + throw new UnsupportedOperationException(); + } + }; + } + }; + } +} + +public class AdapterMethodIdiom { + public static void main(String[] args) { + ReversibleArrayList ral = + new ReversibleArrayList( + Arrays.asList("To be or not to be".split(" "))); + // Grabs the ordinary iterator via iterator(): + for(String s : ral) + System.out.print(s + " "); + System.out.println(); + // Hand it the Iterable of your choice + for(String s : ral.reversed()) + System.out.print(s + " "); + } +} +/* Output: +To be or not to be +be to not or be To +*/ diff --git a/code/collections/AddingGroups.java b/code/collections/AddingGroups.java new file mode 100644 index 00000000..ecfc8a5a --- /dev/null +++ b/code/collections/AddingGroups.java @@ -0,0 +1,24 @@ +// collections/AddingGroups.java +// (c)2020 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. +// Adding groups of elements to Collection objects +import java.util.*; + +public class AddingGroups { + public static void main(String[] args) { + Collection collection = + new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5)); + Integer[] moreInts = { 6, 7, 8, 9, 10 }; + collection.addAll(Arrays.asList(moreInts)); + // Runs significantly faster, but you can't + // construct a Collection this way: + Collections.addAll(collection, 11, 12, 13, 14, 15); + Collections.addAll(collection, moreInts); + // Produces a list "backed by" an array: + List list = Arrays.asList(16,17,18,19,20); + list.set(1, 99); // OK -- modify an element + // list.add(21); // Runtime error; the underlying + // array cannot be resized. + } +} diff --git a/code/collections/ApplesAndOrangesWithGenerics.java b/code/collections/ApplesAndOrangesWithGenerics.java new file mode 100644 index 00000000..c251672c --- /dev/null +++ b/code/collections/ApplesAndOrangesWithGenerics.java @@ -0,0 +1,23 @@ +// collections/ApplesAndOrangesWithGenerics.java +// (c)2020 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. +import java.util.*; + +public class ApplesAndOrangesWithGenerics { + public static void main(String[] args) { + ArrayList apples = new ArrayList<>(); + for(int i = 0; i < 3; i++) + apples.add(new Apple()); + // Compile-time error: + // apples.add(new Orange()); + for(Apple apple : apples) { + System.out.println(apple.id()); + } + } +} +/* Output: +0 +1 +2 +*/ diff --git a/code/collections/ApplesAndOrangesWithoutGenerics.java b/code/collections/ApplesAndOrangesWithoutGenerics.java new file mode 100644 index 00000000..6afacd12 --- /dev/null +++ b/code/collections/ApplesAndOrangesWithoutGenerics.java @@ -0,0 +1,38 @@ +// collections/ApplesAndOrangesWithoutGenerics.java +// (c)2020 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. +// Simple collection use (suppressing compiler warnings) +// {ThrowsException} +import java.util.*; + +class Apple { + private static long counter; + private final long id = counter++; + public long id() { return id; } +} + +class Orange {} + +public class ApplesAndOrangesWithoutGenerics { + @SuppressWarnings("unchecked") + public static void main(String[] args) { + ArrayList apples = new ArrayList(); + for(int i = 0; i < 3; i++) + apples.add(new Apple()); + // No problem adding an Orange to apples: + apples.add(new Orange()); + for(Object apple : apples) { + ((Apple) apple).id(); + // Orange is detected only at run time + } + } +} +/* Output: +___[ Error Output ]___ +Exception in thread "main" +java.lang.ClassCastException: Orange cannot be cast to +Apple + at ApplesAndOrangesWithoutGenerics.main(ApplesA +ndOrangesWithoutGenerics.java:23) +*/ diff --git a/code/collections/ArrayIsNotIterable.java b/code/collections/ArrayIsNotIterable.java new file mode 100644 index 00000000..d496feb1 --- /dev/null +++ b/code/collections/ArrayIsNotIterable.java @@ -0,0 +1,23 @@ +// collections/ArrayIsNotIterable.java +// (c)2020 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. +import java.util.*; + +public class ArrayIsNotIterable { + static void test(Iterable ib) { + for(T t : ib) + System.out.print(t + " "); + } + public static void main(String[] args) { + test(Arrays.asList(1, 2, 3)); + String[] strings = { "A", "B", "C" }; + // An array works in for-in, but it's not Iterable: + //- test(strings); + // You must explicitly convert it to an Iterable: + test(Arrays.asList(strings)); + } +} +/* Output: +1 2 3 A B C +*/ diff --git a/code/collections/AsListInference.java b/code/collections/AsListInference.java new file mode 100644 index 00000000..ef813708 --- /dev/null +++ b/code/collections/AsListInference.java @@ -0,0 +1,34 @@ +// collections/AsListInference.java +// (c)2020 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. +import java.util.*; + +class Snow {} +class Powder extends Snow {} +class Light extends Powder {} +class Heavy extends Powder {} +class Crusty extends Snow {} +class Slush extends Snow {} + +public class AsListInference { + public static void main(String[] args) { + List snow1 = Arrays.asList( + new Crusty(), new Slush(), new Powder()); + //- snow1.add(new Heavy()); // Exception + + List snow2 = Arrays.asList( + new Light(), new Heavy()); + //- snow2.add(new Slush()); // Exception + + List snow3 = new ArrayList<>(); + Collections.addAll(snow3, + new Light(), new Heavy(), new Powder()); + snow3.add(new Crusty()); + + // Hint with explicit type argument specification: + List snow4 = Arrays.asList( + new Light(), new Heavy(), new Slush()); + //- snow4.add(new Powder()); // Exception + } +} diff --git a/code/collections/CollectionDifferences.java b/code/collections/CollectionDifferences.java new file mode 100644 index 00000000..711f7bd7 --- /dev/null +++ b/code/collections/CollectionDifferences.java @@ -0,0 +1,71 @@ +// collections/CollectionDifferences.java +// (c)2020 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. +import onjava.*; + +public class CollectionDifferences { + public static void main(String[] args) { + CollectionMethodDifferences.main(args); + } +} +/* Output: +Collection: [add, addAll, clear, contains, containsAll, +equals, forEach, hashCode, isEmpty, iterator, +parallelStream, remove, removeAll, removeIf, retainAll, +size, spliterator, stream, toArray] +Interfaces in Collection: [Iterable] +Set extends Collection, adds: [] +Interfaces in Set: [Collection] +HashSet extends Set, adds: [] +Interfaces in HashSet: [Set, Cloneable, Serializable] +LinkedHashSet extends HashSet, adds: [] +Interfaces in LinkedHashSet: [Set, Cloneable, +Serializable] +TreeSet extends Set, adds: [headSet, +descendingIterator, descendingSet, pollLast, subSet, +floor, tailSet, ceiling, last, lower, comparator, +pollFirst, first, higher] +Interfaces in TreeSet: [NavigableSet, Cloneable, +Serializable] +List extends Collection, adds: [replaceAll, get, +indexOf, subList, set, sort, lastIndexOf, listIterator] +Interfaces in List: [Collection] +ArrayList extends List, adds: [trimToSize, +ensureCapacity] +Interfaces in ArrayList: [List, RandomAccess, +Cloneable, Serializable] +LinkedList extends List, adds: [offerFirst, poll, +getLast, offer, getFirst, removeFirst, element, +removeLastOccurrence, peekFirst, peekLast, push, +pollFirst, removeFirstOccurrence, descendingIterator, +pollLast, removeLast, pop, addLast, peek, offerLast, +addFirst] +Interfaces in LinkedList: [List, Deque, Cloneable, +Serializable] +Queue extends Collection, adds: [poll, peek, offer, +element] +Interfaces in Queue: [Collection] +PriorityQueue extends Queue, adds: [comparator] +Interfaces in PriorityQueue: [Serializable] +Map: [clear, compute, computeIfAbsent, +computeIfPresent, containsKey, containsValue, entrySet, +equals, forEach, get, getOrDefault, hashCode, isEmpty, +keySet, merge, put, putAll, putIfAbsent, remove, +replace, replaceAll, size, values] +HashMap extends Map, adds: [] +Interfaces in HashMap: [Map, Cloneable, Serializable] +LinkedHashMap extends HashMap, adds: [] +Interfaces in LinkedHashMap: [Map] +SortedMap extends Map, adds: [lastKey, subMap, +comparator, firstKey, headMap, tailMap] +Interfaces in SortedMap: [Map] +TreeMap extends Map, adds: [descendingKeySet, +navigableKeySet, higherEntry, higherKey, floorKey, +subMap, ceilingKey, pollLastEntry, firstKey, lowerKey, +headMap, tailMap, lowerEntry, ceilingEntry, +descendingMap, pollFirstEntry, lastKey, firstEntry, +floorEntry, comparator, lastEntry] +Interfaces in TreeMap: [NavigableMap, Cloneable, +Serializable] +*/ diff --git a/code/collections/CollectionSequence.java b/code/collections/CollectionSequence.java new file mode 100644 index 00000000..6a12ed69 --- /dev/null +++ b/code/collections/CollectionSequence.java @@ -0,0 +1,40 @@ +// collections/CollectionSequence.java +// (c)2020 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. +import typeinfo.pets.*; +import java.util.*; + +public class CollectionSequence +extends AbstractCollection { + private Pet[] pets = Pets.array(8); + @Override + public int size() { return pets.length; } + @Override + public Iterator iterator() { + return new Iterator() { // [1] + private int index = 0; + @Override + public boolean hasNext() { + return index < pets.length; + } + @Override + public Pet next() { return pets[index++]; } + @Override + public void remove() { // Not implemented + throw new UnsupportedOperationException(); + } + }; + } + public static void main(String[] args) { + CollectionSequence c = new CollectionSequence(); + InterfaceVsIterator.display(c); + InterfaceVsIterator.display(c.iterator()); + } +} +/* Output: +0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug +7:Manx +0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug +7:Manx +*/ diff --git a/code/collections/CrossCollectionIteration.java b/code/collections/CrossCollectionIteration.java new file mode 100644 index 00000000..99769fe2 --- /dev/null +++ b/code/collections/CrossCollectionIteration.java @@ -0,0 +1,36 @@ +// collections/CrossCollectionIteration.java +// (c)2020 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. +import typeinfo.pets.*; +import java.util.*; + +public class CrossCollectionIteration { + public static void display(Iterator it) { + while(it.hasNext()) { + Pet p = it.next(); + System.out.print(p.id() + ":" + p + " "); + } + System.out.println(); + } + public static void main(String[] args) { + List pets = Pets.list(8); + LinkedList petsLL = new LinkedList<>(pets); + HashSet petsHS = new HashSet<>(pets); + TreeSet petsTS = new TreeSet<>(pets); + display(pets.iterator()); + display(petsLL.iterator()); + display(petsHS.iterator()); + display(petsTS.iterator()); + } +} +/* Output: +0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug +7:Manx +0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug +7:Manx +0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug +7:Manx +5:Cymric 2:Cymric 7:Manx 1:Manx 3:Mutt 6:Pug 4:Pug +0:Rat +*/ diff --git a/code/collections/CrossCollectionIteration2.java b/code/collections/CrossCollectionIteration2.java new file mode 100644 index 00000000..c7da143f --- /dev/null +++ b/code/collections/CrossCollectionIteration2.java @@ -0,0 +1,37 @@ +// collections/CrossCollectionIteration2.java +// (c)2020 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. +import typeinfo.pets.*; +import java.util.*; + +public class CrossCollectionIteration2 { + public static void display(Iterable ip) { + Iterator it = ip.iterator(); + while(it.hasNext()) { + Pet p = it.next(); + System.out.print(p.id() + ":" + p + " "); + } + System.out.println(); + } + public static void main(String[] args) { + List pets = Pets.list(8); + LinkedList petsLL = new LinkedList<>(pets); + HashSet petsHS = new HashSet<>(pets); + TreeSet petsTS = new TreeSet<>(pets); + display(pets); + display(petsLL); + display(petsHS); + display(petsTS); + } +} +/* Output: +0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug +7:Manx +0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug +7:Manx +0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug +7:Manx +5:Cymric 2:Cymric 7:Manx 1:Manx 3:Mutt 6:Pug 4:Pug +0:Rat +*/ diff --git a/code/collections/EnvironmentVariables.java b/code/collections/EnvironmentVariables.java new file mode 100644 index 00000000..af89e5a2 --- /dev/null +++ b/code/collections/EnvironmentVariables.java @@ -0,0 +1,15 @@ +// collections/EnvironmentVariables.java +// (c)2020 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. +// {VisuallyInspectOutput} +import java.util.*; + +public class EnvironmentVariables { + public static void main(String[] args) { + for(Map.Entry entry: System.getenv().entrySet()) { + System.out.println(entry.getKey() + ": " + + entry.getValue()); + } + } +} diff --git a/code/collections/ForInCollections.java b/code/collections/ForInCollections.java new file mode 100644 index 00000000..a8ddd792 --- /dev/null +++ b/code/collections/ForInCollections.java @@ -0,0 +1,19 @@ +// collections/ForInCollections.java +// (c)2020 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. +// All collections work with for-in +import java.util.*; + +public class ForInCollections { + public static void main(String[] args) { + Collection cs = new LinkedList<>(); + Collections.addAll(cs, + "Take the long way home".split(" ")); + for(String s : cs) + System.out.print("'" + s + "' "); + } +} +/* Output: +'Take' 'the' 'long' 'way' 'home' +*/ diff --git a/code/collections/GenericsAndUpcasting.java b/code/collections/GenericsAndUpcasting.java new file mode 100644 index 00000000..ed8d3f55 --- /dev/null +++ b/code/collections/GenericsAndUpcasting.java @@ -0,0 +1,28 @@ +// collections/GenericsAndUpcasting.java +// (c)2020 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. +import java.util.*; + +class GrannySmith extends Apple {} +class Gala extends Apple {} +class Fuji extends Apple {} +class Braeburn extends Apple {} + +public class GenericsAndUpcasting { + public static void main(String[] args) { + ArrayList apples = new ArrayList<>(); + apples.add(new GrannySmith()); + apples.add(new Gala()); + apples.add(new Fuji()); + apples.add(new Braeburn()); + for(Apple apple : apples) + System.out.println(apple); + } +} +/* Output: +GrannySmith@15db9742 +Gala@6d06d69c +Fuji@7852e922 +Braeburn@4e25154f +*/ diff --git a/code/collections/InterfaceVsIterator.java b/code/collections/InterfaceVsIterator.java new file mode 100644 index 00000000..b5a8663d --- /dev/null +++ b/code/collections/InterfaceVsIterator.java @@ -0,0 +1,55 @@ +// collections/InterfaceVsIterator.java +// (c)2020 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. +import typeinfo.pets.*; +import java.util.*; + +public class InterfaceVsIterator { + public static void display(Iterator it) { + while(it.hasNext()) { + Pet p = it.next(); + System.out.print(p.id() + ":" + p + " "); + } + System.out.println(); + } + public static void display(Collection pets) { + for(Pet p : pets) + System.out.print(p.id() + ":" + p + " "); + System.out.println(); + } + public static void main(String[] args) { + List petList = Pets.list(8); + Set petSet = new HashSet<>(petList); + Map petMap = new LinkedHashMap<>(); + String[] names = ("Ralph, Eric, Robin, Lacey, " + + "Britney, Sam, Spot, Fluffy").split(", "); + for(int i = 0; i < names.length; i++) + petMap.put(names[i], petList.get(i)); + display(petList); + display(petSet); + display(petList.iterator()); + display(petSet.iterator()); + System.out.println(petMap); + System.out.println(petMap.keySet()); + display(petMap.values()); + display(petMap.values().iterator()); + } +} +/* Output: +0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug +7:Manx +0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug +7:Manx +0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug +7:Manx +0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug +7:Manx +{Ralph=Rat, Eric=Manx, Robin=Cymric, Lacey=Mutt, +Britney=Pug, Sam=Cymric, Spot=Pug, Fluffy=Manx} +[Ralph, Eric, Robin, Lacey, Britney, Sam, Spot, Fluffy] +0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug +7:Manx +0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug +7:Manx +*/ diff --git a/code/collections/IterableClass.java b/code/collections/IterableClass.java new file mode 100644 index 00000000..260edc7d --- /dev/null +++ b/code/collections/IterableClass.java @@ -0,0 +1,35 @@ +// collections/IterableClass.java +// (c)2020 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. +// Anything Iterable works with for-in +import java.util.*; + +public class IterableClass implements Iterable { + protected String[] words = ("And that is how " + + "we know the Earth to be banana-shaped." + ).split(" "); + @Override + public Iterator iterator() { + return new Iterator() { + private int index = 0; + @Override + public boolean hasNext() { + return index < words.length; + } + @Override + public String next() { return words[index++]; } + @Override + public void remove() { // Not implemented + throw new UnsupportedOperationException(); + } + }; + } + public static void main(String[] args) { + for(String s : new IterableClass()) + System.out.print(s + " "); + } +} +/* Output: +And that is how we know the Earth to be banana-shaped. +*/ diff --git a/code/collections/LinkedListFeatures.java b/code/collections/LinkedListFeatures.java new file mode 100644 index 00000000..3c10ff4e --- /dev/null +++ b/code/collections/LinkedListFeatures.java @@ -0,0 +1,54 @@ +// collections/LinkedListFeatures.java +// (c)2020 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. +import typeinfo.pets.*; +import java.util.*; + +public class LinkedListFeatures { + public static void main(String[] args) { + LinkedList pets = + new LinkedList<>(Pets.list(5)); + System.out.println(pets); + // Identical: + System.out.println( + "pets.getFirst(): " + pets.getFirst()); + System.out.println( + "pets.element(): " + pets.element()); + // Only differs in empty-list behavior: + System.out.println("pets.peek(): " + pets.peek()); + // Identical; remove and return the first element: + System.out.println( + "pets.remove(): " + pets.remove()); + System.out.println( + "pets.removeFirst(): " + pets.removeFirst()); + // Only differs in empty-list behavior: + System.out.println("pets.poll(): " + pets.poll()); + System.out.println(pets); + pets.addFirst(new Rat()); + System.out.println("After addFirst(): " + pets); + pets.offer(Pets.get()); + System.out.println("After offer(): " + pets); + pets.add(Pets.get()); + System.out.println("After add(): " + pets); + pets.addLast(new Hamster()); + System.out.println("After addLast(): " + pets); + System.out.println( + "pets.removeLast(): " + pets.removeLast()); + } +} +/* Output: +[Rat, Manx, Cymric, Mutt, Pug] +pets.getFirst(): Rat +pets.element(): Rat +pets.peek(): Rat +pets.remove(): Rat +pets.removeFirst(): Manx +pets.poll(): Cymric +[Mutt, Pug] +After addFirst(): [Rat, Mutt, Pug] +After offer(): [Rat, Mutt, Pug, Cymric] +After add(): [Rat, Mutt, Pug, Cymric, Pug] +After addLast(): [Rat, Mutt, Pug, Cymric, Pug, Hamster] +pets.removeLast(): Hamster +*/ diff --git a/code/collections/ListFeatures.java b/code/collections/ListFeatures.java new file mode 100644 index 00000000..b4ee16ab --- /dev/null +++ b/code/collections/ListFeatures.java @@ -0,0 +1,93 @@ +// collections/ListFeatures.java +// (c)2020 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. +import typeinfo.pets.*; +import java.util.*; + +public class ListFeatures { + public static void main(String[] args) { + Random rand = new Random(47); + List pets = Pets.list(7); + System.out.println("1: " + pets); + Hamster h = new Hamster(); + pets.add(h); // Automatically resizes + System.out.println("2: " + pets); + System.out.println("3: " + pets.contains(h)); + pets.remove(h); // Remove by object + Pet p = pets.get(2); + System.out.println( + "4: " + p + " " + pets.indexOf(p)); + Pet cymric = new Cymric(); + System.out.println("5: " + pets.indexOf(cymric)); + System.out.println("6: " + pets.remove(cymric)); + // Must be the exact object: + System.out.println("7: " + pets.remove(p)); + System.out.println("8: " + pets); + pets.add(3, new Mouse()); // Insert at an index + System.out.println("9: " + pets); + List sub = pets.subList(1, 4); + System.out.println("subList: " + sub); + System.out.println("10: " + pets.containsAll(sub)); + Collections.sort(sub); // In-place sort + System.out.println("sorted subList: " + sub); + // Order is not important in containsAll(): + System.out.println("11: " + pets.containsAll(sub)); + Collections.shuffle(sub, rand); // Mix it up + System.out.println("shuffled subList: " + sub); + System.out.println("12: " + pets.containsAll(sub)); + List copy = new ArrayList<>(pets); + sub = Arrays.asList(pets.get(1), pets.get(4)); + System.out.println("sub: " + sub); + copy.retainAll(sub); + System.out.println("13: " + copy); + copy = new ArrayList<>(pets); // Get a fresh copy + copy.remove(2); // Remove by index + System.out.println("14: " + copy); + copy.removeAll(sub); // Only removes exact objects + System.out.println("15: " + copy); + copy.set(1, new Mouse()); // Replace an element + System.out.println("16: " + copy); + copy.addAll(2, sub); // Insert a list in the middle + System.out.println("17: " + copy); + System.out.println("18: " + pets.isEmpty()); + pets.clear(); // Remove all elements + System.out.println("19: " + pets); + System.out.println("20: " + pets.isEmpty()); + pets.addAll(Pets.list(4)); + System.out.println("21: " + pets); + Object[] o = pets.toArray(); + System.out.println("22: " + o[3]); + Pet[] pa = pets.toArray(new Pet[0]); + System.out.println("23: " + pa[3].id()); + } +} +/* Output: +1: [Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug] +2: [Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug, Hamster] +3: true +4: Cymric 2 +5: -1 +6: false +7: true +8: [Rat, Manx, Mutt, Pug, Cymric, Pug] +9: [Rat, Manx, Mutt, Mouse, Pug, Cymric, Pug] +subList: [Manx, Mutt, Mouse] +10: true +sorted subList: [Manx, Mouse, Mutt] +11: true +shuffled subList: [Mouse, Manx, Mutt] +12: true +sub: [Mouse, Pug] +13: [Mouse, Pug] +14: [Rat, Mouse, Mutt, Pug, Cymric, Pug] +15: [Rat, Mutt, Cymric, Pug] +16: [Rat, Mouse, Cymric, Pug] +17: [Rat, Mouse, Mouse, Pug, Cymric, Pug] +18: false +19: [] +20: true +21: [Manx, Cymric, Rat, EgyptianMau] +22: EgyptianMau +23: 14 +*/ diff --git a/code/collections/ListIteration.java b/code/collections/ListIteration.java new file mode 100644 index 00000000..95d2786c --- /dev/null +++ b/code/collections/ListIteration.java @@ -0,0 +1,37 @@ +// collections/ListIteration.java +// (c)2020 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. +import typeinfo.pets.*; +import java.util.*; + +public class ListIteration { + public static void main(String[] args) { + List pets = Pets.list(8); + ListIterator it = pets.listIterator(); + while(it.hasNext()) + System.out.print(it.next() + + ", " + it.nextIndex() + + ", " + it.previousIndex() + "; "); + System.out.println(); + // Backwards: + while(it.hasPrevious()) + System.out.print(it.previous().id() + " "); + System.out.println(); + System.out.println(pets); + it = pets.listIterator(3); + while(it.hasNext()) { + it.next(); + it.set(Pets.get()); + } + System.out.println(pets); + } +} +/* Output: +Rat, 1, 0; Manx, 2, 1; Cymric, 3, 2; Mutt, 4, 3; Pug, +5, 4; Cymric, 6, 5; Pug, 7, 6; Manx, 8, 7; +7 6 5 4 3 2 1 0 +[Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug, Manx] +[Rat, Manx, Cymric, Cymric, Rat, EgyptianMau, Hamster, +EgyptianMau] +*/ diff --git a/code/collections/MapOfList.java b/code/collections/MapOfList.java new file mode 100644 index 00000000..3a985dd9 --- /dev/null +++ b/code/collections/MapOfList.java @@ -0,0 +1,65 @@ +// collections/MapOfList.java +// (c)2020 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. +// {java collections.MapOfList} +package collections; +import typeinfo.pets.*; +import java.util.*; + +public class MapOfList { + public static final Map> + petPeople = new HashMap<>(); + static { + petPeople.put(new Person("Dawn"), + Arrays.asList( + new Cymric("Molly"), + new Mutt("Spot"))); + petPeople.put(new Person("Kate"), + Arrays.asList(new Cat("Shackleton"), + new Cat("Elsie May"), new Dog("Margrett"))); + petPeople.put(new Person("Marilyn"), + Arrays.asList( + new Pug("Louie aka Louis Snorkelstein Dupree"), + new Cat("Stanford"), + new Cat("Pinkola"))); + petPeople.put(new Person("Luke"), + Arrays.asList( + new Rat("Fuzzy"), new Rat("Fizzy"))); + petPeople.put(new Person("Isaac"), + Arrays.asList(new Rat("Freckly"))); + } + public static void main(String[] args) { + System.out.println("People: " + petPeople.keySet()); + System.out.println("Pets: " + petPeople.values()); + for(Person person : petPeople.keySet()) { + System.out.println(person + " has:"); + for(Pet pet : petPeople.get(person)) + System.out.println(" " + pet); + } + } +} +/* Output: +People: [Person Dawn, Person Kate, Person Isaac, Person +Marilyn, Person Luke] +Pets: [[Cymric Molly, Mutt Spot], [Cat Shackleton, Cat +Elsie May, Dog Margrett], [Rat Freckly], [Pug Louie aka +Louis Snorkelstein Dupree, Cat Stanford, Cat Pinkola], +[Rat Fuzzy, Rat Fizzy]] +Person Dawn has: + Cymric Molly + Mutt Spot +Person Kate has: + Cat Shackleton + Cat Elsie May + Dog Margrett +Person Isaac has: + Rat Freckly +Person Marilyn has: + Pug Louie aka Louis Snorkelstein Dupree + Cat Stanford + Cat Pinkola +Person Luke has: + Rat Fuzzy + Rat Fizzy +*/ diff --git a/code/collections/ModifyingArraysAsList.java b/code/collections/ModifyingArraysAsList.java new file mode 100644 index 00000000..fea3da42 --- /dev/null +++ b/code/collections/ModifyingArraysAsList.java @@ -0,0 +1,32 @@ +// collections/ModifyingArraysAsList.java +// (c)2020 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. +import java.util.*; + +public class ModifyingArraysAsList { + public static void main(String[] args) { + Random rand = new Random(47); + Integer[] ia = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + List list1 = + new ArrayList<>(Arrays.asList(ia)); + System.out.println("Before shuffling: " + list1); + Collections.shuffle(list1, rand); + System.out.println("After shuffling: " + list1); + System.out.println("array: " + Arrays.toString(ia)); + + List list2 = Arrays.asList(ia); + System.out.println("Before shuffling: " + list2); + Collections.shuffle(list2, rand); + System.out.println("After shuffling: " + list2); + System.out.println("array: " + Arrays.toString(ia)); + } +} +/* Output: +Before shuffling: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +After shuffling: [4, 6, 3, 1, 8, 7, 2, 5, 10, 9] +array: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +Before shuffling: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +After shuffling: [9, 1, 6, 3, 7, 2, 5, 10, 4, 8] +array: [9, 1, 6, 3, 7, 2, 5, 10, 4, 8] +*/ diff --git a/code/collections/MultiIterableClass.java b/code/collections/MultiIterableClass.java new file mode 100644 index 00000000..1d7376e5 --- /dev/null +++ b/code/collections/MultiIterableClass.java @@ -0,0 +1,53 @@ +// collections/MultiIterableClass.java +// (c)2020 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. +// Adding several Adapter Methods +import java.util.*; + +public class MultiIterableClass extends IterableClass { + public Iterable reversed() { + return new Iterable() { + public Iterator iterator() { + return new Iterator() { + int current = words.length - 1; + public boolean hasNext() { + return current > -1; + } + public String next() { + return words[current--]; + } + public void remove() { // Not implemented + throw new UnsupportedOperationException(); + } + }; + } + }; + } + public Iterable randomized() { + return new Iterable() { + public Iterator iterator() { + List shuffled = + new ArrayList(Arrays.asList(words)); + Collections.shuffle(shuffled, new Random(47)); + return shuffled.iterator(); + } + }; + } + public static void main(String[] args) { + MultiIterableClass mic = new MultiIterableClass(); + for(String s : mic.reversed()) + System.out.print(s + " "); + System.out.println(); + for(String s : mic.randomized()) + System.out.print(s + " "); + System.out.println(); + for(String s : mic) + System.out.print(s + " "); + } +} +/* Output: +banana-shaped. be to Earth the know we how is that And +is banana-shaped. Earth that how the be And we know to +And that is how we know the Earth to be banana-shaped. +*/ diff --git a/code/collections/NonCollectionSequence.java b/code/collections/NonCollectionSequence.java new file mode 100644 index 00000000..ed1ae6f6 --- /dev/null +++ b/code/collections/NonCollectionSequence.java @@ -0,0 +1,37 @@ +// collections/NonCollectionSequence.java +// (c)2020 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. +import typeinfo.pets.*; +import java.util.*; + +class PetSequence { + protected Pet[] pets = Pets.array(8); +} + +public class NonCollectionSequence extends PetSequence { + public Iterator iterator() { + return new Iterator() { + private int index = 0; + @Override + public boolean hasNext() { + return index < pets.length; + } + @Override + public Pet next() { return pets[index++]; } + @Override + public void remove() { // Not implemented + throw new UnsupportedOperationException(); + } + }; + } + public static void main(String[] args) { + NonCollectionSequence nc = + new NonCollectionSequence(); + InterfaceVsIterator.display(nc.iterator()); + } +} +/* Output: +0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug +7:Manx +*/ diff --git a/code/collections/PetMap.java b/code/collections/PetMap.java new file mode 100644 index 00000000..18d02ef0 --- /dev/null +++ b/code/collections/PetMap.java @@ -0,0 +1,27 @@ +// collections/PetMap.java +// (c)2020 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. +import typeinfo.pets.*; +import java.util.*; + +public class PetMap { + public static void main(String[] args) { + Map petMap = new HashMap<>(); + petMap.put("My Cat", new Cat("Molly")); + petMap.put("My Dog", new Dog("Ginger")); + petMap.put("My Hamster", new Hamster("Bosco")); + System.out.println(petMap); + Pet dog = petMap.get("My Dog"); + System.out.println(dog); + System.out.println(petMap.containsKey("My Dog")); + System.out.println(petMap.containsValue(dog)); + } +} +/* Output: +{My Dog=Dog Ginger, My Cat=Cat Molly, My +Hamster=Hamster Bosco} +Dog Ginger +true +true +*/ diff --git a/code/collections/PrintingCollections.java b/code/collections/PrintingCollections.java new file mode 100644 index 00000000..c5746fc3 --- /dev/null +++ b/code/collections/PrintingCollections.java @@ -0,0 +1,44 @@ +// collections/PrintingCollections.java +// (c)2020 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. +// Collections print themselves automatically +import java.util.*; + +public class PrintingCollections { + static Collection + fill(Collection collection) { + collection.add("rat"); + collection.add("cat"); + collection.add("dog"); + collection.add("dog"); + return collection; + } + static Map fill(Map map) { + map.put("rat", "Fuzzy"); + map.put("cat", "Rags"); + map.put("dog", "Bosco"); + map.put("dog", "Spot"); + return map; + } + public static void main(String[] args) { + System.out.println(fill(new ArrayList<>())); + System.out.println(fill(new LinkedList<>())); + System.out.println(fill(new HashSet<>())); + System.out.println(fill(new TreeSet<>())); + System.out.println(fill(new LinkedHashSet<>())); + System.out.println(fill(new HashMap<>())); + System.out.println(fill(new TreeMap<>())); + System.out.println(fill(new LinkedHashMap<>())); + } +} +/* Output: +[rat, cat, dog, dog] +[rat, cat, dog, dog] +[rat, cat, dog] +[cat, dog, rat] +[rat, cat, dog] +{rat=Fuzzy, cat=Rags, dog=Spot} +{cat=Rags, dog=Spot, rat=Fuzzy} +{rat=Fuzzy, cat=Rags, dog=Spot} +*/ diff --git a/code/collections/PriorityQueueDemo.java b/code/collections/PriorityQueueDemo.java new file mode 100644 index 00000000..4f71ab0e --- /dev/null +++ b/code/collections/PriorityQueueDemo.java @@ -0,0 +1,53 @@ +// collections/PriorityQueueDemo.java +// (c)2020 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. +import java.util.*; + +public class PriorityQueueDemo { + public static void main(String[] args) { + PriorityQueue priorityQueue = + new PriorityQueue<>(); + Random rand = new Random(47); + for(int i = 0; i < 10; i++) + priorityQueue.offer(rand.nextInt(i + 10)); + QueueDemo.printQ(priorityQueue); + + List ints = Arrays.asList(25, 22, 20, + 18, 14, 9, 3, 1, 1, 2, 3, 9, 14, 18, 21, 23, 25); + priorityQueue = new PriorityQueue<>(ints); + QueueDemo.printQ(priorityQueue); + priorityQueue = new PriorityQueue<>( + ints.size(), Collections.reverseOrder()); + priorityQueue.addAll(ints); + QueueDemo.printQ(priorityQueue); + + String fact = "EDUCATION SHOULD ESCHEW OBFUSCATION"; + List strings = + Arrays.asList(fact.split("")); + PriorityQueue stringPQ = + new PriorityQueue<>(strings); + QueueDemo.printQ(stringPQ); + stringPQ = new PriorityQueue<>( + strings.size(), Collections.reverseOrder()); + stringPQ.addAll(strings); + QueueDemo.printQ(stringPQ); + + Set charSet = new HashSet<>(); + for(char c : fact.toCharArray()) + charSet.add(c); // Autoboxing + PriorityQueue characterPQ = + new PriorityQueue<>(charSet); + QueueDemo.printQ(characterPQ); + } +} +/* Output: +0 1 1 1 1 1 3 5 8 14 +1 1 2 3 3 9 9 14 14 18 18 20 21 22 23 25 25 +25 25 23 22 21 20 18 18 14 14 9 9 3 3 2 1 1 + A A B C C C D D E E E F H H I I L N N O O O O S S +S T T U U U W +W U U U T T S S S O O O O N N L I I H H F E E E D D C C +C B A A + A B C D E F H I L N O S T U W +*/ diff --git a/code/collections/QueueDemo.java b/code/collections/QueueDemo.java new file mode 100644 index 00000000..f807e89a --- /dev/null +++ b/code/collections/QueueDemo.java @@ -0,0 +1,29 @@ +// collections/QueueDemo.java +// (c)2020 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. +// Upcasting to a Queue from a LinkedList +import java.util.*; + +public class QueueDemo { + public static void printQ(Queue queue) { + while(queue.peek() != null) + System.out.print(queue.remove() + " "); + System.out.println(); + } + public static void main(String[] args) { + Queue queue = new LinkedList<>(); + Random rand = new Random(47); + for(int i = 0; i < 10; i++) + queue.offer(rand.nextInt(i + 10)); + printQ(queue); + Queue qc = new LinkedList<>(); + for(char c : "Brontosaurus".toCharArray()) + qc.offer(c); + printQ(qc); + } +} +/* Output: +8 1 1 1 5 14 3 1 0 1 +B r o n t o s a u r u s +*/ diff --git a/code/collections/SetOfInteger.java b/code/collections/SetOfInteger.java new file mode 100644 index 00000000..78157d5c --- /dev/null +++ b/code/collections/SetOfInteger.java @@ -0,0 +1,19 @@ +// collections/SetOfInteger.java +// (c)2020 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. +import java.util.*; + +public class SetOfInteger { + public static void main(String[] args) { + Random rand = new Random(47); + Set intset = new HashSet<>(); + for(int i = 0; i < 10000; i++) + intset.add(rand.nextInt(30)); + System.out.println(intset); + } +} +/* Output: +[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, +16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29] +*/ diff --git a/code/collections/SetOfString.java b/code/collections/SetOfString.java new file mode 100644 index 00000000..01d9455e --- /dev/null +++ b/code/collections/SetOfString.java @@ -0,0 +1,25 @@ +// collections/SetOfString.java +// (c)2020 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. +import java.util.*; + +public class SetOfString { + public static void main(String[] args) { + Set colors = new HashSet<>(); + for(int i = 0; i < 100; i++) { + colors.add("Yellow"); + colors.add("Blue"); + colors.add("Red"); + colors.add("Red"); + colors.add("Orange"); + colors.add("Yellow"); + colors.add("Blue"); + colors.add("Purple"); + } + System.out.println(colors); + } +} +/* Output: +[Red, Yellow, Blue, Purple, Orange] +*/ diff --git a/code/collections/SetOperations.java b/code/collections/SetOperations.java new file mode 100644 index 00000000..f716f965 --- /dev/null +++ b/code/collections/SetOperations.java @@ -0,0 +1,40 @@ +// collections/SetOperations.java +// (c)2020 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. +import java.util.*; + +public class SetOperations { + public static void main(String[] args) { + Set set1 = new HashSet<>(); + Collections.addAll(set1, + "A B C D E F G H I J K L".split(" ")); + set1.add("M"); + System.out.println("H: " + set1.contains("H")); + System.out.println("N: " + set1.contains("N")); + Set set2 = new HashSet<>(); + Collections.addAll(set2, "H I J K L".split(" ")); + System.out.println( + "set2 in set1: " + set1.containsAll(set2)); + set1.remove("H"); + System.out.println("set1: " + set1); + System.out.println( + "set2 in set1: " + set1.containsAll(set2)); + set1.removeAll(set2); + System.out.println( + "set2 removed from set1: " + set1); + Collections.addAll(set1, "X Y Z".split(" ")); + System.out.println( + "'X Y Z' added to set1: " + set1); + } +} +/* Output: +H: true +N: false +set2 in set1: true +set1: [A, B, C, D, E, F, G, I, J, K, L, M] +set2 in set1: false +set2 removed from set1: [A, B, C, D, E, F, G, M] +'X Y Z' added to set1: [A, B, C, D, E, F, G, M, X, Y, +Z] +*/ diff --git a/code/collections/SimpleCollection.java b/code/collections/SimpleCollection.java new file mode 100644 index 00000000..8915e259 --- /dev/null +++ b/code/collections/SimpleCollection.java @@ -0,0 +1,18 @@ +// collections/SimpleCollection.java +// (c)2020 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. +import java.util.*; + +public class SimpleCollection { + public static void main(String[] args) { + Collection c = new ArrayList<>(); + for(int i = 0; i < 10; i++) + c.add(i); // Autoboxing + for(Integer i : c) + System.out.print(i + ", "); + } +} +/* Output: +0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +*/ diff --git a/code/collections/SimpleIteration.java b/code/collections/SimpleIteration.java new file mode 100644 index 00000000..a65a2a71 --- /dev/null +++ b/code/collections/SimpleIteration.java @@ -0,0 +1,36 @@ +// collections/SimpleIteration.java +// (c)2020 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. +import typeinfo.pets.*; +import java.util.*; + +public class SimpleIteration { + public static void main(String[] args) { + List pets = Pets.list(12); + Iterator it = pets.iterator(); + while(it.hasNext()) { + Pet p = it.next(); + System.out.print(p.id() + ":" + p + " "); + } + System.out.println(); + // A simpler approach, when possible: + for(Pet p : pets) + System.out.print(p.id() + ":" + p + " "); + System.out.println(); + // An Iterator can also remove elements: + it = pets.iterator(); + for(int i = 0; i < 6; i++) { + it.next(); + it.remove(); + } + System.out.println(pets); + } +} +/* Output: +0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug +7:Manx 8:Cymric 9:Rat 10:EgyptianMau 11:Hamster +0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug +7:Manx 8:Cymric 9:Rat 10:EgyptianMau 11:Hamster +[Pug, Manx, Cymric, Rat, EgyptianMau, Hamster] +*/ diff --git a/code/collections/SortedSetOfString.java b/code/collections/SortedSetOfString.java new file mode 100644 index 00000000..a043b791 --- /dev/null +++ b/code/collections/SortedSetOfString.java @@ -0,0 +1,25 @@ +// collections/SortedSetOfString.java +// (c)2020 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. +import java.util.*; + +public class SortedSetOfString { + public static void main(String[] args) { + Set colors = new TreeSet<>(); + for(int i = 0; i < 100; i++) { + colors.add("Yellow"); + colors.add("Blue"); + colors.add("Red"); + colors.add("Red"); + colors.add("Orange"); + colors.add("Yellow"); + colors.add("Blue"); + colors.add("Purple"); + } + System.out.println(colors); + } +} +/* Output: +[Blue, Orange, Purple, Red, Yellow] +*/ diff --git a/code/collections/StackCollision.java b/code/collections/StackCollision.java new file mode 100644 index 00000000..67ee4d90 --- /dev/null +++ b/code/collections/StackCollision.java @@ -0,0 +1,25 @@ +// collections/StackCollision.java +// (c)2020 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. + +public class StackCollision { + public static void main(String[] args) { + onjava.Stack stack = new onjava.Stack<>(); + for(String s : "My dog has fleas".split(" ")) + stack.push(s); + while(!stack.isEmpty()) + System.out.print(stack.pop() + " "); + System.out.println(); + java.util.Stack stack2 = + new java.util.Stack<>(); + for(String s : "My dog has fleas".split(" ")) + stack2.push(s); + while(!stack2.empty()) + System.out.print(stack2.pop() + " "); + } +} +/* Output: +fleas has dog My +fleas has dog My +*/ diff --git a/code/collections/StackTest.java b/code/collections/StackTest.java new file mode 100644 index 00000000..dc1663cc --- /dev/null +++ b/code/collections/StackTest.java @@ -0,0 +1,18 @@ +// collections/StackTest.java +// (c)2020 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. +import java.util.*; + +public class StackTest { + public static void main(String[] args) { + Deque stack = new ArrayDeque<>(); + for(String s : "My dog has fleas".split(" ")) + stack.push(s); + while(!stack.isEmpty()) + System.out.print(stack.pop() + " "); + } +} +/* Output: +fleas has dog My +*/ diff --git a/code/collections/StackTest2.java b/code/collections/StackTest2.java new file mode 100644 index 00000000..2464d7a9 --- /dev/null +++ b/code/collections/StackTest2.java @@ -0,0 +1,18 @@ +// collections/StackTest2.java +// (c)2020 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. +import onjava.*; + +public class StackTest2 { + public static void main(String[] args) { + Stack stack = new Stack<>(); + for(String s : "My dog has fleas".split(" ")) + stack.push(s); + while(!stack.isEmpty()) + System.out.print(stack.pop() + " "); + } +} +/* Output: +fleas has dog My +*/ diff --git a/code/collections/Statistics.java b/code/collections/Statistics.java new file mode 100644 index 00000000..f888db58 --- /dev/null +++ b/code/collections/Statistics.java @@ -0,0 +1,25 @@ +// collections/Statistics.java +// (c)2020 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. +// Simple demonstration of HashMap +import java.util.*; + +public class Statistics { + public static void main(String[] args) { + Random rand = new Random(47); + Map m = new HashMap<>(); + for(int i = 0; i < 10000; i++) { + // Produce a number between 0 and 20: + int r = rand.nextInt(20); + Integer freq = m.get(r); // [1] + m.put(r, freq == null ? 1 : freq + 1); + } + System.out.println(m); + } +} +/* Output: +{0=481, 1=502, 2=489, 3=508, 4=481, 5=503, 6=519, +7=471, 8=468, 9=549, 10=513, 11=531, 12=521, 13=506, +14=477, 15=497, 16=533, 17=509, 18=478, 19=464} +*/ diff --git a/code/collections/UniqueWords.java b/code/collections/UniqueWords.java new file mode 100644 index 00000000..c6c3681d --- /dev/null +++ b/code/collections/UniqueWords.java @@ -0,0 +1,29 @@ +// collections/UniqueWords.java +// (c)2020 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. +import java.util.*; +import java.nio.file.*; + +public class UniqueWords { + public static void + main(String[] args) throws Exception { + List lines = Files.readAllLines( + Paths.get("SetOperations.java")); + Set words = new TreeSet<>(); + for(String line : lines) + for(String word : line.split("\\W+")) + if(word.trim().length() > 0) + words.add(word); + System.out.println(words); + } +} +/* Output: +[A, B, C, Collections, D, E, F, G, H, HashSet, I, J, K, +L, M, N, Output, Set, SetOperations, String, System, X, +Y, Z, add, addAll, added, args, class, collections, +contains, containsAll, false, from, import, in, java, +main, new, out, println, public, remove, removeAll, +removed, set1, set2, split, static, to, true, util, +void] +*/ diff --git a/code/collections/UniqueWordsAlphabetic.java b/code/collections/UniqueWordsAlphabetic.java new file mode 100644 index 00000000..66a7fecf --- /dev/null +++ b/code/collections/UniqueWordsAlphabetic.java @@ -0,0 +1,30 @@ +// collections/UniqueWordsAlphabetic.java +// (c)2020 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. +// Producing an alphabetic listing +import java.util.*; +import java.nio.file.*; + +public class UniqueWordsAlphabetic { + public static void + main(String[] args) throws Exception { + List lines = Files.readAllLines( + Paths.get("SetOperations.java")); + Set words = + new TreeSet<>(String.CASE_INSENSITIVE_ORDER); + for(String line : lines) + for(String word : line.split("\\W+")) + if(word.trim().length() > 0) + words.add(word); + System.out.println(words); + } +} +/* Output: +[A, add, addAll, added, args, B, C, class, collections, +contains, containsAll, D, E, F, false, from, G, H, +HashSet, I, import, in, J, java, K, L, M, main, N, new, +out, Output, println, public, remove, removeAll, +removed, Set, set1, set2, SetOperations, split, static, +String, System, to, true, util, void, X, Y, Z] +*/ diff --git a/code/collectiontopics/AssociativeArray.java b/code/collectiontopics/AssociativeArray.java new file mode 100644 index 00000000..e7488489 --- /dev/null +++ b/code/collectiontopics/AssociativeArray.java @@ -0,0 +1,64 @@ +// collectiontopics/AssociativeArray.java +// (c)2020 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. +// Associates keys with values + +public class AssociativeArray { + private Object[][] pairs; + private int index; + public AssociativeArray(int length) { + pairs = new Object[length][2]; + } + public void put(K key, V value) { + if(index >= pairs.length) + throw new ArrayIndexOutOfBoundsException(); + pairs[index++] = new Object[]{ key, value }; + } + @SuppressWarnings("unchecked") + public V get(K key) { + for(int i = 0; i < index; i++) + if(key.equals(pairs[i][0])) + return (V)pairs[i][1]; + return null; // Did not find key + } + @Override + public String toString() { + StringBuilder result = new StringBuilder(); + for(int i = 0; i < index; i++) { + result.append(pairs[i][0].toString()); + result.append(" : "); + result.append(pairs[i][1].toString()); + if(i < index - 1) + result.append("\n"); + } + return result.toString(); + } + public static void main(String[] args) { + AssociativeArray map = + new AssociativeArray<>(6); + map.put("sky", "blue"); + map.put("grass", "green"); + map.put("ocean", "dancing"); + map.put("tree", "tall"); + map.put("earth", "brown"); + map.put("sun", "warm"); + try { + map.put("extra", "object"); // Past the end + } catch(ArrayIndexOutOfBoundsException e) { + System.out.println("Too many objects!"); + } + System.out.println(map); + System.out.println(map.get("ocean")); + } +} +/* Output: +Too many objects! +sky : blue +grass : green +ocean : dancing +tree : tall +earth : brown +sun : warm +dancing +*/ diff --git a/code/collectiontopics/Bits.java b/code/collectiontopics/Bits.java new file mode 100644 index 00000000..16afb361 --- /dev/null +++ b/code/collectiontopics/Bits.java @@ -0,0 +1,79 @@ +// collectiontopics/Bits.java +// (c)2020 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. +// Demonstration of BitSet +import java.util.*; + +public class Bits { + public static void printBitSet(BitSet b) { + System.out.println("bits: " + b); + StringBuilder bbits = new StringBuilder(); + for(int j = 0; j < b.size() ; j++) + bbits.append(b.get(j) ? "1" : "0"); + System.out.println("bit pattern: " + bbits); + } + public static void main(String[] args) { + Random rand = new Random(47); + // Take the LSB of nextInt(): + byte bt = (byte)rand.nextInt(); + BitSet bb = new BitSet(); + for(int i = 7; i >= 0; i--) + if(((1 << i) & bt) != 0) + bb.set(i); + else + bb.clear(i); + System.out.println("byte value: " + bt); + printBitSet(bb); + + short st = (short)rand.nextInt(); + BitSet bs = new BitSet(); + for(int i = 15; i >= 0; i--) + if(((1 << i) & st) != 0) + bs.set(i); + else + bs.clear(i); + System.out.println("short value: " + st); + printBitSet(bs); + + int it = rand.nextInt(); + BitSet bi = new BitSet(); + for(int i = 31; i >= 0; i--) + if(((1 << i) & it) != 0) + bi.set(i); + else + bi.clear(i); + System.out.println("int value: " + it); + printBitSet(bi); + + // Test bitsets >= 64 bits: + BitSet b127 = new BitSet(); + b127.set(127); + System.out.println("set bit 127: " + b127); + BitSet b255 = new BitSet(65); + b255.set(255); + System.out.println("set bit 255: " + b255); + BitSet b1023 = new BitSet(512); + b1023.set(1023); + b1023.set(1024); + System.out.println("set bit 1023: " + b1023); + } +} +/* Output: +byte value: -107 +bits: {0, 2, 4, 7} +bit pattern: 101010010000000000000000000000000000000000 +0000000000000000000000 +short value: 1302 +bits: {1, 2, 4, 8, 10} +bit pattern: 011010001010000000000000000000000000000000 +0000000000000000000000 +int value: -2014573909 +bits: {0, 1, 3, 5, 7, 9, 11, 18, 19, 21, 22, 23, 24, +25, 26, 31} +bit pattern: 110101010101000000110111111000010000000000 +0000000000000000000000 +set bit 127: {127} +set bit 255: {255} +set bit 1023: {1023, 1024} +*/ diff --git a/code/collectiontopics/CanonicalMapping.java b/code/collectiontopics/CanonicalMapping.java new file mode 100644 index 00000000..c02f9132 --- /dev/null +++ b/code/collectiontopics/CanonicalMapping.java @@ -0,0 +1,56 @@ +// collectiontopics/CanonicalMapping.java +// (c)2020 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. +// Demonstrates WeakHashMap +import java.util.*; + +class Element { + private String ident; + Element(String id) { ident = id; } + @Override + public String toString() { return ident; } + @Override + public int hashCode() { + return Objects.hashCode(ident); + } + @Override + public boolean equals(Object r) { + return r instanceof Element && + Objects.equals(ident, ((Element)r).ident); + } + @SuppressWarnings("deprecation") + @Override + protected void finalize() { + System.out.println("Finalizing " + + getClass().getSimpleName() + " " + ident); + } +} + +class Key extends Element { + Key(String id) { super(id); } +} + +class Value extends Element { + Value(String id) { super(id); } +} + +public class CanonicalMapping { + public static void main(String[] args) { + int size = 1000; + // Or, choose size via the command line: + if(args.length > 0) + size = Integer.valueOf(args[0]); + Key[] keys = new Key[size]; + WeakHashMap map = + new WeakHashMap<>(); + for(int i = 0; i < size; i++) { + Key k = new Key(Integer.toString(i)); + Value v = new Value(Integer.toString(i)); + if(i % 3 == 0) + keys[i] = k; // Save as "real" references + map.put(k, v); + } + System.gc(); + } +} diff --git a/code/collectiontopics/CollectionMethods.java b/code/collectiontopics/CollectionMethods.java new file mode 100644 index 00000000..e32e5982 --- /dev/null +++ b/code/collectiontopics/CollectionMethods.java @@ -0,0 +1,135 @@ +// collectiontopics/CollectionMethods.java +// (c)2020 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. +// Things you can do with all Collections +import java.util.*; +import static onjava.HTMLColors.*; + +public class CollectionMethods { + public static void main(String[] args) { + Collection c = + new ArrayList<>(LIST.subList(0, 4)); + c.add("ten"); + c.add("eleven"); + show(c); + border(); + // Make an array from the List: + Object[] array = c.toArray(); + // Make a String array from the List: + String[] str = c.toArray(new String[0]); + // Find max and min elements; this means + // different things depending on the way + // the Comparable interface is implemented: + System.out.println( + "Collections.max(c) = " + Collections.max(c)); + System.out.println( + "Collections.min(c) = " + Collections.min(c)); + border(); + // Add a Collection to another Collection + Collection c2 = + new ArrayList<>(LIST.subList(10, 14)); + c.addAll(c2); + show(c); + border(); + c.remove(LIST.get(0)); + show(c); + border(); + // Remove all components that are + // in the argument collection: + c.removeAll(c2); + show(c); + border(); + c.addAll(c2); + show(c); + border(); + // Is an element in this Collection? + String val = LIST.get(3); + System.out.println( + "c.contains(" + val + ") = " + c.contains(val)); + // Is a Collection in this Collection? + System.out.println( + "c.containsAll(c2) = " + c.containsAll(c2)); + Collection c3 = + ((List)c).subList(3, 5); + // Keep all the elements that are in both + // c2 and c3 (an intersection of sets): + c2.retainAll(c3); + show(c2); + // Throw away all the elements + // in c2 that also appear in c3: + c2.removeAll(c3); + System.out.println( + "c2.isEmpty() = " + c2.isEmpty()); + border(); + // Functional operation: + c = new ArrayList<>(LIST); + c.removeIf(s -> !s.startsWith("P")); + c.removeIf(s -> s.startsWith("Pale")); + // Stream operation: + c.stream().forEach(System.out::println); + c.clear(); // Remove all elements + System.out.println("after c.clear():" + c); + } +} +/* Output: +AliceBlue +AntiqueWhite +Aquamarine +Azure +ten +eleven +****************************** +Collections.max(c) = ten +Collections.min(c) = AliceBlue +****************************** +AliceBlue +AntiqueWhite +Aquamarine +Azure +ten +eleven +Brown +BurlyWood +CadetBlue +Chartreuse +****************************** +AntiqueWhite +Aquamarine +Azure +ten +eleven +Brown +BurlyWood +CadetBlue +Chartreuse +****************************** +AntiqueWhite +Aquamarine +Azure +ten +eleven +****************************** +AntiqueWhite +Aquamarine +Azure +ten +eleven +Brown +BurlyWood +CadetBlue +Chartreuse +****************************** +c.contains(Azure) = true +c.containsAll(c2) = true +c2.isEmpty() = true +****************************** +PapayaWhip +PeachPuff +Peru +Pink +Plum +PowderBlue +Purple +after c.clear():[] +*/ diff --git a/code/collectiontopics/Enumerations.java b/code/collectiontopics/Enumerations.java new file mode 100644 index 00000000..22b83e52 --- /dev/null +++ b/code/collectiontopics/Enumerations.java @@ -0,0 +1,24 @@ +// collectiontopics/Enumerations.java +// (c)2020 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. +// Java 1.0/1.1 Vector and Enumeration +import java.util.*; +import onjava.*; + +public class Enumerations { + public static void main(String[] args) { + Vector v = + new Vector<>(Countries.names(10)); + Enumeration e = v.elements(); + while(e.hasMoreElements()) + System.out.print(e.nextElement() + ", "); + // Produce an Enumeration from a Collection: + e = Collections.enumeration(new ArrayList<>()); + } +} +/* Output: +ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, +BURUNDI, CAMEROON, CAPE VERDE, CENTRAL AFRICAN +REPUBLIC, CHAD, +*/ diff --git a/code/collectiontopics/FailFast.java b/code/collectiontopics/FailFast.java new file mode 100644 index 00000000..0b0ce253 --- /dev/null +++ b/code/collectiontopics/FailFast.java @@ -0,0 +1,22 @@ +// collectiontopics/FailFast.java +// (c)2020 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. +// Demonstrates the "fail-fast" behavior +import java.util.*; + +public class FailFast { + public static void main(String[] args) { + Collection c = new ArrayList<>(); + Iterator it = c.iterator(); + c.add("An object"); + try { + String s = it.next(); + } catch(ConcurrentModificationException e) { + System.out.println(e); + } + } +} +/* Output: +java.util.ConcurrentModificationException +*/ diff --git a/code/collectiontopics/FillMapTest.java b/code/collectiontopics/FillMapTest.java new file mode 100644 index 00000000..5cfd612b --- /dev/null +++ b/code/collectiontopics/FillMapTest.java @@ -0,0 +1,32 @@ +// collectiontopics/FillMapTest.java +// (c)2020 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. +import java.util.*; +import java.util.function.*; +import java.util.stream.*; +import onjava.*; + +public class FillMapTest { + public static void main(String[] args) { + Map mcs = FillMap.basic( + new Rand.String(4), new Count.Integer(), 7); + System.out.println(mcs); + HashMap hashm = + FillMap.create(new Rand.String(4), + new Count.Integer(), HashMap::new, 7); + System.out.println(hashm); + LinkedHashMap linkm = + FillMap.create(new Rand.String(4), + new Count.Integer(), LinkedHashMap::new, 7); + System.out.println(linkm); + } +} +/* Output: +{npcc=1, ztdv=6, gvgm=3, btpe=0, einn=4, eelo=5, +uxsz=2} +{npcc=1, ztdv=6, gvgm=3, btpe=0, einn=4, eelo=5, +uxsz=2} +{btpe=0, npcc=1, uxsz=2, gvgm=3, einn=4, eelo=5, +ztdv=6} +*/ diff --git a/code/collectiontopics/FillingLists.java b/code/collectiontopics/FillingLists.java new file mode 100644 index 00000000..32bdb8ef --- /dev/null +++ b/code/collectiontopics/FillingLists.java @@ -0,0 +1,35 @@ +// collectiontopics/FillingLists.java +// (c)2020 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. +// Collections.fill() & Collections.nCopies() +import java.util.*; + +class StringAddress { + private String s; + StringAddress(String s) { this.s = s; } + @Override + public String toString() { + return super.toString() + " " + s; + } +} + +public class FillingLists { + public static void main(String[] args) { + List list = new ArrayList<>( + Collections.nCopies(4, + new StringAddress("Hello"))); + System.out.println(list); + Collections.fill(list, + new StringAddress("World!")); + System.out.println(list); + } +} +/* Output: +[StringAddress@15db9742 Hello, StringAddress@15db9742 +Hello, StringAddress@15db9742 Hello, +StringAddress@15db9742 Hello] +[StringAddress@6d06d69c World!, StringAddress@6d06d69c +World!, StringAddress@6d06d69c World!, +StringAddress@6d06d69c World!] +*/ diff --git a/code/collectiontopics/FunctionalMap.java b/code/collectiontopics/FunctionalMap.java new file mode 100644 index 00000000..404a1a64 --- /dev/null +++ b/code/collectiontopics/FunctionalMap.java @@ -0,0 +1,38 @@ +// collectiontopics/FunctionalMap.java +// (c)2020 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. +// Functional operations on a Map +import java.util.*; +import java.util.stream.*; +import java.util.concurrent.*; +import static onjava.HTMLColors.*; + +public class FunctionalMap { + public static void main(String[] args) { + MAP.entrySet().stream() + .map(Map.Entry::getValue) + .filter(v -> v.startsWith("Dark")) + .map(v -> v.replaceFirst("Dark", "Hot")) + .forEach(System.out::println); + } +} +/* Output: +HotBlue +HotCyan +HotGoldenRod +HotGray +HotGreen +HotKhaki +HotMagenta +HotOliveGreen +HotOrange +HotOrchid +HotRed +HotSalmon +HotSeaGreen +HotSlateBlue +HotSlateGray +HotTurquoise +HotViolet +*/ diff --git a/code/collectiontopics/HTMLColorTest.java b/code/collectiontopics/HTMLColorTest.java new file mode 100644 index 00000000..99037ced --- /dev/null +++ b/code/collectiontopics/HTMLColorTest.java @@ -0,0 +1,103 @@ +// collectiontopics/HTMLColorTest.java +// (c)2020 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. +import static onjava.HTMLColors.*; + +public class HTMLColorTest { + static final int DISPLAY_SIZE = 20; + public static void main(String[] args) { + show(MAP, DISPLAY_SIZE); + border(); + showInv(INVMAP, DISPLAY_SIZE); + border(); + show(LIST, DISPLAY_SIZE); + border(); + showrgb(RGBLIST, DISPLAY_SIZE); + } +} +/* Output: +0xF0F8FF: AliceBlue +0xFAEBD7: AntiqueWhite +0x7FFFD4: Aquamarine +0xF0FFFF: Azure +0xF5F5DC: Beige +0xFFE4C4: Bisque +0x000000: Black +0xFFEBCD: BlanchedAlmond +0x0000FF: Blue +0x8A2BE2: BlueViolet +0xA52A2A: Brown +0xDEB887: BurlyWood +0x5F9EA0: CadetBlue +0x7FFF00: Chartreuse +0xD2691E: Chocolate +0xFF7F50: Coral +0x6495ED: CornflowerBlue +0xFFF8DC: Cornsilk +0xDC143C: Crimson +0x00FFFF: Cyan +****************************** +AliceBlue 0xF0F8FF +AntiqueWhite 0xFAEBD7 +Aquamarine 0x7FFFD4 +Azure 0xF0FFFF +Beige 0xF5F5DC +Bisque 0xFFE4C4 +Black 0x000000 +BlanchedAlmond 0xFFEBCD +Blue 0x0000FF +BlueViolet 0x8A2BE2 +Brown 0xA52A2A +BurlyWood 0xDEB887 +CadetBlue 0x5F9EA0 +Chartreuse 0x7FFF00 +Chocolate 0xD2691E +Coral 0xFF7F50 +CornflowerBlue 0x6495ED +Cornsilk 0xFFF8DC +Crimson 0xDC143C +Cyan 0x00FFFF +****************************** +AliceBlue +AntiqueWhite +Aquamarine +Azure +Beige +Bisque +Black +BlanchedAlmond +Blue +BlueViolet +Brown +BurlyWood +CadetBlue +Chartreuse +Chocolate +Coral +CornflowerBlue +Cornsilk +Crimson +Cyan +****************************** +0xF0F8FF +0xFAEBD7 +0x7FFFD4 +0xF0FFFF +0xF5F5DC +0xFFE4C4 +0x000000 +0xFFEBCD +0x0000FF +0x8A2BE2 +0xA52A2A +0xDEB887 +0x5F9EA0 +0x7FFF00 +0xD2691E +0xFF7F50 +0x6495ED +0xFFF8DC +0xDC143C +0x00FFFF +*/ diff --git a/code/collectiontopics/LinkedHashMapDemo.java b/code/collectiontopics/LinkedHashMapDemo.java new file mode 100644 index 00000000..d0b93393 --- /dev/null +++ b/code/collectiontopics/LinkedHashMapDemo.java @@ -0,0 +1,31 @@ +// collectiontopics/LinkedHashMapDemo.java +// (c)2020 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 LinkedHashMap +import java.util.*; +import onjava.*; + +public class LinkedHashMapDemo { + public static void main(String[] args) { + LinkedHashMap linkedMap = + new LinkedHashMap<>(new CountMap(9)); + System.out.println(linkedMap); + // Least-recently-used order: + linkedMap = + new LinkedHashMap<>(16, 0.75f, true); + linkedMap.putAll(new CountMap(9)); + System.out.println(linkedMap); + for(int i = 0; i < 6; i++) + linkedMap.get(i); + System.out.println(linkedMap); + linkedMap.get(0); + System.out.println(linkedMap); + } +} +/* Output: +{0=A0, 1=B0, 2=C0, 3=D0, 4=E0, 5=F0, 6=G0, 7=H0, 8=I0} +{0=A0, 1=B0, 2=C0, 3=D0, 4=E0, 5=F0, 6=G0, 7=H0, 8=I0} +{6=G0, 7=H0, 8=I0, 0=A0, 1=B0, 2=C0, 3=D0, 4=E0, 5=F0} +{6=G0, 7=H0, 8=I0, 1=B0, 2=C0, 3=D0, 4=E0, 5=F0, 0=A0} +*/ diff --git a/code/collectiontopics/ListOps.java b/code/collectiontopics/ListOps.java new file mode 100644 index 00000000..824ffba9 --- /dev/null +++ b/code/collectiontopics/ListOps.java @@ -0,0 +1,167 @@ +// collectiontopics/ListOps.java +// (c)2020 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. +// Things you can do with Lists +import java.util.*; +import onjava.HTMLColors; + +public class ListOps { + // Create a short list for testing: + static final List LIST = + HTMLColors.LIST.subList(0, 10); + private static boolean b; + private static String s; + private static int i; + private static Iterator it; + private static ListIterator lit; + public static void basicTest(List a) { + a.add(1, "x"); // Add at location 1 + a.add("x"); // Add at end + // Add a collection: + a.addAll(LIST); + // Add a collection starting at location 3: + a.addAll(3, LIST); + b = a.contains("1"); // Is it in there? + // Is the entire collection in there? + b = a.containsAll(LIST); + // Lists allow random access, which is cheap + // for ArrayList, expensive for LinkedList: + s = a.get(1); // Get (typed) object at location 1 + i = a.indexOf("1"); // Tell index of object + b = a.isEmpty(); // Any elements inside? + it = a.iterator(); // Ordinary Iterator + lit = a.listIterator(); // ListIterator + lit = a.listIterator(3); // Start at location 3 + i = a.lastIndexOf("1"); // Last match + a.remove(1); // Remove location 1 + a.remove("3"); // Remove this object + a.set(1, "y"); // Set location 1 to "y" + // Keep everything that's in the argument + // (the intersection of the two sets): + a.retainAll(LIST); + // Remove everything that's in the argument: + a.removeAll(LIST); + i = a.size(); // How big is it? + a.clear(); // Remove all elements + } + public static void iterMotion(List a) { + ListIterator it = a.listIterator(); + b = it.hasNext(); + b = it.hasPrevious(); + s = it.next(); + i = it.nextIndex(); + s = it.previous(); + i = it.previousIndex(); + } + public static void iterManipulation(List a) { + ListIterator it = a.listIterator(); + it.add("47"); + // Must move to an element after add(): + it.next(); + // Remove the element after the new one: + it.remove(); + // Must move to an element after remove(): + it.next(); + // Change the element after the deleted one: + it.set("47"); + } + public static void testVisual(List a) { + System.out.println(a); + List b = LIST; + System.out.println("b = " + b); + a.addAll(b); + a.addAll(b); + System.out.println(a); + // Insert, remove, and replace elements + // using a ListIterator: + ListIterator x = + a.listIterator(a.size()/2); + x.add("one"); + System.out.println(a); + System.out.println(x.next()); + x.remove(); + System.out.println(x.next()); + x.set("47"); + System.out.println(a); + // Traverse the list backwards: + x = a.listIterator(a.size()); + while(x.hasPrevious()) + System.out.print(x.previous() + " "); + System.out.println(); + System.out.println("testVisual finished"); + } + // There are some things that only LinkedLists can do: + public static void testLinkedList() { + LinkedList ll = new LinkedList<>(); + ll.addAll(LIST); + System.out.println(ll); + // Treat it like a stack, pushing: + ll.addFirst("one"); + ll.addFirst("two"); + System.out.println(ll); + // Like "peeking" at the top of a stack: + System.out.println(ll.getFirst()); + // Like popping a stack: + System.out.println(ll.removeFirst()); + System.out.println(ll.removeFirst()); + // Treat it like a queue, pulling elements + // off the tail end: + System.out.println(ll.removeLast()); + System.out.println(ll); + } + public static void main(String[] args) { + // Make and fill a new list each time: + basicTest(new LinkedList<>(LIST)); + basicTest(new ArrayList<>(LIST)); + iterMotion(new LinkedList<>(LIST)); + iterMotion(new ArrayList<>(LIST)); + iterManipulation(new LinkedList<>(LIST)); + iterManipulation(new ArrayList<>(LIST)); + testVisual(new LinkedList<>(LIST)); + testLinkedList(); + } +} +/* Output: +[AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, +Bisque, Black, BlanchedAlmond, Blue, BlueViolet] +b = [AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, +Bisque, Black, BlanchedAlmond, Blue, BlueViolet] +[AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, +Bisque, Black, BlanchedAlmond, Blue, BlueViolet, +AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, +Bisque, Black, BlanchedAlmond, Blue, BlueViolet, +AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, +Bisque, Black, BlanchedAlmond, Blue, BlueViolet] +[AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, +Bisque, Black, BlanchedAlmond, Blue, BlueViolet, +AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, one, +Bisque, Black, BlanchedAlmond, Blue, BlueViolet, +AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, +Bisque, Black, BlanchedAlmond, Blue, BlueViolet] +Bisque +Black +[AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, +Bisque, Black, BlanchedAlmond, Blue, BlueViolet, +AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, one, +47, BlanchedAlmond, Blue, BlueViolet, AliceBlue, +AntiqueWhite, Aquamarine, Azure, Beige, Bisque, Black, +BlanchedAlmond, Blue, BlueViolet] +BlueViolet Blue BlanchedAlmond Black Bisque Beige Azure +Aquamarine AntiqueWhite AliceBlue BlueViolet Blue +BlanchedAlmond 47 one Beige Azure Aquamarine +AntiqueWhite AliceBlue BlueViolet Blue BlanchedAlmond +Black Bisque Beige Azure Aquamarine AntiqueWhite +AliceBlue +testVisual finished +[AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, +Bisque, Black, BlanchedAlmond, Blue, BlueViolet] +[two, one, AliceBlue, AntiqueWhite, Aquamarine, Azure, +Beige, Bisque, Black, BlanchedAlmond, Blue, BlueViolet] +two +two +one +BlueViolet +[AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, +Bisque, Black, BlanchedAlmond, Blue] +*/ diff --git a/code/collectiontopics/ListSortSearch.java b/code/collectiontopics/ListSortSearch.java new file mode 100644 index 00000000..4d1fbcf8 --- /dev/null +++ b/code/collectiontopics/ListSortSearch.java @@ -0,0 +1,57 @@ +// collectiontopics/ListSortSearch.java +// (c)2020 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. +// Sorting/searching Lists with Collections utilities +import java.util.*; + +public class ListSortSearch { + public static void main(String[] args) { + List list = + new ArrayList<>(Utilities.list); + list.addAll(Utilities.list); + System.out.println(list); + Collections.shuffle(list, new Random(47)); + System.out.println("Shuffled: " + list); + // Use ListIterator to trim off last elements: + ListIterator it = list.listIterator(10); + while(it.hasNext()) { + it.next(); + it.remove(); + } + System.out.println("Trimmed: " + list); + Collections.sort(list); + System.out.println("Sorted: " + list); + String key = list.get(7); + int index = Collections.binarySearch(list, key); + System.out.println( + "Location of " + key + " is " + index + + ", list.get(" + index + ") = " + + list.get(index)); + Collections.sort(list, + String.CASE_INSENSITIVE_ORDER); + System.out.println( + "Case-insensitive sorted: " + list); + key = list.get(7); + index = Collections.binarySearch(list, key, + String.CASE_INSENSITIVE_ORDER); + System.out.println( + "Location of " + key + " is " + index + + ", list.get(" + index + ") = " + + list.get(index)); + } +} +/* Output: +[one, Two, three, Four, five, six, one, one, Two, +three, Four, five, six, one] +Shuffled: [Four, five, one, one, Two, six, six, three, +three, five, Four, Two, one, one] +Trimmed: [Four, five, one, one, Two, six, six, three, +three, five] +Sorted: [Four, Two, five, five, one, one, six, six, +three, three] +Location of six is 7, list.get(7) = six +Case-insensitive sorted: [five, five, Four, one, one, +six, six, three, three, Two] +Location of three is 7, list.get(7) = three +*/ diff --git a/code/collectiontopics/MapOps.java b/code/collectiontopics/MapOps.java new file mode 100644 index 00000000..b214fa2d --- /dev/null +++ b/code/collectiontopics/MapOps.java @@ -0,0 +1,76 @@ +// collectiontopics/MapOps.java +// (c)2020 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. +// Things you can do with Maps +import java.util.concurrent.*; +import java.util.*; +import onjava.*; + +public class MapOps { + public static + void printKeys(Map map) { + System.out.print("Size = " + map.size() + ", "); + System.out.print("Keys: "); + // Produce a Set of the keys: + System.out.println(map.keySet()); + } + public static + void test(Map map) { + System.out.println( + map.getClass().getSimpleName()); + map.putAll(new CountMap(25)); + // Map has 'Set' behavior for keys: + map.putAll(new CountMap(25)); + printKeys(map); + // Producing a Collection of the values: + System.out.print("Values: "); + System.out.println(map.values()); + System.out.println(map); + System.out.println("map.containsKey(11): " + + map.containsKey(11)); + System.out.println( + "map.get(11): " + map.get(11)); + System.out.println("map.containsValue(\"F0\"): " + + map.containsValue("F0")); + Integer key = map.keySet().iterator().next(); + System.out.println("First key in map: " + key); + map.remove(key); + printKeys(map); + map.clear(); + System.out.println( + "map.isEmpty(): " + map.isEmpty()); + map.putAll(new CountMap(25)); + // Operations on the Set change the Map: + map.keySet().removeAll(map.keySet()); + System.out.println( + "map.isEmpty(): " + map.isEmpty()); + } + public static void main(String[] args) { + test(new HashMap<>()); + test(new TreeMap<>()); + test(new LinkedHashMap<>()); + test(new IdentityHashMap<>()); + test(new ConcurrentHashMap<>()); + test(new WeakHashMap<>()); + } +} +/* Output: (First 11 Lines) +HashMap +Size = 25, Keys: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, +12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] +Values: [A0, B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, +L0, M0, N0, O0, P0, Q0, R0, S0, T0, U0, V0, W0, X0, Y0] +{0=A0, 1=B0, 2=C0, 3=D0, 4=E0, 5=F0, 6=G0, 7=H0, 8=I0, +9=J0, 10=K0, 11=L0, 12=M0, 13=N0, 14=O0, 15=P0, 16=Q0, +17=R0, 18=S0, 19=T0, 20=U0, 21=V0, 22=W0, 23=X0, 24=Y0} +map.containsKey(11): true +map.get(11): L0 +map.containsValue("F0"): true +First key in map: 0 +Size = 24, Keys: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, +12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] +map.isEmpty(): true +map.isEmpty(): true + ... +*/ diff --git a/code/collectiontopics/NavMap.java b/code/collectiontopics/NavMap.java new file mode 100644 index 00000000..076ae841 --- /dev/null +++ b/code/collectiontopics/NavMap.java @@ -0,0 +1,96 @@ +// collectiontopics/NavMap.java +// (c)2020 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. +// NavigableMap produces pieces of a Map +import java.util.*; +import java.util.concurrent.*; +import static onjava.HTMLColors.*; + +public class NavMap { + public static final + NavigableMap COLORS = + new ConcurrentSkipListMap<>(MAP); + public static void main(String[] args) { + show(COLORS.firstEntry()); + border(); + show(COLORS.lastEntry()); + border(); + NavigableMap toLime = + COLORS.headMap(rgb("Lime"), true); + show(toLime); + border(); + show(COLORS.ceilingEntry(rgb("DeepSkyBlue") - 1)); + border(); + show(COLORS.floorEntry(rgb("DeepSkyBlue") - 1)); + border(); + show(toLime.descendingMap()); + border(); + show(COLORS.tailMap(rgb("MistyRose"), true)); + border(); + show(COLORS.subMap( + rgb("Orchid"), true, + rgb("DarkSalmon"), false)); + } +} +/* Output: +0x000000: Black +****************************** +0xFFFFFF: White +****************************** +0x000000: Black +0x000080: Navy +0x00008B: DarkBlue +0x0000CD: MediumBlue +0x0000FF: Blue +0x006400: DarkGreen +0x008000: Green +0x008080: Teal +0x008B8B: DarkCyan +0x00BFFF: DeepSkyBlue +0x00CED1: DarkTurquoise +0x00FA9A: MediumSpringGreen +0x00FF00: Lime +****************************** +0x00BFFF: DeepSkyBlue +****************************** +0x008B8B: DarkCyan +****************************** +0x00FF00: Lime +0x00FA9A: MediumSpringGreen +0x00CED1: DarkTurquoise +0x00BFFF: DeepSkyBlue +0x008B8B: DarkCyan +0x008080: Teal +0x008000: Green +0x006400: DarkGreen +0x0000FF: Blue +0x0000CD: MediumBlue +0x00008B: DarkBlue +0x000080: Navy +0x000000: Black +****************************** +0xFFE4E1: MistyRose +0xFFEBCD: BlanchedAlmond +0xFFEFD5: PapayaWhip +0xFFF0F5: LavenderBlush +0xFFF5EE: SeaShell +0xFFF8DC: Cornsilk +0xFFFACD: LemonChiffon +0xFFFAF0: FloralWhite +0xFFFAFA: Snow +0xFFFF00: Yellow +0xFFFFE0: LightYellow +0xFFFFF0: Ivory +0xFFFFFF: White +****************************** +0xDA70D6: Orchid +0xDAA520: GoldenRod +0xDB7093: PaleVioletRed +0xDC143C: Crimson +0xDCDCDC: Gainsboro +0xDDA0DD: Plum +0xDEB887: BurlyWood +0xE0FFFF: LightCyan +0xE6E6FA: Lavender +*/ diff --git a/code/collectiontopics/QueueBehavior.java b/code/collectiontopics/QueueBehavior.java new file mode 100644 index 00000000..136fbaf8 --- /dev/null +++ b/code/collectiontopics/QueueBehavior.java @@ -0,0 +1,50 @@ +// collectiontopics/QueueBehavior.java +// (c)2020 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 basic behavior +import java.util.*; +import java.util.stream.*; +import java.util.concurrent.*; + +public class QueueBehavior { + 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(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: +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/code/collectiontopics/ReadOnly.java b/code/collectiontopics/ReadOnly.java new file mode 100644 index 00000000..93c336c4 --- /dev/null +++ b/code/collectiontopics/ReadOnly.java @@ -0,0 +1,56 @@ +// collectiontopics/ReadOnly.java +// (c)2020 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. +// Using the Collections.unmodifiable methods +import java.util.*; +import onjava.*; + +public class ReadOnly { + static Collection data = + new ArrayList<>(Countries.names(6)); + public static void main(String[] args) { + Collection c = + Collections.unmodifiableCollection( + new ArrayList<>(data)); + System.out.println(c); // Reading is OK + //- c.add("one"); // Can't change it + + List a = Collections.unmodifiableList( + new ArrayList<>(data)); + ListIterator lit = a.listIterator(); + System.out.println(lit.next()); // Reading is OK + //- lit.add("one"); // Can't change it + + Set s = Collections.unmodifiableSet( + new HashSet<>(data)); + System.out.println(s); // Reading is OK + //- s.add("one"); // Can't change it + + // For a SortedSet: + Set ss = + Collections.unmodifiableSortedSet( + new TreeSet<>(data)); + + Map m = + Collections.unmodifiableMap( + new HashMap<>(Countries.capitals(6))); + System.out.println(m); // Reading is OK + //- m.put("Ralph", "Howdy!"); + + // For a SortedMap: + Map sm = + Collections.unmodifiableSortedMap( + new TreeMap<>(Countries.capitals(6))); + } +} +/* Output: +[ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, +BURUNDI] +ALGERIA +[BENIN, BOTSWANA, ANGOLA, BURKINA FASO, ALGERIA, +BURUNDI] +{BENIN=Porto-Novo, BOTSWANA=Gaberone, ANGOLA=Luanda, +BURKINA FASO=Ouagadougou, ALGERIA=Algiers, +BURUNDI=Bujumbura} +*/ diff --git a/code/collectiontopics/References.java b/code/collectiontopics/References.java new file mode 100644 index 00000000..5fcca940 --- /dev/null +++ b/code/collectiontopics/References.java @@ -0,0 +1,92 @@ +// collectiontopics/References.java +// (c)2020 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. +// Demonstrates Reference objects +import java.lang.ref.*; +import java.util.*; + +class VeryBig { + private static final int SIZE = 10000; + private long[] la = new long[SIZE]; + private String ident; + VeryBig(String id) { ident = id; } + @Override + public String toString() { return ident; } + @SuppressWarnings("deprecation") + @Override + protected void finalize() { + System.out.println("Finalizing " + ident); + } +} + +public class References { + private static ReferenceQueue rq = + new ReferenceQueue<>(); + public static void checkQueue() { + Reference inq = rq.poll(); + if(inq != null) + System.out.println("In queue: " + inq.get()); + } + public static void main(String[] args) { + int size = 10; + // Or, choose size via the command line: + if(args.length > 0) + size = Integer.valueOf(args[0]); + LinkedList> sa = + new LinkedList<>(); + for(int i = 0; i < size; i++) { + sa.add(new SoftReference<>( + new VeryBig("Soft " + i), rq)); + System.out.println( + "Just created: " + sa.getLast()); + checkQueue(); + } + LinkedList> wa = + new LinkedList<>(); + for(int i = 0; i < size; i++) { + wa.add(new WeakReference<>( + new VeryBig("Weak " + i), rq)); + System.out.println( + "Just created: " + wa.getLast()); + checkQueue(); + } + SoftReference s = + new SoftReference<>(new VeryBig("Soft")); + WeakReference w = + new WeakReference<>(new VeryBig("Weak")); + System.gc(); + LinkedList> pa = + new LinkedList<>(); + for(int i = 0; i < size; i++) { + pa.add(new PhantomReference<>( + new VeryBig("Phantom " + i), rq)); + System.out.println( + "Just created: " + pa.getLast()); + checkQueue(); + } + } +} +/* Output: (First and Last 10 Lines) +Just created: java.lang.ref.SoftReference@15db9742 +Just created: java.lang.ref.SoftReference@6d06d69c +Just created: java.lang.ref.SoftReference@7852e922 +Just created: java.lang.ref.SoftReference@4e25154f +Just created: java.lang.ref.SoftReference@70dea4e +Just created: java.lang.ref.SoftReference@5c647e05 +Just created: java.lang.ref.SoftReference@33909752 +Just created: java.lang.ref.SoftReference@55f96302 +Just created: java.lang.ref.SoftReference@3d4eac69 +Just created: java.lang.ref.SoftReference@42a57993 +...________...________...________...________... +Just created: java.lang.ref.PhantomReference@45ee12a7 +In queue: null +Just created: java.lang.ref.PhantomReference@330bedb4 +In queue: null +Just created: java.lang.ref.PhantomReference@2503dbd3 +In queue: null +Just created: java.lang.ref.PhantomReference@4b67cf4d +In queue: null +Just created: java.lang.ref.PhantomReference@7ea987ac +In queue: null +*/ diff --git a/code/collectiontopics/SetOrder.java b/code/collectiontopics/SetOrder.java new file mode 100644 index 00000000..1c25be23 --- /dev/null +++ b/code/collectiontopics/SetOrder.java @@ -0,0 +1,92 @@ +// collectiontopics/SetOrder.java +// (c)2020 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. +import java.util.*; +import onjava.HTMLColors; + +public class SetOrder { + static String[] sets = { + "java.util.HashSet", + "java.util.TreeSet", + "java.util.concurrent.ConcurrentSkipListSet", + "java.util.LinkedHashSet", + "java.util.concurrent.CopyOnWriteArraySet", + }; + static final List RLIST = + new ArrayList<>(HTMLColors.LIST); + static { + Collections.reverse(RLIST); + } + public static void + main(String[] args) throws Exception { + for(String type: sets) { + System.out.format("[-> %s <-]%n", + type.substring(type.lastIndexOf('.') + 1)); + @SuppressWarnings({"unchecked", "deprecation"}) + Set set = (Set) + Class.forName(type).newInstance(); + set.addAll(RLIST); + set.stream() + .limit(10) + .forEach(System.out::println); + } + } +} +/* Output: +[-> HashSet <-] +MediumOrchid +PaleGoldenRod +Sienna +LightSlateGray +DarkSeaGreen +Black +Gainsboro +Orange +LightCoral +DodgerBlue +[-> TreeSet <-] +AliceBlue +AntiqueWhite +Aquamarine +Azure +Beige +Bisque +Black +BlanchedAlmond +Blue +BlueViolet +[-> ConcurrentSkipListSet <-] +AliceBlue +AntiqueWhite +Aquamarine +Azure +Beige +Bisque +Black +BlanchedAlmond +Blue +BlueViolet +[-> LinkedHashSet <-] +YellowGreen +Yellow +WhiteSmoke +White +Wheat +Violet +Turquoise +Tomato +Thistle +Teal +[-> CopyOnWriteArraySet <-] +YellowGreen +Yellow +WhiteSmoke +White +Wheat +Violet +Turquoise +Tomato +Thistle +Teal +*/ diff --git a/code/collectiontopics/SimpleDeques.java b/code/collectiontopics/SimpleDeques.java new file mode 100644 index 00000000..fbb4a5ff --- /dev/null +++ b/code/collectiontopics/SimpleDeques.java @@ -0,0 +1,70 @@ +// collectiontopics/SimpleDeques.java +// (c)2020 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. +// Very basic test of Deques +import java.util.*; +import java.util.concurrent.*; +import java.util.function.*; + +class CountString implements Supplier { + private int n = 0; + CountString() {} + CountString(int start) { n = start; } + @Override + public String get() { + return Integer.toString(n++); + } +} + +public class SimpleDeques { + static void test(Deque deque) { + CountString s1 = new CountString(), + s2 = new CountString(20); + for(int n = 0; n < 8; n++) { + deque.offerFirst(s1.get()); + deque.offerLast(s2.get()); // Same as offer() + } + System.out.println(deque); + String result = ""; + while(deque.size() > 0) { + System.out.print(deque.peekFirst() + " "); + result += deque.pollFirst() + " "; + System.out.print(deque.peekLast() + " "); + result += deque.pollLast() + " "; + } + System.out.println("\n" + result); + } + public static void main(String[] args) { + int count = 10; + System.out.println("LinkedList"); + test(new LinkedList<>()); + System.out.println("ArrayDeque"); + test(new ArrayDeque<>()); + System.out.println("LinkedBlockingDeque"); + test(new LinkedBlockingDeque<>(count)); + System.out.println("ConcurrentLinkedDeque"); + test(new ConcurrentLinkedDeque<>()); + } +} +/* Output: +LinkedList +[7, 6, 5, 4, 3, 2, 1, 0, 20, 21, 22, 23, 24, 25, 26, +27] +7 27 6 26 5 25 4 24 3 23 2 22 1 21 0 20 +7 27 6 26 5 25 4 24 3 23 2 22 1 21 0 20 +ArrayDeque +[7, 6, 5, 4, 3, 2, 1, 0, 20, 21, 22, 23, 24, 25, 26, +27] +7 27 6 26 5 25 4 24 3 23 2 22 1 21 0 20 +7 27 6 26 5 25 4 24 3 23 2 22 1 21 0 20 +LinkedBlockingDeque +[4, 3, 2, 1, 0, 20, 21, 22, 23, 24] +4 24 3 23 2 22 1 21 0 20 +4 24 3 23 2 22 1 21 0 20 +ConcurrentLinkedDeque +[7, 6, 5, 4, 3, 2, 1, 0, 20, 21, 22, 23, 24, 25, 26, +27] +7 27 6 26 5 25 4 24 3 23 2 22 1 21 0 20 +7 27 6 26 5 25 4 24 3 23 2 22 1 21 0 20 +*/ diff --git a/code/collectiontopics/SortedMapDemo.java b/code/collectiontopics/SortedMapDemo.java new file mode 100644 index 00000000..4d57d34a --- /dev/null +++ b/code/collectiontopics/SortedMapDemo.java @@ -0,0 +1,42 @@ +// collectiontopics/SortedMapDemo.java +// (c)2020 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 TreeMap +import java.util.*; +import onjava.*; + +public class SortedMapDemo { + public static void main(String[] args) { + TreeMap sortedMap = + new TreeMap<>(new CountMap(10)); + System.out.println(sortedMap); + Integer low = sortedMap.firstKey(); + Integer high = sortedMap.lastKey(); + System.out.println(low); + System.out.println(high); + Iterator it = + sortedMap.keySet().iterator(); + for(int i = 0; i <= 6; i++) { + if(i == 3) low = it.next(); + if(i == 6) high = it.next(); + else it.next(); + } + System.out.println(low); + System.out.println(high); + System.out.println(sortedMap.subMap(low, high)); + System.out.println(sortedMap.headMap(high)); + System.out.println(sortedMap.tailMap(low)); + } +} +/* Output: +{0=A0, 1=B0, 2=C0, 3=D0, 4=E0, 5=F0, 6=G0, 7=H0, 8=I0, +9=J0} +0 +9 +3 +7 +{3=D0, 4=E0, 5=F0, 6=G0} +{0=A0, 1=B0, 2=C0, 3=D0, 4=E0, 5=F0, 6=G0} +{3=D0, 4=E0, 5=F0, 6=G0, 7=H0, 8=I0, 9=J0} +*/ diff --git a/code/collectiontopics/SortedSetDemo.java b/code/collectiontopics/SortedSetDemo.java new file mode 100644 index 00000000..6ed81fb1 --- /dev/null +++ b/code/collectiontopics/SortedSetDemo.java @@ -0,0 +1,42 @@ +// collectiontopics/SortedSetDemo.java +// (c)2020 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. +import java.util.*; +import static java.util.stream.Collectors.*; + +public class SortedSetDemo { + public static void main(String[] args) { + 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(); + System.out.println(low); + System.out.println(high); + Iterator it = sortedSet.iterator(); + for(int i = 0; i <= 6; i++) { + if(i == 3) low = it.next(); + if(i == 6) high = it.next(); + else it.next(); + } + System.out.println(low); + System.out.println(high); + System.out.println(sortedSet.subSet(low, high)); + System.out.println(sortedSet.headSet(high)); + System.out.println(sortedSet.tailSet(low)); + } +} +/* Output: +[eight, five, four, one, seven, six, three, two] +eight +two +one +two +[one, seven, six, three] +[eight, five, four, one, seven, six, three] +[one, seven, six, three, two] +*/ diff --git a/code/collectiontopics/Stacks.java b/code/collectiontopics/Stacks.java new file mode 100644 index 00000000..79a684cb --- /dev/null +++ b/code/collectiontopics/Stacks.java @@ -0,0 +1,61 @@ +// collectiontopics/Stacks.java +// (c)2020 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. +// Demonstration of Stack Class +import java.util.*; + +enum Month { JANUARY, FEBRUARY, MARCH, APRIL, + MAY, JUNE, JULY, AUGUST, SEPTEMBER, + OCTOBER, NOVEMBER } + +public class Stacks { + public static void main(String[] args) { + Stack stack = new Stack<>(); + for(Month m : Month.values()) + stack.push(m.toString()); + System.out.println("stack = " + stack); + // Treating a stack as a Vector: + stack.addElement("The last line"); + System.out.println( + "element 5 = " + stack.elementAt(5)); + System.out.println("popping elements:"); + while(!stack.empty()) + System.out.print(stack.pop() + " "); + + // Using a LinkedList as a Stack: + LinkedList lstack = new LinkedList<>(); + for(Month m : Month.values()) + lstack.addFirst(m.toString()); + System.out.println("lstack = " + lstack); + while(!lstack.isEmpty()) + System.out.print(lstack.removeFirst() + " "); + + // Using the Stack class from + // the Collections Chapter: + onjava.Stack stack2 = + new onjava.Stack<>(); + for(Month m : Month.values()) + stack2.push(m.toString()); + System.out.println("stack2 = " + stack2); + while(!stack2.isEmpty()) + System.out.print(stack2.pop() + " "); + + } +} +/* Output: +stack = [JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, +JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER] +element 5 = JUNE +popping elements: +The last line NOVEMBER OCTOBER SEPTEMBER AUGUST JULY +JUNE MAY APRIL MARCH FEBRUARY JANUARY lstack = +[NOVEMBER, OCTOBER, SEPTEMBER, AUGUST, JULY, JUNE, MAY, +APRIL, MARCH, FEBRUARY, JANUARY] +NOVEMBER OCTOBER SEPTEMBER AUGUST JULY JUNE MAY APRIL +MARCH FEBRUARY JANUARY stack2 = [NOVEMBER, OCTOBER, +SEPTEMBER, AUGUST, JULY, JUNE, MAY, APRIL, MARCH, +FEBRUARY, JANUARY] +NOVEMBER OCTOBER SEPTEMBER AUGUST JULY JUNE MAY APRIL +MARCH FEBRUARY JANUARY +*/ diff --git a/code/collectiontopics/StreamFillMaps.java b/code/collectiontopics/StreamFillMaps.java new file mode 100644 index 00000000..816a74b3 --- /dev/null +++ b/code/collectiontopics/StreamFillMaps.java @@ -0,0 +1,55 @@ +// collectiontopics/StreamFillMaps.java +// (c)2020 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. +import java.util.*; +import java.util.function.*; +import java.util.stream.*; +import onjava.*; + +class Letters +implements Supplier> { + private int number = 1; + private char letter = 'A'; + @Override + public Pair get() { + return new Pair<>(number++, "" + letter++); + } +} + +public class StreamFillMaps { + public static void main(String[] args) { + Map m = + Stream.generate(new Letters()) + .limit(11) + .collect(Collectors + .toMap(Pair::key, Pair::value)); + System.out.println(m); + + // Two separate Suppliers: + Rand.String rs = new Rand.String(3); + Count.Character cc = new Count.Character(); + Map mcs = Stream.generate( + () -> Pair.make(cc.get(), rs.get())) + .limit(8) + .collect(Collectors + .toMap(Pair::key, Pair::value)); + System.out.println(mcs); + + // A key Supplier and a single value: + Map mcs2 = Stream.generate( + () -> Pair.make(cc.get(), "Val")) + .limit(8) + .collect(Collectors + .toMap(Pair::key, Pair::value)); + System.out.println(mcs2); + } +} +/* Output: +{1=A, 2=B, 3=C, 4=D, 5=E, 6=F, 7=G, 8=H, 9=I, 10=J, +11=K} +{b=btp, c=enp, d=ccu, e=xsz, f=gvg, g=mei, h=nne, +i=elo} +{p=Val, q=Val, j=Val, k=Val, l=Val, m=Val, n=Val, +o=Val} +*/ diff --git a/code/collectiontopics/SuppliersCollectionTest.java b/code/collectiontopics/SuppliersCollectionTest.java new file mode 100644 index 00000000..b30f1490 --- /dev/null +++ b/code/collectiontopics/SuppliersCollectionTest.java @@ -0,0 +1,67 @@ +// collectiontopics/SuppliersCollectionTest.java +// (c)2020 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. +import java.util.*; +import java.util.function.*; +import java.util.stream.*; +import onjava.*; + +class Government implements Supplier { + static String[] foundation = ( + "strange women lying in ponds " + + "distributing swords is no basis " + + "for a system of government").split(" "); + private int index; + @Override + public String get() { + return foundation[index++]; + } +} + +public class SuppliersCollectionTest { + public static void main(String[] args) { + // Suppliers class from the Generics chapter: + Set set = Suppliers.create( + LinkedHashSet::new, new Government(), 15); + System.out.println(set); + List list = Suppliers.create( + LinkedList::new, new Government(), 15); + System.out.println(list); + list = new ArrayList<>(); + Suppliers.fill(list, new Government(), 15); + System.out.println(list); + + // Or we can use Streams: + set = Arrays.stream(Government.foundation) + .collect(Collectors.toSet()); + System.out.println(set); + list = Arrays.stream(Government.foundation) + .collect(Collectors.toList()); + System.out.println(list); + list = Arrays.stream(Government.foundation) + .collect(Collectors + .toCollection(LinkedList::new)); + System.out.println(list); + set = Arrays.stream(Government.foundation) + .collect(Collectors + .toCollection(LinkedHashSet::new)); + System.out.println(set); + } +} +/* Output: +[strange, women, lying, in, ponds, distributing, +swords, is, no, basis, for, a, system, of, government] +[strange, women, lying, in, ponds, distributing, +swords, is, no, basis, for, a, system, of, government] +[strange, women, lying, in, ponds, distributing, +swords, is, no, basis, for, a, system, of, government] +[ponds, no, a, in, swords, for, is, basis, strange, +system, government, distributing, of, women, lying] +[strange, women, lying, in, ponds, distributing, +swords, is, no, basis, for, a, system, of, government] +[strange, women, lying, in, ponds, distributing, +swords, is, no, basis, for, a, system, of, government] +[strange, women, lying, in, ponds, distributing, +swords, is, no, basis, for, a, system, of, government] +*/ diff --git a/code/collectiontopics/Synchronization.java b/code/collectiontopics/Synchronization.java new file mode 100644 index 00000000..c7d3b732 --- /dev/null +++ b/code/collectiontopics/Synchronization.java @@ -0,0 +1,24 @@ +// collectiontopics/Synchronization.java +// (c)2020 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. +// Using the Collections.synchronized methods +import java.util.*; + +public class Synchronization { + public static void main(String[] args) { + Collection c = + Collections.synchronizedCollection( + new ArrayList<>()); + List list = Collections + .synchronizedList(new ArrayList<>()); + Set s = Collections + .synchronizedSet(new HashSet<>()); + Set ss = Collections + .synchronizedSortedSet(new TreeSet<>()); + Map m = Collections + .synchronizedMap(new HashMap<>()); + Map sm = Collections + .synchronizedSortedMap(new TreeMap<>()); + } +} diff --git a/code/collectiontopics/ToDoList.java b/code/collectiontopics/ToDoList.java new file mode 100644 index 00000000..b288e8e1 --- /dev/null +++ b/code/collectiontopics/ToDoList.java @@ -0,0 +1,56 @@ +// collectiontopics/ToDoList.java +// (c)2020 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. +// A more complex use of PriorityQueue +import java.util.*; + +class ToDoItem implements Comparable { + private char primary; + private int secondary; + private String item; + 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; + else if(secondary == arg.secondary) + return 0; + return -1; + } + @Override + public String toString() { + return Character.toString(primary) + + secondary + ": " + item; + } +} + +class ToDoList { + public static void main(String[] args) { + 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()); + } +} +/* Output: +A1: Water lawn +A2: Feed dog +B1: Feed cat +B7: Feed bird +C3: Mow lawn +C4: Empty trash +*/ diff --git a/code/collectiontopics/TypesForSets.java b/code/collectiontopics/TypesForSets.java new file mode 100644 index 00000000..9950b003 --- /dev/null +++ b/code/collectiontopics/TypesForSets.java @@ -0,0 +1,93 @@ +// collectiontopics/TypesForSets.java +// (c)2020 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. +// Methods necessary to put your own type in a Set +import java.util.*; +import java.util.function.*; +import java.util.Objects; + +class SetType { + protected int i; + SetType(int n) { i = n; } + @Override + public boolean equals(Object o) { + return o instanceof SetType && + Objects.equals(i, ((SetType)o).i); + } + @Override + public String toString() { + return Integer.toString(i); + } +} + +class HashType extends SetType { + HashType(int n) { super(n); } + @Override + public int hashCode() { + return Objects.hashCode(i); + } +} + +class TreeType extends SetType +implements Comparable { + TreeType(int n) { super(n); } + @Override + public int compareTo(TreeType arg) { + return Integer.compare(arg.i, i); + // Equivalent to: + // return arg.i < i ? -1 : (arg.i == i ? 0 : 1); + } +} + +public class TypesForSets { + static void + fill(Set set, Function type) { + 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) { + fill(set, type); + fill(set, type); // Try to add duplicates + fill(set, type); + System.out.println(set); + } + public static void main(String[] args) { + test(new HashSet<>(), HashType::new); + test(new LinkedHashSet<>(), HashType::new); + test(new TreeSet<>(), TreeType::new); + // Things that don't work: + test(new HashSet<>(), SetType::new); + test(new HashSet<>(), TreeType::new); + test(new LinkedHashSet<>(), SetType::new); + test(new LinkedHashSet<>(), TreeType::new); + try { + test(new TreeSet<>(), SetType::new); + } catch(Exception e) { + System.out.println(e.getMessage()); + } + try { + test(new TreeSet<>(), HashType::new); + } catch(Exception e) { + System.out.println(e.getMessage()); + } + } +} +/* Output: +[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/code/collectiontopics/Unsupported.java b/code/collectiontopics/Unsupported.java new file mode 100644 index 00000000..a66b1cfd --- /dev/null +++ b/code/collectiontopics/Unsupported.java @@ -0,0 +1,60 @@ +// collectiontopics/Unsupported.java +// (c)2020 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. +// Unsupported operations in Java collections +import java.util.*; + +public class Unsupported { + static void + check(String description, Runnable tst) { + try { + tst.run(); + } catch(Exception e) { + System.out.println(description + "(): " + e); + } + } + static void test(String msg, List list) { + System.out.println("--- " + msg + " ---"); + Collection c = list; + Collection subList = list.subList(1,8); + // Copy of the sublist: + Collection c2 = new ArrayList<>(subList); + check("retainAll", () -> c.retainAll(c2)); + check("removeAll", () -> c.removeAll(c2)); + check("clear", () -> c.clear()); + check("add", () -> c.add("X")); + check("addAll", () -> c.addAll(c2)); + check("remove", () -> c.remove("C")); + // The List.set() method modifies the value but + // doesn't change the size of the data structure: + check("List.set", () -> list.set(0, "X")); + } + public static void main(String[] args) { + List list = Arrays.asList( + "A B C D E F G H I J K L".split(" ")); + test("Modifiable Copy", new ArrayList<>(list)); + test("Arrays.asList()", list); + test("unmodifiableList()", + Collections.unmodifiableList( + new ArrayList<>(list))); + } +} +/* Output: +--- Modifiable Copy --- +--- Arrays.asList() --- +retainAll(): java.lang.UnsupportedOperationException +removeAll(): java.lang.UnsupportedOperationException +clear(): java.lang.UnsupportedOperationException +add(): java.lang.UnsupportedOperationException +addAll(): java.lang.UnsupportedOperationException +remove(): java.lang.UnsupportedOperationException +--- unmodifiableList() --- +retainAll(): java.lang.UnsupportedOperationException +removeAll(): java.lang.UnsupportedOperationException +clear(): java.lang.UnsupportedOperationException +add(): java.lang.UnsupportedOperationException +addAll(): java.lang.UnsupportedOperationException +remove(): java.lang.UnsupportedOperationException +List.set(): java.lang.UnsupportedOperationException +*/ diff --git a/code/collectiontopics/Utilities.java b/code/collectiontopics/Utilities.java new file mode 100644 index 00000000..a2acc427 --- /dev/null +++ b/code/collectiontopics/Utilities.java @@ -0,0 +1,88 @@ +// collectiontopics/Utilities.java +// (c)2020 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. +// Simple demonstrations of the Collections utilities +import java.util.*; + +public class Utilities { + static List list = Arrays.asList( + "one Two three Four five six one".split(" ")); + public static void main(String[] args) { + System.out.println(list); + System.out.println("'list' disjoint (Four)?: " + + Collections.disjoint(list, + Collections.singletonList("Four"))); + System.out.println( + "max: " + Collections.max(list)); + System.out.println( + "min: " + Collections.min(list)); + System.out.println( + "max w/ comparator: " + Collections.max(list, + String.CASE_INSENSITIVE_ORDER)); + System.out.println( + "min w/ comparator: " + Collections.min(list, + String.CASE_INSENSITIVE_ORDER)); + List sublist = + Arrays.asList("Four five six".split(" ")); + System.out.println("indexOfSubList: " + + Collections.indexOfSubList(list, sublist)); + System.out.println("lastIndexOfSubList: " + + Collections.lastIndexOfSubList(list, sublist)); + Collections.replaceAll(list, "one", "Yo"); + System.out.println("replaceAll: " + list); + Collections.reverse(list); + System.out.println("reverse: " + list); + Collections.rotate(list, 3); + System.out.println("rotate: " + list); + List source = + Arrays.asList("in the matrix".split(" ")); + Collections.copy(list, source); + System.out.println("copy: " + list); + Collections.swap(list, 0, list.size() - 1); + System.out.println("swap: " + list); + Collections.shuffle(list, new Random(47)); + System.out.println("shuffled: " + list); + Collections.fill(list, "pop"); + System.out.println("fill: " + list); + System.out.println("frequency of 'pop': " + + Collections.frequency(list, "pop")); + List dups = + Collections.nCopies(3, "snap"); + System.out.println("dups: " + dups); + System.out.println("'list' disjoint 'dups'?: " + + Collections.disjoint(list, dups)); + // Getting an old-style Enumeration: + Enumeration e = + Collections.enumeration(dups); + Vector v = new Vector<>(); + while(e.hasMoreElements()) + v.addElement(e.nextElement()); + // Converting an old-style Vector + // to a List via an Enumeration: + ArrayList arrayList = + Collections.list(v.elements()); + System.out.println("arrayList: " + arrayList); + } +} +/* Output: +[one, Two, three, Four, five, six, one] +'list' disjoint (Four)?: false +max: three +min: Four +max w/ comparator: Two +min w/ comparator: five +indexOfSubList: 3 +lastIndexOfSubList: 3 +replaceAll: [Yo, Two, three, Four, five, six, Yo] +reverse: [Yo, six, five, Four, three, Two, Yo] +rotate: [three, Two, Yo, Yo, six, five, Four] +copy: [in, the, matrix, Yo, six, five, Four] +swap: [Four, the, matrix, Yo, six, five, in] +shuffled: [six, matrix, the, Four, Yo, five, in] +fill: [pop, pop, pop, pop, pop, pop, pop] +frequency of 'pop': 7 +dups: [snap, snap, snap] +'list' disjoint 'dups'?: true +arrayList: [snap, snap, snap] +*/ diff --git a/code/com/mindviewinc/simple/List.java b/code/com/mindviewinc/simple/List.java new file mode 100644 index 00000000..84b30315 --- /dev/null +++ b/code/com/mindviewinc/simple/List.java @@ -0,0 +1,12 @@ +// com/mindviewinc/simple/List.java +// (c)2020 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. +// Creating a package +package com.mindviewinc.simple; + +public class List { + public List() { + System.out.println("com.mindviewinc.simple.List"); + } +} diff --git a/code/com/mindviewinc/simple/Vector.java b/code/com/mindviewinc/simple/Vector.java new file mode 100644 index 00000000..19824cce --- /dev/null +++ b/code/com/mindviewinc/simple/Vector.java @@ -0,0 +1,12 @@ +// com/mindviewinc/simple/Vector.java +// (c)2020 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. +// Creating a package +package com.mindviewinc.simple; + +public class Vector { + public Vector() { + System.out.println("com.mindviewinc.simple.Vector"); + } +} diff --git a/code/compression/GZIPcompress.java b/code/compression/GZIPcompress.java new file mode 100644 index 00000000..c9022e78 --- /dev/null +++ b/code/compression/GZIPcompress.java @@ -0,0 +1,45 @@ +// compression/GZIPcompress.java +// (c)2020 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. +// {java GZIPcompress GZIPcompress.java} +// {VisuallyInspectOutput} +import java.util.zip.*; +import java.io.*; + +public class GZIPcompress { + public static void main(String[] args) { + if(args.length == 0) { + System.out.println( + "Usage: \nGZIPcompress file\n" + + "\tUses GZIP compression to compress " + + "the file to test.gz"); + System.exit(1); + } + try( + InputStream in = new BufferedInputStream( + new FileInputStream(args[0])); + BufferedOutputStream out = + new BufferedOutputStream( + new GZIPOutputStream( + new FileOutputStream("test.gz"))) + ) { + System.out.println("Writing file"); + int c; + while((c = in.read()) != -1) + out.write(c); + } catch(IOException e) { + throw new RuntimeException(e); + } + System.out.println("Reading file"); + try( + BufferedReader in2 = new BufferedReader( + new InputStreamReader(new GZIPInputStream( + new FileInputStream("test.gz")))) + ) { + in2.lines().forEach(System.out::println); + } catch(IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/code/compression/ZipCompress.java b/code/compression/ZipCompress.java new file mode 100644 index 00000000..f9ce7670 --- /dev/null +++ b/code/compression/ZipCompress.java @@ -0,0 +1,83 @@ +// compression/ZipCompress.java +// (c)2020 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. +// Uses Zip compression to compress any +// number of files given on the command line +// {java ZipCompress ZipCompress.java} +// {VisuallyInspectOutput} +import java.util.zip.*; +import java.io.*; +import java.util.*; + +public class ZipCompress { + public static void main(String[] args) { + try( + FileOutputStream f = + new FileOutputStream("test.zip"); + CheckedOutputStream csum = + new CheckedOutputStream(f, new Adler32()); + ZipOutputStream zos = new ZipOutputStream(csum); + BufferedOutputStream out = + new BufferedOutputStream(zos) + ) { + zos.setComment("A test of Java Zipping"); + // No corresponding getComment(), though. + for(String arg : args) { + System.out.println("Writing file " + arg); + try( + InputStream in = new BufferedInputStream( + new FileInputStream(arg)) + ) { + zos.putNextEntry(new ZipEntry(arg)); + int c; + while((c = in.read()) != -1) + out.write(c); + } + out.flush(); + } + // Checksum valid only after the file is closed! + System.out.println( + "Checksum: " + csum.getChecksum().getValue()); + } catch(IOException e) { + throw new RuntimeException(e); + } + // Now extract the files: + System.out.println("Reading file"); + try( + FileInputStream fi = + new FileInputStream("test.zip"); + CheckedInputStream csumi = + new CheckedInputStream(fi, new Adler32()); + ZipInputStream in2 = new ZipInputStream(csumi); + BufferedInputStream bis = + new BufferedInputStream(in2) + ) { + ZipEntry ze; + while((ze = in2.getNextEntry()) != null) { + System.out.println("Reading file " + ze); + int x; + while((x = bis.read()) != -1) + System.out.write(x); + } + if(args.length == 1) + System.out.println( + "Checksum: "+csumi.getChecksum().getValue()); + } catch(IOException e) { + throw new RuntimeException(e); + } + // Alternative way to open and read Zip files: + try( + ZipFile zf = new ZipFile("test.zip") + ) { + Enumeration e = zf.entries(); + while(e.hasMoreElements()) { + ZipEntry ze2 = (ZipEntry)e.nextElement(); + System.out.println("File: " + ze2); + // ... and extract the data as before + } + } catch(IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/code/concurrent/Baked.java b/code/concurrent/Baked.java new file mode 100644 index 00000000..d616d94b --- /dev/null +++ b/code/concurrent/Baked.java @@ -0,0 +1,31 @@ +// concurrent/Baked.java +// (c)2020 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. +import java.util.concurrent.*; +import java.util.stream.*; +import onjava.Nap; + +public class Baked { + static class Pan {} + static Pan pan(Batter b) { + new Nap(0.1); + return new Pan(); + } + static Baked heat(Pan p) { + new Nap(0.1); + return new Baked(); + } + static CompletableFuture + bake(CompletableFuture cfb) { + return cfb + .thenApplyAsync(Baked::pan) + .thenApplyAsync(Baked::heat); + } + public static + Stream> batch() { + CompletableFuture batter = Batter.mix(); + return Stream.of(bake(batter), bake(batter), + bake(batter), bake(batter)); + } +} diff --git a/code/concurrent/Batter.java b/code/concurrent/Batter.java new file mode 100644 index 00000000..9fe14c4f --- /dev/null +++ b/code/concurrent/Batter.java @@ -0,0 +1,34 @@ +// concurrent/Batter.java +// (c)2020 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. +import java.util.concurrent.*; +import onjava.Nap; + +public class Batter { + static class Eggs {} + static class Milk {} + static class Sugar {} + static class Flour {} + static T prepare(T ingredient) { + new Nap(0.1); + return ingredient; + } + static CompletableFuture prep(T ingredient) { + return CompletableFuture + .completedFuture(ingredient) + .thenApplyAsync(Batter::prepare); + } + public static CompletableFuture mix() { + CompletableFuture eggs = prep(new Eggs()); + CompletableFuture milk = prep(new Milk()); + CompletableFuture sugar = prep(new Sugar()); + CompletableFuture flour = prep(new Flour()); + CompletableFuture + .allOf(eggs, milk, sugar, flour) + .join(); + new Nap(0.1); // Mixing time + return + CompletableFuture.completedFuture(new Batter()); + } +} diff --git a/code/concurrent/Breakable.java b/code/concurrent/Breakable.java new file mode 100644 index 00000000..facd7095 --- /dev/null +++ b/code/concurrent/Breakable.java @@ -0,0 +1,29 @@ +// concurrent/Breakable.java +// (c)2020 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. +import java.util.concurrent.*; + +public class Breakable { + String id; + private int failcount; + public Breakable(String id, int failcount) { + this.id = id; + this.failcount = failcount; + } + @Override + public String toString() { + return "Breakable_" + id + + " [" + failcount + "]"; + } + public static Breakable work(Breakable b) { + if(--b.failcount == 0) { + System.out.println( + "Throwing Exception for " + b.id + ""); + throw new RuntimeException( + "Breakable_" + b.id + " failed"); + } + System.out.println(b); + return b; + } +} diff --git a/code/concurrent/CachedThreadPool.java b/code/concurrent/CachedThreadPool.java new file mode 100644 index 00000000..e0b825a2 --- /dev/null +++ b/code/concurrent/CachedThreadPool.java @@ -0,0 +1,29 @@ +// concurrent/CachedThreadPool.java +// (c)2020 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. +import java.util.concurrent.*; +import java.util.stream.*; + +public class CachedThreadPool { + public static void main(String[] args) { + ExecutorService exec = + Executors.newCachedThreadPool(); + IntStream.range(0, 10) + .mapToObj(NapTask::new) + .forEach(exec::execute); + exec.shutdown(); + } +} +/* Output: +NapTask[7] pool-1-thread-8 +NapTask[4] pool-1-thread-5 +NapTask[1] pool-1-thread-2 +NapTask[3] pool-1-thread-4 +NapTask[0] pool-1-thread-1 +NapTask[8] pool-1-thread-9 +NapTask[2] pool-1-thread-3 +NapTask[9] pool-1-thread-10 +NapTask[6] pool-1-thread-7 +NapTask[5] pool-1-thread-6 +*/ diff --git a/code/concurrent/CachedThreadPool2.java b/code/concurrent/CachedThreadPool2.java new file mode 100644 index 00000000..9d763656 --- /dev/null +++ b/code/concurrent/CachedThreadPool2.java @@ -0,0 +1,29 @@ +// concurrent/CachedThreadPool2.java +// (c)2020 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. +import java.util.concurrent.*; +import java.util.stream.*; + +public class CachedThreadPool2 { + public static void main(String[] args) { + ExecutorService exec = + Executors.newCachedThreadPool(); + IntStream.range(0, 10) + .mapToObj(InterferingTask::new) + .forEach(exec::execute); + exec.shutdown(); + } +} +/* Output: +0 pool-1-thread-1 200 +1 pool-1-thread-2 200 +4 pool-1-thread-5 300 +5 pool-1-thread-6 400 +8 pool-1-thread-9 500 +9 pool-1-thread-10 600 +2 pool-1-thread-3 700 +7 pool-1-thread-8 800 +3 pool-1-thread-4 900 +6 pool-1-thread-7 1000 +*/ diff --git a/code/concurrent/CachedThreadPool3.java b/code/concurrent/CachedThreadPool3.java new file mode 100644 index 00000000..4b6e6d2e --- /dev/null +++ b/code/concurrent/CachedThreadPool3.java @@ -0,0 +1,47 @@ +// concurrent/CachedThreadPool3.java +// (c)2020 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. +import java.util.*; +import java.util.concurrent.*; +import java.util.stream.*; + +public class CachedThreadPool3 { + public static Integer + extractResult(Future f) { + try { + return f.get(); + } catch(Exception e) { + throw new RuntimeException(e); + } + } + public static void main(String[] args) + throws InterruptedException { + ExecutorService exec = + Executors.newCachedThreadPool(); + List tasks = + IntStream.range(0, 10) + .mapToObj(CountingTask::new) + .collect(Collectors.toList()); + List> futures = + exec.invokeAll(tasks); + Integer sum = futures.stream() + .map(CachedThreadPool3::extractResult) + .reduce(0, Integer::sum); + System.out.println("sum = " + sum); + exec.shutdown(); + } +} +/* Output: +1 pool-1-thread-2 100 +0 pool-1-thread-1 100 +4 pool-1-thread-5 100 +5 pool-1-thread-6 100 +8 pool-1-thread-9 100 +9 pool-1-thread-10 100 +2 pool-1-thread-3 100 +3 pool-1-thread-4 100 +6 pool-1-thread-7 100 +7 pool-1-thread-8 100 +sum = 1000 +*/ diff --git a/code/concurrent/CatchCompletableExceptions.java b/code/concurrent/CatchCompletableExceptions.java new file mode 100644 index 00000000..67451ed4 --- /dev/null +++ b/code/concurrent/CatchCompletableExceptions.java @@ -0,0 +1,81 @@ +// concurrent/CatchCompletableExceptions.java +// (c)2020 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. +import java.util.concurrent.*; + +public class CatchCompletableExceptions { + static void handleException(int failcount) { + // Call the Function only if there's an + // exception, must produce same type as came in: + CompletableExceptions + .test("exceptionally", failcount) + .exceptionally((ex) -> { // Function + if(ex == null) + System.out.println("I don't get it yet"); + return new Breakable(ex.getMessage(), 0); + }) + .thenAccept(str -> + System.out.println("result: " + str)); + + // Create a new result (recover): + CompletableExceptions + .test("handle", failcount) + .handle((result, fail) -> { // BiFunction + if(fail != null) + return "Failure recovery object"; + else + return result + " is good"; + }) + .thenAccept(str -> + System.out.println("result: " + str)); + + // Do something but pass the same result through: + CompletableExceptions + .test("whenComplete", failcount) + .whenComplete((result, fail) -> { // BiConsumer + if(fail != null) + System.out.println("It failed"); + else + System.out.println(result + " OK"); + }) + .thenAccept(r -> + System.out.println("result: " + r)); + } + public static void main(String[] args) { + System.out.println("**** Failure Mode ****"); + handleException(2); + System.out.println("**** Success Mode ****"); + handleException(0); + } +} +/* Output: +**** Failure Mode **** +Breakable_exceptionally [1] +Throwing Exception for exceptionally +result: Breakable_java.lang.RuntimeException: +Breakable_exceptionally failed [0] +Breakable_handle [1] +Throwing Exception for handle +result: Failure recovery object +Breakable_whenComplete [1] +Throwing Exception for whenComplete +It failed +**** Success Mode **** +Breakable_exceptionally [-1] +Breakable_exceptionally [-2] +Breakable_exceptionally [-3] +Breakable_exceptionally [-4] +result: Breakable_exceptionally [-4] +Breakable_handle [-1] +Breakable_handle [-2] +Breakable_handle [-3] +Breakable_handle [-4] +result: Breakable_handle [-4] is good +Breakable_whenComplete [-1] +Breakable_whenComplete [-2] +Breakable_whenComplete [-3] +Breakable_whenComplete [-4] +Breakable_whenComplete [-4] OK +result: Breakable_whenComplete [-4] +*/ diff --git a/code/concurrent/CollectionIntoStream.java b/code/concurrent/CollectionIntoStream.java new file mode 100644 index 00000000..2dc51a7e --- /dev/null +++ b/code/concurrent/CollectionIntoStream.java @@ -0,0 +1,36 @@ +// concurrent/CollectionIntoStream.java +// (c)2020 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. +import onjava.*; +import java.util.*; +import java.util.stream.*; + +public class CollectionIntoStream { + public static void main(String[] args) { + List strings = + Stream.generate(new Rand.String(5)) + .limit(10) + .collect(Collectors.toList()); + strings.forEach(System.out::println); + // Convert to a Stream for many more options: + String result = strings.stream() + .map(String::toUpperCase) + .map(s -> s.substring(2)) + .reduce(":", (s1, s2) -> s1 + s2); + System.out.println(result); + } +} +/* Output: +btpen +pccux +szgvg +meinn +eeloz +tdvew +cippc +ygpoa +lkljl +bynxt +:PENCUXGVGINNLOZVEWPPCPOALJLNXT +*/ diff --git a/code/concurrent/CompletableApply.java b/code/concurrent/CompletableApply.java new file mode 100644 index 00000000..2f5bd9b4 --- /dev/null +++ b/code/concurrent/CompletableApply.java @@ -0,0 +1,27 @@ +// concurrent/CompletableApply.java +// (c)2020 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. +import java.util.concurrent.*; + +public class CompletableApply { + public static void main(String[] args) { + CompletableFuture cf = + CompletableFuture.completedFuture( + new Machina(0)); + CompletableFuture cf2 = + cf.thenApply(Machina::work); + CompletableFuture cf3 = + cf2.thenApply(Machina::work); + CompletableFuture cf4 = + cf3.thenApply(Machina::work); + CompletableFuture cf5 = + cf4.thenApply(Machina::work); + } +} +/* Output: +Machina0: ONE +Machina0: TWO +Machina0: THREE +Machina0: complete +*/ diff --git a/code/concurrent/CompletableApplyAsync.java b/code/concurrent/CompletableApplyAsync.java new file mode 100644 index 00000000..fa7c9271 --- /dev/null +++ b/code/concurrent/CompletableApplyAsync.java @@ -0,0 +1,31 @@ +// concurrent/CompletableApplyAsync.java +// (c)2020 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. +import java.util.concurrent.*; +import onjava.*; + +public class CompletableApplyAsync { + public static void main(String[] args) { + Timer timer = new Timer(); + CompletableFuture cf = + CompletableFuture.completedFuture( + new Machina(0)) + .thenApplyAsync(Machina::work) + .thenApplyAsync(Machina::work) + .thenApplyAsync(Machina::work) + .thenApplyAsync(Machina::work); + System.out.println(timer.duration()); + System.out.println(cf.join()); + System.out.println(timer.duration()); + } +} +/* Output: +116 +Machina0: ONE +Machina0: TWO +Machina0: THREE +Machina0: complete +Machina0: complete +552 +*/ diff --git a/code/concurrent/CompletableApplyChained.java b/code/concurrent/CompletableApplyChained.java new file mode 100644 index 00000000..aa6828d5 --- /dev/null +++ b/code/concurrent/CompletableApplyChained.java @@ -0,0 +1,27 @@ +// concurrent/CompletableApplyChained.java +// (c)2020 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. +import java.util.concurrent.*; +import onjava.Timer; + +public class CompletableApplyChained { + public static void main(String[] args) { + Timer timer = new Timer(); + CompletableFuture cf = + CompletableFuture.completedFuture( + new Machina(0)) + .thenApply(Machina::work) + .thenApply(Machina::work) + .thenApply(Machina::work) + .thenApply(Machina::work); + System.out.println(timer.duration()); + } +} +/* Output: +Machina0: ONE +Machina0: TWO +Machina0: THREE +Machina0: complete +514 +*/ diff --git a/code/concurrent/CompletableExceptions.java b/code/concurrent/CompletableExceptions.java new file mode 100644 index 00000000..624815d5 --- /dev/null +++ b/code/concurrent/CompletableExceptions.java @@ -0,0 +1,75 @@ +// concurrent/CompletableExceptions.java +// (c)2020 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. +import java.util.concurrent.*; + +public class CompletableExceptions { + static CompletableFuture + test(String id, int failcount) { + return + CompletableFuture.completedFuture( + new Breakable(id, failcount)) + .thenApply(Breakable::work) + .thenApply(Breakable::work) + .thenApply(Breakable::work) + .thenApply(Breakable::work); + } + public static void main(String[] args) { + // Exceptions don't appear ... + test("A", 1); + test("B", 2); + test("C", 3); + test("D", 4); + test("E", 5); + // ... until you try to fetch the value: + try { + test("F", 2).get(); // or join() + } catch(Exception e) { + System.out.println(e.getMessage()); + } + // Test for exceptions: + System.out.println( + test("G", 2).isCompletedExceptionally()); + // Counts as "done": + System.out.println(test("H", 2).isDone()); + // Force an exception: + CompletableFuture cfi = + new CompletableFuture<>(); + System.out.println("done? " + cfi.isDone()); + cfi.completeExceptionally( + new RuntimeException("forced")); + try { + cfi.get(); + } catch(Exception e) { + System.out.println(e.getMessage()); + } + } +} +/* Output: +Throwing Exception for A +Breakable_B [1] +Throwing Exception for B +Breakable_C [2] +Breakable_C [1] +Throwing Exception for C +Breakable_D [3] +Breakable_D [2] +Breakable_D [1] +Throwing Exception for D +Breakable_E [4] +Breakable_E [3] +Breakable_E [2] +Breakable_E [1] +Breakable_F [1] +Throwing Exception for F +java.lang.RuntimeException: Breakable_F failed +Breakable_G [1] +Throwing Exception for G +true +Breakable_H [1] +Throwing Exception for H +true +done? false +java.lang.RuntimeException: forced +*/ diff --git a/code/concurrent/CompletableOperations.java b/code/concurrent/CompletableOperations.java new file mode 100644 index 00000000..d03e8422 --- /dev/null +++ b/code/concurrent/CompletableOperations.java @@ -0,0 +1,74 @@ +// concurrent/CompletableOperations.java +// (c)2020 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. +import java.util.concurrent.*; +import static onjava.CompletableUtilities.*; + +public class CompletableOperations { + static CompletableFuture cfi(int i) { + return + CompletableFuture.completedFuture( + Integer.valueOf(i)); + } + public static void main(String[] args) { + showr(cfi(1)); // Basic test + voidr(cfi(2).runAsync(() -> + System.out.println("runAsync"))); + voidr(cfi(3).thenRunAsync(() -> + System.out.println("thenRunAsync"))); + voidr(CompletableFuture.runAsync(() -> + System.out.println("runAsync is static"))); + showr(CompletableFuture.supplyAsync(() -> 99)); + voidr(cfi(4).thenAcceptAsync(i -> + System.out.println("thenAcceptAsync: " + i))); + showr(cfi(5).thenApplyAsync(i -> i + 42)); + showr(cfi(6).thenComposeAsync(i -> cfi(i + 99))); + CompletableFuture c = cfi(7); + c.obtrudeValue(111); + showr(c); + showr(cfi(8).toCompletableFuture()); + c = new CompletableFuture<>(); + c.complete(9); + showr(c); + c = new CompletableFuture<>(); + c.cancel(true); + System.out.println("cancelled: " + + c.isCancelled()); + System.out.println("completed exceptionally: " + + c.isCompletedExceptionally()); + System.out.println("done: " + c.isDone()); + System.out.println(c); + c = new CompletableFuture<>(); + System.out.println(c.getNow(777)); + c = new CompletableFuture<>(); + c.thenApplyAsync(i -> i + 42) + .thenApplyAsync(i -> i * 12); + System.out.println("dependents: " + + c.getNumberOfDependents()); + c.thenApplyAsync(i -> i / 2); + System.out.println("dependents: " + + c.getNumberOfDependents()); + } +} +/* Output: +1 +runAsync +thenRunAsync +runAsync is static +99 +thenAcceptAsync: 4 +47 +105 +111 +8 +9 +cancelled: true +completed exceptionally: true +done: true +java.util.concurrent.CompletableFuture@6d311334[Complet +ed exceptionally] +777 +dependents: 1 +dependents: 2 +*/ diff --git a/code/concurrent/CompletablePizza.java b/code/concurrent/CompletablePizza.java new file mode 100644 index 00000000..97b68545 --- /dev/null +++ b/code/concurrent/CompletablePizza.java @@ -0,0 +1,87 @@ +// concurrent/CompletablePizza.java +// (c)2020 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. +import java.util.*; +import java.util.concurrent.*; +import java.util.stream.*; +import onjava.Timer; + +public class CompletablePizza { + static final int QUANTITY = 5; + public static CompletableFuture + makeCF(Pizza za) { + return CompletableFuture + .completedFuture(za) + .thenApplyAsync(Pizza::roll) + .thenApplyAsync(Pizza::sauce) + .thenApplyAsync(Pizza::cheese) + .thenApplyAsync(Pizza::toppings) + .thenApplyAsync(Pizza::bake) + .thenApplyAsync(Pizza::slice) + .thenApplyAsync(Pizza::box); + } + public static void + show(CompletableFuture cf) { + try { + System.out.println(cf.get()); + } catch(Exception e) { + throw new RuntimeException(e); + } + } + public static void main(String[] args) { + Timer timer = new Timer(); + List> pizzas = + IntStream.range(0, QUANTITY) + .mapToObj(Pizza::new) + .map(CompletablePizza::makeCF) + .collect(Collectors.toList()); + System.out.println(timer.duration()); + pizzas.forEach(CompletablePizza::show); + System.out.println(timer.duration()); + } +} +/* Output: +169 +Pizza 0: ROLLED +Pizza 1: ROLLED +Pizza 2: ROLLED +Pizza 4: ROLLED +Pizza 3: ROLLED +Pizza 1: SAUCED +Pizza 0: SAUCED +Pizza 2: SAUCED +Pizza 4: SAUCED +Pizza 3: SAUCED +Pizza 0: CHEESED +Pizza 4: CHEESED +Pizza 1: CHEESED +Pizza 2: CHEESED +Pizza 3: CHEESED +Pizza 0: TOPPED +Pizza 4: TOPPED +Pizza 1: TOPPED +Pizza 2: TOPPED +Pizza 3: TOPPED +Pizza 0: BAKED +Pizza 4: BAKED +Pizza 1: BAKED +Pizza 3: BAKED +Pizza 2: BAKED +Pizza 0: SLICED +Pizza 4: SLICED +Pizza 1: SLICED +Pizza 3: SLICED +Pizza 2: SLICED +Pizza 4: BOXED +Pizza 0: BOXED +Pizza0: complete +Pizza 1: BOXED +Pizza1: complete +Pizza 3: BOXED +Pizza 2: BOXED +Pizza2: complete +Pizza3: complete +Pizza4: complete +1797 +*/ diff --git a/code/concurrent/CompletableUtilities.java b/code/concurrent/CompletableUtilities.java new file mode 100644 index 00000000..8f3a0e51 --- /dev/null +++ b/code/concurrent/CompletableUtilities.java @@ -0,0 +1,27 @@ +// concurrent/CompletableUtilities.java +// (c)2020 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 onjava; +import java.util.concurrent.*; + +public class CompletableUtilities { + // Get and show value stored in a CF: + public static void showr(CompletableFuture c) { + try { + System.out.println(c.get()); + } catch(InterruptedException + | ExecutionException e) { + throw new RuntimeException(e); + } + } + // For CF operations that have no value: + public static void voidr(CompletableFuture c) { + try { + c.get(); // Returns void + } catch(InterruptedException + | ExecutionException e) { + throw new RuntimeException(e); + } + } +} diff --git a/code/concurrent/CompletedMachina.java b/code/concurrent/CompletedMachina.java new file mode 100644 index 00000000..06a78710 --- /dev/null +++ b/code/concurrent/CompletedMachina.java @@ -0,0 +1,19 @@ +// concurrent/CompletedMachina.java +// (c)2020 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. +import java.util.concurrent.*; + +public class CompletedMachina { + public static void main(String[] args) { + CompletableFuture cf = + CompletableFuture.completedFuture( + new Machina(0)); + try { + Machina m = cf.get(); // Doesn't block + } catch(InterruptedException | + ExecutionException e) { + throw new RuntimeException(e); + } + } +} diff --git a/code/concurrent/CountingStream.java b/code/concurrent/CountingStream.java new file mode 100644 index 00000000..4cebb24e --- /dev/null +++ b/code/concurrent/CountingStream.java @@ -0,0 +1,32 @@ +// concurrent/CountingStream.java +// (c)2020 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. +// {VisuallyInspectOutput} +import java.util.*; +import java.util.concurrent.*; +import java.util.stream.*; + +public class CountingStream { + public static void main(String[] args) { + System.out.println( + IntStream.range(0, 10) + .parallel() + .mapToObj(CountingTask::new) + .map(ct -> ct.call()) + .reduce(0, Integer::sum)); + } +} +/* Output: +1 ForkJoinPool.commonPool-worker-3 100 +8 ForkJoinPool.commonPool-worker-2 100 +0 ForkJoinPool.commonPool-worker-6 100 +2 ForkJoinPool.commonPool-worker-1 100 +4 ForkJoinPool.commonPool-worker-5 100 +9 ForkJoinPool.commonPool-worker-7 100 +6 main 100 +7 ForkJoinPool.commonPool-worker-4 100 +5 ForkJoinPool.commonPool-worker-2 100 +3 ForkJoinPool.commonPool-worker-3 100 +1000 +*/ diff --git a/code/concurrent/CountingTask.java b/code/concurrent/CountingTask.java new file mode 100644 index 00000000..b1fb7b89 --- /dev/null +++ b/code/concurrent/CountingTask.java @@ -0,0 +1,19 @@ +// concurrent/CountingTask.java +// (c)2020 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. +import java.util.concurrent.*; + +public class CountingTask implements Callable { + final int id; + public CountingTask(int id) { this.id = id; } + @Override + public Integer call() { + Integer val = 0; + for(int i = 0; i < 100; i++) + val++; + System.out.println(id + " " + + Thread.currentThread().getName() + " " + val); + return val; + } +} diff --git a/code/concurrent/DiningPhilosophers.java b/code/concurrent/DiningPhilosophers.java new file mode 100644 index 00000000..5c2b2f1b --- /dev/null +++ b/code/concurrent/DiningPhilosophers.java @@ -0,0 +1,33 @@ +// concurrent/DiningPhilosophers.java +// (c)2020 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. +// Hidden deadlock +// {ExcludeFromGradle} Gradle has trouble +import java.util.*; +import java.util.concurrent.*; +import onjava.Nap; + +public class DiningPhilosophers { + private StickHolder[] sticks; + private Philosopher[] philosophers; + public DiningPhilosophers(int n) { + sticks = new StickHolder[n]; + Arrays.setAll(sticks, i -> new StickHolder()); + philosophers = new Philosopher[n]; + Arrays.setAll(philosophers, i -> + new Philosopher(i, + sticks[i], sticks[(i + 1) % n])); // [1] + // Fix by reversing stick order for this one: + // philosophers[1] = // [2] + // new Philosopher(0, sticks[0], sticks[1]); + Arrays.stream(philosophers) + .forEach(CompletableFuture::runAsync); // [3] + } + public static void main(String[] args) { + // Returns right away: + new DiningPhilosophers(5); // [4] + // Keeps main() from exiting: + new Nap(3, "Shutdown"); + } +} diff --git a/code/concurrent/DualCompletableOperations.java b/code/concurrent/DualCompletableOperations.java new file mode 100644 index 00000000..42052312 --- /dev/null +++ b/code/concurrent/DualCompletableOperations.java @@ -0,0 +1,115 @@ +// concurrent/DualCompletableOperations.java +// (c)2020 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. +import java.util.concurrent.*; +import static onjava.CompletableUtilities.*; + +public class DualCompletableOperations { + static CompletableFuture cfA, cfB; + static void init() { + cfA = Workable.make("A", 0.15); + cfB = Workable.make("B", 0.10); // Always wins + } + static void join() { + cfA.join(); + cfB.join(); + System.out.println("*****************"); + } + public static void main(String[] args) { + init(); + voidr(cfA.runAfterEitherAsync(cfB, () -> + System.out.println("runAfterEither"))); + join(); + + init(); + voidr(cfA.runAfterBothAsync(cfB, () -> + System.out.println("runAfterBoth"))); + join(); + + init(); + showr(cfA.applyToEitherAsync(cfB, w -> { + System.out.println("applyToEither: " + w); + return w; + })); + join(); + + init(); + voidr(cfA.acceptEitherAsync(cfB, w -> { + System.out.println("acceptEither: " + w); + })); + join(); + + init(); + voidr(cfA.thenAcceptBothAsync(cfB, (w1, w2) -> { + System.out.println("thenAcceptBoth: " + + w1 + ", " + w2); + })); + join(); + + init(); + showr(cfA.thenCombineAsync(cfB, (w1, w2) -> { + System.out.println("thenCombine: " + + w1 + ", " + w2); + return w1; + })); + join(); + + init(); + CompletableFuture + cfC = Workable.make("C", 0.08), + cfD = Workable.make("D", 0.09); + CompletableFuture.anyOf(cfA, cfB, cfC, cfD) + .thenRunAsync(() -> + System.out.println("anyOf")); + join(); + + init(); + cfC = Workable.make("C", 0.08); + cfD = Workable.make("D", 0.09); + CompletableFuture.allOf(cfA, cfB, cfC, cfD) + .thenRunAsync(() -> + System.out.println("allOf")); + join(); + } +} +/* Output: +Workable[BW] +runAfterEither +Workable[AW] +***************** +Workable[BW] +Workable[AW] +runAfterBoth +***************** +Workable[BW] +applyToEither: Workable[BW] +Workable[BW] +Workable[AW] +***************** +Workable[BW] +acceptEither: Workable[BW] +Workable[AW] +***************** +Workable[BW] +Workable[AW] +thenAcceptBoth: Workable[AW], Workable[BW] +***************** +Workable[BW] +Workable[AW] +thenCombine: Workable[AW], Workable[BW] +Workable[AW] +***************** +Workable[CW] +anyOf +Workable[DW] +Workable[BW] +Workable[AW] +***************** +Workable[CW] +Workable[DW] +Workable[BW] +Workable[AW] +***************** +allOf +*/ diff --git a/code/concurrent/FrostedCake.java b/code/concurrent/FrostedCake.java new file mode 100644 index 00000000..1be8b661 --- /dev/null +++ b/code/concurrent/FrostedCake.java @@ -0,0 +1,32 @@ +// concurrent/FrostedCake.java +// (c)2020 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. +import java.util.concurrent.*; +import java.util.stream.*; +import onjava.Nap; + +final class Frosting { + private Frosting() {} + static CompletableFuture make() { + new Nap(0.1); + return CompletableFuture + .completedFuture(new Frosting()); + } +} + +public class FrostedCake { + public FrostedCake(Baked baked, Frosting frosting) { + new Nap(0.1); + } + @Override + public String toString() { return "FrostedCake"; } + public static void main(String[] args) { + Baked.batch().forEach(baked -> baked + .thenCombineAsync(Frosting.make(), + (cake, frosting) -> + new FrostedCake(cake, frosting)) + .thenAcceptAsync(System.out::println) + .join()); + } +} diff --git a/code/concurrent/Futures.java b/code/concurrent/Futures.java new file mode 100644 index 00000000..888e7f0d --- /dev/null +++ b/code/concurrent/Futures.java @@ -0,0 +1,23 @@ +// concurrent/Futures.java +// (c)2020 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. +import java.util.*; +import java.util.concurrent.*; +import java.util.stream.*; + +public class Futures { + public static void main(String[] args) + throws InterruptedException, ExecutionException { + ExecutorService exec = + Executors.newSingleThreadExecutor(); + Future f = + exec.submit(new CountingTask(99)); + System.out.println(f.get()); // [1] + exec.shutdown(); + } +} +/* Output: +99 pool-1-thread-1 100 +100 +*/ diff --git a/code/concurrent/GuardedIDField.java b/code/concurrent/GuardedIDField.java new file mode 100644 index 00000000..e570a5d3 --- /dev/null +++ b/code/concurrent/GuardedIDField.java @@ -0,0 +1,18 @@ +// concurrent/GuardedIDField.java +// (c)2020 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. +import java.util.concurrent.atomic.*; + +public class GuardedIDField implements HasID { + private static AtomicInteger counter = + new AtomicInteger(); + private int id = counter.getAndIncrement(); + public int getID() { return id; } + public static void main(String[] args) { + IDChecker.test(GuardedIDField::new); + } +} +/* Output: +0 +*/ diff --git a/code/concurrent/HasID.java b/code/concurrent/HasID.java new file mode 100644 index 00000000..e5e13438 --- /dev/null +++ b/code/concurrent/HasID.java @@ -0,0 +1,8 @@ +// concurrent/HasID.java +// (c)2020 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. + +public interface HasID { + int getID(); +} diff --git a/code/concurrent/IDChecker.java b/code/concurrent/IDChecker.java new file mode 100644 index 00000000..845c9e6a --- /dev/null +++ b/code/concurrent/IDChecker.java @@ -0,0 +1,41 @@ +// concurrent/IDChecker.java +// (c)2020 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. +import java.util.*; +import java.util.function.*; +import java.util.stream.*; +import java.util.concurrent.*; +import com.google.common.collect.Sets; + +public class IDChecker { + public static final int SIZE = 100_000; + static class MakeObjects + implements Supplier> { + private Supplier gen; + MakeObjects(Supplier gen) { + this.gen = gen; + } + @Override + public List get() { + return + Stream.generate(gen) + .limit(SIZE) + .map(HasID::getID) + .collect(Collectors.toList()); + } + } + public static void test(Supplier gen) { + CompletableFuture> + groupA = CompletableFuture + .supplyAsync(new MakeObjects(gen)), + groupB = CompletableFuture + .supplyAsync(new MakeObjects(gen)); + groupA.thenAcceptBoth(groupB, (a, b) -> { + System.out.println( + Sets.intersection( + Sets.newHashSet(a), + Sets.newHashSet(b)).size()); + }).join(); + } +} diff --git a/code/concurrent/InterferingTask.java b/code/concurrent/InterferingTask.java new file mode 100644 index 00000000..da08f653 --- /dev/null +++ b/code/concurrent/InterferingTask.java @@ -0,0 +1,17 @@ +// concurrent/InterferingTask.java +// (c)2020 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. + +public class InterferingTask implements Runnable { + final int id; + private static Integer val = 0; + public InterferingTask(int id) { this.id = id; } + @Override + public void run() { + for(int i = 0; i < 100; i++) + val++; + System.out.println(id + " " + + Thread.currentThread().getName() + " " + val); + } +} diff --git a/code/concurrent/LambdasAndMethodReferences.java b/code/concurrent/LambdasAndMethodReferences.java new file mode 100644 index 00000000..10552499 --- /dev/null +++ b/code/concurrent/LambdasAndMethodReferences.java @@ -0,0 +1,40 @@ +// concurrent/LambdasAndMethodReferences.java +// (c)2020 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. +import java.util.concurrent.*; + +class NotRunnable { + public void go() { + System.out.println("NotRunnable"); + } +} + +class NotCallable { + public Integer get() { + System.out.println("NotCallable"); + return 1; + } +} + +public class LambdasAndMethodReferences { + public static void main(String[] args) + throws InterruptedException { + ExecutorService exec = + Executors.newCachedThreadPool(); + exec.submit(() -> System.out.println("Lambda1")); + exec.submit(new NotRunnable()::go); + exec.submit(() -> { + System.out.println("Lambda2"); + return 1; + }); + exec.submit(new NotCallable()::get); + exec.shutdown(); + } +} +/* Output: +Lambda1 +NotCallable +NotRunnable +Lambda2 +*/ diff --git a/code/concurrent/Machina.java b/code/concurrent/Machina.java new file mode 100644 index 00000000..e70cd2b4 --- /dev/null +++ b/code/concurrent/Machina.java @@ -0,0 +1,31 @@ +// concurrent/Machina.java +// (c)2020 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. +import onjava.Nap; + +public class Machina { + public enum State { + START, ONE, TWO, THREE, END; + State step() { + if(equals(END)) return END; + return values()[ordinal() + 1]; + } + } + private State state = State.START; + private final int id; + public Machina(int id) { this.id = id; } + public static Machina work(Machina m) { + if(!m.state.equals(State.END)){ + new Nap(0.1); + m.state = m.state.step(); + } + System.out.println(m); + return m; + } + @Override + public String toString() { + return "Machina" + id + ": " + + (state.equals(State.END)? "complete" : state); + } +} diff --git a/code/concurrent/MoreTasksAfterShutdown.java b/code/concurrent/MoreTasksAfterShutdown.java new file mode 100644 index 00000000..28b96af8 --- /dev/null +++ b/code/concurrent/MoreTasksAfterShutdown.java @@ -0,0 +1,27 @@ +// concurrent/MoreTasksAfterShutdown.java +// (c)2020 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. +import java.util.concurrent.*; + +public class MoreTasksAfterShutdown { + public static void main(String[] args) { + ExecutorService exec = + Executors.newSingleThreadExecutor(); + exec.execute(new NapTask(1)); + exec.shutdown(); + try { + exec.execute(new NapTask(99)); + } catch(RejectedExecutionException e) { + System.out.println(e); + } + } +} +/* Output: +java.util.concurrent.RejectedExecutionException: Task +NapTask[99] rejected from java.util.concurrent.ThreadPo +olExecutor@4e25154f[Shutting down, pool size = 1, +active threads = 1, queued tasks = 0, completed tasks = +0] +NapTask[1] pool-1-thread-1 +*/ diff --git a/code/concurrent/NapTask.java b/code/concurrent/NapTask.java new file mode 100644 index 00000000..92df6b60 --- /dev/null +++ b/code/concurrent/NapTask.java @@ -0,0 +1,20 @@ +// concurrent/NapTask.java +// (c)2020 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. +import onjava.Nap; + +public class NapTask implements Runnable { + final int id; + public NapTask(int id) { this.id = id; } + @Override + public void run() { + new Nap(0.1); // Seconds + System.out.println(this + " " + + Thread.currentThread().getName()); + } + @Override + public String toString() { + return "NapTask[" + id + "]"; + } +} diff --git a/code/concurrent/OnePizza.java b/code/concurrent/OnePizza.java new file mode 100644 index 00000000..f4f27249 --- /dev/null +++ b/code/concurrent/OnePizza.java @@ -0,0 +1,26 @@ +// concurrent/OnePizza.java +// (c)2020 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. +import onjava.Timer; + +public class OnePizza { + public static void main(String[] args) { + Pizza za = new Pizza(0); + System.out.println( + Timer.duration(() -> { + while(!za.complete()) + za.next(); + })); + } +} +/* Output: +Pizza 0: ROLLED +Pizza 0: SAUCED +Pizza 0: CHEESED +Pizza 0: TOPPED +Pizza 0: BAKED +Pizza 0: SLICED +Pizza 0: BOXED +1622 +*/ diff --git a/code/concurrent/ParallelPrime.java b/code/concurrent/ParallelPrime.java new file mode 100644 index 00000000..97c02575 --- /dev/null +++ b/code/concurrent/ParallelPrime.java @@ -0,0 +1,35 @@ +// concurrent/ParallelPrime.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import static java.util.stream.LongStream.*; +import java.io.*; +import java.nio.file.*; +import onjava.Timer; + +public class ParallelPrime { + static final int COUNT = 100_000; + public static boolean isPrime(long n) { + return rangeClosed(2, (long)Math.sqrt(n)) + .noneMatch(i -> n % i == 0); + } + public static void main(String[] args) + throws IOException { + Timer timer = new Timer(); + List primes = + iterate(2, i -> i + 1) + .parallel() // [1] + .filter(ParallelPrime::isPrime) + .limit(COUNT) + .mapToObj(Long::toString) + .collect(Collectors.toList()); + System.out.println(timer.duration()); + Files.write(Paths.get("primes.txt"), primes, + StandardOpenOption.CREATE); + } +} +/* Output: +1224 +*/ diff --git a/code/concurrent/ParallelStreamPuzzle.java b/code/concurrent/ParallelStreamPuzzle.java new file mode 100644 index 00000000..f57dec24 --- /dev/null +++ b/code/concurrent/ParallelStreamPuzzle.java @@ -0,0 +1,28 @@ +// concurrent/ParallelStreamPuzzle.java +// (c)2020 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. +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +public class ParallelStreamPuzzle { + static class IntGenerator + implements Supplier { + private int current = 0; + public Integer get() { + return current++; + } + } + public static void main(String[] args) { + List x = + Stream.generate(new IntGenerator()) + .limit(10) + .parallel() // [1] + .collect(Collectors.toList()); + System.out.println(x); + } +} +/* Output: +[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +*/ diff --git a/code/concurrent/ParallelStreamPuzzle2.java b/code/concurrent/ParallelStreamPuzzle2.java new file mode 100644 index 00000000..2fc11d48 --- /dev/null +++ b/code/concurrent/ParallelStreamPuzzle2.java @@ -0,0 +1,38 @@ +// concurrent/ParallelStreamPuzzle2.java +// (c)2020 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. +import java.util.*; +import java.util.function.*; +import java.util.stream.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; +import java.nio.file.*; + +public class ParallelStreamPuzzle2 { + public static final Deque trace = + new ConcurrentLinkedDeque<>(); + static class + IntGenerator implements Supplier { + private AtomicInteger current = + new AtomicInteger(); + public Integer get() { + trace.add(current.get() + ": " + + Thread.currentThread().getName()); + return current.getAndIncrement(); + } + } + public static void + main(String[] args) throws Exception { + List x = + Stream.generate(new IntGenerator()) + .limit(10) + .parallel() + .collect(Collectors.toList()); + System.out.println(x); + Files.write(Paths.get("PSP2.txt"), trace); + } +} +/* Output: +[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +*/ diff --git a/code/concurrent/ParallelStreamPuzzle3.java b/code/concurrent/ParallelStreamPuzzle3.java new file mode 100644 index 00000000..757bddd5 --- /dev/null +++ b/code/concurrent/ParallelStreamPuzzle3.java @@ -0,0 +1,33 @@ +// concurrent/ParallelStreamPuzzle3.java +// (c)2020 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. +// {VisuallyInspectOutput} +import java.util.*; +import java.util.stream.*; + +public class ParallelStreamPuzzle3 { + public static void main(String[] args) { + List x = IntStream.range(0, 30) + .peek(e -> System.out.println(e + ": " + + Thread.currentThread().getName())) + .limit(10) + .parallel() + .boxed() + .collect(Collectors.toList()); + System.out.println(x); + } +} +/* Output: +8: main +6: ForkJoinPool.commonPool-worker-5 +3: ForkJoinPool.commonPool-worker-7 +5: ForkJoinPool.commonPool-worker-5 +1: ForkJoinPool.commonPool-worker-3 +2: ForkJoinPool.commonPool-worker-6 +4: ForkJoinPool.commonPool-worker-1 +0: ForkJoinPool.commonPool-worker-4 +7: ForkJoinPool.commonPool-worker-1 +9: ForkJoinPool.commonPool-worker-2 +[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +*/ diff --git a/code/concurrent/Philosopher.java b/code/concurrent/Philosopher.java new file mode 100644 index 00000000..48facb38 --- /dev/null +++ b/code/concurrent/Philosopher.java @@ -0,0 +1,30 @@ +// concurrent/Philosopher.java +// (c)2020 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. + +public class Philosopher implements Runnable { + private final int seat; + private final StickHolder left, right; + public Philosopher(int seat, + StickHolder left, StickHolder right) { + this.seat = seat; + this.left = left; + this.right = right; + } + @Override + public String toString() { + return "P" + seat; + } + @Override + public void run() { + while(true) { + // System.out.println("Thinking"); // [1] + right.pickUp(); + left.pickUp(); + System.out.println(this + " eating"); + right.putDown(); + left.putDown(); + } + } +} diff --git a/code/concurrent/Pizza.java b/code/concurrent/Pizza.java new file mode 100644 index 00000000..8cd5ff30 --- /dev/null +++ b/code/concurrent/Pizza.java @@ -0,0 +1,49 @@ +// concurrent/Pizza.java +// (c)2020 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. +import java.util.function.*; +import onjava.Nap; + +public class Pizza { + public enum Step { + DOUGH(4), ROLLED(1), SAUCED(1), CHEESED(2), + TOPPED(5), BAKED(2), SLICED(1), BOXED(0); + int effort; // Needed to get to the next step + Step(int effort) { this.effort = effort; } + Step forward() { + if(equals(BOXED)) return BOXED; + new Nap(effort * 0.1); + return values()[ordinal() + 1]; + } + } + private Step step = Step.DOUGH; + private final int id; + public Pizza(int id) { this.id = id; } + public Pizza next() { + step = step.forward(); + System.out.println("Pizza " + id + ": " + step); + return this; + } + public Pizza next(Step previousStep) { + if(!step.equals(previousStep)) + throw new IllegalStateException("Expected " + + previousStep + " but found " + step); + return next(); + } + public Pizza roll() { return next(Step.DOUGH); } + public Pizza sauce() { return next(Step.ROLLED); } + public Pizza cheese() { return next(Step.SAUCED); } + public Pizza toppings() { return next(Step.CHEESED); } + public Pizza bake() { return next(Step.TOPPED); } + public Pizza slice() { return next(Step.BAKED); } + public Pizza box() { return next(Step.SLICED); } + public boolean complete() { + return step.equals(Step.BOXED); + } + @Override + public String toString() { + return "Pizza" + id + ": " + + (step.equals(Step.BOXED)? "complete" : step); + } +} diff --git a/code/concurrent/PizzaParallelSteps.java b/code/concurrent/PizzaParallelSteps.java new file mode 100644 index 00000000..605e9985 --- /dev/null +++ b/code/concurrent/PizzaParallelSteps.java @@ -0,0 +1,69 @@ +// concurrent/PizzaParallelSteps.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import onjava.Timer; + +public class PizzaParallelSteps { + static final int QUANTITY = 5; + public static void main(String[] args) { + Timer timer = new Timer(); + IntStream.range(0, QUANTITY) + .mapToObj(Pizza::new) + .parallel() + .map(Pizza::roll) + .map(Pizza::sauce) + .map(Pizza::cheese) + .map(Pizza::toppings) + .map(Pizza::bake) + .map(Pizza::slice) + .map(Pizza::box) + .forEach(za -> System.out.println(za)); + System.out.println(timer.duration()); + } +} +/* Output: +Pizza 2: ROLLED +Pizza 0: ROLLED +Pizza 1: ROLLED +Pizza 4: ROLLED +Pizza 3: ROLLED +Pizza 1: SAUCED +Pizza 0: SAUCED +Pizza 2: SAUCED +Pizza 3: SAUCED +Pizza 4: SAUCED +Pizza 1: CHEESED +Pizza 0: CHEESED +Pizza 2: CHEESED +Pizza 3: CHEESED +Pizza 4: CHEESED +Pizza 0: TOPPED +Pizza 2: TOPPED +Pizza 1: TOPPED +Pizza 3: TOPPED +Pizza 4: TOPPED +Pizza 1: BAKED +Pizza 2: BAKED +Pizza 0: BAKED +Pizza 4: BAKED +Pizza 3: BAKED +Pizza 0: SLICED +Pizza 2: SLICED +Pizza 1: SLICED +Pizza 3: SLICED +Pizza 4: SLICED +Pizza 1: BOXED +Pizza1: complete +Pizza 2: BOXED +Pizza 0: BOXED +Pizza2: complete +Pizza0: complete +Pizza 3: BOXED +Pizza 4: BOXED +Pizza4: complete +Pizza3: complete +1738 +*/ diff --git a/code/concurrent/PizzaStreams.java b/code/concurrent/PizzaStreams.java new file mode 100644 index 00000000..16be983a --- /dev/null +++ b/code/concurrent/PizzaStreams.java @@ -0,0 +1,60 @@ +// concurrent/PizzaStreams.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import onjava.Timer; + +public class PizzaStreams { + static final int QUANTITY = 5; + public static void main(String[] args) { + Timer timer = new Timer(); + IntStream.range(0, QUANTITY) + .mapToObj(Pizza::new) + .parallel() // [1] + .forEach(za -> { + while(!za.complete()) + za.next(); + }); + System.out.println(timer.duration()); + } +} +/* Output: +Pizza 2: ROLLED +Pizza 0: ROLLED +Pizza 1: ROLLED +Pizza 4: ROLLED +Pizza 3: ROLLED +Pizza 2: SAUCED +Pizza 1: SAUCED +Pizza 0: SAUCED +Pizza 4: SAUCED +Pizza 3: SAUCED +Pizza 2: CHEESED +Pizza 1: CHEESED +Pizza 0: CHEESED +Pizza 4: CHEESED +Pizza 3: CHEESED +Pizza 2: TOPPED +Pizza 1: TOPPED +Pizza 0: TOPPED +Pizza 4: TOPPED +Pizza 3: TOPPED +Pizza 2: BAKED +Pizza 1: BAKED +Pizza 0: BAKED +Pizza 4: BAKED +Pizza 3: BAKED +Pizza 2: SLICED +Pizza 1: SLICED +Pizza 0: SLICED +Pizza 4: SLICED +Pizza 3: SLICED +Pizza 2: BOXED +Pizza 1: BOXED +Pizza 0: BOXED +Pizza 4: BOXED +Pizza 3: BOXED +1739 +*/ diff --git a/code/concurrent/QuittableTask.java b/code/concurrent/QuittableTask.java new file mode 100644 index 00000000..3cf2a62e --- /dev/null +++ b/code/concurrent/QuittableTask.java @@ -0,0 +1,20 @@ +// concurrent/QuittableTask.java +// (c)2020 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. +import java.util.concurrent.atomic.AtomicBoolean; +import onjava.Nap; + +public class QuittableTask implements Runnable { + final int id; + public QuittableTask(int id) { this.id = id; } + private AtomicBoolean running = + new AtomicBoolean(true); + public void quit() { running.set(false); } + @Override + public void run() { + while(running.get()) // [1] + new Nap(0.1); + System.out.print(id + " "); // [2] + } +} diff --git a/code/concurrent/QuittingCompletable.java b/code/concurrent/QuittingCompletable.java new file mode 100644 index 00000000..e41e3899 --- /dev/null +++ b/code/concurrent/QuittingCompletable.java @@ -0,0 +1,35 @@ +// concurrent/QuittingCompletable.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import java.util.concurrent.*; +import onjava.Nap; + +public class QuittingCompletable { + public static void main(String[] args) { + List tasks = + IntStream.range(1, QuittingTasks.COUNT) + .mapToObj(QuittableTask::new) + .collect(Collectors.toList()); + List> cfutures = + tasks.stream() + .map(CompletableFuture::runAsync) + .collect(Collectors.toList()); + new Nap(1); + tasks.forEach(QuittableTask::quit); + cfutures.forEach(CompletableFuture::join); + } +} +/* Output: +7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 +26 27 28 29 30 31 32 33 34 6 35 4 38 39 40 41 42 43 44 +45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 +63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 +81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 +99 100 101 102 103 104 105 106 107 108 109 110 111 112 +1 113 114 116 117 118 119 120 121 122 123 124 125 126 +127 128 129 130 131 132 133 134 135 136 137 138 139 140 +141 142 143 144 145 146 147 148 149 5 115 37 36 2 3 +*/ diff --git a/code/concurrent/QuittingTasks.java b/code/concurrent/QuittingTasks.java new file mode 100644 index 00000000..326e24ce --- /dev/null +++ b/code/concurrent/QuittingTasks.java @@ -0,0 +1,35 @@ +// concurrent/QuittingTasks.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import java.util.concurrent.*; +import onjava.Nap; + +public class QuittingTasks { + public static final int COUNT = 150; + public static void main(String[] args) { + ExecutorService es = + Executors.newCachedThreadPool(); + List tasks = + IntStream.range(1, COUNT) + .mapToObj(QuittableTask::new) + .peek(qt -> es.execute(qt)) + .collect(Collectors.toList()); + new Nap(1); + tasks.forEach(QuittableTask::quit); + es.shutdown(); + } +} +/* Output: +24 27 31 8 11 7 19 12 16 4 23 3 28 32 15 20 63 60 68 67 +64 39 47 52 51 55 40 43 48 59 44 56 36 35 71 72 83 103 +96 92 88 99 100 87 91 79 75 84 76 115 108 112 104 107 +111 95 80 147 120 127 119 123 144 143 116 132 124 128 +136 131 135 139 148 140 2 126 6 5 1 18 129 17 14 13 21 +22 9 10 30 33 58 37 125 26 34 133 145 78 137 141 138 62 +74 142 86 65 73 146 70 42 149 121 110 134 105 82 117 +106 113 122 45 114 118 38 50 29 90 101 89 57 53 94 41 +61 66 130 69 77 81 85 93 25 102 54 109 98 49 46 97 +*/ diff --git a/code/concurrent/SharedConstructorArgument.java b/code/concurrent/SharedConstructorArgument.java new file mode 100644 index 00000000..4b09cc26 --- /dev/null +++ b/code/concurrent/SharedConstructorArgument.java @@ -0,0 +1,44 @@ +// concurrent/SharedConstructorArgument.java +// (c)2020 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. +import java.util.concurrent.atomic.*; + +interface SharedArg { + int get(); +} + +class Unsafe implements SharedArg { + private int i = 0; + public int get() { return i++; } +} + +class Safe implements SharedArg { + private static AtomicInteger counter = + new AtomicInteger(); + public int get() { + return counter.getAndIncrement(); + } +} + +class SharedUser implements HasID { + private final int id; + SharedUser(SharedArg sa) { + id = sa.get(); + } + @Override + public int getID() { return id; } +} + +public class SharedConstructorArgument { + public static void main(String[] args) { + Unsafe unsafe = new Unsafe(); + IDChecker.test(() -> new SharedUser(unsafe)); + Safe safe = new Safe(); + IDChecker.test(() -> new SharedUser(safe)); + } +} +/* Output: +24838 +0 +*/ diff --git a/code/concurrent/SingleThreadExecutor.java b/code/concurrent/SingleThreadExecutor.java new file mode 100644 index 00000000..ef89e3a5 --- /dev/null +++ b/code/concurrent/SingleThreadExecutor.java @@ -0,0 +1,49 @@ +// concurrent/SingleThreadExecutor.java +// (c)2020 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. +import java.util.concurrent.*; +import java.util.stream.*; +import onjava.*; + +public class SingleThreadExecutor { + public static void main(String[] args) { + ExecutorService exec = + Executors.newSingleThreadExecutor(); + IntStream.range(0, 10) + .mapToObj(NapTask::new) + .forEach(exec::execute); + System.out.println("All tasks submitted"); + exec.shutdown(); + while(!exec.isTerminated()) { + System.out.println( + Thread.currentThread().getName() + + " awaiting termination"); + new Nap(0.1); + } + } +} +/* Output: +All tasks submitted +main awaiting termination +main awaiting termination +NapTask[0] pool-1-thread-1 +main awaiting termination +NapTask[1] pool-1-thread-1 +main awaiting termination +NapTask[2] pool-1-thread-1 +main awaiting termination +NapTask[3] pool-1-thread-1 +main awaiting termination +NapTask[4] pool-1-thread-1 +main awaiting termination +NapTask[5] pool-1-thread-1 +main awaiting termination +NapTask[6] pool-1-thread-1 +main awaiting termination +NapTask[7] pool-1-thread-1 +main awaiting termination +NapTask[8] pool-1-thread-1 +main awaiting termination +NapTask[9] pool-1-thread-1 +*/ diff --git a/code/concurrent/SingleThreadExecutor2.java b/code/concurrent/SingleThreadExecutor2.java new file mode 100644 index 00000000..08467df5 --- /dev/null +++ b/code/concurrent/SingleThreadExecutor2.java @@ -0,0 +1,30 @@ +// concurrent/SingleThreadExecutor2.java +// (c)2020 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. +import java.util.concurrent.*; +import java.util.stream.*; + +public class SingleThreadExecutor2 { + public static void main(String[] args) + throws InterruptedException { + ExecutorService exec = + Executors.newSingleThreadExecutor(); + IntStream.range(0, 10) + .mapToObj(NapTask::new) + .forEach(exec::execute); + exec.shutdown(); + } +} +/* Output: +NapTask[0] pool-1-thread-1 +NapTask[1] pool-1-thread-1 +NapTask[2] pool-1-thread-1 +NapTask[3] pool-1-thread-1 +NapTask[4] pool-1-thread-1 +NapTask[5] pool-1-thread-1 +NapTask[6] pool-1-thread-1 +NapTask[7] pool-1-thread-1 +NapTask[8] pool-1-thread-1 +NapTask[9] pool-1-thread-1 +*/ diff --git a/code/concurrent/SingleThreadExecutor3.java b/code/concurrent/SingleThreadExecutor3.java new file mode 100644 index 00000000..58149423 --- /dev/null +++ b/code/concurrent/SingleThreadExecutor3.java @@ -0,0 +1,30 @@ +// concurrent/SingleThreadExecutor3.java +// (c)2020 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. +import java.util.concurrent.*; +import java.util.stream.*; + +public class SingleThreadExecutor3 { + public static void main(String[] args) + throws InterruptedException { + ExecutorService exec = + Executors.newSingleThreadExecutor(); + IntStream.range(0, 10) + .mapToObj(InterferingTask::new) + .forEach(exec::execute); + exec.shutdown(); + } +} +/* Output: +0 pool-1-thread-1 100 +1 pool-1-thread-1 200 +2 pool-1-thread-1 300 +3 pool-1-thread-1 400 +4 pool-1-thread-1 500 +5 pool-1-thread-1 600 +6 pool-1-thread-1 700 +7 pool-1-thread-1 800 +8 pool-1-thread-1 900 +9 pool-1-thread-1 1000 +*/ diff --git a/code/concurrent/StaticIDField.java b/code/concurrent/StaticIDField.java new file mode 100644 index 00000000..22623faa --- /dev/null +++ b/code/concurrent/StaticIDField.java @@ -0,0 +1,10 @@ +// concurrent/StaticIDField.java +// (c)2020 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. + +public class StaticIDField implements HasID { + private static int counter = 0; + private int id = counter++; + public int getID() { return id; } +} diff --git a/code/concurrent/StickHolder.java b/code/concurrent/StickHolder.java new file mode 100644 index 00000000..719a1c63 --- /dev/null +++ b/code/concurrent/StickHolder.java @@ -0,0 +1,27 @@ +// concurrent/StickHolder.java +// (c)2020 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. +import java.util.concurrent.*; + +public class StickHolder { + private static class Chopstick {} + private Chopstick stick = new Chopstick(); + private BlockingQueue holder = + new ArrayBlockingQueue<>(1); + public StickHolder() { putDown(); } + public void pickUp() { + try { + holder.take(); // Blocks if unavailable + } catch(InterruptedException e) { + throw new RuntimeException(e); + } + } + public void putDown() { + try { + holder.put(stick); + } catch(InterruptedException e) { + throw new RuntimeException(e); + } + } +} diff --git a/code/concurrent/StreamExceptions.java b/code/concurrent/StreamExceptions.java new file mode 100644 index 00000000..493daee1 --- /dev/null +++ b/code/concurrent/StreamExceptions.java @@ -0,0 +1,40 @@ +// concurrent/StreamExceptions.java +// (c)2020 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. +import java.util.concurrent.*; +import java.util.stream.*; + +public class StreamExceptions { + static Stream + test(String id, int failcount) { + return + Stream.of(new Breakable(id, failcount)) + .map(Breakable::work) + .map(Breakable::work) + .map(Breakable::work) + .map(Breakable::work); + } + public static void main(String[] args) { + // No operations are even applied ... + test("A", 1); + test("B", 2); + Stream c = test("C", 3); + test("D", 4); + test("E", 5); + // ... until there's a terminal operation: + System.out.println("Entering try"); + try { + c.forEach(System.out::println); // [1] + } catch(Exception e) { + System.out.println(e.getMessage()); + } + } +} +/* Output: +Entering try +Breakable_C [2] +Breakable_C [1] +Throwing Exception for C +Breakable_C failed +*/ diff --git a/code/concurrent/Summing.java b/code/concurrent/Summing.java new file mode 100644 index 00000000..321dcb57 --- /dev/null +++ b/code/concurrent/Summing.java @@ -0,0 +1,47 @@ +// concurrent/Summing.java +// (c)2020 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. +import java.util.stream.*; +import java.util.function.*; +import onjava.Timer; + +public class Summing { + static void timeTest(String id, long checkValue, + LongSupplier operation) { + System.out.print(id + ": "); + Timer timer = new Timer(); + long result = operation.getAsLong(); + if(result == checkValue) + System.out.println(timer.duration() + "ms"); + else + System.out.format("result: %d%ncheckValue: %d%n", + result, checkValue); + } + public static final int SZ = 100_000_000; + // This even works: + // public static final int SZ = 1_000_000_000; + public static final long CHECK = + (long)SZ * ((long)SZ + 1)/2; // Gauss's formula + public static void main(String[] args) { + System.out.println(CHECK); + timeTest("Sum Stream", CHECK, () -> + LongStream.rangeClosed(0, SZ).sum()); + timeTest("Sum Stream Parallel", CHECK, () -> + LongStream.rangeClosed(0, SZ).parallel().sum()); + timeTest("Sum Iterated", CHECK, () -> + LongStream.iterate(0, i -> i + 1) + .limit(SZ+1).sum()); + // Slower & runs out of memory above 1_000_000: + // timeTest("Sum Iterated Parallel", CHECK, () -> + // LongStream.iterate(0, i -> i + 1) + // .parallel() + // .limit(SZ+1).sum()); + } +} +/* Output: +5000000050000000 +Sum Stream: 167ms +Sum Stream Parallel: 46ms +Sum Iterated: 284ms +*/ diff --git a/code/concurrent/Summing2.java b/code/concurrent/Summing2.java new file mode 100644 index 00000000..c046721f --- /dev/null +++ b/code/concurrent/Summing2.java @@ -0,0 +1,44 @@ +// concurrent/Summing2.java +// (c)2020 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. +// {ExcludeFromTravisCI} +import java.util.*; + +public class Summing2 { + static long basicSum(long[] ia) { + long sum = 0; + int size = ia.length; + for(int i = 0; i < size; i++) + sum += ia[i]; + return sum; + } + // Approximate largest value of SZ before + // running out of memory on my machine: + public static final int SZ = 20_000_000; + public static final long CHECK = + (long)SZ * ((long)SZ + 1)/2; + public static void main(String[] args) { + System.out.println(CHECK); + long[] la = new long[SZ+1]; + Arrays.parallelSetAll(la, i -> i); + Summing.timeTest("Array Stream Sum", CHECK, () -> + Arrays.stream(la).sum()); + Summing.timeTest("Parallel", CHECK, () -> + Arrays.stream(la).parallel().sum()); + Summing.timeTest("Basic Sum", CHECK, () -> + basicSum(la)); + // Destructive summation: + Summing.timeTest("parallelPrefix", CHECK, () -> { + Arrays.parallelPrefix(la, Long::sum); + return la[la.length - 1]; + }); + } +} +/* Output: +200000010000000 +Array Stream Sum: 104ms +Parallel: 81ms +Basic Sum: 106ms +parallelPrefix: 265ms +*/ diff --git a/code/concurrent/Summing3.java b/code/concurrent/Summing3.java new file mode 100644 index 00000000..252e96f7 --- /dev/null +++ b/code/concurrent/Summing3.java @@ -0,0 +1,42 @@ +// concurrent/Summing3.java +// (c)2020 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. +// {ExcludeFromTravisCI} +import java.util.*; + +public class Summing3 { + static long basicSum(Long[] ia) { + long sum = 0; + int size = ia.length; + for(int i = 0; i < size; i++) + sum += ia[i]; + return sum; + } + // Approximate largest value of SZ before + // running out of memory on my machine: + public static final int SZ = 10_000_000; + public static final long CHECK = + (long)SZ * ((long)SZ + 1)/2; + public static void main(String[] args) { + System.out.println(CHECK); + Long[] aL = new Long[SZ+1]; + Arrays.parallelSetAll(aL, i -> (long)i); + Summing.timeTest("Long Array Stream Reduce", + CHECK, () -> + Arrays.stream(aL).reduce(0L, Long::sum)); + Summing.timeTest("Long Basic Sum", CHECK, () -> + basicSum(aL)); + // Destructive summation: + Summing.timeTest("Long parallelPrefix",CHECK, ()-> { + Arrays.parallelPrefix(aL, Long::sum); + return aL[aL.length - 1]; + }); + } +} +/* Output: +50000005000000 +Long Array Stream Reduce: 1038ms +Long Basic Sum: 21ms +Long parallelPrefix: 3616ms +*/ diff --git a/code/concurrent/Summing4.java b/code/concurrent/Summing4.java new file mode 100644 index 00000000..bb4fe2ea --- /dev/null +++ b/code/concurrent/Summing4.java @@ -0,0 +1,23 @@ +// concurrent/Summing4.java +// (c)2020 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. +// {ExcludeFromTravisCI} +import java.util.*; + +public class Summing4 { + public static void main(String[] args) { + System.out.println(Summing3.CHECK); + Long[] aL = new Long[Summing3.SZ+1]; + Arrays.parallelSetAll(aL, i -> (long)i); + Summing.timeTest("Long Parallel", + Summing3.CHECK, () -> + Arrays.stream(aL) + .parallel() + .reduce(0L,Long::sum)); + } +} +/* Output: +50000005000000 +Long Parallel: 1014ms +*/ diff --git a/code/concurrent/SynchronizedConstructor.java b/code/concurrent/SynchronizedConstructor.java new file mode 100644 index 00000000..95aa6a54 --- /dev/null +++ b/code/concurrent/SynchronizedConstructor.java @@ -0,0 +1,29 @@ +// concurrent/SynchronizedConstructor.java +// (c)2020 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. +import java.util.concurrent.atomic.*; + +class SyncConstructor implements HasID { + private final int id; + private static Object + constructorLock = new Object(); + SyncConstructor(SharedArg sa) { + synchronized(constructorLock) { + id = sa.get(); + } + } + @Override + public int getID() { return id; } +} + +public class SynchronizedConstructor { + public static void main(String[] args) { + Unsafe unsafe = new Unsafe(); + IDChecker.test(() -> + new SyncConstructor(unsafe)); + } +} +/* Output: +0 +*/ diff --git a/code/concurrent/SynchronizedFactory.java b/code/concurrent/SynchronizedFactory.java new file mode 100644 index 00000000..669d4d76 --- /dev/null +++ b/code/concurrent/SynchronizedFactory.java @@ -0,0 +1,29 @@ +// concurrent/SynchronizedFactory.java +// (c)2020 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. +import java.util.concurrent.atomic.*; + +final class SyncFactory implements HasID { + private final int id; + private SyncFactory(SharedArg sa) { + id = sa.get(); + } + @Override + public int getID() { return id; } + public static synchronized + SyncFactory factory(SharedArg sa) { + return new SyncFactory(sa); + } +} + +public class SynchronizedFactory { + public static void main(String[] args) { + Unsafe unsafe = new Unsafe(); + IDChecker.test(() -> + SyncFactory.factory(unsafe)); + } +} +/* Output: +0 +*/ diff --git a/code/concurrent/TestStaticIDField.java b/code/concurrent/TestStaticIDField.java new file mode 100644 index 00000000..5df298b7 --- /dev/null +++ b/code/concurrent/TestStaticIDField.java @@ -0,0 +1,13 @@ +// concurrent/TestStaticIDField.java +// (c)2020 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. + +public class TestStaticIDField { + public static void main(String[] args) { + IDChecker.test(StaticIDField::new); + } +} +/* Output: +13287 +*/ diff --git a/code/concurrent/ThrowsChecked.java b/code/concurrent/ThrowsChecked.java new file mode 100644 index 00000000..59177b35 --- /dev/null +++ b/code/concurrent/ThrowsChecked.java @@ -0,0 +1,42 @@ +// concurrent/ThrowsChecked.java +// (c)2020 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. +import java.util.stream.*; +import java.util.concurrent.*; + +public class ThrowsChecked { + class Checked extends Exception {} + static ThrowsChecked nochecked(ThrowsChecked tc) { + return tc; + } + static ThrowsChecked + withchecked(ThrowsChecked tc) throws Checked { + return tc; + } + static void testStream() { + Stream.of(new ThrowsChecked()) + .map(ThrowsChecked::nochecked) + // .map(ThrowsChecked::withchecked); // [1] + .map(tc -> { + try { + return withchecked(tc); + } catch(Checked e) { + throw new RuntimeException(e); + } + }); + } + static void testCompletableFuture() { + CompletableFuture + .completedFuture(new ThrowsChecked()) + .thenApply(ThrowsChecked::nochecked) + // .thenApply(ThrowsChecked::withchecked); // [2] + .thenApply(tc -> { + try { + return withchecked(tc); + } catch(Checked e) { + throw new RuntimeException(e); + } + }); + } +} diff --git a/code/concurrent/Workable.java b/code/concurrent/Workable.java new file mode 100644 index 00000000..fcdbbbf8 --- /dev/null +++ b/code/concurrent/Workable.java @@ -0,0 +1,32 @@ +// concurrent/Workable.java +// (c)2020 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. +import java.util.concurrent.*; +import onjava.Nap; + +public class Workable { + String id; + final double duration; + public Workable(String id, double duration) { + this.id = id; + this.duration = duration; + } + @Override + public String toString() { + return "Workable[" + id + "]"; + } + public static Workable work(Workable tt) { + new Nap(tt.duration); // Seconds + tt.id = tt.id + "W"; + System.out.println(tt); + return tt; + } + public static CompletableFuture + make(String id, double duration) { + return + CompletableFuture.completedFuture( + new Workable(id, duration)) + .thenApplyAsync(Workable::work); + } +} diff --git a/code/control/BreakAndContinue.java b/code/control/BreakAndContinue.java new file mode 100644 index 00000000..1faaaa03 --- /dev/null +++ b/code/control/BreakAndContinue.java @@ -0,0 +1,38 @@ +// control/BreakAndContinue.java +// (c)2020 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. +// Break and continue keywords +import static onjava.Range.*; + +public class BreakAndContinue { + public static void main(String[] args) { + for(int i = 0; i < 100; i++) { // [1] + if(i == 74) break; // Out of for loop + if(i % 9 != 0) continue; // Next iteration + System.out.print(i + " "); + } + System.out.println(); + // Using for-in: + for(int i : range(100)) { // [2] + if(i == 74) break; // Out of for loop + if(i % 9 != 0) continue; // Next iteration + System.out.print(i + " "); + } + System.out.println(); + int i = 0; + // An "infinite loop": + while(true) { // [3] + i++; + int j = i * 27; + if(j == 1269) break; // Out of loop + if(i % 10 != 0) continue; // Top of loop + System.out.print(i + " "); + } + } +} +/* Output: +0 9 18 27 36 45 54 63 72 +0 9 18 27 36 45 54 63 72 +10 20 30 40 +*/ diff --git a/code/control/CommaOperator.java b/code/control/CommaOperator.java new file mode 100644 index 00000000..eae2df82 --- /dev/null +++ b/code/control/CommaOperator.java @@ -0,0 +1,18 @@ +// control/CommaOperator.java +// (c)2020 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. + +public class CommaOperator { + public static void main(String[] args) { + for(int i = 1, j = i + 10; i < 5; i++, j = i * 2) { + System.out.println("i = " + i + " j = " + j); + } + } +} +/* Output: +i = 1 j = 11 +i = 2 j = 4 +i = 3 j = 6 +i = 4 j = 8 +*/ diff --git a/code/control/ForInFloat.java b/code/control/ForInFloat.java new file mode 100644 index 00000000..cee845b5 --- /dev/null +++ b/code/control/ForInFloat.java @@ -0,0 +1,28 @@ +// control/ForInFloat.java +// (c)2020 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. +import java.util.*; + +public class ForInFloat { + public static void main(String[] args) { + Random rand = new Random(47); + float[] f = new float[10]; + for(int i = 0; i < 10; i++) + f[i] = rand.nextFloat(); + for(float x : f) + System.out.println(x); + } +} +/* Output: +0.72711575 +0.39982635 +0.5309454 +0.0534122 +0.16020656 +0.57799757 +0.18847865 +0.4170137 +0.51660204 +0.73734957 +*/ diff --git a/code/control/ForInInt.java b/code/control/ForInInt.java new file mode 100644 index 00000000..f6b283a3 --- /dev/null +++ b/code/control/ForInInt.java @@ -0,0 +1,28 @@ +// control/ForInInt.java +// (c)2020 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. +import static onjava.Range.*; + +public class ForInInt { + public static void main(String[] args) { + for(int i : range(10)) // 0..9 + System.out.print(i + " "); + System.out.println(); + for(int i : range(5, 10)) // 5..9 + System.out.print(i + " "); + System.out.println(); + for(int i : range(5, 20, 3)) // 5..20 step 3 + System.out.print(i + " "); + System.out.println(); + for(int i : range(20, 5, -3)) // Count down + System.out.print(i + " "); + System.out.println(); + } +} +/* Output: +0 1 2 3 4 5 6 7 8 9 +5 6 7 8 9 +5 8 11 14 17 +20 17 14 11 8 +*/ diff --git a/code/control/ForInString.java b/code/control/ForInString.java new file mode 100644 index 00000000..73e16538 --- /dev/null +++ b/code/control/ForInString.java @@ -0,0 +1,14 @@ +// control/ForInString.java +// (c)2020 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. + +public class ForInString { + public static void main(String[] args) { + for(char c : "An African Swallow".toCharArray()) + System.out.print(c + " "); + } +} +/* Output: +A n A f r i c a n S w a l l o w +*/ diff --git a/code/control/IfElse.java b/code/control/IfElse.java new file mode 100644 index 00000000..f40a07b7 --- /dev/null +++ b/code/control/IfElse.java @@ -0,0 +1,29 @@ +// control/IfElse.java +// (c)2020 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. + +public class IfElse { + static int result = 0; + static void test(int testval, int target) { + if(testval > target) + result = +1; + else if(testval < target) // [1] + result = -1; + else + result = 0; // Match + } + public static void main(String[] args) { + test(10, 5); + System.out.println(result); + test(5, 10); + System.out.println(result); + test(5, 5); + System.out.println(result); + } +} +/* Output: +1 +-1 +0 +*/ diff --git a/code/control/LabeledFor.java b/code/control/LabeledFor.java new file mode 100644 index 00000000..2df79bad --- /dev/null +++ b/code/control/LabeledFor.java @@ -0,0 +1,65 @@ +// control/LabeledFor.java +// (c)2020 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. +// For loops with "labeled break"/"labeled continue." + +public class LabeledFor { + public static void main(String[] args) { + int i = 0; + outer: // Can't have statements here + for(; true ;) { // infinite loop + inner: // Can't have statements here + for(; i < 10; i++) { + System.out.println("i = " + i); + if(i == 2) { + System.out.println("continue"); + continue; + } + if(i == 3) { + System.out.println("break"); + i++; // Otherwise i never + // gets incremented. + break; + } + if(i == 7) { + System.out.println("continue outer"); + i++; // Otherwise i never + // gets incremented. + continue outer; + } + if(i == 8) { + System.out.println("break outer"); + break outer; + } + for(int k = 0; k < 5; k++) { + if(k == 3) { + System.out.println("continue inner"); + continue inner; + } + } + } + } + // Can't break or continue to labels here + } +} +/* Output: +i = 0 +continue inner +i = 1 +continue inner +i = 2 +continue +i = 3 +break +i = 4 +continue inner +i = 5 +continue inner +i = 6 +continue inner +i = 7 +continue outer +i = 8 +break outer +*/ diff --git a/code/control/LabeledWhile.java b/code/control/LabeledWhile.java new file mode 100644 index 00000000..961f5ff3 --- /dev/null +++ b/code/control/LabeledWhile.java @@ -0,0 +1,51 @@ +// control/LabeledWhile.java +// (c)2020 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. +// "While" with "labeled break" and "labeled continue." + +public class LabeledWhile { + public static void main(String[] args) { + int i = 0; + outer: + while(true) { + System.out.println("Outer while loop"); + while(true) { + i++; + System.out.println("i = " + i); + if(i == 1) { + System.out.println("continue"); + continue; + } + if(i == 3) { + System.out.println("continue outer"); + continue outer; + } + if(i == 5) { + System.out.println("break"); + break; + } + if(i == 7) { + System.out.println("break outer"); + break outer; + } + } + } + } +} +/* Output: +Outer while loop +i = 1 +continue +i = 2 +i = 3 +continue outer +Outer while loop +i = 4 +i = 5 +break +Outer while loop +i = 6 +i = 7 +break outer +*/ diff --git a/code/control/ListCharacters.java b/code/control/ListCharacters.java new file mode 100644 index 00000000..43efce9f --- /dev/null +++ b/code/control/ListCharacters.java @@ -0,0 +1,27 @@ +// control/ListCharacters.java +// (c)2020 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. +// List all the lowercase ASCII letters + +public class ListCharacters { + public static void main(String[] args) { + for(char c = 0; c < 128; c++) + if(Character.isLowerCase(c)) + System.out.println("value: " + (int)c + + " character: " + c); + } +} +/* Output: (First 10 Lines) +value: 97 character: a +value: 98 character: b +value: 99 character: c +value: 100 character: d +value: 101 character: e +value: 102 character: f +value: 103 character: g +value: 104 character: h +value: 105 character: i +value: 106 character: j + ... +*/ diff --git a/code/control/RandomBounds.java b/code/control/RandomBounds.java new file mode 100644 index 00000000..6befc6f4 --- /dev/null +++ b/code/control/RandomBounds.java @@ -0,0 +1,30 @@ +// control/RandomBounds.java +// (c)2020 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. +// Does Math.random() produce 0.0 and 1.0? +// {java RandomBounds lower} +import onjava.*; + +public class RandomBounds { + public static void main(String[] args) { + new TimedAbort(3); + switch(args.length == 0 ? "" : args[0]) { + case "lower": + while(Math.random() != 0.0) + ; // Keep trying + System.out.println("Produced 0.0!"); + break; + case "upper": + while(Math.random() != 1.0) + ; // Keep trying + System.out.println("Produced 1.0!"); + break; + default: + System.out.println("Usage:"); + System.out.println("\tRandomBounds lower"); + System.out.println("\tRandomBounds upper"); + System.exit(1); + } + } +} diff --git a/code/control/StringSwitch.java b/code/control/StringSwitch.java new file mode 100644 index 00000000..638cc427 --- /dev/null +++ b/code/control/StringSwitch.java @@ -0,0 +1,44 @@ +// control/StringSwitch.java +// (c)2020 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. + +public class StringSwitch { + public static void main(String[] args) { + String color = "red"; + // Old way: using if-then + if("red".equals(color)) { + System.out.println("RED"); + } else if("green".equals(color)) { + System.out.println("GREEN"); + } else if("blue".equals(color)) { + System.out.println("BLUE"); + } else if("yellow".equals(color)) { + System.out.println("YELLOW"); + } else { + System.out.println("Unknown"); + } + // New way: Strings in switch + switch(color) { + case "red": + System.out.println("RED"); + break; + case "green": + System.out.println("GREEN"); + break; + case "blue": + System.out.println("BLUE"); + break; + case "yellow": + System.out.println("YELLOW"); + break; + default: + System.out.println("Unknown"); + break; + } + } +} +/* Output: +RED +RED +*/ diff --git a/code/control/TestWithReturn.java b/code/control/TestWithReturn.java new file mode 100644 index 00000000..efe05c90 --- /dev/null +++ b/code/control/TestWithReturn.java @@ -0,0 +1,24 @@ +// control/TestWithReturn.java +// (c)2020 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. + +public class TestWithReturn { + static int test(int testval, int target) { + if(testval > target) + return +1; + if(testval < target) + return -1; + return 0; // Match + } + public static void main(String[] args) { + System.out.println(test(10, 5)); + System.out.println(test(5, 10)); + System.out.println(test(5, 5)); + } +} +/* Output: +1 +-1 +0 +*/ diff --git a/code/control/TrueFalse.java b/code/control/TrueFalse.java new file mode 100644 index 00000000..e87dade4 --- /dev/null +++ b/code/control/TrueFalse.java @@ -0,0 +1,15 @@ +// control/TrueFalse.java +// (c)2020 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. + +public class TrueFalse { + public static void main(String[] args) { + System.out.println(1 == 1); + System.out.println(1 == 2); + } +} +/* Output: +true +false +*/ diff --git a/code/control/VowelsAndConsonants.java b/code/control/VowelsAndConsonants.java new file mode 100644 index 00000000..d3a192d0 --- /dev/null +++ b/code/control/VowelsAndConsonants.java @@ -0,0 +1,44 @@ +// control/VowelsAndConsonants.java +// (c)2020 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. +// Demonstrates the switch statement +import java.util.*; + +public class VowelsAndConsonants { + public static void main(String[] args) { + Random rand = new Random(47); + for(int i = 0; i < 100; i++) { + int c = rand.nextInt(26) + 'a'; + System.out.print((char)c + ", " + c + ": "); + switch(c) { + case 'a': + case 'e': + case 'i': + case 'o': + case 'u': System.out.println("vowel"); + break; + case 'y': + case 'w': System.out.println("Sometimes vowel"); + break; + default: System.out.println("consonant"); + } + } + } +} +/* Output: (First 13 Lines) +y, 121: Sometimes vowel +n, 110: consonant +z, 122: consonant +b, 98: consonant +r, 114: consonant +n, 110: consonant +y, 121: Sometimes vowel +g, 103: consonant +c, 99: consonant +f, 102: consonant +o, 111: vowel +w, 119: Sometimes vowel +z, 122: consonant + ... +*/ diff --git a/code/control/WhileTest.java b/code/control/WhileTest.java new file mode 100644 index 00000000..075068cf --- /dev/null +++ b/code/control/WhileTest.java @@ -0,0 +1,31 @@ +// control/WhileTest.java +// (c)2020 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. +// Demonstrates the while loop + +public class WhileTest { + static boolean condition() { + boolean result = Math.random() < 0.99; + System.out.print(result + ", "); + return result; + } + public static void main(String[] args) { + while(condition()) + System.out.println("Inside 'while'"); + System.out.println("Exited 'while'"); + } +} +/* Output: (First and Last 5 Lines) +true, Inside 'while' +true, Inside 'while' +true, Inside 'while' +true, Inside 'while' +true, Inside 'while' +...________...________...________...________... +true, Inside 'while' +true, Inside 'while' +true, Inside 'while' +true, Inside 'while' +false, Exited 'while' +*/ diff --git a/code/enums/AlarmPoints.java b/code/enums/AlarmPoints.java new file mode 100644 index 00000000..a8731137 --- /dev/null +++ b/code/enums/AlarmPoints.java @@ -0,0 +1,9 @@ +// enums/AlarmPoints.java +// (c)2020 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 enums; +public enum AlarmPoints { + STAIR1, STAIR2, LOBBY, OFFICE1, OFFICE2, OFFICE3, + OFFICE4, BATHROOM, UTILITY, KITCHEN +} diff --git a/code/enums/BigEnumSet.java b/code/enums/BigEnumSet.java new file mode 100644 index 00000000..52ac3445 --- /dev/null +++ b/code/enums/BigEnumSet.java @@ -0,0 +1,29 @@ +// enums/BigEnumSet.java +// (c)2020 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. +import java.util.*; + +public class BigEnumSet { + enum Big { A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, + A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, + A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, + A30, A31, A32, A33, A34, A35, A36, A37, A38, A39, + A40, A41, A42, A43, A44, A45, A46, A47, A48, A49, + A50, A51, A52, A53, A54, A55, A56, A57, A58, A59, + A60, A61, A62, A63, A64, A65, A66, A67, A68, A69, + A70, A71, A72, A73, A74, A75 } + public static void main(String[] args) { + EnumSet bigEnumSet = EnumSet.allOf(Big.class); + System.out.println(bigEnumSet); + } +} +/* Output: +[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, +A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, +A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, +A35, A36, A37, A38, A39, A40, A41, A42, A43, A44, A45, +A46, A47, A48, A49, A50, A51, A52, A53, A54, A55, A56, +A57, A58, A59, A60, A61, A62, A63, A64, A65, A66, A67, +A68, A69, A70, A71, A72, A73, A74, A75] +*/ diff --git a/code/enums/Burrito2.java b/code/enums/Burrito2.java new file mode 100644 index 00000000..8b92ab0d --- /dev/null +++ b/code/enums/Burrito2.java @@ -0,0 +1,28 @@ +// enums/Burrito2.java +// (c)2020 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. +// {java enums.Burrito2} +package enums; +import static enums.SpicinessEnum.*; + +public class Burrito2 { + SpicinessEnum degree; + public Burrito2(SpicinessEnum degree) { + this.degree = degree; + } + @Override + public String toString() { + return "Burrito is "+ degree; + } + public static void main(String[] args) { + System.out.println(new Burrito2(NOT)); + System.out.println(new Burrito2(MEDIUM)); + System.out.println(new Burrito2(HOT)); + } +} +/* Output: +Burrito is NOT +Burrito is MEDIUM +Burrito is HOT +*/ diff --git a/code/enums/CarWash.java b/code/enums/CarWash.java new file mode 100644 index 00000000..95800e8f --- /dev/null +++ b/code/enums/CarWash.java @@ -0,0 +1,88 @@ +// enums/CarWash.java +// (c)2020 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. +import java.util.*; + +public class CarWash { + public enum Cycle { + UNDERBODY { + @Override + void action() { + System.out.println("Spraying the underbody"); + } + }, + WHEELWASH { + @Override + void action() { + System.out.println("Washing the wheels"); + } + }, + PREWASH { + @Override + void action() { + System.out.println("Loosening the dirt"); + } + }, + BASIC { + @Override + void action() { + System.out.println("The basic wash"); + } + }, + HOTWAX { + @Override + void action() { + System.out.println("Applying hot wax"); + } + }, + RINSE { + @Override + void action() { + System.out.println("Rinsing"); + } + }, + BLOWDRY { + @Override + void action() { + System.out.println("Blowing dry"); + } + }; + abstract void action(); + } + EnumSet cycles = + EnumSet.of(Cycle.BASIC, Cycle.RINSE); + public void add(Cycle cycle) { + cycles.add(cycle); + } + public void washCar() { + for(Cycle c : cycles) + c.action(); + } + @Override + public String toString() { + return cycles.toString(); + } + public static void main(String[] args) { + CarWash wash = new CarWash(); + System.out.println(wash); + wash.washCar(); + // Order of addition is unimportant: + wash.add(Cycle.BLOWDRY); + wash.add(Cycle.BLOWDRY); // Duplicates ignored + wash.add(Cycle.RINSE); + wash.add(Cycle.HOTWAX); + System.out.println(wash); + wash.washCar(); + } +} +/* Output: +[BASIC, RINSE] +The basic wash +Rinsing +[BASIC, HOTWAX, RINSE, BLOWDRY] +The basic wash +Applying hot wax +Rinsing +Blowing dry +*/ diff --git a/code/enums/Competitor.java b/code/enums/Competitor.java new file mode 100644 index 00000000..09bf7141 --- /dev/null +++ b/code/enums/Competitor.java @@ -0,0 +1,10 @@ +// enums/Competitor.java +// (c)2020 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. +// Switching one enum on another +package enums; + +public interface Competitor> { + Outcome compete(T competitor); +} diff --git a/code/enums/ConstantSpecificMethod.java b/code/enums/ConstantSpecificMethod.java new file mode 100644 index 00000000..913aa291 --- /dev/null +++ b/code/enums/ConstantSpecificMethod.java @@ -0,0 +1,41 @@ +// enums/ConstantSpecificMethod.java +// (c)2020 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. +import java.util.*; +import java.text.*; + +public enum ConstantSpecificMethod { + DATE_TIME { + @Override + String getInfo() { + return + DateFormat.getDateInstance() + .format(new Date()); + } + }, + CLASSPATH { + @Override + String getInfo() { + return System.getenv("CLASSPATH"); + } + }, + VERSION { + @Override + String getInfo() { + return System.getProperty("java.version"); + } + }; + abstract String getInfo(); + public static void main(String[] args) { + for(ConstantSpecificMethod csm : values()) + System.out.println(csm.getInfo()); + } +} +/* Output: +May 9, 2017 +C:\Users\Bruce\Documents\GitHub\on- +java\ExtractedExamples\\gradle\wrapper\gradle- +wrapper.jar +1.8.0_112 +*/ diff --git a/code/enums/EnumClass.java b/code/enums/EnumClass.java new file mode 100644 index 00000000..061f8abf --- /dev/null +++ b/code/enums/EnumClass.java @@ -0,0 +1,51 @@ +// enums/EnumClass.java +// (c)2020 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. +// Capabilities of the Enum class + +enum Shrubbery { GROUND, CRAWLING, HANGING } + +public class EnumClass { + public static void main(String[] args) { + for(Shrubbery s : Shrubbery.values()) { + System.out.println( + s + " ordinal: " + s.ordinal()); + System.out.print( + s.compareTo(Shrubbery.CRAWLING) + " "); + System.out.print( + s.equals(Shrubbery.CRAWLING) + " "); + System.out.println(s == Shrubbery.CRAWLING); + System.out.println(s.getDeclaringClass()); + System.out.println(s.name()); + System.out.println("********************"); + } + // Produce an enum value from a String name: + for(String s : + "HANGING CRAWLING GROUND".split(" ")) { + Shrubbery shrub = + Enum.valueOf(Shrubbery.class, s); + System.out.println(shrub); + } + } +} +/* Output: +GROUND ordinal: 0 +-1 false false +class Shrubbery +GROUND +******************** +CRAWLING ordinal: 1 +0 true true +class Shrubbery +CRAWLING +******************** +HANGING ordinal: 2 +1 false false +class Shrubbery +HANGING +******************** +HANGING +CRAWLING +GROUND +*/ diff --git a/code/enums/EnumMaps.java b/code/enums/EnumMaps.java new file mode 100644 index 00000000..f75c5cd4 --- /dev/null +++ b/code/enums/EnumMaps.java @@ -0,0 +1,37 @@ +// enums/EnumMaps.java +// (c)2020 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. +// Basics of EnumMaps +// {java enums.EnumMaps} +package enums; +import java.util.*; +import static enums.AlarmPoints.*; + +interface Command { void action(); } + +public class EnumMaps { + public static void main(String[] args) { + EnumMap em = + new EnumMap<>(AlarmPoints.class); + em.put(KITCHEN, + () -> System.out.println("Kitchen fire!")); + em.put(BATHROOM, + () -> System.out.println("Bathroom alert!")); + for(Map.Entry e: + em.entrySet()) { + System.out.print(e.getKey() + ": "); + e.getValue().action(); + } + try { // If there's no value for a particular key: + em.get(UTILITY).action(); + } catch(Exception e) { + System.out.println("Expected: " + e); + } + } +} +/* Output: +BATHROOM: Bathroom alert! +KITCHEN: Kitchen fire! +Expected: java.lang.NullPointerException +*/ diff --git a/code/enums/EnumSets.java b/code/enums/EnumSets.java new file mode 100644 index 00000000..0e749cad --- /dev/null +++ b/code/enums/EnumSets.java @@ -0,0 +1,39 @@ +// enums/EnumSets.java +// (c)2020 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. +// Operations on EnumSets +// {java enums.EnumSets} +package enums; +import java.util.*; +import static enums.AlarmPoints.*; + +public class EnumSets { + public static void main(String[] args) { + EnumSet points = + EnumSet.noneOf(AlarmPoints.class); // Empty + points.add(BATHROOM); + System.out.println(points); + points.addAll( + EnumSet.of(STAIR1, STAIR2, KITCHEN)); + System.out.println(points); + points = EnumSet.allOf(AlarmPoints.class); + points.removeAll( + EnumSet.of(STAIR1, STAIR2, KITCHEN)); + System.out.println(points); + points.removeAll( + EnumSet.range(OFFICE1, OFFICE4)); + System.out.println(points); + points = EnumSet.complementOf(points); + System.out.println(points); + } +} +/* Output: +[BATHROOM] +[STAIR1, STAIR2, BATHROOM, KITCHEN] +[LOBBY, OFFICE1, OFFICE2, OFFICE3, OFFICE4, BATHROOM, +UTILITY] +[LOBBY, BATHROOM, UTILITY] +[STAIR1, STAIR2, OFFICE1, OFFICE2, OFFICE3, OFFICE4, +KITCHEN] +*/ diff --git a/code/enums/Input.java b/code/enums/Input.java new file mode 100644 index 00000000..3dc0ec44 --- /dev/null +++ b/code/enums/Input.java @@ -0,0 +1,33 @@ +// enums/Input.java +// (c)2020 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. +import java.util.*; + +public enum Input { + NICKEL(5), DIME(10), QUARTER(25), DOLLAR(100), + TOOTHPASTE(200), CHIPS(75), SODA(100), SOAP(50), + ABORT_TRANSACTION { + @Override + public int amount() { // Disallow + throw new RuntimeException("ABORT.amount()"); + } + }, + STOP { // This must be the last instance. + @Override + public int amount() { // Disallow + throw new + RuntimeException("SHUT_DOWN.amount()"); + } + }; + int value; // In cents + Input(int value) { this.value = value; } + Input() {} + int amount() { return value; }; // In cents + static Random rand = new Random(47); + public static Input randomSelection() { + // Don't include STOP: + return + values()[rand.nextInt(values().length - 1)]; + } +} diff --git a/code/enums/NonEnum.java b/code/enums/NonEnum.java new file mode 100644 index 00000000..34440730 --- /dev/null +++ b/code/enums/NonEnum.java @@ -0,0 +1,19 @@ +// enums/NonEnum.java +// (c)2020 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. + +public class NonEnum { + public static void main(String[] args) { + Class intClass = Integer.class; + try { + for(Object en : intClass.getEnumConstants()) + System.out.println(en); + } catch(Exception e) { + System.out.println("Expected: " + e); + } + } +} +/* Output: +Expected: java.lang.NullPointerException +*/ diff --git a/code/enums/NotClasses.java b/code/enums/NotClasses.java new file mode 100644 index 00000000..681e807d --- /dev/null +++ b/code/enums/NotClasses.java @@ -0,0 +1,50 @@ +// enums/NotClasses.java +// (c)2020 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. +// {ExcludeFromGradle} +// javap -c LikeClasses + +enum LikeClasses { + WINKEN { + @Override + void behavior() { + System.out.println("Behavior1"); + } + }, + BLINKEN { + @Override + void behavior() { + System.out.println("Behavior2"); + } + }, + NOD { + @Override + void behavior() { + System.out.println("Behavior3"); + } + }; + abstract void behavior(); +} + +public class NotClasses { + // void f1(LikeClasses.WINKEN instance) {} // Nope +} +/* Output: (First 12 Lines) +Compiled from "NotClasses.java" +abstract class LikeClasses extends +java.lang.Enum { + public static final LikeClasses WINKEN; + + public static final LikeClasses BLINKEN; + + public static final LikeClasses NOD; + + public static LikeClasses[] values(); + Code: + 0: getstatic #2 // Field +$VALUES:[LLikeClasses; + 3: invokevirtual #3 // Method +"[LLikeClasses;".clone:()Ljava/lang/Object; + ... +*/ diff --git a/code/enums/Outcome.java b/code/enums/Outcome.java new file mode 100644 index 00000000..0e2a25d6 --- /dev/null +++ b/code/enums/Outcome.java @@ -0,0 +1,6 @@ +// enums/Outcome.java +// (c)2020 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 enums; +public enum Outcome { WIN, LOSE, DRAW } diff --git a/code/enums/OverrideConstantSpecific.java b/code/enums/OverrideConstantSpecific.java new file mode 100644 index 00000000..28e3343b --- /dev/null +++ b/code/enums/OverrideConstantSpecific.java @@ -0,0 +1,28 @@ +// enums/OverrideConstantSpecific.java +// (c)2020 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. + +public enum OverrideConstantSpecific { + NUT, BOLT, + WASHER { + @Override + void f() { + System.out.println("Overridden method"); + } + }; + void f() { + System.out.println("default behavior"); + } + public static void main(String[] args) { + for(OverrideConstantSpecific ocs : values()) { + System.out.print(ocs + ": "); + ocs.f(); + } + } +} +/* Output: +NUT: default behavior +BOLT: default behavior +WASHER: Overridden method +*/ diff --git a/code/enums/OzWitch.java b/code/enums/OzWitch.java new file mode 100644 index 00000000..c9eedb4f --- /dev/null +++ b/code/enums/OzWitch.java @@ -0,0 +1,32 @@ +// enums/OzWitch.java +// (c)2020 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. +// The witches in the land of Oz + +public enum OzWitch { + // Instances must be defined first, before methods: + WEST("Miss Gulch, aka the Wicked Witch of the West"), + NORTH("Glinda, the Good Witch of the North"), + EAST("Wicked Witch of the East, wearer of the Ruby " + + "Slippers, crushed by Dorothy's house"), + SOUTH("Good by inference, but missing"); + private String description; + // Constructor must be package or private access: + private OzWitch(String description) { + this.description = description; + } + public String getDescription() { return description; } + public static void main(String[] args) { + for(OzWitch witch : OzWitch.values()) + System.out.println( + witch + ": " + witch.getDescription()); + } +} +/* Output: +WEST: Miss Gulch, aka the Wicked Witch of the West +NORTH: Glinda, the Good Witch of the North +EAST: Wicked Witch of the East, wearer of the Ruby +Slippers, crushed by Dorothy's house +SOUTH: Good by inference, but missing +*/ diff --git a/code/enums/PostOffice.java b/code/enums/PostOffice.java new file mode 100644 index 00000000..05634820 --- /dev/null +++ b/code/enums/PostOffice.java @@ -0,0 +1,197 @@ +// enums/PostOffice.java +// (c)2020 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. +// Modeling a post office +import java.util.*; +import onjava.*; + +class Mail { + // The NO's reduce probability of random selection: + enum GeneralDelivery {YES,NO1,NO2,NO3,NO4,NO5} + enum Scannability {UNSCANNABLE,YES1,YES2,YES3,YES4} + enum Readability {ILLEGIBLE,YES1,YES2,YES3,YES4} + enum Address {INCORRECT,OK1,OK2,OK3,OK4,OK5,OK6} + enum ReturnAddress {MISSING,OK1,OK2,OK3,OK4,OK5} + GeneralDelivery generalDelivery; + Scannability scannability; + Readability readability; + Address address; + ReturnAddress returnAddress; + static long counter = 0; + long id = counter++; + @Override + public String toString() { return "Mail " + id; } + public String details() { + return toString() + + ", General Delivery: " + generalDelivery + + ", Address Scanability: " + scannability + + ", Address Readability: " + readability + + ", Address Address: " + address + + ", Return address: " + returnAddress; + } + // Generate test Mail: + public static Mail randomMail() { + Mail m = new Mail(); + m.generalDelivery = + Enums.random(GeneralDelivery.class); + m.scannability = + Enums.random(Scannability.class); + m.readability = + Enums.random(Readability.class); + m.address = Enums.random(Address.class); + m.returnAddress = + Enums.random(ReturnAddress.class); + return m; + } + public static + Iterable generator(final int count) { + return new Iterable() { + int n = count; + @Override + public Iterator iterator() { + return new Iterator() { + @Override + public boolean hasNext() { + return n-- > 0; + } + @Override + public Mail next() { + return randomMail(); + } + @Override + public void remove() { // Not implemented + throw new UnsupportedOperationException(); + } + }; + } + }; + } +} + +public class PostOffice { + enum MailHandler { + GENERAL_DELIVERY { + @Override + boolean handle(Mail m) { + switch(m.generalDelivery) { + case YES: + System.out.println( + "Using general delivery for " + m); + return true; + default: return false; + } + } + }, + MACHINE_SCAN { + @Override + boolean handle(Mail m) { + switch(m.scannability) { + case UNSCANNABLE: return false; + default: + switch(m.address) { + case INCORRECT: return false; + default: + System.out.println( + "Delivering "+ m + " automatically"); + return true; + } + } + } + }, + VISUAL_INSPECTION { + @Override + boolean handle(Mail m) { + switch(m.readability) { + case ILLEGIBLE: return false; + default: + switch(m.address) { + case INCORRECT: return false; + default: + System.out.println( + "Delivering " + m + " normally"); + return true; + } + } + } + }, + RETURN_TO_SENDER { + @Override + boolean handle(Mail m) { + switch(m.returnAddress) { + case MISSING: return false; + default: + System.out.println( + "Returning " + m + " to sender"); + return true; + } + } + }; + abstract boolean handle(Mail m); + } + static void handle(Mail m) { + for(MailHandler handler : MailHandler.values()) + if(handler.handle(m)) + return; + System.out.println(m + " is a dead letter"); + } + public static void main(String[] args) { + for(Mail mail : Mail.generator(10)) { + System.out.println(mail.details()); + handle(mail); + System.out.println("*****"); + } + } +} +/* Output: +Mail 0, General Delivery: NO2, Address Scanability: +UNSCANNABLE, Address Readability: YES3, Address +Address: OK1, Return address: OK1 +Delivering Mail 0 normally +***** +Mail 1, General Delivery: NO5, Address Scanability: +YES3, Address Readability: ILLEGIBLE, Address Address: +OK5, Return address: OK1 +Delivering Mail 1 automatically +***** +Mail 2, General Delivery: YES, Address Scanability: +YES3, Address Readability: YES1, Address Address: OK1, +Return address: OK5 +Using general delivery for Mail 2 +***** +Mail 3, General Delivery: NO4, Address Scanability: +YES3, Address Readability: YES1, Address Address: +INCORRECT, Return address: OK4 +Returning Mail 3 to sender +***** +Mail 4, General Delivery: NO4, Address Scanability: +UNSCANNABLE, Address Readability: YES1, Address +Address: INCORRECT, Return address: OK2 +Returning Mail 4 to sender +***** +Mail 5, General Delivery: NO3, Address Scanability: +YES1, Address Readability: ILLEGIBLE, Address Address: +OK4, Return address: OK2 +Delivering Mail 5 automatically +***** +Mail 6, General Delivery: YES, Address Scanability: +YES4, Address Readability: ILLEGIBLE, Address Address: +OK4, Return address: OK4 +Using general delivery for Mail 6 +***** +Mail 7, General Delivery: YES, Address Scanability: +YES3, Address Readability: YES4, Address Address: OK2, +Return address: MISSING +Using general delivery for Mail 7 +***** +Mail 8, General Delivery: NO3, Address Scanability: +YES1, Address Readability: YES3, Address Address: +INCORRECT, Return address: MISSING +Mail 8 is a dead letter +***** +Mail 9, General Delivery: NO1, Address Scanability: +UNSCANNABLE, Address Readability: YES2, Address +Address: OK1, Return address: OK4 +Delivering Mail 9 normally +***** +*/ diff --git a/code/enums/RandomTest.java b/code/enums/RandomTest.java new file mode 100644 index 00000000..92f2e481 --- /dev/null +++ b/code/enums/RandomTest.java @@ -0,0 +1,21 @@ +// enums/RandomTest.java +// (c)2020 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. +import onjava.*; + +enum Activity { SITTING, LYING, STANDING, HOPPING, + RUNNING, DODGING, JUMPING, FALLING, FLYING } + +public class RandomTest { + public static void main(String[] args) { + for(int i = 0; i < 20; i++) + System.out.print( + Enums.random(Activity.class) + " "); + } +} +/* Output: +STANDING FLYING RUNNING STANDING RUNNING STANDING LYING +DODGING SITTING RUNNING HOPPING HOPPING HOPPING RUNNING +STANDING LYING FALLING RUNNING FLYING LYING +*/ diff --git a/code/enums/Reflection.java b/code/enums/Reflection.java new file mode 100644 index 00000000..822a134e --- /dev/null +++ b/code/enums/Reflection.java @@ -0,0 +1,71 @@ +// enums/Reflection.java +// (c)2020 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. +// Analyzing enums using reflection +import java.lang.reflect.*; +import java.util.*; +import onjava.*; + +enum Explore { HERE, THERE } + +public class Reflection { + public static + Set analyze(Class enumClass) { + System.out.println( + "_____ Analyzing " + enumClass + " _____"); + System.out.println("Interfaces:"); + for(Type t : enumClass.getGenericInterfaces()) + System.out.println(t); + System.out.println( + "Base: " + enumClass.getSuperclass()); + System.out.println("Methods: "); + Set methods = new TreeSet<>(); + for(Method m : enumClass.getMethods()) + methods.add(m.getName()); + System.out.println(methods); + return methods; + } + public static void main(String[] args) { + Set exploreMethods = + analyze(Explore.class); + Set enumMethods = analyze(Enum.class); + System.out.println( + "Explore.containsAll(Enum)? " + + exploreMethods.containsAll(enumMethods)); + System.out.print("Explore.removeAll(Enum): "); + exploreMethods.removeAll(enumMethods); + System.out.println(exploreMethods); + // Decompile the code for the enum: + OSExecute.command( + "javap -cp build/classes/java/main Explore"); + } +} +/* Output: +_____ Analyzing class Explore _____ +Interfaces: +Base: class java.lang.Enum +Methods: +[compareTo, equals, getClass, getDeclaringClass, +hashCode, name, notify, notifyAll, ordinal, toString, +valueOf, values, wait] +_____ Analyzing class java.lang.Enum _____ +Interfaces: +java.lang.Comparable +interface java.io.Serializable +Base: class java.lang.Object +Methods: +[compareTo, equals, getClass, getDeclaringClass, +hashCode, name, notify, notifyAll, ordinal, toString, +valueOf, wait] +Explore.containsAll(Enum)? true +Explore.removeAll(Enum): [values] +Compiled from "Reflection.java" +final class Explore extends java.lang.Enum { + public static final Explore HERE; + public static final Explore THERE; + public static Explore[] values(); + public static Explore valueOf(java.lang.String); + static {}; +} +*/ diff --git a/code/enums/RoShamBo.java b/code/enums/RoShamBo.java new file mode 100644 index 00000000..76b3d76f --- /dev/null +++ b/code/enums/RoShamBo.java @@ -0,0 +1,21 @@ +// enums/RoShamBo.java +// (c)2020 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. +// Common tools for RoShamBo examples +package enums; +import onjava.*; + +public class RoShamBo { + public static > + void match(T a, T b) { + System.out.println( + a + " vs. " + b + ": " + a.compete(b)); + } + public static & Competitor> + void play(Class rsbClass, int size) { + for(int i = 0; i < size; i++) + match( + Enums.random(rsbClass),Enums.random(rsbClass)); + } +} diff --git a/code/enums/RoShamBo1.java b/code/enums/RoShamBo1.java new file mode 100644 index 00000000..abf52c9c --- /dev/null +++ b/code/enums/RoShamBo1.java @@ -0,0 +1,104 @@ +// enums/RoShamBo1.java +// (c)2020 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. +// Demonstration of multiple dispatching +// {java enums.RoShamBo1} +package enums; +import java.util.*; +import static enums.Outcome.*; + +interface Item { + Outcome compete(Item it); + Outcome eval(Paper p); + Outcome eval(Scissors s); + Outcome eval(Rock r); +} + +class Paper implements Item { + @Override + public Outcome compete(Item it) { + return it.eval(this); + } + @Override + public Outcome eval(Paper p) { return DRAW; } + @Override + public Outcome eval(Scissors s) { return WIN; } + @Override + public Outcome eval(Rock r) { return LOSE; } + @Override + public String toString() { return "Paper"; } +} + +class Scissors implements Item { + @Override + public Outcome compete(Item it) { + return it.eval(this); + } + @Override + public Outcome eval(Paper p) { return LOSE; } + @Override + public Outcome eval(Scissors s) { return DRAW; } + @Override + public Outcome eval(Rock r) { return WIN; } + @Override + public String toString() { return "Scissors"; } +} + +class Rock implements Item { + @Override + public Outcome compete(Item it) { + return it.eval(this); + } + @Override + public Outcome eval(Paper p) { return WIN; } + @Override + public Outcome eval(Scissors s) { return LOSE; } + @Override + public Outcome eval(Rock r) { return DRAW; } + @Override + public String toString() { return "Rock"; } +} + +public class RoShamBo1 { + static final int SIZE = 20; + private static Random rand = new Random(47); + public static Item newItem() { + switch(rand.nextInt(3)) { + default: + case 0: return new Scissors(); + case 1: return new Paper(); + case 2: return new Rock(); + } + } + public static void match(Item a, Item b) { + System.out.println( + a + " vs. " + b + ": " + a.compete(b)); + } + public static void main(String[] args) { + for(int i = 0; i < SIZE; i++) + match(newItem(), newItem()); + } +} +/* Output: +Rock vs. Rock: DRAW +Paper vs. Rock: WIN +Paper vs. Rock: WIN +Paper vs. Rock: WIN +Scissors vs. Paper: WIN +Scissors vs. Scissors: DRAW +Scissors vs. Paper: WIN +Rock vs. Paper: LOSE +Paper vs. Paper: DRAW +Rock vs. Paper: LOSE +Paper vs. Scissors: LOSE +Paper vs. Scissors: LOSE +Rock vs. Scissors: WIN +Rock vs. Paper: LOSE +Paper vs. Rock: WIN +Scissors vs. Paper: WIN +Paper vs. Scissors: LOSE +Paper vs. Scissors: LOSE +Paper vs. Scissors: LOSE +Paper vs. Scissors: LOSE +*/ diff --git a/code/enums/RoShamBo2.java b/code/enums/RoShamBo2.java new file mode 100644 index 00000000..ec8ab25b --- /dev/null +++ b/code/enums/RoShamBo2.java @@ -0,0 +1,55 @@ +// enums/RoShamBo2.java +// (c)2020 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. +// Switching one enum on another +// {java enums.RoShamBo2} +package enums; +import static enums.Outcome.*; + +public enum RoShamBo2 implements Competitor { + PAPER(DRAW, LOSE, WIN), + SCISSORS(WIN, DRAW, LOSE), + ROCK(LOSE, WIN, DRAW); + private Outcome vPAPER, vSCISSORS, vROCK; + RoShamBo2(Outcome paper, + Outcome scissors, Outcome rock) { + this.vPAPER = paper; + this.vSCISSORS = scissors; + this.vROCK = rock; + } + @Override + public Outcome compete(RoShamBo2 it) { + switch(it) { + default: + case PAPER: return vPAPER; + case SCISSORS: return vSCISSORS; + case ROCK: return vROCK; + } + } + public static void main(String[] args) { + RoShamBo.play(RoShamBo2.class, 20); + } +} +/* Output: +ROCK vs. ROCK: DRAW +SCISSORS vs. ROCK: LOSE +SCISSORS vs. ROCK: LOSE +SCISSORS vs. ROCK: LOSE +PAPER vs. SCISSORS: LOSE +PAPER vs. PAPER: DRAW +PAPER vs. SCISSORS: LOSE +ROCK vs. SCISSORS: WIN +SCISSORS vs. SCISSORS: DRAW +ROCK vs. SCISSORS: WIN +SCISSORS vs. PAPER: WIN +SCISSORS vs. PAPER: WIN +ROCK vs. PAPER: LOSE +ROCK vs. SCISSORS: WIN +SCISSORS vs. ROCK: LOSE +PAPER vs. SCISSORS: LOSE +SCISSORS vs. PAPER: WIN +SCISSORS vs. PAPER: WIN +SCISSORS vs. PAPER: WIN +SCISSORS vs. PAPER: WIN +*/ diff --git a/code/enums/RoShamBo3.java b/code/enums/RoShamBo3.java new file mode 100644 index 00000000..ffcd2cf1 --- /dev/null +++ b/code/enums/RoShamBo3.java @@ -0,0 +1,71 @@ +// enums/RoShamBo3.java +// (c)2020 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. +// Using constant-specific methods +// {java enums.RoShamBo3} +package enums; +import static enums.Outcome.*; + +public enum RoShamBo3 implements Competitor { + PAPER { + @Override + public Outcome compete(RoShamBo3 it) { + switch(it) { + default: // To placate the compiler + case PAPER: return DRAW; + case SCISSORS: return LOSE; + case ROCK: return WIN; + } + } + }, + SCISSORS { + @Override + public Outcome compete(RoShamBo3 it) { + switch(it) { + default: + case PAPER: return WIN; + case SCISSORS: return DRAW; + case ROCK: return LOSE; + } + } + }, + ROCK { + @Override + public Outcome compete(RoShamBo3 it) { + switch(it) { + default: + case PAPER: return LOSE; + case SCISSORS: return WIN; + case ROCK: return DRAW; + } + } + }; + @Override + public abstract Outcome compete(RoShamBo3 it); + public static void main(String[] args) { + RoShamBo.play(RoShamBo3.class, 20); + } +} +/* Output: +ROCK vs. ROCK: DRAW +SCISSORS vs. ROCK: LOSE +SCISSORS vs. ROCK: LOSE +SCISSORS vs. ROCK: LOSE +PAPER vs. SCISSORS: LOSE +PAPER vs. PAPER: DRAW +PAPER vs. SCISSORS: LOSE +ROCK vs. SCISSORS: WIN +SCISSORS vs. SCISSORS: DRAW +ROCK vs. SCISSORS: WIN +SCISSORS vs. PAPER: WIN +SCISSORS vs. PAPER: WIN +ROCK vs. PAPER: LOSE +ROCK vs. SCISSORS: WIN +SCISSORS vs. ROCK: LOSE +PAPER vs. SCISSORS: LOSE +SCISSORS vs. PAPER: WIN +SCISSORS vs. PAPER: WIN +SCISSORS vs. PAPER: WIN +SCISSORS vs. PAPER: WIN +*/ diff --git a/code/enums/RoShamBo4.java b/code/enums/RoShamBo4.java new file mode 100644 index 00000000..f0b473ae --- /dev/null +++ b/code/enums/RoShamBo4.java @@ -0,0 +1,57 @@ +// enums/RoShamBo4.java +// (c)2020 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. +// {java enums.RoShamBo4} +package enums; + +public enum RoShamBo4 implements Competitor { + ROCK { + @Override + public Outcome compete(RoShamBo4 opponent) { + return compete(SCISSORS, opponent); + } + }, + SCISSORS { + @Override + public Outcome compete(RoShamBo4 opponent) { + return compete(PAPER, opponent); + } + }, + PAPER { + @Override + public Outcome compete(RoShamBo4 opponent) { + return compete(ROCK, opponent); + } + }; + Outcome compete(RoShamBo4 loser, RoShamBo4 opponent) { + return ((opponent == this) ? Outcome.DRAW + : ((opponent == loser) ? Outcome.WIN + : Outcome.LOSE)); + } + public static void main(String[] args) { + RoShamBo.play(RoShamBo4.class, 20); + } +} +/* Output: +PAPER vs. PAPER: DRAW +SCISSORS vs. PAPER: WIN +SCISSORS vs. PAPER: WIN +SCISSORS vs. PAPER: WIN +ROCK vs. SCISSORS: WIN +ROCK vs. ROCK: DRAW +ROCK vs. SCISSORS: WIN +PAPER vs. SCISSORS: LOSE +SCISSORS vs. SCISSORS: DRAW +PAPER vs. SCISSORS: LOSE +SCISSORS vs. ROCK: LOSE +SCISSORS vs. ROCK: LOSE +PAPER vs. ROCK: WIN +PAPER vs. SCISSORS: LOSE +SCISSORS vs. PAPER: WIN +ROCK vs. SCISSORS: WIN +SCISSORS vs. ROCK: LOSE +SCISSORS vs. ROCK: LOSE +SCISSORS vs. ROCK: LOSE +SCISSORS vs. ROCK: LOSE +*/ diff --git a/code/enums/RoShamBo5.java b/code/enums/RoShamBo5.java new file mode 100644 index 00000000..69885c01 --- /dev/null +++ b/code/enums/RoShamBo5.java @@ -0,0 +1,59 @@ +// enums/RoShamBo5.java +// (c)2020 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. +// Multiple dispatching using an EnumMap of EnumMaps +// {java enums.RoShamBo5} +package enums; +import java.util.*; +import static enums.Outcome.*; + +enum RoShamBo5 implements Competitor { + PAPER, SCISSORS, ROCK; + static EnumMap> + table = new EnumMap<>(RoShamBo5.class); + static { + for(RoShamBo5 it : RoShamBo5.values()) + table.put(it, new EnumMap<>(RoShamBo5.class)); + initRow(PAPER, DRAW, LOSE, WIN); + initRow(SCISSORS, WIN, DRAW, LOSE); + initRow(ROCK, LOSE, WIN, DRAW); + } + static void initRow(RoShamBo5 it, + Outcome vPAPER, Outcome vSCISSORS, Outcome vROCK) { + EnumMap row = + RoShamBo5.table.get(it); + row.put(RoShamBo5.PAPER, vPAPER); + row.put(RoShamBo5.SCISSORS, vSCISSORS); + row.put(RoShamBo5.ROCK, vROCK); + } + @Override + public Outcome compete(RoShamBo5 it) { + return table.get(this).get(it); + } + public static void main(String[] args) { + RoShamBo.play(RoShamBo5.class, 20); + } +} +/* Output: +ROCK vs. ROCK: DRAW +SCISSORS vs. ROCK: LOSE +SCISSORS vs. ROCK: LOSE +SCISSORS vs. ROCK: LOSE +PAPER vs. SCISSORS: LOSE +PAPER vs. PAPER: DRAW +PAPER vs. SCISSORS: LOSE +ROCK vs. SCISSORS: WIN +SCISSORS vs. SCISSORS: DRAW +ROCK vs. SCISSORS: WIN +SCISSORS vs. PAPER: WIN +SCISSORS vs. PAPER: WIN +ROCK vs. PAPER: LOSE +ROCK vs. SCISSORS: WIN +SCISSORS vs. ROCK: LOSE +PAPER vs. SCISSORS: LOSE +SCISSORS vs. PAPER: WIN +SCISSORS vs. PAPER: WIN +SCISSORS vs. PAPER: WIN +SCISSORS vs. PAPER: WIN +*/ diff --git a/code/enums/RoShamBo6.java b/code/enums/RoShamBo6.java new file mode 100644 index 00000000..164911d5 --- /dev/null +++ b/code/enums/RoShamBo6.java @@ -0,0 +1,46 @@ +// enums/RoShamBo6.java +// (c)2020 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. +// Enums using "tables" instead of multiple dispatch +// {java enums.RoShamBo6} +package enums; +import static enums.Outcome.*; + +enum RoShamBo6 implements Competitor { + PAPER, SCISSORS, ROCK; + private static Outcome[][] table = { + { DRAW, LOSE, WIN }, // PAPER + { WIN, DRAW, LOSE }, // SCISSORS + { LOSE, WIN, DRAW }, // ROCK + }; + @Override + public Outcome compete(RoShamBo6 other) { + return table[this.ordinal()][other.ordinal()]; + } + public static void main(String[] args) { + RoShamBo.play(RoShamBo6.class, 20); + } +} +/* Output: +ROCK vs. ROCK: DRAW +SCISSORS vs. ROCK: LOSE +SCISSORS vs. ROCK: LOSE +SCISSORS vs. ROCK: LOSE +PAPER vs. SCISSORS: LOSE +PAPER vs. PAPER: DRAW +PAPER vs. SCISSORS: LOSE +ROCK vs. SCISSORS: WIN +SCISSORS vs. SCISSORS: DRAW +ROCK vs. SCISSORS: WIN +SCISSORS vs. PAPER: WIN +SCISSORS vs. PAPER: WIN +ROCK vs. PAPER: LOSE +ROCK vs. SCISSORS: WIN +SCISSORS vs. ROCK: LOSE +PAPER vs. SCISSORS: LOSE +SCISSORS vs. PAPER: WIN +SCISSORS vs. PAPER: WIN +SCISSORS vs. PAPER: WIN +SCISSORS vs. PAPER: WIN +*/ diff --git a/code/enums/SecurityCategory.java b/code/enums/SecurityCategory.java new file mode 100644 index 00000000..884cb56a --- /dev/null +++ b/code/enums/SecurityCategory.java @@ -0,0 +1,46 @@ +// enums/SecurityCategory.java +// (c)2020 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. +// More succinct subcategorization of enums +import onjava.*; + +enum SecurityCategory { + STOCK(Security.Stock.class), + BOND(Security.Bond.class); + Security[] values; + SecurityCategory(Class kind) { + values = kind.getEnumConstants(); + } + interface Security { + enum Stock implements Security { + SHORT, LONG, MARGIN + } + enum Bond implements Security { + MUNICIPAL, JUNK + } + } + public Security randomSelection() { + return Enums.random(values); + } + public static void main(String[] args) { + for(int i = 0; i < 10; i++) { + SecurityCategory category = + Enums.random(SecurityCategory.class); + System.out.println(category + ": " + + category.randomSelection()); + } + } +} +/* Output: +BOND: MUNICIPAL +BOND: MUNICIPAL +STOCK: MARGIN +STOCK: MARGIN +BOND: JUNK +STOCK: SHORT +STOCK: LONG +STOCK: LONG +BOND: MUNICIPAL +BOND: JUNK +*/ diff --git a/code/enums/SpaceShip.java b/code/enums/SpaceShip.java new file mode 100644 index 00000000..3623389e --- /dev/null +++ b/code/enums/SpaceShip.java @@ -0,0 +1,28 @@ +// enums/SpaceShip.java +// (c)2020 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. +import java.util.stream.*; + +public enum SpaceShip { + SCOUT, CARGO, TRANSPORT, + CRUISER, BATTLESHIP, MOTHERSHIP; + @Override + public String toString() { + String id = name(); + String lower = id.substring(1).toLowerCase(); + return id.charAt(0) + lower; + } + public static void main(String[] args) { + Stream.of(values()) + .forEach(System.out::println); + } +} +/* Output: +Scout +Cargo +Transport +Cruiser +Battleship +Mothership +*/ diff --git a/code/enums/SpicinessEnum.java b/code/enums/SpicinessEnum.java new file mode 100644 index 00000000..eef6f89a --- /dev/null +++ b/code/enums/SpicinessEnum.java @@ -0,0 +1,9 @@ +// enums/SpicinessEnum.java +// (c)2020 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 enums; + +public enum SpicinessEnum { + NOT, MILD, MEDIUM, HOT, FLAMING +} diff --git a/code/enums/TrafficLight.java b/code/enums/TrafficLight.java new file mode 100644 index 00000000..b018e02c --- /dev/null +++ b/code/enums/TrafficLight.java @@ -0,0 +1,44 @@ +// enums/TrafficLight.java +// (c)2020 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. +// Enums in switch statements + +// Define an enum type: +enum Signal { GREEN, YELLOW, RED, } + +public class TrafficLight { + Signal color = Signal.RED; + public void change() { + switch(color) { + // Note you don't have to say Signal.RED + // in the case statement: + case RED: color = Signal.GREEN; + break; + case GREEN: color = Signal.YELLOW; + break; + case YELLOW: color = Signal.RED; + break; + } + } + @Override + public String toString() { + return "The traffic light is " + color; + } + public static void main(String[] args) { + TrafficLight t = new TrafficLight(); + for(int i = 0; i < 7; i++) { + System.out.println(t); + t.change(); + } + } +} +/* Output: +The traffic light is RED +The traffic light is GREEN +The traffic light is YELLOW +The traffic light is RED +The traffic light is GREEN +The traffic light is YELLOW +The traffic light is RED +*/ diff --git a/code/enums/UpcastEnum.java b/code/enums/UpcastEnum.java new file mode 100644 index 00000000..a5df2a86 --- /dev/null +++ b/code/enums/UpcastEnum.java @@ -0,0 +1,21 @@ +// enums/UpcastEnum.java +// (c)2020 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. +// No values() method if you upcast an enum + +enum Search { HITHER, YON } + +public class UpcastEnum { + public static void main(String[] args) { + Search[] vals = Search.values(); + Enum e = Search.HITHER; // Upcast + // e.values(); // No values() in Enum + for(Enum en : e.getClass().getEnumConstants()) + System.out.println(en); + } +} +/* Output: +HITHER +YON +*/ diff --git a/code/enums/VendingMachine.java b/code/enums/VendingMachine.java new file mode 100644 index 00000000..bc7d7c19 --- /dev/null +++ b/code/enums/VendingMachine.java @@ -0,0 +1,183 @@ +// enums/VendingMachine.java +// (c)2020 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. +// {java VendingMachine VendingMachineInput.txt} +import java.util.*; +import java.io.IOException; +import java.util.function.*; +import java.nio.file.*; +import java.util.stream.*; + +enum Category { + MONEY(Input.NICKEL, Input.DIME, + Input.QUARTER, Input.DOLLAR), + ITEM_SELECTION(Input.TOOTHPASTE, Input.CHIPS, + Input.SODA, Input.SOAP), + QUIT_TRANSACTION(Input.ABORT_TRANSACTION), + SHUT_DOWN(Input.STOP); + private Input[] values; + Category(Input... types) { values = types; } + private static EnumMap categories = + new EnumMap<>(Input.class); + static { + for(Category c : Category.class.getEnumConstants()) + for(Input type : c.values) + categories.put(type, c); + } + public static Category categorize(Input input) { + return categories.get(input); + } +} + +public class VendingMachine { + private static State state = State.RESTING; + private static int amount = 0; + private static Input selection = null; + enum StateDuration { TRANSIENT } // Tagging enum + enum State { + RESTING { + @Override + void next(Input input) { + switch(Category.categorize(input)) { + case MONEY: + amount += input.amount(); + state = ADDING_MONEY; + break; + case SHUT_DOWN: + state = TERMINAL; + default: + } + } + }, + ADDING_MONEY { + @Override + void next(Input input) { + switch(Category.categorize(input)) { + case MONEY: + amount += input.amount(); + break; + case ITEM_SELECTION: + selection = input; + if(amount < selection.amount()) + System.out.println( + "Insufficient money for " + selection); + else state = DISPENSING; + break; + case QUIT_TRANSACTION: + state = GIVING_CHANGE; + break; + case SHUT_DOWN: + state = TERMINAL; + default: + } + } + }, + DISPENSING(StateDuration.TRANSIENT) { + @Override + void next() { + System.out.println("here is your " + selection); + amount -= selection.amount(); + state = GIVING_CHANGE; + } + }, + GIVING_CHANGE(StateDuration.TRANSIENT) { + @Override + void next() { + if(amount > 0) { + System.out.println("Your change: " + amount); + amount = 0; + } + state = RESTING; + } + }, + TERMINAL {@Override + void output() { System.out.println("Halted"); } }; + private boolean isTransient = false; + State() {} + State(StateDuration trans) { isTransient = true; } + void next(Input input) { + throw new RuntimeException("Only call " + + "next(Input input) for non-transient states"); + } + void next() { + throw new RuntimeException( + "Only call next() for " + + "StateDuration.TRANSIENT states"); + } + void output() { System.out.println(amount); } + } + static void run(Supplier gen) { + while(state != State.TERMINAL) { + state.next(gen.get()); + while(state.isTransient) + state.next(); + state.output(); + } + } + public static void main(String[] args) { + Supplier gen = new RandomInputSupplier(); + if(args.length == 1) + gen = new FileInputSupplier(args[0]); + run(gen); + } +} + +// For a basic sanity check: +class RandomInputSupplier implements Supplier { + @Override + public Input get() { + return Input.randomSelection(); + } +} + +// Create Inputs from a file of ';'-separated strings: +class FileInputSupplier implements Supplier { + private Iterator input; + FileInputSupplier(String fileName) { + try { + input = Files.lines(Paths.get(fileName)) + .skip(1) // Skip the comment line + .flatMap(s -> Arrays.stream(s.split(";"))) + .map(String::trim) + .collect(Collectors.toList()) + .iterator(); + } catch(IOException e) { + throw new RuntimeException(e); + } + } + @Override + public Input get() { + if(!input.hasNext()) + return null; + return Enum.valueOf( + Input.class, input.next().trim()); + } +} +/* Output: +25 +50 +75 +here is your CHIPS +0 +100 +200 +here is your TOOTHPASTE +0 +25 +35 +Your change: 35 +0 +25 +35 +Insufficient money for SODA +35 +60 +70 +75 +Insufficient money for SODA +75 +Your change: 75 +0 +Halted +*/ diff --git a/code/enums/VendingMachineInput.txt b/code/enums/VendingMachineInput.txt new file mode 100644 index 00000000..b39554f0 --- /dev/null +++ b/code/enums/VendingMachineInput.txt @@ -0,0 +1,8 @@ +// enums/VendingMachineInput.txt +QUARTER; QUARTER; QUARTER; CHIPS; +DOLLAR; DOLLAR; TOOTHPASTE; +QUARTER; DIME; ABORT_TRANSACTION; +QUARTER; DIME; SODA; +QUARTER; DIME; NICKEL; SODA; +ABORT_TRANSACTION; +STOP; diff --git a/code/enums/cartoons/EnumImplementation.java b/code/enums/cartoons/EnumImplementation.java new file mode 100644 index 00000000..58902e3f --- /dev/null +++ b/code/enums/cartoons/EnumImplementation.java @@ -0,0 +1,37 @@ +// enums/cartoons/EnumImplementation.java +// (c)2020 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. +// An enum can implement an interface +// {java enums.cartoons.EnumImplementation} +package enums.cartoons; +import java.util.*; +import java.util.function.*; + +enum CartoonCharacter +implements Supplier { + SLAPPY, SPANKY, PUNCHY, + SILLY, BOUNCY, NUTTY, BOB; + private Random rand = + new Random(47); + @Override + public CartoonCharacter get() { + return values()[rand.nextInt(values().length)]; + } +} + +public class EnumImplementation { + public static void printNext(Supplier rg) { + System.out.print(rg.get() + ", "); + } + public static void main(String[] args) { + // Choose any instance: + CartoonCharacter cc = CartoonCharacter.BOB; + for(int i = 0; i < 10; i++) + printNext(cc); + } +} +/* Output: +BOB, PUNCHY, BOB, SPANKY, NUTTY, PUNCHY, SLAPPY, NUTTY, +NUTTY, SLAPPY, +*/ diff --git a/code/enums/menu/Course.java b/code/enums/menu/Course.java new file mode 100644 index 00000000..96481f1e --- /dev/null +++ b/code/enums/menu/Course.java @@ -0,0 +1,20 @@ +// enums/menu/Course.java +// (c)2020 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 enums.menu; +import onjava.*; + +public enum Course { + APPETIZER(Food.Appetizer.class), + MAINCOURSE(Food.MainCourse.class), + DESSERT(Food.Dessert.class), + COFFEE(Food.Coffee.class); + private Food[] values; + private Course(Class kind) { + values = kind.getEnumConstants(); + } + public Food randomSelection() { + return Enums.random(values); + } +} diff --git a/code/enums/menu/Food.java b/code/enums/menu/Food.java new file mode 100644 index 00000000..4b97f69e --- /dev/null +++ b/code/enums/menu/Food.java @@ -0,0 +1,24 @@ +// enums/menu/Food.java +// (c)2020 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. +// Subcategorization of enums within interfaces +package enums.menu; + +public interface Food { + enum Appetizer implements Food { + SALAD, SOUP, SPRING_ROLLS; + } + enum MainCourse implements Food { + LASAGNE, BURRITO, PAD_THAI, + LENTILS, HUMMOUS, VINDALOO; + } + enum Dessert implements Food { + TIRAMISU, GELATO, BLACK_FOREST_CAKE, + FRUIT, CREME_CARAMEL; + } + enum Coffee implements Food { + BLACK_COFFEE, DECAF_COFFEE, ESPRESSO, + LATTE, CAPPUCCINO, TEA, HERB_TEA; + } +} diff --git a/code/enums/menu/Meal.java b/code/enums/menu/Meal.java new file mode 100644 index 00000000..64bc496d --- /dev/null +++ b/code/enums/menu/Meal.java @@ -0,0 +1,45 @@ +// enums/menu/Meal.java +// (c)2020 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. +// {java enums.menu.Meal} +package enums.menu; + +public class Meal { + public static void main(String[] args) { + for(int i = 0; i < 5; i++) { + for(Course course : Course.values()) { + Food food = course.randomSelection(); + System.out.println(food); + } + System.out.println("***"); + } + } +} +/* Output: +SPRING_ROLLS +VINDALOO +FRUIT +DECAF_COFFEE +*** +SOUP +VINDALOO +FRUIT +TEA +*** +SALAD +BURRITO +FRUIT +TEA +*** +SALAD +BURRITO +CREME_CARAMEL +LATTE +*** +SOUP +BURRITO +TIRAMISU +ESPRESSO +*** +*/ diff --git a/code/enums/menu/Meal2.java b/code/enums/menu/Meal2.java new file mode 100644 index 00000000..df1b90a5 --- /dev/null +++ b/code/enums/menu/Meal2.java @@ -0,0 +1,74 @@ +// enums/menu/Meal2.java +// (c)2020 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. +// {java enums.menu.Meal2} +package enums.menu; +import onjava.*; + +public enum Meal2 { + APPETIZER(Food.Appetizer.class), + MAINCOURSE(Food.MainCourse.class), + DESSERT(Food.Dessert.class), + COFFEE(Food.Coffee.class); + private Food[] values; + private Meal2(Class kind) { + values = kind.getEnumConstants(); + } + public interface Food { + enum Appetizer implements Food { + SALAD, SOUP, SPRING_ROLLS; + } + enum MainCourse implements Food { + LASAGNE, BURRITO, PAD_THAI, + LENTILS, HUMMOUS, VINDALOO; + } + enum Dessert implements Food { + TIRAMISU, GELATO, BLACK_FOREST_CAKE, + FRUIT, CREME_CARAMEL; + } + enum Coffee implements Food { + BLACK_COFFEE, DECAF_COFFEE, ESPRESSO, + LATTE, CAPPUCCINO, TEA, HERB_TEA; + } + } + public Food randomSelection() { + return Enums.random(values); + } + public static void main(String[] args) { + for(int i = 0; i < 5; i++) { + for(Meal2 meal : Meal2.values()) { + Food food = meal.randomSelection(); + System.out.println(food); + } + System.out.println("***"); + } + } +} +/* Output: +SPRING_ROLLS +VINDALOO +FRUIT +DECAF_COFFEE +*** +SOUP +VINDALOO +FRUIT +TEA +*** +SALAD +BURRITO +FRUIT +TEA +*** +SALAD +BURRITO +CREME_CARAMEL +LATTE +*** +SOUP +BURRITO +TIRAMISU +ESPRESSO +*** +*/ diff --git a/code/enums/menu/TypeOfFood.java b/code/enums/menu/TypeOfFood.java new file mode 100644 index 00000000..5e59e78b --- /dev/null +++ b/code/enums/menu/TypeOfFood.java @@ -0,0 +1,16 @@ +// enums/menu/TypeOfFood.java +// (c)2020 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. +// {java enums.menu.TypeOfFood} +package enums.menu; +import static enums.menu.Food.*; + +public class TypeOfFood { + public static void main(String[] args) { + Food food = Appetizer.SALAD; + food = MainCourse.LASAGNE; + food = Dessert.GELATO; + food = Coffee.CAPPUCCINO; + } +} diff --git a/code/equalshashcode/ComposedEquality.java b/code/equalshashcode/ComposedEquality.java new file mode 100644 index 00000000..c224231c --- /dev/null +++ b/code/equalshashcode/ComposedEquality.java @@ -0,0 +1,66 @@ +// equalshashcode/ComposedEquality.java +// (c)2020 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. +import java.util.*; + +class Part { + String ss; + double dd; + Part(String ss, double dd) { + this.ss = ss; + this.dd = dd; + } + @Override + public boolean equals(Object rval) { + return rval instanceof Part && + Objects.equals(ss, ((Part)rval).ss) && + Objects.equals(dd, ((Part)rval).dd); + } +} + +public class ComposedEquality extends SuccinctEquality { + Part part; + public ComposedEquality(int i, String s, double d) { + super(i, s, d); + part = new Part(s, d); + System.out.println("made 'ComposedEquality'"); + } + @Override + public boolean equals(Object rval) { + return rval instanceof ComposedEquality && + super.equals(rval) && + Objects.equals(part, + ((ComposedEquality)rval).part); + } + public static void main(String[] args) { + Equality.testAll( (i, s, d) -> + new ComposedEquality(i, s, d)); + } +} +/* Output: +made 'Equality' +made 'SuccinctEquality' +made 'ComposedEquality' +made 'Equality' +made 'SuccinctEquality' +made 'ComposedEquality' +made 'Equality' +made 'SuccinctEquality' +made 'ComposedEquality' +-- Testing null -- +null instanceof Equality: false +Expected false, got false +-- Testing same object -- +same object instanceof Equality: true +Expected true, got true +-- Testing different type -- +different type instanceof Equality: false +Expected false, got false +-- Testing same values -- +same values instanceof Equality: true +Expected true, got true +-- Testing different values -- +different values instanceof Equality: true +Expected false, got false +*/ diff --git a/code/equalshashcode/CountedString.java b/code/equalshashcode/CountedString.java new file mode 100644 index 00000000..5a6ec5fa --- /dev/null +++ b/code/equalshashcode/CountedString.java @@ -0,0 +1,72 @@ +// equalshashcode/CountedString.java +// (c)2020 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. +// Creating a good hashCode() +import java.util.*; + +public class CountedString { + private static List created = + new ArrayList<>(); + private String s; + private int id = 0; + public CountedString(String str) { + s = str; + created.add(s); + // id is the total number of instances + // of this String used by CountedString: + for(String s2 : created) + if(s2.equals(s)) + id++; + } + @Override + public String toString() { + return "String: " + s + " id: " + id + + " hashCode(): " + hashCode(); + } + @Override + public int hashCode() { + // The very simple approach: + // return s.hashCode() * id; + // Using Joshua Bloch's recipe: + int result = 17; + result = 37 * result + s.hashCode(); + result = 37 * result + id; + return result; + } + @Override + public boolean equals(Object o) { + return o instanceof CountedString && + Objects.equals(s, ((CountedString)o).s) && + Objects.equals(id, ((CountedString)o).id); + } + public static void main(String[] args) { + Map map = new HashMap<>(); + CountedString[] cs = new CountedString[5]; + for(int i = 0; i < cs.length; i++) { + cs[i] = new CountedString("hi"); + map.put(cs[i], i); // Autobox int to Integer + } + System.out.println(map); + for(CountedString cstring : cs) { + System.out.println("Looking up " + cstring); + System.out.println(map.get(cstring)); + } + } +} +/* Output: +{String: hi id: 4 hashCode(): 146450=3, String: hi id: +5 hashCode(): 146451=4, String: hi id: 2 hashCode(): +146448=1, String: hi id: 3 hashCode(): 146449=2, +String: hi id: 1 hashCode(): 146447=0} +Looking up String: hi id: 1 hashCode(): 146447 +0 +Looking up String: hi id: 2 hashCode(): 146448 +1 +Looking up String: hi id: 3 hashCode(): 146449 +2 +Looking up String: hi id: 4 hashCode(): 146450 +3 +Looking up String: hi id: 5 hashCode(): 146451 +4 +*/ diff --git a/code/equalshashcode/DefaultComparison.java b/code/equalshashcode/DefaultComparison.java new file mode 100644 index 00000000..d855de36 --- /dev/null +++ b/code/equalshashcode/DefaultComparison.java @@ -0,0 +1,24 @@ +// equalshashcode/DefaultComparison.java +// (c)2020 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. + +class DefaultComparison { + private int i, j, k; + DefaultComparison(int i, int j, int k) { + this.i = i; + this.j = j; + this.k = k; + } + public static void main(String[] args) { + DefaultComparison + a = new DefaultComparison(1, 2, 3), + b = new DefaultComparison(1, 2, 3); + System.out.println(a == a); + System.out.println(a == b); + } +} +/* Output: +true +false +*/ diff --git a/code/equalshashcode/Equality.java b/code/equalshashcode/Equality.java new file mode 100644 index 00000000..6ab13e5e --- /dev/null +++ b/code/equalshashcode/Equality.java @@ -0,0 +1,77 @@ +// equalshashcode/Equality.java +// (c)2020 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. +import java.util.*; + +public class Equality { + protected int i; + protected String s; + protected double d; + public Equality(int i, String s, double d) { + this.i = i; + this.s = s; + this.d = d; + System.out.println("made 'Equality'"); + } + @Override + public boolean equals(Object rval) { + if(rval == null) + return false; + if(rval == this) + return true; + if(!(rval instanceof Equality)) + return false; + Equality other = (Equality)rval; + if(!Objects.equals(i, other.i)) + return false; + if(!Objects.equals(s, other.s)) + return false; + if(!Objects.equals(d, other.d)) + return false; + return true; + } + public void + test(String descr, String expected, Object rval) { + System.out.format("-- Testing %s --%n" + + "%s instanceof Equality: %s%n" + + "Expected %s, got %s%n", + descr, descr, rval instanceof Equality, + expected, equals(rval)); + } + public static void testAll(EqualityFactory eqf) { + Equality + e = eqf.make(1, "Monty", 3.14), + eq = eqf.make(1, "Monty", 3.14), + neq = eqf.make(99, "Bob", 1.618); + e.test("null", "false", null); + e.test("same object", "true", e); + e.test("different type", + "false", Integer.valueOf(99)); + e.test("same values", "true", eq); + e.test("different values", "false", neq); + } + public static void main(String[] args) { + testAll( (i, s, d) -> new Equality(i, s, d)); + } +} +/* Output: +made 'Equality' +made 'Equality' +made 'Equality' +-- Testing null -- +null instanceof Equality: false +Expected false, got false +-- Testing same object -- +same object instanceof Equality: true +Expected true, got true +-- Testing different type -- +different type instanceof Equality: false +Expected false, got false +-- Testing same values -- +same values instanceof Equality: true +Expected true, got true +-- Testing different values -- +different values instanceof Equality: true +Expected false, got false +*/ diff --git a/code/equalshashcode/EqualityFactory.java b/code/equalshashcode/EqualityFactory.java new file mode 100644 index 00000000..378b56b0 --- /dev/null +++ b/code/equalshashcode/EqualityFactory.java @@ -0,0 +1,9 @@ +// equalshashcode/EqualityFactory.java +// (c)2020 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. +import java.util.*; + +interface EqualityFactory { + Equality make(int i, String s, double d); +} diff --git a/code/equalshashcode/Groundhog.java b/code/equalshashcode/Groundhog.java new file mode 100644 index 00000000..55c77563 --- /dev/null +++ b/code/equalshashcode/Groundhog.java @@ -0,0 +1,14 @@ +// equalshashcode/Groundhog.java +// (c)2020 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. +// Looks plausible, but doesn't work as a HashMap key + +public class Groundhog { + protected int number; + public Groundhog(int n) { number = n; } + @Override + public String toString() { + return "Groundhog #" + number; + } +} diff --git a/code/equalshashcode/Groundhog2.java b/code/equalshashcode/Groundhog2.java new file mode 100644 index 00000000..5348d1e5 --- /dev/null +++ b/code/equalshashcode/Groundhog2.java @@ -0,0 +1,19 @@ +// equalshashcode/Groundhog2.java +// (c)2020 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. +// A class that's used as a key in a HashMap +// must override hashCode() and equals() +import java.util.*; + +public class Groundhog2 extends Groundhog { + public Groundhog2(int n) { super(n); } + @Override + public int hashCode() { return number; } + @Override + public boolean equals(Object o) { + return o instanceof Groundhog2 && + Objects.equals( + number, ((Groundhog2)o).number); + } +} diff --git a/code/equalshashcode/IndividualTest.java b/code/equalshashcode/IndividualTest.java new file mode 100644 index 00000000..d8f50974 --- /dev/null +++ b/code/equalshashcode/IndividualTest.java @@ -0,0 +1,31 @@ +// equalshashcode/IndividualTest.java +// (c)2020 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. +import collections.MapOfList; +import typeinfo.pets.*; +import java.util.*; + +public class IndividualTest { + public static void main(String[] args) { + Set pets = new TreeSet<>(); + for(List lp : + MapOfList.petPeople.values()) + for(Pet p : lp) + pets.add(p); + pets.forEach(System.out::println); + } +} +/* Output: +Cat Elsie May +Cat Pinkola +Cat Shackleton +Cat Stanford +Cymric Molly +Dog Margrett +Mutt Spot +Pug Louie aka Louis Snorkelstein Dupree +Rat Fizzy +Rat Freckly +Rat Fuzzy +*/ diff --git a/code/equalshashcode/MapEntry.java b/code/equalshashcode/MapEntry.java new file mode 100644 index 00000000..c6e28bf4 --- /dev/null +++ b/code/equalshashcode/MapEntry.java @@ -0,0 +1,42 @@ +// equalshashcode/MapEntry.java +// (c)2020 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. +// A simple Map.Entry for sample Map implementations +import java.util.*; + +public class MapEntry implements Map.Entry { + private K key; + private V value; + public MapEntry(K key, V value) { + this.key = key; + this.value = value; + } + @Override + public K getKey() { return key; } + @Override + public V getValue() { return value; } + @Override + public V setValue(V v) { + V result = value; + value = v; + return result; + } + @Override + public int hashCode() { + return Objects.hash(key, value); + } + @SuppressWarnings("unchecked") + @Override + public boolean equals(Object rval) { + return rval instanceof MapEntry && + Objects.equals(key, + ((MapEntry)rval).getKey()) && + Objects.equals(value, + ((MapEntry)rval).getValue()); + } + @Override + public String toString() { + return key + "=" + value; + } +} diff --git a/code/equalshashcode/Prediction.java b/code/equalshashcode/Prediction.java new file mode 100644 index 00000000..c8ff9777 --- /dev/null +++ b/code/equalshashcode/Prediction.java @@ -0,0 +1,15 @@ +// equalshashcode/Prediction.java +// (c)2020 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. +// Predicting the weather +import java.util.*; + +public class Prediction { + private static Random rand = new Random(47); + @Override + public String toString() { + return rand.nextBoolean() ? + "Six more weeks of Winter!" : "Early Spring!"; + } +} diff --git a/code/equalshashcode/SimpleHashMap.java b/code/equalshashcode/SimpleHashMap.java new file mode 100644 index 00000000..f82022a1 --- /dev/null +++ b/code/equalshashcode/SimpleHashMap.java @@ -0,0 +1,90 @@ +// equalshashcode/SimpleHashMap.java +// (c)2020 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. +// A demonstration hashed Map +import java.util.*; +import onjava.*; + +public +class SimpleHashMap extends AbstractMap { + // Choose a prime number for the hash table + // size, to achieve a uniform distribution: + static final int SIZE = 997; + // You can't have a physical array of generics, + // but you can upcast to one: + @SuppressWarnings("unchecked") + LinkedList>[] buckets = + new LinkedList[SIZE]; + @Override + public V put(K key, V value) { + V oldValue = null; + int index = Math.abs(key.hashCode()) % SIZE; + if(buckets[index] == null) + buckets[index] = new LinkedList<>(); + LinkedList> bucket = buckets[index]; + MapEntry pair = new MapEntry<>(key, value); + boolean found = false; + ListIterator> it = + bucket.listIterator(); + while(it.hasNext()) { + MapEntry iPair = it.next(); + if(iPair.getKey().equals(key)) { + oldValue = iPair.getValue(); + it.set(pair); // Replace old with new + found = true; + break; + } + } + if(!found) + buckets[index].add(pair); + return oldValue; + } + @Override + public V get(Object key) { + int index = Math.abs(key.hashCode()) % SIZE; + if(buckets[index] == null) return null; + for(MapEntry iPair : buckets[index]) + if(iPair.getKey().equals(key)) + return iPair.getValue(); + return null; + } + @Override + public Set> entrySet() { + Set> set= new HashSet<>(); + for(LinkedList> bucket : buckets) { + if(bucket == null) continue; + for(MapEntry mpair : bucket) + set.add(mpair); + } + return set; + } + public static void main(String[] args) { + SimpleHashMap m = + new SimpleHashMap<>(); + m.putAll(Countries.capitals(8)); + m.forEach((k, v) -> + System.out.println(k + "=" + v)); + System.out.println(m.get("BENIN")); + m.entrySet().forEach(System.out::println); + } +} +/* Output: +CAMEROON=Yaounde +ANGOLA=Luanda +BURKINA FASO=Ouagadougou +BURUNDI=Bujumbura +ALGERIA=Algiers +BENIN=Porto-Novo +CAPE VERDE=Praia +BOTSWANA=Gaberone +Porto-Novo +CAMEROON=Yaounde +ANGOLA=Luanda +BURKINA FASO=Ouagadougou +BURUNDI=Bujumbura +ALGERIA=Algiers +BENIN=Porto-Novo +CAPE VERDE=Praia +BOTSWANA=Gaberone +*/ diff --git a/code/equalshashcode/SlowMap.java b/code/equalshashcode/SlowMap.java new file mode 100644 index 00000000..63f17092 --- /dev/null +++ b/code/equalshashcode/SlowMap.java @@ -0,0 +1,64 @@ +// equalshashcode/SlowMap.java +// (c)2020 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. +// A Map implemented with ArrayLists +import java.util.*; +import onjava.*; + +public class SlowMap extends AbstractMap { + private List keys = new ArrayList<>(); + private List values = new ArrayList<>(); + @Override + public V put(K key, V value) { + V oldValue = get(key); // The old value or null + if(!keys.contains(key)) { + keys.add(key); + values.add(value); + } else + values.set(keys.indexOf(key), value); + return oldValue; + } + @Override + public V get(Object key) { // key: type Object, not K + if(!keys.contains(key)) + return null; + return values.get(keys.indexOf(key)); + } + @Override + public Set> entrySet() { + Set> set= new HashSet<>(); + Iterator ki = keys.iterator(); + Iterator vi = values.iterator(); + while(ki.hasNext()) + set.add(new MapEntry<>(ki.next(), vi.next())); + return set; + } + public static void main(String[] args) { + SlowMap m= new SlowMap<>(); + m.putAll(Countries.capitals(8)); + m.forEach((k, v) -> + System.out.println(k + "=" + v)); + System.out.println(m.get("BENIN")); + m.entrySet().forEach(System.out::println); + } +} +/* Output: +CAMEROON=Yaounde +ANGOLA=Luanda +BURKINA FASO=Ouagadougou +BURUNDI=Bujumbura +ALGERIA=Algiers +BENIN=Porto-Novo +CAPE VERDE=Praia +BOTSWANA=Gaberone +Porto-Novo +CAMEROON=Yaounde +ANGOLA=Luanda +BURKINA FASO=Ouagadougou +BURUNDI=Bujumbura +ALGERIA=Algiers +BENIN=Porto-Novo +CAPE VERDE=Praia +BOTSWANA=Gaberone +*/ diff --git a/code/equalshashcode/SpringDetector.java b/code/equalshashcode/SpringDetector.java new file mode 100644 index 00000000..9b41bd3e --- /dev/null +++ b/code/equalshashcode/SpringDetector.java @@ -0,0 +1,62 @@ +// equalshashcode/SpringDetector.java +// (c)2020 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 will the weather be? +import java.util.*; +import java.util.stream.*; +import java.util.function.*; +import java.lang.reflect.*; + +public class SpringDetector { + public static + void detectSpring(Class type) { + try { + Constructor ghog = + type.getConstructor(int.class); + Map map = + IntStream.range(0, 10) + .mapToObj(i -> { + try { + return ghog.newInstance(i); + } catch(Exception e) { + throw new RuntimeException(e); + } + }) + .collect(Collectors.toMap( + Function.identity(), + gh -> new Prediction())); + map.forEach((k, v) -> + System.out.println(k + ": " + v)); + Groundhog gh = ghog.newInstance(3); + System.out.println( + "Looking up prediction for " + gh); + if(map.containsKey(gh)) + System.out.println(map.get(gh)); + else + System.out.println("Key not found: " + gh); + } catch(NoSuchMethodException | + IllegalAccessException | + InvocationTargetException | + InstantiationException e) { + throw new RuntimeException(e); + } + } + public static void main(String[] args) { + detectSpring(Groundhog.class); + } +} +/* Output: +Groundhog #3: Six more weeks of Winter! +Groundhog #0: Early Spring! +Groundhog #8: Six more weeks of Winter! +Groundhog #6: Early Spring! +Groundhog #4: Early Spring! +Groundhog #2: Six more weeks of Winter! +Groundhog #1: Early Spring! +Groundhog #9: Early Spring! +Groundhog #5: Six more weeks of Winter! +Groundhog #7: Six more weeks of Winter! +Looking up prediction for Groundhog #3 +Key not found: Groundhog #3 +*/ diff --git a/code/equalshashcode/SpringDetector2.java b/code/equalshashcode/SpringDetector2.java new file mode 100644 index 00000000..1e136e47 --- /dev/null +++ b/code/equalshashcode/SpringDetector2.java @@ -0,0 +1,25 @@ +// equalshashcode/SpringDetector2.java +// (c)2020 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. +// A working key + +public class SpringDetector2 { + public static void main(String[] args) { + SpringDetector.detectSpring(Groundhog2.class); + } +} +/* Output: +Groundhog #0: Six more weeks of Winter! +Groundhog #1: Early Spring! +Groundhog #2: Six more weeks of Winter! +Groundhog #3: Early Spring! +Groundhog #4: Early Spring! +Groundhog #5: Six more weeks of Winter! +Groundhog #6: Early Spring! +Groundhog #7: Early Spring! +Groundhog #8: Six more weeks of Winter! +Groundhog #9: Six more weeks of Winter! +Looking up prediction for Groundhog #3 +Early Spring! +*/ diff --git a/code/equalshashcode/StringHashCode.java b/code/equalshashcode/StringHashCode.java new file mode 100644 index 00000000..222fa612 --- /dev/null +++ b/code/equalshashcode/StringHashCode.java @@ -0,0 +1,16 @@ +// equalshashcode/StringHashCode.java +// (c)2020 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. + +public class StringHashCode { + public static void main(String[] args) { + String[] hellos = "Hello Hello".split(" "); + System.out.println(hellos[0].hashCode()); + System.out.println(hellos[1].hashCode()); + } +} +/* Output: +69609650 +69609650 +*/ diff --git a/code/equalshashcode/SubtypeEquality.java b/code/equalshashcode/SubtypeEquality.java new file mode 100644 index 00000000..90320c88 --- /dev/null +++ b/code/equalshashcode/SubtypeEquality.java @@ -0,0 +1,60 @@ +// equalshashcode/SubtypeEquality.java +// (c)2020 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. +import java.util.*; + +enum Size { SMALL, MEDIUM, LARGE } + +class Animal { + private static int counter = 0; + private final int id = counter++; + private final String name; + private final Size size; + Animal(String name, Size size) { + this.name = name; + this.size = size; + } + @Override + public boolean equals(Object rval) { + return rval instanceof Animal && + // Objects.equals(id, ((Animal)rval).id) && // [1] + Objects.equals(name, ((Animal)rval).name) && + Objects.equals(size, ((Animal)rval).size); + } + @Override + public int hashCode() { + return Objects.hash(name, size); + // return Objects.hash(name, size, id); // [2] + } + @Override + public String toString() { + return String.format("%s[%d]: %s %s %x", + getClass().getSimpleName(), id, + name, size, hashCode()); + } +} + +class Dog extends Animal { + Dog(String name, Size size) { + super(name, size); + } +} + +class Pig extends Animal { + Pig(String name, Size size) { + super(name, size); + } +} + +public class SubtypeEquality { + public static void main(String[] args) { + Set pets = new HashSet<>(); + pets.add(new Dog("Ralph", Size.MEDIUM)); + pets.add(new Pig("Ralph", Size.MEDIUM)); + pets.forEach(System.out::println); + } +} +/* Output: +Dog[0]: Ralph MEDIUM a752aeee +*/ diff --git a/code/equalshashcode/SubtypeEquality2.java b/code/equalshashcode/SubtypeEquality2.java new file mode 100644 index 00000000..c0ac5057 --- /dev/null +++ b/code/equalshashcode/SubtypeEquality2.java @@ -0,0 +1,40 @@ +// equalshashcode/SubtypeEquality2.java +// (c)2020 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. +import java.util.*; + +class Dog2 extends Animal { + Dog2(String name, Size size) { + super(name, size); + } + @Override + public boolean equals(Object rval) { + return rval instanceof Dog2 && + super.equals(rval); + } +} + +class Pig2 extends Animal { + Pig2(String name, Size size) { + super(name, size); + } + @Override + public boolean equals(Object rval) { + return rval instanceof Pig2 && + super.equals(rval); + } +} + +public class SubtypeEquality2 { + public static void main(String[] args) { + Set pets = new HashSet<>(); + pets.add(new Dog2("Ralph", Size.MEDIUM)); + pets.add(new Pig2("Ralph", Size.MEDIUM)); + pets.forEach(System.out::println); + } +} +/* Output: +Dog2[0]: Ralph MEDIUM a752aeee +Pig2[1]: Ralph MEDIUM a752aeee +*/ diff --git a/code/equalshashcode/SuccinctEquality.java b/code/equalshashcode/SuccinctEquality.java new file mode 100644 index 00000000..55a0d8de --- /dev/null +++ b/code/equalshashcode/SuccinctEquality.java @@ -0,0 +1,46 @@ +// equalshashcode/SuccinctEquality.java +// (c)2020 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. +import java.util.*; + +public class SuccinctEquality extends Equality { + public SuccinctEquality(int i, String s, double d) { + super(i, s, d); + System.out.println("made 'SuccinctEquality'"); + } + @Override + public boolean equals(Object rval) { + return rval instanceof SuccinctEquality && + Objects.equals(i, ((SuccinctEquality)rval).i) && + Objects.equals(s, ((SuccinctEquality)rval).s) && + Objects.equals(d, ((SuccinctEquality)rval).d); + } + public static void main(String[] args) { + Equality.testAll( (i, s, d) -> + new SuccinctEquality(i, s, d)); + } +} +/* Output: +made 'Equality' +made 'SuccinctEquality' +made 'Equality' +made 'SuccinctEquality' +made 'Equality' +made 'SuccinctEquality' +-- Testing null -- +null instanceof Equality: false +Expected false, got false +-- Testing same object -- +same object instanceof Equality: true +Expected true, got true +-- Testing different type -- +different type instanceof Equality: false +Expected false, got false +-- Testing same values -- +same values instanceof Equality: true +Expected true, got true +-- Testing different values -- +different values instanceof Equality: true +Expected false, got false +*/ diff --git a/code/exceptions/AlwaysFinally.java b/code/exceptions/AlwaysFinally.java new file mode 100644 index 00000000..bb2270f7 --- /dev/null +++ b/code/exceptions/AlwaysFinally.java @@ -0,0 +1,33 @@ +// exceptions/AlwaysFinally.java +// (c)2020 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. +// Finally is always executed + +class FourException extends Exception {} + +public class AlwaysFinally { + public static void main(String[] args) { + System.out.println("Entering first try block"); + try { + System.out.println("Entering second try block"); + try { + throw new FourException(); + } finally { + System.out.println("finally in 2nd try block"); + } + } catch(FourException e) { + System.out.println( + "Caught FourException in 1st try block"); + } finally { + System.out.println("finally in 1st try block"); + } + } +} +/* Output: +Entering first try block +Entering second try block +finally in 2nd try block +Caught FourException in 1st try block +finally in 1st try block +*/ diff --git a/code/exceptions/AutoCloseableDetails.java b/code/exceptions/AutoCloseableDetails.java new file mode 100644 index 00000000..24a22e9d --- /dev/null +++ b/code/exceptions/AutoCloseableDetails.java @@ -0,0 +1,33 @@ +// exceptions/AutoCloseableDetails.java +// (c)2020 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. + +class Reporter implements AutoCloseable { + String name = getClass().getSimpleName(); + Reporter() { + System.out.println("Creating " + name); + } + public void close() { + System.out.println("Closing " + name); + } +} + +class First extends Reporter {} +class Second extends Reporter {} + +public class AutoCloseableDetails { + public static void main(String[] args) { + try( + First f = new First(); + Second s = new Second() + ) { + } + } +} +/* Output: +Creating First +Creating Second +Closing Second +Closing First +*/ diff --git a/code/exceptions/BodyException.java b/code/exceptions/BodyException.java new file mode 100644 index 00000000..3e907f8a --- /dev/null +++ b/code/exceptions/BodyException.java @@ -0,0 +1,32 @@ +// exceptions/BodyException.java +// (c)2020 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. + +class Third extends Reporter {} + +public class BodyException { + public static void main(String[] args) { + try( + First f = new First(); + Second s2 = new Second() + ) { + System.out.println("In body"); + Third t = new Third(); + new SecondExcept(); + System.out.println("End of body"); + } catch(CE e) { + System.out.println("Caught: " + e); + } + } +} +/* Output: +Creating First +Creating Second +In body +Creating Third +Creating SecondExcept +Closing Second +Closing First +Caught: CE +*/ diff --git a/code/exceptions/Cleanup.java b/code/exceptions/Cleanup.java new file mode 100644 index 00000000..3d072304 --- /dev/null +++ b/code/exceptions/Cleanup.java @@ -0,0 +1,30 @@ +// exceptions/Cleanup.java +// (c)2020 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. +// Guaranteeing proper cleanup of a resource + +public class Cleanup { + public static void main(String[] args) { + try { + InputFile in = new InputFile("Cleanup.java"); + try { + String s; + int i = 1; + while((s = in.getLine()) != null) + ; // Perform line-by-line processing here... + } catch(Exception e) { + System.out.println("Caught Exception in main"); + e.printStackTrace(System.out); + } finally { + in.dispose(); + } + } catch(Exception e) { + System.out.println( + "InputFile construction failed"); + } + } +} +/* Output: +dispose() successful +*/ diff --git a/code/exceptions/CleanupIdiom.java b/code/exceptions/CleanupIdiom.java new file mode 100644 index 00000000..e8dd62c4 --- /dev/null +++ b/code/exceptions/CleanupIdiom.java @@ -0,0 +1,72 @@ +// exceptions/CleanupIdiom.java +// (c)2020 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. +// Disposable objects must be followed by a try-finally + +class NeedsCleanup { // Construction can't fail + private static long counter = 1; + private final long id = counter++; + public void dispose() { + System.out.println( + "NeedsCleanup " + id + " disposed"); + } +} + +class ConstructionException extends Exception {} + +class NeedsCleanup2 extends NeedsCleanup { + // Construction can fail: + NeedsCleanup2() throws ConstructionException {} +} + +public class CleanupIdiom { + public static void main(String[] args) { + // [1]: + NeedsCleanup nc1 = new NeedsCleanup(); + try { + // ... + } finally { + nc1.dispose(); + } + + // [2]: + // If construction cannot fail, + // you can group objects: + NeedsCleanup nc2 = new NeedsCleanup(); + NeedsCleanup nc3 = new NeedsCleanup(); + try { + // ... + } finally { + nc3.dispose(); // Reverse order of construction + nc2.dispose(); + } + + // [3]: + // If construction can fail you must guard each one: + try { + NeedsCleanup2 nc4 = new NeedsCleanup2(); + try { + NeedsCleanup2 nc5 = new NeedsCleanup2(); + try { + // ... + } finally { + nc5.dispose(); + } + } catch(ConstructionException e) { // nc5 const. + System.out.println(e); + } finally { + nc4.dispose(); + } + } catch(ConstructionException e) { // nc4 const. + System.out.println(e); + } + } +} +/* Output: +NeedsCleanup 1 disposed +NeedsCleanup 3 disposed +NeedsCleanup 2 disposed +NeedsCleanup 5 disposed +NeedsCleanup 4 disposed +*/ diff --git a/code/exceptions/CloseExceptions.java b/code/exceptions/CloseExceptions.java new file mode 100644 index 00000000..4309a888 --- /dev/null +++ b/code/exceptions/CloseExceptions.java @@ -0,0 +1,48 @@ +// exceptions/CloseExceptions.java +// (c)2020 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. + +class CloseException extends Exception {} + +class Reporter2 implements AutoCloseable { + String name = getClass().getSimpleName(); + Reporter2() { + System.out.println("Creating " + name); + } + public void close() throws CloseException { + System.out.println("Closing " + name); + } +} + +class Closer extends Reporter2 { + @Override + public void close() throws CloseException { + super.close(); + throw new CloseException(); + } +} + +public class CloseExceptions { + public static void main(String[] args) { + try( + First f = new First(); + Closer c = new Closer(); + Second s = new Second() + ) { + System.out.println("In body"); + } catch(CloseException e) { + System.out.println("Caught: " + e); + } + } +} +/* Output: +Creating First +Creating Closer +Creating Second +In body +Closing Second +Closing Closer +Closing First +Caught: CloseException +*/ diff --git a/code/exceptions/ConstructorException.java b/code/exceptions/ConstructorException.java new file mode 100644 index 00000000..54eaaba3 --- /dev/null +++ b/code/exceptions/ConstructorException.java @@ -0,0 +1,33 @@ +// exceptions/ConstructorException.java +// (c)2020 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. + +class CE extends Exception {} + +class SecondExcept extends Reporter { + SecondExcept() throws CE { + super(); + throw new CE(); + } +} + +public class ConstructorException { + public static void main(String[] args) { + try( + First f = new First(); + SecondExcept s = new SecondExcept(); + Second s2 = new Second() + ) { + System.out.println("In body"); + } catch(CE e) { + System.out.println("Caught: " + e); + } + } +} +/* Output: +Creating First +Creating SecondExcept +Closing First +Caught: CE +*/ diff --git a/code/exceptions/DynamicFields.java b/code/exceptions/DynamicFields.java new file mode 100644 index 00000000..da3b9617 --- /dev/null +++ b/code/exceptions/DynamicFields.java @@ -0,0 +1,130 @@ +// exceptions/DynamicFields.java +// (c)2020 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. +// A Class that dynamically adds fields to itself to +// demonstrate exception chaining + +class DynamicFieldsException extends Exception {} + +public class DynamicFields { + private Object[][] fields; + public DynamicFields(int initialSize) { + fields = new Object[initialSize][2]; + for(int i = 0; i < initialSize; i++) + fields[i] = new Object[] { null, null }; + } + @Override + public String toString() { + StringBuilder result = new StringBuilder(); + for(Object[] obj : fields) { + result.append(obj[0]); + result.append(": "); + result.append(obj[1]); + result.append("\n"); + } + return result.toString(); + } + private int hasField(String id) { + for(int i = 0; i < fields.length; i++) + if(id.equals(fields[i][0])) + return i; + return -1; + } + private int getFieldNumber(String id) + throws NoSuchFieldException { + int fieldNum = hasField(id); + if(fieldNum == -1) + throw new NoSuchFieldException(); + return fieldNum; + } + private int makeField(String id) { + for(int i = 0; i < fields.length; i++) + if(fields[i][0] == null) { + fields[i][0] = id; + return i; + } + // No empty fields. Add one: + Object[][] tmp = new Object[fields.length + 1][2]; + for(int i = 0; i < fields.length; i++) + tmp[i] = fields[i]; + for(int i = fields.length; i < tmp.length; i++) + tmp[i] = new Object[] { null, null }; + fields = tmp; + // Recursive call with expanded fields: + return makeField(id); + } + public Object + getField(String id) throws NoSuchFieldException { + return fields[getFieldNumber(id)][1]; + } + public Object setField(String id, Object value) + throws DynamicFieldsException { + if(value == null) { + // Most exceptions don't have a "cause" + // constructor. In these cases you must use + // initCause(), available in all + // Throwable subclasses. + DynamicFieldsException dfe = + new DynamicFieldsException(); + dfe.initCause(new NullPointerException()); + throw dfe; + } + int fieldNumber = hasField(id); + if(fieldNumber == -1) + fieldNumber = makeField(id); + Object result = null; + try { + result = getField(id); // Get old value + } catch(NoSuchFieldException e) { + // Use constructor that takes "cause": + throw new RuntimeException(e); + } + fields[fieldNumber][1] = value; + return result; + } + public static void main(String[] args) { + DynamicFields df = new DynamicFields(3); + System.out.println(df); + try { + df.setField("d", "A value for d"); + df.setField("number", 47); + df.setField("number2", 48); + System.out.println(df); + df.setField("d", "A new value for d"); + df.setField("number3", 11); + System.out.println("df: " + df); + System.out.println("df.getField(\"d\") : " + + df.getField("d")); + Object field = + df.setField("d", null); // Exception + } catch(NoSuchFieldException | + DynamicFieldsException e) { + e.printStackTrace(System.out); + } + } +} +/* Output: +null: null +null: null +null: null + +d: A value for d +number: 47 +number2: 48 + +df: d: A new value for d +number: 47 +number2: 48 +number3: 11 + +df.getField("d") : A new value for d +DynamicFieldsException + at +DynamicFields.setField(DynamicFields.java:65) + at DynamicFields.main(DynamicFields.java:97) +Caused by: java.lang.NullPointerException + at +DynamicFields.setField(DynamicFields.java:67) + ... 1 more +*/ diff --git a/code/exceptions/ExceptionMethods.java b/code/exceptions/ExceptionMethods.java new file mode 100644 index 00000000..bd6e8259 --- /dev/null +++ b/code/exceptions/ExceptionMethods.java @@ -0,0 +1,32 @@ +// exceptions/ExceptionMethods.java +// (c)2020 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. +// Demonstrating the Exception Methods + +public class ExceptionMethods { + public static void main(String[] args) { + try { + throw new Exception("My Exception"); + } catch(Exception e) { + System.out.println("Caught Exception"); + System.out.println( + "getMessage():" + e.getMessage()); + System.out.println("getLocalizedMessage():" + + e.getLocalizedMessage()); + System.out.println("toString():" + e); + System.out.println("printStackTrace():"); + e.printStackTrace(System.out); + } + } +} +/* Output: +Caught Exception +getMessage():My Exception +getLocalizedMessage():My Exception +toString():java.lang.Exception: My Exception +printStackTrace(): +java.lang.Exception: My Exception + at +ExceptionMethods.main(ExceptionMethods.java:7) +*/ diff --git a/code/exceptions/ExceptionSilencer.java b/code/exceptions/ExceptionSilencer.java new file mode 100644 index 00000000..e418e9de --- /dev/null +++ b/code/exceptions/ExceptionSilencer.java @@ -0,0 +1,16 @@ +// exceptions/ExceptionSilencer.java +// (c)2020 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. + +public class ExceptionSilencer { + public static void main(String[] args) { + try { + throw new RuntimeException(); + } finally { + // Using 'return' inside the finally block + // will silence any thrown exception. + return; + } + } +} diff --git a/code/exceptions/ExtraFeatures.java b/code/exceptions/ExtraFeatures.java new file mode 100644 index 00000000..8aa922af --- /dev/null +++ b/code/exceptions/ExtraFeatures.java @@ -0,0 +1,72 @@ +// exceptions/ExtraFeatures.java +// (c)2020 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. +// Further embellishment of exception classes + +class MyException2 extends Exception { + private int x; + MyException2() {} + MyException2(String msg) { super(msg); } + MyException2(String msg, int x) { + super(msg); + this.x = x; + } + public int val() { return x; } + @Override + public String getMessage() { + return "Detail Message: "+ x + + " "+ super.getMessage(); + } +} + +public class ExtraFeatures { + public static void f() throws MyException2 { + System.out.println( + "Throwing MyException2 from f()"); + throw new MyException2(); + } + public static void g() throws MyException2 { + System.out.println( + "Throwing MyException2 from g()"); + throw new MyException2("Originated in g()"); + } + public static void h() throws MyException2 { + System.out.println( + "Throwing MyException2 from h()"); + throw new MyException2("Originated in h()", 47); + } + public static void main(String[] args) { + try { + f(); + } catch(MyException2 e) { + e.printStackTrace(System.out); + } + try { + g(); + } catch(MyException2 e) { + e.printStackTrace(System.out); + } + try { + h(); + } catch(MyException2 e) { + e.printStackTrace(System.out); + System.out.println("e.val() = " + e.val()); + } + } +} +/* Output: +Throwing MyException2 from f() +MyException2: Detail Message: 0 null + at ExtraFeatures.f(ExtraFeatures.java:24) + at ExtraFeatures.main(ExtraFeatures.java:38) +Throwing MyException2 from g() +MyException2: Detail Message: 0 Originated in g() + at ExtraFeatures.g(ExtraFeatures.java:29) + at ExtraFeatures.main(ExtraFeatures.java:43) +Throwing MyException2 from h() +MyException2: Detail Message: 47 Originated in h() + at ExtraFeatures.h(ExtraFeatures.java:34) + at ExtraFeatures.main(ExtraFeatures.java:48) +e.val() = 47 +*/ diff --git a/code/exceptions/FinallyWorks.java b/code/exceptions/FinallyWorks.java new file mode 100644 index 00000000..fc4fec0a --- /dev/null +++ b/code/exceptions/FinallyWorks.java @@ -0,0 +1,32 @@ +// exceptions/FinallyWorks.java +// (c)2020 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. +// The finally clause is always executed + +class ThreeException extends Exception {} + +public class FinallyWorks { + static int count = 0; + public static void main(String[] args) { + while(true) { + try { + // Post-increment is zero first time: + if(count++ == 0) + throw new ThreeException(); + System.out.println("No exception"); + } catch(ThreeException e) { + System.out.println("ThreeException"); + } finally { + System.out.println("In finally clause"); + if(count == 2) break; // out of "while" + } + } + } +} +/* Output: +ThreeException +In finally clause +No exception +In finally clause +*/ diff --git a/code/exceptions/FullConstructors.java b/code/exceptions/FullConstructors.java new file mode 100644 index 00000000..f5b4c9ff --- /dev/null +++ b/code/exceptions/FullConstructors.java @@ -0,0 +1,44 @@ +// exceptions/FullConstructors.java +// (c)2020 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. + +class MyException extends Exception { + MyException() {} + MyException(String msg) { super(msg); } +} + +public class FullConstructors { + public static void f() throws MyException { + System.out.println("Throwing MyException from f()"); + throw new MyException(); + } + public static void g() throws MyException { + System.out.println("Throwing MyException from g()"); + throw new MyException("Originated in g()"); + } + public static void main(String[] args) { + try { + f(); + } catch(MyException e) { + e.printStackTrace(System.out); + } + try { + g(); + } catch(MyException e) { + e.printStackTrace(System.out); + } + } +} +/* Output: +Throwing MyException from f() +MyException + at FullConstructors.f(FullConstructors.java:11) + at +FullConstructors.main(FullConstructors.java:19) +Throwing MyException from g() +MyException: Originated in g() + at FullConstructors.g(FullConstructors.java:15) + at +FullConstructors.main(FullConstructors.java:24) +*/ diff --git a/code/exceptions/Human.java b/code/exceptions/Human.java new file mode 100644 index 00000000..7ee7dcaa --- /dev/null +++ b/code/exceptions/Human.java @@ -0,0 +1,31 @@ +// exceptions/Human.java +// (c)2020 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. +// Catching exception hierarchies + +class Annoyance extends Exception {} +class Sneeze extends Annoyance {} + +public class Human { + public static void main(String[] args) { + // Catch the exact type: + try { + throw new Sneeze(); + } catch(Sneeze s) { + System.out.println("Caught Sneeze"); + } catch(Annoyance a) { + System.out.println("Caught Annoyance"); + } + // Catch the base type: + try { + throw new Sneeze(); + } catch(Annoyance a) { + System.out.println("Caught Annoyance"); + } + } +} +/* Output: +Caught Sneeze +Caught Annoyance +*/ diff --git a/code/exceptions/InheritingExceptions.java b/code/exceptions/InheritingExceptions.java new file mode 100644 index 00000000..abb80c3b --- /dev/null +++ b/code/exceptions/InheritingExceptions.java @@ -0,0 +1,28 @@ +// exceptions/InheritingExceptions.java +// (c)2020 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. +// Creating your own exceptions + +class SimpleException extends Exception {} + +public class InheritingExceptions { + public void f() throws SimpleException { + System.out.println( + "Throw SimpleException from f()"); + throw new SimpleException(); + } + public static void main(String[] args) { + InheritingExceptions sed = + new InheritingExceptions(); + try { + sed.f(); + } catch(SimpleException e) { + System.out.println("Caught it!"); + } + } +} +/* Output: +Throw SimpleException from f() +Caught it! +*/ diff --git a/code/exceptions/InputFile.java b/code/exceptions/InputFile.java new file mode 100644 index 00000000..5c269851 --- /dev/null +++ b/code/exceptions/InputFile.java @@ -0,0 +1,47 @@ +// exceptions/InputFile.java +// (c)2020 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. +// Paying attention to exceptions in constructors +import java.io.*; + +public class InputFile { + private BufferedReader in; + public InputFile(String fname) throws Exception { + try { + in = new BufferedReader(new FileReader(fname)); + // Other code that might throw exceptions + } catch(FileNotFoundException e) { + System.out.println("Could not open " + fname); + // Wasn't open, so don't close it + throw e; + } catch(Exception e) { + // All other exceptions must close it + try { + in.close(); + } catch(IOException e2) { + System.out.println("in.close() unsuccessful"); + } + throw e; // Rethrow + } finally { + // Don't close it here!!! + } + } + public String getLine() { + String s; + try { + s = in.readLine(); + } catch(IOException e) { + throw new RuntimeException("readLine() failed"); + } + return s; + } + public void dispose() { + try { + in.close(); + System.out.println("dispose() successful"); + } catch(IOException e2) { + throw new RuntimeException("in.close() failed"); + } + } +} diff --git a/code/exceptions/InputFile2.java b/code/exceptions/InputFile2.java new file mode 100644 index 00000000..74a68c3f --- /dev/null +++ b/code/exceptions/InputFile2.java @@ -0,0 +1,28 @@ +// exceptions/InputFile2.java +// (c)2020 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. +import java.io.*; +import java.nio.file.*; +import java.util.stream.*; + +public class InputFile2 { + private String fname; + public InputFile2(String fname) { + this.fname = fname; + } + public + Stream getLines() throws IOException { + return Files.lines(Paths.get(fname)); + } + public static void + main(String[] args) throws IOException { + new InputFile2("InputFile2.java").getLines() + .skip(15) + .limit(1) + .forEach(System.out::println); + } +} +/* Output: + main(String[] args) throws IOException { +*/ diff --git a/code/exceptions/LoggingExceptions.java b/code/exceptions/LoggingExceptions.java new file mode 100644 index 00000000..0120ee17 --- /dev/null +++ b/code/exceptions/LoggingExceptions.java @@ -0,0 +1,48 @@ +// exceptions/LoggingExceptions.java +// (c)2020 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. +// An exception that reports through a Logger +// {ErrorOutputExpected} +import java.util.logging.*; +import java.io.*; + +class LoggingException extends Exception { + private static Logger logger = + Logger.getLogger("LoggingException"); + LoggingException() { + StringWriter trace = new StringWriter(); + printStackTrace(new PrintWriter(trace)); + logger.severe(trace.toString()); + } +} + +public class LoggingExceptions { + public static void main(String[] args) { + try { + throw new LoggingException(); + } catch(LoggingException e) { + System.err.println("Caught " + e); + } + try { + throw new LoggingException(); + } catch(LoggingException e) { + System.err.println("Caught " + e); + } + } +} +/* Output: +___[ Error Output ]___ +May 09, 2017 6:07:17 AM LoggingException +SEVERE: LoggingException + at +LoggingExceptions.main(LoggingExceptions.java:20) + +Caught LoggingException +May 09, 2017 6:07:17 AM LoggingException +SEVERE: LoggingException + at +LoggingExceptions.main(LoggingExceptions.java:25) + +Caught LoggingException +*/ diff --git a/code/exceptions/LoggingExceptions2.java b/code/exceptions/LoggingExceptions2.java new file mode 100644 index 00000000..21a92137 --- /dev/null +++ b/code/exceptions/LoggingExceptions2.java @@ -0,0 +1,32 @@ +// exceptions/LoggingExceptions2.java +// (c)2020 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. +// Logging caught exceptions +// {ErrorOutputExpected} +import java.util.logging.*; +import java.io.*; + +public class LoggingExceptions2 { + private static Logger logger = + Logger.getLogger("LoggingExceptions2"); + static void logException(Exception e) { + StringWriter trace = new StringWriter(); + e.printStackTrace(new PrintWriter(trace)); + logger.severe(trace.toString()); + } + public static void main(String[] args) { + try { + throw new NullPointerException(); + } catch(NullPointerException e) { + logException(e); + } + } +} +/* Output: +___[ Error Output ]___ +May 09, 2017 6:07:17 AM LoggingExceptions2 logException +SEVERE: java.lang.NullPointerException + at +LoggingExceptions2.main(LoggingExceptions2.java:17) +*/ diff --git a/code/exceptions/LostMessage.java b/code/exceptions/LostMessage.java new file mode 100644 index 00000000..1446d903 --- /dev/null +++ b/code/exceptions/LostMessage.java @@ -0,0 +1,44 @@ +// exceptions/LostMessage.java +// (c)2020 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. +// How an exception can be lost + +class VeryImportantException extends Exception { + @Override + public String toString() { + return "A very important exception!"; + } +} + +class HoHumException extends Exception { + @Override + public String toString() { + return "A trivial exception"; + } +} + +public class LostMessage { + void f() throws VeryImportantException { + throw new VeryImportantException(); + } + void dispose() throws HoHumException { + throw new HoHumException(); + } + public static void main(String[] args) { + try { + LostMessage lm = new LostMessage(); + try { + lm.f(); + } finally { + lm.dispose(); + } + } catch(VeryImportantException | + HoHumException e) { + System.out.println(e); + } + } +} +/* Output: +A trivial exception +*/ diff --git a/code/exceptions/MainException.java b/code/exceptions/MainException.java new file mode 100644 index 00000000..7a7e2638 --- /dev/null +++ b/code/exceptions/MainException.java @@ -0,0 +1,17 @@ +// exceptions/MainException.java +// (c)2020 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. +import java.util.*; +import java.nio.file.*; + +public class MainException { + // Pass exceptions to the console: + public static void + main(String[] args) throws Exception { + // Open the file: + List lines = Files.readAllLines( + Paths.get("MainException.java")); + // Use the file ... + } +} diff --git a/code/exceptions/MessyExceptions.java b/code/exceptions/MessyExceptions.java new file mode 100644 index 00000000..e8f7fc9d --- /dev/null +++ b/code/exceptions/MessyExceptions.java @@ -0,0 +1,27 @@ +// exceptions/MessyExceptions.java +// (c)2020 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. +import java.io.*; + +public class MessyExceptions { + public static void main(String[] args) { + InputStream in = null; + try { + in = new FileInputStream( + new File("MessyExceptions.java")); + int contents = in.read(); + // Process contents + } catch(IOException e) { + // Handle the error + } finally { + if(in != null) { + try { + in.close(); + } catch(IOException e) { + // Handle the close() error + } + } + } + } +} diff --git a/code/exceptions/MultiCatch.java b/code/exceptions/MultiCatch.java new file mode 100644 index 00000000..f97bde13 --- /dev/null +++ b/code/exceptions/MultiCatch.java @@ -0,0 +1,16 @@ +// exceptions/MultiCatch.java +// (c)2020 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. + +public class MultiCatch { + void x() throws Except1, Except2, Except3, Except4 {} + void process() {} + void f() { + try { + x(); + } catch(Except1 | Except2 | Except3 | Except4 e) { + process(); + } + } +} diff --git a/code/exceptions/MultiCatch2.java b/code/exceptions/MultiCatch2.java new file mode 100644 index 00000000..4629e93f --- /dev/null +++ b/code/exceptions/MultiCatch2.java @@ -0,0 +1,19 @@ +// exceptions/MultiCatch2.java +// (c)2020 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. + +public class MultiCatch2 { + void x() throws Except1, Except2, Except3, Except4 {} + void process1() {} + void process2() {} + void f() { + try { + x(); + } catch(Except1 | Except2 e) { + process1(); + } catch(Except3 | Except4 e) { + process2(); + } + } +} diff --git a/code/exceptions/MultipleReturns.java b/code/exceptions/MultipleReturns.java new file mode 100644 index 00000000..3f667b33 --- /dev/null +++ b/code/exceptions/MultipleReturns.java @@ -0,0 +1,47 @@ +// exceptions/MultipleReturns.java +// (c)2020 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. + +public class MultipleReturns { + public static void f(int i) { + System.out.println( + "Initialization that requires cleanup"); + try { + System.out.println("Point 1"); + if(i == 1) return; + System.out.println("Point 2"); + if(i == 2) return; + System.out.println("Point 3"); + if(i == 3) return; + System.out.println("End"); + return; + } finally { + System.out.println("Performing cleanup"); + } + } + public static void main(String[] args) { + for(int i = 1; i <= 4; i++) + f(i); + } +} +/* Output: +Initialization that requires cleanup +Point 1 +Performing cleanup +Initialization that requires cleanup +Point 1 +Point 2 +Performing cleanup +Initialization that requires cleanup +Point 1 +Point 2 +Point 3 +Performing cleanup +Initialization that requires cleanup +Point 1 +Point 2 +Point 3 +End +Performing cleanup +*/ diff --git a/code/exceptions/NeverCaught.java b/code/exceptions/NeverCaught.java new file mode 100644 index 00000000..c8bb0a2f --- /dev/null +++ b/code/exceptions/NeverCaught.java @@ -0,0 +1,26 @@ +// exceptions/NeverCaught.java +// (c)2020 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. +// Ignoring RuntimeExceptions +// {ThrowsException} + +public class NeverCaught { + static void f() { + throw new RuntimeException("From f()"); + } + static void g() { + f(); + } + public static void main(String[] args) { + g(); + } +} +/* Output: +___[ Error Output ]___ +Exception in thread "main" java.lang.RuntimeException: +From f() + at NeverCaught.f(NeverCaught.java:7) + at NeverCaught.g(NeverCaught.java:10) + at NeverCaught.main(NeverCaught.java:13) +*/ diff --git a/code/exceptions/OnOffException1.java b/code/exceptions/OnOffException1.java new file mode 100644 index 00000000..3333d815 --- /dev/null +++ b/code/exceptions/OnOffException1.java @@ -0,0 +1,5 @@ +// exceptions/OnOffException1.java +// (c)2020 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. +public class OnOffException1 extends Exception {} diff --git a/code/exceptions/OnOffException2.java b/code/exceptions/OnOffException2.java new file mode 100644 index 00000000..0bb5e164 --- /dev/null +++ b/code/exceptions/OnOffException2.java @@ -0,0 +1,5 @@ +// exceptions/OnOffException2.java +// (c)2020 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. +public class OnOffException2 extends Exception {} diff --git a/code/exceptions/OnOffSwitch.java b/code/exceptions/OnOffSwitch.java new file mode 100644 index 00000000..fe05fa35 --- /dev/null +++ b/code/exceptions/OnOffSwitch.java @@ -0,0 +1,29 @@ +// exceptions/OnOffSwitch.java +// (c)2020 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. +// Why use finally? + +public class OnOffSwitch { + private static Switch sw = new Switch(); + public static void f() + throws OnOffException1, OnOffException2 {} + public static void main(String[] args) { + try { + sw.on(); + // Code that can throw exceptions... + f(); + sw.off(); + } catch(OnOffException1 e) { + System.out.println("OnOffException1"); + sw.off(); + } catch(OnOffException2 e) { + System.out.println("OnOffException2"); + sw.off(); + } + } +} +/* Output: +on +off +*/ diff --git a/code/exceptions/PreciseRethrow.java b/code/exceptions/PreciseRethrow.java new file mode 100644 index 00000000..f8849a3d --- /dev/null +++ b/code/exceptions/PreciseRethrow.java @@ -0,0 +1,17 @@ +// exceptions/PreciseRethrow.java +// (c)2020 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. + +class BaseException extends Exception {} +class DerivedException extends BaseException {} + +public class PreciseRethrow { + void catcher() throws DerivedException { + try { + throw new DerivedException(); + } catch(BaseException e) { + throw e; + } + } +} diff --git a/code/exceptions/RethrowNew.java b/code/exceptions/RethrowNew.java new file mode 100644 index 00000000..daa4ad41 --- /dev/null +++ b/code/exceptions/RethrowNew.java @@ -0,0 +1,47 @@ +// exceptions/RethrowNew.java +// (c)2020 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. +// Rethrow a different object from the one you caught + +class OneException extends Exception { + OneException(String s) { super(s); } +} + +class TwoException extends Exception { + TwoException(String s) { super(s); } +} + +public class RethrowNew { + public static void f() throws OneException { + System.out.println( + "originating the exception in f()"); + throw new OneException("thrown from f()"); + } + public static void main(String[] args) { + try { + try { + f(); + } catch(OneException e) { + System.out.println( + "Caught in inner try, e.printStackTrace()"); + e.printStackTrace(System.out); + throw new TwoException("from inner try"); + } + } catch(TwoException e) { + System.out.println( + "Caught in outer try, e.printStackTrace()"); + e.printStackTrace(System.out); + } + } +} +/* Output: +originating the exception in f() +Caught in inner try, e.printStackTrace() +OneException: thrown from f() + at RethrowNew.f(RethrowNew.java:16) + at RethrowNew.main(RethrowNew.java:21) +Caught in outer try, e.printStackTrace() +TwoException: from inner try + at RethrowNew.main(RethrowNew.java:26) +*/ diff --git a/code/exceptions/Rethrowing.java b/code/exceptions/Rethrowing.java new file mode 100644 index 00000000..5bf1a635 --- /dev/null +++ b/code/exceptions/Rethrowing.java @@ -0,0 +1,70 @@ +// exceptions/Rethrowing.java +// (c)2020 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. +// Demonstrating fillInStackTrace() + +public class Rethrowing { + public static void f() throws Exception { + System.out.println( + "originating the exception in f()"); + throw new Exception("thrown from f()"); + } + public static void g() throws Exception { + try { + f(); + } catch(Exception e) { + System.out.println( + "Inside g(), e.printStackTrace()"); + e.printStackTrace(System.out); + throw e; + } + } + public static void h() throws Exception { + try { + f(); + } catch(Exception e) { + System.out.println( + "Inside h(), e.printStackTrace()"); + e.printStackTrace(System.out); + throw (Exception)e.fillInStackTrace(); + } + } + public static void main(String[] args) { + try { + g(); + } catch(Exception e) { + System.out.println("main: printStackTrace()"); + e.printStackTrace(System.out); + } + try { + h(); + } catch(Exception e) { + System.out.println("main: printStackTrace()"); + e.printStackTrace(System.out); + } + } +} +/* Output: +originating the exception in f() +Inside g(), e.printStackTrace() +java.lang.Exception: thrown from f() + at Rethrowing.f(Rethrowing.java:8) + at Rethrowing.g(Rethrowing.java:12) + at Rethrowing.main(Rethrowing.java:32) +main: printStackTrace() +java.lang.Exception: thrown from f() + at Rethrowing.f(Rethrowing.java:8) + at Rethrowing.g(Rethrowing.java:12) + at Rethrowing.main(Rethrowing.java:32) +originating the exception in f() +Inside h(), e.printStackTrace() +java.lang.Exception: thrown from f() + at Rethrowing.f(Rethrowing.java:8) + at Rethrowing.h(Rethrowing.java:22) + at Rethrowing.main(Rethrowing.java:38) +main: printStackTrace() +java.lang.Exception: thrown from f() + at Rethrowing.h(Rethrowing.java:27) + at Rethrowing.main(Rethrowing.java:38) +*/ diff --git a/code/exceptions/SameHandler.java b/code/exceptions/SameHandler.java new file mode 100644 index 00000000..8c680567 --- /dev/null +++ b/code/exceptions/SameHandler.java @@ -0,0 +1,31 @@ +// exceptions/SameHandler.java +// (c)2020 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. + +class EBase1 extends Exception {} +class Except1 extends EBase1 {} +class EBase2 extends Exception {} +class Except2 extends EBase2 {} +class EBase3 extends Exception {} +class Except3 extends EBase3 {} +class EBase4 extends Exception {} +class Except4 extends EBase4 {} + +public class SameHandler { + void x() throws Except1, Except2, Except3, Except4 {} + void process() {} + void f() { + try { + x(); + } catch(Except1 e) { + process(); + } catch(Except2 e) { + process(); + } catch(Except3 e) { + process(); + } catch(Except4 e) { + process(); + } + } +} diff --git a/code/exceptions/StormyInning.java b/code/exceptions/StormyInning.java new file mode 100644 index 00000000..644c10ba --- /dev/null +++ b/code/exceptions/StormyInning.java @@ -0,0 +1,83 @@ +// exceptions/StormyInning.java +// (c)2020 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. +// Overridden methods can throw only the exceptions +// specified in their base-class versions, or exceptions +// derived from the base-class exceptions + +class BaseballException extends Exception {} +class Foul extends BaseballException {} +class Strike extends BaseballException {} + +abstract class Inning { + Inning() throws BaseballException {} + public void event() throws BaseballException { + // Doesn't actually have to throw anything + } + public abstract void atBat() throws Strike, Foul; + public void walk() {} // Throws no checked exceptions +} + +class StormException extends Exception {} +class RainedOut extends StormException {} +class PopFoul extends Foul {} + +interface Storm { + void event() throws RainedOut; + void rainHard() throws RainedOut; +} + +public +class StormyInning extends Inning implements Storm { + // OK to add new exceptions for constructors, but you + // must deal with the base constructor exceptions: + public StormyInning() + throws RainedOut, BaseballException {} + public StormyInning(String s) + throws BaseballException {} + // Regular methods must conform to base class: + //- void walk() throws PopFoul {} //Compile error + // Interface CANNOT add exceptions to existing + // methods from the base class: + //- public void event() throws RainedOut {} + // If the method doesn't already exist in the + // base class, the exception is OK: + @Override + public void rainHard() throws RainedOut {} + // You can choose to not throw any exceptions, + // even if the base version does: + @Override + public void event() {} + // Overridden methods can throw inherited exceptions: + @Override + public void atBat() throws PopFoul {} + public static void main(String[] args) { + try { + StormyInning si = new StormyInning(); + si.atBat(); + } catch(PopFoul e) { + System.out.println("Pop foul"); + } catch(RainedOut e) { + System.out.println("Rained out"); + } catch(BaseballException e) { + System.out.println("Generic baseball exception"); + } + // Strike not thrown in derived version. + try { + // What happens if you upcast? + Inning i = new StormyInning(); + i.atBat(); + // You must catch the exceptions from the + // base-class version of the method: + } catch(Strike e) { + System.out.println("Strike"); + } catch(Foul e) { + System.out.println("Foul"); + } catch(RainedOut e) { + System.out.println("Rained out"); + } catch(BaseballException e) { + System.out.println("Generic baseball exception"); + } + } +} diff --git a/code/exceptions/StreamsAreAutoCloseable.java b/code/exceptions/StreamsAreAutoCloseable.java new file mode 100644 index 00000000..c55bf417 --- /dev/null +++ b/code/exceptions/StreamsAreAutoCloseable.java @@ -0,0 +1,24 @@ +// exceptions/StreamsAreAutoCloseable.java +// (c)2020 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. +import java.io.*; +import java.nio.file.*; +import java.util.stream.*; + +public class StreamsAreAutoCloseable { + public static void + main(String[] args) throws IOException{ + try( + Stream in = Files.lines( + Paths.get("StreamsAreAutoCloseable.java")); + PrintWriter outfile = new PrintWriter( + "Results.txt"); // [1] + ) { + in.skip(5) + .limit(1) + .map(String::toLowerCase) + .forEachOrdered(outfile::println); + } // [2] + } +} diff --git a/code/exceptions/Switch.java b/code/exceptions/Switch.java new file mode 100644 index 00000000..7d491d00 --- /dev/null +++ b/code/exceptions/Switch.java @@ -0,0 +1,21 @@ +// exceptions/Switch.java +// (c)2020 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. + +public class Switch { + private boolean state = false; + public boolean read() { return state; } + public void on() { + state = true; + System.out.println(this); + } + public void off() { + state = false; + System.out.println(this); + } + @Override + public String toString() { + return state ? "on" : "off"; + } +} diff --git a/code/exceptions/TryAnything.java b/code/exceptions/TryAnything.java new file mode 100644 index 00000000..9eeee07b --- /dev/null +++ b/code/exceptions/TryAnything.java @@ -0,0 +1,16 @@ +// exceptions/TryAnything.java +// (c)2020 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. +// {WillNotCompile} + +class Anything {} + +public class TryAnything { + public static void main(String[] args) { + try( + Anything a = new Anything() + ) { + } + } +} diff --git a/code/exceptions/TryWithResources.java b/code/exceptions/TryWithResources.java new file mode 100644 index 00000000..cdc83a5c --- /dev/null +++ b/code/exceptions/TryWithResources.java @@ -0,0 +1,19 @@ +// exceptions/TryWithResources.java +// (c)2020 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. +import java.io.*; + +public class TryWithResources { + public static void main(String[] args) { + try( + InputStream in = new FileInputStream( + new File("TryWithResources.java")) + ) { + int contents = in.read(); + // Process contents + } catch(IOException e) { + // Handle the error + } + } +} diff --git a/code/exceptions/TurnOffChecking.java b/code/exceptions/TurnOffChecking.java new file mode 100644 index 00000000..898431b6 --- /dev/null +++ b/code/exceptions/TurnOffChecking.java @@ -0,0 +1,64 @@ +// exceptions/TurnOffChecking.java +// (c)2020 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. +// "Turning off" Checked exceptions +import java.io.*; + +class WrapCheckedException { + void throwRuntimeException(int type) { + try { + switch(type) { + case 0: throw new FileNotFoundException(); + case 1: throw new IOException(); + case 2: throw new + RuntimeException("Where am I?"); + default: return; + } + } catch(IOException | RuntimeException e) { + // Adapt to unchecked: + throw new RuntimeException(e); + } + } +} + +class SomeOtherException extends Exception {} + +public class TurnOffChecking { + public static void main(String[] args) { + WrapCheckedException wce = + new WrapCheckedException(); + // You can call throwRuntimeException() without + // a try block, and let RuntimeExceptions + // leave the method: + wce.throwRuntimeException(3); + // Or you can choose to catch exceptions: + for(int i = 0; i < 4; i++) + try { + if(i < 3) + wce.throwRuntimeException(i); + else + throw new SomeOtherException(); + } catch(SomeOtherException e) { + System.out.println( + "SomeOtherException: " + e); + } catch(RuntimeException re) { + try { + throw re.getCause(); + } catch(FileNotFoundException e) { + System.out.println( + "FileNotFoundException: " + e); + } catch(IOException e) { + System.out.println("IOException: " + e); + } catch(Throwable e) { + System.out.println("Throwable: " + e); + } + } + } +} +/* Output: +FileNotFoundException: java.io.FileNotFoundException +IOException: java.io.IOException +Throwable: java.lang.RuntimeException: Where am I? +SomeOtherException: SomeOtherException +*/ diff --git a/code/exceptions/WhoCalled.java b/code/exceptions/WhoCalled.java new file mode 100644 index 00000000..4c4e0104 --- /dev/null +++ b/code/exceptions/WhoCalled.java @@ -0,0 +1,39 @@ +// exceptions/WhoCalled.java +// (c)2020 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. +// Programmatic access to stack trace information + +public class WhoCalled { + static void f() { + // Generate an exception to fill in the stack trace + try { + throw new Exception(); + } catch(Exception e) { + for(StackTraceElement ste : e.getStackTrace()) + System.out.println(ste.getMethodName()); + } + } + static void g() { f(); } + static void h() { g(); } + public static void main(String[] args) { + f(); + System.out.println("*******"); + g(); + System.out.println("*******"); + h(); + } +} +/* Output: +f +main +******* +f +g +main +******* +f +g +h +main +*/ diff --git a/code/exceptions/WithFinally.java b/code/exceptions/WithFinally.java new file mode 100644 index 00000000..9d3efc3a --- /dev/null +++ b/code/exceptions/WithFinally.java @@ -0,0 +1,26 @@ +// exceptions/WithFinally.java +// (c)2020 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. +// Finally Guarantees cleanup + +public class WithFinally { + static Switch sw = new Switch(); + public static void main(String[] args) { + try { + sw.on(); + // Code that can throw exceptions... + OnOffSwitch.f(); + } catch(OnOffException1 e) { + System.out.println("OnOffException1"); + } catch(OnOffException2 e) { + System.out.println("OnOffException2"); + } finally { + sw.off(); + } + } +} +/* Output: +on +off +*/ diff --git a/code/files/AddAndSubtractPaths.java b/code/files/AddAndSubtractPaths.java new file mode 100644 index 00000000..f3984d19 --- /dev/null +++ b/code/files/AddAndSubtractPaths.java @@ -0,0 +1,87 @@ +// files/AddAndSubtractPaths.java +// (c)2020 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. +import java.nio.file.*; +import java.io.IOException; + +public class AddAndSubtractPaths { + static Path base = Paths.get("..", "..", "..") + .toAbsolutePath() + .normalize(); + static void show(int id, Path result) { + if(result.isAbsolute()) + System.out.println("(" + id + ")r " + + base.relativize(result)); + else + System.out.println("(" + id + ") " + result); + try { + System.out.println("RealPath: " + + result.toRealPath()); + } catch(IOException e) { + System.out.println(e); + } + } + public static void main(String[] args) { + System.out.println(System.getProperty("os.name")); + System.out.println(base); + Path p = Paths.get("AddAndSubtractPaths.java") + .toAbsolutePath(); + show(1, p); + Path convoluted = p.getParent().getParent() + .resolve("strings") + .resolve("..") + .resolve(p.getParent().getFileName()); + show(2, convoluted); + show(3, convoluted.normalize()); + + Path p2 = Paths.get("..", ".."); + show(4, p2); + show(5, p2.normalize()); + show(6, p2.toAbsolutePath().normalize()); + + Path p3 = Paths.get(".").toAbsolutePath(); + Path p4 = p3.resolve(p2); + show(7, p4); + show(8, p4.normalize()); + + Path p5 = Paths.get("").toAbsolutePath(); + show(9, p5); + show(10, p5.resolveSibling("strings")); + show(11, Paths.get("nonexistent")); + } +} +/* Output: +Windows 10 +C:\Users\Bruce\Documents\GitHub +(1)r on- +java\ExtractedExamples\files\AddAndSubtractPaths.java +RealPath: C:\Users\Bruce\Documents\GitHub\on- +java\ExtractedExamples\files\AddAndSubtractPaths.java +(2)r on-java\ExtractedExamples\strings\..\files +RealPath: C:\Users\Bruce\Documents\GitHub\on- +java\ExtractedExamples\files +(3)r on-java\ExtractedExamples\files +RealPath: C:\Users\Bruce\Documents\GitHub\on- +java\ExtractedExamples\files +(4) ..\.. +RealPath: C:\Users\Bruce\Documents\GitHub\on-java +(5) ..\.. +RealPath: C:\Users\Bruce\Documents\GitHub\on-java +(6)r on-java +RealPath: C:\Users\Bruce\Documents\GitHub\on-java +(7)r on-java\ExtractedExamples\files\.\..\.. +RealPath: C:\Users\Bruce\Documents\GitHub\on-java +(8)r on-java +RealPath: C:\Users\Bruce\Documents\GitHub\on-java +(9)r on-java\ExtractedExamples\files +RealPath: C:\Users\Bruce\Documents\GitHub\on- +java\ExtractedExamples\files +(10)r on-java\ExtractedExamples\strings +RealPath: C:\Users\Bruce\Documents\GitHub\on- +java\ExtractedExamples\strings +(11) nonexistent +java.nio.file.NoSuchFileException: +C:\Users\Bruce\Documents\GitHub\on- +java\ExtractedExamples\files\nonexistent +*/ diff --git a/code/files/Directories.java b/code/files/Directories.java new file mode 100644 index 00000000..10ad9bee --- /dev/null +++ b/code/files/Directories.java @@ -0,0 +1,94 @@ +// files/Directories.java +// (c)2020 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. +import java.util.*; +import java.nio.file.*; +import onjava.RmDir; + +public class Directories { + static Path test = Paths.get("test"); + static String sep = + FileSystems.getDefault().getSeparator(); + static List parts = + Arrays.asList("foo", "bar", "baz", "bag"); + static Path makeVariant() { + Collections.rotate(parts, 1); + return Paths.get("test", String.join(sep, parts)); + } + static void refreshTestDir() throws Exception { + if(Files.exists(test)) + RmDir.rmdir(test); + if(!Files.exists(test)) + Files.createDirectory(test); + } + public static void + main(String[] args) throws Exception { + refreshTestDir(); + Files.createFile(test.resolve("Hello.txt")); + Path variant = makeVariant(); + // Throws exception (too many levels): + try { + Files.createDirectory(variant); + } catch(Exception e) { + System.out.println("Nope, that doesn't work."); + } + populateTestDir(); + Path tempdir = + Files.createTempDirectory(test, "DIR_"); + Files.createTempFile(tempdir, "pre", ".non"); + Files.newDirectoryStream(test) + .forEach(System.out::println); + System.out.println("*********"); + Files.walk(test).forEach(System.out::println); + } + static void populateTestDir() throws Exception { + for(int i = 0; i < parts.size(); i++) { + Path variant = makeVariant(); + if(!Files.exists(variant)) { + Files.createDirectories(variant); + Files.copy(Paths.get("Directories.java"), + variant.resolve("File.txt")); + Files.createTempFile(variant, null, null); + } + } + } +} +/* Output: +Nope, that doesn't work. +test\bag +test\bar +test\baz +test\DIR_5142667942049986036 +test\foo +test\Hello.txt +********* +test +test\bag +test\bag\foo +test\bag\foo\bar +test\bag\foo\bar\baz +test\bag\foo\bar\baz\8279660869874696036.tmp +test\bag\foo\bar\baz\File.txt +test\bar +test\bar\baz +test\bar\baz\bag +test\bar\baz\bag\foo +test\bar\baz\bag\foo\1274043134240426261.tmp +test\bar\baz\bag\foo\File.txt +test\baz +test\baz\bag +test\baz\bag\foo +test\baz\bag\foo\bar +test\baz\bag\foo\bar\6130572530014544105.tmp +test\baz\bag\foo\bar\File.txt +test\DIR_5142667942049986036 +test\DIR_5142667942049986036\pre7704286843227113253.non +test\foo +test\foo\bar +test\foo\bar\baz +test\foo\bar\baz\bag +test\foo\bar\baz\bag\5412864507741775436.tmp +test\foo\bar\baz\bag\File.txt +test\Hello.txt +*/ diff --git a/code/files/FileSystemDemo.java b/code/files/FileSystemDemo.java new file mode 100644 index 00000000..3d9024ca --- /dev/null +++ b/code/files/FileSystemDemo.java @@ -0,0 +1,41 @@ +// files/FileSystemDemo.java +// (c)2020 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. +import java.nio.file.*; + +public class FileSystemDemo { + static void show(String id, Object o) { + System.out.println(id + ": " + o); + } + public static void main(String[] args) { + System.out.println(System.getProperty("os.name")); + FileSystem fsys = FileSystems.getDefault(); + for(FileStore fs : fsys.getFileStores()) + show("File Store", fs); + for(Path rd : fsys.getRootDirectories()) + show("Root Directory", rd); + show("Separator", fsys.getSeparator()); + show("UserPrincipalLookupService", + fsys.getUserPrincipalLookupService()); + show("isOpen", fsys.isOpen()); + show("isReadOnly", fsys.isReadOnly()); + show("FileSystemProvider", fsys.provider()); + show("File Attribute Views", + fsys.supportedFileAttributeViews()); + } +} +/* Output: +Windows 10 +File Store: SSD (C:) +Root Directory: C:\ +Root Directory: D:\ +Separator: \ +UserPrincipalLookupService: +sun.nio.fs.WindowsFileSystem$LookupService$1@15db9742 +isOpen: true +isReadOnly: false +FileSystemProvider: +sun.nio.fs.WindowsFileSystemProvider@6d06d69c +File Attribute Views: [owner, dos, acl, basic, user] +*/ diff --git a/code/files/Find.java b/code/files/Find.java new file mode 100644 index 00000000..ac97ebdc --- /dev/null +++ b/code/files/Find.java @@ -0,0 +1,60 @@ +// files/Find.java +// (c)2020 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. +// {ExcludeFromGradle} +import java.nio.file.*; + +public class Find { + public static void + main(String[] args) throws Exception { + Path test = Paths.get("test"); + Directories.refreshTestDir(); + Directories.populateTestDir(); + // Creating a *directory*, not a file: + Files.createDirectory(test.resolve("dir.tmp")); + + PathMatcher matcher = FileSystems.getDefault() + .getPathMatcher("glob:**/*.{tmp,txt}"); + Files.walk(test) + .filter(matcher::matches) + .forEach(System.out::println); + System.out.println("***************"); + + PathMatcher matcher2 = FileSystems.getDefault() + .getPathMatcher("glob:*.tmp"); + Files.walk(test) + .map(Path::getFileName) + .filter(matcher2::matches) + .forEach(System.out::println); + System.out.println("***************"); + + Files.walk(test) // Only look for files + .filter(Files::isRegularFile) + .map(Path::getFileName) + .filter(matcher2::matches) + .forEach(System.out::println); + } +} +/* Output: +test\bag\foo\bar\baz\5208762845883213974.tmp +test\bag\foo\bar\baz\File.txt +test\bar\baz\bag\foo\7918367201207778677.tmp +test\bar\baz\bag\foo\File.txt +test\baz\bag\foo\bar\8016595521026696632.tmp +test\baz\bag\foo\bar\File.txt +test\dir.tmp +test\foo\bar\baz\bag\5832319279813617280.tmp +test\foo\bar\baz\bag\File.txt +*************** +5208762845883213974.tmp +7918367201207778677.tmp +8016595521026696632.tmp +dir.tmp +5832319279813617280.tmp +*************** +5208762845883213974.tmp +7918367201207778677.tmp +8016595521026696632.tmp +5832319279813617280.tmp +*/ diff --git a/code/files/ListOfLines.java b/code/files/ListOfLines.java new file mode 100644 index 00000000..6f9ef467 --- /dev/null +++ b/code/files/ListOfLines.java @@ -0,0 +1,26 @@ +// files/ListOfLines.java +// (c)2020 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. +import java.util.*; +import java.nio.file.*; + +public class ListOfLines { + public static void + main(String[] args) throws Exception { + Files.readAllLines( + Paths.get("../streams/Cheese.dat")) + .stream() + .filter(line -> !line.startsWith("//")) + .map(line -> + line.substring(0, line.length()/2)) + .forEach(System.out::println); + } +} +/* Output: +Not much of a cheese +Finest in the +And what leads you +Well, it's +It's certainly uncon +*/ diff --git a/code/files/PartsOfPaths.java b/code/files/PartsOfPaths.java new file mode 100644 index 00000000..1170fc68 --- /dev/null +++ b/code/files/PartsOfPaths.java @@ -0,0 +1,45 @@ +// files/PartsOfPaths.java +// (c)2020 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. +import java.nio.file.*; + +public class PartsOfPaths { + public static void main(String[] args) { + System.out.println(System.getProperty("os.name")); + Path p = + Paths.get("PartsOfPaths.java").toAbsolutePath(); + for(int i = 0; i < p.getNameCount(); i++) + System.out.println(p.getName(i)); + System.out.println("ends with '.java': " + + p.endsWith(".java")); + for(Path pp : p) { + System.out.print(pp + ": "); + System.out.print(p.startsWith(pp) + " : "); + System.out.println(p.endsWith(pp)); + } + System.out.println("Starts with " + p.getRoot() + + " " + p.startsWith(p.getRoot())); + } +} +/* Output: +Windows 10 +Users +Bruce +Documents +GitHub +on-java +ExtractedExamples +files +PartsOfPaths.java +ends with '.java': false +Users: false : false +Bruce: false : false +Documents: false : false +GitHub: false : false +on-java: false : false +ExtractedExamples: false : false +files: false : false +PartsOfPaths.java: false : true +Starts with C:\ true +*/ diff --git a/code/files/PathAnalysis.java b/code/files/PathAnalysis.java new file mode 100644 index 00000000..117119cd --- /dev/null +++ b/code/files/PathAnalysis.java @@ -0,0 +1,56 @@ +// files/PathAnalysis.java +// (c)2020 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. +import java.nio.file.*; +import java.io.IOException; + +public class PathAnalysis { + static void say(String id, Object result) { + System.out.print(id + ": "); + System.out.println(result); + } + public static void + main(String[] args) throws IOException { + System.out.println(System.getProperty("os.name")); + Path p = + Paths.get("PathAnalysis.java").toAbsolutePath(); + say("Exists", Files.exists(p)); + say("Directory", Files.isDirectory(p)); + say("Executable", Files.isExecutable(p)); + say("Readable", Files.isReadable(p)); + say("RegularFile", Files.isRegularFile(p)); + say("Writable", Files.isWritable(p)); + say("notExists", Files.notExists(p)); + say("Hidden", Files.isHidden(p)); + say("size", Files.size(p)); + say("FileStore", Files.getFileStore(p)); + say("LastModified: ", Files.getLastModifiedTime(p)); + say("Owner", Files.getOwner(p)); + say("ContentType", Files.probeContentType(p)); + say("SymbolicLink", Files.isSymbolicLink(p)); + if(Files.isSymbolicLink(p)) + say("SymbolicLink", Files.readSymbolicLink(p)); + if(FileSystems.getDefault() + .supportedFileAttributeViews().contains("posix")) + say("PosixFilePermissions", + Files.getPosixFilePermissions(p)); + } +} +/* Output: +Windows 10 +Exists: true +Directory: false +Executable: true +Readable: true +RegularFile: true +Writable: true +notExists: false +Hidden: false +size: 1631 +FileStore: SSD (C:) +LastModified: : 2017-05-09T12:07:00.428366Z +Owner: MINDVIEWTOSHIBA\Bruce (User) +ContentType: null +SymbolicLink: false +*/ diff --git a/code/files/PathInfo.java b/code/files/PathInfo.java new file mode 100644 index 00000000..96af9d93 --- /dev/null +++ b/code/files/PathInfo.java @@ -0,0 +1,102 @@ +// files/PathInfo.java +// (c)2020 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. +import java.nio.file.*; +import java.net.URI; +import java.io.File; +import java.io.IOException; + +public class PathInfo { + static void show(String id, Object p) { + System.out.println(id + ": " + p); + } + static void info(Path p) { + show("toString", p); + show("Exists", Files.exists(p)); + show("RegularFile", Files.isRegularFile(p)); + show("Directory", Files.isDirectory(p)); + show("Absolute", p.isAbsolute()); + show("FileName", p.getFileName()); + show("Parent", p.getParent()); + show("Root", p.getRoot()); + System.out.println("******************"); + } + public static void main(String[] args) { + System.out.println(System.getProperty("os.name")); + info(Paths.get( + "C:", "path", "to", "nowhere", "NoFile.txt")); + Path p = Paths.get("PathInfo.java"); + info(p); + Path ap = p.toAbsolutePath(); + info(ap); + info(ap.getParent()); + try { + info(p.toRealPath()); + } catch(IOException e) { + System.out.println(e); + } + URI u = p.toUri(); + System.out.println("URI: " + u); + Path puri = Paths.get(u); + System.out.println(Files.exists(puri)); + File f = ap.toFile(); // Don't be fooled + } +} +/* Output: +Windows 10 +toString: C:\path\to\nowhere\NoFile.txt +Exists: false +RegularFile: false +Directory: false +Absolute: true +FileName: NoFile.txt +Parent: C:\path\to\nowhere +Root: C:\ +****************** +toString: PathInfo.java +Exists: true +RegularFile: true +Directory: false +Absolute: false +FileName: PathInfo.java +Parent: null +Root: null +****************** +toString: C:\Users\Bruce\Documents\GitHub\on- +java\ExtractedExamples\files\PathInfo.java +Exists: true +RegularFile: true +Directory: false +Absolute: true +FileName: PathInfo.java +Parent: C:\Users\Bruce\Documents\GitHub\on- +java\ExtractedExamples\files +Root: C:\ +****************** +toString: C:\Users\Bruce\Documents\GitHub\on- +java\ExtractedExamples\files +Exists: true +RegularFile: false +Directory: true +Absolute: true +FileName: files +Parent: C:\Users\Bruce\Documents\GitHub\on- +java\ExtractedExamples +Root: C:\ +****************** +toString: C:\Users\Bruce\Documents\GitHub\on- +java\ExtractedExamples\files\PathInfo.java +Exists: true +RegularFile: true +Directory: false +Absolute: true +FileName: PathInfo.java +Parent: C:\Users\Bruce\Documents\GitHub\on- +java\ExtractedExamples\files +Root: C:\ +****************** +URI: file:///C:/Users/Bruce/Documents/GitHub/on- +java/ExtractedExamples/files/PathInfo.java +true +*/ diff --git a/code/files/PathWatcher.java b/code/files/PathWatcher.java new file mode 100644 index 00000000..162641d7 --- /dev/null +++ b/code/files/PathWatcher.java @@ -0,0 +1,61 @@ +// files/PathWatcher.java +// (c)2020 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. +// {ExcludeFromGradle} +import java.io.IOException; +import java.nio.file.*; +import static java.nio.file.StandardWatchEventKinds.*; +import java.util.concurrent.*; + +public class PathWatcher { + static Path test = Paths.get("test"); + static void delTxtFiles() { + try { + Files.walk(test) + .filter(f -> + f.toString().endsWith(".txt")) + .forEach(f -> { + try { + System.out.println("deleting " + f); + Files.delete(f); + } catch(IOException e) { + throw new RuntimeException(e); + } + }); + } catch(IOException e) { + throw new RuntimeException(e); + } + } + public static void + main(String[] args) throws Exception { + Directories.refreshTestDir(); + Directories.populateTestDir(); + Files.createFile(test.resolve("Hello.txt")); + WatchService watcher = + FileSystems.getDefault().newWatchService(); + test.register(watcher, ENTRY_DELETE); + Executors.newSingleThreadScheduledExecutor() + .schedule( + PathWatcher::delTxtFiles, + 250, TimeUnit.MILLISECONDS); + WatchKey key = watcher.take(); + for(WatchEvent evt : key.pollEvents()) { + System.out.println( + "evt.context(): " + evt.context() + + "\nevt.count(): " + evt.count() + + "\nevt.kind(): " + evt.kind()); + System.exit(0); + } + } +} +/* Output: +deleting test\bag\foo\bar\baz\File.txt +deleting test\bar\baz\bag\foo\File.txt +deleting test\baz\bag\foo\bar\File.txt +deleting test\foo\bar\baz\bag\File.txt +deleting test\Hello.txt +evt.context(): Hello.txt +evt.count(): 1 +evt.kind(): ENTRY_DELETE +*/ diff --git a/code/files/ReadLineStream.java b/code/files/ReadLineStream.java new file mode 100644 index 00000000..64b0f562 --- /dev/null +++ b/code/files/ReadLineStream.java @@ -0,0 +1,18 @@ +// files/ReadLineStream.java +// (c)2020 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. +import java.nio.file.*; + +public class ReadLineStream { + public static void + main(String[] args) throws Exception { + Files.lines(Paths.get("PathInfo.java")) + .skip(13) + .findFirst() + .ifPresent(System.out::println); + } +} +/* Output: + show("RegularFile", Files.isRegularFile(p)); +*/ diff --git a/code/files/StreamInAndOut.java b/code/files/StreamInAndOut.java new file mode 100644 index 00000000..ec17c700 --- /dev/null +++ b/code/files/StreamInAndOut.java @@ -0,0 +1,24 @@ +// files/StreamInAndOut.java +// (c)2020 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. +import java.io.*; +import java.nio.file.*; +import java.util.stream.*; + +public class StreamInAndOut { + public static void main(String[] args) { + try( + Stream input = + Files.lines(Paths.get("StreamInAndOut.java")); + PrintWriter output = + new PrintWriter("StreamInAndOut.txt") + ) { + input + .map(String::toUpperCase) + .forEachOrdered(output::println); + } catch(Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/code/files/TreeWatcher.java b/code/files/TreeWatcher.java new file mode 100644 index 00000000..f0660888 --- /dev/null +++ b/code/files/TreeWatcher.java @@ -0,0 +1,51 @@ +// files/TreeWatcher.java +// (c)2020 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. +// {ExcludeFromGradle} +import java.io.IOException; +import java.nio.file.*; +import static java.nio.file.StandardWatchEventKinds.*; +import java.util.concurrent.*; + +public class TreeWatcher { + static void watchDir(Path dir) { + try { + WatchService watcher = + FileSystems.getDefault().newWatchService(); + dir.register(watcher, ENTRY_DELETE); + Executors.newSingleThreadExecutor().submit(() -> { + try { + WatchKey key = watcher.take(); + for(WatchEvent evt : key.pollEvents()) { + System.out.println( + "evt.context(): " + evt.context() + + "\nevt.count(): " + evt.count() + + "\nevt.kind(): " + evt.kind()); + System.exit(0); + } + } catch(InterruptedException e) { + return; + } + }); + } catch(IOException e) { + throw new RuntimeException(e); + } + } + public static void + main(String[] args) throws Exception { + Directories.refreshTestDir(); + Directories.populateTestDir(); + Files.walk(Paths.get("test")) + .filter(Files::isDirectory) + .forEach(TreeWatcher::watchDir); + PathWatcher.delTxtFiles(); + } +} +/* Output: +deleting test\bag\foo\bar\baz\File.txt +deleting test\bar\baz\bag\foo\File.txt +evt.context(): File.txt +evt.count(): 1 +evt.kind(): ENTRY_DELETE +*/ diff --git a/code/files/Writing.java b/code/files/Writing.java new file mode 100644 index 00000000..68a04fbc --- /dev/null +++ b/code/files/Writing.java @@ -0,0 +1,31 @@ +// files/Writing.java +// (c)2020 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. +import java.util.*; +import java.nio.file.*; + +public class Writing { + static Random rand = new Random(47); + static final int SIZE = 1000; + public static void + main(String[] args) throws Exception { + // Write bytes to a file: + byte[] bytes = new byte[SIZE]; + rand.nextBytes(bytes); + Files.write(Paths.get("bytes.dat"), bytes); + System.out.println("bytes.dat: " + + Files.size(Paths.get("bytes.dat"))); + + // Write an iterable to a file: + List lines = Files.readAllLines( + Paths.get("../streams/Cheese.dat")); + Files.write(Paths.get("Cheese.txt"), lines); + System.out.println("Cheese.txt: " + + Files.size(Paths.get("Cheese.txt"))); + } +} +/* Output: +bytes.dat: 1000 +Cheese.txt: 199 +*/ diff --git a/code/functional/AnonymousClosure.java b/code/functional/AnonymousClosure.java new file mode 100644 index 00000000..497a1a52 --- /dev/null +++ b/code/functional/AnonymousClosure.java @@ -0,0 +1,17 @@ +// functional/AnonymousClosure.java +// (c)2020 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. +import java.util.function.*; + +public class AnonymousClosure { + IntSupplier makeFun(int x) { + int i = 0; + // Same rules apply: + // i++; // Not "effectively final" + // x++; // Ditto + return new IntSupplier() { + public int getAsInt() { return x + i; } + }; + } +} diff --git a/code/functional/BiConsumerPermutations.java b/code/functional/BiConsumerPermutations.java new file mode 100644 index 00000000..75b7c32d --- /dev/null +++ b/code/functional/BiConsumerPermutations.java @@ -0,0 +1,24 @@ +// functional/BiConsumerPermutations.java +// (c)2020 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. +import java.util.function.*; + +public class BiConsumerPermutations { + static BiConsumer bicid = (i, d) -> + System.out.format("%d, %f%n", i, d); + static BiConsumer bicdi = (d, i) -> + System.out.format("%d, %f%n", i, d); + static BiConsumer bicil = (i, l) -> + System.out.format("%d, %d%n", i, l); + public static void main(String[] args) { + bicid.accept(47, 11.34); + bicdi.accept(22.45, 92); + bicil.accept(1, 11L); + } +} +/* Output: +47, 11.340000 +92, 22.450000 +1, 11 +*/ diff --git a/code/functional/ClassFunctionals.java b/code/functional/ClassFunctionals.java new file mode 100644 index 00000000..e5101df4 --- /dev/null +++ b/code/functional/ClassFunctionals.java @@ -0,0 +1,45 @@ +// functional/ClassFunctionals.java +// (c)2020 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. +import java.util.*; +import java.util.function.*; + +class AA {} +class BB {} +class CC {} + +public class ClassFunctionals { + static AA f1() { return new AA(); } + static int f2(AA aa1, AA aa2) { return 1; } + static void f3(AA aa) {} + static void f4(AA aa, BB bb) {} + static CC f5(AA aa) { return new CC(); } + static CC f6(AA aa, BB bb) { return new CC(); } + static boolean f7(AA aa) { return true; } + static boolean f8(AA aa, BB bb) { return true; } + static AA f9(AA aa) { return new AA(); } + static AA f10(AA aa1, AA aa2) { return new AA(); } + public static void main(String[] args) { + Supplier s = ClassFunctionals::f1; + s.get(); + Comparator c = ClassFunctionals::f2; + c.compare(new AA(), new AA()); + Consumer cons = ClassFunctionals::f3; + cons.accept(new AA()); + BiConsumer bicons = ClassFunctionals::f4; + bicons.accept(new AA(), new BB()); + Function f = ClassFunctionals::f5; + CC cc = f.apply(new AA()); + BiFunction bif = ClassFunctionals::f6; + cc = bif.apply(new AA(), new BB()); + Predicate p = ClassFunctionals::f7; + boolean result = p.test(new AA()); + BiPredicate bip = ClassFunctionals::f8; + result = bip.test(new AA(), new BB()); + UnaryOperator uo = ClassFunctionals::f9; + AA aa = uo.apply(new AA()); + BinaryOperator bo = ClassFunctionals::f10; + aa = bo.apply(new AA(), new AA()); + } +} diff --git a/code/functional/Closure1.java b/code/functional/Closure1.java new file mode 100644 index 00000000..2f504f42 --- /dev/null +++ b/code/functional/Closure1.java @@ -0,0 +1,12 @@ +// functional/Closure1.java +// (c)2020 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. +import java.util.function.*; + +public class Closure1 { + int i; + IntSupplier makeFun(int x) { + return () -> x + i++; + } +} diff --git a/code/functional/Closure2.java b/code/functional/Closure2.java new file mode 100644 index 00000000..825cf423 --- /dev/null +++ b/code/functional/Closure2.java @@ -0,0 +1,12 @@ +// functional/Closure2.java +// (c)2020 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. +import java.util.function.*; + +public class Closure2 { + IntSupplier makeFun(int x) { + int i = 0; + return () -> x + i; + } +} diff --git a/code/functional/Closure3.java b/code/functional/Closure3.java new file mode 100644 index 00000000..811179fb --- /dev/null +++ b/code/functional/Closure3.java @@ -0,0 +1,14 @@ +// functional/Closure3.java +// (c)2020 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. +// {WillNotCompile} +import java.util.function.*; + +public class Closure3 { + IntSupplier makeFun(int x) { + int i = 0; + // Neither x++ nor i++ will work: + return () -> x++ + i++; + } +} diff --git a/code/functional/Closure4.java b/code/functional/Closure4.java new file mode 100644 index 00000000..148aaf64 --- /dev/null +++ b/code/functional/Closure4.java @@ -0,0 +1,12 @@ +// functional/Closure4.java +// (c)2020 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. +import java.util.function.*; + +public class Closure4 { + IntSupplier makeFun(final int x) { + final int i = 0; + return () -> x + i; + } +} diff --git a/code/functional/Closure5.java b/code/functional/Closure5.java new file mode 100644 index 00000000..fb9aad77 --- /dev/null +++ b/code/functional/Closure5.java @@ -0,0 +1,15 @@ +// functional/Closure5.java +// (c)2020 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. +// {WillNotCompile} +import java.util.function.*; + +public class Closure5 { + IntSupplier makeFun(int x) { + int i = 0; + i++; + x++; + return () -> x + i; + } +} diff --git a/code/functional/Closure6.java b/code/functional/Closure6.java new file mode 100644 index 00000000..178f9b4a --- /dev/null +++ b/code/functional/Closure6.java @@ -0,0 +1,16 @@ +// functional/Closure6.java +// (c)2020 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. +import java.util.function.*; + +public class Closure6 { + IntSupplier makeFun(int x) { + int i = 0; + i++; + x++; + final int iFinal = i; + final int xFinal = x; + return () -> xFinal + iFinal; + } +} diff --git a/code/functional/Closure7.java b/code/functional/Closure7.java new file mode 100644 index 00000000..9facdc06 --- /dev/null +++ b/code/functional/Closure7.java @@ -0,0 +1,14 @@ +// functional/Closure7.java +// (c)2020 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. +// {WillNotCompile} +import java.util.function.*; + +public class Closure7 { + IntSupplier makeFun(int x) { + Integer i = 0; + i = i + 1; + return () -> x + i; + } +} diff --git a/code/functional/Closure8.java b/code/functional/Closure8.java new file mode 100644 index 00000000..7ec059b2 --- /dev/null +++ b/code/functional/Closure8.java @@ -0,0 +1,32 @@ +// functional/Closure8.java +// (c)2020 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. +import java.util.*; +import java.util.function.*; + +public class Closure8 { + Supplier> makeFun() { + final List ai = new ArrayList<>(); + ai.add(1); + return () -> ai; + } + public static void main(String[] args) { + Closure8 c7 = new Closure8(); + List + l1 = c7.makeFun().get(), + l2 = c7.makeFun().get(); + System.out.println(l1); + System.out.println(l2); + l1.add(42); + l2.add(96); + System.out.println(l1); + System.out.println(l2); + } +} +/* Output: +[1] +[1] +[1, 42] +[1, 96] +*/ diff --git a/code/functional/Closure9.java b/code/functional/Closure9.java new file mode 100644 index 00000000..4eddb47a --- /dev/null +++ b/code/functional/Closure9.java @@ -0,0 +1,15 @@ +// functional/Closure9.java +// (c)2020 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. +// {WillNotCompile} +import java.util.*; +import java.util.function.*; + +public class Closure9 { + Supplier> makeFun() { + List ai = new ArrayList<>(); + ai = new ArrayList<>(); // Reassignment + return () -> ai; + } +} diff --git a/code/functional/ConsumeFunction.java b/code/functional/ConsumeFunction.java new file mode 100644 index 00000000..ea84a24a --- /dev/null +++ b/code/functional/ConsumeFunction.java @@ -0,0 +1,17 @@ +// functional/ConsumeFunction.java +// (c)2020 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. +import java.util.function.*; + +class One {} +class Two {} + +public class ConsumeFunction { + static Two consume(Function onetwo) { + return onetwo.apply(new One()); + } + public static void main(String[] args) { + Two two = consume(one -> new Two()); + } +} diff --git a/code/functional/CtorReference.java b/code/functional/CtorReference.java new file mode 100644 index 00000000..4c22bdf1 --- /dev/null +++ b/code/functional/CtorReference.java @@ -0,0 +1,36 @@ +// functional/CtorReference.java +// (c)2020 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. + +class Dog { + String name; + int age = -1; // For "unknown" + Dog() { name = "stray"; } + Dog(String nm) { name = nm; } + Dog(String nm, int yrs) { name = nm; age = yrs; } +} + +interface MakeNoArgs { + Dog make(); +} + +interface Make1Arg { + Dog make(String nm); +} + +interface Make2Args { + Dog make(String nm, int age); +} + +public class CtorReference { + public static void main(String[] args) { + MakeNoArgs mna = Dog::new; // [1] + Make1Arg m1a = Dog::new; // [2] + Make2Args m2a = Dog::new; // [3] + + Dog dn = mna.make(); + Dog d1 = m1a.make("Comet"); + Dog d2 = m2a.make("Ralph", 4); + } +} diff --git a/code/functional/CurriedIntAdd.java b/code/functional/CurriedIntAdd.java new file mode 100644 index 00000000..e89ac8e2 --- /dev/null +++ b/code/functional/CurriedIntAdd.java @@ -0,0 +1,17 @@ +// functional/CurriedIntAdd.java +// (c)2020 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. +import java.util.function.*; + +public class CurriedIntAdd { + public static void main(String[] args) { + IntFunction + curriedIntAdd = a -> b -> a + b; + IntUnaryOperator add4 = curriedIntAdd.apply(4); + System.out.println(add4.applyAsInt(5)); + } +} +/* Output: +9 +*/ diff --git a/code/functional/Curry3Args.java b/code/functional/Curry3Args.java new file mode 100644 index 00000000..0fd376bc --- /dev/null +++ b/code/functional/Curry3Args.java @@ -0,0 +1,23 @@ +// functional/Curry3Args.java +// (c)2020 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. +import java.util.function.*; + +public class Curry3Args { + public static void main(String[] args) { + Function>> sum = + a -> b -> c -> a + b + c; + Function> hi = + sum.apply("Hi "); + Function ho = + hi.apply("Ho "); + System.out.println(ho.apply("Hup")); + } +} +/* Output: +Hi Ho Hup +*/ diff --git a/code/functional/CurryingAndPartials.java b/code/functional/CurryingAndPartials.java new file mode 100644 index 00000000..0addb811 --- /dev/null +++ b/code/functional/CurryingAndPartials.java @@ -0,0 +1,35 @@ +// functional/CurryingAndPartials.java +// (c)2020 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. +import java.util.function.*; + +public class CurryingAndPartials { + // Uncurried: + static String uncurried(String a, String b) { + return a + b; + } + public static void main(String[] args) { + // Curried function: + Function> sum = + a -> b -> a + b; // [1] + + System.out.println(uncurried("Hi ", "Ho")); + + Function + hi = sum.apply("Hi "); // [2] + System.out.println(hi.apply("Ho")); + + // Partial application: + Function sumHi = + sum.apply("Hup "); + System.out.println(sumHi.apply("Ho")); + System.out.println(sumHi.apply("Hey")); + } +} +/* Output: +Hi Ho +Hi Ho +Hup Ho +Hup Hey +*/ diff --git a/code/functional/FunctionComposition.java b/code/functional/FunctionComposition.java new file mode 100644 index 00000000..a183039d --- /dev/null +++ b/code/functional/FunctionComposition.java @@ -0,0 +1,24 @@ +// functional/FunctionComposition.java +// (c)2020 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. +import java.util.function.*; + +public class FunctionComposition { + static Function + f1 = s -> { + System.out.println(s); + return s.replace('A', '_'); + }, + f2 = s -> s.substring(3), + f3 = s -> s.toLowerCase(), + f4 = f1.compose(f2).andThen(f3); + public static void main(String[] args) { + System.out.println( + f4.apply("GO AFTER ALL AMBULANCES")); + } +} +/* Output: +AFTER ALL AMBULANCES +_fter _ll _mbul_nces +*/ diff --git a/code/functional/FunctionVariants.java b/code/functional/FunctionVariants.java new file mode 100644 index 00000000..a6205462 --- /dev/null +++ b/code/functional/FunctionVariants.java @@ -0,0 +1,65 @@ +// functional/FunctionVariants.java +// (c)2020 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. +import java.util.function.*; + +class Foo {} + +class Bar { + Foo f; + Bar(Foo f) { this.f = f; } +} + +class IBaz { + int i; + IBaz(int i) { + this.i = i; + } +} + +class LBaz { + long l; + LBaz(long l) { + this.l = l; + } +} + +class DBaz { + double d; + DBaz(double d) { + this.d = d; + } +} + +public class FunctionVariants { + static Function f1 = f -> new Bar(f); + static IntFunction f2 = i -> new IBaz(i); + static LongFunction f3 = l -> new LBaz(l); + static DoubleFunction f4 = d -> new DBaz(d); + static ToIntFunction f5 = ib -> ib.i; + static ToLongFunction f6 = lb -> lb.l; + static ToDoubleFunction f7 = db -> db.d; + static IntToLongFunction f8 = i -> i; + static IntToDoubleFunction f9 = i -> i; + static LongToIntFunction f10 = l -> (int)l; + static LongToDoubleFunction f11 = l -> l; + static DoubleToIntFunction f12 = d -> (int)d; + static DoubleToLongFunction f13 = d -> (long)d; + + public static void main(String[] args) { + Bar b = f1.apply(new Foo()); + IBaz ib = f2.apply(11); + LBaz lb = f3.apply(11); + DBaz db = f4.apply(11); + int i = f5.applyAsInt(ib); + long l = f6.applyAsLong(lb); + double d = f7.applyAsDouble(db); + l = f8.applyAsLong(12); + d = f9.applyAsDouble(12); + i = f10.applyAsInt(12); + d = f11.applyAsDouble(12); + i = f12.applyAsInt(13.0); + l = f13.applyAsLong(13.0); + } +} diff --git a/code/functional/FunctionWithWrapped.java b/code/functional/FunctionWithWrapped.java new file mode 100644 index 00000000..b654da65 --- /dev/null +++ b/code/functional/FunctionWithWrapped.java @@ -0,0 +1,12 @@ +// functional/FunctionWithWrapped.java +// (c)2020 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. +import java.util.function.*; + +public class FunctionWithWrapped { + public static void main(String[] args) { + Function fid = i -> (double)i; + IntToDoubleFunction fid2 = i -> i; + } +} diff --git a/code/functional/FunctionalAnnotation.java b/code/functional/FunctionalAnnotation.java new file mode 100644 index 00000000..84cec649 --- /dev/null +++ b/code/functional/FunctionalAnnotation.java @@ -0,0 +1,40 @@ +// functional/FunctionalAnnotation.java +// (c)2020 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. + +@FunctionalInterface +interface Functional { + String goodbye(String arg); +} + +interface FunctionalNoAnn { + String goodbye(String arg); +} + +/* +@FunctionalInterface +interface NotFunctional { + String goodbye(String arg); + String hello(String arg); +} +Produces error message: +NotFunctional is not a functional interface +multiple non-overriding abstract methods +found in interface NotFunctional +*/ + +public class FunctionalAnnotation { + public String goodbye(String arg) { + return "Goodbye, " + arg; + } + public static void main(String[] args) { + FunctionalAnnotation fa = + new FunctionalAnnotation(); + Functional f = fa::goodbye; + FunctionalNoAnn fna = fa::goodbye; + // Functional fac = fa; // Incompatible + Functional fl = a -> "Goodbye, " + a; + FunctionalNoAnn fnal = a -> "Goodbye, " + a; + } +} diff --git a/code/functional/IntCall.java b/code/functional/IntCall.java new file mode 100644 index 00000000..a8256a00 --- /dev/null +++ b/code/functional/IntCall.java @@ -0,0 +1,8 @@ +// functional/IntCall.java +// (c)2020 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. + +interface IntCall { + int call(int arg); +} diff --git a/code/functional/LambdaExpressions.java b/code/functional/LambdaExpressions.java new file mode 100644 index 00000000..fe7e3acb --- /dev/null +++ b/code/functional/LambdaExpressions.java @@ -0,0 +1,48 @@ +// functional/LambdaExpressions.java +// (c)2020 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. + +interface Description { + String brief(); +} + +interface Body { + String detailed(String head); +} + +interface Multi { + String twoArg(String head, Double d); +} + +public class LambdaExpressions { + + static Body bod = h -> h + " No Parens!"; // [1] + + static Body bod2 = (h) -> h + " More details"; // [2] + + static Description desc = () -> "Short info"; // [3] + + static Multi mult = (h, n) -> h + n; // [4] + + static Description moreLines = () -> { // [5] + System.out.println("moreLines()"); + return "from moreLines()"; + }; + + public static void main(String[] args) { + System.out.println(bod.detailed("Oh!")); + System.out.println(bod2.detailed("Hi!")); + System.out.println(desc.brief()); + System.out.println(mult.twoArg("Pi! ", 3.14159)); + System.out.println(moreLines.brief()); + } +} +/* Output: +Oh! No Parens! +Hi! More details +Short info +Pi! 3.14159 +moreLines() +from moreLines() +*/ diff --git a/code/functional/MethodConversion.java b/code/functional/MethodConversion.java new file mode 100644 index 00000000..008ecfc0 --- /dev/null +++ b/code/functional/MethodConversion.java @@ -0,0 +1,31 @@ +// functional/MethodConversion.java +// (c)2020 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. +import java.util.function.*; + +class In1 {} +class In2 {} + +public class MethodConversion { + static void accept(In1 i1, In2 i2) { + System.out.println("accept()"); + } + static void someOtherName(In1 i1, In2 i2) { + System.out.println("someOtherName()"); + } + public static void main(String[] args) { + BiConsumer bic; + + bic = MethodConversion::accept; + bic.accept(new In1(), new In2()); + + bic = MethodConversion::someOtherName; + // bic.someOtherName(new In1(), new In2()); // Nope + bic.accept(new In1(), new In2()); + } +} +/* Output: +accept() +someOtherName() +*/ diff --git a/code/functional/MethodReferences.java b/code/functional/MethodReferences.java new file mode 100644 index 00000000..63bc365d --- /dev/null +++ b/code/functional/MethodReferences.java @@ -0,0 +1,53 @@ +// functional/MethodReferences.java +// (c)2020 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. +import java.util.*; + +interface Callable { // [1] + void call(String s); +} + +class Describe { + void show(String msg) { // [2] + System.out.println(msg); + } +} + +public class MethodReferences { + static void hello(String name) { // [3] + System.out.println("Hello, " + name); + } + static class Description { + String about; + Description(String desc) { about = desc; } + void help(String msg) { // [4] + System.out.println(about + " " + msg); + } + } + static class Helper { + static void assist(String msg) { // [5] + System.out.println(msg); + } + } + public static void main(String[] args) { + Describe d = new Describe(); + Callable c = d::show; // [6] + c.call("call()"); // [7] + + c = MethodReferences::hello; // [8] + c.call("Bob"); + + c = new Description("valuable")::help; // [9] + c.call("information"); + + c = Helper::assist; // [10] + c.call("Help!"); + } +} +/* Output: +call() +Hello, Bob +valuable information +Help! +*/ diff --git a/code/functional/MultiUnbound.java b/code/functional/MultiUnbound.java new file mode 100644 index 00000000..4209fb04 --- /dev/null +++ b/code/functional/MultiUnbound.java @@ -0,0 +1,36 @@ +// functional/MultiUnbound.java +// (c)2020 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. +// Unbound methods with multiple arguments + +class This { + void two(int i, double d) {} + void three(int i, double d, String s) {} + void four(int i, double d, String s, char c) {} +} + +interface TwoArgs { + void call2(This athis, int i, double d); +} + +interface ThreeArgs { + void call3(This athis, int i, double d, String s); +} + +interface FourArgs { + void call4( + This athis, int i, double d, String s, char c); +} + +public class MultiUnbound { + public static void main(String[] args) { + TwoArgs twoargs = This::two; + ThreeArgs threeargs = This::three; + FourArgs fourargs = This::four; + This athis = new This(); + twoargs.call2(athis, 11, 3.14); + threeargs.call3(athis, 11, 3.14, "Three"); + fourargs.call4(athis, 11, 3.14, "Four", 'Z'); + } +} diff --git a/code/functional/PredicateComposition.java b/code/functional/PredicateComposition.java new file mode 100644 index 00000000..f95bbcbd --- /dev/null +++ b/code/functional/PredicateComposition.java @@ -0,0 +1,23 @@ +// functional/PredicateComposition.java +// (c)2020 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. +import java.util.function.*; +import java.util.stream.*; + +public class PredicateComposition { + static Predicate + p1 = s -> s.contains("bar"), + p2 = s -> s.length() < 5, + p3 = s -> s.contains("foo"), + p4 = p1.negate().and(p2).or(p3); + public static void main(String[] args) { + Stream.of("bar", "foobar", "foobaz", "fongopuckey") + .filter(p4) + .forEach(System.out::println); + } +} +/* Output: +foobar +foobaz +*/ diff --git a/code/functional/ProduceFunction.java b/code/functional/ProduceFunction.java new file mode 100644 index 00000000..03471601 --- /dev/null +++ b/code/functional/ProduceFunction.java @@ -0,0 +1,21 @@ +// functional/ProduceFunction.java +// (c)2020 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. +import java.util.function.*; + +interface +FuncSS extends Function {} // [1] + +public class ProduceFunction { + static FuncSS produce() { + return s -> s.toLowerCase(); // [2] + } + public static void main(String[] args) { + FuncSS f = produce(); + System.out.println(f.apply("YELLING")); + } +} +/* Output: +yelling +*/ diff --git a/code/functional/RecursiveFactorial.java b/code/functional/RecursiveFactorial.java new file mode 100644 index 00000000..2d610441 --- /dev/null +++ b/code/functional/RecursiveFactorial.java @@ -0,0 +1,26 @@ +// functional/RecursiveFactorial.java +// (c)2020 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. + +public class RecursiveFactorial { + static IntCall fact; + public static void main(String[] args) { + fact = n -> n == 0 ? 1 : n * fact.call(n - 1); + for(int i = 0; i <= 10; i++) + System.out.println(fact.call(i)); + } +} +/* Output: +1 +1 +2 +6 +24 +120 +720 +5040 +40320 +362880 +3628800 +*/ diff --git a/code/functional/RecursiveFibonacci.java b/code/functional/RecursiveFibonacci.java new file mode 100644 index 00000000..9be43dc6 --- /dev/null +++ b/code/functional/RecursiveFibonacci.java @@ -0,0 +1,32 @@ +// functional/RecursiveFibonacci.java +// (c)2020 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. + +public class RecursiveFibonacci { + IntCall fib; + RecursiveFibonacci() { + fib = n -> n == 0 ? 0 : + n == 1 ? 1 : + fib.call(n - 1) + fib.call(n - 2); + } + int fibonacci(int n) { return fib.call(n); } + public static void main(String[] args) { + RecursiveFibonacci rf = new RecursiveFibonacci(); + for(int i = 0; i <= 10; i++) + System.out.println(rf.fibonacci(i)); + } +} +/* Output: +0 +1 +1 +2 +3 +5 +8 +13 +21 +34 +55 +*/ diff --git a/code/functional/RunnableMethodReference.java b/code/functional/RunnableMethodReference.java new file mode 100644 index 00000000..5fb8cd00 --- /dev/null +++ b/code/functional/RunnableMethodReference.java @@ -0,0 +1,33 @@ +// functional/RunnableMethodReference.java +// (c)2020 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. +// Method references with interface Runnable + +class Go { + static void go() { + System.out.println("Go::go()"); + } +} + +public class RunnableMethodReference { + public static void main(String[] args) { + + new Thread(new Runnable() { + public void run() { + System.out.println("Anonymous"); + } + }).start(); + + new Thread( + () -> System.out.println("lambda") + ).start(); + + new Thread(Go::go).start(); + } +} +/* Output: +Anonymous +lambda +Go::go() +*/ diff --git a/code/functional/SharedStorage.java b/code/functional/SharedStorage.java new file mode 100644 index 00000000..c2a41f66 --- /dev/null +++ b/code/functional/SharedStorage.java @@ -0,0 +1,22 @@ +// functional/SharedStorage.java +// (c)2020 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. +import java.util.function.*; + +public class SharedStorage { + public static void main(String[] args) { + Closure1 c1 = new Closure1(); + IntSupplier f1 = c1.makeFun(0); + IntSupplier f2 = c1.makeFun(0); + IntSupplier f3 = c1.makeFun(0); + System.out.println(f1.getAsInt()); + System.out.println(f2.getAsInt()); + System.out.println(f3.getAsInt()); + } +} +/* Output: +0 +1 +2 +*/ diff --git a/code/functional/Strategize.java b/code/functional/Strategize.java new file mode 100644 index 00000000..e46c9143 --- /dev/null +++ b/code/functional/Strategize.java @@ -0,0 +1,58 @@ +// functional/Strategize.java +// (c)2020 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. + +interface Strategy { + String approach(String msg); +} + +class Soft implements Strategy { + public String approach(String msg) { + return msg.toLowerCase() + "?"; + } +} + +class Unrelated { + static String twice(String msg) { + return msg + " " + msg; + } +} + +public class Strategize { + Strategy strategy; + String msg; + Strategize(String msg) { + strategy = new Soft(); // [1] + this.msg = msg; + } + void communicate() { + System.out.println(strategy.approach(msg)); + } + void changeStrategy(Strategy strategy) { + this.strategy = strategy; + } + public static void main(String[] args) { + Strategy[] strategies = { + new Strategy() { // [2] + public String approach(String msg) { + return msg.toUpperCase() + "!"; + } + }, + msg -> msg.substring(0, 5), // [3] + Unrelated::twice // [4] + }; + Strategize s = new Strategize("Hello there"); + s.communicate(); + for(Strategy newStrategy : strategies) { + s.changeStrategy(newStrategy); // [5] + s.communicate(); // [6] + } + } +} +/* Output: +hello there? +HELLO THERE! +Hello +Hello there Hello there +*/ diff --git a/code/functional/TransformFunction.java b/code/functional/TransformFunction.java new file mode 100644 index 00000000..1a046eb1 --- /dev/null +++ b/code/functional/TransformFunction.java @@ -0,0 +1,35 @@ +// functional/TransformFunction.java +// (c)2020 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. +import java.util.function.*; + +class I { + @Override + public String toString() { return "I"; } +} + +class O { + @Override + public String toString() { return "O"; } +} + +public class TransformFunction { + static Function transform(Function in) { + return in.andThen(o -> { + System.out.println(o); + return o; + }); + } + public static void main(String[] args) { + Function f2 = transform(i -> { + System.out.println(i); + return new O(); + }); + O o = f2.apply(new I()); + } +} +/* Output: +I +O +*/ diff --git a/code/functional/TriFunction.java b/code/functional/TriFunction.java new file mode 100644 index 00000000..76049621 --- /dev/null +++ b/code/functional/TriFunction.java @@ -0,0 +1,9 @@ +// functional/TriFunction.java +// (c)2020 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. + +@FunctionalInterface +public interface TriFunction { + R apply(T t, U u, V v); +} diff --git a/code/functional/TriFunctionTest.java b/code/functional/TriFunctionTest.java new file mode 100644 index 00000000..fccf8b9a --- /dev/null +++ b/code/functional/TriFunctionTest.java @@ -0,0 +1,13 @@ +// functional/TriFunctionTest.java +// (c)2020 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. + +public class TriFunctionTest { + static int f(int i, long l, double d) { return 99; } + public static void main(String[] args) { + TriFunction tf = + TriFunctionTest::f; + tf = (i, l, d) -> 12; + } +} diff --git a/code/functional/UnboundMethodReference.java b/code/functional/UnboundMethodReference.java new file mode 100644 index 00000000..da2c7872 --- /dev/null +++ b/code/functional/UnboundMethodReference.java @@ -0,0 +1,31 @@ +// functional/UnboundMethodReference.java +// (c)2020 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. +// Method reference without an object + +class X { + String f() { return "X::f()"; } +} + +interface MakeString { + String make(); +} + +interface TransformX { + String transform(X x); +} + +public class UnboundMethodReference { + public static void main(String[] args) { + // MakeString ms = X::f; // [1] + TransformX sp = X::f; + X x = new X(); + System.out.println(sp.transform(x)); // [2] + System.out.println(x.f()); // Same effect + } +} +/* Output: +X::f() +X::f() +*/ diff --git a/code/generics/Amphibian.java b/code/generics/Amphibian.java new file mode 100644 index 00000000..5e76d8b1 --- /dev/null +++ b/code/generics/Amphibian.java @@ -0,0 +1,5 @@ +// generics/Amphibian.java +// (c)2020 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. +public class Amphibian {} diff --git a/code/generics/Apply.java b/code/generics/Apply.java new file mode 100644 index 00000000..c9378611 --- /dev/null +++ b/code/generics/Apply.java @@ -0,0 +1,21 @@ +// generics/Apply.java +// (c)2020 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. +import java.lang.reflect.*; +import java.util.*; + +public class Apply { + public static > + void apply(S seq, Method f, Object... args) { + try { + for(T t: seq) + f.invoke(t, args); + } catch(IllegalAccessException | + IllegalArgumentException | + InvocationTargetException e) { + // Failures are programmer errors + throw new RuntimeException(e); + } + } +} diff --git a/code/generics/ApplyFunctional.java b/code/generics/ApplyFunctional.java new file mode 100644 index 00000000..4cce156e --- /dev/null +++ b/code/generics/ApplyFunctional.java @@ -0,0 +1,49 @@ +// generics/ApplyFunctional.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import java.util.function.*; +import onjava.*; + +public class ApplyFunctional { + public static void main(String[] args) { + Stream.of( + Stream.generate(Shape::new).limit(2), + Stream.generate(Square::new).limit(2)) + .flatMap(c -> c) // flatten into one stream + .peek(Shape::rotate) + .forEach(s -> s.resize(7)); + + new FilledList<>(Shape::new, 2) + .forEach(Shape::rotate); + new FilledList<>(Square::new, 2) + .forEach(Shape::rotate); + + SimpleQueue shapeQ = Suppliers.fill( + new SimpleQueue<>(), SimpleQueue::add, + Shape::new, 2); + Suppliers.fill(shapeQ, SimpleQueue::add, + Square::new, 2); + shapeQ.forEach(Shape::rotate); + } +} +/* Output: +Shape 0 rotate +Shape 0 resize 7 +Shape 1 rotate +Shape 1 resize 7 +Square 2 rotate +Square 2 resize 7 +Square 3 rotate +Square 3 resize 7 +Shape 4 rotate +Shape 5 rotate +Square 6 rotate +Square 7 rotate +Shape 8 rotate +Shape 9 rotate +Square 10 rotate +Square 11 rotate +*/ diff --git a/code/generics/ApplyTest.java b/code/generics/ApplyTest.java new file mode 100644 index 00000000..62ef4eec --- /dev/null +++ b/code/generics/ApplyTest.java @@ -0,0 +1,65 @@ +// generics/ApplyTest.java +// (c)2020 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. +import java.util.*; +import java.util.function.*; +import onjava.*; + +public class ApplyTest { + public static + void main(String[] args) throws Exception { + List shapes = + Suppliers.create(ArrayList::new, Shape::new, 3); + Apply.apply(shapes, + Shape.class.getMethod("rotate")); + Apply.apply(shapes, + Shape.class.getMethod("resize", int.class), 7); + + List squares = + Suppliers.create(ArrayList::new, Square::new, 3); + Apply.apply(squares, + Shape.class.getMethod("rotate")); + Apply.apply(squares, + Shape.class.getMethod("resize", int.class), 7); + + Apply.apply(new FilledList<>(Shape::new, 3), + Shape.class.getMethod("rotate")); + Apply.apply(new FilledList<>(Square::new, 3), + Shape.class.getMethod("rotate")); + + SimpleQueue shapeQ = Suppliers.fill( + new SimpleQueue<>(), SimpleQueue::add, + Shape::new, 3); + Suppliers.fill(shapeQ, SimpleQueue::add, + Square::new, 3); + Apply.apply(shapeQ, + Shape.class.getMethod("rotate")); + } +} +/* Output: +Shape 0 rotate +Shape 1 rotate +Shape 2 rotate +Shape 0 resize 7 +Shape 1 resize 7 +Shape 2 resize 7 +Square 3 rotate +Square 4 rotate +Square 5 rotate +Square 3 resize 7 +Square 4 resize 7 +Square 5 resize 7 +Shape 6 rotate +Shape 7 rotate +Shape 8 rotate +Square 9 rotate +Square 10 rotate +Square 11 rotate +Shape 12 rotate +Shape 13 rotate +Shape 14 rotate +Square 15 rotate +Square 16 rotate +Square 17 rotate +*/ diff --git a/code/generics/ArrayMaker.java b/code/generics/ArrayMaker.java new file mode 100644 index 00000000..f1bb6b9a --- /dev/null +++ b/code/generics/ArrayMaker.java @@ -0,0 +1,24 @@ +// generics/ArrayMaker.java +// (c)2020 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. +import java.lang.reflect.*; +import java.util.*; + +public class ArrayMaker { + private Class kind; + public ArrayMaker(Class kind) { this.kind = kind; } + @SuppressWarnings("unchecked") + T[] create(int size) { + return (T[])Array.newInstance(kind, size); + } + public static void main(String[] args) { + ArrayMaker stringMaker = + new ArrayMaker<>(String.class); + String[] stringArray = stringMaker.create(9); + System.out.println(Arrays.toString(stringArray)); + } +} +/* Output: +[null, null, null, null, null, null, null, null, null] +*/ diff --git a/code/generics/ArrayOfGeneric.java b/code/generics/ArrayOfGeneric.java new file mode 100644 index 00000000..67e6cb97 --- /dev/null +++ b/code/generics/ArrayOfGeneric.java @@ -0,0 +1,28 @@ +// generics/ArrayOfGeneric.java +// (c)2020 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. + +public class ArrayOfGeneric { + static final int SIZE = 100; + static Generic[] gia; + @SuppressWarnings("unchecked") + public static void main(String[] args) { + try { + gia = (Generic[])new Object[SIZE]; + } catch(ClassCastException e) { + System.out.println(e.getMessage()); + } + // Runtime type is the raw (erased) type: + gia = (Generic[])new Generic[SIZE]; + System.out.println(gia.getClass().getSimpleName()); + gia[0] = new Generic<>(); + //- gia[1] = new Object(); // Compile-time error + // Discovers type mismatch at compile time: + //- gia[2] = new Generic(); + } +} +/* Output: +[Ljava.lang.Object; cannot be cast to [LGeneric; +Generic[] +*/ diff --git a/code/generics/ArrayOfGenericReference.java b/code/generics/ArrayOfGenericReference.java new file mode 100644 index 00000000..1cb2f345 --- /dev/null +++ b/code/generics/ArrayOfGenericReference.java @@ -0,0 +1,10 @@ +// generics/ArrayOfGenericReference.java +// (c)2020 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. + +class Generic {} + +public class ArrayOfGenericReference { + static Generic[] gia; +} diff --git a/code/generics/BankTeller.java b/code/generics/BankTeller.java new file mode 100644 index 00000000..68301996 --- /dev/null +++ b/code/generics/BankTeller.java @@ -0,0 +1,71 @@ +// generics/BankTeller.java +// (c)2020 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. +// A very simple bank teller simulation +import java.util.*; +import onjava.*; + +class Customer { + private static long counter = 1; + private final long id = counter++; + @Override + public String toString() { + return "Customer " + id; + } +} + +class Teller { + private static long counter = 1; + private final long id = counter++; + @Override + public String toString() { + return "Teller " + id; + } +} + +class Bank { + private List tellers = + new ArrayList<>(); + public void put(BankTeller bt) { + tellers.add(bt); + } +} + +public class BankTeller { + public static void serve(Teller t, Customer c) { + System.out.println(t + " serves " + c); + } + public static void main(String[] args) { + // Demonstrate create(): + RandomList tellers = + Suppliers.create( + RandomList::new, Teller::new, 4); + // Demonstrate fill(): + List customers = Suppliers.fill( + new ArrayList<>(), Customer::new, 12); + customers.forEach(c -> + serve(tellers.select(), c)); + // Demonstrate assisted latent typing: + Bank bank = Suppliers.fill( + new Bank(), Bank::put, BankTeller::new, 3); + // Can also use second version of fill(): + List customers2 = Suppliers.fill( + new ArrayList<>(), + List::add, Customer::new, 12); + } +} +/* Output: +Teller 3 serves Customer 1 +Teller 2 serves Customer 2 +Teller 3 serves Customer 3 +Teller 1 serves Customer 4 +Teller 1 serves Customer 5 +Teller 3 serves Customer 6 +Teller 1 serves Customer 7 +Teller 2 serves Customer 8 +Teller 3 serves Customer 9 +Teller 3 serves Customer 10 +Teller 2 serves Customer 11 +Teller 4 serves Customer 12 +*/ diff --git a/code/generics/BasicBounds.java b/code/generics/BasicBounds.java new file mode 100644 index 00000000..434d0fd8 --- /dev/null +++ b/code/generics/BasicBounds.java @@ -0,0 +1,63 @@ +// generics/BasicBounds.java +// (c)2020 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. + +interface HasColor { java.awt.Color getColor(); } + +class WithColor { + T item; + WithColor(T item) { this.item = item; } + T getItem() { return item; } + // The bound allows you to call a method: + java.awt.Color color() { return item.getColor(); } +} + +class Coord { public int x, y, z; } + +// This fails. Class must be first, then interfaces: +// class WithColorCoord { + +// Multiple bounds: +class WithColorCoord { + T item; + WithColorCoord(T item) { this.item = item; } + T getItem() { return item; } + java.awt.Color color() { return item.getColor(); } + int getX() { return item.x; } + int getY() { return item.y; } + int getZ() { return item.z; } +} + +interface Weight { int weight(); } + +// As with inheritance, you can have only one +// concrete class but multiple interfaces: +class Solid { + T item; + Solid(T item) { this.item = item; } + T getItem() { return item; } + java.awt.Color color() { return item.getColor(); } + int getX() { return item.x; } + int getY() { return item.y; } + int getZ() { return item.z; } + int weight() { return item.weight(); } +} + +class Bounded +extends Coord implements HasColor, Weight { + @Override + public java.awt.Color getColor() { return null; } + @Override + public int weight() { return 0; } +} + +public class BasicBounds { + public static void main(String[] args) { + Solid solid = + new Solid<>(new Bounded()); + solid.color(); + solid.getY(); + solid.weight(); + } +} diff --git a/code/generics/BasicHolder.java b/code/generics/BasicHolder.java new file mode 100644 index 00000000..2b8b8a9b --- /dev/null +++ b/code/generics/BasicHolder.java @@ -0,0 +1,14 @@ +// generics/BasicHolder.java +// (c)2020 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. + +public class BasicHolder { + T element; + void set(T arg) { element = arg; } + T get() { return element; } + void f() { + System.out.println( + element.getClass().getSimpleName()); + } +} diff --git a/code/generics/BasicSupplierDemo.java b/code/generics/BasicSupplierDemo.java new file mode 100644 index 00000000..1ce95ca1 --- /dev/null +++ b/code/generics/BasicSupplierDemo.java @@ -0,0 +1,22 @@ +// generics/BasicSupplierDemo.java +// (c)2020 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. +import onjava.*; +import java.util.stream.*; + +public class BasicSupplierDemo { + public static void main(String[] args) { + Stream.generate( + BasicSupplier.create(CountedObject.class)) + .limit(5) + .forEach(System.out::println); + } +} +/* Output: +CountedObject 0 +CountedObject 1 +CountedObject 2 +CountedObject 3 +CountedObject 4 +*/ diff --git a/code/generics/ByteSet.java b/code/generics/ByteSet.java new file mode 100644 index 00000000..19b27091 --- /dev/null +++ b/code/generics/ByteSet.java @@ -0,0 +1,14 @@ +// generics/ByteSet.java +// (c)2020 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. +import java.util.*; + +public class ByteSet { + Byte[] possibles = { 1,2,3,4,5,6,7,8,9 }; + Set mySet = + new HashSet<>(Arrays.asList(possibles)); + // But you can't do this: + // Set mySet2 = new HashSet<>( + // Arrays.asList(1,2,3,4,5,6,7,8,9)); +} diff --git a/code/generics/CRGWithBasicHolder.java b/code/generics/CRGWithBasicHolder.java new file mode 100644 index 00000000..eb85868a --- /dev/null +++ b/code/generics/CRGWithBasicHolder.java @@ -0,0 +1,20 @@ +// generics/CRGWithBasicHolder.java +// (c)2020 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. + +class Subtype extends BasicHolder {} + +public class CRGWithBasicHolder { + public static void main(String[] args) { + Subtype + st1 = new Subtype(), + st2 = new Subtype(); + st1.set(st2); + Subtype st3 = st1.get(); + st1.f(); + } +} +/* Output: +Subtype +*/ diff --git a/code/generics/CaptureConversion.java b/code/generics/CaptureConversion.java new file mode 100644 index 00000000..16348468 --- /dev/null +++ b/code/generics/CaptureConversion.java @@ -0,0 +1,62 @@ +// generics/CaptureConversion.java +// (c)2020 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. + +public class CaptureConversion { + static void f1(Holder holder) { + T t = holder.get(); + System.out.println(t.getClass().getSimpleName()); + } + static void f2(Holder holder) { + f1(holder); // Call with captured type + } + @SuppressWarnings("unchecked") + public static void main(String[] args) { + Holder raw = new Holder<>(1); + + f1(raw); + // warning: [unchecked] unchecked method invocation: + // method f1 in class CaptureConversion + // is applied to given types + // f1(raw); + // ^ + // required: Holder + // found: Holder + // where T is a type-variable: + // T extends Object declared in + // method f1(Holder) + // warning: [unchecked] unchecked conversion + // f1(raw); + // ^ + // required: Holder + // found: Holder + // where T is a type-variable: + // T extends Object declared in + // method f1(Holder) + // 2 warnings + + f2(raw); // No warnings + Holder rawBasic = new Holder(); + + rawBasic.set(new Object()); + // warning: [unchecked] unchecked call to set(T) + // as a member of the raw type Holder + // rawBasic.set(new Object()); + // ^ + // where T is a type-variable: + // T extends Object declared in class Holder + // 1 warning + + f2(rawBasic); // No warnings + // Upcast to Holder, still figures it out: + Holder wildcarded = new Holder<>(1.0); + f2(wildcarded); + } +} +/* Output: +Integer +Integer +Object +Double +*/ diff --git a/code/generics/CheckedList.java b/code/generics/CheckedList.java new file mode 100644 index 00000000..6e330cf6 --- /dev/null +++ b/code/generics/CheckedList.java @@ -0,0 +1,35 @@ +// generics/CheckedList.java +// (c)2020 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. +// Using Collection.checkedList() +import typeinfo.pets.*; +import java.util.*; + +public class CheckedList { + @SuppressWarnings("unchecked") + static void oldStyleMethod(List probablyDogs) { + probablyDogs.add(new Cat()); + } + public static void main(String[] args) { + List dogs1 = new ArrayList<>(); + oldStyleMethod(dogs1); // Quietly accepts a Cat + List dogs2 = Collections.checkedList( + new ArrayList<>(), Dog.class); + try { + oldStyleMethod(dogs2); // Throws an exception + } catch(Exception e) { + System.out.println("Expected: " + e); + } + // Derived types work fine: + List pets = Collections.checkedList( + new ArrayList<>(), Pet.class); + pets.add(new Dog()); + pets.add(new Cat()); + } +} +/* Output: +Expected: java.lang.ClassCastException: Attempt to +insert class typeinfo.pets.Cat element into collection +with element type class typeinfo.pets.Dog +*/ diff --git a/code/generics/ClassCasting.java b/code/generics/ClassCasting.java new file mode 100644 index 00000000..c6da592a --- /dev/null +++ b/code/generics/ClassCasting.java @@ -0,0 +1,18 @@ +// generics/ClassCasting.java +// (c)2020 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. +import java.io.*; +import java.util.*; + +public class ClassCasting { + @SuppressWarnings("unchecked") + public void f(String[] args) throws Exception { + ObjectInputStream in = new ObjectInputStream( + new FileInputStream(args[0])); + // Won't Compile: +// List lw1 = +// List<>.class.cast(in.readObject()); + List lw2 = List.class.cast(in.readObject()); + } +} diff --git a/code/generics/ClassTypeCapture.java b/code/generics/ClassTypeCapture.java new file mode 100644 index 00000000..ab193dfe --- /dev/null +++ b/code/generics/ClassTypeCapture.java @@ -0,0 +1,33 @@ +// generics/ClassTypeCapture.java +// (c)2020 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. + +class Building {} +class House extends Building {} + +public class ClassTypeCapture { + Class kind; + public ClassTypeCapture(Class kind) { + this.kind = kind; + } + public boolean f(Object arg) { + return kind.isInstance(arg); + } + public static void main(String[] args) { + ClassTypeCapture ctt1 = + new ClassTypeCapture<>(Building.class); + System.out.println(ctt1.f(new Building())); + System.out.println(ctt1.f(new House())); + ClassTypeCapture ctt2 = + new ClassTypeCapture<>(House.class); + System.out.println(ctt2.f(new Building())); + System.out.println(ctt2.f(new House())); + } +} +/* Output: +true +true +false +true +*/ diff --git a/code/generics/ComparablePet.java b/code/generics/ComparablePet.java new file mode 100644 index 00000000..3646e66a --- /dev/null +++ b/code/generics/ComparablePet.java @@ -0,0 +1,12 @@ +// generics/ComparablePet.java +// (c)2020 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. + +public class ComparablePet +implements Comparable { + @Override + public int compareTo(ComparablePet arg) { + return 0; + } +} diff --git a/code/generics/CompilerIntelligence.java b/code/generics/CompilerIntelligence.java new file mode 100644 index 00000000..6e4cd0e8 --- /dev/null +++ b/code/generics/CompilerIntelligence.java @@ -0,0 +1,15 @@ +// generics/CompilerIntelligence.java +// (c)2020 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. +import java.util.*; + +public class CompilerIntelligence { + public static void main(String[] args) { + List flist = + Arrays.asList(new Apple()); + Apple a = (Apple)flist.get(0); // No warning + flist.contains(new Apple()); // Argument is 'Object' + flist.indexOf(new Apple()); // Argument is 'Object' + } +} diff --git a/code/generics/CountedObject.java b/code/generics/CountedObject.java new file mode 100644 index 00000000..ab4caecd --- /dev/null +++ b/code/generics/CountedObject.java @@ -0,0 +1,14 @@ +// generics/CountedObject.java +// (c)2020 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. + +public class CountedObject { + private static long counter = 0; + private final long id = counter++; + public long id() { return id; } + @Override + public String toString() { + return "CountedObject " + id; + } +} diff --git a/code/generics/CovariantArrays.java b/code/generics/CovariantArrays.java new file mode 100644 index 00000000..e202ca07 --- /dev/null +++ b/code/generics/CovariantArrays.java @@ -0,0 +1,30 @@ +// generics/CovariantArrays.java +// (c)2020 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. + +class Fruit {} +class Apple extends Fruit {} +class Jonathan extends Apple {} +class Orange extends Fruit {} + +public class CovariantArrays { + public static void main(String[] args) { + Fruit[] fruit = new Apple[10]; + fruit[0] = new Apple(); // OK + fruit[1] = new Jonathan(); // OK + // Runtime type is Apple[], not Fruit[] or Orange[]: + try { + // Compiler allows you to add Fruit: + fruit[0] = new Fruit(); // ArrayStoreException + } catch(Exception e) { System.out.println(e); } + try { + // Compiler allows you to add Oranges: + fruit[0] = new Orange(); // ArrayStoreException + } catch(Exception e) { System.out.println(e); } + } +} +/* Output: +java.lang.ArrayStoreException: Fruit +java.lang.ArrayStoreException: Orange +*/ diff --git a/code/generics/CovariantReturnTypes.java b/code/generics/CovariantReturnTypes.java new file mode 100644 index 00000000..04178ad4 --- /dev/null +++ b/code/generics/CovariantReturnTypes.java @@ -0,0 +1,23 @@ +// generics/CovariantReturnTypes.java +// (c)2020 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. + +class Base {} +class Derived extends Base {} + +interface OrdinaryGetter { + Base get(); +} + +interface DerivedGetter extends OrdinaryGetter { + // Overridden method return type can vary: + @Override + Derived get(); +} + +public class CovariantReturnTypes { + void test(DerivedGetter d) { + Derived d2 = d.get(); + } +} diff --git a/code/generics/CreatorGeneric.java b/code/generics/CreatorGeneric.java new file mode 100644 index 00000000..7fd90df4 --- /dev/null +++ b/code/generics/CreatorGeneric.java @@ -0,0 +1,31 @@ +// generics/CreatorGeneric.java +// (c)2020 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. + +abstract class GenericWithCreate { + final T element; + GenericWithCreate() { element = create(); } + abstract T create(); +} + +class X {} + +class XCreator extends GenericWithCreate { + @Override + X create() { return new X(); } + void f() { + System.out.println( + element.getClass().getSimpleName()); + } +} + +public class CreatorGeneric { + public static void main(String[] args) { + XCreator xc = new XCreator(); + xc.f(); + } +} +/* Output: +X +*/ diff --git a/code/generics/CuriouslyRecurringGeneric.java b/code/generics/CuriouslyRecurringGeneric.java new file mode 100644 index 00000000..ee1f3a61 --- /dev/null +++ b/code/generics/CuriouslyRecurringGeneric.java @@ -0,0 +1,9 @@ +// generics/CuriouslyRecurringGeneric.java +// (c)2020 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. + +class GenericType {} + +public class CuriouslyRecurringGeneric + extends GenericType {} diff --git a/code/generics/Diamond.java b/code/generics/Diamond.java new file mode 100644 index 00000000..32c3ff1a --- /dev/null +++ b/code/generics/Diamond.java @@ -0,0 +1,13 @@ +// generics/Diamond.java +// (c)2020 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. + +class Bob {} + +public class Diamond { + public static void main(String[] args) { + GenericHolder h3 = new GenericHolder<>(); + h3.set(new Bob()); + } +} diff --git a/code/generics/DogsAndRobotMethodReferences.java b/code/generics/DogsAndRobotMethodReferences.java new file mode 100644 index 00000000..7c3fa357 --- /dev/null +++ b/code/generics/DogsAndRobotMethodReferences.java @@ -0,0 +1,45 @@ +// generics/DogsAndRobotMethodReferences.java +// (c)2020 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. +// "Assisted Latent Typing" +import typeinfo.pets.*; +import java.util.function.*; + +class PerformingDogA extends Dog { + public void speak() { System.out.println("Woof!"); } + public void sit() { System.out.println("Sitting"); } + public void reproduce() {} +} + +class RobotA { + public void speak() { System.out.println("Click!"); } + public void sit() { System.out.println("Clank!"); } + public void oilChange() {} +} + +class CommunicateA { + public static

void perform(P performer, + Consumer

action1, Consumer

action2) { + action1.accept(performer); + action2.accept(performer); + } +} + +public class DogsAndRobotMethodReferences { + public static void main(String[] args) { + CommunicateA.perform(new PerformingDogA(), + PerformingDogA::speak, PerformingDogA::sit); + CommunicateA.perform(new RobotA(), + RobotA::speak, RobotA::sit); + CommunicateA.perform(new Mime(), + Mime::walkAgainstTheWind, + Mime::pushInvisibleWalls); + } +} +/* Output: +Woof! +Sitting +Click! +Clank! +*/ diff --git a/code/generics/DogsAndRobots.cpp b/code/generics/DogsAndRobots.cpp new file mode 100644 index 00000000..81ced5d9 --- /dev/null +++ b/code/generics/DogsAndRobots.cpp @@ -0,0 +1,38 @@ +// generics/DogsAndRobots.cpp +// (c)2020 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. +#include +using namespace std; + +class Dog { +public: + void speak() { cout << "Arf!" << endl; } + void sit() { cout << "Sitting" << endl; } + void reproduce() {} +}; + +class Robot { +public: + void speak() { cout << "Click!" << endl; } + void sit() { cout << "Clank!" << endl; } + void oilChange() {} +}; + +template void perform(T anything) { + anything.speak(); + anything.sit(); +} + +int main() { + Dog d; + Robot r; + perform(d); + perform(r); +} +/* Output: +Arf! +Sitting +Click! +Clank! +*/ diff --git a/code/generics/DogsAndRobots.java b/code/generics/DogsAndRobots.java new file mode 100644 index 00000000..b6151122 --- /dev/null +++ b/code/generics/DogsAndRobots.java @@ -0,0 +1,41 @@ +// generics/DogsAndRobots.java +// (c)2020 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. +// No (direct) latent typing in Java +import typeinfo.pets.*; + +class PerformingDog extends Dog implements Performs { + @Override + public void speak() { System.out.println("Woof!"); } + @Override + public void sit() { System.out.println("Sitting"); } + public void reproduce() {} +} + +class Robot implements Performs { + public void speak() { System.out.println("Click!"); } + public void sit() { System.out.println("Clank!"); } + public void oilChange() {} +} + +class Communicate { + public static + void perform(T performer) { + performer.speak(); + performer.sit(); + } +} + +public class DogsAndRobots { + public static void main(String[] args) { + Communicate.perform(new PerformingDog()); + Communicate.perform(new Robot()); + } +} +/* Output: +Woof! +Sitting +Click! +Clank! +*/ diff --git a/code/generics/DogsAndRobots.py b/code/generics/DogsAndRobots.py new file mode 100644 index 00000000..c9ca6fef --- /dev/null +++ b/code/generics/DogsAndRobots.py @@ -0,0 +1,36 @@ +# generics/DogsAndRobots.py +# (c)2020 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. + +class Dog: + def speak(self): + print("Arf!") + def sit(self): + print("Sitting") + def reproduce(self): + pass + +class Robot: + def speak(self): + print("Click!") + def sit(self): + print("Clank!") + def oilChange(self): + pass + +def perform(anything): + anything.speak() + anything.sit() + +a = Dog() +b = Robot() +perform(a) +perform(b) + +output = """ +Arf! +Sitting +Click! +Clank! +""" diff --git a/code/generics/DynamicProxyMixin.java b/code/generics/DynamicProxyMixin.java new file mode 100644 index 00000000..38431e31 --- /dev/null +++ b/code/generics/DynamicProxyMixin.java @@ -0,0 +1,66 @@ +// generics/DynamicProxyMixin.java +// (c)2020 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. +import java.lang.reflect.*; +import java.util.*; +import onjava.*; +import static onjava.Tuple.*; + +class MixinProxy implements InvocationHandler { + Map delegatesByMethod; + @SuppressWarnings("unchecked") + MixinProxy(Tuple2>... pairs) { + delegatesByMethod = new HashMap<>(); + for(Tuple2> pair : pairs) { + for(Method method : pair.a2.getMethods()) { + String methodName = method.getName(); + // The first interface in the map + // implements the method. + if(!delegatesByMethod.containsKey(methodName)) + delegatesByMethod.put(methodName, pair.a1); + } + } + } + @Override + public Object invoke(Object proxy, Method method, + Object[] args) throws Throwable { + String methodName = method.getName(); + Object delegate = delegatesByMethod.get(methodName); + return method.invoke(delegate, args); + } + @SuppressWarnings("unchecked") + public static Object newInstance(Tuple2... pairs) { + Class[] interfaces = new Class[pairs.length]; + for(int i = 0; i < pairs.length; i++) { + interfaces[i] = (Class)pairs[i].a2; + } + ClassLoader cl = + pairs[0].a1.getClass().getClassLoader(); + return Proxy.newProxyInstance( + cl, interfaces, new MixinProxy(pairs)); + } +} + +public class DynamicProxyMixin { + public static void main(String[] args) { + @SuppressWarnings("unchecked") + Object mixin = MixinProxy.newInstance( + tuple(new BasicImp(), Basic.class), + tuple(new TimeStampedImp(), TimeStamped.class), + tuple(new SerialNumberedImp(), + SerialNumbered.class)); + Basic b = (Basic)mixin; + TimeStamped t = (TimeStamped)mixin; + SerialNumbered s = (SerialNumbered)mixin; + b.set("Hello"); + System.out.println(b.get()); + System.out.println(t.getStamp()); + System.out.println(s.getSerialNumber()); + } +} +/* Output: +Hello +1494331653339 +1 +*/ diff --git a/code/generics/EpicBattle.java b/code/generics/EpicBattle.java new file mode 100644 index 00000000..908a3343 --- /dev/null +++ b/code/generics/EpicBattle.java @@ -0,0 +1,74 @@ +// generics/EpicBattle.java +// (c)2020 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. +// Bounds in Java generics +import java.util.*; + +interface SuperPower {} + +interface XRayVision extends SuperPower { + void seeThroughWalls(); +} + +interface SuperHearing extends SuperPower { + void hearSubtleNoises(); +} + +interface SuperSmell extends SuperPower { + void trackBySmell(); +} + +class SuperHero { + POWER power; + SuperHero(POWER power) { this.power = power; } + POWER getPower() { return power; } +} + +class SuperSleuth +extends SuperHero { + SuperSleuth(POWER power) { super(power); } + void see() { power.seeThroughWalls(); } +} + +class +CanineHero +extends SuperHero { + CanineHero(POWER power) { super(power); } + void hear() { power.hearSubtleNoises(); } + void smell() { power.trackBySmell(); } +} + +class SuperHearSmell +implements SuperHearing, SuperSmell { + @Override + public void hearSubtleNoises() {} + @Override + public void trackBySmell() {} +} + +class DogPerson extends CanineHero { + DogPerson() { super(new SuperHearSmell()); } +} + +public class EpicBattle { + // Bounds in generic methods: + static + void useSuperHearing(SuperHero hero) { + hero.getPower().hearSubtleNoises(); + } + static + void superFind(SuperHero hero) { + hero.getPower().hearSubtleNoises(); + hero.getPower().trackBySmell(); + } + public static void main(String[] args) { + DogPerson dogPerson = new DogPerson(); + useSuperHearing(dogPerson); + superFind(dogPerson); + // You can do this: + List audioPeople; + // But you can't do this: + // List dogPs; + } +} diff --git a/code/generics/Erased.java b/code/generics/Erased.java new file mode 100644 index 00000000..911839c3 --- /dev/null +++ b/code/generics/Erased.java @@ -0,0 +1,24 @@ +// generics/Erased.java +// (c)2020 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. +// {WillNotCompile} + +public class Erased { + private final int SIZE = 100; + public void f(Object arg) { + + // error: illegal generic type for instanceof + if(arg instanceof T) {} + + // error: unexpected type + T var = new T(); + + // error: generic array creation + T[] array = new T[SIZE]; + + // warning: [unchecked] unchecked cast + T[] array = (T[])new Object[SIZE]; + + } +} diff --git a/code/generics/ErasedTypeEquivalence.java b/code/generics/ErasedTypeEquivalence.java new file mode 100644 index 00000000..6034b304 --- /dev/null +++ b/code/generics/ErasedTypeEquivalence.java @@ -0,0 +1,16 @@ +// generics/ErasedTypeEquivalence.java +// (c)2020 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. +import java.util.*; + +public class ErasedTypeEquivalence { + public static void main(String[] args) { + Class c1 = new ArrayList().getClass(); + Class c2 = new ArrayList().getClass(); + System.out.println(c1 == c2); + } +} +/* Output: +true +*/ diff --git a/code/generics/ErasureAndInheritance.java b/code/generics/ErasureAndInheritance.java new file mode 100644 index 00000000..44a07b62 --- /dev/null +++ b/code/generics/ErasureAndInheritance.java @@ -0,0 +1,28 @@ +// generics/ErasureAndInheritance.java +// (c)2020 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. + +class GenericBase { + private T element; + public void set(T arg) { element = arg; } + public T get() { return element; } +} + +class Derived1 extends GenericBase {} + +class Derived2 extends GenericBase {} // No warning + +// class Derived3 extends GenericBase {} +// Strange error: +// unexpected type +// required: class or interface without bounds + +public class ErasureAndInheritance { + @SuppressWarnings("unchecked") + public static void main(String[] args) { + Derived2 d2 = new Derived2(); + Object obj = d2.get(); + d2.set(obj); // Warning here! + } +} diff --git a/code/generics/FactoryConstraint.java b/code/generics/FactoryConstraint.java new file mode 100644 index 00000000..f0651073 --- /dev/null +++ b/code/generics/FactoryConstraint.java @@ -0,0 +1,62 @@ +// generics/FactoryConstraint.java +// (c)2020 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. +import java.util.*; +import java.util.function.*; +import onjava.*; + +class IntegerFactory implements Supplier { + private int i = 0; + @Override + public Integer get() { + return ++i; + } +} + +class Widget { + private int id; + Widget(int n) { id = n; } + @Override + public String toString() { + return "Widget " + id; + } + public static + class Factory implements Supplier { + private int i = 0; + @Override + public Widget get() { return new Widget(++i); } + } +} + +class Fudge { + private static int count = 1; + private int n = count++; + @Override + public String toString() { return "Fudge " + n; } +} + +class Foo2 { + private List x = new ArrayList<>(); + Foo2(Supplier factory) { + Suppliers.fill(x, factory, 5); + } + @Override + public String toString() { return x.toString(); } +} + +public class FactoryConstraint { + public static void main(String[] args) { + System.out.println( + new Foo2<>(new IntegerFactory())); + System.out.println( + new Foo2<>(new Widget.Factory())); + System.out.println( + new Foo2<>(Fudge::new)); + } +} +/* Output: +[1, 2, 3, 4, 5] +[Widget 1, Widget 2, Widget 3, Widget 4, Widget 5] +[Fudge 1, Fudge 2, Fudge 3, Fudge 4, Fudge 5] +*/ diff --git a/code/generics/Fibonacci.java b/code/generics/Fibonacci.java new file mode 100644 index 00000000..11540061 --- /dev/null +++ b/code/generics/Fibonacci.java @@ -0,0 +1,27 @@ +// generics/Fibonacci.java +// (c)2020 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. +// Generate a Fibonacci sequence +import java.util.function.*; +import java.util.stream.*; + +public class Fibonacci implements Supplier { + private int count = 0; + @Override + public Integer get() { return fib(count++); } + private int fib(int n) { + if(n < 2) return 1; + return fib(n-2) + fib(n-1); + } + public static void main(String[] args) { + Stream.generate(new Fibonacci()) + .limit(18) + .map(n -> n + " ") + .forEach(System.out::print); + } +} +/* Output: +1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 +2584 +*/ diff --git a/code/generics/FilledList.java b/code/generics/FilledList.java new file mode 100644 index 00000000..e24423ce --- /dev/null +++ b/code/generics/FilledList.java @@ -0,0 +1,28 @@ +// generics/FilledList.java +// (c)2020 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. +import java.util.*; +import java.util.function.*; +import onjava.*; + +public class FilledList extends ArrayList { + FilledList(Supplier gen, int size) { + Suppliers.fill(this, gen, size); + } + public FilledList(T t, int size) { + for(int i = 0; i < size; i++) + this.add(t); + } + public static void main(String[] args) { + List list = new FilledList<>("Hello", 4); + System.out.println(list); + // Supplier version: + List ilist = new FilledList<>(() -> 47, 4); + System.out.println(ilist); + } +} +/* Output: +[Hello, Hello, Hello, Hello] +[47, 47, 47, 47] +*/ diff --git a/code/generics/GenericArray.java b/code/generics/GenericArray.java new file mode 100644 index 00000000..f0ffba3d --- /dev/null +++ b/code/generics/GenericArray.java @@ -0,0 +1,32 @@ +// generics/GenericArray.java +// (c)2020 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. + +public class GenericArray { + private T[] array; + @SuppressWarnings("unchecked") + public GenericArray(int sz) { + array = (T[])new Object[sz]; + } + public void put(int index, T item) { + array[index] = item; + } + public T get(int index) { return array[index]; } + // Method that exposes the underlying representation: + public T[] rep() { return array; } + public static void main(String[] args) { + GenericArray gai = new GenericArray<>(10); + try { + Integer[] ia = gai.rep(); + } catch(ClassCastException e) { + System.out.println(e.getMessage()); + } + // This is OK: + Object[] oa = gai.rep(); + } +} +/* Output: +[Ljava.lang.Object; cannot be cast to +[Ljava.lang.Integer; +*/ diff --git a/code/generics/GenericArray2.java b/code/generics/GenericArray2.java new file mode 100644 index 00000000..7ef4179e --- /dev/null +++ b/code/generics/GenericArray2.java @@ -0,0 +1,39 @@ +// generics/GenericArray2.java +// (c)2020 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. + +public class GenericArray2 { + private Object[] array; + public GenericArray2(int sz) { + array = new Object[sz]; + } + public void put(int index, T item) { + array[index] = item; + } + @SuppressWarnings("unchecked") + public T get(int index) { return (T)array[index]; } + @SuppressWarnings("unchecked") + public T[] rep() { + return (T[])array; // Unchecked cast + } + public static void main(String[] args) { + GenericArray2 gai = + new GenericArray2<>(10); + for(int i = 0; i < 10; i ++) + gai.put(i, i); + for(int i = 0; i < 10; i ++) + System.out.print(gai.get(i) + " "); + System.out.println(); + try { + Integer[] ia = gai.rep(); + } catch(Exception e) { + System.out.println(e); + } + } +} +/* Output: +0 1 2 3 4 5 6 7 8 9 +java.lang.ClassCastException: [Ljava.lang.Object; +cannot be cast to [Ljava.lang.Integer; +*/ diff --git a/code/generics/GenericArrayWithTypeToken.java b/code/generics/GenericArrayWithTypeToken.java new file mode 100644 index 00000000..6ea36a76 --- /dev/null +++ b/code/generics/GenericArrayWithTypeToken.java @@ -0,0 +1,27 @@ +// generics/GenericArrayWithTypeToken.java +// (c)2020 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. +import java.lang.reflect.*; + +public class GenericArrayWithTypeToken { + private T[] array; + @SuppressWarnings("unchecked") + public + GenericArrayWithTypeToken(Class type, int sz) { + array = (T[])Array.newInstance(type, sz); + } + public void put(int index, T item) { + array[index] = item; + } + public T get(int index) { return array[index]; } + // Expose the underlying representation: + public T[] rep() { return array; } + public static void main(String[] args) { + GenericArrayWithTypeToken gai = + new GenericArrayWithTypeToken<>( + Integer.class, 10); + // This now works: + Integer[] ia = gai.rep(); + } +} diff --git a/code/generics/GenericCast.java b/code/generics/GenericCast.java new file mode 100644 index 00000000..c3f82dac --- /dev/null +++ b/code/generics/GenericCast.java @@ -0,0 +1,47 @@ +// generics/GenericCast.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; + +class FixedSizeStack { + private final int size; + private Object[] storage; + private int index = 0; + FixedSizeStack(int size) { + this.size = size; + storage = new Object[size]; + } + public void push(T item) { + if(index < size) + storage[index++] = item; + } + @SuppressWarnings("unchecked") + public T pop() { + return index == 0 ? null : (T)storage[--index]; + } + @SuppressWarnings("unchecked") + Stream stream() { + return (Stream)Arrays.stream(storage); + } +} + +public class GenericCast { + static String[] letters = + "ABCDEFGHIJKLMNOPQRS".split(""); + public static void main(String[] args) { + FixedSizeStack strings = + new FixedSizeStack<>(letters.length); + Arrays.stream("ABCDEFGHIJKLMNOPQRS".split("")) + .forEach(strings::push); + System.out.println(strings.pop()); + strings.stream() + .map(s -> s + " ") + .forEach(System.out::print); + } +} +/* Output: +S +A B C D E F G H I J K L M N O P Q R S +*/ diff --git a/code/generics/GenericHolder.java b/code/generics/GenericHolder.java new file mode 100644 index 00000000..6d998a1c --- /dev/null +++ b/code/generics/GenericHolder.java @@ -0,0 +1,19 @@ +// generics/GenericHolder.java +// (c)2020 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. + +public class GenericHolder { + private T a; + public GenericHolder() {} + public void set(T a) { this.a = a; } + public T get() { return a; } + public static void main(String[] args) { + GenericHolder h3 = + new GenericHolder(); + h3.set(new Automobile()); // type checked + Automobile a = h3.get(); // No cast needed + //- h3.set("Not an Automobile"); // Error + //- h3.set(1); // Error + } +} diff --git a/code/generics/GenericHolder2.java b/code/generics/GenericHolder2.java new file mode 100644 index 00000000..9747f49b --- /dev/null +++ b/code/generics/GenericHolder2.java @@ -0,0 +1,16 @@ +// generics/GenericHolder2.java +// (c)2020 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. + +public class GenericHolder2 { + private T obj; + public void set(T obj) { this.obj = obj; } + public T get() { return obj; } + public static void main(String[] args) { + GenericHolder2 holder = + new GenericHolder2<>(); + holder.set("Item"); + String s = holder.get(); + } +} diff --git a/code/generics/GenericMethods.java b/code/generics/GenericMethods.java new file mode 100644 index 00000000..66f40e72 --- /dev/null +++ b/code/generics/GenericMethods.java @@ -0,0 +1,27 @@ +// generics/GenericMethods.java +// (c)2020 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. + +public class GenericMethods { + public void f(T x) { + System.out.println(x.getClass().getName()); + } + public static void main(String[] args) { + GenericMethods gm = new GenericMethods(); + gm.f(""); + gm.f(1); + gm.f(1.0); + gm.f(1.0F); + gm.f('c'); + gm.f(gm); + } +} +/* Output: +java.lang.String +java.lang.Integer +java.lang.Double +java.lang.Float +java.lang.Character +GenericMethods +*/ diff --git a/code/generics/GenericReading.java b/code/generics/GenericReading.java new file mode 100644 index 00000000..5709c7a9 --- /dev/null +++ b/code/generics/GenericReading.java @@ -0,0 +1,46 @@ +// generics/GenericReading.java +// (c)2020 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. +import java.util.*; + +public class GenericReading { + static List apples = + Arrays.asList(new Apple()); + static List fruit = Arrays.asList(new Fruit()); + static T readExact(List list) { + return list.get(0); + } + // A static method adapts to each call: + static void f1() { + Apple a = readExact(apples); + Fruit f = readExact(fruit); + f = readExact(apples); + } + // A class type is established + // when the class is instantiated: + static class Reader { + T readExact(List list) { return list.get(0); } + } + static void f2() { + Reader fruitReader = new Reader<>(); + Fruit f = fruitReader.readExact(fruit); + //- Fruit a = fruitReader.readExact(apples); + // error: incompatible types: List + // cannot be converted to List + } + static class CovariantReader { + T readCovariant(List list) { + return list.get(0); + } + } + static void f3() { + CovariantReader fruitReader = + new CovariantReader<>(); + Fruit f = fruitReader.readCovariant(fruit); + Fruit a = fruitReader.readCovariant(apples); + } + public static void main(String[] args) { + f1(); f2(); f3(); + } +} diff --git a/code/generics/GenericVarargs.java b/code/generics/GenericVarargs.java new file mode 100644 index 00000000..3a6e348c --- /dev/null +++ b/code/generics/GenericVarargs.java @@ -0,0 +1,30 @@ +// generics/GenericVarargs.java +// (c)2020 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. +import java.util.*; + +public class GenericVarargs { + @SafeVarargs + public static List makeList(T... args) { + List result = new ArrayList<>(); + for(T item : args) + result.add(item); + return result; + } + public static void main(String[] args) { + List ls = makeList("A"); + System.out.println(ls); + ls = makeList("A", "B", "C"); + System.out.println(ls); + ls = makeList( + "ABCDEFFHIJKLMNOPQRSTUVWXYZ".split("")); + System.out.println(ls); + } +} +/* Output: +[A] +[A, B, C] +[A, B, C, D, E, F, F, H, I, J, K, L, M, N, O, P, Q, R, +S, T, U, V, W, X, Y, Z] +*/ diff --git a/code/generics/GenericsAndCovariance.java b/code/generics/GenericsAndCovariance.java new file mode 100644 index 00000000..f16b837b --- /dev/null +++ b/code/generics/GenericsAndCovariance.java @@ -0,0 +1,19 @@ +// generics/GenericsAndCovariance.java +// (c)2020 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. +import java.util.*; + +public class GenericsAndCovariance { + public static void main(String[] args) { + // Wildcards allow covariance: + List flist = new ArrayList<>(); + // Compile Error: can't add any type of object: + // flist.add(new Apple()); + // flist.add(new Fruit()); + // flist.add(new Object()); + flist.add(null); // Legal but uninteresting + // We know it returns at least Fruit: + Fruit f = flist.get(0); + } +} diff --git a/code/generics/GenericsAndReturnTypes.java b/code/generics/GenericsAndReturnTypes.java new file mode 100644 index 00000000..de661864 --- /dev/null +++ b/code/generics/GenericsAndReturnTypes.java @@ -0,0 +1,17 @@ +// generics/GenericsAndReturnTypes.java +// (c)2020 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. + +interface GenericGetter> { + T get(); +} + +interface Getter extends GenericGetter {} + +public class GenericsAndReturnTypes { + void test(Getter g) { + Getter result = g.get(); + GenericGetter gg = g.get(); // Also the base type + } +} diff --git a/code/generics/HasF.java b/code/generics/HasF.java new file mode 100644 index 00000000..f967386e --- /dev/null +++ b/code/generics/HasF.java @@ -0,0 +1,10 @@ +// generics/HasF.java +// (c)2020 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. + +public class HasF { + public void f() { + System.out.println("HasF.f()"); + } +} diff --git a/code/generics/HijackedInterface.java b/code/generics/HijackedInterface.java new file mode 100644 index 00000000..868e1d46 --- /dev/null +++ b/code/generics/HijackedInterface.java @@ -0,0 +1,16 @@ +// generics/HijackedInterface.java +// (c)2020 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. +// {WillNotCompile} + +class Cat + extends ComparablePet implements Comparable{ + // error: Comparable cannot be inherited with + // different arguments: and + // class Cat + // ^ + // 1 error + + public int compareTo(Cat arg) { return 0; } +} diff --git a/code/generics/Holder.java b/code/generics/Holder.java new file mode 100644 index 00000000..e4301dc6 --- /dev/null +++ b/code/generics/Holder.java @@ -0,0 +1,42 @@ +// generics/Holder.java +// (c)2020 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. +import java.util.Objects; + +public class Holder { + private T value; + public Holder() {} + public Holder(T val) { value = val; } + public void set(T val) { value = val; } + public T get() { return value; } + @Override + public boolean equals(Object o) { + return o instanceof Holder && + Objects.equals(value, ((Holder)o).value); + } + @Override + public int hashCode() { + return Objects.hashCode(value); + } + public static void main(String[] args) { + Holder apple = new Holder<>(new Apple()); + Apple d = apple.get(); + apple.set(d); + // Holder Fruit = apple; // Cannot upcast + Holder fruit = apple; // OK + Fruit p = fruit.get(); + d = (Apple)fruit.get(); // Returns 'Object' + try { + Orange c = (Orange)fruit.get(); // No warning + } catch(Exception e) { System.out.println(e); } + // fruit.set(new Apple()); // Cannot call set() + // fruit.set(new Fruit()); // Cannot call set() + System.out.println(fruit.equals(d)); // OK + } +} +/* Output: +java.lang.ClassCastException: Apple cannot be cast to +Orange +false +*/ diff --git a/code/generics/Holder1.java b/code/generics/Holder1.java new file mode 100644 index 00000000..0c222cb5 --- /dev/null +++ b/code/generics/Holder1.java @@ -0,0 +1,12 @@ +// generics/Holder1.java +// (c)2020 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. + +class Automobile {} + +public class Holder1 { + private Automobile a; + public Holder1(Automobile a) { this.a = a; } + Automobile get() { return a; } +} diff --git a/code/generics/InheritBounds.java b/code/generics/InheritBounds.java new file mode 100644 index 00000000..fddd2543 --- /dev/null +++ b/code/generics/InheritBounds.java @@ -0,0 +1,40 @@ +// generics/InheritBounds.java +// (c)2020 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. + +class HoldItem { + T item; + HoldItem(T item) { this.item = item; } + T getItem() { return item; } +} + +class WithColor2 +extends HoldItem { + WithColor2(T item) { super(item); } + java.awt.Color color() { return item.getColor(); } +} + +class WithColorCoord2 +extends WithColor2 { + WithColorCoord2(T item) { super(item); } + int getX() { return item.x; } + int getY() { return item.y; } + int getZ() { return item.z; } +} + +class Solid2 +extends WithColorCoord2 { + Solid2(T item) { super(item); } + int weight() { return item.weight(); } +} + +public class InheritBounds { + public static void main(String[] args) { + Solid2 solid2 = + new Solid2<>(new Bounded()); + solid2.color(); + solid2.getY(); + solid2.weight(); + } +} diff --git a/code/generics/InstantiateGenericType.cpp b/code/generics/InstantiateGenericType.cpp new file mode 100644 index 00000000..1799d05b --- /dev/null +++ b/code/generics/InstantiateGenericType.cpp @@ -0,0 +1,20 @@ +// generics/InstantiateGenericType.cpp +// (c)2020 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. +// C++, not Java! + +template class Foo { + T x; // Create a field of type T + T* y; // Pointer to T +public: + // Initialize the pointer: + Foo() { y = new T(); } +}; + +class Bar {}; + +int main() { + Foo fb; + Foo fi; // ... and it works with primitives +} diff --git a/code/generics/InstantiateGenericType.java b/code/generics/InstantiateGenericType.java new file mode 100644 index 00000000..9424c9a1 --- /dev/null +++ b/code/generics/InstantiateGenericType.java @@ -0,0 +1,46 @@ +// generics/InstantiateGenericType.java +// (c)2020 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. +import java.util.function.*; +import java.lang.reflect.InvocationTargetException; + +class ClassAsFactory implements Supplier { + Class kind; + ClassAsFactory(Class kind) { + this.kind = kind; + } + @SuppressWarnings("deprecation") + @Override + public T get() { + try { + return kind.newInstance(); + } catch(Exception e) { + throw new RuntimeException(e); + } + } +} + +class Employee { + @Override + public String toString() { return "Employee"; } +} + +public class InstantiateGenericType { + public static void main(String[] args) { + ClassAsFactory fe = + new ClassAsFactory<>(Employee.class); + System.out.println(fe.get()); + ClassAsFactory fi = + new ClassAsFactory<>(Integer.class); + try { + System.out.println(fi.get()); + } catch(Exception e) { + System.out.println(e.getMessage()); + } + } +} +/* Output: +Employee +java.lang.InstantiationException: java.lang.Integer +*/ diff --git a/code/generics/IterableFibonacci.java b/code/generics/IterableFibonacci.java new file mode 100644 index 00000000..b5ccf285 --- /dev/null +++ b/code/generics/IterableFibonacci.java @@ -0,0 +1,36 @@ +// generics/IterableFibonacci.java +// (c)2020 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. +// Adapt the Fibonacci class to make it Iterable +import java.util.*; + +public class IterableFibonacci +extends Fibonacci implements Iterable { + private int n; + public IterableFibonacci(int count) { n = count; } + @Override + public Iterator iterator() { + return new Iterator() { + @Override + public boolean hasNext() { return n > 0; } + @Override + public Integer next() { + n--; + return IterableFibonacci.this.get(); + } + @Override + public void remove() { // Not implemented + throw new UnsupportedOperationException(); + } + }; + } + public static void main(String[] args) { + for(int i : new IterableFibonacci(18)) + System.out.print(i + " "); + } +} +/* Output: +1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 +2584 +*/ diff --git a/code/generics/LatentReflection.java b/code/generics/LatentReflection.java new file mode 100644 index 00000000..0e9511a3 --- /dev/null +++ b/code/generics/LatentReflection.java @@ -0,0 +1,65 @@ +// generics/LatentReflection.java +// (c)2020 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. +// Using reflection for latent typing +import java.lang.reflect.*; + +// Does not implement Performs: +class Mime { + public void walkAgainstTheWind() {} + public void sit() { + System.out.println("Pretending to sit"); + } + public void pushInvisibleWalls() {} + @Override + public String toString() { return "Mime"; } +} + +// Does not implement Performs: +class SmartDog { + public void speak() { System.out.println("Woof!"); } + public void sit() { System.out.println("Sitting"); } + public void reproduce() {} +} + +class CommunicateReflectively { + public static void perform(Object speaker) { + Class spkr = speaker.getClass(); + try { + try { + Method speak = spkr.getMethod("speak"); + speak.invoke(speaker); + } catch(NoSuchMethodException e) { + System.out.println(speaker + " cannot speak"); + } + try { + Method sit = spkr.getMethod("sit"); + sit.invoke(speaker); + } catch(NoSuchMethodException e) { + System.out.println(speaker + " cannot sit"); + } + } catch(SecurityException | + IllegalAccessException | + IllegalArgumentException | + InvocationTargetException e) { + throw new RuntimeException(speaker.toString(), e); + } + } +} + +public class LatentReflection { + public static void main(String[] args) { + CommunicateReflectively.perform(new SmartDog()); + CommunicateReflectively.perform(new Robot()); + CommunicateReflectively.perform(new Mime()); + } +} +/* Output: +Woof! +Sitting +Click! +Clank! +Mime cannot speak +Pretending to sit +*/ diff --git a/code/generics/LinkedStack.java b/code/generics/LinkedStack.java new file mode 100644 index 00000000..5142bcc7 --- /dev/null +++ b/code/generics/LinkedStack.java @@ -0,0 +1,43 @@ +// generics/LinkedStack.java +// (c)2020 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. +// A stack implemented with an internal linked structure + +public class LinkedStack { + private static class Node { + U item; + Node next; + Node() { item = null; next = null; } + Node(U item, Node next) { + this.item = item; + this.next = next; + } + boolean end() { + return item == null && next == null; + } + } + private Node top = new Node<>(); // End sentinel + public void push(T item) { + top = new Node<>(item, top); + } + public T pop() { + T result = top.item; + if(!top.end()) + top = top.next; + return result; + } + public static void main(String[] args) { + LinkedStack lss = new LinkedStack<>(); + for(String s : "Phasers on stun!".split(" ")) + lss.push(s); + String s; + while((s = lss.pop()) != null) + System.out.println(s); + } +} +/* Output: +stun! +on +Phasers +*/ diff --git a/code/generics/ListMaker.java b/code/generics/ListMaker.java new file mode 100644 index 00000000..582cbaea --- /dev/null +++ b/code/generics/ListMaker.java @@ -0,0 +1,13 @@ +// generics/ListMaker.java +// (c)2020 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. +import java.util.*; + +public class ListMaker { + List create() { return new ArrayList<>(); } + public static void main(String[] args) { + ListMaker stringMaker = new ListMaker<>(); + List stringList = stringMaker.create(); + } +} diff --git a/code/generics/ListOfGenerics.java b/code/generics/ListOfGenerics.java new file mode 100644 index 00000000..10a48031 --- /dev/null +++ b/code/generics/ListOfGenerics.java @@ -0,0 +1,11 @@ +// generics/ListOfGenerics.java +// (c)2020 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. +import java.util.*; + +public class ListOfGenerics { + private List array = new ArrayList<>(); + public void add(T item) { array.add(item); } + public T get(int index) { return array.get(index); } +} diff --git a/code/generics/ListOfInt.java b/code/generics/ListOfInt.java new file mode 100644 index 00000000..f8ac8e11 --- /dev/null +++ b/code/generics/ListOfInt.java @@ -0,0 +1,20 @@ +// generics/ListOfInt.java +// (c)2020 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. +// Autoboxing compensates for the inability +// to use primitives in generics +import java.util.*; +import java.util.stream.*; + +public class ListOfInt { + public static void main(String[] args) { + List li = IntStream.range(38, 48) + .boxed() // Converts ints to Integers + .collect(Collectors.toList()); + System.out.println(li); + } +} +/* Output: +[38, 39, 40, 41, 42, 43, 44, 45, 46, 47] +*/ diff --git a/code/generics/LostInformation.java b/code/generics/LostInformation.java new file mode 100644 index 00000000..e27430d2 --- /dev/null +++ b/code/generics/LostInformation.java @@ -0,0 +1,33 @@ +// generics/LostInformation.java +// (c)2020 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. +import java.util.*; + +class Frob {} +class Fnorkle {} +class Quark {} +class Particle {} + +public class LostInformation { + public static void main(String[] args) { + List list = new ArrayList<>(); + Map map = new HashMap<>(); + Quark quark = new Quark<>(); + Particle p = new Particle<>(); + System.out.println(Arrays.toString( + list.getClass().getTypeParameters())); + System.out.println(Arrays.toString( + map.getClass().getTypeParameters())); + System.out.println(Arrays.toString( + quark.getClass().getTypeParameters())); + System.out.println(Arrays.toString( + p.getClass().getTypeParameters())); + } +} +/* Output: +[E] +[K, V] +[Q] +[POSITION, MOMENTUM] +*/ diff --git a/code/generics/Manipulation.java b/code/generics/Manipulation.java new file mode 100644 index 00000000..f365cf19 --- /dev/null +++ b/code/generics/Manipulation.java @@ -0,0 +1,21 @@ +// generics/Manipulation.java +// (c)2020 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. +// {WillNotCompile} + +class Manipulator { + private T obj; + Manipulator(T x) { obj = x; } + // Error: cannot find symbol: method f(): + public void manipulate() { obj.f(); } +} + +public class Manipulation { + public static void main(String[] args) { + HasF hf = new HasF(); + Manipulator manipulator = + new Manipulator<>(hf); + manipulator.manipulate(); + } +} diff --git a/code/generics/Manipulator2.java b/code/generics/Manipulator2.java new file mode 100644 index 00000000..7c7c648b --- /dev/null +++ b/code/generics/Manipulator2.java @@ -0,0 +1,10 @@ +// generics/Manipulator2.java +// (c)2020 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. + +class Manipulator2 { + private T obj; + Manipulator2(T x) { obj = x; } + public void manipulate() { obj.f(); } +} diff --git a/code/generics/Manipulator3.java b/code/generics/Manipulator3.java new file mode 100644 index 00000000..2201d474 --- /dev/null +++ b/code/generics/Manipulator3.java @@ -0,0 +1,10 @@ +// generics/Manipulator3.java +// (c)2020 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. + +class Manipulator3 { + private HasF obj; + Manipulator3(HasF x) { obj = x; } + public void manipulate() { obj.f(); } +} diff --git a/code/generics/Mixins.cpp b/code/generics/Mixins.cpp new file mode 100644 index 00000000..89949d46 --- /dev/null +++ b/code/generics/Mixins.cpp @@ -0,0 +1,47 @@ +// generics/Mixins.cpp +// (c)2020 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. +#include +#include +#include +using namespace std; + +template class TimeStamped : public T { + long timeStamp; +public: + TimeStamped() { timeStamp = time(0); } + long getStamp() { return timeStamp; } +}; + +template class SerialNumbered : public T { + long serialNumber; + static long counter; +public: + SerialNumbered() { serialNumber = counter++; } + long getSerialNumber() { return serialNumber; } +}; + +// Define and initialize the static storage: +template long SerialNumbered::counter = 1; + +class Basic { + string value; +public: + void set(string val) { value = val; } + string get() { return value; } +}; + +int main() { + TimeStamped> mixin1, mixin2; + mixin1.set("test string 1"); + mixin2.set("test string 2"); + cout << mixin1.get() << " " << mixin1.getStamp() << + " " << mixin1.getSerialNumber() << endl; + cout << mixin2.get() << " " << mixin2.getStamp() << + " " << mixin2.getSerialNumber() << endl; +} +/* Output: +test string 1 1452987605 1 +test string 2 1452987605 2 +*/ diff --git a/code/generics/Mixins.java b/code/generics/Mixins.java new file mode 100644 index 00000000..af58b81e --- /dev/null +++ b/code/generics/Mixins.java @@ -0,0 +1,71 @@ +// generics/Mixins.java +// (c)2020 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. +import java.util.*; + +interface TimeStamped { long getStamp(); } + +class TimeStampedImp implements TimeStamped { + private final long timeStamp; + TimeStampedImp() { + timeStamp = new Date().getTime(); + } + @Override + public long getStamp() { return timeStamp; } +} + +interface SerialNumbered { long getSerialNumber(); } + +class SerialNumberedImp implements SerialNumbered { + private static long counter = 1; + private final long serialNumber = counter++; + @Override + public long getSerialNumber() { return serialNumber; } +} + +interface Basic { + void set(String val); + String get(); +} + +class BasicImp implements Basic { + private String value; + @Override + public void set(String val) { value = val; } + @Override + public String get() { return value; } +} + +class Mixin extends BasicImp +implements TimeStamped, SerialNumbered { + private TimeStamped timeStamp = new TimeStampedImp(); + private SerialNumbered serialNumber = + new SerialNumberedImp(); + @Override + public long getStamp() { + return timeStamp.getStamp(); + } + @Override + public long getSerialNumber() { + return serialNumber.getSerialNumber(); + } +} + +public class Mixins { + public static void main(String[] args) { + Mixin mixin1 = new Mixin(), mixin2 = new Mixin(); + mixin1.set("test string 1"); + mixin2.set("test string 2"); + System.out.println(mixin1.get() + " " + + mixin1.getStamp() + " " + + mixin1.getSerialNumber()); + System.out.println(mixin2.get() + " " + + mixin2.getStamp() + " " + + mixin2.getSerialNumber()); + } +} +/* Output: +test string 1 1494331663026 1 +test string 2 1494331663027 2 +*/ diff --git a/code/generics/MultipleInterfaceVariants.java b/code/generics/MultipleInterfaceVariants.java new file mode 100644 index 00000000..70a535a2 --- /dev/null +++ b/code/generics/MultipleInterfaceVariants.java @@ -0,0 +1,13 @@ +// generics/MultipleInterfaceVariants.java +// (c)2020 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. +// {WillNotCompile} +package generics; + +interface Payable {} + +class Employee implements Payable {} + +class Hourly extends Employee +implements Payable {} diff --git a/code/generics/NeedCasting.java b/code/generics/NeedCasting.java new file mode 100644 index 00000000..8801f5d8 --- /dev/null +++ b/code/generics/NeedCasting.java @@ -0,0 +1,15 @@ +// generics/NeedCasting.java +// (c)2020 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. +import java.io.*; +import java.util.*; + +public class NeedCasting { + @SuppressWarnings("unchecked") + public void f(String[] args) throws Exception { + ObjectInputStream in = new ObjectInputStream( + new FileInputStream(args[0])); + List shapes = (List)in.readObject(); + } +} diff --git a/code/generics/NonCovariantGenerics.java b/code/generics/NonCovariantGenerics.java new file mode 100644 index 00000000..c219a0d3 --- /dev/null +++ b/code/generics/NonCovariantGenerics.java @@ -0,0 +1,11 @@ +// generics/NonCovariantGenerics.java +// (c)2020 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. +// {WillNotCompile} +import java.util.*; + +public class NonCovariantGenerics { + // Compile Error: incompatible types: + List flist = new ArrayList(); +} diff --git a/code/generics/NotSelfBounded.java b/code/generics/NotSelfBounded.java new file mode 100644 index 00000000..76aa593c --- /dev/null +++ b/code/generics/NotSelfBounded.java @@ -0,0 +1,24 @@ +// generics/NotSelfBounded.java +// (c)2020 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. + +public class NotSelfBounded { + T element; + NotSelfBounded set(T arg) { + element = arg; + return this; + } + T get() { return element; } +} + +class A2 extends NotSelfBounded {} +class B2 extends NotSelfBounded {} + +class C2 extends NotSelfBounded { + C2 setAndGet(C2 arg) { set(arg); return get(); } +} + +class D2 {} +// Now this is OK: +class E2 extends NotSelfBounded {} diff --git a/code/generics/ObjectHolder.java b/code/generics/ObjectHolder.java new file mode 100644 index 00000000..f1dafd30 --- /dev/null +++ b/code/generics/ObjectHolder.java @@ -0,0 +1,20 @@ +// generics/ObjectHolder.java +// (c)2020 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. + +public class ObjectHolder { + private Object a; + public ObjectHolder(Object a) { this.a = a; } + public void set(Object a) { this.a = a; } + public Object get() { return a; } + public static void main(String[] args) { + ObjectHolder h2 = + new ObjectHolder(new Automobile()); + Automobile a = (Automobile)h2.get(); + h2.set("Not an Automobile"); + String s = (String)h2.get(); + h2.set(1); // Autoboxes to Integer + Integer x = (Integer)h2.get(); + } +} diff --git a/code/generics/OrdinaryArguments.java b/code/generics/OrdinaryArguments.java new file mode 100644 index 00000000..6e50550d --- /dev/null +++ b/code/generics/OrdinaryArguments.java @@ -0,0 +1,31 @@ +// generics/OrdinaryArguments.java +// (c)2020 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. + +class OrdinarySetter { + void set(Base base) { + System.out.println("OrdinarySetter.set(Base)"); + } +} + +class DerivedSetter extends OrdinarySetter { + void set(Derived derived) { + System.out.println("DerivedSetter.set(Derived)"); + } +} + +public class OrdinaryArguments { + public static void main(String[] args) { + Base base = new Base(); + Derived derived = new Derived(); + DerivedSetter ds = new DerivedSetter(); + ds.set(derived); + // Compiles--overloaded, not overridden!: + ds.set(base); + } +} +/* Output: +DerivedSetter.set(Derived) +OrdinarySetter.set(Base) +*/ diff --git a/code/generics/Performs.java b/code/generics/Performs.java new file mode 100644 index 00000000..ace09523 --- /dev/null +++ b/code/generics/Performs.java @@ -0,0 +1,9 @@ +// generics/Performs.java +// (c)2020 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. + +public interface Performs { + void speak(); + void sit(); +} diff --git a/code/generics/PlainGenericInheritance.java b/code/generics/PlainGenericInheritance.java new file mode 100644 index 00000000..93eb61c6 --- /dev/null +++ b/code/generics/PlainGenericInheritance.java @@ -0,0 +1,30 @@ +// generics/PlainGenericInheritance.java +// (c)2020 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. + +class GenericSetter { // Not self-bounded + void set(T arg) { + System.out.println("GenericSetter.set(Base)"); + } +} + +class DerivedGS extends GenericSetter { + void set(Derived derived) { + System.out.println("DerivedGS.set(Derived)"); + } +} + +public class PlainGenericInheritance { + public static void main(String[] args) { + Base base = new Base(); + Derived derived = new Derived(); + DerivedGS dgs = new DerivedGS(); + dgs.set(derived); + dgs.set(base); // Overloaded, not overridden! + } +} +/* Output: +DerivedGS.set(Derived) +GenericSetter.set(Base) +*/ diff --git a/code/generics/PrimitiveGenericTest.java b/code/generics/PrimitiveGenericTest.java new file mode 100644 index 00000000..79356437 --- /dev/null +++ b/code/generics/PrimitiveGenericTest.java @@ -0,0 +1,42 @@ +// generics/PrimitiveGenericTest.java +// (c)2020 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. +import onjava.*; +import java.util.*; +import java.util.function.*; + +// Fill an array using a generator: +interface FillArray { + static T[] fill(T[] a, Supplier gen) { + Arrays.setAll(a, n -> gen.get()); + return a; + } + static int[] fill(int[] a, IntSupplier gen) { + Arrays.setAll(a, n -> gen.getAsInt()); + return a; + } + static long[] fill(long[] a, LongSupplier gen) { + Arrays.setAll(a, n -> gen.getAsLong()); + return a; + } + static double[] fill(double[] a, DoubleSupplier gen) { + Arrays.setAll(a, n -> gen.getAsDouble()); + return a; + } +} + +public class PrimitiveGenericTest { + public static void main(String[] args) { + String[] strings = FillArray.fill( + new String[5], new Rand.String(9)); + System.out.println(Arrays.toString(strings)); + int[] integers = FillArray.fill( + new int[9], new Rand.Pint()); + System.out.println(Arrays.toString(integers)); + } +} +/* Output: +[btpenpccu, xszgvgmei, nneeloztd, vewcippcy, gpoalkljl] +[635, 8737, 3941, 4720, 6177, 8479, 6656, 3768, 4948] +*/ diff --git a/code/generics/RandomList.java b/code/generics/RandomList.java new file mode 100644 index 00000000..d4f198bc --- /dev/null +++ b/code/generics/RandomList.java @@ -0,0 +1,26 @@ +// generics/RandomList.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; + +public class RandomList extends ArrayList { + private Random rand = new Random(47); + public T select() { + return get(rand.nextInt(size())); + } + public static void main(String[] args) { + RandomList rs = new RandomList<>(); + Arrays.stream( + ("The quick brown fox jumped over " + + "the lazy brown dog").split(" ")) + .forEach(rs::add); + IntStream.range(0, 11).forEach(i -> + System.out.print(rs.select() + " ")); + } +} +/* Output: +brown over fox quick quick dog brown The brown lazy +brown +*/ diff --git a/code/generics/RestrictedComparablePets.java b/code/generics/RestrictedComparablePets.java new file mode 100644 index 00000000..16146d7b --- /dev/null +++ b/code/generics/RestrictedComparablePets.java @@ -0,0 +1,19 @@ +// generics/RestrictedComparablePets.java +// (c)2020 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. + +class Hamster extends ComparablePet +implements Comparable { + public int compareTo(ComparablePet arg) { + return 0; + } +} + +// Or just: + +class Gecko extends ComparablePet { + public int compareTo(ComparablePet arg) { + return 0; + } +} diff --git a/code/generics/ReturnGenericType.java b/code/generics/ReturnGenericType.java new file mode 100644 index 00000000..bf46ae15 --- /dev/null +++ b/code/generics/ReturnGenericType.java @@ -0,0 +1,10 @@ +// generics/ReturnGenericType.java +// (c)2020 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. + +class ReturnGenericType { + private T obj; + ReturnGenericType(T x) { obj = x; } + public T get() { return obj; } +} diff --git a/code/generics/SelfBounding.java b/code/generics/SelfBounding.java new file mode 100644 index 00000000..c8ecf0ff --- /dev/null +++ b/code/generics/SelfBounding.java @@ -0,0 +1,40 @@ +// generics/SelfBounding.java +// (c)2020 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. + +class SelfBounded> { + T element; + SelfBounded set(T arg) { + element = arg; + return this; + } + T get() { return element; } +} + +class A extends SelfBounded {} +class B extends SelfBounded {} // Also OK + +class C extends SelfBounded { + C setAndGet(C arg) { set(arg); return get(); } +} + +class D {} +// Can't do this: +// class E extends SelfBounded {} +// Compile error: +// Type parameter D is not within its bound + +// Alas, you can do this, so you cannot force the idiom: +class F extends SelfBounded {} + +public class SelfBounding { + public static void main(String[] args) { + A a = new A(); + a.set(new A()); + a = a.set(new A()).get(); + a = a.get(); + C c = new C(); + c = c.setAndGet(new C()); + } +} diff --git a/code/generics/SelfBoundingAndCovariantArguments.java b/code/generics/SelfBoundingAndCovariantArguments.java new file mode 100644 index 00000000..34262b0e --- /dev/null +++ b/code/generics/SelfBoundingAndCovariantArguments.java @@ -0,0 +1,31 @@ +// generics/SelfBoundingAndCovariantArguments.java +// (c)2020 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. + +interface +SelfBoundSetter> { + void set(T arg); +} + +interface Setter extends SelfBoundSetter {} + +public class SelfBoundingAndCovariantArguments { + void + testA(Setter s1, Setter s2, SelfBoundSetter sbs) { + s1.set(s2); + //- s1.set(sbs); + // error: method set in interface SelfBoundSetter + // cannot be applied to given types; + // s1.set(sbs); + // ^ + // required: Setter + // found: SelfBoundSetter + // reason: argument mismatch; + // SelfBoundSetter cannot be converted to Setter + // where T is a type-variable: + // T extends SelfBoundSetter declared in + // interface SelfBoundSetter + // 1 error + } +} diff --git a/code/generics/SelfBoundingMethods.java b/code/generics/SelfBoundingMethods.java new file mode 100644 index 00000000..e6cb7949 --- /dev/null +++ b/code/generics/SelfBoundingMethods.java @@ -0,0 +1,13 @@ +// generics/SelfBoundingMethods.java +// (c)2020 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. + +public class SelfBoundingMethods { + static > T f(T arg) { + return arg.set(arg).get(); + } + public static void main(String[] args) { + A a = f(new A()); + } +} diff --git a/code/generics/Shape.java b/code/generics/Shape.java new file mode 100644 index 00000000..dd2458c2 --- /dev/null +++ b/code/generics/Shape.java @@ -0,0 +1,19 @@ +// generics/Shape.java +// (c)2020 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. + +public class Shape { + private static long counter = 0; + private final long id = counter++; + @Override + public String toString() { + return getClass().getSimpleName() + " " + id; + } + public void rotate() { + System.out.println(this + " rotate"); + } + public void resize(int newSize) { + System.out.println(this + " resize " + newSize); + } +} diff --git a/code/generics/SimpleDogsAndRobots.java b/code/generics/SimpleDogsAndRobots.java new file mode 100644 index 00000000..b9cee77b --- /dev/null +++ b/code/generics/SimpleDogsAndRobots.java @@ -0,0 +1,25 @@ +// generics/SimpleDogsAndRobots.java +// (c)2020 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. +// Removing the generic; code still works + +class CommunicateSimply { + static void perform(Performs performer) { + performer.speak(); + performer.sit(); + } +} + +public class SimpleDogsAndRobots { + public static void main(String[] args) { + CommunicateSimply.perform(new PerformingDog()); + CommunicateSimply.perform(new Robot()); + } +} +/* Output: +Woof! +Sitting +Click! +Clank! +*/ diff --git a/code/generics/SimpleHolder.java b/code/generics/SimpleHolder.java new file mode 100644 index 00000000..a73af0ab --- /dev/null +++ b/code/generics/SimpleHolder.java @@ -0,0 +1,15 @@ +// generics/SimpleHolder.java +// (c)2020 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. + +public class SimpleHolder { + private Object obj; + public void set(Object obj) { this.obj = obj; } + public Object get() { return obj; } + public static void main(String[] args) { + SimpleHolder holder = new SimpleHolder(); + holder.set("Item"); + String s = (String)holder.get(); + } +} diff --git a/code/generics/SimpleQueue.java b/code/generics/SimpleQueue.java new file mode 100644 index 00000000..76fb4f3e --- /dev/null +++ b/code/generics/SimpleQueue.java @@ -0,0 +1,16 @@ +// generics/SimpleQueue.java +// (c)2020 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. +// A different kind of Iterable collection +import java.util.*; + +public class SimpleQueue implements Iterable { + private LinkedList storage = new LinkedList<>(); + public void add(T t) { storage.offer(t); } + public T get() { return storage.poll(); } + @Override + public Iterator iterator() { + return storage.iterator(); + } +} diff --git a/code/generics/Square.java b/code/generics/Square.java new file mode 100644 index 00000000..e3bcad93 --- /dev/null +++ b/code/generics/Square.java @@ -0,0 +1,5 @@ +// generics/Square.java +// (c)2020 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. +public class Square extends Shape {} diff --git a/code/generics/Store.java b/code/generics/Store.java new file mode 100644 index 00000000..c165926a --- /dev/null +++ b/code/generics/Store.java @@ -0,0 +1,90 @@ +// generics/Store.java +// (c)2020 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. +// Building a complex model using generic collections +import java.util.*; +import java.util.function.*; +import onjava.*; + +class Product { + private final int id; + private String description; + private double price; + Product(int idNumber, String descr, double price) { + id = idNumber; + description = descr; + this.price = price; + System.out.println(toString()); + } + @Override + public String toString() { + return id + ": " + description + + ", price: $" + price; + } + public void priceChange(double change) { + price += change; + } + public static Supplier generator = + new Supplier() { + private Random rand = new Random(47); + @Override + public Product get() { + return new Product(rand.nextInt(1000), "Test", + Math.round( + rand.nextDouble() * 1000.0) + 0.99); + } + }; +} + +class Shelf extends ArrayList { + Shelf(int nProducts) { + Suppliers.fill(this, Product.generator, nProducts); + } +} + +class Aisle extends ArrayList { + Aisle(int nShelves, int nProducts) { + for(int i = 0; i < nShelves; i++) + add(new Shelf(nProducts)); + } +} + +class CheckoutStand {} +class Office {} + +public class Store extends ArrayList { + private ArrayList checkouts = + new ArrayList<>(); + private Office office = new Office(); + public Store( + int nAisles, int nShelves, int nProducts) { + for(int i = 0; i < nAisles; i++) + add(new Aisle(nShelves, nProducts)); + } + @Override + public String toString() { + StringBuilder result = new StringBuilder(); + for(Aisle a : this) + for(Shelf s : a) + for(Product p : s) { + result.append(p); + result.append("\n"); + } + return result.toString(); + } + public static void main(String[] args) { + System.out.println(new Store(5, 4, 3)); + } +} +/* Output: (First 8 Lines) +258: Test, price: $400.99 +861: Test, price: $160.99 +868: Test, price: $417.99 +207: Test, price: $268.99 +551: Test, price: $114.99 +278: Test, price: $804.99 +520: Test, price: $554.99 +140: Test, price: $530.99 + ... +*/ diff --git a/code/generics/SuperTypeWildcards.java b/code/generics/SuperTypeWildcards.java new file mode 100644 index 00000000..f8672a4f --- /dev/null +++ b/code/generics/SuperTypeWildcards.java @@ -0,0 +1,13 @@ +// generics/SuperTypeWildcards.java +// (c)2020 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. +import java.util.*; + +public class SuperTypeWildcards { + static void writeTo(List apples) { + apples.add(new Apple()); + apples.add(new Jonathan()); + // apples.add(new Fruit()); // Error + } +} diff --git a/code/generics/Templates.cpp b/code/generics/Templates.cpp new file mode 100644 index 00000000..ab2a3b64 --- /dev/null +++ b/code/generics/Templates.cpp @@ -0,0 +1,27 @@ +// generics/Templates.cpp +// (c)2020 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. +#include +using namespace std; + +template class Manipulator { + T obj; +public: + Manipulator(T x) { obj = x; } + void manipulate() { obj.f(); } +}; + +class HasF { +public: + void f() { cout << "HasF::f()" << endl; } +}; + +int main() { + HasF hf; + Manipulator manipulator(hf); + manipulator.manipulate(); +} +/* Output: +HasF::f() +*/ diff --git a/code/generics/ThrowGenericException.java b/code/generics/ThrowGenericException.java new file mode 100644 index 00000000..994c7f88 --- /dev/null +++ b/code/generics/ThrowGenericException.java @@ -0,0 +1,82 @@ +// generics/ThrowGenericException.java +// (c)2020 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. +import java.util.*; + +interface Processor { + void process(List resultCollector) throws E; +} + +class ProcessRunner +extends ArrayList> { + List processAll() throws E { + List resultCollector = new ArrayList<>(); + for(Processor processor : this) + processor.process(resultCollector); + return resultCollector; + } +} + +class Failure1 extends Exception {} + +class Processor1 +implements Processor { + static int count = 3; + @Override + public void process(List resultCollector) + throws Failure1 { + if(count-- > 1) + resultCollector.add("Hep!"); + else + resultCollector.add("Ho!"); + if(count < 0) + throw new Failure1(); + } +} + +class Failure2 extends Exception {} + +class Processor2 +implements Processor { + static int count = 2; + @Override + public void process(List resultCollector) + throws Failure2 { + if(count-- == 0) + resultCollector.add(47); + else { + resultCollector.add(11); + } + if(count < 0) + throw new Failure2(); + } +} + +public class ThrowGenericException { + public static void main(String[] args) { + ProcessRunner runner = + new ProcessRunner<>(); + for(int i = 0; i < 3; i++) + runner.add(new Processor1()); + try { + System.out.println(runner.processAll()); + } catch(Failure1 e) { + System.out.println(e); + } + + ProcessRunner runner2 = + new ProcessRunner<>(); + for(int i = 0; i < 3; i++) + runner2.add(new Processor2()); + try { + System.out.println(runner2.processAll()); + } catch(Failure2 e) { + System.out.println(e); + } + } +} +/* Output: +[Hep!, Hep!, Ho!] +Failure2 +*/ diff --git a/code/generics/TupleList.java b/code/generics/TupleList.java new file mode 100644 index 00000000..fe93330b --- /dev/null +++ b/code/generics/TupleList.java @@ -0,0 +1,23 @@ +// generics/TupleList.java +// (c)2020 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. +// Combining generic types to make complex generic types +import java.util.*; +import onjava.*; +import java.util.stream.*; + +public class TupleList +extends ArrayList> { + public static void main(String[] args) { + TupleList tl = + new TupleList<>(); + tl.add(TupleTest2.h()); + tl.add(TupleTest2.h()); + tl.forEach(System.out::println); + } +} +/* Output: +(Vehicle@7cca494b, Amphibian@7ba4f24f, hi, 47) +(Vehicle@3b9a45b3, Amphibian@7699a589, hi, 47) +*/ diff --git a/code/generics/TupleTest.java b/code/generics/TupleTest.java new file mode 100644 index 00000000..e207da40 --- /dev/null +++ b/code/generics/TupleTest.java @@ -0,0 +1,42 @@ +// generics/TupleTest.java +// (c)2020 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. +import onjava.*; + +public class TupleTest { + static Tuple2 f() { + // Autoboxing converts the int to Integer: + return new Tuple2<>("hi", 47); + } + static Tuple3 g() { + return new Tuple3<>(new Amphibian(), "hi", 47); + } + static + Tuple4 h() { + return + new Tuple4<>( + new Vehicle(), new Amphibian(), "hi", 47); + } + static + Tuple5 k() { + return new + Tuple5<>( + new Vehicle(), new Amphibian(), "hi", 47, 11.1); + } + public static void main(String[] args) { + Tuple2 ttsi = f(); + System.out.println(ttsi); + // ttsi.a1 = "there"; // Compile error: final + System.out.println(g()); + System.out.println(h()); + System.out.println(k()); + } +} +/* Output: +(hi, 47) +(Amphibian@1540e19d, hi, 47) +(Vehicle@7f31245a, Amphibian@6d6f6e28, hi, 47) +(Vehicle@330bedb4, Amphibian@2503dbd3, hi, 47, 11.1) +*/ diff --git a/code/generics/TupleTest2.java b/code/generics/TupleTest2.java new file mode 100644 index 00000000..3a0c8d14 --- /dev/null +++ b/code/generics/TupleTest2.java @@ -0,0 +1,42 @@ +// generics/TupleTest2.java +// (c)2020 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. +import onjava.*; +import static onjava.Tuple.*; + +public class TupleTest2 { + static Tuple2 f() { + return tuple("hi", 47); + } + static Tuple2 f2() { return tuple("hi", 47); } + static Tuple3 g() { + return tuple(new Amphibian(), "hi", 47); + } + static + Tuple4 h() { + return tuple( + new Vehicle(), new Amphibian(), "hi", 47); + } + static + Tuple5 k() { + return tuple(new Vehicle(), new Amphibian(), + "hi", 47, 11.1); + } + public static void main(String[] args) { + Tuple2 ttsi = f(); + System.out.println(ttsi); + System.out.println(f2()); + System.out.println(g()); + System.out.println(h()); + System.out.println(k()); + } +} +/* Output: +(hi, 47) +(hi, 47) +(Amphibian@14ae5a5, hi, 47) +(Vehicle@135fbaa4, Amphibian@45ee12a7, hi, 47) +(Vehicle@4b67cf4d, Amphibian@7ea987ac, hi, 47, 11.1) +*/ diff --git a/code/generics/UnboundedWildcards1.java b/code/generics/UnboundedWildcards1.java new file mode 100644 index 00000000..6b163a4c --- /dev/null +++ b/code/generics/UnboundedWildcards1.java @@ -0,0 +1,58 @@ +// generics/UnboundedWildcards1.java +// (c)2020 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. +import java.util.*; + +public class UnboundedWildcards1 { + static List list1; + static List list2; + static List list3; + static void assign1(List list) { + list1 = list; + list2 = list; + //- list3 = list; + // warning: [unchecked] unchecked conversion + // list3 = list; + // ^ + // required: List + // found: List + } + static void assign2(List list) { + list1 = list; + list2 = list; + list3 = list; + } + static void assign3(List list) { + list1 = list; + list2 = list; + list3 = list; + } + public static void main(String[] args) { + assign1(new ArrayList()); + assign2(new ArrayList()); + //- assign3(new ArrayList()); + // warning: [unchecked] unchecked method invocation: + // method assign3 in class UnboundedWildcards1 + // is applied to given types + // assign3(new ArrayList()); + // ^ + // required: List + // found: ArrayList + // warning: [unchecked] unchecked conversion + // assign3(new ArrayList()); + // ^ + // required: List + // found: ArrayList + // 2 warnings + assign1(new ArrayList<>()); + assign2(new ArrayList<>()); + assign3(new ArrayList<>()); + // Both forms are acceptable as List: + List wildList = new ArrayList(); + wildList = new ArrayList<>(); + assign1(wildList); + assign2(wildList); + assign3(wildList); + } +} diff --git a/code/generics/UnboundedWildcards2.java b/code/generics/UnboundedWildcards2.java new file mode 100644 index 00000000..ee80d555 --- /dev/null +++ b/code/generics/UnboundedWildcards2.java @@ -0,0 +1,35 @@ +// generics/UnboundedWildcards2.java +// (c)2020 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. +import java.util.*; + +public class UnboundedWildcards2 { + static Map map1; + static Map map2; + static Map map3; + static void assign1(Map map) { map1 = map; } + static void assign2(Map map) { map2 = map; } + static void assign3(Map map) { map3 = map; } + public static void main(String[] args) { + assign1(new HashMap()); + assign2(new HashMap()); + //- assign3(new HashMap()); + // warning: [unchecked] unchecked method invocation: + // method assign3 in class UnboundedWildcards2 + // is applied to given types + // assign3(new HashMap()); + // ^ + // required: Map + // found: HashMap + // warning: [unchecked] unchecked conversion + // assign3(new HashMap()); + // ^ + // required: Map + // found: HashMap + // 2 warnings + assign1(new HashMap<>()); + assign2(new HashMap<>()); + assign3(new HashMap<>()); + } +} diff --git a/code/generics/Unconstrained.java b/code/generics/Unconstrained.java new file mode 100644 index 00000000..f683d53f --- /dev/null +++ b/code/generics/Unconstrained.java @@ -0,0 +1,20 @@ +// generics/Unconstrained.java +// (c)2020 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. + +class Other {} +class BasicOther extends BasicHolder {} + +public class Unconstrained { + public static void main(String[] args) { + BasicOther b = new BasicOther(); + BasicOther b2 = new BasicOther(); + b.set(new Other()); + Other other = b.get(); + b.f(); + } +} +/* Output: +Other +*/ diff --git a/code/generics/UseList.java b/code/generics/UseList.java new file mode 100644 index 00000000..924d3b56 --- /dev/null +++ b/code/generics/UseList.java @@ -0,0 +1,11 @@ +// generics/UseList.java +// (c)2020 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. +// {WillNotCompile} +import java.util.*; + +public class UseList { + void f(List v) {} + void f(List v) {} +} diff --git a/code/generics/UseList2.java b/code/generics/UseList2.java new file mode 100644 index 00000000..83d3b5d3 --- /dev/null +++ b/code/generics/UseList2.java @@ -0,0 +1,10 @@ +// generics/UseList2.java +// (c)2020 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. +import java.util.*; + +public class UseList2 { + void f1(List v) {} + void f2(List v) {} +} diff --git a/code/generics/Vehicle.java b/code/generics/Vehicle.java new file mode 100644 index 00000000..301a84e4 --- /dev/null +++ b/code/generics/Vehicle.java @@ -0,0 +1,5 @@ +// generics/Vehicle.java +// (c)2020 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. +public class Vehicle {} diff --git a/code/generics/WatercolorSets.java b/code/generics/WatercolorSets.java new file mode 100644 index 00000000..7956778d --- /dev/null +++ b/code/generics/WatercolorSets.java @@ -0,0 +1,54 @@ +// generics/WatercolorSets.java +// (c)2020 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. +import generics.watercolors.*; +import java.util.*; +import static onjava.Sets.*; +import static generics.watercolors.Watercolors.*; + +public class WatercolorSets { + public static void main(String[] args) { + Set set1 = + EnumSet.range(BRILLIANT_RED, VIRIDIAN_HUE); + Set set2 = + EnumSet.range(CERULEAN_BLUE_HUE, BURNT_UMBER); + System.out.println("set1: " + set1); + System.out.println("set2: " + set2); + System.out.println( + "union(set1, set2): " + union(set1, set2)); + Set subset = intersection(set1, set2); + System.out.println( + "intersection(set1, set2): " + subset); + System.out.println("difference(set1, subset): " + + difference(set1, subset)); + System.out.println("difference(set2, subset): " + + difference(set2, subset)); + System.out.println("complement(set1, set2): " + + complement(set1, set2)); + } +} +/* Output: +set1: [BRILLIANT_RED, CRIMSON, MAGENTA, ROSE_MADDER, +VIOLET, CERULEAN_BLUE_HUE, PHTHALO_BLUE, ULTRAMARINE, +COBALT_BLUE_HUE, PERMANENT_GREEN, VIRIDIAN_HUE] +set2: [CERULEAN_BLUE_HUE, PHTHALO_BLUE, ULTRAMARINE, +COBALT_BLUE_HUE, PERMANENT_GREEN, VIRIDIAN_HUE, +SAP_GREEN, YELLOW_OCHRE, BURNT_SIENNA, RAW_UMBER, +BURNT_UMBER] +union(set1, set2): [BURNT_SIENNA, BRILLIANT_RED, +YELLOW_OCHRE, MAGENTA, SAP_GREEN, CERULEAN_BLUE_HUE, +ULTRAMARINE, VIRIDIAN_HUE, VIOLET, RAW_UMBER, +ROSE_MADDER, PERMANENT_GREEN, BURNT_UMBER, +PHTHALO_BLUE, CRIMSON, COBALT_BLUE_HUE] +intersection(set1, set2): [PERMANENT_GREEN, +CERULEAN_BLUE_HUE, ULTRAMARINE, VIRIDIAN_HUE, +PHTHALO_BLUE, COBALT_BLUE_HUE] +difference(set1, subset): [BRILLIANT_RED, MAGENTA, +VIOLET, CRIMSON, ROSE_MADDER] +difference(set2, subset): [BURNT_SIENNA, YELLOW_OCHRE, +BURNT_UMBER, SAP_GREEN, RAW_UMBER] +complement(set1, set2): [BURNT_SIENNA, BRILLIANT_RED, +YELLOW_OCHRE, MAGENTA, SAP_GREEN, VIOLET, RAW_UMBER, +ROSE_MADDER, BURNT_UMBER, CRIMSON] +*/ diff --git a/code/generics/Wildcards.java b/code/generics/Wildcards.java new file mode 100644 index 00000000..65348ecb --- /dev/null +++ b/code/generics/Wildcards.java @@ -0,0 +1,285 @@ +// generics/Wildcards.java +// (c)2020 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. +// Exploring the meaning of wildcards + +public class Wildcards { + // Raw argument: + static void rawArgs(Holder holder, Object arg) { + //- holder.set(arg); + // warning: [unchecked] unchecked call to set(T) + // as a member of the raw type Holder + // holder.set(arg); + // ^ + // where T is a type-variable: + // T extends Object declared in class Holder + // 1 warning + + // Can't do this; don't have any 'T': + // T t = holder.get(); + + // OK, but type information is lost: + Object obj = holder.get(); + } + // Like rawArgs(), but errors instead of warnings: + static void + unboundedArg(Holder holder, Object arg) { + //- holder.set(arg); + // error: method set in class Holder + // cannot be applied to given types; + // holder.set(arg); + // ^ + // required: CAP#1 + // found: Object + // reason: argument mismatch; + // Object cannot be converted to CAP#1 + // where T is a type-variable: + // T extends Object declared in class Holder + // where CAP#1 is a fresh type-variable: + // CAP#1 extends Object from capture of ? + // 1 error + + // Can't do this; don't have any 'T': + // T t = holder.get(); + + // OK, but type information is lost: + Object obj = holder.get(); + } + static T exact1(Holder holder) { + return holder.get(); + } + static T exact2(Holder holder, T arg) { + holder.set(arg); + return holder.get(); + } + static + T wildSubtype(Holder holder, T arg) { + //- holder.set(arg); + // error: method set in class Holder + // cannot be applied to given types; + // holder.set(arg); + // ^ + // required: CAP#1 + // found: T#1 + // reason: argument mismatch; + // T#1 cannot be converted to CAP#1 + // where T#1,T#2 are type-variables: + // T#1 extends Object declared in method + // wildSubtype(Holder,T#1) + // T#2 extends Object declared in class Holder + // where CAP#1 is a fresh type-variable: + // CAP#1 extends T#1 from + // capture of ? extends T#1 + // 1 error + + return holder.get(); + } + static + void wildSupertype(Holder holder, T arg) { + holder.set(arg); + //- T t = holder.get(); + // error: incompatible types: + // CAP#1 cannot be converted to T + // T t = holder.get(); + // ^ + // where T is a type-variable: + // T extends Object declared in method + // wildSupertype(Holder,T) + // where CAP#1 is a fresh type-variable: + // CAP#1 extends Object super: + // T from capture of ? super T + // 1 error + + // OK, but type information is lost: + Object obj = holder.get(); + } + public static void main(String[] args) { + Holder raw = new Holder<>(); + // Or: + raw = new Holder(); + Holder qualified = new Holder<>(); + Holder unbounded = new Holder<>(); + Holder bounded = new Holder<>(); + Long lng = 1L; + + rawArgs(raw, lng); + rawArgs(qualified, lng); + rawArgs(unbounded, lng); + rawArgs(bounded, lng); + + unboundedArg(raw, lng); + unboundedArg(qualified, lng); + unboundedArg(unbounded, lng); + unboundedArg(bounded, lng); + + //- Object r1 = exact1(raw); + // warning: [unchecked] unchecked method invocation: + // method exact1 in class Wildcards is applied + // to given types + // Object r1 = exact1(raw); + // ^ + // required: Holder + // found: Holder + // where T is a type-variable: + // T extends Object declared in + // method exact1(Holder) + // warning: [unchecked] unchecked conversion + // Object r1 = exact1(raw); + // ^ + // required: Holder + // found: Holder + // where T is a type-variable: + // T extends Object declared in + // method exact1(Holder) + // 2 warnings + + Long r2 = exact1(qualified); + Object r3 = exact1(unbounded); // Must return Object + Long r4 = exact1(bounded); + + //- Long r5 = exact2(raw, lng); + // warning: [unchecked] unchecked method invocation: + // method exact2 in class Wildcards is + // applied to given types + // Long r5 = exact2(raw, lng); + // ^ + // required: Holder,T + // found: Holder,Long + // where T is a type-variable: + // T extends Object declared in + // method exact2(Holder,T) + // warning: [unchecked] unchecked conversion + // Long r5 = exact2(raw, lng); + // ^ + // required: Holder + // found: Holder + // where T is a type-variable: + // T extends Object declared in + // method exact2(Holder,T) + // 2 warnings + + Long r6 = exact2(qualified, lng); + + //- Long r7 = exact2(unbounded, lng); + // error: method exact2 in class Wildcards + // cannot be applied to given types; + // Long r7 = exact2(unbounded, lng); + // ^ + // required: Holder,T + // found: Holder,Long + // reason: inference variable T has + // incompatible bounds + // equality constraints: CAP#1 + // lower bounds: Long + // where T is a type-variable: + // T extends Object declared in + // method exact2(Holder,T) + // where CAP#1 is a fresh type-variable: + // CAP#1 extends Object from capture of ? + // 1 error + + //- Long r8 = exact2(bounded, lng); + // error: method exact2 in class Wildcards + // cannot be applied to given types; + // Long r8 = exact2(bounded, lng); + // ^ + // required: Holder,T + // found: Holder,Long + // reason: inference variable T + // has incompatible bounds + // equality constraints: CAP#1 + // lower bounds: Long + // where T is a type-variable: + // T extends Object declared in + // method exact2(Holder,T) + // where CAP#1 is a fresh type-variable: + // CAP#1 extends Long from + // capture of ? extends Long + // 1 error + + //- Long r9 = wildSubtype(raw, lng); + // warning: [unchecked] unchecked method invocation: + // method wildSubtype in class Wildcards + // is applied to given types + // Long r9 = wildSubtype(raw, lng); + // ^ + // required: Holder,T + // found: Holder,Long + // where T is a type-variable: + // T extends Object declared in + // method wildSubtype(Holder,T) + // warning: [unchecked] unchecked conversion + // Long r9 = wildSubtype(raw, lng); + // ^ + // required: Holder + // found: Holder + // where T is a type-variable: + // T extends Object declared in + // method wildSubtype(Holder,T) + // 2 warnings + + Long r10 = wildSubtype(qualified, lng); + // OK, but can only return Object: + Object r11 = wildSubtype(unbounded, lng); + Long r12 = wildSubtype(bounded, lng); + + //- wildSupertype(raw, lng); + // warning: [unchecked] unchecked method invocation: + // method wildSupertype in class Wildcards + // is applied to given types + // wildSupertype(raw, lng); + // ^ + // required: Holder,T + // found: Holder,Long + // where T is a type-variable: + // T extends Object declared in + // method wildSupertype(Holder,T) + // warning: [unchecked] unchecked conversion + // wildSupertype(raw, lng); + // ^ + // required: Holder + // found: Holder + // where T is a type-variable: + // T extends Object declared in + // method wildSupertype(Holder,T) + // 2 warnings + + wildSupertype(qualified, lng); + + //- wildSupertype(unbounded, lng); + // error: method wildSupertype in class Wildcards + // cannot be applied to given types; + // wildSupertype(unbounded, lng); + // ^ + // required: Holder,T + // found: Holder,Long + // reason: cannot infer type-variable(s) T + // (argument mismatch; Holder + // cannot be converted to Holder) + // where T is a type-variable: + // T extends Object declared in + // method wildSupertype(Holder,T) + // where CAP#1 is a fresh type-variable: + // CAP#1 extends Object from capture of ? + // 1 error + + //- wildSupertype(bounded, lng); + // error: method wildSupertype in class Wildcards + // cannot be applied to given types; + // wildSupertype(bounded, lng); + // ^ + // required: Holder,T + // found: Holder,Long + // reason: cannot infer type-variable(s) T + // (argument mismatch; Holder + // cannot be converted to Holder) + // where T is a type-variable: + // T extends Object declared in + // method wildSupertype(Holder,T) + // where CAP#1 is a fresh type-variable: + // CAP#1 extends Long from capture of + // ? extends Long + // 1 error + } +} diff --git a/code/generics/coffee/Americano.java b/code/generics/coffee/Americano.java new file mode 100644 index 00000000..96cd4a1f --- /dev/null +++ b/code/generics/coffee/Americano.java @@ -0,0 +1,6 @@ +// generics/coffee/Americano.java +// (c)2020 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 generics.coffee; +public class Americano extends Coffee {} diff --git a/code/generics/coffee/Breve.java b/code/generics/coffee/Breve.java new file mode 100644 index 00000000..329c406b --- /dev/null +++ b/code/generics/coffee/Breve.java @@ -0,0 +1,6 @@ +// generics/coffee/Breve.java +// (c)2020 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 generics.coffee; +public class Breve extends Coffee {} diff --git a/code/generics/coffee/Cappuccino.java b/code/generics/coffee/Cappuccino.java new file mode 100644 index 00000000..3ce89b50 --- /dev/null +++ b/code/generics/coffee/Cappuccino.java @@ -0,0 +1,6 @@ +// generics/coffee/Cappuccino.java +// (c)2020 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 generics.coffee; +public class Cappuccino extends Coffee {} diff --git a/code/generics/coffee/Coffee.java b/code/generics/coffee/Coffee.java new file mode 100644 index 00000000..c90d88c1 --- /dev/null +++ b/code/generics/coffee/Coffee.java @@ -0,0 +1,14 @@ +// generics/coffee/Coffee.java +// (c)2020 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 generics.coffee; + +public class Coffee { + private static long counter = 0; + private final long id = counter++; + @Override + public String toString() { + return getClass().getSimpleName() + " " + id; + } +} diff --git a/code/generics/coffee/CoffeeSupplier.java b/code/generics/coffee/CoffeeSupplier.java new file mode 100644 index 00000000..fe5dced8 --- /dev/null +++ b/code/generics/coffee/CoffeeSupplier.java @@ -0,0 +1,72 @@ +// generics/coffee/CoffeeSupplier.java +// (c)2020 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. +// {java generics.coffee.CoffeeSupplier} +package generics.coffee; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; +import java.lang.reflect.InvocationTargetException; + +public class CoffeeSupplier +implements Supplier, Iterable { + private Class[] types = { Latte.class, Mocha.class, + Cappuccino.class, Americano.class, Breve.class, }; + private static Random rand = new Random(47); + public CoffeeSupplier() {} + // For iteration: + private int size = 0; + public CoffeeSupplier(int sz) { size = sz; } + @Override + public Coffee get() { + try { + return (Coffee) + types[rand.nextInt(types.length)] + .getConstructor().newInstance(); + // Report programmer errors at run time: + } catch(InstantiationException | + NoSuchMethodException | + InvocationTargetException | + IllegalAccessException e) { + throw new RuntimeException(e); + } + } + class CoffeeIterator implements Iterator { + int count = size; + @Override + public boolean hasNext() { return count > 0; } + @Override + public Coffee next() { + count--; + return CoffeeSupplier.this.get(); + } + @Override + public void remove() { // Not implemented + throw new UnsupportedOperationException(); + } + } + @Override + public Iterator iterator() { + return new CoffeeIterator(); + } + public static void main(String[] args) { + Stream.generate(new CoffeeSupplier()) + .limit(5) + .forEach(System.out::println); + for(Coffee c : new CoffeeSupplier(5)) + System.out.println(c); + } +} +/* Output: +Americano 0 +Latte 1 +Americano 2 +Mocha 3 +Mocha 4 +Breve 5 +Americano 6 +Latte 7 +Cappuccino 8 +Cappuccino 9 +*/ diff --git a/code/generics/coffee/Latte.java b/code/generics/coffee/Latte.java new file mode 100644 index 00000000..d735cc87 --- /dev/null +++ b/code/generics/coffee/Latte.java @@ -0,0 +1,6 @@ +// generics/coffee/Latte.java +// (c)2020 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 generics.coffee; +public class Latte extends Coffee {} diff --git a/code/generics/coffee/Mocha.java b/code/generics/coffee/Mocha.java new file mode 100644 index 00000000..cc567be1 --- /dev/null +++ b/code/generics/coffee/Mocha.java @@ -0,0 +1,6 @@ +// generics/coffee/Mocha.java +// (c)2020 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 generics.coffee; +public class Mocha extends Coffee {} diff --git a/code/generics/decorator/Decoration.java b/code/generics/decorator/Decoration.java new file mode 100644 index 00000000..96611a75 --- /dev/null +++ b/code/generics/decorator/Decoration.java @@ -0,0 +1,51 @@ +// generics/decorator/Decoration.java +// (c)2020 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. +// {java generics.decorator.Decoration} +package generics.decorator; +import java.util.*; + +class Basic { + private String value; + public void set(String val) { value = val; } + public String get() { return value; } +} + +class Decorator extends Basic { + protected Basic basic; + Decorator(Basic basic) { this.basic = basic; } + @Override + public void set(String val) { basic.set(val); } + @Override + public String get() { return basic.get(); } +} + +class TimeStamped extends Decorator { + private final long timeStamp; + TimeStamped(Basic basic) { + super(basic); + timeStamp = new Date().getTime(); + } + public long getStamp() { return timeStamp; } +} + +class SerialNumbered extends Decorator { + private static long counter = 1; + private final long serialNumber = counter++; + SerialNumbered(Basic basic) { super(basic); } + public long getSerialNumber() { return serialNumber; } +} + +public class Decoration { + public static void main(String[] args) { + TimeStamped t = new TimeStamped(new Basic()); + TimeStamped t2 = new TimeStamped( + new SerialNumbered(new Basic())); + //- t2.getSerialNumber(); // Not available + SerialNumbered s = new SerialNumbered(new Basic()); + SerialNumbered s2 = new SerialNumbered( + new TimeStamped(new Basic())); + //- s2.getStamp(); // Not available + } +} diff --git a/code/generics/dogsandrobots.go b/code/generics/dogsandrobots.go new file mode 100644 index 00000000..f65b9c18 --- /dev/null +++ b/code/generics/dogsandrobots.go @@ -0,0 +1,32 @@ +// generics/dogsandrobots.go +// (c)2020 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 main +import "fmt" + +type Dog struct {} +func (this Dog) speak() { fmt.Printf("Arf!\n")} +func (this Dog) sit() { fmt.Printf("Sitting\n")} +func (this Dog) reproduce() {} + +type Robot struct {} +func (this Robot) speak() { fmt.Printf("Click!\n") } +func (this Robot) sit() { fmt.Printf("Clank!\n") } +func (this Robot) oilChange() {} + +func perform(speaker interface { speak(); sit() }) { + speaker.speak(); + speaker.sit(); +} + +func main() { + perform(Dog{}) + perform(Robot{}) +} +/* Output: +Arf! +Sitting +Click! +Clank! +*/ diff --git a/code/generics/watercolors/Watercolors.java b/code/generics/watercolors/Watercolors.java new file mode 100644 index 00000000..0625e532 --- /dev/null +++ b/code/generics/watercolors/Watercolors.java @@ -0,0 +1,15 @@ +// generics/watercolors/Watercolors.java +// (c)2020 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 generics.watercolors; + +public enum Watercolors { + ZINC, LEMON_YELLOW, MEDIUM_YELLOW, DEEP_YELLOW, + ORANGE, BRILLIANT_RED, CRIMSON, MAGENTA, + ROSE_MADDER, VIOLET, CERULEAN_BLUE_HUE, + PHTHALO_BLUE, ULTRAMARINE, COBALT_BLUE_HUE, + PERMANENT_GREEN, VIRIDIAN_HUE, SAP_GREEN, + YELLOW_OCHRE, BURNT_SIENNA, RAW_UMBER, + BURNT_UMBER, PAYNES_GRAY, IVORY_BLACK +} diff --git a/code/gradle.properties b/code/gradle.properties new file mode 100644 index 00000000..f97ebb7d --- /dev/null +++ b/code/gradle.properties @@ -0,0 +1 @@ +org.gradle.parallel=true diff --git a/code/gradle/checkstyle.gradle b/code/gradle/checkstyle.gradle new file mode 100644 index 00000000..0f0e6086 --- /dev/null +++ b/code/gradle/checkstyle.gradle @@ -0,0 +1,14 @@ +apply plugin: 'checkstyle' + +checkstyle { + ignoreFailures = true + configFile = new File(rootProject.projectDir, 'checkstyle.xml') + sourceSets = [sourceSets.main] +} + +tasks.withType(Checkstyle) { + reports { + xml.enabled = false + html.enabled = true + } +} diff --git a/code/gradle/findbugs.gradle b/code/gradle/findbugs.gradle new file mode 100644 index 00000000..ac628cb2 --- /dev/null +++ b/code/gradle/findbugs.gradle @@ -0,0 +1,15 @@ +/* +apply plugin: 'findbugs' + +findbugs { + ignoreFailures = true + sourceSets = [sourceSets.main] +} + +tasks.withType(FindBugs) { + reports { + xml.enabled = false + html.enabled = true + } +} +*/ diff --git a/code/gradle/java.gradle b/code/gradle/java.gradle new file mode 100644 index 00000000..eadc4ef9 --- /dev/null +++ b/code/gradle/java.gradle @@ -0,0 +1,39 @@ +apply plugin: 'java' + +sourceCompatibility = '1.8' +targetCompatibility = '1.8' + +compileJava { + options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" +} + +sourceSets { + main { + java { + srcDir projectDir + exclude "tests/**" + } + resources { + srcDir projectDir + include '*.xml' + } + } + + test { + java { + srcDir file("tests") + } + } +} + +repositories { + jcenter() +} + +dependencies { + // Logging: + compile 'org.slf4j:slf4j-api:1.7.21' + compile 'ch.qos.logback:logback-classic:1.1.7' + // You can also use the JDK's built-in logging as the back end: + // compile group: 'org.slf4j:slf4j-jdk14:1.7.21' +} \ No newline at end of file diff --git a/code/gradle/jmh.gradle b/code/gradle/jmh.gradle new file mode 100644 index 00000000..ce61db4b --- /dev/null +++ b/code/gradle/jmh.gradle @@ -0,0 +1,17 @@ +apply plugin: 'me.champeau.gradle.jmh' + +sourceSets { + jmh { + java { + srcDir projectDir + } + } +} + +jmh { + jmhVersion = '1.17.4' + duplicateClassesStrategy = 'warn' + failOnError = true + // See https://github.com/melix/jmh-gradle-plugin + // for other options +} diff --git a/code/gradle/junit-jupiter.gradle b/code/gradle/junit-jupiter.gradle new file mode 100644 index 00000000..98a77843 --- /dev/null +++ b/code/gradle/junit-jupiter.gradle @@ -0,0 +1,72 @@ +import org.apache.tools.ant.util.TeeOutputStream + +dependencies { + testImplementation(platform('org.junit:junit-bom:5.7.0')) + testImplementation('org.junit.jupiter:junit-jupiter') +} + +test { + useJUnitPlatform() + testLogging { + events "passed", "skipped", "failed" + } +} + +/* NEW: (REQUIRES CODE REWRITES IN BOOK AND TEST CODE) +-> http://junit.org/junit5/docs/current/user-guide/ + +ext { + junitJupiterVersion = '5.0.0-M3' +} + +dependencies { + testCompile "org.junit.jupiter:junit-jupiter-api:${junitJupiterVersion}" + testRuntime "org.junit.jupiter:junit-jupiter-engine:${junitJupiterVersion}" +} + + +junitPlatform { + platformVersion '1.0.0-M3' + + filters { + packages { + exclude 'collectiontopics.jmh' + } + includeClassNamePattern '.*' + } +} +*/ + +/* Store test output in $projectName/tests + JUnit 5's junitPlatformTest runs as a "javaExec" rather than a "test", + so we can't hook into the before/after test behavior. +*/ +tasks.findByPath(":$name:test").configure { + File testDir = file("tests") + if(testDir.exists()) { + File outFile = new File(testDir, 'report.txt') + + Writer taskOutput + + doFirst { + taskOutput = project.file(outFile).newWriter() + } + + testLogging.showStandardStreams = true + + onOutput { descriptor, event -> + taskOutput.append(event.message) + } + + doLast { + // WARNING: if the task fails, this won't be executed and the file remains open. + // The memory cache version doesn't have this problem. + taskOutput.close() + + if(outFile.size() == 0) + outFile.delete() + else if(outFile.text.contains("0 tests found")) + outFile.delete() + } + } +} diff --git a/code/gradle/subprojects.gradle b/code/gradle/subprojects.gradle new file mode 100644 index 00000000..e9d857d8 --- /dev/null +++ b/code/gradle/subprojects.gradle @@ -0,0 +1,67 @@ +project(':validating') { + jmh { + include = 'validating.jmh.*' + } +} + +project(':equalshashcode') { + dependencies { + compile project(':typeinfo') + compile project(':collections') + } +} + +project(':lowlevel') { + dependencies { + compile project(':enums') + } +} + +project(':strings') { + dependencies { + compile project(':generics') + } +} + +project(':serialization') { + configurations.all { + resolutionStrategy { + force 'xml-apis:xml-apis:1.0.b2' + } + } + dependencies { + compile 'com.io7m.xom:xom:1.2.10' + } +} + +project(':interfaces') { + dependencies { + compile project(':polymorphism') + } +} + +project(':hiding') { + dependencies { + compile project(':com') + } +} + +project(':generics') { + dependencies { + compile project(':typeinfo') + } +} + +project(':collections') { + dependencies { + compile project(':typeinfo') + } +} + +configure(subprojects - project(':onjava')) { + dependencies { + compile project(':onjava') + compile 'com.google.guava:guava:21.0' + compileOnly "org.openjdk.jmh:jmh-core:${jmh.jmhVersion}" + } +} diff --git a/code/gradle/wrapper/gradle-wrapper.jar b/code/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f GIT binary patch literal 59203 zcma&O1CT9Y(k9%tZQHhO+qUh#ZQHhO+qmuS+qP|E@9xZO?0h@l{(r>DQ>P;GjjD{w zH}lENr;dU&FbEU?00aa80D$0M0RRB{U*7-#kbjS|qAG&4l5%47zyJ#WrfA#1$1Ctx zf&Z_d{GW=lf^w2#qRJ|CvSJUi(^E3iv~=^Z(zH}F)3Z%V3`@+rNB7gTVU{Bb~90p|f+0(v;nz01EG7yDMX9@S~__vVgv%rS$+?IH+oZ03D5zYrv|^ zC1J)SruYHmCki$jLBlTaE5&dFG9-kq3!^i>^UQL`%gn6)jz54$WDmeYdsBE9;PqZ_ zoGd=P4+|(-u4U1dbAVQrFWoNgNd;0nrghPFbQrJctO>nwDdI`Q^i0XJDUYm|T|RWc zZ3^Qgo_Qk$%Fvjj-G}1NB#ZJqIkh;kX%V{THPqOyiq)d)0+(r9o(qKlSp*hmK#iIY zA^)Vr$-Hz<#SF=0@tL@;dCQsm`V9s1vYNq}K1B)!XSK?=I1)tX+bUV52$YQu*0%fnWEukW>mxkz+%3-S!oguE8u#MGzST8_Dy^#U?fA@S#K$S@9msUiX!gd_ow>08w5)nX{-KxqMOo7d?k2&?Vf z&diGDtZr(0cwPe9z9FAUSD9KC)7(n^lMWuayCfxzy8EZsns%OEblHFSzP=cL6}?J| z0U$H!4S_TVjj<`6dy^2j`V`)mC;cB%* z8{>_%E1^FH!*{>4a7*C1v>~1*@TMcLK{7nEQ!_igZC}ikJ$*<$yHy>7)oy79A~#xE zWavoJOIOC$5b6*q*F_qN1>2#MY)AXVyr$6x4b=$x^*aqF*L?vmj>Mgv+|ITnw_BoW zO?jwHvNy^prH{9$rrik1#fhyU^MpFqF2fYEt(;4`Q&XWOGDH8k6M=%@fics4ajI;st# zCU^r1CK&|jzUhRMv;+W~6N;u<;#DI6cCw-otsc@IsN3MoSD^O`eNflIoR~l4*&-%RBYk@gb^|-JXs&~KuSEmMxB}xSb z@K76cXD=Y|=I&SNC2E+>Zg?R6E%DGCH5J1nU!A|@eX9oS(WPaMm==k2s_ueCqdZw| z&hqHp)47`c{BgwgvY2{xz%OIkY1xDwkw!<0veB#yF4ZKJyabhyyVS`gZepcFIk%e2 zTcrmt2@-8`7i-@5Nz>oQWFuMC_KlroCl(PLSodswHqJ3fn<;gxg9=}~3x_L3P`9Sn zChIf}8vCHvTriz~T2~FamRi?rh?>3bX1j}%bLH+uFX+p&+^aXbOK7clZxdU~6Uxgy z8R=obwO4dL%pmVo*Ktf=lH6hnlz_5k3cG;m8lgaPp~?eD!Yn2kf)tU6PF{kLyn|oI@eQ`F z3IF7~Blqg8-uwUuWZScRKn%c2_}dXB6Dx_&xR*n9M9LXasJhtZdr$vBY!rP{c@=)& z#!?L$2UrkvClwQO>U*fSMs67oSj2mxiJ$t;E|>q%Kh_GzzWWO&3;ufU%2z%ucBU8H z3WIwr$n)cfCXR&>tyB7BcSInK>=ByZA%;cVEJhcg<#6N{aZC4>K41XF>ZgjG`z_u& zGY?;Ad?-sgiOnI`oppF1o1Gurqbi*;#x2>+SSV6|1^G@ooVy@fg?wyf@0Y!UZ4!}nGuLeC^l)6pwkh|oRY`s1Pm$>zZ3u-83T|9 zGaKJIV3_x+u1>cRibsaJpJqhcm%?0-L;2 zitBrdRxNmb0OO2J%Y&Ym(6*`_P3&&5Bw157{o7LFguvxC$4&zTy#U=W*l&(Q2MNO} zfaUwYm{XtILD$3864IA_nn34oVa_g^FRuHL5wdUd)+W-p-iWCKe8m_cMHk+=? zeKX)M?Dt(|{r5t7IenkAXo%&EXIb-i^w+0CX0D=xApC=|Xy(`xy+QG^UyFe z+#J6h_&T5i#sV)hj3D4WN%z;2+jJcZxcI3*CHXGmOF3^)JD5j&wfX)e?-|V0GPuA+ zQFot%aEqGNJJHn$!_}#PaAvQ^{3-Ye7b}rWwrUmX53(|~i0v{}G_sI9uDch_brX&6 zWl5Ndj-AYg(W9CGfQf<6!YmY>Ey)+uYd_JNXH=>|`OH-CDCmcH(0%iD_aLlNHKH z7bcW-^5+QV$jK?R*)wZ>r9t}loM@XN&M-Pw=F#xn(;u3!(3SXXY^@=aoj70;_=QE9 zGghsG3ekq#N||u{4We_25U=y#T*S{4I{++Ku)> zQ!DZW;pVcn>b;&g2;YE#+V`v*Bl&Y-i@X6D*OpNA{G@JAXho&aOk(_j^weW{#3X5Y z%$q_wpb07EYPdmyH(1^09i$ca{O<}7) zRWncXdSPgBE%BM#by!E>tdnc$8RwUJg1*x($6$}ae$e9Knj8gvVZe#bLi!<+&BkFj zg@nOpDneyc+hU9P-;jmOSMN|*H#>^Ez#?;%C3hg_65leSUm;iz)UkW)jX#p)e&S&M z1|a?wDzV5NVnlhRBCd_;F87wp>6c<&nkgvC+!@KGiIqWY4l}=&1w7|r6{oBN8xyzh zG$b#2=RJp_iq6)#t5%yLkKx(0@D=C3w+oiXtSuaQ%I1WIb-eiE$d~!)b@|4XLy!CZ z9p=t=%3ad@Ep+<9003D2KZ5VyP~_n$=;~r&YUg5UZ0KVD&tR1DHy9x)qWtKJp#Kq# zP*8p#W(8JJ_*h_3W}FlvRam?<4Z+-H77^$Lvi+#vmhL9J zJ<1SV45xi;SrO2f=-OB(7#iNA5)x1uNC-yNxUw|!00vcW2PufRm>e~toH;M0Q85MQLWd?3O{i8H+5VkR@l9Dg-ma ze2fZ%>G(u5(k9EHj2L6!;(KZ8%8|*-1V|B#EagbF(rc+5iL_5;Eu)L4Z-V;0HfK4d z*{utLse_rvHZeQ>V5H=f78M3Ntg1BPxFCVD{HbNA6?9*^YIq;B-DJd{Ca2L#)qWP? zvX^NhFmX?CTWw&Ns}lgs;r3i+Bq@y}Ul+U%pzOS0Fcv9~aB(0!>GT0)NO?p=25LjN z2bh>6RhgqD7bQj#k-KOm@JLgMa6>%-ok1WpOe)FS^XOU{c?d5shG(lIn3GiVBxmg`u%-j=)^v&pX1JecJics3&jvPI)mDut52? z3jEA)DM%}BYbxxKrizVYwq?(P&19EXlwD9^-6J+4!}9{ywR9Gk42jjAURAF&EO|~N z)?s>$Da@ikI4|^z0e{r`J8zIs>SpM~Vn^{3fArRu;?+43>lD+^XtUcY1HidJwnR6+ z!;oG2=B6Z_=M%*{z-RaHc(n|1RTKQdNjjV!Pn9lFt^4w|AeN06*j}ZyhqZ^!-=cyGP_ShV1rGxkx8t zB;8`h!S{LD%ot``700d0@Grql(DTt4Awgmi+Yr0@#jbe=2#UkK%rv=OLqF)9D7D1j z!~McAwMYkeaL$~kI~90)5vBhBzWYc3Cj1WI0RS`z000R8-@ET0dA~*r(gSiCJmQMN&4%1D zyVNf0?}sBH8zNbBLn>~(W{d3%@kL_eQ6jEcR{l>C|JK z(R-fA!z|TTRG40|zv}7E@PqCAXP3n`;%|SCQ|ZS%ym$I{`}t3KPL&^l5`3>yah4*6 zifO#{VNz3)?ZL$be;NEaAk9b#{tV?V7 zP|wf5YA*1;s<)9A4~l3BHzG&HH`1xNr#%){4xZ!jq%o=7nN*wMuXlFV{HaiQLJ`5G zBhDi#D(m`Q1pLh@Tq+L;OwuC52RdW7b8}~60WCOK5iYMUad9}7aWBuILb({5=z~YF zt?*Jr5NG+WadM{mDL>GyiByCuR)hd zA=HM?J6l1Xv0Dl+LW@w$OTcEoOda^nFCw*Sy^I@$sSuneMl{4ys)|RY#9&NxW4S)9 zq|%83IpslTLoz~&vTo!Ga@?rj_kw{|k{nv+w&Ku?fyk4Ki4I?);M|5Axm)t+BaE)D zm(`AQ#k^DWrjbuXoJf2{Aj^KT zFb1zMSqxq|vceV+Mf-)$oPflsO$@*A0n0Z!R{&(xh8s}=;t(lIy zv$S8x>m;vQNHuRzoaOo?eiWFe{0;$s`Bc+Osz~}Van${u;g(su`3lJ^TEfo~nERfP z)?aFzpDgnLYiERsKPu|0tq4l2wT)Atr6Qb%m-AUn6HnCue*yWICp7TjW$@sO zm5rm4aTcPQ(rfi7a`xP7cKCFrJD}*&_~xgLyr^-bmsL}y;A5P|al8J3WUoBSjqu%v zxC;mK!g(7r6RRJ852Z~feoC&sD3(6}^5-uLK8o)9{8L_%%rItZK9C){UxB|;G>JbP zsRRtS4-3B*5c+K2kvmgZK8472%l>3cntWUOVHxB|{Ay~aOg5RN;{PJgeVD*H%ac+y!h#wi%o2bF2Ca8IyMyH{>4#{E_8u^@+l-+n=V}Sq?$O z{091@v%Bd*3pk0^2UtiF9Z+(a@wy6 zUdw8J*ze$K#=$48IBi1U%;hmhO>lu!uU;+RS}p&6@rQila7WftH->*A4=5W|Fmtze z)7E}jh@cbmr9iup^i%*(uF%LG&!+Fyl@LFA-}Ca#bxRfDJAiR2dt6644TaYw1Ma79 zt8&DYj31j^5WPNf5P&{)J?WlCe@<3u^78wnd(Ja4^a>{^Tw}W>|Cjt^If|7l^l)^Q zbz|7~CF(k_9~n|h;ysZ+jHzkXf(*O*@5m zLzUmbHp=x!Q|!9NVXyipZ3)^GuIG$k;D)EK!a5=8MFLI_lpf`HPKl=-Ww%z8H_0$j ztJ||IfFG1lE9nmQ0+jPQy zCBdKkjArH@K7jVcMNz);Q(Q^R{d5G?-kk;Uu_IXSyWB)~KGIizZL(^&qF;|1PI7!E zTP`%l)gpX|OFn&)M%txpQ2F!hdA~hX1Cm5)IrdljqzRg!f{mN%G~H1&oqe`5eJCIF zHdD7O;AX-{XEV(a`gBFJ9ews#CVS2y!&>Cm_dm3C8*n3MA*e67(WC?uP@8TXuMroq z{#w$%z@CBIkRM7?}Xib+>hRjy?%G!fiw8! z8(gB+8J~KOU}yO7UGm&1g_MDJ$IXS!`+*b*QW2x)9>K~Y*E&bYMnjl6h!{17_8d!%&9D`a7r&LKZjC<&XOvTRaKJ1 zUY@hl5^R&kZl3lU3njk`3dPzxj$2foOL26r(9zsVF3n_F#v)s5vv3@dgs|lP#eylq62{<-vczqP!RpVBTgI>@O6&sU>W|do17+#OzQ7o5A$ICH z?GqwqnK^n2%LR;$^oZM;)+>$X3s2n}2jZ7CdWIW0lnGK-b#EG01)P@aU`pg}th&J-TrU`tIpb5t((0eu|!u zQz+3ZiOQ^?RxxK4;zs=l8q!-n7X{@jSwK(iqNFiRColuEOg}!7cyZi`iBX4g1pNBj zAPzL?P^Ljhn;1$r8?bc=#n|Ed7wB&oHcw()&*k#SS#h}jO?ZB246EGItsz*;^&tzp zu^YJ0=lwsi`eP_pU8}6JA7MS;9pfD;DsSsLo~ogzMNP70@@;Fm8f0^;>$Z>~}GWRw!W5J3tNX*^2+1f3hz{~rIzJo z6W%J(H!g-eI_J1>0juX$X4Cl6i+3wbc~k146UIX&G22}WE>0ga#WLsn9tY(&29zBvH1$`iWtTe zG2jYl@P!P)eb<5DsR72BdI7-zP&cZNI{7q3e@?N8IKc4DE#UVr->|-ryuJXk^u^>4 z$3wE~=q390;XuOQP~TNoDR?#|NSPJ%sTMInA6*rJ%go|=YjGe!B>z6u$IhgQSwoV* zjy3F2#I>uK{42{&IqP59)Y(1*Z>>#W8rCf4_eVsH)`v!P#^;BgzKDR`ARGEZzkNX+ zJUQu=*-ol=Xqqt5=`=pA@BIn@6a9G8C{c&`i^(i+BxQO9?YZ3iu%$$da&Kb?2kCCo zo7t$UpSFWqmydXf@l3bVJ=%K?SSw)|?srhJ-1ZdFu*5QhL$~-IQS!K1s@XzAtv6*Y zl8@(5BlWYLt1yAWy?rMD&bwze8bC3-GfNH=p zynNFCdxyX?K&G(ZZ)afguQ2|r;XoV^=^(;Cku#qYn4Lus`UeKt6rAlFo_rU`|Rq z&G?~iWMBio<78of-2X(ZYHx~=U0Vz4btyXkctMKdc9UM!vYr~B-(>)(Hc|D zMzkN4!PBg%tZoh+=Gba!0++d193gbMk2&krfDgcbx0jI92cq?FFESVg0D$>F+bil} zY~$)|>1HZsX=5sAZ2WgPB5P=8X#TI+NQ(M~GqyVB53c6IdX=k>Wu@A0Svf5#?uHaF zsYn|koIi3$(%GZ2+G+7Fv^lHTb#5b8sAHSTnL^qWZLM<(1|9|QFw9pnRU{svj}_Al zL)b9>fN{QiA($8peNEJyy`(a{&uh-T4_kdZFIVsKKVM(?05}76EEz?#W za^fiZOAd14IJ4zLX-n7Lq0qlQ^lW8Cvz4UKkV9~P}>sq0?xD3vg+$4vLm~C(+ zM{-3Z#qnZ09bJ>}j?6ry^h+@PfaD7*jZxBEY4)UG&daWb??6)TP+|3#Z&?GL?1i+280CFsE|vIXQbm| zM}Pk!U`U5NsNbyKzkrul-DzwB{X?n3E6?TUHr{M&+R*2%yOiXdW-_2Yd6?38M9Vy^ z*lE%gA{wwoSR~vN0=no}tP2Ul5Gk5M(Xq`$nw#ndFk`tcpd5A=Idue`XZ!FS>Q zG^0w#>P4pPG+*NC9gLP4x2m=cKP}YuS!l^?sHSFftZy{4CoQrb_ z^20(NnG`wAhMI=eq)SsIE~&Gp9Ne0nD4%Xiu|0Fj1UFk?6avDqjdXz{O1nKao*46y zT8~iA%Exu=G#{x=KD;_C&M+Zx4+n`sHT>^>=-1YM;H<72k>$py1?F3#T1*ef9mLZw z5naLQr?n7K;2l+{_uIw*_1nsTn~I|kkCgrn;|G~##hM;9l7Jy$yJfmk+&}W@JeKcF zx@@Woiz8qdi|D%aH3XTx5*wDlbs?dC1_nrFpm^QbG@wM=i2?Zg;$VK!c^Dp8<}BTI zyRhAq@#%2pGV49*Y5_mV4+OICP|%I(dQ7x=6Ob}>EjnB_-_18*xrY?b%-yEDT(wrO z9RY2QT0`_OpGfMObKHV;QLVnrK%mc?$WAdIT`kJQT^n%GuzE7|9@k3ci5fYOh(287 zuIbg!GB3xLg$YN=n)^pHGB0jH+_iIiC=nUcD;G6LuJsjn2VI1cyZx=a?ShCsF==QK z;q~*m&}L<-cb+mDDXzvvrRsybcgQ;Vg21P(uLv5I+eGc7o7tc6`;OA9{soHFOz zT~2?>Ts}gprIX$wRBb4yE>ot<8+*Bv`qbSDv*VtRi|cyWS>)Fjs>fkNOH-+PX&4(~ z&)T8Zam2L6puQl?;5zg9h<}k4#|yH9czHw;1jw-pwBM*O2hUR6yvHATrI%^mvs9q_ z&ccT0>f#eDG<^WG^q@oVqlJrhxH)dcq2cty@l3~|5#UDdExyXUmLQ}f4#;6fI{f^t zDCsgIJ~0`af%YR%Ma5VQq-p21k`vaBu6WE?66+5=XUd%Ay%D$irN>5LhluRWt7 zov-=f>QbMk*G##&DTQyou$s7UqjjW@k6=!I@!k+S{pP8R(2=e@io;N8E`EOB;OGoI zw6Q+{X1_I{OO0HPpBz!X!@`5YQ2)t{+!?M_iH25X(d~-Zx~cXnS9z>u?+If|iNJbx zyFU2d1!ITX64D|lE0Z{dLRqL1Ajj=CCMfC4lD3&mYR_R_VZ>_7_~|<^o*%_&jevU+ zQ4|qzci=0}Jydw|LXLCrOl1_P6Xf@c0$ieK2^7@A9UbF{@V_0p%lqW|L?5k>bVM8|p5v&2g;~r>B8uo<4N+`B zH{J)h;SYiIVx@#jI&p-v3dwL5QNV1oxPr8J%ooezTnLW>i*3Isb49%5i!&ac_dEXv zvXmVUck^QHmyrF8>CGXijC_R-y(Qr{3Zt~EmW)-nC!tiH`wlw5D*W7Pip;T?&j%kX z6DkZX4&}iw>hE(boLyjOoupf6JpvBG8}jIh!!VhnD0>}KSMMo{1#uU6kiFcA04~|7 zVO8eI&x1`g4CZ<2cYUI(n#wz2MtVFHx47yE5eL~8bot~>EHbevSt}LLMQX?odD{Ux zJMnam{d)W4da{l7&y-JrgiU~qY3$~}_F#G7|MxT)e;G{U`In&?`j<5D->}cb{}{T(4DF0BOk-=1195KB-E*o@c?`>y#4=dMtYtSY=&L{!TAjFVcq0y@AH`vH! z$41+u!Ld&}F^COPgL(EE{0X7LY&%D7-(?!kjFF7=qw<;`V{nwWBq<)1QiGJgUc^Vz ztMUlq1bZqKn17|6x6iAHbWc~l1HcmAxr%$Puv!znW)!JiukwIrqQ00|H$Z)OmGG@= zv%A8*4cq}(?qn4rN6o`$Y))(MyXr8R<2S^J+v(wmFmtac!%VOfN?&(8Nr!T@kV`N; z*Q33V3t`^rN&aBiHet)18wy{*wi1=W!B%B-Q6}SCrUl$~Hl{@!95ydml@FK8P=u4s z4e*7gV2s=YxEvskw2Ju!2%{8h01rx-3`NCPc(O zH&J0VH5etNB2KY6k4R@2Wvl^Ck$MoR3=)|SEclT2ccJ!RI9Nuter7u9@;sWf-%um;GfI!=eEIQ2l2p_YWUd{|6EG ze{yO6;lMc>;2tPrsNdi@&1K6(1;|$xe8vLgiouj%QD%gYk`4p{Ktv9|j+!OF-P?@p z;}SV|oIK)iwlBs+`ROXkhd&NK zzo__r!B>tOXpBJMDcv!Mq54P+n4(@dijL^EpO1wdg~q+!DT3lB<>9AANSe!T1XgC=J^)IP0XEZ()_vpu!!3HQyJhwh?r`Ae%Yr~b% zO*NY9t9#qWa@GCPYOF9aron7thfWT`eujS4`t2uG6)~JRTI;f(ZuoRQwjZjp5Pg34 z)rp$)Kr?R+KdJ;IO;pM{$6|2y=k_siqvp%)2||cHTe|b5Ht8&A{wazGNca zX$Ol?H)E_R@SDi~4{d-|8nGFhZPW;Cts1;08TwUvLLv&_2$O6Vt=M)X;g%HUr$&06 zISZb(6)Q3%?;3r~*3~USIg=HcJhFtHhIV(siOwV&QkQe#J%H9&E21!C*d@ln3E@J* zVqRO^<)V^ky-R|%{(9`l-(JXq9J)1r$`uQ8a}$vr9E^nNiI*thK8=&UZ0dsFN_eSl z(q~lnD?EymWLsNa3|1{CRPW60>DSkY9YQ;$4o3W7Ms&@&lv9eH!tk~N&dhqX&>K@} zi1g~GqglxkZ5pEFkllJ)Ta1I^c&Bt6#r(QLQ02yHTaJB~- zCcE=5tmi`UA>@P=1LBfBiqk)HB4t8D?02;9eXj~kVPwv?m{5&!&TFYhu>3=_ zsGmYZ^mo*-j69-42y&Jj0cBLLEulNRZ9vXE)8~mt9C#;tZs;=#M=1*hebkS;7(aGf zcs7zH(I8Eui9UU4L--))yy`&d&$In&VA2?DAEss4LAPCLd>-$i?lpXvn!gu^JJ$(DoUlc6wE98VLZ*z`QGQov5l4Fm_h?V-;mHLYDVOwKz7>e4+%AzeO>P6v}ndPW| zM>m#6Tnp7K?0mbK=>gV}=@k*0Mr_PVAgGMu$j+pWxzq4MAa&jpCDU&-5eH27Iz>m^ zax1?*HhG%pJ((tkR(V(O(L%7v7L%!_X->IjS3H5kuXQT2!ow(;%FDE>16&3r){!ex zhf==oJ!}YU89C9@mfDq!P3S4yx$aGB?rbtVH?sHpg?J5C->!_FHM%Hl3#D4eplxzQ zRA+<@LD%LKSkTk2NyWCg7u=$%F#;SIL44~S_OGR}JqX}X+=bc@swpiClB`Zbz|f!4 z7Ysah7OkR8liXfI`}IIwtEoL}(URrGe;IM8%{>b1SsqXh)~w}P>yiFRaE>}rEnNkT z!HXZUtxUp1NmFm)Dm@-{FI^aRQqpSkz}ZSyKR%Y}YHNzBk)ZIp} zMtS=aMvkgWKm9&oTcU0?S|L~CDqA+sHpOxwnswF-fEG)cXCzUR?ps@tZa$=O)=L+5 zf%m58cq8g_o}3?Bhh+c!w4(7AjxwQ3>WnVi<{{38g7yFboo>q|+7qs<$8CPXUFAN< zG&}BHbbyQ5n|qqSr?U~GY{@GJ{(Jny{bMaOG{|IkUj7tj^9pa9|FB_<+KHLxSxR;@ zHpS$4V)PP+tx}22fWx(Ku9y+}Ap;VZqD0AZW4gCDTPCG=zgJmF{|x;(rvdM|2|9a}cex6xrMkERnkE;}jvU-kmzd%_J50$M`lIPCKf+^*zL=@LW`1SaEc%=m zQ+lT06Gw+wVwvQ9fZ~#qd430v2HndFsBa9WjD0P}K(rZYdAt^5WQIvb%D^Q|pkVE^ zte$&#~zmULFACGfS#g=2OLOnIf2Of-k!(BIHjs77nr!5Q1*I9 z1%?=~#Oss!rV~?-6Gm~BWJiA4mJ5TY&iPm_$)H1_rTltuU1F3I(qTQ^U$S>%$l z)Wx1}R?ij0idp@8w-p!Oz{&*W;v*IA;JFHA9%nUvVDy7Q8woheC#|8QuDZb-L_5@R zOqHwrh|mVL9b=+$nJxM`3eE{O$sCt$UK^2@L$R(r^-_+z?lOo+me-VW=Zw z-Bn>$4ovfWd%SPY`ab-u9{INc*k2h+yH%toDHIyqQ zO68=u`N}RIIs7lsn1D){)~%>ByF<>i@qFb<-axvu(Z+6t7v<^z&gm9McRB~BIaDn$ z#xSGT!rzgad8o>~kyj#h1?7g96tOcCJniQ+*#=b7wPio>|6a1Z?_(TS{)KrPe}(8j z!#&A=k(&Pj^F;r)CI=Z{LVu>uj!_W1q4b`N1}E(i%;BWjbEcnD=mv$FL$l?zS6bW!{$7j1GR5ocn94P2u{ z70tAAcpqtQo<@cXw~@i-@6B23;317|l~S>CB?hR5qJ%J3EFgyBdJd^fHZu7AzHF(BQ!tyAz^L0`X z23S4Fe{2X$W0$zu9gm%rg~A>ijaE#GlYlrF9$ds^QtaszE#4M(OLVP2O-;XdT(XIC zatwzF*)1c+t~c{L=fMG8Z=k5lv>U0;C{caN1NItnuSMp)6G3mbahu>E#sj&oy94KC zpH}8oEw{G@N3pvHhp{^-YaZeH;K+T_1AUv;IKD<=mv^&Ueegrb!yf`4VlRl$M?wsl zZyFol(2|_QM`e_2lYSABpKR{{NlxlDSYQNkS;J66aT#MSiTx~;tUmvs-b*CrR4w=f z8+0;*th6kfZ3|5!Icx3RV11sp=?`0Jy3Fs0N4GZQMN=8HmT6%x9@{Dza)k}UwL6JT zHRDh;%!XwXr6yuuy`4;Xsn0zlR$k%r%9abS1;_v?`HX_hI|+EibVnlyE@3aL5vhQq zlIG?tN^w@0(v9M*&L+{_+RQZw=o|&BRPGB>e5=ys7H`nc8nx)|-g;s7mRc7hg{GJC zAe^vCIJhajmm7C6g! zL&!WAQ~5d_5)00?w_*|*H>3$loHrvFbitw#WvLB!JASO?#5Ig5$Ys10n>e4|3d;tS zELJ0|R4n3Az(Fl3-r^QiV_C;)lQ1_CW{5bKS15U|E9?ZgLec@%kXr84>5jV2a5v=w z?pB1GPdxD$IQL4)G||B_lI+A=08MUFFR4MxfGOu07vfIm+j=z9tp~5i_6jb`tR>qV z$#`=BQ*jpCjm$F0+F)L%xRlnS%#&gro6PiRfu^l!EVan|r3y}AHJQOORGx4~ z&<)3=K-tx518DZyp%|!EqpU!+X3Et7n2AaC5(AtrkW>_57i}$eqs$rupubg0a1+WO zGHZKLN2L0D;ab%{_S1Plm|hx8R?O14*w*f&2&bB050n!R2by zw!@XOQx$SqZ5I<(Qu$V6g>o#A!JVwErWv#(Pjx=KeS0@hxr4?13zj#oWwPS(7Ro|v z>Mp@Kmxo79q|}!5qtX2-O@U&&@6s~!I&)1WQIl?lTnh6UdKT_1R640S4~f=_xoN3- zI+O)$R@RjV$F=>Ti7BlnG1-cFKCC(t|Qjm{SalS~V-tX#+2ekRhwmN zZr`8{QF6y~Z!D|{=1*2D-JUa<(1Z=;!Ei!KiRNH?o{p5o3crFF=_pX9O-YyJchr$~ zRC`+G+8kx~fD2k*ZIiiIGR<8r&M@3H?%JVOfE>)})7ScOd&?OjgAGT@WVNSCZ8N(p zuQG~76GE3%(%h1*vUXg$vH{ua0b`sQ4f0*y=u~lgyb^!#CcPJa2mkSEHGLsnO^kb$ zru5_l#nu=Y{rSMWiYx?nO{8I!gH+?wEj~UM?IrG}E|bRIBUM>UlY<`T1EHpRr36vv zBi&dG8oxS|J$!zoaq{+JpJy+O^W(nt*|#g32bd&K^w-t>!Vu9N!k9eA8r!Xc{utY> zg9aZ(D2E0gL#W0MdjwES-7~Wa8iubPrd?8-$C4BP?*wok&O8+ykOx{P=Izx+G~hM8 z*9?BYz!T8~dzcZr#ux8kS7u7r@A#DogBH8km8Ry4slyie^n|GrTbO|cLhpqgMdsjX zJ_LdmM#I&4LqqsOUIXK8gW;V0B(7^$y#h3h>J0k^WJfAMeYek%Y-Dcb_+0zPJez!GM zAmJ1u;*rK=FNM0Nf}Y!!P9c4)HIkMnq^b;JFd!S3?_Qi2G#LIQ)TF|iHl~WKK6JmK zbv7rPE6VkYr_%_BT}CK8h=?%pk@3cz(UrZ{@h40%XgThP*-Oeo`T0eq9 zA8BnWZKzCy5e&&_GEsU4*;_k}(8l_&al5K-V*BFM=O~;MgRkYsOs%9eOY6s6AtE*<7GQAR2ulC3RAJrG_P1iQK5Z~&B z&f8X<>yJV6)oDGIlS$Y*D^Rj(cszTy5c81a5IwBr`BtnC6_e`ArI8CaTX_%rx7;cn zR-0?J_LFg*?(#n~G8cXut(1nVF0Oka$A$1FGcERU<^ggx;p@CZc?3UB41RY+wLS`LWFNSs~YP zuw1@DNN3lTd|jDL7gjBsd9}wIw}4xT2+8dBQzI00m<@?c2L%>}QLfK5%r!a-iII`p zX@`VEUH)uj^$;7jVUYdADQ2k*!1O3WdfgF?OMtUXNpQ1}QINamBTKDuv19^{$`8A1 zeq%q*O0mi@(%sZU>Xdb0Ru96CFqk9-L3pzLVsMQ`Xpa~N6CR{9Rm2)A|CI21L(%GW zh&)Y$BNHa=FD+=mBw3{qTgw)j0b!Eahs!rZnpu)z!!E$*eXE~##yaXz`KE5(nQM`s zD!$vW9XH)iMxu9R>r$VlLk9oIR%HxpUiW=BK@4U)|1WNQ=mz9a z^!KkO=>GaJ!GBXm{KJj^;kh-MkUlEQ%lza`-G&}C5y1>La1sR6hT=d*NeCnuK%_LV zOXt$}iP6(YJKc9j-Fxq~*ItVUqljQ8?oaysB-EYtFQp9oxZ|5m0^Hq(qV!S+hq#g( z?|i*H2MIr^Kxgz+3vIljQ*Feejy6S4v~jKEPTF~Qhq!(ms5>NGtRgO5vfPPc4Z^AM zTj!`5xEreIN)vaNxa|q6qWdg>+T`Ol0Uz)ckXBXEGvPNEL3R8hB3=C5`@=SYgAju1 z!)UBr{2~=~xa{b8>x2@C7weRAEuatC)3pkRhT#pMPTpSbA|tan%U7NGMvzmF?c!V8 z=pEWxbdXbTAGtWTyI?Fml%lEr-^AE}w#l(<7OIw;ctw}imYax&vR4UYNJZK6P7ZOd zP87XfhnUHxCUHhM@b*NbTi#(-8|wcv%3BGNs#zRCVV(W?1Qj6^PPQa<{yaBwZ`+<`w|;rqUY_C z&AeyKwwf*q#OW-F()lir=T^<^wjK65Lif$puuU5+tk$;e_EJ;Lu+pH>=-8=PDhkBg z8cWt%@$Sc#C6F$Vd+0507;{OOyT7Hs%nKS88q-W!$f~9*WGBpHGgNp}=C*7!RiZ5s zn1L_DbKF@B8kwhDiLKRB@lsXVVLK|ph=w%_`#owlf@s@V(pa`GY$8h%;-#h@TsO|Y8V=n@*!Rog7<7Cid%apR|x zOjhHCyfbIt%+*PCveTEcuiDi%Wx;O;+K=W?OFUV%)%~6;gl?<0%)?snDDqIvkHF{ zyI02)+lI9ov42^hL>ZRrh*HhjF9B$A@=H94iaBESBF=eC_KT$8A@uB^6$~o?3Wm5t1OIaqF^~><2?4e3c&)@wKn9bD? zoeCs;H>b8DL^F&>Xw-xjZEUFFTv>JD^O#1E#)CMBaG4DX9bD(Wtc8Rzq}9soQ8`jf zeSnHOL}<+WVSKp4kkq&?SbETjq6yr@4%SAqOG=9E(3YeLG9dtV+8vmzq+6PFPk{L; z(&d++iu=^F%b+ea$i2UeTC{R*0Isk;vFK!no<;L+(`y`3&H-~VTdKROkdyowo1iqR zbVW(3`+(PQ2>TKY>N!jGmGo7oeoB8O|P_!Ic@ zZ^;3dnuXo;WJ?S+)%P>{Hcg!Jz#2SI(s&dY4QAy_vRlmOh)QHvs_7c&zkJCmJGVvV zX;Mtb>QE+xp`KyciG$Cn*0?AK%-a|=o!+7x&&yzHQOS>8=B*R=niSnta^Pxp1`=md z#;$pS$4WCT?mbiCYU?FcHGZ#)kHVJTTBt^%XE(Q};aaO=Zik0UgLcc0I(tUpt(>|& zcxB_|fxCF7>&~5eJ=Dpn&5Aj{A^cV^^}(7w#p;HG&Q)EaN~~EqrE1qKrMAc&WXIE;>@<&)5;gD2?={Xf@Mvn@OJKw=8Mgn z!JUFMwD+s==JpjhroT&d{$kQAy%+d`a*XxDEVxy3`NHzmITrE`o!;5ClXNPb4t*8P zzAivdr{j_v!=9!^?T3y?gzmqDWX6mkzhIzJ-3S{T5bcCFMr&RPDryMcdwbBuZbsgN zGrp@^i?rcfN7v0NKGzDPGE#4yszxu=I_`MI%Z|10nFjU-UjQXXA?k8Pk|OE<(?ae) zE%vG#eZAlj*E7_3dx#Zz4kMLj>H^;}33UAankJiDy5ZvEhrjr`!9eMD8COp}U*hP+ zF}KIYx@pkccIgyxFm#LNw~G&`;o&5)2`5aogs`1~7cMZQ7zj!%L4E`2yzlQN6REX20&O<9 zKV6fyr)TScJPPzNTC2gL+0x#=u>(({{D7j)c-%tvqls3#Y?Z1m zV5WUE)zdJ{$p>yX;^P!UcXP?UD~YM;IRa#Rs5~l+*$&nO(;Ers`G=0D!twR(0GF@c zHl9E5DQI}Oz74n zfKP>&$q0($T4y$6w(p=ERAFh+>n%iaeRA%!T%<^+pg?M)@ucY<&59$x9M#n+V&>}=nO9wCV{O~lg&v#+jcUj(tQ z`0u1YH)-`U$15a{pBkGyPL0THv1P|4e@pf@3IBZS4dVJPo#H>pWq%Lr0YS-SeWash z8R7=jb28KPMI|_lo#GEO|5B?N_e``H*23{~a!AmUJ+fb4HX-%QI@lSEUxKlGV7z7Q zSKw@-TR>@1RL%w{x}dW#k1NgW+q4yt2Xf1J62Bx*O^WG8OJ|FqI4&@d3_o8Id@*)4 zYrk=>@!wv~mh7YWv*bZhxqSmFh2Xq)o=m;%n$I?GSz49l1$xRpPu_^N(vZ>*>Z<04 z2+rP70oM=NDysd!@fQdM2OcyT?3T^Eb@lIC-UG=Bw{BjQ&P`KCv$AcJ;?`vdZ4){d z&gkoUK{$!$$K`3*O-jyM1~p-7T*qb)Ys>Myt^;#1&a%O@x8A+E>! zY8=eD`ZG)LVagDLBeHg>=atOG?Kr%h4B%E6m@J^C+U|y)XX@f z8oyJDW|9g=<#f<{JRr{y#~euMnv)`7j=%cHWLc}ngjq~7k**6%4u>Px&W%4D94(r* z+akunK}O0DC2A%Xo9jyF;DobX?!1I(7%}@7F>i%&nk*LMO)bMGg2N+1iqtg+r(70q zF5{Msgsm5GS7DT`kBsjMvOrkx&|EU!{{~gL4d2MWrAT=KBQ-^zQCUq{5PD1orxlIL zq;CvlWx#f1NWvh`hg011I%?T_s!e38l*lWVt|~z-PO4~~1g)SrJ|>*tXh=QfXT)%( z+ex+inPvD&O4Ur;JGz>$sUOnWdpSLcm1X%aQDw4{dB!cnj`^muI$CJ2%p&-kULVCE z>$eMR36kN$wCPR+OFDM3-U(VOrp9k3)lI&YVFqd;Kpz~K)@Fa&FRw}L(SoD z9B4a+hQzZT-BnVltst&=kq6Y(f^S4hIGNKYBgMxGJ^;2yrO}P3;r)(-I-CZ)26Y6? z&rzHI_1GCvGkgy-t1E;r^3Le30|%$ebDRu2+gdLG)r=A~Qz`}~&L@aGJ{}vVs_GE* zVUjFnzHiXfKQbpv&bR&}l2bzIjAooB)=-XNcYmrGmBh(&iu@o!^hn0^#}m2yZZUK8 zufVm7Gq0y`Mj;9b>`c?&PZkU0j4>IL=UL&-Lp3j&47B5pAW4JceG{!XCA)kT<%2nqCxj<)uy6XR_uws~>_MEKPOpAQ!H zkn>FKh)<9DwwS*|Y(q?$^N!6(51O0 z^JM~Ax{AI1Oj$fs-S5d4T7Z_i1?{%0SsIuQ&r8#(JA=2iLcTN+?>wOL532%&dMYkT z*T5xepC+V6zxhS@vNbMoi|i)=rpli@R9~P!39tWbSSb904ekv7D#quKbgFEMTb48P zuq(VJ+&L8aWU(_FCD$3^uD!YM%O^K(dvy~Wm2hUuh6bD|#(I39Xt>N1Y{ZqXL`Fg6 zKQ?T2htHN!(Bx;tV2bfTtIj7e)liN-29s1kew>v(D^@)#v;}C4-G=7x#;-dM4yRWm zyY`cS21ulzMK{PoaQ6xChEZ}o_#}X-o}<&0)$1#3we?+QeLt;aVCjeA)hn!}UaKt< zat1fHEx13y-rXNMvpUUmCVzocPmN~-Y4(YJvQ#db)4|%B!rBsgAe+*yor~}FrNH08 z3V!97S}D7d$zbSD{$z;@IYMxM6aHdypIuS*pr_U6;#Y!_?0i|&yU*@16l z*dcMqDQgfNBf}?quiu4e>H)yTVfsp#f+Du0@=Kc41QockXkCkvu>FBd6Q+@FL!(Yx z2`YuX#eMEiLEDhp+9uFqME_E^faV&~9qjBHJkIp~%$x^bN=N)K@kvSVEMdDuzA0sn z88CBG?`RX1@#hQNd`o^V{37)!w|nA)QfiYBE^m=yQKv-fQF+UCMcuEe1d4BH7$?>b zJl-r9@0^Ie=)guO1vOd=i$_4sz>y3x^R7n4ED!5oXL3@5**h(xr%Hv)_gILarO46q+MaDOF%ChaymKoI6JU5Pg;7#2n9-18|S1;AK+ zgsn6;k6-%!QD>D?cFy}8F;r@z8H9xN1jsOBw2vQONVqBVEbkiNUqgw~*!^##ht>w0 zUOykwH=$LwX2j&nLy=@{hr)2O&-wm-NyjW7n~Zs9UlH;P7iP3 zI}S(r0YFVYacnKH(+{*)Tbw)@;6>%=&Th=+Z6NHo_tR|JCI8TJiXv2N7ei7M^Q+RM z?9o`meH$5Yi;@9XaNR#jIK^&{N|DYNNbtdb)XW1Lv2k{E>;?F`#Pq|&_;gm~&~Zc9 zf+6ZE%{x4|{YdtE?a^gKyzr}dA>OxQv+pq|@IXL%WS0CiX!V zm$fCePA%lU{%pTKD7|5NJHeXg=I0jL@$tOF@K*MI$)f?om)D63K*M|r`gb9edD1~Y zc|w7N)Y%do7=0{RC|AziW7#am$)9jciRJ?IWl9PE{G3U+$%FcyKs_0Cgq`=K3@ttV z9g;M!3z~f_?P%y3-ph%vBMeS@p7P&Ea8M@97+%XEj*(1E6vHj==d zjsoviB>j^$_^OI_DEPvFkVo(BGRo%cJeD){6Uckei=~1}>sp299|IRjhXe)%?uP0I zF5+>?0#Ye}T^Y$u_rc4=lPcq4K^D(TZG-w30-YiEM=dcK+4#o*>lJ8&JLi+3UcpZk z!^?95S^C0ja^jwP`|{<+3cBVog$(mRdQmadS+Vh~z zS@|P}=|z3P6uS+&@QsMp0no9Od&27O&14zHXGAOEy zh~OKpymK5C%;LLb467@KgIiVwYbYd6wFxI{0-~MOGfTq$nBTB!{SrWmL9Hs}C&l&l#m?s*{tA?BHS4mVKHAVMqm63H<|c5n0~k)-kbg zXidai&9ZUy0~WFYYKT;oe~rytRk?)r8bptITsWj(@HLI;@=v5|XUnSls7$uaxFRL+ zRVMGuL3w}NbV1`^=Pw*0?>bm8+xfeY(1PikW*PB>>Tq(FR`91N0c2&>lL2sZo5=VD zQY{>7dh_TX98L2)n{2OV=T10~*YzX27i2Q7W86M4$?gZIXZaBq#sA*{PH8){|GUi;oM>e?ua7eF4WFuFYZSG| zze?srg|5Ti8Og{O zeFxuw9!U+zhyk?@w zjsA6(oKD=Ka;A>Ca)oPORxK+kxH#O@zhC!!XS4@=swnuMk>t+JmLmFiE^1aX3f<)D@`%K0FGK^gg1a1j>zi z2KhV>sjU7AX3F$SEqrXSC}fRx64GDoc%!u2Yag68Lw@w9v;xOONf@o)Lc|Uh3<21ctTYu-mFZuHk*+R{GjXHIGq3p)tFtQp%TYqD=j1&y)>@zxoxUJ!G@ zgI0XKmP6MNzw>nRxK$-Gbzs}dyfFzt>#5;f6oR27ql!%+{tr+(`(>%51|k`ML} zY4eE)Lxq|JMas(;JibNQds1bUB&r}ydMQXBY4x(^&fY_&LlQC)3hylc$~8&~|06-D z#T+%66rYbHX%^KuqJED_wuGB+=h`nWA!>1n0)3wZrBG3%`b^Ozv6__dNa@%V14|!D zQ?o$z5u0^8`giv%qE!BzZ!3j;BlDlJDk)h@9{nSQeEk!z9RGW) z${RSF3phEM*ce*>Xdp}585vj$|40=&S{S-GTiE?Op*vY&Lvr9}BO$XWy80IF+6@%n z5*2ueT_g@ofP#u5pxb7n*fv^Xtt7&?SRc{*2Ka-*!BuOpf}neHGCiHy$@Ka1^Dint z;DkmIL$-e)rj4o2WQV%Gy;Xg(_Bh#qeOsTM2f@KEe~4kJ8kNLQ+;(!j^bgJMcNhvklP5Z6I+9Fq@c&D~8Fb-4rmDT!MB5QC{Dsb;BharP*O;SF4& zc$wj-7Oep7#$WZN!1nznc@Vb<_Dn%ga-O#J(l=OGB`dy=Sy&$(5-n3zzu%d7E#^8`T@}V+5B;PP8J14#4cCPw-SQTdGa2gWL0*zKM z#DfSXs_iWOMt)0*+Y>Lkd=LlyoHjublNLefhKBv@JoC>P7N1_#> zv=mLWe96%EY;!ZGSQDbZWb#;tzqAGgx~uk+-$+2_8U`!ypbwXl z^2E-FkM1?lY@yt8=J3%QK+xaZ6ok=-y%=KXCD^0r!5vUneW>95PzCkOPO*t}p$;-> ze5j-BLT_;)cZQzR2CEsm@rU7GZfFtdp*a|g4wDr%8?2QkIGasRfDWT-Dvy*U{?IHT z*}wGnzdlSptl#ZF^sf)KT|BJs&kLG91^A6ls{CzFprZ6-Y!V0Xysh%9p%iMd7HLsS zN+^Un$tDV)T@i!v?3o0Fsx2qI(AX_$dDkBzQ@fRM%n zRXk6hb9Py#JXUs+7)w@eo;g%QQ95Yq!K_d=z{0dGS+pToEI6=Bo8+{k$7&Z zo4>PH(`ce8E-Ps&uv`NQ;U$%t;w~|@E3WVOCi~R4oj5wP?%<*1C%}Jq%a^q~T7u>K zML5AKfQDv6>PuT`{SrKHRAF+^&edg6+5R_#H?Lz3iGoWo#PCEd0DS;)2U({{X#zU^ zw_xv{4x7|t!S)>44J;KfA|DC?;uQ($l+5Vp7oeqf7{GBF9356nx|&B~gs+@N^gSdd zvb*>&W)|u#F{Z_b`f#GVtQ`pYv3#||N{xj1NgB<#=Odt6{eB%#9RLt5v zIi|0u70`#ai}9fJjKv7dE!9ZrOIX!3{$z_K5FBd-Kp-&e4(J$LD-)NMTp^_pB`RT; zftVVlK2g@+1Ahv2$D){@Y#cL#dUj9*&%#6 zd2m9{1NYp>)6=oAvqdCn5#cx{AJ%S8skUgMglu2*IAtd+z1>B&`MuEAS(D(<6X#Lj z?f4CFx$)M&$=7*>9v1ER4b6!SIz-m0e{o0BfkySREchp?WdVPpQCh!q$t>?rL!&Jg zd#heM;&~A}VEm8Dvy&P|J*eAV&w!&Nx6HFV&B8jJFVTmgLaswn!cx$&%JbTsloz!3 zMEz1d`k==`Ueub_JAy_&`!ogbwx27^ZXgFNAbx=g_I~5nO^r)}&myw~+yY*cJl4$I znNJ32M&K=0(2Dj_>@39`3=FX!v3nZHno_@q^!y}%(yw0PqOo=);6Y@&ylVe>nMOZ~ zd>j#QQSBn3oaWd;qy$&5(5H$Ayi)0haAYO6TH>FR?rhqHmNOO+(})NB zLI@B@v0)eq!ug`>G<@htRlp3n!EpU|n+G+AvXFrWSUsLMBfL*ZB`CRsIVHNTR&b?K zxBgsN0BjfB>UVcJ|x%=-zb%OV7lmZc& zxiupadZVF7)6QuhoY;;FK2b*qL0J-Rn-8!X4ZY$-ZSUXV5DFd7`T41c(#lAeLMoeT z4%g655v@7AqT!i@)Edt5JMbN(=Q-6{=L4iG8RA%}w;&pKmtWvI4?G9pVRp|RTw`g0 zD5c12B&A2&P6Ng~8WM2eIW=wxd?r7A*N+&!Be7PX3s|7~z=APxm=A?5 zt>xB4WG|*Td@VX{Rs)PV0|yK`oI3^xn(4c_j&vgxk_Y3o(-`_5o`V zRTghg6%l@(qodXN;dB#+OKJEEvhfcnc#BeO2|E(5df-!fKDZ!%9!^BJ_4)9P+9Dq5 zK1=(v?KmIp34r?z{NEWnLB3Px{XYwy-akun4F7xTRr2^zeYW{gcK9)>aJDdU5;w5@ zak=<+-PLH-|04pelTb%ULpuuuJC7DgyT@D|p{!V!0v3KpDnRjANN12q6SUR3mb9<- z>2r~IApQGhstZ!3*?5V z8#)hJ0TdZg0M-BK#nGFP>$i=qk82DO z7h;Ft!D5E15OgW)&%lej*?^1~2=*Z5$2VX>V{x8SC+{i10BbtUk9@I#Vi&hX)q

Q!LwySI{Bnv%Sm)yh{^sSVJ8&h_D-BJ_YZe5eCaAWU9b$O2c z$T|{vWVRtOL!xC0DTc(Qbe`ItNtt5hr<)VijD0{U;T#bUEp381_y`%ZIav?kuYG{iyYdEBPW=*xNSc;Rlt6~F4M`5G+VtOjc z*0qGzCb@gME5udTjJA-9O<&TWd~}ysBd(eVT1-H82-doyH9RST)|+Pb{o*;$j9Tjs zhU!IlsPsj8=(x3bAKJTopW3^6AKROHR^7wZ185wJGVhA~hEc|LP;k7NEz-@4p5o}F z`AD6naG3(n=NF9HTH81=F+Q|JOz$7wm9I<+#BSmB@o_cLt2GkW9|?7mM;r!JZp89l zbo!Hp8=n!XH1{GwaDU+k)pGp`C|cXkCU5%vcH)+v@0eK>%7gWxmuMu9YLlChA|_D@ zi#5zovN_!a-0?~pUV-Rj*1P)KwdU-LguR>YM&*Nen+ln8Q$?WFCJg%DY%K}2!!1FE zDv-A%Cbwo^p(lzac&_TZ-l#9kq`mhLcY3h9ZTUVCM(Ad&=EriQY5{jJv<5K&g|*Lk zgV%ILnf1%8V2B0E&;Sp4sYbYOvvMebLwYwzkRQ#F8GpTQq#uv=J`uaSJ34OWITeSGo6+-8Xw znCk*n{kdDEi)Hi&u^)~cs@iyCkFWB2SWZU|Uc%^43ZIZQ-vWNExCCtDWjqHs;;tWf$v{}0{p0Rvxkq``)*>+Akq%|Na zA`@~-Vfe|+(AIlqru+7Ceh4nsVmO9p9jc8}HX^W&ViBDXT+uXbT#R#idPn&L>+#b6 zflC-4C5-X;kUnR~L>PSLh*gvL68}RBsu#2l`s_9KjUWRhiqF`j)`y`2`YU(>3bdBj z?>iyjEhe-~$^I5!nn%B6Wh+I`FvLNvauve~eX<+Ipl&04 zT}};W&1a3%W?dJ2=N#0t?e+aK+%t}5q%jSLvp3jZ%?&F}nOOWr>+{GFIa%wO_2`et z=JzoRR~}iKuuR+azPI8;Gf9)z3kyA4EIOSl!sRR$DlW}0>&?GbgPojmjmnln;cTqCt=ADbE zZ8GAnoM+S1(5$i8^O4t`ue;vO4i}z0wz-QEIVe5_u03;}-!G1NyY8;h^}y;tzY}i5 zqQr#Ur3Fy8sSa$Q0ys+f`!`+>9WbvU_I`Sj;$4{S>O3?#inLHCrtLy~!s#WXV=oVP zeE93*Nc`PBi4q@%Ao$x4lw9vLHM!6mn3-b_cebF|n-2vt-zYVF_&sDE--J-P;2WHo z+@n2areE0o$LjvjlV2X7ZU@j+`{*8zq`JR3gKF#EW|#+{nMyo-a>nFFTg&vhyT=b} zDa8+v0(Dgx0yRL@ZXOYIlVSZ0|MFizy0VPW8;AfA5|pe!#j zX}Py^8fl5SyS4g1WSKKtnyP+_PoOwMMwu`(i@Z)diJp~U54*-miOchy7Z35eL>^M z4p<-aIxH4VUZgS783@H%M7P9hX>t{|RU7$n4T(brCG#h9e9p! z+o`i;EGGq3&pF;~5V~eBD}lC)>if$w%Vf}AFxGqO88|ApfHf&Bvu+xdG)@vuF}Yvk z)o;~k-%+0K0g+L`Wala!$=ZV|z$e%>f0%XoLib%)!R^RoS+{!#X?h-6uu zF&&KxORdZU&EwQFITIRLo(7TA3W}y6X{?Y%y2j0It!ekU#<)$qghZtpcS>L3uh`Uj z7GY;6f$9qKynP#oS3$$a{p^{D+0oJQ71`1?OAn_m8)UGZmj3l*ZI)`V-a>MKGGFG< z&^jg#Ok%(hhm>hSrZ5;Qga4u(?^i>GiW_j9%_7M>j(^|Om$#{k+^*ULnEgzW_1gCICtAD^WpC`A z{9&DXkG#01Xo)U$OC(L5Y$DQ|Q4C6CjUKk1UkPj$nXH##J{c8e#K|&{mA*;b$r0E4 zUNo0jthwA(c&N1l=PEe8Rw_8cEl|-eya9z&H3#n`B$t#+aJ03RFMzrV@gowbe8v(c zIFM60^0&lCFO10NU4w@|61xiZ4CVXeaKjd;d?sv52XM*lS8XiVjgWpRB;&U_C0g+`6B5V&w|O6B*_q zsATxL!M}+$He)1eOWECce#eS@2n^xhlB4<_Nn?yCVEQWDs(r`|@2GqLe<#(|&P0U? z$7V5IgpWf09uIf_RazRwC?qEqRaHyL?iiS05UiGesJy%^>-C{{ypTBI&B0-iUYhk> zIk<5xpsuV@g|z(AZD+C-;A!fTG=df1=<%nxy(a(IS+U{ME4ZbDEBtcD_3V=icT6*_ z)>|J?>&6%nvHhZERBtjK+s4xnut*@>GAmA5m*OTp$!^CHTr}vM4n(X1Q*;{e-Rd2BCF-u@1ZGm z!S8hJ6L=Gl4T_SDa7Xx|-{4mxveJg=ctf`BJ*fy!yF6Dz&?w(Q_6B}WQVtNI!BVBC zKfX<>7vd6C96}XAQmF-Jd?1Q4eTfRB3q7hCh0f!(JkdWT5<{iAE#dKy*Jxq&3a1@~ z8C||Dn2mFNyrUV|<-)C^_y7@8c2Fz+2jrae9deBDu;U}tJ{^xAdxCD248(k;dCJ%o z`y3sADe>U%suxwwv~8A1+R$VB=Q?%U?4joI$um;aH+eCrBqpn- z%79D_7rb;R-;-9RTrwi9dPlg8&@tfWhhZ(Vx&1PQ+6(huX`;M9x~LrW~~#3{j0Bh2kDU$}@!fFQej4VGkJv?M4rU^x!RU zEwhu$!CA_iDjFjrJa`aocySDX16?~;+wgav;}Zut6Mg%C4>}8FL?8)Kgwc(Qlj{@#2Pt0?G`$h7P#M+qoXtlV@d}%c&OzO+QYKK`kyXaK{U(O^2DyIXCZlNQjt0^8~8JzNGrIxhj}}M z&~QZlbx%t;MJ(Vux;2tgNKGlAqphLq%pd}JG9uoVHUo?|hN{pLQ6Em%r*+7t^<);X zm~6=qChlNAVXNN*Sow->*4;}T;l;D1I-5T{Bif@4_}=>l`tK;qqDdt5zvisCKhMAH z#r}`)7VW?LZqfdmXQ%zo5bJ00{Xb9^YKrk0Nf|oIW*K@(=`o2Vndz}ZDyk{!u}PVx zzd--+_WC*U{~DH3{?GI64IB+@On&@9X>EUAo&L+G{L^dozaI4C3G#2wr~hseW@K&g zKWs{uHu-9Je!3;4pE>eBltKUXb^*hG8I&413)$J&{D4N%7PcloU6bn%jPxJyQL?g* z9g+YFFEDiE`8rW^laCNzQmi7CTnPfwyg3VDHRAl>h=In6jeaVOP@!-CP60j3+#vpL zEYmh_oP0{-gTe7Or`L6x)6w?77QVi~jD8lWN@3RHcm80iV%M1A!+Y6iHM)05iC64tb$X2lV_%Txk@0l^hZqi^%Z?#- zE;LE0uFx)R08_S-#(wC=dS&}vj6P4>5ZWjhthP=*Hht&TdLtKDR;rXEX4*z0h74FA zMCINqrh3Vq;s%3MC1YL`{WjIAPkVL#3rj^9Pj9Ss7>7duy!9H0vYF%>1jh)EPqvlr6h%R%CxDsk| z!BACz7E%j?bm=pH6Eaw{+suniuY7C9Ut~1cWfOX9KW9=H><&kQlinPV3h9R>3nJvK z4L9(DRM=x;R&d#a@oFY7mB|m8h4692U5eYfcw|QKwqRsshN(q^v$4$)HgPpAJDJ`I zkqjq(8Cd!K!+wCd=d@w%~e$=gdUgD&wj$LQ1r>-E=O@c ze+Z$x{>6(JA-fNVr)X;*)40Eym1TtUZI1Pwwx1hUi+G1Jlk~vCYeXMNYtr)1?qwyg zsX_e*$h?380O00ou?0R@7-Fc59o$UvyVs4cUbujHUA>sH!}L54>`e` zHUx#Q+Hn&Og#YVOuo*niy*GU3rH;%f``nk#NN5-xrZ34NeH$l`4@t);4(+0|Z#I>Y z)~Kzs#exIAaf--65L0UHT_SvV8O2WYeD>Mq^Y6L!Xu8%vnpofG@w!}R7M28?i1*T&zp3X4^OMCY6(Dg<-! zXmcGQrRgHXGYre7GfTJ)rhl|rs%abKT_Nt24_Q``XH{88NVPW+`x4ZdrMuO0iZ0g` z%p}y};~T5gbb9SeL8BSc`SO#ixC$@QhXxZ=B}L`tP}&k?1oSPS=4%{UOHe0<_XWln zwbl5cn(j-qK`)vGHY5B5C|QZd5)W7c@{bNVXqJ!!n$^ufc?N9C-BF2QK1(kv++h!>$QbAjq)_b$$PcJdV+F7hz0Hu@ zqj+}m0qn{t^tD3DfBb~0B36|Q`bs*xs|$i^G4uNUEBl4g;op-;Wl~iThgga?+dL7s zUP(8lMO?g{GcYpDS{NM!UA8Hco?#}eNEioRBHy4`mq!Pd-9@-97|k$hpEX>xoX+dY zDr$wfm^P&}Wu{!%?)U_(%Mn79$(ywvu*kJ9r4u|MyYLI_67U7%6Gd_vb##Nerf@>& z8W11z$$~xEZt$dPG}+*IZky+os5Ju2eRi;1=rUEeIn>t-AzC_IGM-IXWK3^6QNU+2pe=MBn4I*R@A%-iLDCOHTE-O^wo$sL_h{dcPl=^muAQb`_BRm};=cy{qSkui;`WSsj9%c^+bIDQ z0`_?KX0<-=o!t{u(Ln)v>%VGL z0pC=GB7*AQ?N7N{ut*a%MH-tdtNmNC+Yf$|KS)BW(gQJ*z$d{+{j?(e&hgTy^2|AR9vx1Xre2fagGv0YXWqtNkg*v%40v?BJBt|f9wX5 z{QTlCM}b-0{mV?IG>TW_BdviUKhtosrBqdfq&Frdz>cF~yK{P@(w{Vr7z2qKFwLhc zQuogKO@~YwyS9%+d-zD7mJG~@?EFJLSn!a&mhE5$_4xBl&6QHMzL?CdzEnC~C3$X@ zvY!{_GR06ep5;<#cKCSJ%srxX=+pn?ywDwtJ2{TV;0DKBO2t++B(tIO4)Wh`rD13P z4fE$#%zkd=UzOB74gi=-*CuID&Z3zI^-`4U^S?dHxK8fP*;fE|a(KYMgMUo`THIS1f!*6dOI2 zFjC3O=-AL`6=9pp;`CYPTdVX z8(*?V&%QoipuH0>WKlL8A*zTKckD!paN@~hh zmXzm~qZhMGVdQGd=AG8&20HW0RGV8X{$9LldFZYm zE?}`Q3i?xJRz43S?VFMmqRyvWaS#(~Lempg9nTM$EFDP(Gzx#$r)W&lpFKqcAoJh-AxEw$-bjW>`_+gEi z2w`99#UbFZGiQjS8kj~@PGqpsPX`T{YOj`CaEqTFag;$jY z8_{Wzz>HXx&G*Dx<5skhpETxIdhKH?DtY@b9l8$l?UkM#J-Snmts7bd7xayKTFJ(u zyAT&@6cAYcs{PBfpqZa%sxhJ5nSZBPji?Zlf&}#L?t)vC4X5VLp%~fz2Sx<*oN<7` z?ge=k<=X7r<~F7Tvp9#HB{!mA!QWBOf%EiSJ6KIF8QZNjg&x~-%e*tflL(ji_S^sO ztmib1rp09uon}RcsFi#k)oLs@$?vs(i>5k3YN%$T(5Or(TZ5JW9mA6mIMD08=749$ z!d+l*iu{Il7^Yu}H;lgw=En1sJpCKPSqTCHy4(f&NPelr31^*l%KHq^QE>z>Ks_bH zjbD?({~8Din7IvZeJ>8Ey=e;I?thpzD=zE5UHeO|neioJwG;IyLk?xOz(yO&0DTU~ z^#)xcs|s>Flgmp;SmYJ4g(|HMu3v7#;c*Aa8iF#UZo7CvDq4>8#qLJ|YdZ!AsH%^_7N1IQjCro

K7UpUK$>l@ zw`1S}(D?mUXu_C{wupRS-jiX~w=Uqqhf|Vb3Cm9L=T+w91Cu^ z*&Ty%sN?x*h~mJc4g~k{xD4ZmF%FXZNC;oVDwLZ_WvrnzY|{v8hc1nmx4^}Z;yriXsAf+Lp+OFLbR!&Ox?xABwl zu8w&|5pCxmu#$?Cv2_-Vghl2LZ6m7}VLEfR5o2Ou$x02uA-%QB2$c(c1rH3R9hesc zfpn#oqpbKuVsdfV#cv@5pV4^f_!WS+F>SV6N0JQ9E!T90EX((_{bSSFv9ld%I0&}9 zH&Jd4MEX1e0iqDtq~h?DBrxQX1iI0lIs<|kB$Yrh&cpeK0-^K%=FBsCBT46@h#yi!AyDq1V(#V}^;{{V*@T4WJ&U-NTq43w=|K>z8%pr_nC>%C(Wa_l78Ufib$r8Od)IIN=u>417 z`Hl{9A$mI5A(;+-Q&$F&h-@;NR>Z<2U;Y21>>Z;s@0V@SbkMQQj%_;~+qTuQ?c|AV zcWm3XZQHhP&R%QWarS%mJ!9R^&!_)*s(v+VR@I#QrAT}`17Y+l<`b-nvmDNW`De%y zrwTZ9EJrj1AFA>B`1jYDow}~*dfPs}IZMO3=a{Fy#IOILc8F0;JS4x(k-NSpbN@qM z`@aE_e}5{!$v3+qVs7u?sOV(y@1Os*Fgu`fCW9=G@F_#VQ%xf$hj0~wnnP0$hFI+@ zkQj~v#V>xn)u??YutKsX>pxKCl^p!C-o?+9;!Nug^ z{rP!|+KsP5%uF;ZCa5F;O^9TGac=M|=V z_H(PfkV1rz4jl?gJ(ArXMyWT4y(86d3`$iI4^l9`vLdZkzpznSd5Ikfrs8qcSy&>z zTIZgWZGXw0n9ibQxYWE@gI0(3#KA-dAdPcsL_|hg2@~C!VZDM}5;v_Nykfq!*@*Zf zE_wVgx82GMDryKO{U{D>vSzSc%B~|cjDQrt5BN=Ugpsf8H8f1lR4SGo#hCuXPL;QQ z#~b?C4MoepT3X`qdW2dNn& zo8)K}%Lpu>0tQei+{>*VGErz|qjbK#9 zvtd8rcHplw%YyQCKR{kyo6fgg!)6tHUYT(L>B7er5)41iG`j$qe*kSh$fY!PehLcD zWeKZHn<492B34*JUQh=CY1R~jT9Jt=k=jCU2=SL&&y5QI2uAG2?L8qd2U(^AW#{(x zThSy=C#>k+QMo^7caQcpU?Qn}j-`s?1vXuzG#j8(A+RUAY})F@=r&F(8nI&HspAy4 z4>(M>hI9c7?DCW8rw6|23?qQMSq?*Vx?v30U%luBo)B-k2mkL)Ljk5xUha3pK>EEj z@(;tH|M@xkuN?gsz;*bygizwYR!6=(Xgcg^>WlGtRYCozY<rFX2E>kaZo)O<^J7a`MX8Pf`gBd4vrtD|qKn&B)C&wp0O-x*@-|m*0egT=-t@%dD zgP2D+#WPptnc;_ugD6%zN}Z+X4=c61XNLb7L1gWd8;NHrBXwJ7s0ce#lWnnFUMTR& z1_R9Fin4!d17d4jpKcfh?MKRxxQk$@)*hradH2$3)nyXep5Z;B z?yX+-Bd=TqO2!11?MDtG0n(*T^!CIiF@ZQymqq1wPM_X$Iu9-P=^}v7npvvPBu!d$ z7K?@CsA8H38+zjA@{;{kG)#AHME>Ix<711_iQ@WWMObXyVO)a&^qE1GqpP47Q|_AG zP`(AD&r!V^MXQ^e+*n5~Lp9!B+#y3#f8J^5!iC@3Y@P`;FoUH{G*pj*q7MVV)29+j z>BC`a|1@U_v%%o9VH_HsSnM`jZ-&CDvbiqDg)tQEnV>b%Ptm)T|1?TrpIl)Y$LnG_ zzKi5j2Fx^K^PG1=*?GhK;$(UCF-tM~^=Z*+Wp{FSuy7iHt9#4n(sUuHK??@v+6*|10Csdnyg9hAsC5_OrSL;jVkLlf zHXIPukLqbhs~-*oa^gqgvtpgTk_7GypwH><53riYYL*M=Q@F-yEPLqQ&1Sc zZB%w}T~RO|#jFjMWcKMZccxm-SL)s_ig?OC?y_~gLFj{n8D$J_Kw%{r0oB8?@dWzn zB528d-wUBQzrrSSLq?fR!K%59Zv9J4yCQhhDGwhptpA5O5U?Hjqt>8nOD zi{)0CI|&Gu%zunGI*XFZh(ix)q${jT8wnnzbBMPYVJc4HX*9d^mz|21$=R$J$(y7V zo0dxdbX3N#=F$zjstTf*t8vL)2*{XH!+<2IJ1VVFa67|{?LP&P41h$2i2;?N~RA30LV`BsUcj zfO9#Pg1$t}7zpv#&)8`mis3~o+P(DxOMgz-V*(?wWaxi?R=NhtW}<#^Z?(BhSwyar zG|A#Q7wh4OfK<|DAcl9THc-W4*>J4nTevsD%dkj`U~wSUCh15?_N@uMdF^Kw+{agk zJ`im^wDqj`Ev)W3k3stasP`88-M0ZBs7;B6{-tSm3>I@_e-QfT?7|n0D~0RRqDb^G zyHb=is;IwuQ&ITzL4KsP@Z`b$d%B0Wuhioo1CWttW8yhsER1ZUZzA{F*K=wmi-sb#Ju+j z-l@In^IKnb{bQG}Ps>+Vu_W#grNKNGto+yjA)?>0?~X`4I3T@5G1)RqGUZuP^NJCq&^HykuYtMDD8qq+l8RcZNJsvN(10{ zQ1$XcGt}QH-U^WU!-wRR1d--{B$%vY{JLWIV%P4-KQuxxDeJaF#{eu&&r!3Qu{w}0f--8^H|KwE>)ORrcR+2Qf zb})DRcH>k0zWK8@{RX}NYvTF;E~phK{+F;MkIP$)T$93Ba2R2TvKc>`D??#mv9wg$ zd~|-`Qx5LwwsZ2hb*Rt4S9dsF%Cny5<1fscy~)d;0m2r$f=83<->c~!GNyb!U)PA; zq^!`@@)UaG)Ew(9V?5ZBq#c%dCWZrplmuM`o~TyHjAIMh0*#1{B>K4po-dx$Tk-Cq z=WZDkP5x2W&Os`N8KiYHRH#UY*n|nvd(U>yO=MFI-2BEp?x@=N<~CbLJBf6P)}vLS?xJXYJ2^<3KJUdrwKnJnTp{ zjIi|R=L7rn9b*D#Xxr4*R<3T5AuOS+#U8hNlfo&^9JO{VbH!v9^JbK=TCGR-5EWR@ zN8T-_I|&@A}(hKeL4_*eb!1G8p~&_Im8|wc>Cdir+gg90n1dw?QaXcx6Op_W1r=axRw>4;rM*UOpT#Eb9xU1IiWo@h?|5uP zka>-XW0Ikp@dIe;MN8B01a7+5V@h3WN{J=HJ*pe0uwQ3S&MyWFni47X32Q7SyCTNQ z+sR!_9IZa5!>f&V$`q!%H8ci!a|RMx5}5MA_kr+bhtQy{-^)(hCVa@I!^TV4RBi zAFa!Nsi3y37I5EK;0cqu|9MRj<^r&h1lF}u0KpKQD^5Y+LvFEwM zLU@@v4_Na#Axy6tn3P%sD^5P#<7F;sd$f4a7LBMk zGU^RZHBcxSA%kCx*eH&wgA?Qwazm8>9SCSz_!;MqY-QX<1@p$*T8lc?@`ikEqJ>#w zcG``^CoFMAhdEXT9qt47g0IZkaU)4R7wkGs^Ax}usqJ5HfDYAV$!=6?>J6+Ha1I<5 z|6=9soU4>E))tW$<#>F ziZ$6>KJf0bPfbx_)7-}tMINlc=}|H+$uX)mhC6-Hz+XZxsKd^b?RFB6et}O#+>Wmw9Ec9) z{q}XFWp{3@qmyK*Jvzpyqv57LIR;hPXKsrh{G?&dRjF%Zt5&m20Ll?OyfUYC3WRn{cgQ?^V~UAv+5 z&_m#&nIwffgX1*Z2#5^Kl4DbE#NrD&Hi4|7SPqZ}(>_+JMz=s|k77aEL}<=0Zfb)a z%F(*L3zCA<=xO)2U3B|pcTqDbBoFp>QyAEU(jMu8(jLA61-H!ucI804+B!$E^cQQa z)_ERrW3g!B9iLb3nn3dlkvD7KsY?sRvls3QC0qPi>o<)GHx%4Xb$5a3GBTJ(k@`e@ z$RUa^%S15^1oLEmA=sayrP5;9qtf!Z1*?e$ORVPsXpL{jL<6E)0sj&swP3}NPmR%FM?O>SQgN5XfHE< zo(4#Cv11(%Nnw_{_Ro}r6=gKd{k?NebJ~<~Kv0r(r0qe4n3LFx$5%x(BKvrz$m?LG zjLIc;hbj0FMdb9aH9Lpsof#yG$(0sG2%RL;d(n>;#jb!R_+dad+K;Ccw!|RY?uS(a zj~?=&M!4C(5LnlH6k%aYvz@7?xRa^2gml%vn&eKl$R_lJ+e|xsNfXzr#xuh(>`}9g zLHSyiFwK^-p!;p$yt7$F|3*IfO3Mlu9e>Dpx8O`37?fA`cj`C0B-m9uRhJjs^mRp# zWB;Aj6|G^1V6`jg7#7V9UFvnB4((nIwG?k%c7h`?0tS8J3Bn0t#pb#SA}N-|45$-j z$R>%7cc2ebAClXc(&0UtHX<>pd)akR3Kx_cK+n<}FhzmTx!8e9^u2e4%x{>T6pQ`6 zO182bh$-W5A3^wos0SV_TgPmF4WUP-+D25KjbC{y_6W_9I2_vNKwU(^qSdn&>^=*t z&uvp*@c8#2*paD!ZMCi3;K{Na;I4Q35zw$YrW5U@Kk~)&rw;G?d7Q&c9|x<Hg|CNMsxovmfth*|E*GHezPTWa^Hd^F4!B3sF;)? z(NaPyAhocu1jUe(!5Cy|dh|W2=!@fNmuNOzxi^tE_jAtzNJ0JR-avc_H|ve#KO}#S z#a(8secu|^Tx553d4r@3#6^MHbH)vmiBpn0X^29xEv!Vuh1n(Sr5I0V&`jA2;WS|Y zbf0e}X|)wA-Pf5gBZ>r4YX3Mav1kKY(ulAJ0Q*jB)YhviHK)w!TJsi3^dMa$L@^{` z_De`fF4;M87vM3Ph9SzCoCi$#Fsd38u!^0#*sPful^p5oI(xGU?yeYjn;Hq1!wzFk zG&2w}W3`AX4bxoVm03y>ts{KaDf!}b&7$(P4KAMP=vK5?1In^-YYNtx1f#}+2QK@h zeSeAI@E6Z8a?)>sZ`fbq9_snl6LCu6g>o)rO;ijp3|$vig+4t} zylEo7$SEW<_U+qgVcaVhk+4k+C9THI5V10qV*dOV6pPtAI$)QN{!JRBKh-D zk2^{j@bZ}yqW?<#VVuI_27*cI-V~sJiqQv&m07+10XF+#ZnIJdr8t`9s_EE;T2V;B z4UnQUH9EdX%zwh-5&wflY#ve!IWt0UE-My3?L#^Bh%kcgP1q{&26eXLn zTkjJ*w+(|_>Pq0v8{%nX$QZbf)tbJaLY$03;MO=Ic-uqYUmUCuXD>J>o6BCRF=xa% z3R4SK9#t1!K4I_d>tZgE>&+kZ?Q}1qo4&h%U$GfY058s%*=!kac{0Z+4Hwm!)pFLR zJ+5*OpgWUrm0FPI2ib4NPJ+Sk07j(`diti^i#kh&f}i>P4~|d?RFb#!JN)~D@)beox}bw?4VCf^y*`2{4`-@%SFTry2h z>9VBc9#JxEs1+0i2^LR@B1J`B9Ac=#FW=(?2;5;#U$0E0UNag_!jY$&2diQk_n)bT zl5Me_SUvqUjwCqmVcyb`igygB_4YUB*m$h5oeKv3uIF0sk}~es!{D>4r%PC*F~FN3owq5e0|YeUTSG#Vq%&Gk7uwW z0lDo#_wvflqHeRm*}l?}o;EILszBt|EW*zNPmq#?4A+&i0xx^?9obLyY4xx=Y9&^G;xYXYPxG)DOpPg!i_Ccl#3L}6xAAZzNhPK1XaC_~ z!A|mlo?Be*8Nn=a+FhgpOj@G7yYs(Qk(8&|h@_>w8Y^r&5nCqe0V60rRz?b5%J;GYeBqSAjo|K692GxD4` zRZyM2FdI+-jK2}WAZTZ()w_)V{n5tEb@>+JYluDozCb$fA4H)$bzg(Ux{*hXurjO^ zwAxc+UXu=&JV*E59}h3kzQPG4M)X8E*}#_&}w*KEgtX)cU{vm9b$atHa;s>| z+L6&cn8xUL*OSjx4YGjf6{Eq+Q3{!ZyhrL&^6Vz@jGbI%cAM9GkmFlamTbcQGvOlL zmJ?(FI)c86=JEs|*;?h~o)88>12nXlpMR4@yh%qdwFNpct;vMlc=;{FSo*apJ;p}! zAX~t;3tb~VuP|ZW;z$=IHf->F@Ml)&-&Bnb{iQyE#;GZ@C$PzEf6~q}4D>9jic@mTO5x76ulDz@+XAcm35!VSu zT*Gs>;f0b2TNpjU_BjHZ&S6Sqk6V1370+!eppV2H+FY!q*n=GHQ!9Rn6MjY!Jc77A zG7Y!lFp8?TIHN!LXO?gCnsYM-gQxsm=Ek**VmZu7vnuufD7K~GIxfxbsQ@qv2T zPa`tvHB$fFCyZl>3oYg?_wW)C>^_iDOc^B7klnTOoytQH18WkOk)L2BSD0r%xgRSW zQS9elF^?O=_@|58zKLK;(f77l-Zzu}4{fXed2saq!5k#UZAoDBqYQS{sn@j@Vtp|$ zG%gnZ$U|9@u#w1@11Sjl8ze^Co=)7yS(}=;68a3~g;NDe_X^}yJj;~s8xq9ahQ5_r zxAlTMnep*)w1e(TG%tWsjo3RR;yVGPEO4V{Zp?=a_0R#=V^ioQu4YL=BO4r0$$XTX zZfnw#_$V}sDAIDrezGQ+h?q24St0QNug_?{s-pI(^jg`#JRxM1YBV;a@@JQvH8*>> zIJvku74E0NlXkYe_624>znU0J@L<-c=G#F3k4A_)*;ky!C(^uZfj%WB3-*{*B$?9+ zDm$WFp=0(xnt6`vDQV3Jl5f&R(Mp};;q8d3I%Kn>Kx=^;uSVCw0L=gw53%Bp==8Sw zxtx=cs!^-_+i{2OK`Q;913+AXc_&Z5$@z3<)So0CU3;JAv=H?@Zpi~riQ{z-zLtVL z!oF<}@IgJp)Iyz1zVJ42!SPHSkjYNS4%ulVVIXdRuiZ@5Mx8LJS}J#qD^Zi_xQ@>DKDr-_e#>5h3dtje*NcwH_h;i{Sx7}dkdpuW z(yUCjckQsagv*QGMSi9u1`Z|V^}Wjf7B@q%j2DQXyd0nOyqg%m{CK_lAoKlJ7#8M} z%IvR?Vh$6aDWK2W!=i?*<77q&B8O&3?zP(Cs@kapc)&p7En?J;t-TX9abGT#H?TW? ztO5(lPKRuC7fs}zwcUKbRh=7E8wzTsa#Z{a`WR}?UZ%!HohN}d&xJ=JQhpO1PI#>X zHkb>pW04pU%Bj_mf~U}1F1=wxdBZu1790>3Dm44bQ#F=T4V3&HlOLsGH)+AK$cHk6 zia$=$kog?)07HCL*PI6}DRhpM^*%I*kHM<#1Se+AQ!!xyhcy6j7`iDX7Z-2i73_n# zas*?7LkxS-XSqv;YBa zW_n*32D(HTYQ0$feV_Fru1ZxW0g&iwqixPX3=9t4o)o|kOo79V$?$uh?#8Q8e>4e)V6;_(x&ViUVxma+i25qea;d-oK7ouuDsB^ab{ zu1qjQ%`n56VtxBE#0qAzb7lph`Eb-}TYpXB!H-}3Ykqyp`otprp7{VEuW*^IR2n$Fb99*nAtqT&oOFIf z@w*6>YvOGw@Ja?Pp1=whZqydzx@9X4n^2!n83C5{C?G@|E?&$?p*g68)kNvUTJ)I6 z1Q|(#UuP6pj78GUxq11m-GSszc+)X{C2eo-?8ud9sB=3(D47v?`JAa{V(IF zPZQ_0AY*9M97>Jf<o%#O_%Wq}8>YM=q0|tGY+hlXcpE=Z4Od z`NT7Hu2hnvRoqOw@g1f=bv`+nba{GwA$Ak0INlqI1k<9!x_!sL()h?hEWoWrdU3w` zZ%%)VR+Bc@_v!C#koM1p-3v_^L6)_Ktj4HE>aUh%2XZE@JFMOn)J~c`_7VWNb9c-N z2b|SZMR4Z@E7j&q&9(6H3yjEu6HV7{2!1t0lgizD;mZ9$r(r7W5G$ky@w(T_dFnOD z*p#+z$@pKE+>o@%eT(2-p_C}wbQ5s(%Sn_{$HDN@MB+Ev?t@3dPy`%TZ!z}AThZSu zN<1i$siJhXFdjV zP*y|V<`V8t=h#XTRUR~5`c`Z9^-`*BZf?WAehGdg)E2Je)hqFa!k{V(u+(hTf^Yq& zoruUh2(^3pe)2{bvt4&4Y9CY3js)PUHtd4rVG57}uFJL)D(JfSIo^{P=7liFXG zq5yqgof0V8paQcP!gy+;^pp-DA5pj=gbMN0eW=-eY+N8~y+G>t+x}oa!5r>tW$xhI zPQSv=pi;~653Gvf6~*JcQ%t1xOrH2l3Zy@8AoJ+wz@daW@m7?%LXkr!bw9GY@ns3e zSfuWF_gkWnesv?s3I`@}NgE2xwgs&rj?kH-FEy82=O8`+szN ziHch`vvS`zNfap14!&#i9H@wF7}yIPm=UB%(o(}F{wsZ(wA0nJ2aD^@B41>>o-_U6 zUqD~vdo48S8~FTb^+%#zcbQiiYoDKYcj&$#^;Smmb+Ljp(L=1Kt_J!;0s%1|JK}Wi z;={~oL!foo5n8=}rs6MmUW~R&;SIJO3TL4Ky?kh+b2rT9B1Jl4>#Uh-Bec z`Hsp<==#UEW6pGPhNk8H!!DUQR~#F9jEMI6T*OWfN^Ze&X(4nV$wa8QUJ>oTkruH# zm~O<`J7Wxseo@FqaZMl#Y(mrFW9AHM9Kb|XBMqaZ2a)DvJgYipkDD_VUF_PKd~dT7 z#02}bBfPn9a!X!O#83=lbJSK#E}K&yx-HI#T6ua)6o0{|={*HFusCkHzs|Fn&|C3H zBck1cmfcWVUN&i>X$YU^Sn6k2H;r3zuXbJFz)r5~3$d$tUj(l1?o={MM){kjgqXRO zc5R*#{;V7AQh|G|)jLM@wGAK&rm2~@{Pewv#06pHbKn#wL0P6F1!^qw9g&cW3Z=9} zj)POhOlwsh@eF=>z?#sIs*C-Nl(yU!#DaiaxhEs#iJqQ8w%(?+6lU02MYSeDkr!B- zPjMv+on6OLXgGnAtl(ao>|X2Y8*Hb}GRW5}-IzXnoo-d0!m4Vy$GS!XOLy>3_+UGs z2D|YcQx@M#M|}TDOetGi{9lGo9m-=0-^+nKE^*?$^uHkxZh}I{#UTQd;X!L+W@jm( zDg@N4+lUqI92o_rNk{3P>1gxAL=&O;x)ZT=q1mk0kLlE$WeWuY_$0`0jY-Kkt zP*|m3AF}Ubd=`<>(Xg0har*_@x2YH}bn0Wk*OZz3*e5;Zc;2uBdnl8?&XjupbkOeNZsNh6pvsq_ydmJI+*z**{I{0K)-;p1~k8cpJXL$^t!-`E}=*4G^-E8>H!LjTPxSx zcF+cS`ommfKMhNSbas^@YbTpH1*RFrBuATUR zt{oFWSk^$xU&kbFQ;MCX22RAN5F6eq9UfR$ut`Jw--p2YX)A*J69m^!oYfj2y7NYcH6&r+0~_sH^c^nzeN1AU4Ga7=FlR{S|Mm~MpzY0$Z+p2W(a={b-pR9EO1Rs zB%KY|@wLcAA@)KXi!d2_BxrkhDn`DT1=Dec}V!okd{$+wK z4E{n8R*xKyci1(CnNdhf$Dp2(Jpof0-0%-38X=Dd9PQgT+w%Lshx9+loPS~MOm%ZT zt%2B2iL_KU_ita%N>xjB!#71_3=3c}o zgeW~^U_ZTJQ2!PqXulQd=3b=XOQhwATK$y(9$#1jOQ4}4?~l#&nek)H(04f(Sr=s| zWv7Lu1=%WGk4FSw^;;!8&YPM)pQDCY9DhU`hMty1@sq1=Tj7bFsOOBZOFlpR`W>-J$-(kezWJj;`?x-v>ev{*8V z8p|KXJPV$HyQr1A(9LVrM47u-XpcrIyO`yWvx1pVYc&?154aneRpLqgx)EMvRaa#|9?Wwqs2+W8n5~79G z(}iCiLk;?enn}ew`HzhG+tu+Ru@T+K5juvZN)wY;x6HjvqD!&!)$$;1VAh~7fg0K| zEha#aN=Yv|3^~YFH}cc38ovVb%L|g@9W6fo(JtT6$fa?zf@Ct88e}m?i)b*Jgc{fl zExfdvw-BYDmH6>(4QMt#p0;FUIQqkhD}aH?a7)_%JtA~soqj{ppP_82yi9kaxuK>~ ze_)Zt>1?q=ZH*kF{1iq9sr*tVuy=u>Zev}!gEZx@O6-fjyu9X00gpIl-fS_pzjpqJ z1yqBmf9NF!jaF<+YxgH6oXBdK)sH(>VZ)1siyA$P<#KDt;8NT*l_0{xit~5j1P)FN zI8hhYKhQ)i z37^aP13B~u65?sg+_@2Kr^iWHN=U;EDSZ@2W2!5ALhGNWXnFBY%7W?1 z=HI9JzQ-pLKZDYTv<0-lt|6c-RwhxZ)mU2Os{bsX_i^@*fKUj8*aDO5pks=qn3Dv6 zwggpKLuyRCTVPwmw1r}B#AS}?X7b837UlXwp~E2|PJw2SGVueL7){Y&z!jL!XN=0i zU^Eig`S2`{+gU$68aRdWx?BZ{sU_f=8sn~>s~M?GU~`fH5kCc; z8ICp+INM3(3{#k32RZdv6b9MQYdZXNuk7ed8;G?S2nT+NZBG=Tar^KFl2SvhW$bGW#kdWL-I)s_IqVnCDDM9fm8g;P;8 z7t4yZn3^*NQfx7SwmkzP$=fwdC}bafQSEF@pd&P8@H#`swGy_rz;Z?Ty5mkS%>m#% zp_!m9e<()sfKiY(nF<1zBz&&`ZlJf6QLvLhl`_``%RW&{+O>Xhp;lwSsyRqGf=RWd zpftiR`={2(siiPAS|p}@q=NhVc0ELprt%=fMXO3B)4ryC2LT(o=sLM7hJC!}T1@)E zA3^J$3&1*M6Xq>03FX`R&w*NkrZE?FwU+Muut;>qNhj@bX17ZJxnOlPSZ=Zeiz~T_ zOu#yc3t6ONHB;?|r4w+pI)~KGN;HOGC)txxiUN8#mexj+W(cz%9a4sx|IRG=}ia zuEBuba3AHsV2feqw-3MvuL`I+2|`Ud4~7ZkN=JZ;L20|Oxna5vx1qbIh#k2O4$RQF zo`tL()zxaqibg^GbB+BS5#U{@K;WWQj~GcB1zb}zJkPwH|5hZ9iH2308!>_;%msji zJHSL~s)YHBR=Koa1mLEOHos*`gp=s8KA-C zu0aE+W!#iJ*0xqKm3A`fUGy#O+X+5W36myS>Uh2!R*s$aCU^`K&KKLCCDkejX2p=5 z%o7-fl03x`gaSNyr?3_JLv?2RLS3F*8ub>Jd@^Cc17)v8vYEK4aqo?OS@W9mt%ITJ z9=S2%R8M){CugT@k~~0x`}Vl!svYqX=E)c_oU6o}#Hb^%G1l3BudxA{F*tbjG;W_>=xV73pKY53v%>I)@D36I_@&p$h|Aw zonQS`07z_F#@T-%@-Tb|)7;;anoD_WH>9ewFy(ZcEOM$#Y)8>qi7rCnsH9GO-_7zF zu*C87{Df1P4TEOsnzZ@H%&lvV(3V@;Q!%+OYRp`g05PjY^gL$^$-t0Y>H*CDDs?FZly*oZ&dxvsxaUWF!{em4{A>n@vpXg$dwvt@_rgmHF z-MER`ABa8R-t_H*kv>}CzOpz;!>p^^9ztHMsHL|SRnS<-y5Z*r(_}c4=fXF`l^-i}>e7v!qs_jv zqvWhX^F=2sDNWA9c@P0?lUlr6ecrTKM%pNQ^?*Lq?p-0~?_j50xV%^(+H>sMul#Tw zeciF*1=?a7cI(}352%>LO96pD+?9!fNyl^9v3^v&Y4L)mNGK0FN43&Xf8jUlxW1Bw zyiu2;qW-aGNhs=zbuoxnxiwZ3{PFZM#Kw)9H@(hgX23h(`Wm~m4&TvoZoYp{plb^> z_#?vXcxd>r7K+1HKJvhed>gtK`TAbJUazUWQY6T~t2af%#<+Veyr%7-#*A#@&*;@g58{i|E%6yC_InGXCOd{L0;$)z#?n7M`re zh!kO{6=>7I?*}czyF7_frt#)s1CFJ_XE&VrDA?Dp3XbvF{qsEJgb&OLSNz_5g?HpK z9)8rsr4JN!Af3G9!#Qn(6zaUDqLN(g2g8*M)Djap?WMK9NKlkC)E2|-g|#-rp%!Gz zAHd%`iq|81efi93m3yTBw3g0j#;Yb2X{mhRAI?&KDmbGqou(2xiRNb^sV}%%Wu0?< z?($L>(#BO*)^)rSgyNRni$i`R4v;GhlCZ8$@e^ROX(p=2_v6Y!%^As zu022)fHdv_-~Yu_H6WVPLpHQx!W%^6j)cBhS`O3QBW#x(eX54d&I22op(N59b*&$v zFiSRY6rOc^(dgSV1>a7-5C;(5S5MvKcM2Jm-LD9TGqDpP097%52V+0>Xqq!! zq4e3vj53SE6i8J`XcQB|MZPP8j;PAOnpGnllH6#Ku~vS42xP*Nz@~y%db7Xi8s09P z1)e%8ys6&M8D=Dt6&t`iKG_4X=!kgRQoh%Z`dc&mlOUqXk-k`jKv9@(a^2-Upw>?< zt5*^DV~6Zedbec4NVl($2T{&b)zA@b#dUyd>`2JC0=xa_fIm8{5um zr-!ApXZhC8@=vC2WyxO|!@0Km)h8ep*`^he92$@YwP>VcdoS5OC^s38e#7RPsg4j+ zbVGG}WRSET&ZfrcR(x~k8n1rTP%CnfUNKUonD$P?FtNFF#cn!wEIab-;jU=B1dHK@ z(;(yAQJ`O$sMn>h;pf^8{JISW%d+@v6@CnXh9n5TXGC}?FI9i-D0OMaIg&mAg=0Kn zNJ7oz5*ReJukD55fUsMuaP+H4tDN&V9zfqF@ zr=#ecUk9wu{0;!+gl;3Bw=Vn^)z$ahVhhw)io!na&9}LmWurLb0zubxK=UEnU*{5P z+SP}&*(iBKSO4{alBHaY^)5Q=mZ+2OwIooJ7*Q5XJ+2|q`9#f?6myq!&oz?klihLq z4C)$XP!BNS0G_Z1&TM>?Jk{S~{F3n83ioli=IO6f%wkvCl(RFFw~j0tb{GvXTx>*sB0McY0s&SNvj4+^h`9nJ_wM>F!Uc>X}9PifQekn0sKI2SAJP!a4h z5cyGTuCj3ZBM^&{dRelIlT^9zcfaAuL5Y~bl!ppSf`wZbK$z#6U~rdclk``e+!qhe z6Qspo*%<)eu6?C;Bp<^VuW6JI|Ncvyn+LlSl;Mp22Bl7ARQ0Xc24%29(ZrdsIPw&-=yHQ7_Vle|5h>AST0 zUGX2Zk34vp?U~IHT|;$U86T+UUHl_NE4m|}>E~6q``7hccCaT^#y+?wD##Q%HwPd8 zV3x4L4|qqu`B$4(LXqDJngNy-{&@aFBvVsywt@X^}iH7P%>bR?ciC$I^U-4Foa`YKI^qDyGK7k%E%c_P=yzAi`YnxGA%DeNd++j3*h^ z=rn>oBd0|~lZ<6YvmkKY*ZJlJ;Im0tqgWu&E92eqt;+NYdxx`eS(4Hw_Jb5|yVvBg z*tbdY^!AN;luEyN4VRhS@-_DC{({ziH{&Z}iGElSV~qvT>L-8G%+yEL zX#MFOhj{InyKG=mvW-<1B@c-}x$vA(nU?>S>0*eN#!SLzQ)Ex7fvQ)S4D<8|I#N$3 zT5Ei`Z?cxBODHX8(Xp73v`IsAYC@9b;t}z0wxVuQSY1J^GRwDPN@qbM-ZF48T$GZ< z8WU+;Pqo?{ghI-KZ-i*ydXu`Ep0Xw^McH_KE9J0S7G;x8Fe`DVG?j3Pv=0YzJ}yZR z%2=oqHiUjvuk0~Ca>Kol4CFi0_xQT~;_F?=u+!kIDl-9g`#ZNZ9HCy17Ga1v^Jv9# z{T4Kb1-AzUxq*MutfOWWZgD*HnFfyYg0&e9f(5tZ>krPF6{VikNeHoc{linPPt#Si z&*g>(c54V8rT_AX!J&bNm-!umPvOR}vDai#`CX___J#=zeB*{4<&2WpaDncZsOkp* zsg<%@@rbrMkR_ux9?LsQxzoBa1s%$BBn6vk#{&&zUwcfzeCBJUwFYSF$08qDsB;gWQN*g!p8pxjofWbqNSZOEKOaTx@+* zwdt5*Q47@EOZ~EZL9s?1o?A%9TJT=Ob_13yyugvPg*e&ZU(r6^k4=2+D-@n=Hv5vu zSXG|hM(>h9^zn=eQ=$6`JO&70&2|%V5Lsx>)(%#;pcOfu>*nk_3HB_BNaH$`jM<^S zcSftDU1?nL;jy)+sfonQN}(}gUW?d_ikr*3=^{G)=tjBtEPe>TO|0ddVB zTklrSHiW+!#26frPXQQ(YN8DG$PZo?(po(QUCCf_OJC`pw*uey00%gmH!`WJkrKXj2!#6?`T25mTu9OJp2L8z3! z=arrL$ZqxuE{%yV)14Kd>k}j7pxZ6#$Dz8$@WV5p8kTqN<-7W)Q7Gt2{KoOPK_tZ| zf2WG~O5@{qPI+W<4f_;reuFVdO^5`ADC1!JQE|N`s3cq@(0WB!n0uh@*c{=LAd;~} zyGK@hbF-Oo+!nN)@i*O(`@FA#u?o=~e{`4O#5}z&=UkU*50fOrzi11D^&FOqe>wii z?*k+2|EcUs;Gx{!@KBT~>PAwLrIDT7Th=Utu?~?np@t^gFs?zgX=D${RwOY^WGh-+ z+#4$066ISh8eYW#FXWp~S`<*%O^ZuItL1Tyqt8#tZ zY120E;^VG`!lZn&3sPd$RkdHpU#|w+bYV)pJC|SH9g%|5IkxVTQcBA4CL0}$&}ef@ zW^Vtj%M;;_1xxP9x#ex17&4N*{ksO*_4O}xYu(p*JkL#yr}@7b)t5X?%CY<+s5_MJ zuiqt+N_;A(_)%lumoyRFixWa-M7qK_9s6<1X?JDa9fP!+_6u~~M$5L=ipB=7(j#f< zZ34J%=bs549%~_mA(|={uZNs_0?o7;-LBP(ZRnkd{-^|2|=4vUTmtByHL8 zEph`(LSEzQj68a+`d$V<45J7cyv^#|^|%fD#si1Nx!4NW*`l*{->HEWNh6-|g>-=r zXmQ|-i}Ku$ndUeHQ^&ieT!Lf}vf6GaqW9$DJ2NWrqwPY%%4nip$@vK$nRp*_C-v<| zuKz~ZyN&<%!NS26&x?jhy+@awJipMQ-8(X4#Ae5??U<1QMt1l9R=w9fAnEF}NYu$2 z>6}Vkc zIb*A?G*z8^IvibmBKn_u^5&T_1oey0gZS2~obf(#xk=erZGTEdQnt3DMGM+0oPwss zj5zXD;(oWhB_T@~Ig#9@v)AKtXu3>Inmgf@A|-lD-1U>cNyl3h?ADD9)GG4}zUGPk zZzaXe!~Kf?<~@$G?Uql3t8jy9{2!doq4=J}j9ktTxss{p6!9UdjyDERlA*xZ!=Q)KDs5O)phz>Vq3BNGoM(H|=1*Q4$^2fTZw z(%nq1P|5Rt81}SYJpEEzMPl5VJsV5&4e)ZWKDyoZ>1EwpkHx-AQVQc8%JMz;{H~p{=FXV>jIxvm4X*qv52e?Y-f%DJ zxEA165GikEASQ^fH6K#d!Tpu2HP{sFs%E=e$gYd$aj$+xue6N+Wc(rAz~wUsk2`(b z8Kvmyz%bKQxpP}~baG-rwYcYCvkHOi zlkR<=>ZBTU*8RF_d#Bl@zZsRIhx<%~Z@Z=ik z>adw3!DK(8R|q$vy{FTxw%#xliD~6qXmY^7_9kthVPTF~Xy1CfBqbU~?1QmxmU=+k z(ggxvEuA;0e&+ci-zQR{-f7aO{O(Pz_OsEjLh_K>MbvoZ4nxtk5u{g@nPv)cgW_R} z9}EA4K4@z0?7ue}Z(o~R(X&FjejUI2g~08PH1E4w>9o{)S(?1>Z0XMvTb|;&EuyOE zGvWNpYX)Nv<8|a^;1>bh#&znEcl-r!T#pn= z4$?Yudha6F%4b>*8@=BdtXXY4N+`U4Dmx$}>HeVJk-QdTG@t!tVT#0(LeV0gvqyyw z2sEp^9eY0N`u10Tm4n8No&A=)IeEC|gnmEXoNSzu!1<4R<%-9kY_8~5Ej?zRegMn78wuMs#;i&eUA0Zk_RXQ3b&TT} z;SCI=7-FUB@*&;8|n>(_g^HGf3@QODE3LpmX~ELnymQm{Sx9xrKS zK29p~?v@R$0=v6Dr5aW>-!{+h@?Q58|Kz8{{W`%J+lDAdb&M5VHrX_mDY;1-JLnf)ezmPau$)1;=`-FU=-r-83tX=C`S#}GZufju zQ>sXNT0Ny=k@nc%cFnvA_i4SC)?_ORXHq8B4D%el1uPX`c~uG#S1M7C+*MMqLw78E zhY2dI8@+N^qrMI1+;TUda(vGqGSRyU{Fnm`aqrr7bz42c5xsOO-~oZpkzorD1g}Y<6rk&3>PsSGy}W?MtqFky@A(X# zIuNZK0cK?^=;PUAu>j0#HtjbHCV*6?jzA&OoE$*Jlga*}LF`SF?WLhv1O|zqC<>*> zYB;#lsYKx0&kH@BFpW8n*yDcc6?;_zaJs<-jPSkCsSX-!aV=P5kUgF@Nu<{a%#K*F z134Q{9|YX7X(v$62_cY3^G%t~rD>Q0z@)1|zs)vjJ6Jq9;7#Ki`w+eS**En?7;n&7 zu==V3T&eFboN3ZiMx3D8qYc;VjFUk_H-WWCau(VFXSQf~viH0L$gwD$UfFHqNcgN`x}M+YQ6RnN<+@t>JUp#)9YOkqst-Ga?{FsDpEeX0(5v{0J~SEbWiL zXC2}M4?UH@u&|;%0y`eb33ldo4~z-x8zY!oVmV=c+f$m?RfDC35mdQ2E>Pze7KWP- z>!Bh<&57I+O_^s}9Tg^k)h7{xx@0a0IA~GAOt2yy!X%Q$1rt~LbTB6@Du!_0%HV>N zlf)QI1&gvERKwso23mJ!Ou6ZS#zCS5W`gxE5T>C#E|{i<1D35C222I33?Njaz`On7 zi<+VWFP6D{e-{yiN#M|Jgk<44u1TiMI78S5W`Sdb5f+{zu34s{CfWN7a3Cf^@L%!& zN$?|!!9j2c)j$~+R6n#891w-z8(!oBpL2K=+%a$r2|~8-(vQj5_XT`<0Ksf;oP+tz z9CObS!0m)Tgg`K#xBM8B(|Z)Wb&DYL{WTYv`;A=q6~Nnx2+!lTIXtj8J7dZE!P_{z z#f8w6F}^!?^KE#+ZDv+xd5O&3EmomZzsv?>E-~ygGum45fk!SBN&|eo1rKw^?aZJ4 E2O(~oYXATM literal 0 HcmV?d00001 diff --git a/code/gradle/wrapper/gradle-wrapper.properties b/code/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..6c9a2247 --- /dev/null +++ b/code/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/code/gradlew b/code/gradlew new file mode 100644 index 00000000..4f906e0c --- /dev/null +++ b/code/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/code/gradlew.bat b/code/gradlew.bat new file mode 100644 index 00000000..107acd32 --- /dev/null +++ b/code/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/code/hiding/Cake.java b/code/hiding/Cake.java new file mode 100644 index 00000000..d20e2cbf --- /dev/null +++ b/code/hiding/Cake.java @@ -0,0 +1,15 @@ +// hiding/Cake.java +// (c)2020 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. +// Accesses a class in a separate compilation unit + +class Cake { + public static void main(String[] args) { + Pie x = new Pie(); + x.f(); + } +} +/* Output: +Pie.f() +*/ diff --git a/code/hiding/ChocolateChip.java b/code/hiding/ChocolateChip.java new file mode 100644 index 00000000..1467fff4 --- /dev/null +++ b/code/hiding/ChocolateChip.java @@ -0,0 +1,23 @@ +// hiding/ChocolateChip.java +// (c)2020 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. +// Can't use package-access member from another package +import hiding.dessert.*; + +public class ChocolateChip extends Cookie { + public ChocolateChip() { + System.out.println("ChocolateChip constructor"); + } + public void chomp() { + //- bite(); // Can't access bite + } + public static void main(String[] args) { + ChocolateChip x = new ChocolateChip(); + x.chomp(); + } +} +/* Output: +Cookie constructor +ChocolateChip constructor +*/ diff --git a/code/hiding/ChocolateChip2.java b/code/hiding/ChocolateChip2.java new file mode 100644 index 00000000..03c9d1ab --- /dev/null +++ b/code/hiding/ChocolateChip2.java @@ -0,0 +1,21 @@ +// hiding/ChocolateChip2.java +// (c)2020 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. +import hiding.cookie2.*; + +public class ChocolateChip2 extends Cookie { + public ChocolateChip2() { + System.out.println("ChocolateChip2 constructor"); + } + public void chomp() { bite(); } // Protected method + public static void main(String[] args) { + ChocolateChip2 x = new ChocolateChip2(); + x.chomp(); + } +} +/* Output: +Cookie constructor +ChocolateChip2 constructor +bite +*/ diff --git a/code/hiding/CreatePackageAccessObject.java b/code/hiding/CreatePackageAccessObject.java new file mode 100644 index 00000000..8442b51f --- /dev/null +++ b/code/hiding/CreatePackageAccessObject.java @@ -0,0 +1,12 @@ +// hiding/CreatePackageAccessObject.java +// (c)2020 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. +// {WillNotCompile} +import hiding.packageaccess.*; + +public class CreatePackageAccessObject { + public static void main(String[] args) { + new PublicConstructor(); + } +} diff --git a/code/hiding/Dinner.java b/code/hiding/Dinner.java new file mode 100644 index 00000000..7a7b97d5 --- /dev/null +++ b/code/hiding/Dinner.java @@ -0,0 +1,16 @@ +// hiding/Dinner.java +// (c)2020 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. +// Uses the library +import hiding.dessert.*; + +public class Dinner { + public static void main(String[] args) { + Cookie x = new Cookie(); + //- x.bite(); // Can't access + } +} +/* Output: +Cookie constructor +*/ diff --git a/code/hiding/FullQualification.java b/code/hiding/FullQualification.java new file mode 100644 index 00000000..2fadb28c --- /dev/null +++ b/code/hiding/FullQualification.java @@ -0,0 +1,11 @@ +// hiding/FullQualification.java +// (c)2020 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. + +public class FullQualification { + public static void main(String[] args) { + java.util.ArrayList list = + new java.util.ArrayList(); + } +} diff --git a/code/hiding/IceCream.java b/code/hiding/IceCream.java new file mode 100644 index 00000000..d91619a2 --- /dev/null +++ b/code/hiding/IceCream.java @@ -0,0 +1,19 @@ +// hiding/IceCream.java +// (c)2020 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. +// Demonstrates "private" keyword + +class Sundae { + private Sundae() {} + static Sundae makeASundae() { + return new Sundae(); + } +} + +public class IceCream { + public static void main(String[] args) { + //- Sundae x = new Sundae(); + Sundae x = Sundae.makeASundae(); + } +} diff --git a/code/hiding/ImportedMyClass.java b/code/hiding/ImportedMyClass.java new file mode 100644 index 00000000..a644f5d8 --- /dev/null +++ b/code/hiding/ImportedMyClass.java @@ -0,0 +1,11 @@ +// hiding/ImportedMyClass.java +// (c)2020 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. +import hiding.mypackage.*; + +public class ImportedMyClass { + public static void main(String[] args) { + MyClass m = new MyClass(); + } +} diff --git a/code/hiding/LibTest.java b/code/hiding/LibTest.java new file mode 100644 index 00000000..c439352a --- /dev/null +++ b/code/hiding/LibTest.java @@ -0,0 +1,17 @@ +// hiding/LibTest.java +// (c)2020 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. +// Uses the library +import com.mindviewinc.simple.*; + +public class LibTest { + public static void main(String[] args) { + Vector v = new Vector(); + List l = new List(); + } +} +/* Output: +com.mindviewinc.simple.Vector +com.mindviewinc.simple.List +*/ diff --git a/code/hiding/Lunch.java b/code/hiding/Lunch.java new file mode 100644 index 00000000..eca4baf0 --- /dev/null +++ b/code/hiding/Lunch.java @@ -0,0 +1,36 @@ +// hiding/Lunch.java +// (c)2020 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. +// Demonstrates class access specifiers. Make a class +// effectively private with private constructors: + +class Soup1 { + private Soup1() {} + public static Soup1 makeSoup() { // [1] + return new Soup1(); + } +} + +class Soup2 { + private Soup2() {} + private static Soup2 ps1 = new Soup2(); // [2] + public static Soup2 access() { + return ps1; + } + public void f() {} +} + +// Only one public class allowed per file: +public class Lunch { + void testPrivate() { + // Can't do this! Private constructor: + //- Soup1 soup = new Soup1(); + } + void testStatic() { + Soup1 soup = Soup1.makeSoup(); + } + void testSingleton() { + Soup2.access().f(); + } +} diff --git a/code/hiding/OrganizedByAccess.java b/code/hiding/OrganizedByAccess.java new file mode 100644 index 00000000..46af158f --- /dev/null +++ b/code/hiding/OrganizedByAccess.java @@ -0,0 +1,15 @@ +// hiding/OrganizedByAccess.java +// (c)2020 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. + +public class OrganizedByAccess { + public void pub1() { /* ... */ } + public void pub2() { /* ... */ } + public void pub3() { /* ... */ } + private void priv1() { /* ... */ } + private void priv2() { /* ... */ } + private void priv3() { /* ... */ } + private int i; + // ... +} diff --git a/code/hiding/Pie.java b/code/hiding/Pie.java new file mode 100644 index 00000000..1470fbc3 --- /dev/null +++ b/code/hiding/Pie.java @@ -0,0 +1,9 @@ +// hiding/Pie.java +// (c)2020 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. +// The other class + +class Pie { + void f() { System.out.println("Pie.f()"); } +} diff --git a/code/hiding/QualifiedMyClass.java b/code/hiding/QualifiedMyClass.java new file mode 100644 index 00000000..58a097cc --- /dev/null +++ b/code/hiding/QualifiedMyClass.java @@ -0,0 +1,11 @@ +// hiding/QualifiedMyClass.java +// (c)2020 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. + +public class QualifiedMyClass { + public static void main(String[] args) { + hiding.mypackage.MyClass m = + new hiding.mypackage.MyClass(); + } +} diff --git a/code/hiding/SingleImport.java b/code/hiding/SingleImport.java new file mode 100644 index 00000000..5168ebe8 --- /dev/null +++ b/code/hiding/SingleImport.java @@ -0,0 +1,11 @@ +// hiding/SingleImport.java +// (c)2020 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. +import java.util.ArrayList; + +public class SingleImport { + public static void main(String[] args) { + ArrayList list = new ArrayList(); + } +} diff --git a/code/hiding/cookie2/Cookie.java b/code/hiding/cookie2/Cookie.java new file mode 100644 index 00000000..aff5bb17 --- /dev/null +++ b/code/hiding/cookie2/Cookie.java @@ -0,0 +1,14 @@ +// hiding/cookie2/Cookie.java +// (c)2020 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 hiding.cookie2; + +public class Cookie { + public Cookie() { + System.out.println("Cookie constructor"); + } + protected void bite() { + System.out.println("bite"); + } +} diff --git a/code/hiding/dessert/Cookie.java b/code/hiding/dessert/Cookie.java new file mode 100644 index 00000000..803e504c --- /dev/null +++ b/code/hiding/dessert/Cookie.java @@ -0,0 +1,13 @@ +// hiding/dessert/Cookie.java +// (c)2020 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. +// Creates a library +package hiding.dessert; + +public class Cookie { + public Cookie() { + System.out.println("Cookie constructor"); + } + void bite() { System.out.println("bite"); } +} diff --git a/code/hiding/mypackage/MyClass.java b/code/hiding/mypackage/MyClass.java new file mode 100644 index 00000000..5245d479 --- /dev/null +++ b/code/hiding/mypackage/MyClass.java @@ -0,0 +1,9 @@ +// hiding/mypackage/MyClass.java +// (c)2020 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 hiding.mypackage; + +public class MyClass { + // ... +} diff --git a/code/hiding/packageaccess/PublicConstructor.java b/code/hiding/packageaccess/PublicConstructor.java new file mode 100644 index 00000000..533c28a0 --- /dev/null +++ b/code/hiding/packageaccess/PublicConstructor.java @@ -0,0 +1,9 @@ +// hiding/packageaccess/PublicConstructor.java +// (c)2020 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 hiding.packageaccess; + +class PublicConstructor { + public PublicConstructor() {} +} diff --git a/code/housekeeping/Apricot.java b/code/housekeeping/Apricot.java new file mode 100644 index 00000000..dae8f33d --- /dev/null +++ b/code/housekeeping/Apricot.java @@ -0,0 +1,8 @@ +// housekeeping/Apricot.java +// (c)2020 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. +public class Apricot { + void pick() { /* ... */ } + void pit() { pick(); /* ... */ } +} diff --git a/code/housekeeping/ArrayClassObj.java b/code/housekeeping/ArrayClassObj.java new file mode 100644 index 00000000..44e31b59 --- /dev/null +++ b/code/housekeeping/ArrayClassObj.java @@ -0,0 +1,22 @@ +// housekeeping/ArrayClassObj.java +// (c)2020 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. +// Creating an array of nonprimitive objects +import java.util.*; + +public class ArrayClassObj { + public static void main(String[] args) { + Random rand = new Random(47); + Integer[] a = new Integer[rand.nextInt(20)]; + System.out.println("length of a = " + a.length); + for(int i = 0; i < a.length; i++) + a[i] = rand.nextInt(500); // Autoboxing + System.out.println(Arrays.toString(a)); + } +} +/* Output: +length of a = 18 +[55, 193, 361, 461, 429, 368, 200, 22, 207, 288, 128, +51, 89, 309, 278, 498, 361, 20] +*/ diff --git a/code/housekeeping/ArrayInit.java b/code/housekeeping/ArrayInit.java new file mode 100644 index 00000000..4186bd24 --- /dev/null +++ b/code/housekeeping/ArrayInit.java @@ -0,0 +1,25 @@ +// housekeeping/ArrayInit.java +// (c)2020 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. +// Array initialization +import java.util.*; + +public class ArrayInit { + public static void main(String[] args) { + Integer[] a = { + 1, 2, + 3, // Autoboxing + }; + Integer[] b = new Integer[]{ + 1, 2, + 3, // Autoboxing + }; + System.out.println(Arrays.toString(a)); + System.out.println(Arrays.toString(b)); + } +} +/* Output: +[1, 2, 3] +[1, 2, 3] +*/ diff --git a/code/housekeeping/ArrayNew.java b/code/housekeeping/ArrayNew.java new file mode 100644 index 00000000..022cec16 --- /dev/null +++ b/code/housekeeping/ArrayNew.java @@ -0,0 +1,20 @@ +// housekeeping/ArrayNew.java +// (c)2020 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. +// Creating arrays with new +import java.util.*; + +public class ArrayNew { + public static void main(String[] args) { + int[] a; + Random rand = new Random(47); + a = new int[rand.nextInt(20)]; + System.out.println("length of a = " + a.length); + System.out.println(Arrays.toString(a)); + } +} +/* Output: +length of a = 18 +[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +*/ diff --git a/code/housekeeping/ArraysOfPrimitives.java b/code/housekeeping/ArraysOfPrimitives.java new file mode 100644 index 00000000..165afe89 --- /dev/null +++ b/code/housekeeping/ArraysOfPrimitives.java @@ -0,0 +1,23 @@ +// housekeeping/ArraysOfPrimitives.java +// (c)2020 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. + +public class ArraysOfPrimitives { + public static void main(String[] args) { + int[] a1 = { 1, 2, 3, 4, 5 }; + int[] a2; + a2 = a1; + for(int i = 0; i < a2.length; i++) + a2[i] += 1; + for(int i = 0; i < a1.length; i++) + System.out.println("a1[" + i + "] = " + a1[i]); + } +} +/* Output: +a1[0] = 2 +a1[1] = 3 +a1[2] = 4 +a1[3] = 5 +a1[4] = 6 +*/ diff --git a/code/housekeeping/AutoboxingVarargs.java b/code/housekeeping/AutoboxingVarargs.java new file mode 100644 index 00000000..c670fa67 --- /dev/null +++ b/code/housekeeping/AutoboxingVarargs.java @@ -0,0 +1,22 @@ +// housekeeping/AutoboxingVarargs.java +// (c)2020 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. + +public class AutoboxingVarargs { + public static void f(Integer... args) { + for(Integer i : args) + System.out.print(i + " "); + System.out.println(); + } + public static void main(String[] args) { + f(1, 2); + f(4, 5, 6, 7, 8, 9); + f(10, 11, 12); + } +} +/* Output: +1 2 +4 5 6 7 8 9 +10 11 12 +*/ diff --git a/code/housekeeping/BananaPeel.java b/code/housekeeping/BananaPeel.java new file mode 100644 index 00000000..b3e01b27 --- /dev/null +++ b/code/housekeeping/BananaPeel.java @@ -0,0 +1,15 @@ +// housekeeping/BananaPeel.java +// (c)2020 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. + +class Banana { void peel(int i) { /* ... */ } } + +public class BananaPeel { + public static void main(String[] args) { + Banana a = new Banana(), + b = new Banana(); + a.peel(1); + b.peel(2); + } +} diff --git a/code/housekeeping/Burrito.java b/code/housekeeping/Burrito.java new file mode 100644 index 00000000..e3fd028b --- /dev/null +++ b/code/housekeeping/Burrito.java @@ -0,0 +1,39 @@ +// housekeeping/Burrito.java +// (c)2020 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. + +public class Burrito { + Spiciness degree; + public Burrito(Spiciness degree) { + this.degree = degree; + } + public void describe() { + System.out.print("This burrito is "); + switch(degree) { + case NOT: System.out.println( + "not spicy at all."); + break; + case MILD: + case MEDIUM: System.out.println("a little hot."); + break; + case HOT: + case FLAMING: + default: System.out.println("maybe too hot."); + } + } + public static void main(String[] args) { + Burrito + plain = new Burrito(Spiciness.NOT), + greenChile = new Burrito(Spiciness.MEDIUM), + jalapeno = new Burrito(Spiciness.HOT); + plain.describe(); + greenChile.describe(); + jalapeno.describe(); + } +} +/* Output: +This burrito is not spicy at all. +This burrito is a little hot. +This burrito is maybe too hot. +*/ diff --git a/code/housekeeping/Counter.java b/code/housekeeping/Counter.java new file mode 100644 index 00000000..d0a58ecc --- /dev/null +++ b/code/housekeeping/Counter.java @@ -0,0 +1,9 @@ +// housekeeping/Counter.java +// (c)2020 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. +public class Counter { + int i; + Counter() { i = 7; } + // ... +} diff --git a/code/housekeeping/DefaultConstructor.java b/code/housekeeping/DefaultConstructor.java new file mode 100644 index 00000000..22e3787d --- /dev/null +++ b/code/housekeeping/DefaultConstructor.java @@ -0,0 +1,12 @@ +// housekeeping/DefaultConstructor.java +// (c)2020 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. + +class Bird {} + +public class DefaultConstructor { + public static void main(String[] args) { + Bird b = new Bird(); // Default! + } +} diff --git a/code/housekeeping/Demotion.java b/code/housekeeping/Demotion.java new file mode 100644 index 00000000..ad2c4e86 --- /dev/null +++ b/code/housekeeping/Demotion.java @@ -0,0 +1,43 @@ +// housekeeping/Demotion.java +// (c)2020 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. +// Demotion of primitives + +public class Demotion { + void f1(double x) { + System.out.println("f1(double)"); + } + void f2(float x) { System.out.println("f2(float)"); } + void f3(long x) { System.out.println("f3(long)"); } + void f4(int x) { System.out.println("f4(int)"); } + void f5(short x) { System.out.println("f5(short)"); } + void f6(byte x) { System.out.println("f6(byte)"); } + void f7(char x) { System.out.println("f7(char)"); } + + void testDouble() { + double x = 0; + System.out.println("double argument:"); + f1(x); + f2((float)x); + f3((long)x); + f4((int)x); + f5((short)x); + f6((byte)x); + f7((char)x); + } + public static void main(String[] args) { + Demotion p = new Demotion(); + p.testDouble(); + } +} +/* Output: +double argument: +f1(double) +f2(float) +f3(long) +f4(int) +f5(short) +f6(byte) +f7(char) +*/ diff --git a/code/housekeeping/DynamicArray.java b/code/housekeeping/DynamicArray.java new file mode 100644 index 00000000..726ec034 --- /dev/null +++ b/code/housekeeping/DynamicArray.java @@ -0,0 +1,21 @@ +// housekeeping/DynamicArray.java +// (c)2020 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. +// Array initialization + +public class DynamicArray { + public static void main(String[] args) { + Other.main(new String[]{ "fiddle", "de", "dum" }); + } +} + +class Other { + public static void main(String[] args) { + for(String s : args) + System.out.print(s + " "); + } +} +/* Output: +fiddle de dum +*/ diff --git a/code/housekeeping/EnumOrder.java b/code/housekeeping/EnumOrder.java new file mode 100644 index 00000000..a3c96284 --- /dev/null +++ b/code/housekeeping/EnumOrder.java @@ -0,0 +1,19 @@ +// housekeeping/EnumOrder.java +// (c)2020 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. + +public class EnumOrder { + public static void main(String[] args) { + for(Spiciness s : Spiciness.values()) + System.out.println( + s + ", ordinal " + s.ordinal()); + } +} +/* Output: +NOT, ordinal 0 +MILD, ordinal 1 +MEDIUM, ordinal 2 +HOT, ordinal 3 +FLAMING, ordinal 4 +*/ diff --git a/code/housekeeping/ExplicitStatic.java b/code/housekeeping/ExplicitStatic.java new file mode 100644 index 00000000..7d9cb31a --- /dev/null +++ b/code/housekeeping/ExplicitStatic.java @@ -0,0 +1,41 @@ +// housekeeping/ExplicitStatic.java +// (c)2020 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. +// Explicit static initialization with "static" clause + +class Cup { + Cup(int marker) { + System.out.println("Cup(" + marker + ")"); + } + void f(int marker) { + System.out.println("f(" + marker + ")"); + } +} + +class Cups { + static Cup cup1; + static Cup cup2; + static { + cup1 = new Cup(1); + cup2 = new Cup(2); + } + Cups() { + System.out.println("Cups()"); + } +} + +public class ExplicitStatic { + public static void main(String[] args) { + System.out.println("Inside main()"); + Cups.cup1.f(99); // [1] + } + // static Cups cups1 = new Cups(); // [2] + // static Cups cups2 = new Cups(); // [2] +} +/* Output: +Inside main() +Cup(1) +Cup(2) +f(99) +*/ diff --git a/code/housekeeping/Flower.java b/code/housekeeping/Flower.java new file mode 100644 index 00000000..a62d7cbe --- /dev/null +++ b/code/housekeeping/Flower.java @@ -0,0 +1,46 @@ +// housekeeping/Flower.java +// (c)2020 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. +// Calling constructors with "this" + +public class Flower { + int petalCount = 0; + String s = "initial value"; + Flower(int petals) { + petalCount = petals; + System.out.println( + "Constructor w/ int arg only, petalCount= " + + petalCount); + } + Flower(String ss) { + System.out.println( + "Constructor w/ String arg only, s = " + ss); + s = ss; + } + Flower(String s, int petals) { + this(petals); + //- this(s); // Can't call two! + this.s = s; // Another use of "this" + System.out.println("String & int args"); + } + Flower() { + this("hi", 47); + System.out.println("no-arg constructor"); + } + void printPetalCount() { + //- this(11); // Not inside non-constructor! + System.out.println( + "petalCount = " + petalCount + " s = "+ s); + } + public static void main(String[] args) { + Flower x = new Flower(); + x.printPetalCount(); + } +} +/* Output: +Constructor w/ int arg only, petalCount= 47 +String & int args +no-arg constructor +petalCount = 47 s = hi +*/ diff --git a/code/housekeeping/InitialValues.java b/code/housekeeping/InitialValues.java new file mode 100644 index 00000000..dced4dd2 --- /dev/null +++ b/code/housekeeping/InitialValues.java @@ -0,0 +1,44 @@ +// housekeeping/InitialValues.java +// (c)2020 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. +// Shows default initial values + +public class InitialValues { + boolean t; + char c; + byte b; + short s; + int i; + long l; + float f; + double d; + InitialValues reference; + void printInitialValues() { + System.out.println("Data type Initial value"); + System.out.println("boolean " + t); + System.out.println("char [" + c + "]"); + System.out.println("byte " + b); + System.out.println("short " + s); + System.out.println("int " + i); + System.out.println("long " + l); + System.out.println("float " + f); + System.out.println("double " + d); + System.out.println("reference " + reference); + } + public static void main(String[] args) { + new InitialValues().printInitialValues(); + } +} +/* Output: +Data type Initial value +boolean false +char [NUL] +byte 0 +short 0 +int 0 +long 0 +float 0.0 +double 0.0 +reference null +*/ diff --git a/code/housekeeping/InitialValues2.java b/code/housekeeping/InitialValues2.java new file mode 100644 index 00000000..1cb50974 --- /dev/null +++ b/code/housekeeping/InitialValues2.java @@ -0,0 +1,16 @@ +// housekeeping/InitialValues2.java +// (c)2020 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. +// Providing explicit initial values + +public class InitialValues2 { + boolean bool = true; + char ch = 'x'; + byte b = 47; + short s = 0xff; + int i = 999; + long lng = 1; + float f = 3.14f; + double d = 3.14159; +} diff --git a/code/housekeeping/Leaf.java b/code/housekeeping/Leaf.java new file mode 100644 index 00000000..f9c560b2 --- /dev/null +++ b/code/housekeeping/Leaf.java @@ -0,0 +1,23 @@ +// housekeeping/Leaf.java +// (c)2020 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. +// Simple use of the "this" keyword + +public class Leaf { + int i = 0; + Leaf increment() { + i++; + return this; + } + void print() { + System.out.println("i = " + i); + } + public static void main(String[] args) { + Leaf x = new Leaf(); + x.increment().increment().increment().print(); + } +} +/* Output: +i = 3 +*/ diff --git a/code/housekeeping/Measurement.java b/code/housekeeping/Measurement.java new file mode 100644 index 00000000..8a920779 --- /dev/null +++ b/code/housekeeping/Measurement.java @@ -0,0 +1,10 @@ +// housekeeping/Measurement.java +// (c)2020 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. +class Depth {} + +public class Measurement { + Depth d = new Depth(); + // ... +} diff --git a/code/housekeeping/MethodInit.java b/code/housekeeping/MethodInit.java new file mode 100644 index 00000000..84e15fce --- /dev/null +++ b/code/housekeeping/MethodInit.java @@ -0,0 +1,8 @@ +// housekeeping/MethodInit.java +// (c)2020 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. +public class MethodInit { + int i = f(); + int f() { return 11; } +} diff --git a/code/housekeeping/MethodInit2.java b/code/housekeeping/MethodInit2.java new file mode 100644 index 00000000..24750fb2 --- /dev/null +++ b/code/housekeeping/MethodInit2.java @@ -0,0 +1,10 @@ +// housekeeping/MethodInit2.java +// (c)2020 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. +public class MethodInit2 { + int i = f(); + int j = g(i); + int f() { return 11; } + int g(int n) { return n * 10; } +} diff --git a/code/housekeeping/MethodInit3.java b/code/housekeeping/MethodInit3.java new file mode 100644 index 00000000..2a6524ab --- /dev/null +++ b/code/housekeeping/MethodInit3.java @@ -0,0 +1,10 @@ +// housekeeping/MethodInit3.java +// (c)2020 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. +public class MethodInit3 { + //- int j = g(i); // Illegal forward reference + int i = f(); + int f() { return 11; } + int g(int n) { return n * 10; } +} diff --git a/code/housekeeping/Mugs.java b/code/housekeeping/Mugs.java new file mode 100644 index 00000000..e4ebba69 --- /dev/null +++ b/code/housekeeping/Mugs.java @@ -0,0 +1,47 @@ +// housekeeping/Mugs.java +// (c)2020 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. +// Instance initialization + +class Mug { + Mug(int marker) { + System.out.println("Mug(" + marker + ")"); + } +} + +public class Mugs { + Mug mug1; + Mug mug2; + { // [1] + mug1 = new Mug(1); + mug2 = new Mug(2); + System.out.println("mug1 & mug2 initialized"); + } + Mugs() { + System.out.println("Mugs()"); + } + Mugs(int i) { + System.out.println("Mugs(int)"); + } + public static void main(String[] args) { + System.out.println("Inside main()"); + new Mugs(); + System.out.println("new Mugs() completed"); + new Mugs(1); + System.out.println("new Mugs(1) completed"); + } +} +/* Output: +Inside main() +Mug(1) +Mug(2) +mug1 & mug2 initialized +Mugs() +new Mugs() completed +Mug(1) +Mug(2) +mug1 & mug2 initialized +Mugs(int) +new Mugs(1) completed +*/ diff --git a/code/housekeeping/NewVarArgs.java b/code/housekeeping/NewVarArgs.java new file mode 100644 index 00000000..291dd134 --- /dev/null +++ b/code/housekeeping/NewVarArgs.java @@ -0,0 +1,30 @@ +// housekeeping/NewVarArgs.java +// (c)2020 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. +// Using array syntax to create variable argument lists + +public class NewVarArgs { + static void printArray(Object... args) { + for(Object obj : args) + System.out.print(obj + " "); + System.out.println(); + } + public static void main(String[] args) { + // Can take individual elements: + printArray(47, (float) 3.14, 11.11); + printArray(47, 3.14F, 11.11); + printArray("one", "two", "three"); + printArray(new A(), new A(), new A()); + // Or an array: + printArray((Object[])new Integer[]{ 1, 2, 3, 4 }); + printArray(); // Empty list is OK + } +} +/* Output: +47 3.14 11.11 +47 3.14 11.11 +one two three +A@15db9742 A@6d06d69c A@7852e922 +1 2 3 4 +*/ diff --git a/code/housekeeping/NoSynthesis.java b/code/housekeeping/NoSynthesis.java new file mode 100644 index 00000000..217c2023 --- /dev/null +++ b/code/housekeeping/NoSynthesis.java @@ -0,0 +1,17 @@ +// housekeeping/NoSynthesis.java +// (c)2020 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. + +class Bird2 { + Bird2(int i) {} + Bird2(double d) {} +} + +public class NoSynthesis { + public static void main(String[] args) { + //- Bird2 b = new Bird2(); // No default + Bird2 b2 = new Bird2(1); + Bird2 b3 = new Bird2(1.0); + } +} diff --git a/code/housekeeping/OptionalTrailingArguments.java b/code/housekeeping/OptionalTrailingArguments.java new file mode 100644 index 00000000..d7ee9fbb --- /dev/null +++ b/code/housekeeping/OptionalTrailingArguments.java @@ -0,0 +1,23 @@ +// housekeeping/OptionalTrailingArguments.java +// (c)2020 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. + +public class OptionalTrailingArguments { + static void f(int required, String... trailing) { + System.out.print("required: " + required + " "); + for(String s : trailing) + System.out.print(s + " "); + System.out.println(); + } + public static void main(String[] args) { + f(1, "one"); + f(2, "two", "three"); + f(0); + } +} +/* Output: +required: 1 one +required: 2 two three +required: 0 +*/ diff --git a/code/housekeeping/OrderOfInitialization.java b/code/housekeeping/OrderOfInitialization.java new file mode 100644 index 00000000..c715ed7c --- /dev/null +++ b/code/housekeeping/OrderOfInitialization.java @@ -0,0 +1,40 @@ +// housekeeping/OrderOfInitialization.java +// (c)2020 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. +// Demonstrates initialization order + +// When the constructor is called to create a +// Window object, you'll see a message: +class Window { + Window(int marker) { + System.out.println("Window(" + marker + ")"); + } +} + +class House { + Window w1 = new Window(1); // Before constructor + House() { + // Show that we're in the constructor: + System.out.println("House()"); + w3 = new Window(33); // Reinitialize w3 + } + Window w2 = new Window(2); // After constructor + void f() { System.out.println("f()"); } + Window w3 = new Window(3); // At end +} + +public class OrderOfInitialization { + public static void main(String[] args) { + House h = new House(); + h.f(); // Shows that construction is done + } +} +/* Output: +Window(1) +Window(2) +Window(3) +House() +Window(33) +f() +*/ diff --git a/code/housekeeping/Overloading.java b/code/housekeeping/Overloading.java new file mode 100644 index 00000000..99d21bf8 --- /dev/null +++ b/code/housekeeping/Overloading.java @@ -0,0 +1,56 @@ +// housekeeping/Overloading.java +// (c)2020 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. +// Both constructor and ordinary method overloading + +class Tree { + int height; + Tree() { + System.out.println("Planting a seedling"); + height = 0; + } + Tree(int initialHeight) { + height = initialHeight; + System.out.println("Creating new Tree that is " + + height + " feet tall"); + } + void info() { + System.out.println( + "Tree is " + height + " feet tall"); + } + void info(String s) { + System.out.println( + s + ": Tree is " + height + " feet tall"); + } +} + +public class Overloading { + public static void main(String[] args) { + for(int i = 0; i < 5; i++) { + Tree t = new Tree(i); + t.info(); + t.info("overloaded method"); + } + // Overloaded constructor: + new Tree(); + } +} +/* Output: +Creating new Tree that is 0 feet tall +Tree is 0 feet tall +overloaded method: Tree is 0 feet tall +Creating new Tree that is 1 feet tall +Tree is 1 feet tall +overloaded method: Tree is 1 feet tall +Creating new Tree that is 2 feet tall +Tree is 2 feet tall +overloaded method: Tree is 2 feet tall +Creating new Tree that is 3 feet tall +Tree is 3 feet tall +overloaded method: Tree is 3 feet tall +Creating new Tree that is 4 feet tall +Tree is 4 feet tall +overloaded method: Tree is 4 feet tall +Planting a seedling +*/ diff --git a/code/housekeeping/OverloadingOrder.java b/code/housekeeping/OverloadingOrder.java new file mode 100644 index 00000000..42f6466e --- /dev/null +++ b/code/housekeeping/OverloadingOrder.java @@ -0,0 +1,22 @@ +// housekeeping/OverloadingOrder.java +// (c)2020 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. +// Overloading based on the order of the arguments + +public class OverloadingOrder { + static void f(String s, int i) { + System.out.println("String: " + s + ", int: " + i); + } + static void f(int i, String s) { + System.out.println("int: " + i + ", String: " + s); + } + public static void main(String[] args) { + f("String first", 11); + f(99, "Int first"); + } +} +/* Output: +String: String first, int: 11 +int: 99, String: Int first +*/ diff --git a/code/housekeeping/OverloadingVarargs.java b/code/housekeeping/OverloadingVarargs.java new file mode 100644 index 00000000..c13b7406 --- /dev/null +++ b/code/housekeeping/OverloadingVarargs.java @@ -0,0 +1,37 @@ +// housekeeping/OverloadingVarargs.java +// (c)2020 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. + +public class OverloadingVarargs { + static void f(Character... args) { + System.out.print("first"); + for(Character c : args) + System.out.print(" " + c); + System.out.println(); + } + static void f(Integer... args) { + System.out.print("second"); + for(Integer i : args) + System.out.print(" " + i); + System.out.println(); + } + static void f(Long... args) { + System.out.println("third"); + } + public static void main(String[] args) { + f('a', 'b', 'c'); + f(1); + f(2, 1); + f(0); + f(0L); + //- f(); // Won't compile -- ambiguous + } +} +/* Output: +first a b c +second 1 +second 2 1 +second 0 +third +*/ diff --git a/code/housekeeping/OverloadingVarargs2.java b/code/housekeeping/OverloadingVarargs2.java new file mode 100644 index 00000000..c3a09845 --- /dev/null +++ b/code/housekeeping/OverloadingVarargs2.java @@ -0,0 +1,18 @@ +// housekeeping/OverloadingVarargs2.java +// (c)2020 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. +// {WillNotCompile} + +public class OverloadingVarargs2 { + static void f(float i, Character... args) { + System.out.println("first"); + } + static void f(Character... args) { + System.out.print("second"); + } + public static void main(String[] args) { + f(1, 'a'); + f('a', 'b'); + } +} diff --git a/code/housekeeping/OverloadingVarargs3.java b/code/housekeeping/OverloadingVarargs3.java new file mode 100644 index 00000000..23e757ec --- /dev/null +++ b/code/housekeeping/OverloadingVarargs3.java @@ -0,0 +1,21 @@ +// housekeeping/OverloadingVarargs3.java +// (c)2020 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. + +public class OverloadingVarargs3 { + static void f(float i, Character... args) { + System.out.println("first"); + } + static void f(char c, Character... args) { + System.out.println("second"); + } + public static void main(String[] args) { + f(1, 'a'); + f('a', 'b'); + } +} +/* Output: +first +second +*/ diff --git a/code/housekeeping/PassingThis.java b/code/housekeeping/PassingThis.java new file mode 100644 index 00000000..ce725eab --- /dev/null +++ b/code/housekeeping/PassingThis.java @@ -0,0 +1,31 @@ +// housekeeping/PassingThis.java +// (c)2020 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. + +class Person { + public void eat(Apple apple) { + Apple peeled = apple.getPeeled(); + System.out.println("Yummy"); + } +} + +class Peeler { + static Apple peel(Apple apple) { + // ... remove peel + return apple; // Peeled + } +} + +class Apple { + Apple getPeeled() { return Peeler.peel(this); } +} + +public class PassingThis { + public static void main(String[] args) { + new Person().eat(new Apple()); + } +} +/* Output: +Yummy +*/ diff --git a/code/housekeeping/PrimitiveOverloading.java b/code/housekeeping/PrimitiveOverloading.java new file mode 100644 index 00000000..1d8c1e2c --- /dev/null +++ b/code/housekeeping/PrimitiveOverloading.java @@ -0,0 +1,120 @@ +// housekeeping/PrimitiveOverloading.java +// (c)2020 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. +// Promotion of primitives and overloading + +public class PrimitiveOverloading { + void f1(char x) { System.out.print("f1(char) "); } + void f1(byte x) { System.out.print("f1(byte) "); } + void f1(short x) { System.out.print("f1(short) "); } + void f1(int x) { System.out.print("f1(int) "); } + void f1(long x) { System.out.print("f1(long) "); } + void f1(float x) { System.out.print("f1(float) "); } + void f1(double x) { System.out.print("f1(double) "); } + + void f2(byte x) { System.out.print("f2(byte) "); } + void f2(short x) { System.out.print("f2(short) "); } + void f2(int x) { System.out.print("f2(int) "); } + void f2(long x) { System.out.print("f2(long) "); } + void f2(float x) { System.out.print("f2(float) "); } + void f2(double x) { System.out.print("f2(double) "); } + + void f3(short x) { System.out.print("f3(short) "); } + void f3(int x) { System.out.print("f3(int) "); } + void f3(long x) { System.out.print("f3(long) "); } + void f3(float x) { System.out.print("f3(float) "); } + void f3(double x) { System.out.print("f3(double) "); } + + void f4(int x) { System.out.print("f4(int) "); } + void f4(long x) { System.out.print("f4(long) "); } + void f4(float x) { System.out.print("f4(float) "); } + void f4(double x) { System.out.print("f4(double) "); } + + void f5(long x) { System.out.print("f5(long) "); } + void f5(float x) { System.out.print("f5(float) "); } + void f5(double x) { System.out.print("f5(double) "); } + + void f6(float x) { System.out.print("f6(float) "); } + void f6(double x) { System.out.print("f6(double) "); } + + void f7(double x) { System.out.print("f7(double) "); } + + void testConstVal() { + System.out.print("5: "); + f1(5);f2(5);f3(5);f4(5);f5(5);f6(5);f7(5); + System.out.println(); + } + void testChar() { + char x = 'x'; + System.out.print("char: "); + f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); + System.out.println(); + } + void testByte() { + byte x = 0; + System.out.print("byte: "); + f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); + System.out.println(); + } + void testShort() { + short x = 0; + System.out.print("short: "); + f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); + System.out.println(); + } + void testInt() { + int x = 0; + System.out.print("int: "); + f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); + System.out.println(); + } + void testLong() { + long x = 0; + System.out.print("long: "); + f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); + System.out.println(); + } + void testFloat() { + float x = 0; + System.out.print("float: "); + f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); + System.out.println(); + } + void testDouble() { + double x = 0; + System.out.print("double: "); + f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); + System.out.println(); + } + public static void main(String[] args) { + PrimitiveOverloading p = + new PrimitiveOverloading(); + p.testConstVal(); + p.testChar(); + p.testByte(); + p.testShort(); + p.testInt(); + p.testLong(); + p.testFloat(); + p.testDouble(); + } +} +/* Output: +5: f1(int) f2(int) f3(int) f4(int) f5(long) f6(float) +f7(double) +char: f1(char) f2(int) f3(int) f4(int) f5(long) +f6(float) f7(double) +byte: f1(byte) f2(byte) f3(short) f4(int) f5(long) +f6(float) f7(double) +short: f1(short) f2(short) f3(short) f4(int) f5(long) +f6(float) f7(double) +int: f1(int) f2(int) f3(int) f4(int) f5(long) f6(float) +f7(double) +long: f1(long) f2(long) f3(long) f4(long) f5(long) +f6(float) f7(double) +float: f1(float) f2(float) f3(float) f4(float) +f5(float) f6(float) f7(double) +double: f1(double) f2(double) f3(double) f4(double) +f5(double) f6(double) f7(double) +*/ diff --git a/code/housekeeping/SimpleConstructor.java b/code/housekeeping/SimpleConstructor.java new file mode 100644 index 00000000..c6917c33 --- /dev/null +++ b/code/housekeeping/SimpleConstructor.java @@ -0,0 +1,21 @@ +// housekeeping/SimpleConstructor.java +// (c)2020 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. +// Demonstration of a simple constructor + +class Rock { + Rock() { // This is the constructor + System.out.print("Rock "); + } +} + +public class SimpleConstructor { + public static void main(String[] args) { + for(int i = 0; i < 10; i++) + new Rock(); + } +} +/* Output: +Rock Rock Rock Rock Rock Rock Rock Rock Rock Rock +*/ diff --git a/code/housekeeping/SimpleConstructor2.java b/code/housekeeping/SimpleConstructor2.java new file mode 100644 index 00000000..4a191af7 --- /dev/null +++ b/code/housekeeping/SimpleConstructor2.java @@ -0,0 +1,21 @@ +// housekeeping/SimpleConstructor2.java +// (c)2020 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. +// Constructors can have arguments + +class Rock2 { + Rock2(int i) { + System.out.print("Rock " + i + " "); + } +} + +public class SimpleConstructor2 { + public static void main(String[] args) { + for(int i = 0; i < 8; i++) + new Rock2(i); + } +} +/* Output: +Rock 0 Rock 1 Rock 2 Rock 3 Rock 4 Rock 5 Rock 6 Rock 7 +*/ diff --git a/code/housekeeping/SimpleEnumUse.java b/code/housekeeping/SimpleEnumUse.java new file mode 100644 index 00000000..cc0de33b --- /dev/null +++ b/code/housekeeping/SimpleEnumUse.java @@ -0,0 +1,14 @@ +// housekeeping/SimpleEnumUse.java +// (c)2020 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. + +public class SimpleEnumUse { + public static void main(String[] args) { + Spiciness howHot = Spiciness.MEDIUM; + System.out.println(howHot); + } +} +/* Output: +MEDIUM +*/ diff --git a/code/housekeeping/Spiciness.java b/code/housekeeping/Spiciness.java new file mode 100644 index 00000000..a134a822 --- /dev/null +++ b/code/housekeeping/Spiciness.java @@ -0,0 +1,8 @@ +// housekeeping/Spiciness.java +// (c)2020 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. + +public enum Spiciness { + NOT, MILD, MEDIUM, HOT, FLAMING +} diff --git a/code/housekeeping/Spoon.java b/code/housekeeping/Spoon.java new file mode 100644 index 00000000..fd344815 --- /dev/null +++ b/code/housekeeping/Spoon.java @@ -0,0 +1,10 @@ +// housekeeping/Spoon.java +// (c)2020 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. +public class Spoon { + static int i; + static { + i = 47; + } +} diff --git a/code/housekeeping/StaticInitialization.java b/code/housekeeping/StaticInitialization.java new file mode 100644 index 00000000..0cfe99ae --- /dev/null +++ b/code/housekeeping/StaticInitialization.java @@ -0,0 +1,73 @@ +// housekeeping/StaticInitialization.java +// (c)2020 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. +// Specifying initial values in a class definition + +class Bowl { + Bowl(int marker) { + System.out.println("Bowl(" + marker + ")"); + } + void f1(int marker) { + System.out.println("f1(" + marker + ")"); + } +} + +class Table { + static Bowl bowl1 = new Bowl(1); + Table() { + System.out.println("Table()"); + bowl2.f1(1); + } + void f2(int marker) { + System.out.println("f2(" + marker + ")"); + } + static Bowl bowl2 = new Bowl(2); +} + +class Cupboard { + Bowl bowl3 = new Bowl(3); + static Bowl bowl4 = new Bowl(4); + Cupboard() { + System.out.println("Cupboard()"); + bowl4.f1(2); + } + void f3(int marker) { + System.out.println("f3(" + marker + ")"); + } + static Bowl bowl5 = new Bowl(5); +} + +public class StaticInitialization { + public static void main(String[] args) { + System.out.println("main creating new Cupboard()"); + new Cupboard(); + System.out.println("main creating new Cupboard()"); + new Cupboard(); + table.f2(1); + cupboard.f3(1); + } + static Table table = new Table(); + static Cupboard cupboard = new Cupboard(); +} +/* Output: +Bowl(1) +Bowl(2) +Table() +f1(1) +Bowl(4) +Bowl(5) +Bowl(3) +Cupboard() +f1(2) +main creating new Cupboard() +Bowl(3) +Cupboard() +f1(2) +main creating new Cupboard() +Bowl(3) +Cupboard() +f1(2) +f2(1) +f3(1) +*/ diff --git a/code/housekeeping/TerminationCondition.java b/code/housekeeping/TerminationCondition.java new file mode 100644 index 00000000..dc8d347b --- /dev/null +++ b/code/housekeeping/TerminationCondition.java @@ -0,0 +1,41 @@ +// housekeeping/TerminationCondition.java +// (c)2020 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. +// Using finalize() to detect an object that +// hasn't been properly cleaned up +import onjava.*; + +class Book { + boolean checkedOut = false; + Book(boolean checkOut) { + checkedOut = checkOut; + } + void checkIn() { + checkedOut = false; + } + @SuppressWarnings("deprecation") + @Override + public void finalize() { + if(checkedOut) + System.out.println("Error: checked out"); + // Normally, you'll also do this: + // super.finalize(); // Call the base-class version + } +} + +public class TerminationCondition { + public static void main(String[] args) { + Book novel = new Book(true); + // Proper cleanup: + novel.checkIn(); + // Drop the reference, forget to clean up: + new Book(true); + // Force garbage collection & finalization: + System.gc(); + new Nap(1); // One second delay + } +} +/* Output: +Error: checked out +*/ diff --git a/code/housekeeping/VarArgs.java b/code/housekeeping/VarArgs.java new file mode 100644 index 00000000..73a94c39 --- /dev/null +++ b/code/housekeeping/VarArgs.java @@ -0,0 +1,26 @@ +// housekeeping/VarArgs.java +// (c)2020 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. +// Using array syntax to create variable argument lists + +class A {} + +public class VarArgs { + static void printArray(Object[] args) { + for(Object obj : args) + System.out.print(obj + " "); + System.out.println(); + } + public static void main(String[] args) { + printArray(new Object[]{ + 47, (float) 3.14, 11.11}); + printArray(new Object[]{"one", "two", "three" }); + printArray(new Object[]{new A(), new A(), new A()}); + } +} +/* Output: +47 3.14 11.11 +one two three +A@15db9742 A@6d06d69c A@7852e922 +*/ diff --git a/code/housekeeping/VarargType.java b/code/housekeeping/VarargType.java new file mode 100644 index 00000000..5b25b053 --- /dev/null +++ b/code/housekeeping/VarargType.java @@ -0,0 +1,30 @@ +// housekeeping/VarargType.java +// (c)2020 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. + +public class VarargType { + static void f(Character... args) { + System.out.print(args.getClass()); + System.out.println(" length " + args.length); + } + static void g(int... args) { + System.out.print(args.getClass()); + System.out.println(" length " + args.length); + } + public static void main(String[] args) { + f('a'); + f(); + g(1); + g(); + System.out.println("int[]: " + + new int[0].getClass()); + } +} +/* Output: +class [Ljava.lang.Character; length 1 +class [Ljava.lang.Character; length 0 +class [I length 1 +class [I length 0 +int[]: class [I +*/ diff --git a/code/innerclasses/AnonymousConstructor.java b/code/innerclasses/AnonymousConstructor.java new file mode 100644 index 00000000..d8e08e7c --- /dev/null +++ b/code/innerclasses/AnonymousConstructor.java @@ -0,0 +1,34 @@ +// innerclasses/AnonymousConstructor.java +// (c)2020 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. +// Creating a constructor for an anonymous inner class + +abstract class Base { + Base(int i) { + System.out.println("Base constructor, i = " + i); + } + public abstract void f(); +} + +public class AnonymousConstructor { + public static Base getBase(int i) { + return new Base(i) { + { System.out.println( + "Inside instance initializer"); } + @Override + public void f() { + System.out.println("In anonymous f()"); + } + }; + } + public static void main(String[] args) { + Base base = getBase(47); + base.f(); + } +} +/* Output: +Base constructor, i = 47 +Inside instance initializer +In anonymous f() +*/ diff --git a/code/innerclasses/BigEgg.java b/code/innerclasses/BigEgg.java new file mode 100644 index 00000000..7b2c3624 --- /dev/null +++ b/code/innerclasses/BigEgg.java @@ -0,0 +1,33 @@ +// innerclasses/BigEgg.java +// (c)2020 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. +// An inner class cannot be overridden like a method + +class Egg { + private Yolk y; + protected class Yolk { + public Yolk() { + System.out.println("Egg.Yolk()"); + } + } + Egg() { + System.out.println("New Egg()"); + y = new Yolk(); + } +} + +public class BigEgg extends Egg { + public class Yolk { + public Yolk() { + System.out.println("BigEgg.Yolk()"); + } + } + public static void main(String[] args) { + new BigEgg(); + } +} +/* Output: +New Egg() +Egg.Yolk() +*/ diff --git a/code/innerclasses/BigEgg2.java b/code/innerclasses/BigEgg2.java new file mode 100644 index 00000000..1631008d --- /dev/null +++ b/code/innerclasses/BigEgg2.java @@ -0,0 +1,44 @@ +// innerclasses/BigEgg2.java +// (c)2020 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. +// Proper inheritance of an inner class + +class Egg2 { + protected class Yolk { + public Yolk() { + System.out.println("Egg2.Yolk()"); + } + public void f() { + System.out.println("Egg2.Yolk.f()"); + } + } + private Yolk y = new Yolk(); + Egg2() { System.out.println("New Egg2()"); } + public void insertYolk(Yolk yy) { y = yy; } + public void g() { y.f(); } +} + +public class BigEgg2 extends Egg2 { + public class Yolk extends Egg2.Yolk { + public Yolk() { + System.out.println("BigEgg2.Yolk()"); + } + @Override + public void f() { + System.out.println("BigEgg2.Yolk.f()"); + } + } + public BigEgg2() { insertYolk(new Yolk()); } + public static void main(String[] args) { + Egg2 e2 = new BigEgg2(); + e2.g(); + } +} +/* Output: +Egg2.Yolk() +New Egg2() +Egg2.Yolk() +BigEgg2.Yolk() +BigEgg2.Yolk.f() +*/ diff --git a/code/innerclasses/Callbacks.java b/code/innerclasses/Callbacks.java new file mode 100644 index 00000000..d1659332 --- /dev/null +++ b/code/innerclasses/Callbacks.java @@ -0,0 +1,84 @@ +// innerclasses/Callbacks.java +// (c)2020 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. +// Using inner classes for callbacks +// {java innerclasses.Callbacks} +package innerclasses; + +interface Incrementable { + void increment(); +} + +// Very simple to just implement the interface: +class Callee1 implements Incrementable { + private int i = 0; + @Override + public void increment() { + i++; + System.out.println(i); + } +} + +class MyIncrement { + public void increment() { + System.out.println("Other operation"); + } + static void f(MyIncrement mi) { mi.increment(); } +} + +// If your class must implement increment() in +// some other way, you must use an inner class: +class Callee2 extends MyIncrement { + private int i = 0; + @Override + public void increment() { + super.increment(); + i++; + System.out.println(i); + } + private class Closure implements Incrementable { + @Override + public void increment() { + // Specify outer-class method, otherwise + // you'll get an infinite recursion: + Callee2.this.increment(); + } + } + Incrementable getCallbackReference() { + return new Closure(); + } +} + +class Caller { + private Incrementable callbackReference; + Caller(Incrementable cbh) { + callbackReference = cbh; + } + void go() { callbackReference.increment(); } +} + +public class Callbacks { + public static void main(String[] args) { + Callee1 c1 = new Callee1(); + Callee2 c2 = new Callee2(); + MyIncrement.f(c2); + Caller caller1 = new Caller(c1); + Caller caller2 = + new Caller(c2.getCallbackReference()); + caller1.go(); + caller1.go(); + caller2.go(); + caller2.go(); + } +} +/* Output: +Other operation +1 +1 +2 +Other operation +2 +Other operation +3 +*/ diff --git a/code/innerclasses/ClassInInterface.java b/code/innerclasses/ClassInInterface.java new file mode 100644 index 00000000..c3cc0589 --- /dev/null +++ b/code/innerclasses/ClassInInterface.java @@ -0,0 +1,21 @@ +// innerclasses/ClassInInterface.java +// (c)2020 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. +// {java ClassInInterface$Test} + +public interface ClassInInterface { + void howdy(); + class Test implements ClassInInterface { + @Override + public void howdy() { + System.out.println("Howdy!"); + } + public static void main(String[] args) { + new Test().howdy(); + } + } +} +/* Output: +Howdy! +*/ diff --git a/code/innerclasses/Contents.java b/code/innerclasses/Contents.java new file mode 100644 index 00000000..0cebe1a0 --- /dev/null +++ b/code/innerclasses/Contents.java @@ -0,0 +1,7 @@ +// innerclasses/Contents.java +// (c)2020 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. +public interface Contents { + int value(); +} diff --git a/code/innerclasses/Destination.java b/code/innerclasses/Destination.java new file mode 100644 index 00000000..bf221526 --- /dev/null +++ b/code/innerclasses/Destination.java @@ -0,0 +1,7 @@ +// innerclasses/Destination.java +// (c)2020 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. +public interface Destination { + String readLabel(); +} diff --git a/code/innerclasses/DotNew.java b/code/innerclasses/DotNew.java new file mode 100644 index 00000000..317400e8 --- /dev/null +++ b/code/innerclasses/DotNew.java @@ -0,0 +1,13 @@ +// innerclasses/DotNew.java +// (c)2020 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. +// Creating an inner class directly using .new syntax + +public class DotNew { + public class Inner {} + public static void main(String[] args) { + DotNew dn = new DotNew(); + DotNew.Inner dni = dn.new Inner(); + } +} diff --git a/code/innerclasses/DotThis.java b/code/innerclasses/DotThis.java new file mode 100644 index 00000000..b87cb1f4 --- /dev/null +++ b/code/innerclasses/DotThis.java @@ -0,0 +1,24 @@ +// innerclasses/DotThis.java +// (c)2020 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. +// Accessing the outer-class object + +public class DotThis { + void f() { System.out.println("DotThis.f()"); } + public class Inner { + public DotThis outer() { + return DotThis.this; + // A plain "this" would be Inner's "this" + } + } + public Inner inner() { return new Inner(); } + public static void main(String[] args) { + DotThis dt = new DotThis(); + DotThis.Inner dti = dt.inner(); + dti.outer().f(); + } +} +/* Output: +DotThis.f() +*/ diff --git a/code/innerclasses/GreenhouseController.java b/code/innerclasses/GreenhouseController.java new file mode 100644 index 00000000..cf3ec653 --- /dev/null +++ b/code/innerclasses/GreenhouseController.java @@ -0,0 +1,54 @@ +// innerclasses/GreenhouseController.java +// (c)2020 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. +// Configure and execute the greenhouse system +import innerclasses.controller.*; + +public class GreenhouseController { + public static void main(String[] args) { + GreenhouseControls gc = new GreenhouseControls(); + // Instead of using code, you could parse + // configuration information from a text file: + gc.addEvent(gc.new Bell(900)); + Event[] eventList = { + gc.new ThermostatNight(0), + gc.new LightOn(200), + gc.new LightOff(400), + gc.new WaterOn(600), + gc.new WaterOff(800), + gc.new ThermostatDay(1400) + }; + gc.addEvent(gc.new Restart(2000, eventList)); + gc.addEvent( + new GreenhouseControls.Terminate(5000)); + gc.run(); + } +} +/* Output: +Thermostat on night setting +Light is on +Light is off +Greenhouse water is on +Greenhouse water is off +Bing! +Thermostat on day setting +Bing! +Restarting system +Thermostat on night setting +Light is on +Light is off +Greenhouse water is on +Bing! +Greenhouse water is off +Thermostat on day setting +Bing! +Restarting system +Thermostat on night setting +Light is on +Light is off +Bing! +Greenhouse water is on +Greenhouse water is off +Terminating +*/ diff --git a/code/innerclasses/GreenhouseControls.java b/code/innerclasses/GreenhouseControls.java new file mode 100644 index 00000000..57458d66 --- /dev/null +++ b/code/innerclasses/GreenhouseControls.java @@ -0,0 +1,150 @@ +// innerclasses/GreenhouseControls.java +// (c)2020 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. +// This produces a specific application of the +// control system, all in a single class. Inner +// classes allow you to encapsulate different +// functionality for each type of event. +import innerclasses.controller.*; + +public class GreenhouseControls extends Controller { + private boolean light = false; + public class LightOn extends Event { + public LightOn(long delayTime) { + super(delayTime); + } + @Override + public void action() { + // Put hardware control code here to + // physically turn on the light. + light = true; + } + @Override + public String toString() { + return "Light is on"; + } + } + public class LightOff extends Event { + public LightOff(long delayTime) { + super(delayTime); + } + @Override + public void action() { + // Put hardware control code here to + // physically turn off the light. + light = false; + } + @Override + public String toString() { + return "Light is off"; + } + } + private boolean water = false; + public class WaterOn extends Event { + public WaterOn(long delayTime) { + super(delayTime); + } + @Override + public void action() { + // Put hardware control code here. + water = true; + } + @Override + public String toString() { + return "Greenhouse water is on"; + } + } + public class WaterOff extends Event { + public WaterOff(long delayTime) { + super(delayTime); + } + @Override + public void action() { + // Put hardware control code here. + water = false; + } + @Override + public String toString() { + return "Greenhouse water is off"; + } + } + private String thermostat = "Day"; + public class ThermostatNight extends Event { + public ThermostatNight(long delayTime) { + super(delayTime); + } + @Override + public void action() { + // Put hardware control code here. + thermostat = "Night"; + } + @Override + public String toString() { + return "Thermostat on night setting"; + } + } + public class ThermostatDay extends Event { + public ThermostatDay(long delayTime) { + super(delayTime); + } + @Override + public void action() { + // Put hardware control code here. + thermostat = "Day"; + } + @Override + public String toString() { + return "Thermostat on day setting"; + } + } + // An example of an action() that inserts a + // new one of itself into the event list: + public class Bell extends Event { + public Bell(long delayTime) { + super(delayTime); + } + @Override + public void action() { + addEvent(new Bell(delayTime.toMillis())); + } + @Override + public String toString() { + return "Bing!"; + } + } + public class Restart extends Event { + private Event[] eventList; + public + Restart(long delayTime, Event[] eventList) { + super(delayTime); + this.eventList = eventList; + for(Event e : eventList) + addEvent(e); + } + @Override + public void action() { + for(Event e : eventList) { + e.start(); // Rerun each event + addEvent(e); + } + start(); // Rerun this Event + addEvent(this); + } + @Override + public String toString() { + return "Restarting system"; + } + } + public static class Terminate extends Event { + public Terminate(long delayTime) { + super(delayTime); + } + @Override + public void action() { System.exit(0); } + @Override + public String toString() { + return "Terminating"; + } + } +} diff --git a/code/innerclasses/InheritInner.java b/code/innerclasses/InheritInner.java new file mode 100644 index 00000000..ffc86894 --- /dev/null +++ b/code/innerclasses/InheritInner.java @@ -0,0 +1,20 @@ +// innerclasses/InheritInner.java +// (c)2020 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. +// Inheriting an inner class + +class WithInner { + class Inner {} +} + +public class InheritInner extends WithInner.Inner { + //- InheritInner() {} // Won't compile + InheritInner(WithInner wi) { + wi.super(); + } + public static void main(String[] args) { + WithInner wi = new WithInner(); + InheritInner ii = new InheritInner(wi); + } +} diff --git a/code/innerclasses/LocalInnerClass.java b/code/innerclasses/LocalInnerClass.java new file mode 100644 index 00000000..01510854 --- /dev/null +++ b/code/innerclasses/LocalInnerClass.java @@ -0,0 +1,67 @@ +// innerclasses/LocalInnerClass.java +// (c)2020 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. +// Holds a sequence of Objects + +interface Counter { + int next(); +} + +public class LocalInnerClass { + private int count = 0; + Counter getCounter(final String name) { + // A local inner class: + class LocalCounter implements Counter { + LocalCounter() { + // Local inner class can have a constructor + System.out.println("LocalCounter()"); + } + @Override + public int next() { + System.out.print(name); // Access local final + return count++; + } + } + return new LocalCounter(); + } + // Repeat, but with an anonymous inner class: + Counter getCounter2(final String name) { + return new Counter() { + // Anonymous inner class cannot have a named + // constructor, only an instance initializer: + { + System.out.println("Counter()"); + } + @Override + public int next() { + System.out.print(name); // Access local final + return count++; + } + }; + } + public static void main(String[] args) { + LocalInnerClass lic = new LocalInnerClass(); + Counter + c1 = lic.getCounter("Local inner "), + c2 = lic.getCounter2("Anonymous inner "); + for(int i = 0; i < 5; i++) + System.out.println(c1.next()); + for(int i = 0; i < 5; i++) + System.out.println(c2.next()); + } +} +/* Output: +LocalCounter() +Counter() +Local inner 0 +Local inner 1 +Local inner 2 +Local inner 3 +Local inner 4 +Anonymous inner 5 +Anonymous inner 6 +Anonymous inner 7 +Anonymous inner 8 +Anonymous inner 9 +*/ diff --git a/code/innerclasses/MultiImplementation.java b/code/innerclasses/MultiImplementation.java new file mode 100644 index 00000000..6eb6c494 --- /dev/null +++ b/code/innerclasses/MultiImplementation.java @@ -0,0 +1,25 @@ +// innerclasses/MultiImplementation.java +// (c)2020 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. +// For concrete or abstract classes, inner classes +// produce "multiple implementation inheritance" +// {java innerclasses.MultiImplementation} +package innerclasses; + +class D {} +abstract class E {} + +class Z extends D { + E makeE() { return new E() {}; } +} + +public class MultiImplementation { + static void takesD(D d) {} + static void takesE(E e) {} + public static void main(String[] args) { + Z z = new Z(); + takesD(z); + takesE(z.makeE()); + } +} diff --git a/code/innerclasses/MultiNestingAccess.java b/code/innerclasses/MultiNestingAccess.java new file mode 100644 index 00000000..bf9e3cb0 --- /dev/null +++ b/code/innerclasses/MultiNestingAccess.java @@ -0,0 +1,28 @@ +// innerclasses/MultiNestingAccess.java +// (c)2020 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. +// Nested classes can access all members of all +// levels of the classes they are nested within + +class MNA { + private void f() {} + class A { + private void g() {} + public class B { + void h() { + g(); + f(); + } + } + } +} + +public class MultiNestingAccess { + public static void main(String[] args) { + MNA mna = new MNA(); + MNA.A mnaa = mna.new A(); + MNA.A.B mnaab = mnaa.new B(); + mnaab.h(); + } +} diff --git a/code/innerclasses/Parcel1.java b/code/innerclasses/Parcel1.java new file mode 100644 index 00000000..94464cbc --- /dev/null +++ b/code/innerclasses/Parcel1.java @@ -0,0 +1,33 @@ +// innerclasses/Parcel1.java +// (c)2020 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. +// Creating inner classes + +public class Parcel1 { + class Contents { + private int i = 11; + public int value() { return i; } + } + class Destination { + private String label; + Destination(String whereTo) { + label = whereTo; + } + String readLabel() { return label; } + } + // Using inner classes looks just like + // using any other class, within Parcel1: + public void ship(String dest) { + Contents c = new Contents(); + Destination d = new Destination(dest); + System.out.println(d.readLabel()); + } + public static void main(String[] args) { + Parcel1 p = new Parcel1(); + p.ship("Tasmania"); + } +} +/* Output: +Tasmania +*/ diff --git a/code/innerclasses/Parcel10.java b/code/innerclasses/Parcel10.java new file mode 100644 index 00000000..7150c192 --- /dev/null +++ b/code/innerclasses/Parcel10.java @@ -0,0 +1,31 @@ +// innerclasses/Parcel10.java +// (c)2020 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. +// Using "instance initialization" to perform +// construction on an anonymous inner class + +public class Parcel10 { + public Destination + destination(final String dest, final float price) { + return new Destination() { + private int cost; + // Instance initialization for each object: + { + cost = Math.round(price); + if(cost > 100) + System.out.println("Over budget!"); + } + private String label = dest; + @Override + public String readLabel() { return label; } + }; + } + public static void main(String[] args) { + Parcel10 p = new Parcel10(); + Destination d = p.destination("Tasmania", 101.395F); + } +} +/* Output: +Over budget! +*/ diff --git a/code/innerclasses/Parcel11.java b/code/innerclasses/Parcel11.java new file mode 100644 index 00000000..720981f0 --- /dev/null +++ b/code/innerclasses/Parcel11.java @@ -0,0 +1,40 @@ +// innerclasses/Parcel11.java +// (c)2020 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. +// Nested classes (static inner classes) + +public class Parcel11 { + private static class + ParcelContents implements Contents { + private int i = 11; + @Override + public int value() { return i; } + } + protected static final class ParcelDestination + implements Destination { + private String label; + private ParcelDestination(String whereTo) { + label = whereTo; + } + @Override + public String readLabel() { return label; } + // Nested classes can contain other static elements: + public static void f() {} + static int x = 10; + static class AnotherLevel { + public static void f() {} + static int x = 10; + } + } + public static Destination destination(String s) { + return new ParcelDestination(s); + } + public static Contents contents() { + return new ParcelContents(); + } + public static void main(String[] args) { + Contents c = contents(); + Destination d = destination("Tasmania"); + } +} diff --git a/code/innerclasses/Parcel2.java b/code/innerclasses/Parcel2.java new file mode 100644 index 00000000..1eca5cba --- /dev/null +++ b/code/innerclasses/Parcel2.java @@ -0,0 +1,41 @@ +// innerclasses/Parcel2.java +// (c)2020 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. +// Returning a reference to an inner class + +public class Parcel2 { + class Contents { + private int i = 11; + public int value() { return i; } + } + class Destination { + private String label; + Destination(String whereTo) { + label = whereTo; + } + String readLabel() { return label; } + } + public Destination to(String s) { + return new Destination(s); + } + public Contents contents() { + return new Contents(); + } + public void ship(String dest) { + Contents c = contents(); + Destination d = to(dest); + System.out.println(d.readLabel()); + } + public static void main(String[] args) { + Parcel2 p = new Parcel2(); + p.ship("Tasmania"); + Parcel2 q = new Parcel2(); + // Defining references to inner classes: + Parcel2.Contents c = q.contents(); + Parcel2.Destination d = q.to("Borneo"); + } +} +/* Output: +Tasmania +*/ diff --git a/code/innerclasses/Parcel3.java b/code/innerclasses/Parcel3.java new file mode 100644 index 00000000..2e0733e0 --- /dev/null +++ b/code/innerclasses/Parcel3.java @@ -0,0 +1,25 @@ +// innerclasses/Parcel3.java +// (c)2020 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. +// Using .new to create instances of inner classes + +public class Parcel3 { + class Contents { + private int i = 11; + public int value() { return i; } + } + class Destination { + private String label; + Destination(String whereTo) { label = whereTo; } + String readLabel() { return label; } + } + public static void main(String[] args) { + Parcel3 p = new Parcel3(); + // Must use instance of outer class + // to create an instance of the inner class: + Parcel3.Contents c = p.new Contents(); + Parcel3.Destination d = + p.new Destination("Tasmania"); + } +} diff --git a/code/innerclasses/Parcel5.java b/code/innerclasses/Parcel5.java new file mode 100644 index 00000000..622b3fd0 --- /dev/null +++ b/code/innerclasses/Parcel5.java @@ -0,0 +1,23 @@ +// innerclasses/Parcel5.java +// (c)2020 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. +// Nesting a class within a method + +public class Parcel5 { + public Destination destination(String s) { + final class PDestination implements Destination { + private String label; + private PDestination(String whereTo) { + label = whereTo; + } + @Override + public String readLabel() { return label; } + } + return new PDestination(s); + } + public static void main(String[] args) { + Parcel5 p = new Parcel5(); + Destination d = p.destination("Tasmania"); + } +} diff --git a/code/innerclasses/Parcel6.java b/code/innerclasses/Parcel6.java new file mode 100644 index 00000000..7a2c866e --- /dev/null +++ b/code/innerclasses/Parcel6.java @@ -0,0 +1,28 @@ +// innerclasses/Parcel6.java +// (c)2020 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. +// Nesting a class within a scope + +public class Parcel6 { + private void internalTracking(boolean b) { + if(b) { + class TrackingSlip { + private String id; + TrackingSlip(String s) { + id = s; + } + String getSlip() { return id; } + } + TrackingSlip ts = new TrackingSlip("slip"); + String s = ts.getSlip(); + } + // Can't use it here! Out of scope: + //- TrackingSlip ts = new TrackingSlip("x"); + } + public void track() { internalTracking(true); } + public static void main(String[] args) { + Parcel6 p = new Parcel6(); + p.track(); + } +} diff --git a/code/innerclasses/Parcel7.java b/code/innerclasses/Parcel7.java new file mode 100644 index 00000000..3a4aefbb --- /dev/null +++ b/code/innerclasses/Parcel7.java @@ -0,0 +1,19 @@ +// innerclasses/Parcel7.java +// (c)2020 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. +// Returning an instance of an anonymous inner class + +public class Parcel7 { + public Contents contents() { + return new Contents() { // Insert class definition + private int i = 11; + @Override + public int value() { return i; } + }; // Semicolon required + } + public static void main(String[] args) { + Parcel7 p = new Parcel7(); + Contents c = p.contents(); + } +} diff --git a/code/innerclasses/Parcel7b.java b/code/innerclasses/Parcel7b.java new file mode 100644 index 00000000..bee95727 --- /dev/null +++ b/code/innerclasses/Parcel7b.java @@ -0,0 +1,20 @@ +// innerclasses/Parcel7b.java +// (c)2020 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. +// Expanded version of Parcel7.java + +public class Parcel7b { + class MyContents implements Contents { + private int i = 11; + @Override + public int value() { return i; } + } + public Contents contents() { + return new MyContents(); + } + public static void main(String[] args) { + Parcel7b p = new Parcel7b(); + Contents c = p.contents(); + } +} diff --git a/code/innerclasses/Parcel8.java b/code/innerclasses/Parcel8.java new file mode 100644 index 00000000..1e615ac5 --- /dev/null +++ b/code/innerclasses/Parcel8.java @@ -0,0 +1,21 @@ +// innerclasses/Parcel8.java +// (c)2020 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. +// Calling the base-class constructor + +public class Parcel8 { + public Wrapping wrapping(int x) { + // Base constructor call: + return new Wrapping(x) { // [1] + @Override + public int value() { + return super.value() * 47; + } + }; // [2] + } + public static void main(String[] args) { + Parcel8 p = new Parcel8(); + Wrapping w = p.wrapping(10); + } +} diff --git a/code/innerclasses/Parcel9.java b/code/innerclasses/Parcel9.java new file mode 100644 index 00000000..775390f1 --- /dev/null +++ b/code/innerclasses/Parcel9.java @@ -0,0 +1,20 @@ +// innerclasses/Parcel9.java +// (c)2020 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. + +public class Parcel9 { + // Argument must be final or "effectively final" + // to use within the anonymous inner class: + public Destination destination(final String dest) { + return new Destination() { + private String label = dest; + @Override + public String readLabel() { return label; } + }; + } + public static void main(String[] args) { + Parcel9 p = new Parcel9(); + Destination d = p.destination("Tasmania"); + } +} diff --git a/code/innerclasses/Sequence.java b/code/innerclasses/Sequence.java new file mode 100644 index 00000000..b5a870b9 --- /dev/null +++ b/code/innerclasses/Sequence.java @@ -0,0 +1,48 @@ +// innerclasses/Sequence.java +// (c)2020 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. +// Holds a sequence of Objects + +interface Selector { + boolean end(); + Object current(); + void next(); +} + +public class Sequence { + private Object[] items; + private int next = 0; + public Sequence(int size) { + items = new Object[size]; + } + public void add(Object x) { + if(next < items.length) + items[next++] = x; + } + private class SequenceSelector implements Selector { + private int i = 0; + @Override + public boolean end() { return i == items.length; } + @Override + public Object current() { return items[i]; } + @Override + public void next() { if(i < items.length) i++; } + } + public Selector selector() { + return new SequenceSelector(); + } + public static void main(String[] args) { + Sequence sequence = new Sequence(10); + for(int i = 0; i < 10; i++) + sequence.add(Integer.toString(i)); + Selector selector = sequence.selector(); + while(!selector.end()) { + System.out.print(selector.current() + " "); + selector.next(); + } + } +} +/* Output: +0 1 2 3 4 5 6 7 8 9 +*/ diff --git a/code/innerclasses/TestBed.java b/code/innerclasses/TestBed.java new file mode 100644 index 00000000..d4bc16dd --- /dev/null +++ b/code/innerclasses/TestBed.java @@ -0,0 +1,19 @@ +// innerclasses/TestBed.java +// (c)2020 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. +// Putting test code in a nested class +// {java TestBed$Tester} + +public class TestBed { + public void f() { System.out.println("f()"); } + public static class Tester { + public static void main(String[] args) { + TestBed t = new TestBed(); + t.f(); + } + } +} +/* Output: +f() +*/ diff --git a/code/innerclasses/TestParcel.java b/code/innerclasses/TestParcel.java new file mode 100644 index 00000000..f1ec5d47 --- /dev/null +++ b/code/innerclasses/TestParcel.java @@ -0,0 +1,37 @@ +// innerclasses/TestParcel.java +// (c)2020 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. + +class Parcel4 { + private class PContents implements Contents { + private int i = 11; + @Override + public int value() { return i; } + } + protected final class + PDestination implements Destination { + private String label; + private PDestination(String whereTo) { + label = whereTo; + } + @Override + public String readLabel() { return label; } + } + public Destination destination(String s) { + return new PDestination(s); + } + public Contents contents() { + return new PContents(); + } +} + +public class TestParcel { + public static void main(String[] args) { + Parcel4 p = new Parcel4(); + Contents c = p.contents(); + Destination d = p.destination("Tasmania"); + // Illegal -- can't access private class: + //- Parcel4.PContents pc = p.new PContents(); + } +} diff --git a/code/innerclasses/Wrapping.java b/code/innerclasses/Wrapping.java new file mode 100644 index 00000000..651c0748 --- /dev/null +++ b/code/innerclasses/Wrapping.java @@ -0,0 +1,9 @@ +// innerclasses/Wrapping.java +// (c)2020 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. +public class Wrapping { + private int i; + public Wrapping(int x) { i = x; } + public int value() { return i; } +} diff --git a/code/innerclasses/controller/Controller.java b/code/innerclasses/controller/Controller.java new file mode 100644 index 00000000..9a3625b3 --- /dev/null +++ b/code/innerclasses/controller/Controller.java @@ -0,0 +1,24 @@ +// innerclasses/controller/Controller.java +// (c)2020 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. +// The reusable framework for control systems +package innerclasses.controller; +import java.util.*; + +public class Controller { + // A class from java.util to hold Event objects: + private List eventList = new ArrayList<>(); + public void addEvent(Event c) { eventList.add(c); } + public void run() { + while(eventList.size() > 0) + // Make a copy so you're not modifying the list + // while you're selecting the elements in it: + for(Event e : new ArrayList<>(eventList)) + if(e.ready()) { + System.out.println(e); + e.action(); + eventList.remove(e); + } + } +} diff --git a/code/innerclasses/controller/Event.java b/code/innerclasses/controller/Event.java new file mode 100644 index 00000000..5523168f --- /dev/null +++ b/code/innerclasses/controller/Event.java @@ -0,0 +1,23 @@ +// innerclasses/controller/Event.java +// (c)2020 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. +// The common methods for any control event +package innerclasses.controller; +import java.time.*; // Java 8 time classes + +public abstract class Event { + private Instant eventTime; + protected final Duration delayTime; + public Event(long millisecondDelay) { + delayTime = Duration.ofMillis(millisecondDelay); + start(); + } + public void start() { // Allows restarting + eventTime = Instant.now().plus(delayTime); + } + public boolean ready() { + return Instant.now().isAfter(eventTime); + } + public abstract void action(); +} diff --git a/code/innerclasses/mui/MultiInterfaces.java b/code/innerclasses/mui/MultiInterfaces.java new file mode 100644 index 00000000..127a6c80 --- /dev/null +++ b/code/innerclasses/mui/MultiInterfaces.java @@ -0,0 +1,32 @@ +// innerclasses/mui/MultiInterfaces.java +// (c)2020 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. +// Two ways a class can implement multiple interfaces +// {java innerclasses.mui.MultiInterfaces} +package innerclasses.mui; + +interface A {} +interface B {} + +class X implements A, B {} + +class Y implements A { + B makeB() { + // Anonymous inner class: + return new B() {}; + } +} + +public class MultiInterfaces { + static void takesA(A a) {} + static void takesB(B b) {} + public static void main(String[] args) { + X x = new X(); + Y y = new Y(); + takesA(x); + takesA(y); + takesB(x); + takesB(y.makeB()); + } +} diff --git a/code/interfaces/AbstractAccess.java b/code/interfaces/AbstractAccess.java new file mode 100644 index 00000000..c2e43da3 --- /dev/null +++ b/code/interfaces/AbstractAccess.java @@ -0,0 +1,15 @@ +// interfaces/AbstractAccess.java +// (c)2020 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. + +abstract class AbstractAccess { + private void m1() {} + // private abstract void m1a(); // illegal + protected void m2() {} + protected abstract void m2a(); + void m3() {} + abstract void m3a(); + public void m4() {} + public abstract void m4a(); +} diff --git a/code/interfaces/AbstractWithoutAbstracts.java b/code/interfaces/AbstractWithoutAbstracts.java new file mode 100644 index 00000000..2e6b700c --- /dev/null +++ b/code/interfaces/AbstractWithoutAbstracts.java @@ -0,0 +1,14 @@ +// interfaces/AbstractWithoutAbstracts.java +// (c)2020 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. + +abstract class Basic3 { + int f() { return 111; } + // No abstract methods +} + +public class AbstractWithoutAbstracts { + // Basic3 b3 = new Basic3(); + // error: Basic3 is abstract; cannot be instantiated +} diff --git a/code/interfaces/AdaptedRandomDoubles.java b/code/interfaces/AdaptedRandomDoubles.java new file mode 100644 index 00000000..6c786655 --- /dev/null +++ b/code/interfaces/AdaptedRandomDoubles.java @@ -0,0 +1,35 @@ +// interfaces/AdaptedRandomDoubles.java +// (c)2020 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. +// Creating an adapter with inheritance +import java.nio.*; +import java.util.*; + +public class AdaptedRandomDoubles +implements RandomDoubles, Readable { + private int count; + public AdaptedRandomDoubles(int count) { + this.count = count; + } + @Override + public int read(CharBuffer cb) { + if(count-- == 0) + return -1; + String result = Double.toString(next()) + " "; + cb.append(result); + return result.length(); + } + public static void main(String[] args) { + Scanner s = + new Scanner(new AdaptedRandomDoubles(7)); + while(s.hasNextDouble()) + System.out.print(s.nextDouble() + " "); + } +} +/* Output: +0.7271157860730044 0.5309454508634242 +0.16020656493302599 0.18847866977771732 +0.5166020801268457 0.2678662084200585 +0.2613610344283964 +*/ diff --git a/code/interfaces/Adventure.java b/code/interfaces/Adventure.java new file mode 100644 index 00000000..1a7135d1 --- /dev/null +++ b/code/interfaces/Adventure.java @@ -0,0 +1,41 @@ +// interfaces/Adventure.java +// (c)2020 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. +// Multiple interfaces + +interface CanFight { + void fight(); +} + +interface CanSwim { + void swim(); +} + +interface CanFly { + void fly(); +} + +class ActionCharacter { + public void fight() {} +} + +class Hero extends ActionCharacter + implements CanFight, CanSwim, CanFly { + public void swim() {} + public void fly() {} +} + +public class Adventure { + public static void t(CanFight x) { x.fight(); } + public static void u(CanSwim x) { x.swim(); } + public static void v(CanFly x) { x.fly(); } + public static void w(ActionCharacter x) { x.fight(); } + public static void main(String[] args) { + Hero h = new Hero(); + t(h); // Treat it as a CanFight + u(h); // Treat it as a CanSwim + v(h); // Treat it as a CanFly + w(h); // Treat it as an ActionCharacter + } +} diff --git a/code/interfaces/AnImplementation.java b/code/interfaces/AnImplementation.java new file mode 100644 index 00000000..3ff13a30 --- /dev/null +++ b/code/interfaces/AnImplementation.java @@ -0,0 +1,22 @@ +// interfaces/AnImplementation.java +// (c)2020 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. + +public class AnImplementation implements AnInterface { + public void firstMethod() { + System.out.println("firstMethod"); + } + public void secondMethod() { + System.out.println("secondMethod"); + } + public static void main(String[] args) { + AnInterface i = new AnImplementation(); + i.firstMethod(); + i.secondMethod(); + } +} +/* Output: +firstMethod +secondMethod +*/ diff --git a/code/interfaces/AnInterface.java b/code/interfaces/AnInterface.java new file mode 100644 index 00000000..30f82b3a --- /dev/null +++ b/code/interfaces/AnInterface.java @@ -0,0 +1,9 @@ +// interfaces/AnInterface.java +// (c)2020 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. + +interface AnInterface { + void firstMethod(); + void secondMethod(); +} diff --git a/code/interfaces/Applicator.java b/code/interfaces/Applicator.java new file mode 100644 index 00000000..a6aa172f --- /dev/null +++ b/code/interfaces/Applicator.java @@ -0,0 +1,58 @@ +// interfaces/Applicator.java +// (c)2020 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. +import java.util.*; + +class Processor { + public String name() { + return getClass().getSimpleName(); + } + public Object process(Object input) { + return input; + } +} + +class Upcase extends Processor { + @Override // Covariant return: + public String process(Object input) { + return ((String)input).toUpperCase(); + } +} + +class Downcase extends Processor { + @Override + public String process(Object input) { + return ((String)input).toLowerCase(); + } +} + +class Splitter extends Processor { + @Override + public String process(Object input) { + // split() divides a String into pieces: + return Arrays.toString(((String)input).split(" ")); + } +} + +public class Applicator { + public static void apply(Processor p, Object s) { + System.out.println("Using Processor " + p.name()); + System.out.println(p.process(s)); + } + public static void main(String[] args) { + String s = + "We are such stuff as dreams are made on"; + apply(new Upcase(), s); + apply(new Downcase(), s); + apply(new Splitter(), s); + } +} +/* Output: +Using Processor Upcase +WE ARE SUCH STUFF AS DREAMS ARE MADE ON +Using Processor Downcase +we are such stuff as dreams are made on +Using Processor Splitter +[We, are, such, stuff, as, dreams, are, made, on] +*/ diff --git a/code/interfaces/AttemptToUseBasic.java b/code/interfaces/AttemptToUseBasic.java new file mode 100644 index 00000000..0d265527 --- /dev/null +++ b/code/interfaces/AttemptToUseBasic.java @@ -0,0 +1,10 @@ +// interfaces/AttemptToUseBasic.java +// (c)2020 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. +// {WillNotCompile} + +public class AttemptToUseBasic { + Basic b = new Basic(); + // error: Basic is abstract; cannot be instantiated +} diff --git a/code/interfaces/Basic.java b/code/interfaces/Basic.java new file mode 100644 index 00000000..19c1c75b --- /dev/null +++ b/code/interfaces/Basic.java @@ -0,0 +1,8 @@ +// interfaces/Basic.java +// (c)2020 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. + +abstract class Basic { + abstract void unimplemented(); +} diff --git a/code/interfaces/Basic2.java b/code/interfaces/Basic2.java new file mode 100644 index 00000000..4c8f0c93 --- /dev/null +++ b/code/interfaces/Basic2.java @@ -0,0 +1,10 @@ +// interfaces/Basic2.java +// (c)2020 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. + +abstract class Basic2 extends Basic { + int f() { return 111; } + abstract void g(); + // unimplemented() still not implemented +} diff --git a/code/interfaces/Factories.java b/code/interfaces/Factories.java new file mode 100644 index 00000000..87e28251 --- /dev/null +++ b/code/interfaces/Factories.java @@ -0,0 +1,67 @@ +// interfaces/Factories.java +// (c)2020 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. + +interface Service { + void method1(); + void method2(); +} + +interface ServiceFactory { + Service getService(); +} + +class Service1 implements Service { + Service1() {} // Package access + public void method1() { + System.out.println("Service1 method1"); + } + public void method2() { + System.out.println("Service1 method2"); + } +} + +class Service1Factory implements ServiceFactory { + @Override + public Service getService() { + return new Service1(); + } +} + +class Service2 implements Service { + Service2() {} // Package access + public void method1() { + System.out.println("Service2 method1"); + } + public void method2() { + System.out.println("Service2 method2"); + } +} + +class Service2Factory implements ServiceFactory { + @Override + public Service getService() { + return new Service2(); + } +} + +public class Factories { + public static void + serviceConsumer(ServiceFactory fact) { + Service s = fact.getService(); + s.method1(); + s.method2(); + } + public static void main(String[] args) { + serviceConsumer(new Service1Factory()); + // Services are completely interchangeable: + serviceConsumer(new Service2Factory()); + } +} +/* Output: +Service1 method1 +Service1 method2 +Service2 method1 +Service2 method2 +*/ diff --git a/code/interfaces/Games.java b/code/interfaces/Games.java new file mode 100644 index 00000000..867efe0c --- /dev/null +++ b/code/interfaces/Games.java @@ -0,0 +1,59 @@ +// interfaces/Games.java +// (c)2020 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. +// A Game framework using Factory Methods + +interface Game { boolean move(); } +interface GameFactory { Game getGame(); } + +class Checkers implements Game { + private int moves = 0; + private static final int MOVES = 3; + @Override + public boolean move() { + System.out.println("Checkers move " + moves); + return ++moves != MOVES; + } +} + +class CheckersFactory implements GameFactory { + @Override + public Game getGame() { return new Checkers(); } +} + +class Chess implements Game { + private int moves = 0; + private static final int MOVES = 4; + @Override + public boolean move() { + System.out.println("Chess move " + moves); + return ++moves != MOVES; + } +} + +class ChessFactory implements GameFactory { + @Override + public Game getGame() { return new Chess(); } +} + +public class Games { + public static void playGame(GameFactory factory) { + Game s = factory.getGame(); + while(s.move()) + ; + } + public static void main(String[] args) { + playGame(new CheckersFactory()); + playGame(new ChessFactory()); + } +} +/* Output: +Checkers move 0 +Checkers move 1 +Checkers move 2 +Chess move 0 +Chess move 1 +Chess move 2 +Chess move 3 +*/ diff --git a/code/interfaces/HorrorShow.java b/code/interfaces/HorrorShow.java new file mode 100644 index 00000000..b1c687da --- /dev/null +++ b/code/interfaces/HorrorShow.java @@ -0,0 +1,57 @@ +// interfaces/HorrorShow.java +// (c)2020 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. +// Extending an interface with inheritance + +interface Monster { + void menace(); +} + +interface DangerousMonster extends Monster { + void destroy(); +} + +interface Lethal { + void kill(); +} + +class DragonZilla implements DangerousMonster { + @Override + public void menace() {} + @Override + public void destroy() {} +} + +interface Vampire extends DangerousMonster, Lethal { + void drinkBlood(); +} + +class VeryBadVampire implements Vampire { + @Override + public void menace() {} + @Override + public void destroy() {} + @Override + public void kill() {} + @Override + public void drinkBlood() {} +} + +public class HorrorShow { + static void u(Monster b) { b.menace(); } + static void v(DangerousMonster d) { + d.menace(); + d.destroy(); + } + static void w(Lethal l) { l.kill(); } + public static void main(String[] args) { + DangerousMonster barney = new DragonZilla(); + u(barney); + v(barney); + Vampire vlad = new VeryBadVampire(); + u(vlad); + v(vlad); + w(vlad); + } +} diff --git a/code/interfaces/Implementation2.java b/code/interfaces/Implementation2.java new file mode 100644 index 00000000..61c6efa0 --- /dev/null +++ b/code/interfaces/Implementation2.java @@ -0,0 +1,26 @@ +// interfaces/Implementation2.java +// (c)2020 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. + +public class Implementation2 +implements InterfaceWithDefault { + public void firstMethod() { + System.out.println("firstMethod"); + } + public void secondMethod() { + System.out.println("secondMethod"); + } + public static void main(String[] args) { + InterfaceWithDefault i = + new Implementation2(); + i.firstMethod(); + i.secondMethod(); + i.newMethod(); + } +} +/* Output: +firstMethod +secondMethod +newMethod +*/ diff --git a/code/interfaces/ImplementingAnInterface.java b/code/interfaces/ImplementingAnInterface.java new file mode 100644 index 00000000..6a13ebb6 --- /dev/null +++ b/code/interfaces/ImplementingAnInterface.java @@ -0,0 +1,14 @@ +// interfaces/ImplementingAnInterface.java +// (c)2020 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. + +interface Concept { // Package access + void idea1(); + void idea2(); +} + +class Implementation implements Concept { + public void idea1() { System.out.println("idea1"); } + public void idea2() { System.out.println("idea2"); } +} diff --git a/code/interfaces/Instantiable.java b/code/interfaces/Instantiable.java new file mode 100644 index 00000000..427b6ca3 --- /dev/null +++ b/code/interfaces/Instantiable.java @@ -0,0 +1,19 @@ +// interfaces/Instantiable.java +// (c)2020 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. + +abstract class Uninstantiable { + abstract void f(); + abstract int g(); +} + +public class Instantiable extends Uninstantiable { + @Override + void f() { System.out.println("f()"); } + @Override + int g() { return 22; } + public static void main(String[] args) { + Uninstantiable ui = new Instantiable(); + } +} diff --git a/code/interfaces/InterfaceCollision.java b/code/interfaces/InterfaceCollision.java new file mode 100644 index 00000000..0f7de1ac --- /dev/null +++ b/code/interfaces/InterfaceCollision.java @@ -0,0 +1,31 @@ +// interfaces/InterfaceCollision.java +// (c)2020 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. + +interface I1 { void f(); } +interface I2 { int f(int i); } +interface I3 { int f(); } +class C { public int f() { return 1; } } + +class C2 implements I1, I2 { + @Override + public void f() {} + @Override + public int f(int i) { return 1; } // overloaded +} + +class C3 extends C implements I2 { + @Override + public int f(int i) { return 1; } // overloaded +} + +class C4 extends C implements I3 { + // Identical, no problem: + @Override + public int f() { return 1; } +} + +// Methods differ only by return type: +//- class C5 extends C implements I1 {} +//- interface I4 extends I1, I3 {} diff --git a/code/interfaces/InterfaceWithDefault.java b/code/interfaces/InterfaceWithDefault.java new file mode 100644 index 00000000..a87f02db --- /dev/null +++ b/code/interfaces/InterfaceWithDefault.java @@ -0,0 +1,12 @@ +// interfaces/InterfaceWithDefault.java +// (c)2020 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. + +interface InterfaceWithDefault { + void firstMethod(); + void secondMethod(); + default void newMethod() { + System.out.println("newMethod"); + } +} diff --git a/code/interfaces/Jim.java b/code/interfaces/Jim.java new file mode 100644 index 00000000..515db6e5 --- /dev/null +++ b/code/interfaces/Jim.java @@ -0,0 +1,28 @@ +// interfaces/Jim.java +// (c)2020 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. +import java.util.*; + +interface Jim1 { + default void jim() { + System.out.println("Jim1::jim"); + } +} + +interface Jim2 { + default void jim() { + System.out.println("Jim2::jim"); + } +} + +public class Jim implements Jim1, Jim2 { + @Override + public void jim() { Jim2.super.jim(); } + public static void main(String[] args) { + new Jim().jim(); + } +} +/* Output: +Jim2::jim +*/ diff --git a/code/interfaces/MICollision.java b/code/interfaces/MICollision.java new file mode 100644 index 00000000..c96e5696 --- /dev/null +++ b/code/interfaces/MICollision.java @@ -0,0 +1,60 @@ +// interfaces/MICollision.java +// (c)2020 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. +import java.util.*; + +interface Bob1 { + default void bob() { + System.out.println("Bob1::bob"); + } +} + +interface Bob2 { + default void bob() { + System.out.println("Bob2::bob"); + } +} + +// class Bob implements Bob1, Bob2 {} +/* Produces: +error: class Bob inherits unrelated defaults +for bob() from types Bob1 and Bob2 +class Bob implements Bob1, Bob2 {} +^ +1 error +*/ + +interface Sam1 { + default void sam() { + System.out.println("Sam1::sam"); + } +} + +interface Sam2 { + default void sam(int i) { + System.out.println(i * 2); + } +} + +// This works because the argument lists are distinct: +class Sam implements Sam1, Sam2 {} + +interface Max1 { + default void max() { + System.out.println("Max1::max"); + } +} + +interface Max2 { + default int max() { return 47; } +} + +// class Max implements Max1, Max2 {} +/* Produces: +error: types Max2 and Max1 are incompatible; +both define max(), but with unrelated return types +class Max implements Max1, Max2 {} +^ +1 error +*/ diff --git a/code/interfaces/Machine.java b/code/interfaces/Machine.java new file mode 100644 index 00000000..2b1144ae --- /dev/null +++ b/code/interfaces/Machine.java @@ -0,0 +1,36 @@ +// interfaces/Machine.java +// (c)2020 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. +import java.util.*; +import onjava.Operations; + +class Bing implements Operations { + public void execute() { + Operations.show("Bing"); + } +} + +class Crack implements Operations { + public void execute() { + Operations.show("Crack"); + } +} + +class Twist implements Operations { + public void execute() { + Operations.show("Twist"); + } +} + +public class Machine { + public static void main(String[] args) { + Operations.runOps( + new Bing(), new Crack(), new Twist()); + } +} +/* Output: +Bing +Crack +Twist +*/ diff --git a/code/interfaces/Months.java b/code/interfaces/Months.java new file mode 100644 index 00000000..27317dd5 --- /dev/null +++ b/code/interfaces/Months.java @@ -0,0 +1,13 @@ +// interfaces/Months.java +// (c)2020 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. +// Using interfaces to create groups of constants + +public interface Months { + int + JANUARY = 1, FEBRUARY = 2, MARCH = 3, + APRIL = 4, MAY = 5, JUNE = 6, JULY = 7, + AUGUST = 8, SEPTEMBER = 9, OCTOBER = 10, + NOVEMBER = 11, DECEMBER = 12; +} diff --git a/code/interfaces/MultipleInheritance.java b/code/interfaces/MultipleInheritance.java new file mode 100644 index 00000000..6ce9c91e --- /dev/null +++ b/code/interfaces/MultipleInheritance.java @@ -0,0 +1,35 @@ +// interfaces/MultipleInheritance.java +// (c)2020 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. +import java.util.*; + +interface One { + default void first() { System.out.println("first"); } +} + +interface Two { + default void second() { + System.out.println("second"); + } +} + +interface Three { + default void third() { System.out.println("third"); } +} + +class MI implements One, Two, Three {} + +public class MultipleInheritance { + public static void main(String[] args) { + MI mi = new MI(); + mi.first(); + mi.second(); + mi.third(); + } +} +/* Output: +first +second +third +*/ diff --git a/code/interfaces/PureInterface.java b/code/interfaces/PureInterface.java new file mode 100644 index 00000000..37bf9f0b --- /dev/null +++ b/code/interfaces/PureInterface.java @@ -0,0 +1,11 @@ +// interfaces/PureInterface.java +// (c)2020 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. +// Interface only looked like this before Java 8 + +public interface PureInterface { + int m1(); + void m2(); + double m3(); +} diff --git a/code/interfaces/RandVals.java b/code/interfaces/RandVals.java new file mode 100644 index 00000000..0221c851 --- /dev/null +++ b/code/interfaces/RandVals.java @@ -0,0 +1,15 @@ +// interfaces/RandVals.java +// (c)2020 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. +// Initializing interface fields with +// non-constant initializers +import java.util.*; + +public interface RandVals { + Random RAND = new Random(47); + int RANDOM_INT = RAND.nextInt(10); + long RANDOM_LONG = RAND.nextLong() * 10; + float RANDOM_FLOAT = RAND.nextLong() * 10; + double RANDOM_DOUBLE = RAND.nextDouble() * 10; +} diff --git a/code/interfaces/RandomDoubles.java b/code/interfaces/RandomDoubles.java new file mode 100644 index 00000000..99154d95 --- /dev/null +++ b/code/interfaces/RandomDoubles.java @@ -0,0 +1,21 @@ +// interfaces/RandomDoubles.java +// (c)2020 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. +import java.util.*; + +public interface RandomDoubles { + Random RAND = new Random(47); + default double next() { return RAND.nextDouble(); } + static void main(String[] args) { + RandomDoubles rd = new RandomDoubles() {}; + for(int i = 0; i < 7; i ++) + System.out.print(rd.next() + " "); + } +} +/* Output: +0.7271157860730044 0.5309454508634242 +0.16020656493302599 0.18847866977771732 +0.5166020801268457 0.2678662084200585 +0.2613610344283964 +*/ diff --git a/code/interfaces/RandomStrings.java b/code/interfaces/RandomStrings.java new file mode 100644 index 00000000..82f98230 --- /dev/null +++ b/code/interfaces/RandomStrings.java @@ -0,0 +1,50 @@ +// interfaces/RandomStrings.java +// (c)2020 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. +// Implementing an interface to conform to a method +import java.nio.*; +import java.util.*; + +public class RandomStrings implements Readable { + private static Random rand = new Random(47); + private static final char[] CAPITALS = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); + private static final char[] LOWERS = + "abcdefghijklmnopqrstuvwxyz".toCharArray(); + private static final char[] VOWELS = + "aeiou".toCharArray(); + private int count; + public RandomStrings(int count) { + this.count = count; + } + @Override + public int read(CharBuffer cb) { + if(count-- == 0) + return -1; // Indicates end of input + cb.append(CAPITALS[rand.nextInt(CAPITALS.length)]); + for(int i = 0; i < 4; i++) { + cb.append(VOWELS[rand.nextInt(VOWELS.length)]); + cb.append(LOWERS[rand.nextInt(LOWERS.length)]); + } + cb.append(" "); + return 10; // Number of characters appended + } + public static void main(String[] args) { + Scanner s = new Scanner(new RandomStrings(10)); + while(s.hasNext()) + System.out.println(s.next()); + } +} +/* Output: +Yazeruyac +Fowenucor +Goeazimom +Raeuuacio +Nuoadesiw +Hageaikux +Ruqicibui +Numasetih +Kuuuuozog +Waqizeyoy +*/ diff --git a/code/interfaces/TestRandVals.java b/code/interfaces/TestRandVals.java new file mode 100644 index 00000000..df3490b2 --- /dev/null +++ b/code/interfaces/TestRandVals.java @@ -0,0 +1,19 @@ +// interfaces/TestRandVals.java +// (c)2020 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. + +public class TestRandVals { + public static void main(String[] args) { + System.out.println(RandVals.RANDOM_INT); + System.out.println(RandVals.RANDOM_LONG); + System.out.println(RandVals.RANDOM_FLOAT); + System.out.println(RandVals.RANDOM_DOUBLE); + } +} +/* Output: +8 +-32032247016559954 +-8.5939291E18 +5.779976127815049 +*/ diff --git a/code/interfaces/filters/BandPass.java b/code/interfaces/filters/BandPass.java new file mode 100644 index 00000000..7d09ed28 --- /dev/null +++ b/code/interfaces/filters/BandPass.java @@ -0,0 +1,17 @@ +// interfaces/filters/BandPass.java +// (c)2020 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 interfaces.filters; + +public class BandPass extends Filter { + double lowCutoff, highCutoff; + public BandPass(double lowCut, double highCut) { + lowCutoff = lowCut; + highCutoff = highCut; + } + @Override + public Waveform process(Waveform input) { + return input; + } +} diff --git a/code/interfaces/filters/Filter.java b/code/interfaces/filters/Filter.java new file mode 100644 index 00000000..72e29a9e --- /dev/null +++ b/code/interfaces/filters/Filter.java @@ -0,0 +1,14 @@ +// interfaces/filters/Filter.java +// (c)2020 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 interfaces.filters; + +public class Filter { + public String name() { + return getClass().getSimpleName(); + } + public Waveform process(Waveform input) { + return input; + } +} diff --git a/code/interfaces/filters/HighPass.java b/code/interfaces/filters/HighPass.java new file mode 100644 index 00000000..7bf047df --- /dev/null +++ b/code/interfaces/filters/HighPass.java @@ -0,0 +1,16 @@ +// interfaces/filters/HighPass.java +// (c)2020 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 interfaces.filters; + +public class HighPass extends Filter { + double cutoff; + public HighPass(double cutoff) { + this.cutoff = cutoff; + } + @Override + public Waveform process(Waveform input) { + return input; + } +} diff --git a/code/interfaces/filters/LowPass.java b/code/interfaces/filters/LowPass.java new file mode 100644 index 00000000..e9320a82 --- /dev/null +++ b/code/interfaces/filters/LowPass.java @@ -0,0 +1,16 @@ +// interfaces/filters/LowPass.java +// (c)2020 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 interfaces.filters; + +public class LowPass extends Filter { + double cutoff; + public LowPass(double cutoff) { + this.cutoff = cutoff; + } + @Override + public Waveform process(Waveform input) { + return input; // Dummy processing + } +} diff --git a/code/interfaces/filters/Waveform.java b/code/interfaces/filters/Waveform.java new file mode 100644 index 00000000..40644677 --- /dev/null +++ b/code/interfaces/filters/Waveform.java @@ -0,0 +1,14 @@ +// interfaces/filters/Waveform.java +// (c)2020 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 interfaces.filters; + +public class Waveform { + private static long counter; + private final long id = counter++; + @Override + public String toString() { + return "Waveform " + id; + } +} diff --git a/code/interfaces/interfaceprocessor/Applicator.java b/code/interfaces/interfaceprocessor/Applicator.java new file mode 100644 index 00000000..77d7a9a6 --- /dev/null +++ b/code/interfaces/interfaceprocessor/Applicator.java @@ -0,0 +1,12 @@ +// interfaces/interfaceprocessor/Applicator.java +// (c)2020 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 interfaces.interfaceprocessor; + +public class Applicator { + public static void apply(Processor p, Object s) { + System.out.println("Using Processor " + p.name()); + System.out.println(p.process(s)); + } +} diff --git a/code/interfaces/interfaceprocessor/FilterProcessor.java b/code/interfaces/interfaceprocessor/FilterProcessor.java new file mode 100644 index 00000000..33689ed4 --- /dev/null +++ b/code/interfaces/interfaceprocessor/FilterProcessor.java @@ -0,0 +1,40 @@ +// interfaces/interfaceprocessor/FilterProcessor.java +// (c)2020 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. +// {java interfaces.interfaceprocessor.FilterProcessor} +package interfaces.interfaceprocessor; +import interfaces.filters.*; + +class FilterAdapter implements Processor { + Filter filter; + FilterAdapter(Filter filter) { + this.filter = filter; + } + @Override + public String name() { return filter.name(); } + @Override + public Waveform process(Object input) { + return filter.process((Waveform)input); + } +} + +public class FilterProcessor { + public static void main(String[] args) { + Waveform w = new Waveform(); + Applicator.apply( + new FilterAdapter(new LowPass(1.0)), w); + Applicator.apply( + new FilterAdapter(new HighPass(2.0)), w); + Applicator.apply( + new FilterAdapter(new BandPass(3.0, 4.0)), w); + } +} +/* Output: +Using Processor LowPass +Waveform 0 +Using Processor HighPass +Waveform 0 +Using Processor BandPass +Waveform 0 +*/ diff --git a/code/interfaces/interfaceprocessor/Processor.java b/code/interfaces/interfaceprocessor/Processor.java new file mode 100644 index 00000000..6315da30 --- /dev/null +++ b/code/interfaces/interfaceprocessor/Processor.java @@ -0,0 +1,12 @@ +// interfaces/interfaceprocessor/Processor.java +// (c)2020 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 interfaces.interfaceprocessor; + +public interface Processor { + default String name() { + return getClass().getSimpleName(); + } + Object process(Object input); +} diff --git a/code/interfaces/interfaceprocessor/StringProcessor.java b/code/interfaces/interfaceprocessor/StringProcessor.java new file mode 100644 index 00000000..37cb4946 --- /dev/null +++ b/code/interfaces/interfaceprocessor/StringProcessor.java @@ -0,0 +1,50 @@ +// interfaces/interfaceprocessor/StringProcessor.java +// (c)2020 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. +// {java interfaces.interfaceprocessor.StringProcessor} +package interfaces.interfaceprocessor; +import java.util.*; + +interface StringProcessor extends Processor { + @Override + String process(Object input); // [1] + String S = // [2] + "If she weighs the same as a duck, " + + "she's made of wood"; + static void main(String[] args) { // [3] + Applicator.apply(new Upcase(), S); + Applicator.apply(new Downcase(), S); + Applicator.apply(new Splitter(), S); + } +} + +class Upcase implements StringProcessor { + @Override // Covariant return: + public String process(Object input) { + return ((String)input).toUpperCase(); + } +} + +class Downcase implements StringProcessor { + @Override + public String process(Object input) { + return ((String)input).toLowerCase(); + } +} + +class Splitter implements StringProcessor { + @Override + public String process(Object input) { + return Arrays.toString(((String)input).split(" ")); + } +} +/* Output: +Using Processor Upcase +IF SHE WEIGHS THE SAME AS A DUCK, SHE'S MADE OF WOOD +Using Processor Downcase +if she weighs the same as a duck, she's made of wood +Using Processor Splitter +[If, she, weighs, the, same, as, a, duck,, she's, made, +of, wood] +*/ diff --git a/code/interfaces/music4/Music4.java b/code/interfaces/music4/Music4.java new file mode 100644 index 00000000..71034149 --- /dev/null +++ b/code/interfaces/music4/Music4.java @@ -0,0 +1,105 @@ +// interfaces/music4/Music4.java +// (c)2020 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. +// Abstract classes and methods +// {java interfaces.music4.Music4} +package interfaces.music4; +import polymorphism.music.Note; + +abstract class Instrument { + private int i; // Storage allocated for each + public abstract void play(Note n); + public String what() { return "Instrument"; } + public abstract void adjust(); +} + +class Wind extends Instrument { + @Override + public void play(Note n) { + System.out.println("Wind.play() " + n); + } + @Override + public String what() { return "Wind"; } + @Override + public void adjust() { + System.out.println("Adjusting Wind"); + } +} + +class Percussion extends Instrument { + @Override + public void play(Note n) { + System.out.println("Percussion.play() " + n); + } + @Override + public String what() { return "Percussion"; } + @Override + public void adjust() { + System.out.println("Adjusting Percussion"); + } +} + +class Stringed extends Instrument { + @Override + public void play(Note n) { + System.out.println("Stringed.play() " + n); + } + @Override + public String what() { return "Stringed"; } + @Override + public void adjust() { + System.out.println("Adjusting Stringed"); + } +} + +class Brass extends Wind { + @Override + public void play(Note n) { + System.out.println("Brass.play() " + n); + } + @Override + public void adjust() { + System.out.println("Adjusting Brass"); + } +} + +class Woodwind extends Wind { + @Override + public void play(Note n) { + System.out.println("Woodwind.play() " + n); + } + @Override + public String what() { return "Woodwind"; } +} + +public class Music4 { + // Doesn't care about type, so new types + // added to the system still work right: + static void tune(Instrument i) { + // ... + i.play(Note.MIDDLE_C); + } + static void tuneAll(Instrument[] e) { + for(Instrument i : e) + tune(i); + } + public static void main(String[] args) { + // Upcasting during addition to the array: + Instrument[] orchestra = { + new Wind(), + new Percussion(), + new Stringed(), + new Brass(), + new Woodwind() + }; + tuneAll(orchestra); + } +} +/* Output: +Wind.play() MIDDLE_C +Percussion.play() MIDDLE_C +Stringed.play() MIDDLE_C +Brass.play() MIDDLE_C +Woodwind.play() MIDDLE_C +*/ diff --git a/code/interfaces/music5/Music5.java b/code/interfaces/music5/Music5.java new file mode 100644 index 00000000..2326bdbc --- /dev/null +++ b/code/interfaces/music5/Music5.java @@ -0,0 +1,74 @@ +// interfaces/music5/Music5.java +// (c)2020 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. +// {java interfaces.music5.Music5} +package interfaces.music5; +import polymorphism.music.Note; + +interface Instrument { + // Compile-time constant: + int VALUE = 5; // static & final + default void play(Note n) { // Automatically public + System.out.println(this + ".play() " + n); + } + default void adjust() { + System.out.println("Adjusting " + this); + } +} + +class Wind implements Instrument { + @Override + public String toString() { return "Wind"; } +} + +class Percussion implements Instrument { + @Override + public String toString() { return "Percussion"; } +} + +class Stringed implements Instrument { + @Override + public String toString() { return "Stringed"; } +} + +class Brass extends Wind { + @Override + public String toString() { return "Brass"; } +} + +class Woodwind extends Wind { + @Override + public String toString() { return "Woodwind"; } +} + +public class Music5 { + // Doesn't care about type, so new types + // added to the system still work right: + static void tune(Instrument i) { + // ... + i.play(Note.MIDDLE_C); + } + static void tuneAll(Instrument[] e) { + for(Instrument i : e) + tune(i); + } + public static void main(String[] args) { + // Upcasting during addition to the array: + Instrument[] orchestra = { + new Wind(), + new Percussion(), + new Stringed(), + new Brass(), + new Woodwind() + }; + tuneAll(orchestra); + } +} +/* Output: +Wind.play() MIDDLE_C +Percussion.play() MIDDLE_C +Stringed.play() MIDDLE_C +Brass.play() MIDDLE_C +Woodwind.play() MIDDLE_C +*/ diff --git a/code/interfaces/nesting/NestingInterfaces.java b/code/interfaces/nesting/NestingInterfaces.java new file mode 100644 index 00000000..99b466bb --- /dev/null +++ b/code/interfaces/nesting/NestingInterfaces.java @@ -0,0 +1,105 @@ +// interfaces/nesting/NestingInterfaces.java +// (c)2020 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. +// {java interfaces.nesting.NestingInterfaces} +package interfaces.nesting; + +class A { + interface B { + void f(); + } + public class BImp implements B { + @Override + public void f() {} + } + private class BImp2 implements B { + @Override + public void f() {} + } + public interface C { + void f(); + } + class CImp implements C { + @Override + public void f() {} + } + private class CImp2 implements C { + @Override + public void f() {} + } + private interface D { + void f(); + } + private class DImp implements D { + @Override + public void f() {} + } + public class DImp2 implements D { + @Override + public void f() {} + } + public D getD() { return new DImp2(); } + private D dRef; + public void receiveD(D d) { + dRef = d; + dRef.f(); + } +} + +interface E { + interface G { + void f(); + } + // Redundant "public": + public interface H { + void f(); + } + void g(); + // Cannot be private within an interface: + //- private interface I {} +} + +public class NestingInterfaces { + public class BImp implements A.B { + @Override + public void f() {} + } + class CImp implements A.C { + @Override + public void f() {} + } + // Cannot implement a private interface except + // within that interface's defining class: + //- class DImp implements A.D { + //- public void f() {} + //- } + class EImp implements E { + @Override + public void g() {} + } + class EGImp implements E.G { + @Override + public void f() {} + } + class EImp2 implements E { + @Override + public void g() {} + class EG implements E.G { + @Override + public void f() {} + } + } + public static void main(String[] args) { + A a = new A(); + // Can't access A.D: + //- A.D ad = a.getD(); + // Doesn't return anything but A.D: + //- A.DImp2 di2 = a.getD(); + // Cannot access a member of the interface: + //- a.getD().f(); + // Only another A can do anything with getD(): + A a2 = new A(); + a2.receiveD(a.getD()); + } +} diff --git a/code/iostreams/BasicFileOutput.java b/code/iostreams/BasicFileOutput.java new file mode 100644 index 00000000..1da5c6fd --- /dev/null +++ b/code/iostreams/BasicFileOutput.java @@ -0,0 +1,26 @@ +// iostreams/BasicFileOutput.java +// (c)2020 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. +// {VisuallyInspectOutput} +import java.io.*; + +public class BasicFileOutput { + static String file = "BasicFileOutput.dat"; + public static void main(String[] args) { + try( + BufferedReader in = new BufferedReader( + new StringReader( + BufferedInputFile.read( + "BasicFileOutput.java"))); + PrintWriter out = new PrintWriter( + new BufferedWriter(new FileWriter(file))) + ) { + in.lines().forEach(out::println); + } catch(IOException e) { + throw new RuntimeException(e); + } + // Show the stored file: + System.out.println(BufferedInputFile.read(file)); + } +} diff --git a/code/iostreams/BufferedInputFile.java b/code/iostreams/BufferedInputFile.java new file mode 100644 index 00000000..bfe6396f --- /dev/null +++ b/code/iostreams/BufferedInputFile.java @@ -0,0 +1,23 @@ +// iostreams/BufferedInputFile.java +// (c)2020 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. +// {VisuallyInspectOutput} +import java.io.*; +import java.util.stream.*; + +public class BufferedInputFile { + public static String read(String filename) { + try(BufferedReader in = new BufferedReader( + new FileReader(filename))) { + return in.lines() + .collect(Collectors.joining("\n")); + } catch(IOException e) { + throw new RuntimeException(e); + } + } + public static void main(String[] args) { + System.out.print( + read("BufferedInputFile.java")); + } +} diff --git a/code/iostreams/FileOutputShortcut.java b/code/iostreams/FileOutputShortcut.java new file mode 100644 index 00000000..5a160ec0 --- /dev/null +++ b/code/iostreams/FileOutputShortcut.java @@ -0,0 +1,24 @@ +// iostreams/FileOutputShortcut.java +// (c)2020 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. +// {VisuallyInspectOutput} +import java.io.*; + +public class FileOutputShortcut { + static String file = "FileOutputShortcut.dat"; + public static void main(String[] args) { + try( + BufferedReader in = new BufferedReader( + new StringReader(BufferedInputFile.read( + "FileOutputShortcut.java"))); + // Here's the shortcut: + PrintWriter out = new PrintWriter(file) + ) { + in.lines().forEach(out::println); + } catch(IOException e) { + throw new RuntimeException(e); + } + System.out.println(BufferedInputFile.read(file)); + } +} diff --git a/code/iostreams/FormattedMemoryInput.java b/code/iostreams/FormattedMemoryInput.java new file mode 100644 index 00000000..055dd882 --- /dev/null +++ b/code/iostreams/FormattedMemoryInput.java @@ -0,0 +1,25 @@ +// iostreams/FormattedMemoryInput.java +// (c)2020 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. +// {VisuallyInspectOutput} +import java.io.*; + +public class FormattedMemoryInput { + public static void main(String[] args) { + try( + DataInputStream in = new DataInputStream( + new ByteArrayInputStream( + BufferedInputFile.read( + "FormattedMemoryInput.java") + .getBytes())) + ) { + while(true) + System.out.write((char)in.readByte()); + } catch(EOFException e) { + System.out.println("\nEnd of stream"); + } catch(IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/code/iostreams/MemoryInput.java b/code/iostreams/MemoryInput.java new file mode 100644 index 00000000..1326965c --- /dev/null +++ b/code/iostreams/MemoryInput.java @@ -0,0 +1,17 @@ +// iostreams/MemoryInput.java +// (c)2020 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. +// {VisuallyInspectOutput} +import java.io.*; + +public class MemoryInput { + public static void + main(String[] args) throws IOException { + StringReader in = new StringReader( + BufferedInputFile.read("MemoryInput.java")); + int c; + while((c = in.read()) != -1) + System.out.print((char)c); + } +} diff --git a/code/iostreams/StoringAndRecoveringData.java b/code/iostreams/StoringAndRecoveringData.java new file mode 100644 index 00000000..761f022e --- /dev/null +++ b/code/iostreams/StoringAndRecoveringData.java @@ -0,0 +1,42 @@ +// iostreams/StoringAndRecoveringData.java +// (c)2020 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. +import java.io.*; + +public class StoringAndRecoveringData { + public static void main(String[] args) { + try( + DataOutputStream out = new DataOutputStream( + new BufferedOutputStream( + new FileOutputStream("Data.txt"))) + ) { + out.writeDouble(3.14159); + out.writeUTF("That was pi"); + out.writeDouble(1.41413); + out.writeUTF("Square root of 2"); + } catch(IOException e) { + throw new RuntimeException(e); + } + try( + DataInputStream in = new DataInputStream( + new BufferedInputStream( + new FileInputStream("Data.txt"))) + ) { + System.out.println(in.readDouble()); + // Only readUTF() will recover the + // Java-UTF String properly: + System.out.println(in.readUTF()); + System.out.println(in.readDouble()); + System.out.println(in.readUTF()); + } catch(IOException e) { + throw new RuntimeException(e); + } + } +} +/* Output: +3.14159 +That was pi +1.41413 +Square root of 2 +*/ diff --git a/code/iostreams/TestEOF.java b/code/iostreams/TestEOF.java new file mode 100644 index 00000000..956cb1a0 --- /dev/null +++ b/code/iostreams/TestEOF.java @@ -0,0 +1,22 @@ +// iostreams/TestEOF.java +// (c)2020 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. +// Testing for end of file +// {VisuallyInspectOutput} +import java.io.*; + +public class TestEOF { + public static void main(String[] args) { + try( + DataInputStream in = new DataInputStream( + new BufferedInputStream( + new FileInputStream("TestEOF.java"))) + ) { + while(in.available() != 0) + System.out.write(in.readByte()); + } catch(IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/code/iostreams/UsingRandomAccessFile.java b/code/iostreams/UsingRandomAccessFile.java new file mode 100644 index 00000000..dde6d1ee --- /dev/null +++ b/code/iostreams/UsingRandomAccessFile.java @@ -0,0 +1,65 @@ +// iostreams/UsingRandomAccessFile.java +// (c)2020 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. +import java.io.*; + +public class UsingRandomAccessFile { + static String file = "rtest.dat"; + public static void display() { + try( + RandomAccessFile rf = + new RandomAccessFile(file, "r") + ) { + for(int i = 0; i < 7; i++) + System.out.println( + "Value " + i + ": " + rf.readDouble()); + System.out.println(rf.readUTF()); + } catch(IOException e) { + throw new RuntimeException(e); + } + } + public static void main(String[] args) { + try( + RandomAccessFile rf = + new RandomAccessFile(file, "rw") + ) { + for(int i = 0; i < 7; i++) + rf.writeDouble(i*1.414); + rf.writeUTF("The end of the file"); + rf.close(); + display(); + } catch(IOException e) { + throw new RuntimeException(e); + } + try( + RandomAccessFile rf = + new RandomAccessFile(file, "rw") + ) { + rf.seek(5*8); + rf.writeDouble(47.0001); + rf.close(); + display(); + } catch(IOException e) { + throw new RuntimeException(e); + } + } +} +/* Output: +Value 0: 0.0 +Value 1: 1.414 +Value 2: 2.828 +Value 3: 4.242 +Value 4: 5.656 +Value 5: 7.069999999999999 +Value 6: 8.484 +The end of the file +Value 0: 0.0 +Value 1: 1.414 +Value 2: 2.828 +Value 3: 4.242 +Value 4: 5.656 +Value 5: 47.0001 +Value 6: 8.484 +The end of the file +*/ diff --git a/code/javadoc/Documentation1.java b/code/javadoc/Documentation1.java new file mode 100644 index 00000000..7838fbd9 --- /dev/null +++ b/code/javadoc/Documentation1.java @@ -0,0 +1,11 @@ +// javadoc/Documentation1.java +// (c)2020 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. +/** A class comment */ +public class Documentation1 { + /** A field comment */ + public int i; + /** A method comment */ + public void f() {} +} diff --git a/code/javadoc/Documentation2.java b/code/javadoc/Documentation2.java new file mode 100644 index 00000000..237755f4 --- /dev/null +++ b/code/javadoc/Documentation2.java @@ -0,0 +1,9 @@ +// javadoc/Documentation2.java +// (c)2020 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. +/**

+ * System.out.println(new Date());
+ * 
+ */ +public class Documentation2 {} diff --git a/code/javadoc/Documentation3.java b/code/javadoc/Documentation3.java new file mode 100644 index 00000000..a3063c3d --- /dev/null +++ b/code/javadoc/Documentation3.java @@ -0,0 +1,12 @@ +// javadoc/Documentation3.java +// (c)2020 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. +/** You can even insert a list: + *
    + *
  1. Item one + *
  2. Item two + *
  3. Item three + *
+ */ +public class Documentation3 {} diff --git a/code/javadoc/HelloDateDoc.java b/code/javadoc/HelloDateDoc.java new file mode 100644 index 00000000..54b505a4 --- /dev/null +++ b/code/javadoc/HelloDateDoc.java @@ -0,0 +1,26 @@ +// javadoc/HelloDateDoc.java +// (c)2020 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. +import java.util.*; + +/** The first On Java 8 example program. + * Displays a String and today's date. + * @author Bruce Eckel + * @author www.MindviewInc.com + * @version 5.0 + */ +public class HelloDateDoc { + /** Entry point to class & application. + * @param args array of String arguments + * @throws exceptions No exceptions thrown + */ + public static void main(String[] args) { + System.out.println("Hello, it's: "); + System.out.println(new Date()); + } +} +/* Output: +Hello, it's: +Tue May 09 06:07:27 MDT 2017 +*/ diff --git a/code/lowlevel/AtomicEvenProducer.java b/code/lowlevel/AtomicEvenProducer.java new file mode 100644 index 00000000..8c45b61c --- /dev/null +++ b/code/lowlevel/AtomicEvenProducer.java @@ -0,0 +1,21 @@ +// lowlevel/AtomicEvenProducer.java +// (c)2020 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. +// Atomic classes: occasionally useful in regular code +import java.util.concurrent.atomic.*; + +public class AtomicEvenProducer extends IntGenerator { + private AtomicInteger currentEvenValue = + new AtomicInteger(0); + @Override + public int next() { + return currentEvenValue.addAndGet(2); + } + public static void main(String[] args) { + EvenChecker.test(new AtomicEvenProducer()); + } +} +/* Output: +No odd numbers discovered +*/ diff --git a/code/lowlevel/AtomicIntegerTest.java b/code/lowlevel/AtomicIntegerTest.java new file mode 100644 index 00000000..09db1ca8 --- /dev/null +++ b/code/lowlevel/AtomicIntegerTest.java @@ -0,0 +1,20 @@ +// lowlevel/AtomicIntegerTest.java +// (c)2020 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. +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; +import java.util.*; +import onjava.*; + +public class AtomicIntegerTest extends IntTestable { + private AtomicInteger i = new AtomicInteger(0); + public int getAsInt() { return i.get(); } + public void evenIncrement() { i.addAndGet(2); } + public static void main(String[] args) { + Atomicity.test(new AtomicIntegerTest()); + } +} +/* Output: +No failures found +*/ diff --git a/code/lowlevel/AtomicSerialNumbers.java b/code/lowlevel/AtomicSerialNumbers.java new file mode 100644 index 00000000..2e30e9c4 --- /dev/null +++ b/code/lowlevel/AtomicSerialNumbers.java @@ -0,0 +1,21 @@ +// lowlevel/AtomicSerialNumbers.java +// (c)2020 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. +import java.util.concurrent.atomic.*; + +public class +AtomicSerialNumbers extends SerialNumbers { + private AtomicInteger serialNumber = + new AtomicInteger(); + public int nextSerialNumber() { + return serialNumber.getAndIncrement(); + } + public static void main(String[] args) { + SerialNumberChecker.test( + new AtomicSerialNumbers()); + } +} +/* Output: +No duplicates detected +*/ diff --git a/code/lowlevel/Atomicity.java b/code/lowlevel/Atomicity.java new file mode 100644 index 00000000..632631bf --- /dev/null +++ b/code/lowlevel/Atomicity.java @@ -0,0 +1,20 @@ +// lowlevel/Atomicity.java +// (c)2020 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. +import java.util.concurrent.*; +import onjava.TimedAbort; + +public class Atomicity { + public static void test(IntTestable it) { + new TimedAbort(4, "No failures found"); + CompletableFuture.runAsync(it); + while(true) { + int val = it.getAsInt(); + if(val % 2 != 0) { + System.out.println("failed with: " + val); + System.exit(0); + } + } + } +} diff --git a/code/lowlevel/AttemptLocking.java b/code/lowlevel/AttemptLocking.java new file mode 100644 index 00000000..9dbe2b28 --- /dev/null +++ b/code/lowlevel/AttemptLocking.java @@ -0,0 +1,57 @@ +// lowlevel/AttemptLocking.java +// (c)2020 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. +// Locks in the concurrent library allow you +// to give up on trying to acquire a lock +import java.util.concurrent.*; +import java.util.concurrent.locks.*; +import onjava.Nap; + +public class AttemptLocking { + private ReentrantLock lock = new ReentrantLock(); + public void untimed() { + boolean captured = lock.tryLock(); + try { + System.out.println("tryLock(): " + captured); + } finally { + if(captured) + lock.unlock(); + } + } + public void timed() { + boolean captured = false; + try { + captured = lock.tryLock(2, TimeUnit.SECONDS); + } catch(InterruptedException e) { + throw new RuntimeException(e); + } + try { + System.out.println( + "tryLock(2, TimeUnit.SECONDS): " + captured); + } finally { + if(captured) + lock.unlock(); + } + } + public static void main(String[] args) { + final AttemptLocking al = new AttemptLocking(); + al.untimed(); // True -- lock is available + al.timed(); // True -- lock is available + // Now create a second task to grab the lock: + CompletableFuture.runAsync( () -> { + al.lock.lock(); + System.out.println("acquired"); + }); + new Nap(0.1); // Give the second task a chance + al.untimed(); // False -- lock grabbed by task + al.timed(); // False -- lock grabbed by task + } +} +/* Output: +tryLock(): true +tryLock(2, TimeUnit.SECONDS): true +acquired +tryLock(): false +tryLock(2, TimeUnit.SECONDS): false +*/ diff --git a/code/lowlevel/CaptureUncaughtException.java b/code/lowlevel/CaptureUncaughtException.java new file mode 100644 index 00000000..33261667 --- /dev/null +++ b/code/lowlevel/CaptureUncaughtException.java @@ -0,0 +1,56 @@ +// lowlevel/CaptureUncaughtException.java +// (c)2020 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. +import java.util.concurrent.*; + +class ExceptionThread2 implements Runnable { + @Override + public void run() { + Thread t = Thread.currentThread(); + System.out.println("run() by " + t.getName()); + System.out.println( + "eh = " + t.getUncaughtExceptionHandler()); + throw new RuntimeException(); + } +} + +class MyUncaughtExceptionHandler implements +Thread.UncaughtExceptionHandler { + @Override + public void uncaughtException(Thread t, Throwable e) { + System.out.println("caught " + e); + } +} + +class HandlerThreadFactory implements ThreadFactory { + @Override + public Thread newThread(Runnable r) { + System.out.println(this + " creating new Thread"); + Thread t = new Thread(r); + System.out.println("created " + t); + t.setUncaughtExceptionHandler( + new MyUncaughtExceptionHandler()); + System.out.println( + "eh = " + t.getUncaughtExceptionHandler()); + return t; + } +} + +public class CaptureUncaughtException { + public static void main(String[] args) { + ExecutorService exec = + Executors.newCachedThreadPool( + new HandlerThreadFactory()); + exec.execute(new ExceptionThread2()); + exec.shutdown(); + } +} +/* Output: +HandlerThreadFactory@4e25154f creating new Thread +created Thread[Thread-0,5,main] +eh = MyUncaughtExceptionHandler@70dea4e +run() by Thread-0 +eh = MyUncaughtExceptionHandler@70dea4e +caught java.lang.RuntimeException +*/ diff --git a/code/lowlevel/CircularSet.java b/code/lowlevel/CircularSet.java new file mode 100644 index 00000000..225eaeca --- /dev/null +++ b/code/lowlevel/CircularSet.java @@ -0,0 +1,29 @@ +// lowlevel/CircularSet.java +// (c)2020 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. +// Reuses storage so we don't run out of memory +import java.util.*; + +public class CircularSet { + private int[] array; + private int size; + private int index = 0; + public CircularSet(int size) { + this.size = size; + array = new int[size]; + // Initialize to a value not produced + // by SerialNumbers: + Arrays.fill(array, -1); + } + public synchronized void add(int i) { + array[index] = i; + // Wrap index and write over old elements: + index = ++index % size; + } + public synchronized boolean contains(int val) { + for(int i = 0; i < size; i++) + if(array[i] == val) return true; + return false; + } +} diff --git a/code/lowlevel/DelayQueueDemo.java b/code/lowlevel/DelayQueueDemo.java new file mode 100644 index 00000000..c5575c68 --- /dev/null +++ b/code/lowlevel/DelayQueueDemo.java @@ -0,0 +1,99 @@ +// lowlevel/DelayQueueDemo.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import java.util.concurrent.*; +import static java.util.concurrent.TimeUnit.*; + +class DelayedTask implements Runnable, Delayed { + private static int counter = 0; + private final int id = counter++; + private final int delta; + private final long trigger; + protected static List sequence = + new ArrayList<>(); + DelayedTask(int delayInMilliseconds) { + delta = delayInMilliseconds; + trigger = System.nanoTime() + + NANOSECONDS.convert(delta, MILLISECONDS); + sequence.add(this); + } + @Override + public long getDelay(TimeUnit unit) { + return unit.convert( + trigger - System.nanoTime(), NANOSECONDS); + } + @Override + public int compareTo(Delayed arg) { + DelayedTask that = (DelayedTask)arg; + if(trigger < that.trigger) return -1; + if(trigger > that.trigger) return 1; + return 0; + } + @Override + public void run() { + System.out.print(this + " "); + } + @Override + public String toString() { + return + String.format("[%d] Task %d", delta, id); + } + public String summary() { + return String.format("(%d:%d)", id, delta); + } + public static class EndTask extends DelayedTask { + EndTask(int delay) { super(delay); } + @Override + public void run() { + sequence.forEach(dt -> + System.out.println(dt.summary())); + } + } +} + +public class DelayQueueDemo { + public static void + main(String[] args) throws Exception { + DelayQueue tasks = + Stream.concat( // Random delays: + new Random(47).ints(20, 0, 4000) + .mapToObj(DelayedTask::new), + // Add the summarizing task: + Stream.of(new DelayedTask.EndTask(4000))) + .collect(Collectors + .toCollection(DelayQueue::new)); + while(tasks.size() > 0) + tasks.take().run(); + } +} +/* Output: +[128] Task 12 [429] Task 6 [551] Task 13 [555] Task 2 +[693] Task 3 [809] Task 15 [961] Task 5 [1258] Task 1 +[1258] Task 20 [1520] Task 19 [1861] Task 4 [1998] Task +17 [2200] Task 8 [2207] Task 10 [2288] Task 11 [2522] +Task 9 [2589] Task 14 [2861] Task 18 [2868] Task 7 +[3278] Task 16 (0:4000) +(1:1258) +(2:555) +(3:693) +(4:1861) +(5:961) +(6:429) +(7:2868) +(8:2200) +(9:2522) +(10:2207) +(11:2288) +(12:128) +(13:551) +(14:2589) +(15:809) +(16:3278) +(17:1998) +(18:2861) +(19:1520) +(20:1258) +*/ diff --git a/code/lowlevel/EvenChecker.java b/code/lowlevel/EvenChecker.java new file mode 100644 index 00000000..5e27a39e --- /dev/null +++ b/code/lowlevel/EvenChecker.java @@ -0,0 +1,41 @@ +// lowlevel/EvenChecker.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import java.util.concurrent.*; +import onjava.TimedAbort; + +public class EvenChecker implements Runnable { + private IntGenerator generator; + private final int id; + public EvenChecker(IntGenerator generator, int id) { + this.generator = generator; + this.id = id; + } + @Override + public void run() { + while(!generator.isCanceled()) { + int val = generator.next(); + if(val % 2 != 0) { + System.out.println(val + " not even!"); + generator.cancel(); // Cancels all EvenCheckers + } + } + } + // Test any IntGenerator: + public static void test(IntGenerator gp, int count) { + List> checkers = + IntStream.range(0, count) + .mapToObj(i -> new EvenChecker(gp, i)) + .map(CompletableFuture::runAsync) + .collect(Collectors.toList()); + checkers.forEach(CompletableFuture::join); + } + // Default value for count: + public static void test(IntGenerator gp) { + new TimedAbort(4, "No odd numbers discovered"); + test(gp, 10); + } +} diff --git a/code/lowlevel/EvenProducer.java b/code/lowlevel/EvenProducer.java new file mode 100644 index 00000000..30157755 --- /dev/null +++ b/code/lowlevel/EvenProducer.java @@ -0,0 +1,26 @@ +// lowlevel/EvenProducer.java +// (c)2020 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. +// When threads collide +// {VisuallyInspectOutput} + +public class EvenProducer extends IntGenerator { + private int currentEvenValue = 0; + @Override + public int next() { + ++currentEvenValue; // [1] + ++currentEvenValue; + return currentEvenValue; + } + public static void main(String[] args) { + EvenChecker.test(new EvenProducer()); + } +} +/* Output: +419 not even! +425 not even! +423 not even! +421 not even! +417 not even! +*/ diff --git a/code/lowlevel/ExceptionThread.java b/code/lowlevel/ExceptionThread.java new file mode 100644 index 00000000..518b9f5f --- /dev/null +++ b/code/lowlevel/ExceptionThread.java @@ -0,0 +1,30 @@ +// lowlevel/ExceptionThread.java +// (c)2020 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. +// {ThrowsException} +import java.util.concurrent.*; + +public class ExceptionThread implements Runnable { + @Override + public void run() { + throw new RuntimeException(); + } + public static void main(String[] args) { + ExecutorService es = + Executors.newCachedThreadPool(); + es.execute(new ExceptionThread()); + es.shutdown(); + } +} +/* Output: +___[ Error Output ]___ +Exception in thread "pool-1-thread-1" +java.lang.RuntimeException + at ExceptionThread.run(ExceptionThread.java:8) + at java.util.concurrent.ThreadPoolExecutor.runW +orker(ThreadPoolExecutor.java:1142) + at java.util.concurrent.ThreadPoolExecutor$Work +er.run(ThreadPoolExecutor.java:617) + at java.lang.Thread.run(Thread.java:745) +*/ diff --git a/code/lowlevel/IntGenerator.java b/code/lowlevel/IntGenerator.java new file mode 100644 index 00000000..e1dd0f62 --- /dev/null +++ b/code/lowlevel/IntGenerator.java @@ -0,0 +1,15 @@ +// lowlevel/IntGenerator.java +// (c)2020 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. +import java.util.concurrent.atomic.AtomicBoolean; + +public abstract class IntGenerator { + private AtomicBoolean canceled = + new AtomicBoolean(); + public abstract int next(); + public void cancel() { canceled.set(true); } + public boolean isCanceled() { + return canceled.get(); + } +} diff --git a/code/lowlevel/IntTestable.java b/code/lowlevel/IntTestable.java new file mode 100644 index 00000000..1989ff4d --- /dev/null +++ b/code/lowlevel/IntTestable.java @@ -0,0 +1,15 @@ +// lowlevel/IntTestable.java +// (c)2020 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. +import java.util.function.*; + +public abstract class +IntTestable implements Runnable, IntSupplier { + abstract void evenIncrement(); + @Override + public void run() { + while(true) + evenIncrement(); + } +} diff --git a/code/lowlevel/MutexEvenProducer.java b/code/lowlevel/MutexEvenProducer.java new file mode 100644 index 00000000..ae82df82 --- /dev/null +++ b/code/lowlevel/MutexEvenProducer.java @@ -0,0 +1,30 @@ +// lowlevel/MutexEvenProducer.java +// (c)2020 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. +// Preventing thread collisions with mutexes +import java.util.concurrent.locks.*; +import onjava.Nap; + +public class MutexEvenProducer extends IntGenerator { + private int currentEvenValue = 0; + private Lock lock = new ReentrantLock(); + @Override + public int next() { + lock.lock(); + try { + ++currentEvenValue; + new Nap(0.01); // Cause failure faster + ++currentEvenValue; + return currentEvenValue; + } finally { + lock.unlock(); + } + } + public static void main(String[] args) { + EvenChecker.test(new MutexEvenProducer()); + } +} +/* +No odd numbers discovered +*/ diff --git a/code/lowlevel/NaiveExceptionHandling.java b/code/lowlevel/NaiveExceptionHandling.java new file mode 100644 index 00000000..3681337e --- /dev/null +++ b/code/lowlevel/NaiveExceptionHandling.java @@ -0,0 +1,32 @@ +// lowlevel/NaiveExceptionHandling.java +// (c)2020 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. +// {ThrowsException} +import java.util.concurrent.*; + +public class NaiveExceptionHandling { + public static void main(String[] args) { + ExecutorService es = + Executors.newCachedThreadPool(); + try { + es.execute(new ExceptionThread()); + } catch(RuntimeException ue) { + // This statement will NOT execute! + System.out.println("Exception was handled!"); + } finally { + es.shutdown(); + } + } +} +/* Output: +___[ Error Output ]___ +Exception in thread "pool-1-thread-1" +java.lang.RuntimeException + at ExceptionThread.run(ExceptionThread.java:8) + at java.util.concurrent.ThreadPoolExecutor.runW +orker(ThreadPoolExecutor.java:1142) + at java.util.concurrent.ThreadPoolExecutor$Work +er.run(ThreadPoolExecutor.java:617) + at java.lang.Thread.run(Thread.java:745) +*/ diff --git a/code/lowlevel/NotAtomic.java b/code/lowlevel/NotAtomic.java new file mode 100644 index 00000000..c6c6c321 --- /dev/null +++ b/code/lowlevel/NotAtomic.java @@ -0,0 +1,49 @@ +// lowlevel/NotAtomic.java +// (c)2020 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. +// javap -c NotAtomic +// {ExcludeFromGradle} +// {VisuallyInspectOutput} + +public class NotAtomic { + int i; + void f1() { i++; } + void f2() { i += 3; } +} +/* Output: +Compiled from "NotAtomic.java" +public class NotAtomic { + int i; + + public NotAtomic(); + Code: + 0: aload_0 + 1: invokespecial #1 // Method java/lang/Object."":()V + 4: return + + void f1(); + Code: + 0: aload_0 + 1: dup + 2: getfield #2 // Field +i:I + 5: iconst_1 + 6: iadd + 7: putfield #2 // Field +i:I + 10: return + + void f2(); + Code: + 0: aload_0 + 1: dup + 2: getfield #2 // Field +i:I + 5: iconst_3 + 6: iadd + 7: putfield #2 // Field +i:I + 10: return +} +*/ diff --git a/code/lowlevel/NumberOfProcessors.java b/code/lowlevel/NumberOfProcessors.java new file mode 100644 index 00000000..44abeb5d --- /dev/null +++ b/code/lowlevel/NumberOfProcessors.java @@ -0,0 +1,14 @@ +// lowlevel/NumberOfProcessors.java +// (c)2020 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. + +public class NumberOfProcessors { + public static void main(String[] args) { + System.out.println( + Runtime.getRuntime().availableProcessors()); + } +} +/* Output: +8 +*/ diff --git a/code/lowlevel/PriorityBlockingQueueDemo.java b/code/lowlevel/PriorityBlockingQueueDemo.java new file mode 100644 index 00000000..099a5349 --- /dev/null +++ b/code/lowlevel/PriorityBlockingQueueDemo.java @@ -0,0 +1,139 @@ +// lowlevel/PriorityBlockingQueueDemo.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; +import onjava.Nap; + +class Prioritized implements Comparable { + private static AtomicInteger counter = + new AtomicInteger(); + private final int id = counter.getAndIncrement(); + private final int priority; + private static List sequence = + new CopyOnWriteArrayList<>(); + Prioritized(int priority) { + this.priority = priority; + sequence.add(this); + } + @Override + public int compareTo(Prioritized arg) { + return priority < arg.priority ? 1 : + (priority > arg.priority ? -1 : 0); + } + @Override + public String toString() { + return String.format( + "[%d] Prioritized %d", priority, id); + } + public void displaySequence() { + int count = 0; + for(Prioritized pt : sequence) { + System.out.printf("(%d:%d)", pt.id, pt.priority); + if(++count % 5 == 0) + System.out.println(); + } + } + public static class EndSentinel extends Prioritized { + EndSentinel() { super(-1); } + } +} + +class Producer implements Runnable { + private static AtomicInteger seed = + new AtomicInteger(47); + private SplittableRandom rand = + new SplittableRandom(seed.getAndAdd(10)); + private Queue queue; + Producer(Queue q) { + queue = q; + } + @Override + public void run() { + rand.ints(10, 0, 20) + .mapToObj(Prioritized::new) + .peek(p -> new Nap(rand.nextDouble() / 10)) + .forEach(p -> queue.add(p)); + queue.add(new Prioritized.EndSentinel()); + } +} + +class Consumer implements Runnable { + private PriorityBlockingQueue q; + private SplittableRandom rand = + new SplittableRandom(47); + Consumer(PriorityBlockingQueue q) { + this.q = q; + } + @Override + public void run() { + while(true) { + try { + Prioritized pt = q.take(); + System.out.println(pt); + if(pt instanceof Prioritized.EndSentinel) { + pt.displaySequence(); + break; + } + new Nap(rand.nextDouble() / 10); + } catch(InterruptedException e) { + throw new RuntimeException(e); + } + } + } +} + +public class PriorityBlockingQueueDemo { + public static void main(String[] args) { + PriorityBlockingQueue queue = + new PriorityBlockingQueue<>(); + CompletableFuture.runAsync(new Producer(queue)); + CompletableFuture.runAsync(new Producer(queue)); + CompletableFuture.runAsync(new Producer(queue)); + CompletableFuture.runAsync(new Consumer(queue)) + .join(); + } +} +/* Output: +[15] Prioritized 2 +[17] Prioritized 1 +[17] Prioritized 5 +[16] Prioritized 6 +[14] Prioritized 9 +[12] Prioritized 0 +[11] Prioritized 4 +[11] Prioritized 12 +[13] Prioritized 13 +[12] Prioritized 16 +[14] Prioritized 18 +[15] Prioritized 23 +[18] Prioritized 26 +[16] Prioritized 29 +[12] Prioritized 17 +[11] Prioritized 30 +[11] Prioritized 24 +[10] Prioritized 15 +[10] Prioritized 22 +[8] Prioritized 25 +[8] Prioritized 11 +[8] Prioritized 10 +[6] Prioritized 31 +[3] Prioritized 7 +[2] Prioritized 20 +[1] Prioritized 3 +[0] Prioritized 19 +[0] Prioritized 8 +[0] Prioritized 14 +[0] Prioritized 21 +[-1] Prioritized 28 +(0:12)(2:15)(1:17)(3:1)(4:11) +(5:17)(6:16)(7:3)(8:0)(9:14) +(10:8)(11:8)(12:11)(13:13)(14:0) +(15:10)(16:12)(17:12)(18:14)(19:0) +(20:2)(21:0)(22:10)(23:15)(24:11) +(25:8)(26:18)(27:-1)(28:-1)(29:16) +(30:11)(31:6)(32:-1) +*/ diff --git a/code/lowlevel/ReOrdering.java b/code/lowlevel/ReOrdering.java new file mode 100644 index 00000000..8209ac40 --- /dev/null +++ b/code/lowlevel/ReOrdering.java @@ -0,0 +1,19 @@ +// lowlevel/ReOrdering.java +// (c)2020 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. + +public class ReOrdering implements Runnable { + int one, two, three, four, five, six; + volatile int volaTile; + @Override + public void run() { + one = 1; + two = 2; + three = 3; + volaTile = 92; + int x = four; + int y = five; + int z = six; + } +} diff --git a/code/lowlevel/SafeReturn.java b/code/lowlevel/SafeReturn.java new file mode 100644 index 00000000..751c96be --- /dev/null +++ b/code/lowlevel/SafeReturn.java @@ -0,0 +1,20 @@ +// lowlevel/SafeReturn.java +// (c)2020 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. +import java.util.function.*; +import java.util.concurrent.*; + +public class SafeReturn extends IntTestable { + private int i = 0; + public synchronized int getAsInt() { return i; } + public synchronized void evenIncrement() { + i++; i++; + } + public static void main(String[] args) { + Atomicity.test(new SafeReturn()); + } +} +/* Output: +No failures found +*/ diff --git a/code/lowlevel/SerialNumberChecker.java b/code/lowlevel/SerialNumberChecker.java new file mode 100644 index 00000000..9c2b92ad --- /dev/null +++ b/code/lowlevel/SerialNumberChecker.java @@ -0,0 +1,32 @@ +// lowlevel/SerialNumberChecker.java +// (c)2020 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. +// Test SerialNumbers implementations for thread-safety +import java.util.concurrent.*; +import onjava.Nap; + +public class SerialNumberChecker implements Runnable { + private CircularSet serials = new CircularSet(1000); + private SerialNumbers producer; + public SerialNumberChecker(SerialNumbers producer) { + this.producer = producer; + } + @Override + public void run() { + while(true) { + int serial = producer.nextSerialNumber(); + if(serials.contains(serial)) { + System.out.println("Duplicate: " + serial); + System.exit(0); + } + serials.add(serial); + } + } + static void test(SerialNumbers producer) { + for(int i = 0; i < 10; i++) + CompletableFuture.runAsync( + new SerialNumberChecker(producer)); + new Nap(4, "No duplicates detected"); + } +} diff --git a/code/lowlevel/SerialNumberTest.java b/code/lowlevel/SerialNumberTest.java new file mode 100644 index 00000000..cdeddcd9 --- /dev/null +++ b/code/lowlevel/SerialNumberTest.java @@ -0,0 +1,13 @@ +// lowlevel/SerialNumberTest.java +// (c)2020 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. + +public class SerialNumberTest { + public static void main(String[] args) { + SerialNumberChecker.test(new SerialNumbers()); + } +} +/* Output: +Duplicate: 148044 +*/ diff --git a/code/lowlevel/SerialNumbers.java b/code/lowlevel/SerialNumbers.java new file mode 100644 index 00000000..3f6101c7 --- /dev/null +++ b/code/lowlevel/SerialNumbers.java @@ -0,0 +1,11 @@ +// lowlevel/SerialNumbers.java +// (c)2020 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. + +public class SerialNumbers { + private volatile int serialNumber = 0; + public int nextSerialNumber() { + return serialNumber++; // Not thread-safe + } +} diff --git a/code/lowlevel/SettingDefaultHandler.java b/code/lowlevel/SettingDefaultHandler.java new file mode 100644 index 00000000..56a04642 --- /dev/null +++ b/code/lowlevel/SettingDefaultHandler.java @@ -0,0 +1,19 @@ +// lowlevel/SettingDefaultHandler.java +// (c)2020 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. +import java.util.concurrent.*; + +public class SettingDefaultHandler { + public static void main(String[] args) { + Thread.setDefaultUncaughtExceptionHandler( + new MyUncaughtExceptionHandler()); + ExecutorService es = + Executors.newCachedThreadPool(); + es.execute(new ExceptionThread()); + es.shutdown(); + } +} +/* Output: +caught java.lang.RuntimeException +*/ diff --git a/code/lowlevel/SwallowedException.java b/code/lowlevel/SwallowedException.java new file mode 100644 index 00000000..60edd0d6 --- /dev/null +++ b/code/lowlevel/SwallowedException.java @@ -0,0 +1,17 @@ +// lowlevel/SwallowedException.java +// (c)2020 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. +import java.util.concurrent.*; + +public class SwallowedException { + public static void main(String[] args) + throws InterruptedException { + ExecutorService exec = + Executors.newSingleThreadExecutor(); + exec.submit(() -> { + throw new RuntimeException(); + }); + exec.shutdown(); + } +} diff --git a/code/lowlevel/SyncOnObject.java b/code/lowlevel/SyncOnObject.java new file mode 100644 index 00000000..846c5573 --- /dev/null +++ b/code/lowlevel/SyncOnObject.java @@ -0,0 +1,70 @@ +// lowlevel/SyncOnObject.java +// (c)2020 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. +// Synchronizing on another object +import java.util.*; +import java.util.stream.*; +import java.util.concurrent.*; +import onjava.Nap; + +class DualSynch { + ConcurrentLinkedQueue trace = + new ConcurrentLinkedQueue<>(); + public synchronized void f(boolean nap) { + for(int i = 0; i < 5; i++) { + trace.add(String.format("f() " + i)); + if(nap) new Nap(0.01); + } + } + private Object syncObject = new Object(); + public void g(boolean nap) { + synchronized(syncObject) { + for(int i = 0; i < 5; i++) { + trace.add(String.format("g() " + i)); + if(nap) new Nap(0.01); + } + } + } +} + +public class SyncOnObject { + static void test(boolean fNap, boolean gNap) { + DualSynch ds = new DualSynch(); + List> cfs = + Arrays.stream(new Runnable[] { + () -> ds.f(fNap), () -> ds.g(gNap) }) + .map(CompletableFuture::runAsync) + .collect(Collectors.toList()); + cfs.forEach(CompletableFuture::join); + ds.trace.forEach(System.out::println); + } + public static void main(String[] args) { + test(true, false); + System.out.println("****"); + test(false, true); + } +} +/* Output: +f() 0 +g() 0 +g() 1 +g() 2 +g() 3 +g() 4 +f() 1 +f() 2 +f() 3 +f() 4 +**** +f() 0 +g() 0 +f() 1 +f() 2 +f() 3 +f() 4 +g() 1 +g() 2 +g() 3 +g() 4 +*/ diff --git a/code/lowlevel/SynchronizedComparison.java b/code/lowlevel/SynchronizedComparison.java new file mode 100644 index 00000000..6fbcd1f3 --- /dev/null +++ b/code/lowlevel/SynchronizedComparison.java @@ -0,0 +1,89 @@ +// lowlevel/SynchronizedComparison.java +// (c)2020 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. +// Synchronizing blocks instead of entire methods +// speeds up access. +import java.util.*; +import java.util.stream.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; +import onjava.Nap; + +abstract class Guarded { + AtomicLong callCount = new AtomicLong(); + public abstract void method(); + @Override + public String toString() { + return getClass().getSimpleName() + + ": " + callCount.get(); + } +} + +class SynchronizedMethod extends Guarded { + public synchronized void method() { + new Nap(0.01); + callCount.incrementAndGet(); + } +} + +class CriticalSection extends Guarded { + public void method() { + new Nap(0.01); + synchronized(this) { + callCount.incrementAndGet(); + } + } +} + +class Caller implements Runnable { + private Guarded g; + Caller(Guarded g) { this.g = g; } + private AtomicLong successfulCalls = + new AtomicLong(); + private AtomicBoolean stop = + new AtomicBoolean(false); + @Override + public void run() { + new Timer().schedule(new TimerTask() { + public void run() { stop.set(true); } + }, 2500); + while(!stop.get()) { + g.method(); + successfulCalls.getAndIncrement(); + } + System.out.println( + "-> " + successfulCalls.get()); + } +} + +public class SynchronizedComparison { + static void test(Guarded g) { + List> callers = + Stream.of( + new Caller(g), + new Caller(g), + new Caller(g), + new Caller(g)) + .map(CompletableFuture::runAsync) + .collect(Collectors.toList()); + callers.forEach(CompletableFuture::join); + System.out.println(g); + } + public static void main(String[] args) { + test(new CriticalSection()); + test(new SynchronizedMethod()); + } +} +/* Output: +-> 243 +-> 243 +-> 243 +-> 243 +CriticalSection: 972 +-> 69 +-> 61 +-> 83 +-> 36 +SynchronizedMethod: 249 +*/ diff --git a/code/lowlevel/SynchronizedEvenProducer.java b/code/lowlevel/SynchronizedEvenProducer.java new file mode 100644 index 00000000..377aeecb --- /dev/null +++ b/code/lowlevel/SynchronizedEvenProducer.java @@ -0,0 +1,24 @@ +// lowlevel/SynchronizedEvenProducer.java +// (c)2020 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. +// Simplifying mutexes with the synchronized keyword +import onjava.Nap; + +public class +SynchronizedEvenProducer extends IntGenerator { + private int currentEvenValue = 0; + @Override + public synchronized int next() { + ++currentEvenValue; + new Nap(0.01); // Cause failure faster + ++currentEvenValue; + return currentEvenValue; + } + public static void main(String[] args) { + EvenChecker.test(new SynchronizedEvenProducer()); + } +} +/* Output: +No odd numbers discovered +*/ diff --git a/code/lowlevel/SynchronizedSerialNumbers.java b/code/lowlevel/SynchronizedSerialNumbers.java new file mode 100644 index 00000000..1739d840 --- /dev/null +++ b/code/lowlevel/SynchronizedSerialNumbers.java @@ -0,0 +1,19 @@ +// lowlevel/SynchronizedSerialNumbers.java +// (c)2020 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. + +public class +SynchronizedSerialNumbers extends SerialNumbers { + private int serialNumber = 0; + public synchronized int nextSerialNumber() { + return serialNumber++; + } + public static void main(String[] args) { + SerialNumberChecker.test( + new SynchronizedSerialNumbers()); + } +} +/* Output: +No duplicates detected +*/ diff --git a/code/lowlevel/TestAbort.java b/code/lowlevel/TestAbort.java new file mode 100644 index 00000000..a9efe528 --- /dev/null +++ b/code/lowlevel/TestAbort.java @@ -0,0 +1,17 @@ +// lowlevel/TestAbort.java +// (c)2020 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. +import onjava.*; + +public class TestAbort { + public static void main(String[] args) { + new TimedAbort(1); + System.out.println("Napping for 4"); + new Nap(4); + } +} +/* Output: +Napping for 4 +TimedAbort 1.0 +*/ diff --git a/code/lowlevel/ThreadSize.java b/code/lowlevel/ThreadSize.java new file mode 100644 index 00000000..0f00023d --- /dev/null +++ b/code/lowlevel/ThreadSize.java @@ -0,0 +1,31 @@ +// lowlevel/ThreadSize.java +// (c)2020 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. +// {ExcludeFromGradle} Takes a long time or hangs +import java.util.concurrent.*; +import onjava.Nap; + +public class ThreadSize { + static class Dummy extends Thread { + @Override + public void run() { new Nap(1); } + } + public static void main(String[] args) { + ExecutorService exec = + Executors.newCachedThreadPool(); + int count = 0; + try { + while(true) { + exec.execute(new Dummy()); + count++; + } + } catch(Error e) { + System.out.println( + e.getClass().getSimpleName() + ": " + count); + System.exit(0); + } finally { + exec.shutdown(); + } + } +} diff --git a/code/lowlevel/UnsafeReturn.java b/code/lowlevel/UnsafeReturn.java new file mode 100644 index 00000000..c2481fc0 --- /dev/null +++ b/code/lowlevel/UnsafeReturn.java @@ -0,0 +1,20 @@ +// lowlevel/UnsafeReturn.java +// (c)2020 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. +import java.util.function.*; +import java.util.concurrent.*; + +public class UnsafeReturn extends IntTestable { + private int i = 0; + public int getAsInt() { return i; } + public synchronized void evenIncrement() { + i++; i++; + } + public static void main(String[] args) { + Atomicity.test(new UnsafeReturn()); + } +} +/* Output: +failed with: 79 +*/ diff --git a/code/lowlevel/WorkStealingPool.java b/code/lowlevel/WorkStealingPool.java new file mode 100644 index 00000000..984de706 --- /dev/null +++ b/code/lowlevel/WorkStealingPool.java @@ -0,0 +1,41 @@ +// lowlevel/WorkStealingPool.java +// (c)2020 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. +import java.util.stream.*; +import java.util.concurrent.*; + +class ShowThread implements Runnable { + @Override + public void run() { + System.out.println( + Thread.currentThread().getName()); + } +} + +public class WorkStealingPool { + public static void main(String[] args) + throws InterruptedException { + System.out.println( + Runtime.getRuntime().availableProcessors()); + ExecutorService exec = + Executors.newWorkStealingPool(); + IntStream.range(0, 10) + .mapToObj(n -> new ShowThread()) + .forEach(exec::execute); + exec.awaitTermination(1, TimeUnit.SECONDS); + } +} +/* Output: +8 +ForkJoinPool-1-worker-2 +ForkJoinPool-1-worker-1 +ForkJoinPool-1-worker-2 +ForkJoinPool-1-worker-3 +ForkJoinPool-1-worker-2 +ForkJoinPool-1-worker-1 +ForkJoinPool-1-worker-3 +ForkJoinPool-1-worker-1 +ForkJoinPool-1-worker-4 +ForkJoinPool-1-worker-2 +*/ diff --git a/code/newio/AvailableCharSets.java b/code/newio/AvailableCharSets.java new file mode 100644 index 00000000..eda3b93c --- /dev/null +++ b/code/newio/AvailableCharSets.java @@ -0,0 +1,43 @@ +// newio/AvailableCharSets.java +// (c)2020 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. +// Displays Charsets and aliases +import java.nio.charset.*; +import java.util.*; + +public class AvailableCharSets { + public static void main(String[] args) { + SortedMap charSets = + Charset.availableCharsets(); + for(String csName : charSets.keySet()) { + System.out.print(csName); + Iterator aliases = charSets.get(csName) + .aliases().iterator(); + if(aliases.hasNext()) + System.out.print(": "); + while(aliases.hasNext()) { + System.out.print(aliases.next()); + if(aliases.hasNext()) + System.out.print(", "); + } + System.out.println(); + } + } +} +/* Output: (First 7 Lines) +Big5: csBig5 +Big5-HKSCS: big5-hkscs, big5hk, Big5_HKSCS, big5hkscs +CESU-8: CESU8, csCESU-8 +EUC-JP: csEUCPkdFmtjapanese, x-euc-jp, eucjis, +Extended_UNIX_Code_Packed_Format_for_Japanese, euc_jp, +eucjp, x-eucjp +EUC-KR: ksc5601-1987, csEUCKR, ksc5601_1987, ksc5601, +5601, +euc_kr, ksc_5601, ks_c_5601-1987, euckr +GB18030: gb18030-2000 +GB2312: gb2312, euc-cn, x-EUC-CN, euccn, EUC_CN, +gb2312-80, +gb2312-1980 + ... +*/ diff --git a/code/newio/BufferToText.java b/code/newio/BufferToText.java new file mode 100644 index 00000000..2f38c2c6 --- /dev/null +++ b/code/newio/BufferToText.java @@ -0,0 +1,93 @@ +// newio/BufferToText.java +// (c)2020 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. +// Converting text to and from ByteBuffers +import java.nio.*; +import java.nio.channels.*; +import java.nio.charset.*; +import java.io.*; + +public class BufferToText { + private static final int BSIZE = 1024; + public static void main(String[] args) { + try( + FileChannel fc = new FileOutputStream( + "data2.txt").getChannel() + ) { + fc.write(ByteBuffer.wrap("Some text".getBytes())); + } catch(IOException e) { + throw new RuntimeException(e); + } + ByteBuffer buff = ByteBuffer.allocate(BSIZE); + try( + FileChannel fc = new FileInputStream( + "data2.txt").getChannel() + ) { + fc.read(buff); + } catch(IOException e) { + throw new RuntimeException(e); + } + buff.flip(); + // Doesn't work: + System.out.println(buff.asCharBuffer()); + // Decode using this system's default Charset: + buff.rewind(); + String encoding = + System.getProperty("file.encoding"); + System.out.println("Decoded using " + + encoding + ": " + + Charset.forName(encoding).decode(buff)); + // Encode with something that prints: + try( + FileChannel fc = new FileOutputStream( + "data2.txt").getChannel() + ) { + fc.write(ByteBuffer.wrap( + "Some text".getBytes("UTF-16BE"))); + } catch(IOException e) { + throw new RuntimeException(e); + } + // Now try reading again: + buff.clear(); + try( + FileChannel fc = new FileInputStream( + "data2.txt").getChannel() + ) { + fc.read(buff); + } catch(IOException e) { + throw new RuntimeException(e); + } + buff.flip(); + System.out.println(buff.asCharBuffer()); + // Use a CharBuffer to write through: + buff = ByteBuffer.allocate(24); + buff.asCharBuffer().put("Some text"); + try( + FileChannel fc = new FileOutputStream( + "data2.txt").getChannel() + ) { + fc.write(buff); + } catch(IOException e) { + throw new RuntimeException(e); + } + // Read and display: + buff.clear(); + try( + FileChannel fc = new FileInputStream( + "data2.txt").getChannel() + ) { + fc.read(buff); + } catch(IOException e) { + throw new RuntimeException(e); + } + buff.flip(); + System.out.println(buff.asCharBuffer()); + } +} +/* Output: +???? +Decoded using windows-1252: Some text +Some text +Some textNULNULNUL +*/ diff --git a/code/newio/ChannelCopy.java b/code/newio/ChannelCopy.java new file mode 100644 index 00000000..84696131 --- /dev/null +++ b/code/newio/ChannelCopy.java @@ -0,0 +1,35 @@ +// newio/ChannelCopy.java +// (c)2020 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. +// Copying a file using channels and buffers +// {java ChannelCopy ChannelCopy.java test.txt} +import java.nio.*; +import java.nio.channels.*; +import java.io.*; + +public class ChannelCopy { + private static final int BSIZE = 1024; + public static void main(String[] args) { + if(args.length != 2) { + System.out.println( + "arguments: sourcefile destfile"); + System.exit(1); + } + try( + FileChannel in = new FileInputStream( + args[0]).getChannel(); + FileChannel out = new FileOutputStream( + args[1]).getChannel() + ) { + ByteBuffer buffer = ByteBuffer.allocate(BSIZE); + while(in.read(buffer) != -1) { + buffer.flip(); // Prepare for writing + out.write(buffer); + buffer.clear(); // Prepare for reading + } + } catch(IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/code/newio/Endians.java b/code/newio/Endians.java new file mode 100644 index 00000000..11d66076 --- /dev/null +++ b/code/newio/Endians.java @@ -0,0 +1,28 @@ +// newio/Endians.java +// (c)2020 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. +// Endian differences and data storage +import java.nio.*; +import java.util.*; + +public class Endians { + public static void main(String[] args) { + ByteBuffer bb = ByteBuffer.wrap(new byte[12]); + bb.asCharBuffer().put("abcdef"); + System.out.println(Arrays.toString(bb.array())); + bb.rewind(); + bb.order(ByteOrder.BIG_ENDIAN); + bb.asCharBuffer().put("abcdef"); + System.out.println(Arrays.toString(bb.array())); + bb.rewind(); + bb.order(ByteOrder.LITTLE_ENDIAN); + bb.asCharBuffer().put("abcdef"); + System.out.println(Arrays.toString(bb.array())); + } +} +/* Output: +[0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102] +[0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102] +[97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0] +*/ diff --git a/code/newio/FileLocking.java b/code/newio/FileLocking.java new file mode 100644 index 00000000..e8c74d2a --- /dev/null +++ b/code/newio/FileLocking.java @@ -0,0 +1,30 @@ +// newio/FileLocking.java +// (c)2020 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. +import java.nio.channels.*; +import java.util.concurrent.*; +import java.io.*; + +public class FileLocking { + public static void main(String[] args) { + try( + FileOutputStream fos = + new FileOutputStream("file.txt"); + FileLock fl = fos.getChannel().tryLock() + ) { + if(fl != null) { + System.out.println("Locked File"); + TimeUnit.MILLISECONDS.sleep(100); + fl.release(); + System.out.println("Released Lock"); + } + } catch(IOException | InterruptedException e) { + throw new RuntimeException(e); + } + } +} +/* Output: +Locked File +Released Lock +*/ diff --git a/code/newio/GetChannel.java b/code/newio/GetChannel.java new file mode 100644 index 00000000..16caa340 --- /dev/null +++ b/code/newio/GetChannel.java @@ -0,0 +1,53 @@ +// newio/GetChannel.java +// (c)2020 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. +// Getting channels from streams +import java.nio.*; +import java.nio.channels.*; +import java.io.*; + +public class GetChannel { + private static String name = "data.txt"; + private static final int BSIZE = 1024; + public static void main(String[] args) { + // Write a file: + try( + FileChannel fc = new FileOutputStream(name) + .getChannel() + ) { + fc.write(ByteBuffer + .wrap("Some text ".getBytes())); + } catch(IOException e) { + throw new RuntimeException(e); + } + // Add to the end of the file: + try( + FileChannel fc = new RandomAccessFile( + name, "rw").getChannel() + ) { + fc.position(fc.size()); // Move to the end + fc.write(ByteBuffer + .wrap("Some more".getBytes())); + } catch(IOException e) { + throw new RuntimeException(e); + } + // Read the file: + try( + FileChannel fc = new FileInputStream(name) + .getChannel() + ) { + ByteBuffer buff = ByteBuffer.allocate(BSIZE); + fc.read(buff); + buff.flip(); + while(buff.hasRemaining()) + System.out.write(buff.get()); + } catch(IOException e) { + throw new RuntimeException(e); + } + System.out.flush(); + } +} +/* Output: +Some text Some more +*/ diff --git a/code/newio/GetData.java b/code/newio/GetData.java new file mode 100644 index 00000000..b2518b10 --- /dev/null +++ b/code/newio/GetData.java @@ -0,0 +1,56 @@ +// newio/GetData.java +// (c)2020 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. +// Getting different representations from a ByteBuffer +import java.nio.*; + +public class GetData { + private static final int BSIZE = 1024; + public static void main(String[] args) { + ByteBuffer bb = ByteBuffer.allocate(BSIZE); + // Allocation automatically zeroes the ByteBuffer: + int i = 0; + while(i++ < bb.limit()) + if(bb.get() != 0) + System.out.println("nonzero"); + System.out.println("i = " + i); + bb.rewind(); + // Store and read a char array: + bb.asCharBuffer().put("Howdy!"); + char c; + while((c = bb.getChar()) != 0) + System.out.print(c + " "); + System.out.println(); + bb.rewind(); + // Store and read a short: + bb.asShortBuffer().put((short)471142); + System.out.println(bb.getShort()); + bb.rewind(); + // Store and read an int: + bb.asIntBuffer().put(99471142); + System.out.println(bb.getInt()); + bb.rewind(); + // Store and read a long: + bb.asLongBuffer().put(99471142); + System.out.println(bb.getLong()); + bb.rewind(); + // Store and read a float: + bb.asFloatBuffer().put(99471142); + System.out.println(bb.getFloat()); + bb.rewind(); + // Store and read a double: + bb.asDoubleBuffer().put(99471142); + System.out.println(bb.getDouble()); + bb.rewind(); + } +} +/* Output: +i = 1025 +H o w d y ! +12390 +99471142 +99471142 +9.9471144E7 +9.9471142E7 +*/ diff --git a/code/newio/IntBufferDemo.java b/code/newio/IntBufferDemo.java new file mode 100644 index 00000000..31ffaa8f --- /dev/null +++ b/code/newio/IntBufferDemo.java @@ -0,0 +1,35 @@ +// newio/IntBufferDemo.java +// (c)2020 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. +// Manipulating ints in a ByteBuffer with an IntBuffer +import java.nio.*; + +public class IntBufferDemo { + private static final int BSIZE = 1024; + public static void main(String[] args) { + ByteBuffer bb = ByteBuffer.allocate(BSIZE); + IntBuffer ib = bb.asIntBuffer(); + // Store an array of int: + ib.put(new int[]{ 11, 42, 47, 99, 143, 811, 1016 }); + // Absolute location read and write: + System.out.println(ib.get(3)); + ib.put(3, 1811); + // Setting a new limit before rewinding the buffer. + ib.flip(); + while(ib.hasRemaining()) { + int i = ib.get(); + System.out.println(i); + } + } +} +/* Output: +99 +11 +42 +47 +1811 +143 +811 +1016 +*/ diff --git a/code/newio/LargeMappedFiles.java b/code/newio/LargeMappedFiles.java new file mode 100644 index 00000000..c4976e45 --- /dev/null +++ b/code/newio/LargeMappedFiles.java @@ -0,0 +1,31 @@ +// newio/LargeMappedFiles.java +// (c)2020 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. +// Creating a very large file using mapping +import java.nio.*; +import java.nio.channels.*; +import java.io.*; + +public class LargeMappedFiles { + static int length = 0x8000000; // 128 MB + public static void + main(String[] args) throws Exception { + try( + RandomAccessFile tdat = + new RandomAccessFile("test.dat", "rw") + ) { + MappedByteBuffer out = tdat.getChannel().map( + FileChannel.MapMode.READ_WRITE, 0, length); + for(int i = 0; i < length; i++) + out.put((byte)'x'); + System.out.println("Finished writing"); + for(int i = length/2; i < length/2 + 6; i++) + System.out.print((char)out.get(i)); + } + } +} +/* Output: +Finished writing +xxxxxx +*/ diff --git a/code/newio/LockingMappedFiles.java b/code/newio/LockingMappedFiles.java new file mode 100644 index 00000000..6fe8fee5 --- /dev/null +++ b/code/newio/LockingMappedFiles.java @@ -0,0 +1,60 @@ +// newio/LockingMappedFiles.java +// (c)2020 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. +// Locking portions of a mapped file +import java.nio.*; +import java.nio.channels.*; +import java.io.*; + +public class LockingMappedFiles { + static final int LENGTH = 0x8FFFFFF; // 128 MB + static FileChannel fc; + public static void + main(String[] args) throws Exception { + fc = new RandomAccessFile("test.dat", "rw") + .getChannel(); + MappedByteBuffer out = fc.map( + FileChannel.MapMode.READ_WRITE, 0, LENGTH); + for(int i = 0; i < LENGTH; i++) + out.put((byte)'x'); + new LockAndModify(out, 0, 0 + LENGTH/3); + new LockAndModify( + out, LENGTH/2, LENGTH/2 + LENGTH/4); + } + private static class LockAndModify extends Thread { + private ByteBuffer buff; + private int start, end; + LockAndModify(ByteBuffer mbb, int start, int end) { + this.start = start; + this.end = end; + mbb.limit(end); + mbb.position(start); + buff = mbb.slice(); + start(); + } + @Override + public void run() { + try { + // Exclusive lock with no overlap: + FileLock fl = fc.lock(start, end, false); + System.out.println( + "Locked: "+ start +" to "+ end); + // Perform modification: + while(buff.position() < buff.limit() - 1) + buff.put((byte)(buff.get() + 1)); + fl.release(); + System.out.println( + "Released: " + start + " to " + end); + } catch(IOException e) { + throw new RuntimeException(e); + } + } + } +} +/* Output: +Locked: 75497471 to 113246206 +Locked: 0 to 50331647 +Released: 75497471 to 113246206 +Released: 0 to 50331647 +*/ diff --git a/code/newio/MappedIO.java b/code/newio/MappedIO.java new file mode 100644 index 00000000..93b4ddf3 --- /dev/null +++ b/code/newio/MappedIO.java @@ -0,0 +1,145 @@ +// newio/MappedIO.java +// (c)2020 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. +// {ExcludeFromGradle} Runs too long under WSL2 +import java.util.*; +import java.nio.*; +import java.nio.channels.*; +import java.io.*; + +public class MappedIO { + private static int numOfInts = 4_000_000; + private static int numOfUbuffInts = 100_000; + private abstract static class Tester { + private String name; + Tester(String name) { + this.name = name; + } + public void runTest() { + System.out.print(name + ": "); + long start = System.nanoTime(); + test(); + double duration = System.nanoTime() - start; + System.out.format("%.3f%n", duration/1.0e9); + } + public abstract void test(); + } + private static Tester[] tests = { + new Tester("Stream Write") { + @Override + public void test() { + try( + DataOutputStream dos = + new DataOutputStream( + new BufferedOutputStream( + new FileOutputStream( + new File("temp.tmp")))) + ) { + for(int i = 0; i < numOfInts; i++) + dos.writeInt(i); + } catch(IOException e) { + throw new RuntimeException(e); + } + } + }, + new Tester("Mapped Write") { + @Override + public void test() { + try( + FileChannel fc = + new RandomAccessFile("temp.tmp", "rw") + .getChannel() + ) { + IntBuffer ib = + fc.map(FileChannel.MapMode.READ_WRITE, + 0, fc.size()).asIntBuffer(); + for(int i = 0; i < numOfInts; i++) + ib.put(i); + } catch(IOException e) { + throw new RuntimeException(e); + } + } + }, + new Tester("Stream Read") { + @Override + public void test() { + try( + DataInputStream dis = + new DataInputStream( + new BufferedInputStream( + new FileInputStream("temp.tmp"))) + ) { + for(int i = 0; i < numOfInts; i++) + dis.readInt(); + } catch(IOException e) { + throw new RuntimeException(e); + } + } + }, + new Tester("Mapped Read") { + @Override + public void test() { + try( + FileChannel fc = new FileInputStream( + new File("temp.tmp")).getChannel() + ) { + IntBuffer ib = + fc.map(FileChannel.MapMode.READ_ONLY, + 0, fc.size()).asIntBuffer(); + while(ib.hasRemaining()) + ib.get(); + } catch(IOException e) { + throw new RuntimeException(e); + } + } + }, + new Tester("Stream Read/Write") { + @Override + public void test() { + try( + RandomAccessFile raf = + new RandomAccessFile( + new File("temp.tmp"), "rw") + ) { + raf.writeInt(1); + for(int i = 0; i < numOfUbuffInts; i++) { + raf.seek(raf.length() - 4); + raf.writeInt(raf.readInt()); + } + } catch(IOException e) { + throw new RuntimeException(e); + } + } + }, + new Tester("Mapped Read/Write") { + @Override + public void test() { + try( + FileChannel fc = new RandomAccessFile( + new File("temp.tmp"), "rw").getChannel() + ) { + IntBuffer ib = + fc.map(FileChannel.MapMode.READ_WRITE, + 0, fc.size()).asIntBuffer(); + ib.put(0); + for(int i = 1; i < numOfUbuffInts; i++) + ib.put(ib.get(i - 1)); + } catch(IOException e) { + throw new RuntimeException(e); + } + } + } + }; + public static void main(String[] args) { + Arrays.stream(tests).forEach(Tester::runTest); + } +} +/* Output: +Stream Write: 0.615 +Mapped Write: 0.050 +Stream Read: 0.577 +Mapped Read: 0.015 +Stream Read/Write: 4.069 +Mapped Read/Write: 0.013 +*/ diff --git a/code/newio/TransferTo.java b/code/newio/TransferTo.java new file mode 100644 index 00000000..f3095b71 --- /dev/null +++ b/code/newio/TransferTo.java @@ -0,0 +1,30 @@ +// newio/TransferTo.java +// (c)2020 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. +// Using transferTo() between channels +// {java TransferTo TransferTo.java TransferTo.txt} +import java.nio.channels.*; +import java.io.*; + +public class TransferTo { + public static void main(String[] args) { + if(args.length != 2) { + System.out.println( + "arguments: sourcefile destfile"); + System.exit(1); + } + try( + FileChannel in = new FileInputStream( + args[0]).getChannel(); + FileChannel out = new FileOutputStream( + args[1]).getChannel() + ) { + in.transferTo(0, in.size(), out); + // Or: + // out.transferFrom(in, 0, in.size()); + } catch(IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/code/newio/UsingBuffers.java b/code/newio/UsingBuffers.java new file mode 100644 index 00000000..3f3a6bd1 --- /dev/null +++ b/code/newio/UsingBuffers.java @@ -0,0 +1,35 @@ +// newio/UsingBuffers.java +// (c)2020 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. +import java.nio.*; + +public class UsingBuffers { + private static + void symmetricScramble(CharBuffer buffer) { + while(buffer.hasRemaining()) { + buffer.mark(); + char c1 = buffer.get(); + char c2 = buffer.get(); + buffer.reset(); + buffer.put(c2).put(c1); + } + } + public static void main(String[] args) { + char[] data = "UsingBuffers".toCharArray(); + ByteBuffer bb = + ByteBuffer.allocate(data.length * 2); + CharBuffer cb = bb.asCharBuffer(); + cb.put(data); + System.out.println(cb.rewind()); + symmetricScramble(cb); + System.out.println(cb.rewind()); + symmetricScramble(cb); + System.out.println(cb.rewind()); + } +} +/* Output: +UsingBuffers +sUniBgfuefsr +UsingBuffers +*/ diff --git a/code/newio/ViewBuffers.java b/code/newio/ViewBuffers.java new file mode 100644 index 00000000..d7bb1adf --- /dev/null +++ b/code/newio/ViewBuffers.java @@ -0,0 +1,69 @@ +// newio/ViewBuffers.java +// (c)2020 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. +import java.nio.*; + +public class ViewBuffers { + public static void main(String[] args) { + ByteBuffer bb = ByteBuffer.wrap( + new byte[]{ 0, 0, 0, 0, 0, 0, 0, 'a' }); + bb.rewind(); + System.out.print("Byte Buffer "); + while(bb.hasRemaining()) + System.out.print( + bb.position()+ " -> " + bb.get() + ", "); + System.out.println(); + CharBuffer cb = + ((ByteBuffer)bb.rewind()).asCharBuffer(); + System.out.print("Char Buffer "); + while(cb.hasRemaining()) + System.out.print( + cb.position() + " -> " + cb.get() + ", "); + System.out.println(); + FloatBuffer fb = + ((ByteBuffer)bb.rewind()).asFloatBuffer(); + System.out.print("Float Buffer "); + while(fb.hasRemaining()) + System.out.print( + fb.position()+ " -> " + fb.get() + ", "); + System.out.println(); + IntBuffer ib = + ((ByteBuffer)bb.rewind()).asIntBuffer(); + System.out.print("Int Buffer "); + while(ib.hasRemaining()) + System.out.print( + ib.position()+ " -> " + ib.get() + ", "); + System.out.println(); + LongBuffer lb = + ((ByteBuffer)bb.rewind()).asLongBuffer(); + System.out.print("Long Buffer "); + while(lb.hasRemaining()) + System.out.print( + lb.position()+ " -> " + lb.get() + ", "); + System.out.println(); + ShortBuffer sb = + ((ByteBuffer)bb.rewind()).asShortBuffer(); + System.out.print("Short Buffer "); + while(sb.hasRemaining()) + System.out.print( + sb.position()+ " -> " + sb.get() + ", "); + System.out.println(); + DoubleBuffer db = + ((ByteBuffer)bb.rewind()).asDoubleBuffer(); + System.out.print("Double Buffer "); + while(db.hasRemaining()) + System.out.print( + db.position()+ " -> " + db.get() + ", "); + } +} +/* Output: +Byte Buffer 0 -> 0, 1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0, 5 +-> 0, 6 -> 0, 7 -> 97, +Char Buffer 0 -> NUL, 1 -> NUL, 2 -> NUL, 3 -> a, +Float Buffer 0 -> 0.0, 1 -> 1.36E-43, +Int Buffer 0 -> 0, 1 -> 97, +Long Buffer 0 -> 97, +Short Buffer 0 -> 0, 1 -> 0, 2 -> 0, 3 -> 97, +Double Buffer 0 -> 4.8E-322, +*/ diff --git a/code/objects/HelloDate.java b/code/objects/HelloDate.java new file mode 100644 index 00000000..1f613e8e --- /dev/null +++ b/code/objects/HelloDate.java @@ -0,0 +1,12 @@ +// objects/HelloDate.java +// (c)2020 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. +import java.util.*; + +public class HelloDate { + public static void main(String[] args) { + System.out.println("Hello, it's: "); + System.out.println(new Date()); + } +} diff --git a/code/objects/ShowProperties.java b/code/objects/ShowProperties.java new file mode 100644 index 00000000..ac2bf41e --- /dev/null +++ b/code/objects/ShowProperties.java @@ -0,0 +1,39 @@ +// objects/ShowProperties.java +// (c)2020 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. + +public class ShowProperties { + public static void main(String[] args) { + System.getProperties().list(System.out); + System.out.println(System.getProperty("user.name")); + System.out.println( + System.getProperty("java.library.path")); + } +} +/* Output: (First 20 Lines) +-- listing properties -- +java.runtime.name=Java(TM) SE Runtime Environment +sun.boot.library.path=C:\Program +Files\Java\jdk1.8.0_112\jr... +java.vm.version=25.112-b15 +java.vm.vendor=Oracle Corporation +java.vendor.url=http://java.oracle.com/ +path.separator=; +java.vm.name=Java HotSpot(TM) 64-Bit Server VM +file.encoding.pkg=sun.io +user.script= +user.country=US +sun.java.launcher=SUN_STANDARD +sun.os.patch.level= +java.vm.specification.name=Java Virtual Machine +Specification +user.dir=C:\Users\Bruce\Documents\GitHub\on-ja... +java.runtime.version=1.8.0_112-b15 +java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment +java.endorsed.dirs=C:\Program +Files\Java\jdk1.8.0_112\jr... +os.arch=amd64 +java.io.tmpdir=C:\Users\Bruce\AppData\Local\Temp\ + ... +*/ diff --git a/code/onjava/ArrayShow.java b/code/onjava/ArrayShow.java new file mode 100644 index 00000000..6edd148f --- /dev/null +++ b/code/onjava/ArrayShow.java @@ -0,0 +1,73 @@ +// onjava/ArrayShow.java +// (c)2020 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 onjava; +import java.util.*; + +public interface ArrayShow { + static void show(Object[] a) { + System.out.println(Arrays.toString(a)); + } + static void show(boolean[] a) { + System.out.println(Arrays.toString(a)); + } + static void show(byte[] a) { + System.out.println(Arrays.toString(a)); + } + static void show(char[] a) { + System.out.println(Arrays.toString(a)); + } + static void show(short[] a) { + System.out.println(Arrays.toString(a)); + } + static void show(int[] a) { + System.out.println(Arrays.toString(a)); + } + static void show(long[] a) { + System.out.println(Arrays.toString(a)); + } + static void show(float[] a) { + System.out.println(Arrays.toString(a)); + } + static void show(double[] a) { + System.out.println(Arrays.toString(a)); + } + // Start with a description: + static void show(String info, Object[] a) { + System.out.print(info + ": "); + show(a); + } + static void show(String info, boolean[] a) { + System.out.print(info + ": "); + show(a); + } + static void show(String info, byte[] a) { + System.out.print(info + ": "); + show(a); + } + static void show(String info, char[] a) { + System.out.print(info + ": "); + show(a); + } + static void show(String info, short[] a) { + System.out.print(info + ": "); + show(a); + } + static void show(String info, int[] a) { + System.out.print(info + ": "); + show(a); + } + static void show(String info, long[] a) { + System.out.print(info + ": "); + show(a); + } + static void show(String info, float[] a) { + System.out.print(info + ": "); + show(a); + } + static void show(String info, double[] a) { + System.out.print(info + ": "); + show(a); + } +} diff --git a/code/onjava/BasicSupplier.java b/code/onjava/BasicSupplier.java new file mode 100644 index 00000000..d4bf3b3d --- /dev/null +++ b/code/onjava/BasicSupplier.java @@ -0,0 +1,31 @@ +// onjava/BasicSupplier.java +// (c)2020 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. +// Supplier from a class with a no-arg constructor +package onjava; +import java.util.function.*; +import java.lang.reflect.InvocationTargetException; + +public class BasicSupplier implements Supplier { + private Class type; + public BasicSupplier(Class type) { + this.type = type; + } + @Override + public T get() { + try { + // Assumes type is a public class: + return type.getConstructor().newInstance(); + } catch(InstantiationException | + NoSuchMethodException | + InvocationTargetException | + IllegalAccessException e) { + throw new RuntimeException(e); + } + } + // Produce a default Supplier from a type token: + public static Supplier create(Class type) { + return new BasicSupplier<>(type); + } +} diff --git a/code/onjava/CollectionMethodDifferences.java b/code/onjava/CollectionMethodDifferences.java new file mode 100644 index 00000000..375d4e41 --- /dev/null +++ b/code/onjava/CollectionMethodDifferences.java @@ -0,0 +1,117 @@ +// onjava/CollectionMethodDifferences.java +// (c)2020 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. +// {java onjava.CollectionMethodDifferences} +package onjava; +import java.lang.reflect.*; +import java.util.*; +import java.util.stream.*; + +public class CollectionMethodDifferences { + static Set methodSet(Class type) { + return Arrays.stream(type.getMethods()) + .map(Method::getName) + .collect(Collectors.toCollection(TreeSet::new)); + } + static void interfaces(Class type) { + System.out.print("Interfaces in " + + type.getSimpleName() + ": "); + System.out.println( + Arrays.stream(type.getInterfaces()) + .map(Class::getSimpleName) + .collect(Collectors.toList())); + } + static Set object = methodSet(Object.class); + static { object.add("clone"); } + static void + difference(Class superset, Class subset) { + System.out.print(superset.getSimpleName() + + " extends " + subset.getSimpleName() + + ", adds: "); + Set comp = Sets.difference( + methodSet(superset), methodSet(subset)); + comp.removeAll(object); // Ignore 'Object' methods + System.out.println(comp); + interfaces(superset); + } + public static void main(String[] args) { + System.out.println("Collection: " + + methodSet(Collection.class)); + interfaces(Collection.class); + difference(Set.class, Collection.class); + difference(HashSet.class, Set.class); + difference(LinkedHashSet.class, HashSet.class); + difference(TreeSet.class, Set.class); + difference(List.class, Collection.class); + difference(ArrayList.class, List.class); + difference(LinkedList.class, List.class); + difference(Queue.class, Collection.class); + difference(PriorityQueue.class, Queue.class); + System.out.println("Map: " + methodSet(Map.class)); + difference(HashMap.class, Map.class); + difference(LinkedHashMap.class, HashMap.class); + difference(SortedMap.class, Map.class); + difference(TreeMap.class, Map.class); + } +} +/* Output: +Collection: [add, addAll, clear, contains, containsAll, +equals, forEach, hashCode, isEmpty, iterator, +parallelStream, remove, removeAll, removeIf, retainAll, +size, spliterator, stream, toArray] +Interfaces in Collection: [Iterable] +Set extends Collection, adds: [] +Interfaces in Set: [Collection] +HashSet extends Set, adds: [] +Interfaces in HashSet: [Set, Cloneable, Serializable] +LinkedHashSet extends HashSet, adds: [] +Interfaces in LinkedHashSet: [Set, Cloneable, +Serializable] +TreeSet extends Set, adds: [headSet, +descendingIterator, descendingSet, pollLast, subSet, +floor, tailSet, ceiling, last, lower, comparator, +pollFirst, first, higher] +Interfaces in TreeSet: [NavigableSet, Cloneable, +Serializable] +List extends Collection, adds: [replaceAll, get, +indexOf, subList, set, sort, lastIndexOf, listIterator] +Interfaces in List: [Collection] +ArrayList extends List, adds: [trimToSize, +ensureCapacity] +Interfaces in ArrayList: [List, RandomAccess, +Cloneable, Serializable] +LinkedList extends List, adds: [offerFirst, poll, +getLast, offer, getFirst, removeFirst, element, +removeLastOccurrence, peekFirst, peekLast, push, +pollFirst, removeFirstOccurrence, descendingIterator, +pollLast, removeLast, pop, addLast, peek, offerLast, +addFirst] +Interfaces in LinkedList: [List, Deque, Cloneable, +Serializable] +Queue extends Collection, adds: [poll, peek, offer, +element] +Interfaces in Queue: [Collection] +PriorityQueue extends Queue, adds: [comparator] +Interfaces in PriorityQueue: [Serializable] +Map: [clear, compute, computeIfAbsent, +computeIfPresent, containsKey, containsValue, entrySet, +equals, forEach, get, getOrDefault, hashCode, isEmpty, +keySet, merge, put, putAll, putIfAbsent, remove, +replace, replaceAll, size, values] +HashMap extends Map, adds: [] +Interfaces in HashMap: [Map, Cloneable, Serializable] +LinkedHashMap extends HashMap, adds: [] +Interfaces in LinkedHashMap: [Map] +SortedMap extends Map, adds: [lastKey, subMap, +comparator, firstKey, headMap, tailMap] +Interfaces in SortedMap: [Map] +TreeMap extends Map, adds: [descendingKeySet, +navigableKeySet, higherEntry, higherKey, floorKey, +subMap, ceilingKey, pollLastEntry, firstKey, lowerKey, +headMap, tailMap, lowerEntry, ceilingEntry, +descendingMap, pollFirstEntry, lastKey, firstEntry, +floorEntry, comparator, lastEntry] +Interfaces in TreeMap: [NavigableMap, Cloneable, +Serializable] +*/ diff --git a/code/onjava/ConvertTo.java b/code/onjava/ConvertTo.java new file mode 100644 index 00000000..cc8febd7 --- /dev/null +++ b/code/onjava/ConvertTo.java @@ -0,0 +1,105 @@ +// onjava/ConvertTo.java +// (c)2020 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 onjava; + +public interface ConvertTo { + static boolean[] primitive(Boolean[] in) { + boolean[] result = new boolean[in.length]; + for(int i = 0; i < in.length; i++) + result[i] = in[i]; // Autounboxing + return result; + } + static char[] primitive(Character[] in) { + char[] result = new char[in.length]; + for(int i = 0; i < in.length; i++) + result[i] = in[i]; + return result; + } + static byte[] primitive(Byte[] in) { + byte[] result = new byte[in.length]; + for(int i = 0; i < in.length; i++) + result[i] = in[i]; + return result; + } + static short[] primitive(Short[] in) { + short[] result = new short[in.length]; + for(int i = 0; i < in.length; i++) + result[i] = in[i]; + return result; + } + static int[] primitive(Integer[] in) { + int[] result = new int[in.length]; + for(int i = 0; i < in.length; i++) + result[i] = in[i]; + return result; + } + static long[] primitive(Long[] in) { + long[] result = new long[in.length]; + for(int i = 0; i < in.length; i++) + result[i] = in[i]; + return result; + } + static float[] primitive(Float[] in) { + float[] result = new float[in.length]; + for(int i = 0; i < in.length; i++) + result[i] = in[i]; + return result; + } + static double[] primitive(Double[] in) { + double[] result = new double[in.length]; + for(int i = 0; i < in.length; i++) + result[i] = in[i]; + return result; + } + // Convert from primitive array to wrapped array: + static Boolean[] boxed(boolean[] in) { + Boolean[] result = new Boolean[in.length]; + for(int i = 0; i < in.length; i++) + result[i] = in[i]; // Autoboxing + return result; + } + static Character[] boxed(char[] in) { + Character[] result = new Character[in.length]; + for(int i = 0; i < in.length; i++) + result[i] = in[i]; + return result; + } + static Byte[] boxed(byte[] in) { + Byte[] result = new Byte[in.length]; + for(int i = 0; i < in.length; i++) + result[i] = in[i]; + return result; + } + static Short[] boxed(short[] in) { + Short[] result = new Short[in.length]; + for(int i = 0; i < in.length; i++) + result[i] = in[i]; + return result; + } + static Integer[] boxed(int[] in) { + Integer[] result = new Integer[in.length]; + for(int i = 0; i < in.length; i++) + result[i] = in[i]; + return result; + } + static Long[] boxed(long[] in) { + Long[] result = new Long[in.length]; + for(int i = 0; i < in.length; i++) + result[i] = in[i]; + return result; + } + static Float[] boxed(float[] in) { + Float[] result = new Float[in.length]; + for(int i = 0; i < in.length; i++) + result[i] = in[i]; + return result; + } + static Double[] boxed(double[] in) { + Double[] result = new Double[in.length]; + for(int i = 0; i < in.length; i++) + result[i] = in[i]; + return result; + } +} diff --git a/code/onjava/Count.java b/code/onjava/Count.java new file mode 100644 index 00000000..1f380f87 --- /dev/null +++ b/code/onjava/Count.java @@ -0,0 +1,220 @@ +// onjava/Count.java +// (c)2020 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. +// Generate incremental values of different types +package onjava; +import java.util.*; +import java.util.function.*; +import static onjava.ConvertTo.*; + +public interface Count { + class Boolean + implements Supplier { + private boolean b = true; + @Override + public java.lang.Boolean get() { + b = !b; + return java.lang.Boolean.valueOf(b); + } + public java.lang.Boolean get(int n) { + return get(); + } + public java.lang.Boolean[] array(int sz) { + java.lang.Boolean[] result = + new java.lang.Boolean[sz]; + Arrays.setAll(result, n -> get()); + return result; + } + } + class Pboolean { + private boolean b = true; + public boolean get() { + b = !b; + return b; + } + public boolean get(int n) { return get(); } + public boolean[] array(int sz) { + return primitive(new Boolean().array(sz)); + } + } + class Byte + implements Supplier { + private byte b; + @Override + public java.lang.Byte get() { return b++; } + public java.lang.Byte get(int n) { + return get(); + } + public java.lang.Byte[] array(int sz) { + java.lang.Byte[] result = + new java.lang.Byte[sz]; + Arrays.setAll(result, n -> get()); + return result; + } + } + class Pbyte { + private byte b; + public byte get() { return b++; } + public byte get(int n) { return get(); } + public byte[] array(int sz) { + return primitive(new Byte().array(sz)); + } + } + char[] CHARS = + "abcdefghijklmnopqrstuvwxyz".toCharArray(); + class Character + implements Supplier { + private int i; + @Override + public java.lang.Character get() { + i = (i + 1) % CHARS.length; + return CHARS[i]; + } + public java.lang.Character get(int n) { + return get(); + } + public java.lang.Character[] array(int sz) { + java.lang.Character[] result = + new java.lang.Character[sz]; + Arrays.setAll(result, n -> get()); + return result; + } + } + class Pchar { + private int i; + public char get() { + i = (i + 1) % CHARS.length; + return CHARS[i]; + } + public char get(int n) { return get(); } + public char[] array(int sz) { + return primitive(new Character().array(sz)); + } + } + class Short + implements Supplier { + short s; + @Override + public java.lang.Short get() { return s++; } + public java.lang.Short get(int n) { + return get(); + } + public java.lang.Short[] array(int sz) { + java.lang.Short[] result = + new java.lang.Short[sz]; + Arrays.setAll(result, n -> get()); + return result; + } + } + class Pshort { + short s; + public short get() { return s++; } + public short get(int n) { return get(); } + public short[] array(int sz) { + return primitive(new Short().array(sz)); + } + } + class Integer + implements Supplier { + int i; + @Override + public java.lang.Integer get() { return i++; } + public java.lang.Integer get(int n) { + return get(); + } + public java.lang.Integer[] array(int sz) { + java.lang.Integer[] result = + new java.lang.Integer[sz]; + Arrays.setAll(result, n -> get()); + return result; + } + } + class Pint implements IntSupplier { + int i; + public int get() { return i++; } + public int get(int n) { return get(); } + @Override + public int getAsInt() { return get(); } + public int[] array(int sz) { + return primitive(new Integer().array(sz)); + } + } + class Long + implements Supplier { + private long l; + @Override + public java.lang.Long get() { return l++; } + public java.lang.Long get(int n) { + return get(); + } + public java.lang.Long[] array(int sz) { + java.lang.Long[] result = + new java.lang.Long[sz]; + Arrays.setAll(result, n -> get()); + return result; + } + } + class Plong implements LongSupplier { + private long l; + public long get() { return l++; } + public long get(int n) { return get(); } + @Override + public long getAsLong() { return get(); } + public long[] array(int sz) { + return primitive(new Long().array(sz)); + } + } + class Float + implements Supplier { + private int i; + @Override + public java.lang.Float get() { + return java.lang.Float.valueOf(i++); + } + public java.lang.Float get(int n) { + return get(); + } + public java.lang.Float[] array(int sz) { + java.lang.Float[] result = + new java.lang.Float[sz]; + Arrays.setAll(result, n -> get()); + return result; + } + } + class Pfloat { + private int i; + public float get() { return i++; } + public float get(int n) { return get(); } + public float[] array(int sz) { + return primitive(new Float().array(sz)); + } + } + class Double + implements Supplier { + private int i; + @Override + public java.lang.Double get() { + return java.lang.Double.valueOf(i++); + } + public java.lang.Double get(int n) { + return get(); + } + public java.lang.Double[] array(int sz) { + java.lang.Double[] result = + new java.lang.Double[sz]; + Arrays.setAll(result, n -> get()); + return result; + } + } + class Pdouble implements DoubleSupplier { + private int i; + public double get() { return i++; } + public double get(int n) { return get(); } + @Override + public double getAsDouble() { return get(0); } + public double[] array(int sz) { + return primitive(new Double().array(sz)); + } + } +} diff --git a/code/onjava/CountMap.java b/code/onjava/CountMap.java new file mode 100644 index 00000000..e3759053 --- /dev/null +++ b/code/onjava/CountMap.java @@ -0,0 +1,97 @@ +// onjava/CountMap.java +// (c)2020 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. +// Unlimited-length Map containing sample data +// {java onjava.CountMap} +package onjava; +import java.util.*; +import java.util.stream.*; + +public class CountMap +extends AbstractMap { + private int size; + private static char[] chars = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); + private static String value(int key) { + return + chars[key % chars.length] + + Integer.toString(key / chars.length); + } + public CountMap(int size) { + this.size = size < 0 ? 0 : size; + } + @Override + public String get(Object key) { + return value((Integer)key); + } + private static class Entry + implements Map.Entry { + int index; + Entry(int index) { this.index = index; } + @Override + public boolean equals(Object o) { + return o instanceof Entry && + Objects.equals(index, ((Entry)o).index); + } + @Override + public Integer getKey() { return index; } + @Override + public String getValue() { + return value(index); + } + @Override + public String setValue(String value) { + throw new UnsupportedOperationException(); + } + @Override + public int hashCode() { + return Objects.hashCode(index); + } + } + @Override + public Set> entrySet() { + // LinkedHashSet retains initialization order: + return IntStream.range(0, size) + .mapToObj(Entry::new) + .collect(Collectors + .toCollection(LinkedHashSet::new)); + } + public static void main(String[] args) { + final int size = 6; + CountMap cm = new CountMap(60); + System.out.println(cm); + System.out.println(cm.get(500)); + cm.values().stream() + .limit(size) + .forEach(System.out::println); + System.out.println(); + new Random(47).ints(size, 0, 1000) + .mapToObj(cm::get) + .forEach(System.out::println); + } +} +/* Output: +{0=A0, 1=B0, 2=C0, 3=D0, 4=E0, 5=F0, 6=G0, 7=H0, 8=I0, +9=J0, 10=K0, 11=L0, 12=M0, 13=N0, 14=O0, 15=P0, 16=Q0, +17=R0, 18=S0, 19=T0, 20=U0, 21=V0, 22=W0, 23=X0, 24=Y0, +25=Z0, 26=A1, 27=B1, 28=C1, 29=D1, 30=E1, 31=F1, 32=G1, +33=H1, 34=I1, 35=J1, 36=K1, 37=L1, 38=M1, 39=N1, 40=O1, +41=P1, 42=Q1, 43=R1, 44=S1, 45=T1, 46=U1, 47=V1, 48=W1, +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 + +Y9 +J21 +R26 +D33 +Z36 +N16 +*/ diff --git a/code/onjava/CountingIntegerList.java b/code/onjava/CountingIntegerList.java new file mode 100644 index 00000000..7d5d4f79 --- /dev/null +++ b/code/onjava/CountingIntegerList.java @@ -0,0 +1,34 @@ +// onjava/CountingIntegerList.java +// (c)2020 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. +// List of any length, containing sample data +// {java onjava.CountingIntegerList} +package onjava; +import java.util.*; + +public class CountingIntegerList +extends AbstractList { + private int size; + public CountingIntegerList() { size = 0; } + public CountingIntegerList(int size) { + this.size = size < 0 ? 0 : size; + } + @Override + public Integer get(int index) { + return index; + } + @Override + public int size() { return size; } + public static void main(String[] args) { + List cil = + new CountingIntegerList(30); + System.out.println(cil); + System.out.println(cil.get(500)); + } +} +/* Output: +[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, +16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29] +500 +*/ diff --git a/code/onjava/Countries.java b/code/onjava/Countries.java new file mode 100644 index 00000000..ec42b592 --- /dev/null +++ b/code/onjava/Countries.java @@ -0,0 +1,351 @@ +// onjava/Countries.java +// (c)2020 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. +// "Flyweight" Maps and Lists of sample data +// {java onjava.Countries} +package onjava; +import java.util.*; + +public class Countries { + public static final String[][] DATA = { + // Africa + {"ALGERIA","Algiers"}, + {"ANGOLA","Luanda"}, + {"BENIN","Porto-Novo"}, + {"BOTSWANA","Gaberone"}, + {"BURKINA FASO","Ouagadougou"}, + {"BURUNDI","Bujumbura"}, + {"CAMEROON","Yaounde"}, + {"CAPE VERDE","Praia"}, + {"CENTRAL AFRICAN REPUBLIC","Bangui"}, + {"CHAD","N'djamena"}, + {"COMOROS","Moroni"}, + {"CONGO","Brazzaville"}, + {"DJIBOUTI","Dijibouti"}, + {"EGYPT","Cairo"}, + {"EQUATORIAL GUINEA","Malabo"}, + {"ERITREA","Asmara"}, + {"ETHIOPIA","Addis Ababa"}, + {"GABON","Libreville"}, + {"THE GAMBIA","Banjul"}, + {"GHANA","Accra"}, + {"GUINEA","Conakry"}, + {"BISSAU","Bissau"}, + {"COTE D'IVOIR (IVORY COAST)","Yamoussoukro"}, + {"KENYA","Nairobi"}, + {"LESOTHO","Maseru"}, + {"LIBERIA","Monrovia"}, + {"LIBYA","Tripoli"}, + {"MADAGASCAR","Antananarivo"}, + {"MALAWI","Lilongwe"}, + {"MALI","Bamako"}, + {"MAURITANIA","Nouakchott"}, + {"MAURITIUS","Port Louis"}, + {"MOROCCO","Rabat"}, + {"MOZAMBIQUE","Maputo"}, + {"NAMIBIA","Windhoek"}, + {"NIGER","Niamey"}, + {"NIGERIA","Abuja"}, + {"RWANDA","Kigali"}, + {"SAO TOME E PRINCIPE","Sao Tome"}, + {"SENEGAL","Dakar"}, + {"SEYCHELLES","Victoria"}, + {"SIERRA LEONE","Freetown"}, + {"SOMALIA","Mogadishu"}, + {"SOUTH AFRICA","Pretoria/Cape Town"}, + {"SUDAN","Khartoum"}, + {"SWAZILAND","Mbabane"}, + {"TANZANIA","Dodoma"}, + {"TOGO","Lome"}, + {"TUNISIA","Tunis"}, + {"UGANDA","Kampala"}, + {"DEMOCRATIC REPUBLIC OF THE CONGO (ZAIRE)", + "Kinshasa"}, + {"ZAMBIA","Lusaka"}, + {"ZIMBABWE","Harare"}, + // Asia + {"AFGHANISTAN","Kabul"}, + {"BAHRAIN","Manama"}, + {"BANGLADESH","Dhaka"}, + {"BHUTAN","Thimphu"}, + {"BRUNEI","Bandar Seri Begawan"}, + {"CAMBODIA","Phnom Penh"}, + {"CHINA","Beijing"}, + {"CYPRUS","Nicosia"}, + {"INDIA","New Delhi"}, + {"INDONESIA","Jakarta"}, + {"IRAN","Tehran"}, + {"IRAQ","Baghdad"}, + {"ISRAEL","Jerusalem"}, + {"JAPAN","Tokyo"}, + {"JORDAN","Amman"}, + {"KUWAIT","Kuwait City"}, + {"LAOS","Vientiane"}, + {"LEBANON","Beirut"}, + {"MALAYSIA","Kuala Lumpur"}, + {"THE MALDIVES","Male"}, + {"MONGOLIA","Ulan Bator"}, + {"MYANMAR (BURMA)","Rangoon"}, + {"NEPAL","Katmandu"}, + {"NORTH KOREA","P'yongyang"}, + {"OMAN","Muscat"}, + {"PAKISTAN","Islamabad"}, + {"PHILIPPINES","Manila"}, + {"QATAR","Doha"}, + {"SAUDI ARABIA","Riyadh"}, + {"SINGAPORE","Singapore"}, + {"SOUTH KOREA","Seoul"}, + {"SRI LANKA","Colombo"}, + {"SYRIA","Damascus"}, + {"TAIWAN (REPUBLIC OF CHINA)","Taipei"}, + {"THAILAND","Bangkok"}, + {"TURKEY","Ankara"}, + {"UNITED ARAB EMIRATES","Abu Dhabi"}, + {"VIETNAM","Hanoi"}, + {"YEMEN","Sana'a"}, + // Australia and Oceania + {"AUSTRALIA","Canberra"}, + {"FIJI","Suva"}, + {"KIRIBATI","Bairiki"}, + {"MARSHALL ISLANDS","Dalap-Uliga-Darrit"}, + {"MICRONESIA","Palikir"}, + {"NAURU","Yaren"}, + {"NEW ZEALAND","Wellington"}, + {"PALAU","Koror"}, + {"PAPUA NEW GUINEA","Port Moresby"}, + {"SOLOMON ISLANDS","Honaira"}, + {"TONGA","Nuku'alofa"}, + {"TUVALU","Fongafale"}, + {"VANUATU","Port Vila"}, + {"WESTERN SAMOA","Apia"}, + // Eastern Europe and former USSR + {"ARMENIA","Yerevan"}, + {"AZERBAIJAN","Baku"}, + {"BELARUS (BYELORUSSIA)","Minsk"}, + {"BULGARIA","Sofia"}, + {"GEORGIA","Tbilisi"}, + {"KAZAKSTAN","Almaty"}, + {"KYRGYZSTAN","Alma-Ata"}, + {"MOLDOVA","Chisinau"}, + {"RUSSIA","Moscow"}, + {"TAJIKISTAN","Dushanbe"}, + {"TURKMENISTAN","Ashkabad"}, + {"UKRAINE","Kyiv"}, + {"UZBEKISTAN","Tashkent"}, + // Europe + {"ALBANIA","Tirana"}, + {"ANDORRA","Andorra la Vella"}, + {"AUSTRIA","Vienna"}, + {"BELGIUM","Brussels"}, + {"BOSNIA-HERZEGOVINA","Sarajevo"}, + {"CROATIA","Zagreb"}, + {"CZECH REPUBLIC","Prague"}, + {"DENMARK","Copenhagen"}, + {"ESTONIA","Tallinn"}, + {"FINLAND","Helsinki"}, + {"FRANCE","Paris"}, + {"GERMANY","Berlin"}, + {"GREECE","Athens"}, + {"HUNGARY","Budapest"}, + {"ICELAND","Reykjavik"}, + {"IRELAND","Dublin"}, + {"ITALY","Rome"}, + {"LATVIA","Riga"}, + {"LIECHTENSTEIN","Vaduz"}, + {"LITHUANIA","Vilnius"}, + {"LUXEMBOURG","Luxembourg"}, + {"MACEDONIA","Skopje"}, + {"MALTA","Valletta"}, + {"MONACO","Monaco"}, + {"MONTENEGRO","Podgorica"}, + {"THE NETHERLANDS","Amsterdam"}, + {"NORWAY","Oslo"}, + {"POLAND","Warsaw"}, + {"PORTUGAL","Lisbon"}, + {"ROMANIA","Bucharest"}, + {"SAN MARINO","San Marino"}, + {"SERBIA","Belgrade"}, + {"SLOVAKIA","Bratislava"}, + {"SLOVENIA","Ljuijana"}, + {"SPAIN","Madrid"}, + {"SWEDEN","Stockholm"}, + {"SWITZERLAND","Berne"}, + {"UNITED KINGDOM","London"}, + {"VATICAN CITY","Vatican City"}, + // North and Central America + {"ANTIGUA AND BARBUDA","Saint John's"}, + {"BAHAMAS","Nassau"}, + {"BARBADOS","Bridgetown"}, + {"BELIZE","Belmopan"}, + {"CANADA","Ottawa"}, + {"COSTA RICA","San Jose"}, + {"CUBA","Havana"}, + {"DOMINICA","Roseau"}, + {"DOMINICAN REPUBLIC","Santo Domingo"}, + {"EL SALVADOR","San Salvador"}, + {"GRENADA","Saint George's"}, + {"GUATEMALA","Guatemala City"}, + {"HAITI","Port-au-Prince"}, + {"HONDURAS","Tegucigalpa"}, + {"JAMAICA","Kingston"}, + {"MEXICO","Mexico City"}, + {"NICARAGUA","Managua"}, + {"PANAMA","Panama City"}, + {"ST. KITTS AND NEVIS","Basseterre"}, + {"ST. LUCIA","Castries"}, + {"ST. VINCENT AND THE GRENADINES","Kingstown"}, + {"UNITED STATES OF AMERICA","Washington, D.C."}, + // South America + {"ARGENTINA","Buenos Aires"}, + {"BOLIVIA","Sucre (legal)/La Paz(administrative)"}, + {"BRAZIL","Brasilia"}, + {"CHILE","Santiago"}, + {"COLOMBIA","Bogota"}, + {"ECUADOR","Quito"}, + {"GUYANA","Georgetown"}, + {"PARAGUAY","Asuncion"}, + {"PERU","Lima"}, + {"SURINAME","Paramaribo"}, + {"TRINIDAD AND TOBAGO","Port of Spain"}, + {"URUGUAY","Montevideo"}, + {"VENEZUELA","Caracas"}, + }; + // Use AbstractMap by implementing entrySet() + private static class FlyweightMap + extends AbstractMap { + private static class Entry + implements Map.Entry { + int index; + Entry(int index) { this.index = index; } + @Override + public boolean equals(Object o) { + return o instanceof FlyweightMap && + Objects.equals(DATA[index][0], o); + } + @Override + public int hashCode() { + return Objects.hashCode(DATA[index][0]); + } + @Override + public String getKey() { return DATA[index][0]; } + @Override + public String getValue() { + return DATA[index][1]; + } + @Override + public String setValue(String value) { + throw new UnsupportedOperationException(); + } + } + // Implement size() & iterator() for AbstractSet: + static class EntrySet + extends AbstractSet> { + private int size; + EntrySet(int size) { + if(size < 0) + this.size = 0; + // Can't be any bigger than the array: + else if(size > DATA.length) + this.size = DATA.length; + else + this.size = size; + } + @Override + public int size() { return size; } + private class Iter + implements Iterator> { + // Only one Entry object per Iterator: + private Entry entry = new Entry(-1); + @Override + public boolean hasNext() { + return entry.index < size - 1; + } + @Override + public Map.Entry next() { + entry.index++; + return entry; + } + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } + @Override + public + Iterator> iterator() { + return new Iter(); + } + } + private static + Set> entries = + new EntrySet(DATA.length); + @Override + public Set> entrySet() { + return entries; + } + } + // Create a partial map of 'size' countries: + static Map select(final int size) { + return new FlyweightMap() { + @Override + public Set> entrySet() { + return new EntrySet(size); + } + }; + } + static Map map = new FlyweightMap(); + public static Map capitals() { + return map; // The entire map + } + public static Map capitals(int size) { + return select(size); // A partial map + } + static List names = + new ArrayList<>(map.keySet()); + // All the names: + public static List names() { return names; } + // A partial list: + public static List names(int size) { + return new ArrayList<>(select(size).keySet()); + } + public static void main(String[] args) { + System.out.println(capitals(10)); + System.out.println(names(10)); + System.out.println(new HashMap<>(capitals(3))); + System.out.println( + new LinkedHashMap<>(capitals(3))); + System.out.println(new TreeMap<>(capitals(3))); + System.out.println(new Hashtable<>(capitals(3))); + System.out.println(new HashSet<>(names(6))); + System.out.println(new LinkedHashSet<>(names(6))); + System.out.println(new TreeSet<>(names(6))); + System.out.println(new ArrayList<>(names(6))); + System.out.println(new LinkedList<>(names(6))); + System.out.println(capitals().get("BRAZIL")); + } +} +/* Output: +{ALGERIA=Algiers, ANGOLA=Luanda, BENIN=Porto-Novo, +BOTSWANA=Gaberone, BURKINA FASO=Ouagadougou, +BURUNDI=Bujumbura, CAMEROON=Yaounde, CAPE VERDE=Praia, +CENTRAL AFRICAN REPUBLIC=Bangui, CHAD=N'djamena} +[ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, +BURUNDI, CAMEROON, CAPE VERDE, CENTRAL AFRICAN +REPUBLIC, CHAD] +{BENIN=Porto-Novo, ANGOLA=Luanda, ALGERIA=Algiers} +{ALGERIA=Algiers, ANGOLA=Luanda, BENIN=Porto-Novo} +{ALGERIA=Algiers, ANGOLA=Luanda, BENIN=Porto-Novo} +{ALGERIA=Algiers, ANGOLA=Luanda, BENIN=Porto-Novo} +[BENIN, BOTSWANA, ANGOLA, BURKINA FASO, ALGERIA, +BURUNDI] +[ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, +BURUNDI] +[ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, +BURUNDI] +[ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, +BURUNDI] +[ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, +BURUNDI] +Brasilia +*/ diff --git a/code/onjava/Enums.java b/code/onjava/Enums.java new file mode 100644 index 00000000..0440802f --- /dev/null +++ b/code/onjava/Enums.java @@ -0,0 +1,17 @@ +// onjava/Enums.java +// (c)2020 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 onjava; +import java.util.*; + +public class Enums { + private static Random rand = new Random(47); + public static + > T random(Class ec) { + return random(ec.getEnumConstants()); + } + public static T random(T[] values) { + return values[rand.nextInt(values.length)]; + } +} diff --git a/code/onjava/FillMap.java b/code/onjava/FillMap.java new file mode 100644 index 00000000..eadc5495 --- /dev/null +++ b/code/onjava/FillMap.java @@ -0,0 +1,38 @@ +// onjava/FillMap.java +// (c)2020 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 onjava; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +public class FillMap { + public static Map + basic(Supplier> pairGen, int size) { + return Stream.generate(pairGen) + .limit(size) + .collect(Collectors + .toMap(Pair::key, Pair::value)); + } + public static Map + basic(Supplier keyGen, + Supplier valueGen, int size) { + return Stream.generate( + () -> Pair.make(keyGen.get(), valueGen.get())) + .limit(size) + .collect(Collectors + .toMap(Pair::key, Pair::value)); + } + public static > + M create(Supplier keyGen, + Supplier valueGen, + Supplier mapSupplier, int size) { + return Stream.generate( () -> + Pair.make(keyGen.get(), valueGen.get())) + .limit(size) + .collect(Collectors + .toMap(Pair::key, Pair::value, + (k, v) -> k, mapSupplier)); + } +} diff --git a/code/onjava/HTMLColors.java b/code/onjava/HTMLColors.java new file mode 100644 index 00000000..bdc3458f --- /dev/null +++ b/code/onjava/HTMLColors.java @@ -0,0 +1,236 @@ +// onjava/HTMLColors.java +// (c)2020 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. +// Sample data for collection examples +package onjava; +import java.util.*; +import java.util.stream.*; +import java.util.concurrent.*; + +public class HTMLColors { + public static final Object[][] ARRAY = { + { 0xF0F8FF, "AliceBlue" }, + { 0xFAEBD7, "AntiqueWhite" }, + { 0x7FFFD4, "Aquamarine" }, + { 0xF0FFFF, "Azure" }, + { 0xF5F5DC, "Beige" }, + { 0xFFE4C4, "Bisque" }, + { 0x000000, "Black" }, + { 0xFFEBCD, "BlanchedAlmond" }, + { 0x0000FF, "Blue" }, + { 0x8A2BE2, "BlueViolet" }, + { 0xA52A2A, "Brown" }, + { 0xDEB887, "BurlyWood" }, + { 0x5F9EA0, "CadetBlue" }, + { 0x7FFF00, "Chartreuse" }, + { 0xD2691E, "Chocolate" }, + { 0xFF7F50, "Coral" }, + { 0x6495ED, "CornflowerBlue" }, + { 0xFFF8DC, "Cornsilk" }, + { 0xDC143C, "Crimson" }, + { 0x00FFFF, "Cyan" }, + { 0x00008B, "DarkBlue" }, + { 0x008B8B, "DarkCyan" }, + { 0xB8860B, "DarkGoldenRod" }, + { 0xA9A9A9, "DarkGray" }, + { 0x006400, "DarkGreen" }, + { 0xBDB76B, "DarkKhaki" }, + { 0x8B008B, "DarkMagenta" }, + { 0x556B2F, "DarkOliveGreen" }, + { 0xFF8C00, "DarkOrange" }, + { 0x9932CC, "DarkOrchid" }, + { 0x8B0000, "DarkRed" }, + { 0xE9967A, "DarkSalmon" }, + { 0x8FBC8F, "DarkSeaGreen" }, + { 0x483D8B, "DarkSlateBlue" }, + { 0x2F4F4F, "DarkSlateGray" }, + { 0x00CED1, "DarkTurquoise" }, + { 0x9400D3, "DarkViolet" }, + { 0xFF1493, "DeepPink" }, + { 0x00BFFF, "DeepSkyBlue" }, + { 0x696969, "DimGray" }, + { 0x1E90FF, "DodgerBlue" }, + { 0xB22222, "FireBrick" }, + { 0xFFFAF0, "FloralWhite" }, + { 0x228B22, "ForestGreen" }, + { 0xDCDCDC, "Gainsboro" }, + { 0xF8F8FF, "GhostWhite" }, + { 0xFFD700, "Gold" }, + { 0xDAA520, "GoldenRod" }, + { 0x808080, "Gray" }, + { 0x008000, "Green" }, + { 0xADFF2F, "GreenYellow" }, + { 0xF0FFF0, "HoneyDew" }, + { 0xFF69B4, "HotPink" }, + { 0xCD5C5C, "IndianRed" }, + { 0x4B0082, "Indigo" }, + { 0xFFFFF0, "Ivory" }, + { 0xF0E68C, "Khaki" }, + { 0xE6E6FA, "Lavender" }, + { 0xFFF0F5, "LavenderBlush" }, + { 0x7CFC00, "LawnGreen" }, + { 0xFFFACD, "LemonChiffon" }, + { 0xADD8E6, "LightBlue" }, + { 0xF08080, "LightCoral" }, + { 0xE0FFFF, "LightCyan" }, + { 0xFAFAD2, "LightGoldenRodYellow" }, + { 0xD3D3D3, "LightGray" }, + { 0x90EE90, "LightGreen" }, + { 0xFFB6C1, "LightPink" }, + { 0xFFA07A, "LightSalmon" }, + { 0x20B2AA, "LightSeaGreen" }, + { 0x87CEFA, "LightSkyBlue" }, + { 0x778899, "LightSlateGray" }, + { 0xB0C4DE, "LightSteelBlue" }, + { 0xFFFFE0, "LightYellow" }, + { 0x00FF00, "Lime" }, + { 0x32CD32, "LimeGreen" }, + { 0xFAF0E6, "Linen" }, + { 0xFF00FF, "Magenta" }, + { 0x800000, "Maroon" }, + { 0x66CDAA, "MediumAquaMarine" }, + { 0x0000CD, "MediumBlue" }, + { 0xBA55D3, "MediumOrchid" }, + { 0x9370DB, "MediumPurple" }, + { 0x3CB371, "MediumSeaGreen" }, + { 0x7B68EE, "MediumSlateBlue" }, + { 0x00FA9A, "MediumSpringGreen" }, + { 0x48D1CC, "MediumTurquoise" }, + { 0xC71585, "MediumVioletRed" }, + { 0x191970, "MidnightBlue" }, + { 0xF5FFFA, "MintCream" }, + { 0xFFE4E1, "MistyRose" }, + { 0xFFE4B5, "Moccasin" }, + { 0xFFDEAD, "NavajoWhite" }, + { 0x000080, "Navy" }, + { 0xFDF5E6, "OldLace" }, + { 0x808000, "Olive" }, + { 0x6B8E23, "OliveDrab" }, + { 0xFFA500, "Orange" }, + { 0xFF4500, "OrangeRed" }, + { 0xDA70D6, "Orchid" }, + { 0xEEE8AA, "PaleGoldenRod" }, + { 0x98FB98, "PaleGreen" }, + { 0xAFEEEE, "PaleTurquoise" }, + { 0xDB7093, "PaleVioletRed" }, + { 0xFFEFD5, "PapayaWhip" }, + { 0xFFDAB9, "PeachPuff" }, + { 0xCD853F, "Peru" }, + { 0xFFC0CB, "Pink" }, + { 0xDDA0DD, "Plum" }, + { 0xB0E0E6, "PowderBlue" }, + { 0x800080, "Purple" }, + { 0xFF0000, "Red" }, + { 0xBC8F8F, "RosyBrown" }, + { 0x4169E1, "RoyalBlue" }, + { 0x8B4513, "SaddleBrown" }, + { 0xFA8072, "Salmon" }, + { 0xF4A460, "SandyBrown" }, + { 0x2E8B57, "SeaGreen" }, + { 0xFFF5EE, "SeaShell" }, + { 0xA0522D, "Sienna" }, + { 0xC0C0C0, "Silver" }, + { 0x87CEEB, "SkyBlue" }, + { 0x6A5ACD, "SlateBlue" }, + { 0x708090, "SlateGray" }, + { 0xFFFAFA, "Snow" }, + { 0x00FF7F, "SpringGreen" }, + { 0x4682B4, "SteelBlue" }, + { 0xD2B48C, "Tan" }, + { 0x008080, "Teal" }, + { 0xD8BFD8, "Thistle" }, + { 0xFF6347, "Tomato" }, + { 0x40E0D0, "Turquoise" }, + { 0xEE82EE, "Violet" }, + { 0xF5DEB3, "Wheat" }, + { 0xFFFFFF, "White" }, + { 0xF5F5F5, "WhiteSmoke" }, + { 0xFFFF00, "Yellow" }, + { 0x9ACD32, "YellowGreen" }, + }; + public static final Map MAP = + Arrays.stream(ARRAY) + .collect(Collectors.toMap( + element -> (Integer)element[0], + element -> (String)element[1], + (v1, v2) -> { // Merge function + throw new IllegalStateException(); + }, + LinkedHashMap::new + )); + // Inversion only works if values are unique: + public static Map + invert(Map map) { + return map.entrySet().stream() + .collect(Collectors.toMap( + Map.Entry::getValue, + Map.Entry::getKey, + (v1, v2) -> { + throw new IllegalStateException(); + }, + LinkedHashMap::new + )); + } + public static final Map + INVMAP = invert(MAP); + // Look up RGB value given a name: + public static Integer rgb(String colorName) { + return INVMAP.get(colorName); + } + public static final List LIST = + Arrays.stream(ARRAY) + .map(item -> (String)item[1]) + .collect(Collectors.toList()); + public static final List RGBLIST = + Arrays.stream(ARRAY) + .map(item -> (Integer)item[0]) + .collect(Collectors.toList()); + public static + void show(Map.Entry e) { + System.out.format( + "0x%06X: %s%n", e.getKey(), e.getValue()); + } + public static void + show(Map m, int count) { + m.entrySet().stream() + .limit(count) + .forEach(e -> show(e)); + } + public static void show(Map m) { + show(m, m.size()); + } + public static + void show(Collection lst, int count) { + lst.stream() + .limit(count) + .forEach(System.out::println); + } + public static void show(Collection lst) { + show(lst, lst.size()); + } + public static + void showrgb(Collection lst, int count) { + lst.stream() + .limit(count) + .forEach(n -> System.out.format("0x%06X%n", n)); + } + public static void showrgb(Collection lst) { + showrgb(lst, lst.size()); + } + public static + void showInv(Map m, int count) { + m.entrySet().stream() + .limit(count) + .forEach(e -> + System.out.format( + "%-20s 0x%06X%n", e.getKey(), e.getValue())); + } + public static void showInv(Map m) { + showInv(m, m.size()); + } + public static void border() { + System.out.println( + "******************************"); + } +} diff --git a/code/onjava/MouseClick.java b/code/onjava/MouseClick.java new file mode 100644 index 00000000..70d982f7 --- /dev/null +++ b/code/onjava/MouseClick.java @@ -0,0 +1,19 @@ +// onjava/MouseClick.java +// (c)2020 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. +// Helper interface to allow lambda expressions +package onjava; +import java.awt.event.*; + +// Default everything except mouseClicked(): +public interface MouseClick extends MouseListener { + @Override + default void mouseEntered(MouseEvent e) {} + @Override + default void mouseExited(MouseEvent e) {} + @Override + default void mousePressed(MouseEvent e) {} + @Override + default void mouseReleased(MouseEvent e) {} +} diff --git a/code/onjava/Nap.java b/code/onjava/Nap.java new file mode 100644 index 00000000..2b89745b --- /dev/null +++ b/code/onjava/Nap.java @@ -0,0 +1,20 @@ +// onjava/Nap.java +// (c)2020 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 onjava; +import java.util.concurrent.*; + +public class Nap { + public Nap(double t) { // Seconds + try { + TimeUnit.MILLISECONDS.sleep((int)(1000 * t)); + } catch(InterruptedException e) { + throw new RuntimeException(e); + } + } + public Nap(double t, String msg) { + this(t); + System.out.println(msg); + } +} diff --git a/code/onjava/Null.java b/code/onjava/Null.java new file mode 100644 index 00000000..f3bb70d6 --- /dev/null +++ b/code/onjava/Null.java @@ -0,0 +1,6 @@ +// onjava/Null.java +// (c)2020 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 onjava; +public interface Null {} diff --git a/code/onjava/OSExecute.java b/code/onjava/OSExecute.java new file mode 100644 index 00000000..25ac7f0c --- /dev/null +++ b/code/onjava/OSExecute.java @@ -0,0 +1,37 @@ +// onjava/OSExecute.java +// (c)2020 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. +// Run an operating system command +// and send the output to the console +package onjava; +import java.io.*; + +public class OSExecute { + public static void command(String command) { + boolean err = false; + try { + Process process = new ProcessBuilder( + command.split(" ")).start(); + try( + BufferedReader results = new BufferedReader( + new InputStreamReader( + process.getInputStream())); + BufferedReader errors = new BufferedReader( + new InputStreamReader( + process.getErrorStream())) + ) { + results.lines() + .forEach(System.out::println); + err = errors.lines() + .peek(System.err::println) + .count() > 0; + } + } catch(IOException e) { + throw new RuntimeException(e); + } + if(err) + throw new OSExecuteException( + "Errors executing " + command); + } +} diff --git a/code/onjava/OSExecuteException.java b/code/onjava/OSExecuteException.java new file mode 100644 index 00000000..17d803e1 --- /dev/null +++ b/code/onjava/OSExecuteException.java @@ -0,0 +1,12 @@ +// onjava/OSExecuteException.java +// (c)2020 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 onjava; + +public class +OSExecuteException extends RuntimeException { + public OSExecuteException(String why) { + super(why); + } +} diff --git a/code/onjava/Operations.java b/code/onjava/Operations.java new file mode 100644 index 00000000..33b644c6 --- /dev/null +++ b/code/onjava/Operations.java @@ -0,0 +1,17 @@ +// onjava/Operations.java +// (c)2020 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 onjava; +import java.util.*; + +public interface Operations { + void execute(); + static void runOps(Operations... ops) { + for(Operations op : ops) + op.execute(); + } + static void show(String msg) { + System.out.println(msg); + } +} diff --git a/code/onjava/Pair.java b/code/onjava/Pair.java new file mode 100644 index 00000000..784ef8ac --- /dev/null +++ b/code/onjava/Pair.java @@ -0,0 +1,19 @@ +// onjava/Pair.java +// (c)2020 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 onjava; + +public class Pair { + public final K key; + public final V value; + public Pair(K k, V v) { + key = k; + value = v; + } + public K key() { return key; } + public V value() { return value; } + public static Pair make(K k, V v) { + return new Pair(k, v); + } +} diff --git a/code/onjava/ProcessFiles.java b/code/onjava/ProcessFiles.java new file mode 100644 index 00000000..edcea73a --- /dev/null +++ b/code/onjava/ProcessFiles.java @@ -0,0 +1,48 @@ +// onjava/ProcessFiles.java +// (c)2020 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 onjava; +import java.io.*; +import java.nio.file.*; + +public class ProcessFiles { + public interface Strategy { + void process(File file); + } + private Strategy strategy; + private String ext; + public ProcessFiles(Strategy strategy, String ext) { + this.strategy = strategy; + this.ext = ext; + } + public void start(String[] args) { + try { + if(args.length == 0) + processDirectoryTree(new File(".")); + else + for(String arg : args) { + File fileArg = new File(arg); + if(fileArg.isDirectory()) + processDirectoryTree(fileArg); + else { + // Allow user to leave off extension: + if(!arg.endsWith("." + ext)) + arg += "." + ext; + strategy.process( + new File(arg).getCanonicalFile()); + } + } + } catch(IOException e) { + throw new RuntimeException(e); + } + } + public void + processDirectoryTree(File root) throws IOException { + PathMatcher matcher = FileSystems.getDefault() + .getPathMatcher("glob:**/*.{" + ext + "}"); + Files.walk(root.toPath()) + .filter(matcher::matches) + .forEach(p -> strategy.process(p.toFile())); + } +} diff --git a/code/onjava/Rand.java b/code/onjava/Rand.java new file mode 100644 index 00000000..d21c0e2b --- /dev/null +++ b/code/onjava/Rand.java @@ -0,0 +1,248 @@ +// onjava/Rand.java +// (c)2020 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. +// Generate random values of different types +package onjava; +import java.util.*; +import java.util.function.*; +import static onjava.ConvertTo.*; + +public interface Rand { + int MOD = 10_000; + class Boolean + implements Supplier { + SplittableRandom r = new SplittableRandom(47); + @Override + public java.lang.Boolean get() { + return r.nextBoolean(); + } + public java.lang.Boolean get(int n) { + return get(); + } + public java.lang.Boolean[] array(int sz) { + java.lang.Boolean[] result = + new java.lang.Boolean[sz]; + Arrays.setAll(result, n -> get()); + return result; + } + } + class Pboolean { + public boolean[] array(int sz) { + return primitive(new Boolean().array(sz)); + } + } + class Byte + implements Supplier { + SplittableRandom r = new SplittableRandom(47); + @Override + public java.lang.Byte get() { + return (byte)r.nextInt(MOD); + } + public java.lang.Byte get(int n) { + return get(); + } + public java.lang.Byte[] array(int sz) { + java.lang.Byte[] result = + new java.lang.Byte[sz]; + Arrays.setAll(result, n -> get()); + return result; + } + } + class Pbyte { + public byte[] array(int sz) { + return primitive(new Byte().array(sz)); + } + } + class Character + implements Supplier { + SplittableRandom r = new SplittableRandom(47); + @Override + public java.lang.Character get() { + return (char)r.nextInt('a', 'z' + 1); + } + public java.lang.Character get(int n) { + return get(); + } + public java.lang.Character[] array(int sz) { + java.lang.Character[] result = + new java.lang.Character[sz]; + Arrays.setAll(result, n -> get()); + return result; + } + } + class Pchar { + public char[] array(int sz) { + return primitive(new Character().array(sz)); + } + } + class Short + implements Supplier { + SplittableRandom r = new SplittableRandom(47); + @Override + public java.lang.Short get() { + return (short)r.nextInt(MOD); + } + public java.lang.Short get(int n) { + return get(); + } + public java.lang.Short[] array(int sz) { + java.lang.Short[] result = + new java.lang.Short[sz]; + Arrays.setAll(result, n -> get()); + return result; + } + } + class Pshort { + public short[] array(int sz) { + return primitive(new Short().array(sz)); + } + } + class Integer + implements Supplier { + SplittableRandom r = new SplittableRandom(47); + @Override + public java.lang.Integer get() { + return r.nextInt(MOD); + } + public java.lang.Integer get(int n) { + return get(); + } + public java.lang.Integer[] array(int sz) { + int[] primitive = new Pint().array(sz); + java.lang.Integer[] result = + new java.lang.Integer[sz]; + for(int i = 0; i < sz; i++) + result[i] = primitive[i]; + return result; + } + } + class Pint implements IntSupplier { + SplittableRandom r = new SplittableRandom(47); + @Override + public int getAsInt() { + return r.nextInt(MOD); + } + public int get(int n) { return getAsInt(); } + public int[] array(int sz) { + return r.ints(sz, 0, MOD).toArray(); + } + } + class Long + implements Supplier { + SplittableRandom r = new SplittableRandom(47); + @Override + public java.lang.Long get() { + return r.nextLong(MOD); + } + public java.lang.Long get(int n) { + return get(); + } + public java.lang.Long[] array(int sz) { + long[] primitive = new Plong().array(sz); + java.lang.Long[] result = + new java.lang.Long[sz]; + for(int i = 0; i < sz; i++) + result[i] = primitive[i]; + return result; + } + } + class Plong implements LongSupplier { + SplittableRandom r = new SplittableRandom(47); + @Override + public long getAsLong() { + return r.nextLong(MOD); + } + public long get(int n) { return getAsLong(); } + public long[] array(int sz) { + return r.longs(sz, 0, MOD).toArray(); + } + } + class Float + implements Supplier { + SplittableRandom r = new SplittableRandom(47); + @Override + public java.lang.Float get() { + return (float)trim(r.nextDouble()); + } + public java.lang.Float get(int n) { + return get(); + } + public java.lang.Float[] array(int sz) { + java.lang.Float[] result = + new java.lang.Float[sz]; + Arrays.setAll(result, n -> get()); + return result; + } + } + class Pfloat { + public float[] array(int sz) { + return primitive(new Float().array(sz)); + } + } + static double trim(double d) { + return + ((double)Math.round(d * 1000.0)) / 100.0; + } + class Double + implements Supplier { + SplittableRandom r = new SplittableRandom(47); + @Override + public java.lang.Double get() { + return trim(r.nextDouble()); + } + public java.lang.Double get(int n) { + return get(); + } + public java.lang.Double[] array(int sz) { + double[] primitive = + new Rand.Pdouble().array(sz); + java.lang.Double[] result = + new java.lang.Double[sz]; + for(int i = 0; i < sz; i++) + result[i] = primitive[i]; + return result; + } + } + class Pdouble implements DoubleSupplier { + SplittableRandom r = new SplittableRandom(47); + @Override + public double getAsDouble() { + return trim(r.nextDouble()); + } + public double get(int n) { + return getAsDouble(); + } + public double[] array(int sz) { + double[] result = r.doubles(sz).toArray(); + Arrays.setAll(result, + n -> result[n] = trim(result[n])); + return result; + } + } + class String + implements Supplier { + SplittableRandom r = new SplittableRandom(47); + private int strlen = 7; // Default length + public String() {} + public String(int strLength) { + strlen = strLength; + } + @Override + public java.lang.String get() { + return r.ints(strlen, 'a', 'z' + 1) + .collect(StringBuilder::new, + StringBuilder::appendCodePoint, + StringBuilder::append).toString(); + } + public java.lang.String get(int n) { + return get(); + } + public java.lang.String[] array(int sz) { + java.lang.String[] result = + new java.lang.String[sz]; + Arrays.setAll(result, n -> get()); + return result; + } + } +} diff --git a/code/onjava/Range.java b/code/onjava/Range.java new file mode 100644 index 00000000..e075c9ba --- /dev/null +++ b/code/onjava/Range.java @@ -0,0 +1,34 @@ +// onjava/Range.java +// (c)2020 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. +// Array creation methods that can be used without +// qualifiers, using static imports: +package onjava; + +public class Range { + // Produce a sequence [0..n) + public static int[] range(int n) { + int[] result = new int[n]; + for(int i = 0; i < n; i++) + result[i] = i; + return result; + } + // Produce a sequence [start..end) + public static int[] range(int start, int end) { + int sz = end - start; + int[] result = new int[sz]; + for(int i = 0; i < sz; i++) + result[i] = start + i; + return result; + } + // Produce sequence [start..end) incrementing by step + public static + int[] range(int start, int end, int step) { + int sz = (end - start)/step; + int[] result = new int[sz]; + for(int i = 0; i < sz; i++) + result[i] = start + (i * step); + return result; + } +} diff --git a/code/onjava/Repeat.java b/code/onjava/Repeat.java new file mode 100644 index 00000000..7ab61fac --- /dev/null +++ b/code/onjava/Repeat.java @@ -0,0 +1,12 @@ +// onjava/Repeat.java +// (c)2020 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 onjava; +import static java.util.stream.IntStream.*; + +public class Repeat { + public static void repeat(int n, Runnable action) { + range(0, n).forEach(i -> action.run()); + } +} diff --git a/code/onjava/RmDir.java b/code/onjava/RmDir.java new file mode 100644 index 00000000..be7ea494 --- /dev/null +++ b/code/onjava/RmDir.java @@ -0,0 +1,31 @@ +// onjava/RmDir.java +// (c)2020 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 onjava; +import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; +import java.io.IOException; + +public class RmDir { + public static void rmdir(Path dir) + throws IOException { + Files.walkFileTree(dir, + new SimpleFileVisitor() { + @Override + public FileVisitResult + visitFile(Path file, BasicFileAttributes attrs) + throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + @Override + public FileVisitResult + postVisitDirectory(Path dir, IOException exc) + throws IOException { + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + }); + } +} diff --git a/code/onjava/Sets.java b/code/onjava/Sets.java new file mode 100644 index 00000000..62258f15 --- /dev/null +++ b/code/onjava/Sets.java @@ -0,0 +1,32 @@ +// onjava/Sets.java +// (c)2020 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 onjava; +import java.util.*; + +public class Sets { + public static Set union(Set a, Set b) { + Set result = new HashSet<>(a); + result.addAll(b); + return result; + } + public static + Set intersection(Set a, Set b) { + Set result = new HashSet<>(a); + result.retainAll(b); + return result; + } + // Subtract subset from superset: + public static Set + difference(Set superset, Set subset) { + Set result = new HashSet<>(superset); + result.removeAll(subset); + return result; + } + // Reflexive--everything not in the intersection: + public static + Set complement(Set a, Set b) { + return difference(union(a, b), intersection(a, b)); + } +} diff --git a/code/onjava/Stack.java b/code/onjava/Stack.java new file mode 100644 index 00000000..a5108176 --- /dev/null +++ b/code/onjava/Stack.java @@ -0,0 +1,20 @@ +// onjava/Stack.java +// (c)2020 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. +// A Stack class built with an ArrayDeque +package onjava; +import java.util.Deque; +import java.util.ArrayDeque; + +public class Stack { + private Deque storage = new ArrayDeque<>(); + public void push(T v) { storage.push(v); } + public T peek() { return storage.peek(); } + public T pop() { return storage.pop(); } + public boolean isEmpty() { return storage.isEmpty(); } + @Override + public String toString() { + return storage.toString(); + } +} diff --git a/code/onjava/Suppliers.java b/code/onjava/Suppliers.java new file mode 100644 index 00000000..226a70cb --- /dev/null +++ b/code/onjava/Suppliers.java @@ -0,0 +1,36 @@ +// onjava/Suppliers.java +// (c)2020 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. +// A utility to use with Suppliers +package onjava; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +public class Suppliers { + // Create a collection and fill it: + public static > C + create(Supplier factory, Supplier gen, int n) { + return Stream.generate(gen) + .limit(n) + .collect(factory, C::add, C::addAll); + } + // Fill an existing collection: + public static > + C fill(C coll, Supplier gen, int n) { + Stream.generate(gen) + .limit(n) + .forEach(coll::add); + return coll; + } + // Use an unbound method reference to + // produce a more general method: + public static H fill(H holder, + BiConsumer adder, Supplier
gen, int n) { + Stream.generate(gen) + .limit(n) + .forEach(a -> adder.accept(holder, a)); + return holder; + } +} diff --git a/code/onjava/TimedAbort.java b/code/onjava/TimedAbort.java new file mode 100644 index 00000000..3715cf2e --- /dev/null +++ b/code/onjava/TimedAbort.java @@ -0,0 +1,30 @@ +// onjava/TimedAbort.java +// (c)2020 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. +// Terminate a program after t seconds +package onjava; +import java.util.concurrent.*; + +public class TimedAbort { + private volatile boolean restart = true; + public TimedAbort(double t, String msg) { + CompletableFuture.runAsync(() -> { + try { + while(restart) { + restart = false; + TimeUnit.MILLISECONDS + .sleep((int)(1000 * t)); + } + } catch(InterruptedException e) { + throw new RuntimeException(e); + } + System.out.println(msg); + System.exit(0); + }); + } + public TimedAbort(double t) { + this(t, "TimedAbort " + t); + } + public void restart() { restart = true; } +} diff --git a/code/onjava/Timer.java b/code/onjava/Timer.java new file mode 100644 index 00000000..a695f79f --- /dev/null +++ b/code/onjava/Timer.java @@ -0,0 +1,19 @@ +// onjava/Timer.java +// (c)2020 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 onjava; +import static java.util.concurrent.TimeUnit.*; + +public class Timer { + private long start = System.nanoTime(); + public long duration() { + return NANOSECONDS.toMillis( + System.nanoTime() - start); + } + public static long duration(Runnable test) { + Timer timer = new Timer(); + test.run(); + return timer.duration(); + } +} diff --git a/code/onjava/Tuple.java b/code/onjava/Tuple.java new file mode 100644 index 00000000..73cfaa3c --- /dev/null +++ b/code/onjava/Tuple.java @@ -0,0 +1,24 @@ +// onjava/Tuple.java +// (c)2020 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. +// Tuple library using type argument inference +package onjava; + +public class Tuple { + public static Tuple2 tuple(A a, B b) { + return new Tuple2<>(a, b); + } + public static Tuple3 + tuple(A a, B b, C c) { + return new Tuple3<>(a, b, c); + } + public static Tuple4 + tuple(A a, B b, C c, D d) { + return new Tuple4<>(a, b, c, d); + } + public static + Tuple5 tuple(A a, B b, C c, D d, E e) { + return new Tuple5<>(a, b, c, d, e); + } +} diff --git a/code/onjava/Tuple2.java b/code/onjava/Tuple2.java new file mode 100644 index 00000000..7ca8d199 --- /dev/null +++ b/code/onjava/Tuple2.java @@ -0,0 +1,16 @@ +// onjava/Tuple2.java +// (c)2020 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 onjava; + +public class Tuple2 { + public final A a1; + public final B a2; + public Tuple2(A a, B b) { a1 = a; a2 = b; } + public String rep() { return a1 + ", " + a2; } + @Override + public String toString() { + return "(" + rep() + ")"; + } +} diff --git a/code/onjava/Tuple3.java b/code/onjava/Tuple3.java new file mode 100644 index 00000000..26780642 --- /dev/null +++ b/code/onjava/Tuple3.java @@ -0,0 +1,17 @@ +// onjava/Tuple3.java +// (c)2020 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 onjava; + +public class Tuple3 extends Tuple2 { + public final C a3; + public Tuple3(A a, B b, C c) { + super(a, b); + a3 = c; + } + @Override + public String rep() { + return super.rep() + ", " + a3; + } +} diff --git a/code/onjava/Tuple4.java b/code/onjava/Tuple4.java new file mode 100644 index 00000000..5ab51dc9 --- /dev/null +++ b/code/onjava/Tuple4.java @@ -0,0 +1,18 @@ +// onjava/Tuple4.java +// (c)2020 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 onjava; + +public class Tuple4 + extends Tuple3 { + public final D a4; + public Tuple4(A a, B b, C c, D d) { + super(a, b, c); + a4 = d; + } + @Override + public String rep() { + return super.rep() + ", " + a4; + } +} diff --git a/code/onjava/Tuple5.java b/code/onjava/Tuple5.java new file mode 100644 index 00000000..1df88bfd --- /dev/null +++ b/code/onjava/Tuple5.java @@ -0,0 +1,18 @@ +// onjava/Tuple5.java +// (c)2020 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 onjava; + +public class Tuple5 +extends Tuple4 { + public final E a5; + public Tuple5(A a, B b, C c, D d, E e) { + super(a, b, c, d); + a5 = e; + } + @Override + public String rep() { + return super.rep() + ", " + a5; + } +} diff --git a/code/onjava/TypeCounter.java b/code/onjava/TypeCounter.java new file mode 100644 index 00000000..d8b262b7 --- /dev/null +++ b/code/onjava/TypeCounter.java @@ -0,0 +1,41 @@ +// onjava/TypeCounter.java +// (c)2020 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. +// Counts instances of a type family +package onjava; +import java.util.*; +import java.util.stream.*; + +public class +TypeCounter extends HashMap, Integer> { + private Class baseType; + public TypeCounter(Class baseType) { + this.baseType = baseType; + } + public void count(Object obj) { + Class type = obj.getClass(); + if(!baseType.isAssignableFrom(type)) + throw new RuntimeException( + obj + " incorrect type: " + type + + ", should be type or subtype of " + baseType); + countClass(type); + } + private void countClass(Class type) { + Integer quantity = get(type); + put(type, quantity == null ? 1 : quantity + 1); + Class superClass = type.getSuperclass(); + if(superClass != null && + baseType.isAssignableFrom(superClass)) + countClass(superClass); + } + @Override + public String toString() { + String result = entrySet().stream() + .map(pair -> String.format("%s=%s", + pair.getKey().getSimpleName(), + pair.getValue())) + .collect(Collectors.joining(", ")); + return "{" + result + "}"; + } +} diff --git a/code/onjava/atunit/AtUnit.java b/code/onjava/atunit/AtUnit.java new file mode 100644 index 00000000..b1688cbd --- /dev/null +++ b/code/onjava/atunit/AtUnit.java @@ -0,0 +1,177 @@ +// onjava/atunit/AtUnit.java +// (c)2020 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. +// An annotation-based unit-test framework +// {java onjava.atunit.AtUnit} +package onjava.atunit; +import java.lang.reflect.*; +import java.io.*; +import java.util.*; +import java.nio.file.*; +import java.util.stream.*; +import onjava.*; + +public class AtUnit implements ProcessFiles.Strategy { + static Class testClass; + static List failedTests= new ArrayList<>(); + static long testsRun = 0; + static long failures = 0; + public static void + main(String[] args) throws Exception { + ClassLoader.getSystemClassLoader() + .setDefaultAssertionStatus(true); // Enable assert + new ProcessFiles(new AtUnit(), "class").start(args); + if(failures == 0) + System.out.println("OK (" + testsRun + " tests)"); + else { + System.out.println("(" + testsRun + " tests)"); + System.out.println( + "\n>>> " + failures + " FAILURE" + + (failures > 1 ? "S" : "") + " <<<"); + for(String failed : failedTests) + System.out.println(" " + failed); + } + } + @Override + public void process(File cFile) { + try { + String cName = ClassNameFinder.thisClass( + Files.readAllBytes(cFile.toPath())); + if(!cName.startsWith("public:")) + return; + cName = cName.split(":")[1]; + if(!cName.contains(".")) + return; // Ignore unpackaged classes + testClass = Class.forName(cName); + } catch(IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + TestMethods testMethods = new TestMethods(); + Method creator = null; + Method cleanup = null; + for(Method m : testClass.getDeclaredMethods()) { + testMethods.addIfTestMethod(m); + if(creator == null) + creator = checkForCreatorMethod(m); + if(cleanup == null) + cleanup = checkForCleanupMethod(m); + } + if(testMethods.size() > 0) { + if(creator == null) + try { + if(!Modifier.isPublic(testClass + .getDeclaredConstructor() + .getModifiers())) { + System.out.println("Error: " + testClass + + " no-arg constructor must be public"); + System.exit(1); + } + } catch(NoSuchMethodException e) { + // Synthesized no-arg constructor; OK + } + System.out.println(testClass.getName()); + } + for(Method m : testMethods) { + System.out.print(" . " + m.getName() + " "); + try { + Object testObject = createTestObject(creator); + boolean success = false; + try { + if(m.getReturnType().equals(boolean.class)) + success = (Boolean)m.invoke(testObject); + else { + m.invoke(testObject); + success = true; // If no assert fails + } + } catch(InvocationTargetException e) { + // Actual exception is inside e: + System.out.println(e.getCause()); + } + System.out.println(success ? "" : "(failed)"); + testsRun++; + if(!success) { + failures++; + failedTests.add(testClass.getName() + + ": " + m.getName()); + } + if(cleanup != null) + cleanup.invoke(testObject, testObject); + } catch(IllegalAccessException | + IllegalArgumentException | + InvocationTargetException e) { + throw new RuntimeException(e); + } + } + } + public static + class TestMethods extends ArrayList { + void addIfTestMethod(Method m) { + if(m.getAnnotation(Test.class) == null) + return; + if(!(m.getReturnType().equals(boolean.class) || + m.getReturnType().equals(void.class))) + throw new RuntimeException("@Test method" + + " must return boolean or void"); + m.setAccessible(true); // If it's private, etc. + add(m); + } + } + private static + Method checkForCreatorMethod(Method m) { + if(m.getAnnotation(TestObjectCreate.class) == null) + return null; + if(!m.getReturnType().equals(testClass)) + throw new RuntimeException("@TestObjectCreate " + + "must return instance of Class to be tested"); + if((m.getModifiers() & + java.lang.reflect.Modifier.STATIC) < 1) + throw new RuntimeException("@TestObjectCreate " + + "must be static."); + m.setAccessible(true); + return m; + } + private static + Method checkForCleanupMethod(Method m) { + if(m.getAnnotation(TestObjectCleanup.class) == null) + return null; + if(!m.getReturnType().equals(void.class)) + throw new RuntimeException("@TestObjectCleanup " + + "must return void"); + if((m.getModifiers() & + java.lang.reflect.Modifier.STATIC) < 1) + throw new RuntimeException("@TestObjectCleanup " + + "must be static."); + if(m.getParameterTypes().length == 0 || + m.getParameterTypes()[0] != testClass) + throw new RuntimeException("@TestObjectCleanup " + + "must take an argument of the tested type."); + m.setAccessible(true); + return m; + } + private static Object + createTestObject(Method creator) { + if(creator != null) { + try { + return creator.invoke(testClass); + } catch(IllegalAccessException | + IllegalArgumentException | + InvocationTargetException e) { + throw new RuntimeException("Couldn't run " + + "@TestObject (creator) method."); + } + } else { // Use the no-arg constructor: + try { + return testClass + .getConstructor().newInstance(); + } catch(InstantiationException | + NoSuchMethodException | + InvocationTargetException | + IllegalAccessException e) { + throw new RuntimeException( + "Couldn't create a test object. " + + "Try using a @TestObject method."); + } + } + } +} diff --git a/code/onjava/atunit/ClassNameFinder.java b/code/onjava/atunit/ClassNameFinder.java new file mode 100644 index 00000000..3fef7faf --- /dev/null +++ b/code/onjava/atunit/ClassNameFinder.java @@ -0,0 +1,180 @@ +// onjava/atunit/ClassNameFinder.java +// (c)2020 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. +// {java onjava.atunit.ClassNameFinder} +package onjava.atunit; +import java.io.*; +import java.nio.file.*; +import java.util.*; +import onjava.*; + +public class ClassNameFinder { + public static String thisClass(byte[] classBytes) { + Map offsetTable = new HashMap<>(); + Map classNameTable = + new HashMap<>(); + try { + DataInputStream data = new DataInputStream( + new ByteArrayInputStream(classBytes)); + int magic = data.readInt(); // 0xcafebabe + int minorVersion = data.readShort(); + int majorVersion = data.readShort(); + int constantPoolCount = data.readShort(); + int[] constantPool = new int[constantPoolCount]; + for(int i = 1; i < constantPoolCount; i++) { + int tag = data.read(); + // int tableSize; + switch(tag) { + case 1: // UTF + int length = data.readShort(); + char[] bytes = new char[length]; + for(int k = 0; k < bytes.length; k++) + bytes[k] = (char)data.read(); + String className = new String(bytes); + classNameTable.put(i, className); + break; + case 5: // LONG + case 6: // DOUBLE + data.readLong(); // discard 8 bytes + i++; // Special skip necessary + break; + case 7: // CLASS + int offset = data.readShort(); + offsetTable.put(i, offset); + break; + case 8: // STRING + data.readShort(); // discard 2 bytes + break; + case 3: // INTEGER + case 4: // FLOAT + case 9: // FIELD_REF + case 10: // METHOD_REF + case 11: // INTERFACE_METHOD_REF + case 12: // NAME_AND_TYPE + case 18: // Invoke Dynamic + data.readInt(); // discard 4 bytes + break; + case 15: // Method Handle + data.readByte(); + data.readShort(); + break; + case 16: // Method Type + data.readShort(); + break; + default: + throw + new RuntimeException("Bad tag " + tag); + } + } + short accessFlags = data.readShort(); + String access = (accessFlags & 0x0001) == 0 ? + "nonpublic:" : "public:"; + int thisClass = data.readShort(); + int superClass = data.readShort(); + return access + classNameTable.get( + offsetTable.get(thisClass)).replace('/', '.'); + } catch(IOException | RuntimeException e) { + throw new RuntimeException(e); + } + } + // Demonstration: + public static void + main(String[] args) throws Exception { + PathMatcher matcher = FileSystems.getDefault() + .getPathMatcher("glob:**/*.class"); + // Walk the entire tree: + Files.walk(Paths.get(".")) + .filter(matcher::matches) + .map(p -> { + try { + return thisClass(Files.readAllBytes(p)); + } catch(Exception e) { + throw new RuntimeException(e); + } + }) + .filter(s -> s.startsWith("public:")) + // .filter(s -> s.indexOf('$') >= 0) + .map(s -> s.split(":")[1]) + .filter(s -> !s.startsWith("enums.")) + .filter(s -> s.contains(".")) + .forEach(System.out::println); + } +} +/* Output: +onjava.ArrayShow +onjava.atunit.AtUnit$TestMethods +onjava.atunit.AtUnit +onjava.atunit.ClassNameFinder +onjava.atunit.Test +onjava.atunit.TestObjectCleanup +onjava.atunit.TestObjectCreate +onjava.atunit.TestProperty +onjava.BasicSupplier +onjava.CollectionMethodDifferences +onjava.ConvertTo +onjava.Count$Boolean +onjava.Count$Byte +onjava.Count$Character +onjava.Count$Double +onjava.Count$Float +onjava.Count$Integer +onjava.Count$Long +onjava.Count$Pboolean +onjava.Count$Pbyte +onjava.Count$Pchar +onjava.Count$Pdouble +onjava.Count$Pfloat +onjava.Count$Pint +onjava.Count$Plong +onjava.Count$Pshort +onjava.Count$Short +onjava.Count +onjava.CountingIntegerList +onjava.CountMap +onjava.Countries +onjava.Enums +onjava.FillMap +onjava.HTMLColors +onjava.MouseClick +onjava.Nap +onjava.Null +onjava.Operations +onjava.OSExecute +onjava.OSExecuteException +onjava.Pair +onjava.ProcessFiles$Strategy +onjava.ProcessFiles +onjava.Rand$Boolean +onjava.Rand$Byte +onjava.Rand$Character +onjava.Rand$Double +onjava.Rand$Float +onjava.Rand$Integer +onjava.Rand$Long +onjava.Rand$Pboolean +onjava.Rand$Pbyte +onjava.Rand$Pchar +onjava.Rand$Pdouble +onjava.Rand$Pfloat +onjava.Rand$Pint +onjava.Rand$Plong +onjava.Rand$Pshort +onjava.Rand$Short +onjava.Rand$String +onjava.Rand +onjava.Range +onjava.Repeat +onjava.RmDir +onjava.Sets +onjava.Stack +onjava.Suppliers +onjava.TimedAbort +onjava.Timer +onjava.Tuple +onjava.Tuple2 +onjava.Tuple3 +onjava.Tuple4 +onjava.Tuple5 +onjava.TypeCounter +*/ diff --git a/code/onjava/atunit/Test.java b/code/onjava/atunit/Test.java new file mode 100644 index 00000000..314dce9b --- /dev/null +++ b/code/onjava/atunit/Test.java @@ -0,0 +1,11 @@ +// onjava/atunit/Test.java +// (c)2020 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. +// The @Test tag +package onjava.atunit; +import java.lang.annotation.*; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Test {} diff --git a/code/onjava/atunit/TestObjectCleanup.java b/code/onjava/atunit/TestObjectCleanup.java new file mode 100644 index 00000000..52231177 --- /dev/null +++ b/code/onjava/atunit/TestObjectCleanup.java @@ -0,0 +1,11 @@ +// onjava/atunit/TestObjectCleanup.java +// (c)2020 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. +// The @Unit @TestObjectCleanup tag +package onjava.atunit; +import java.lang.annotation.*; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface TestObjectCleanup {} diff --git a/code/onjava/atunit/TestObjectCreate.java b/code/onjava/atunit/TestObjectCreate.java new file mode 100644 index 00000000..f8b43a09 --- /dev/null +++ b/code/onjava/atunit/TestObjectCreate.java @@ -0,0 +1,11 @@ +// onjava/atunit/TestObjectCreate.java +// (c)2020 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. +// The @Unit @TestObjectCreate tag +package onjava.atunit; +import java.lang.annotation.*; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface TestObjectCreate {} diff --git a/code/onjava/atunit/TestProperty.java b/code/onjava/atunit/TestProperty.java new file mode 100644 index 00000000..4e09cf95 --- /dev/null +++ b/code/onjava/atunit/TestProperty.java @@ -0,0 +1,12 @@ +// onjava/atunit/TestProperty.java +// (c)2020 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. +// The @Unit @TestProperty tag +package onjava.atunit; +import java.lang.annotation.*; + +// Both fields and methods can be tagged as properties: +@Target({ElementType.FIELD, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface TestProperty {} diff --git a/code/operators/AllOps.java b/code/operators/AllOps.java new file mode 100644 index 00000000..bb94e870 --- /dev/null +++ b/code/operators/AllOps.java @@ -0,0 +1,411 @@ +// operators/AllOps.java +// (c)2020 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. +// Tests all operators on all primitive data types +// to show which ones are accepted by the Java compiler + +public class AllOps { + // To accept the results of a boolean test: + void f(boolean b) {} + void boolTest(boolean x, boolean y) { + // Arithmetic operators: + //- x = x * y; + //- x = x / y; + //- x = x % y; + //- x = x + y; + //- x = x - y; + //- x++; + //- x--; + //- x = +y; + //- x = -y; + // Relational and logical: + //- f(x > y); + //- f(x >= y); + //- f(x < y); + //- f(x <= y); + f(x == y); + f(x != y); + f(!y); + x = x && y; + x = x || y; + // Bitwise operators: + //- x = ~y; + x = x & y; + x = x | y; + x = x ^ y; + //- x = x << 1; + //- x = x >> 1; + //- x = x >>> 1; + // Compound assignment: + //- x += y; + //- x -= y; + //- x *= y; + //- x /= y; + //- x %= y; + //- x <<= 1; + //- x >>= 1; + //- x >>>= 1; + x &= y; + x ^= y; + x |= y; + // Casting: + //- char c = (char)x; + //- byte b = (byte)x; + //- short s = (short)x; + //- int i = (int)x; + //- long l = (long)x; + //- float f = (float)x; + //- double d = (double)x; + } + void charTest(char x, char y) { + // Arithmetic operators: + x = (char)(x * y); + x = (char)(x / y); + x = (char)(x % y); + x = (char)(x + y); + x = (char)(x - y); + x++; + x--; + x = (char) + y; + x = (char) - y; + // Relational and logical: + f(x > y); + f(x >= y); + f(x < y); + f(x <= y); + f(x == y); + f(x != y); + //- f(!x); + //- f(x && y); + //- f(x || y); + // Bitwise operators: + x= (char)~y; + x = (char)(x & y); + x = (char)(x | y); + x = (char)(x ^ y); + x = (char)(x << 1); + x = (char)(x >> 1); + x = (char)(x >>> 1); + // Compound assignment: + x += y; + x -= y; + x *= y; + x /= y; + x %= y; + x <<= 1; + x >>= 1; + x >>>= 1; + x &= y; + x ^= y; + x |= y; + // Casting: + //- boolean bl = (boolean)x; + byte b = (byte)x; + short s = (short)x; + int i = (int)x; + long l = (long)x; + float f = (float)x; + double d = (double)x; + } + void byteTest(byte x, byte y) { + // Arithmetic operators: + x = (byte)(x* y); + x = (byte)(x / y); + x = (byte)(x % y); + x = (byte)(x + y); + x = (byte)(x - y); + x++; + x--; + x = (byte) + y; + x = (byte) - y; + // Relational and logical: + f(x > y); + f(x >= y); + f(x < y); + f(x <= y); + f(x == y); + f(x != y); + //- f(!x); + //- f(x && y); + //- f(x || y); + // Bitwise operators: + x = (byte)~y; + x = (byte)(x & y); + x = (byte)(x | y); + x = (byte)(x ^ y); + x = (byte)(x << 1); + x = (byte)(x >> 1); + x = (byte)(x >>> 1); + // Compound assignment: + x += y; + x -= y; + x *= y; + x /= y; + x %= y; + x <<= 1; + x >>= 1; + x >>>= 1; + x &= y; + x ^= y; + x |= y; + // Casting: + //- boolean bl = (boolean)x; + char c = (char)x; + short s = (short)x; + int i = (int)x; + long l = (long)x; + float f = (float)x; + double d = (double)x; + } + void shortTest(short x, short y) { + // Arithmetic operators: + x = (short)(x * y); + x = (short)(x / y); + x = (short)(x % y); + x = (short)(x + y); + x = (short)(x - y); + x++; + x--; + x = (short) + y; + x = (short) - y; + // Relational and logical: + f(x > y); + f(x >= y); + f(x < y); + f(x <= y); + f(x == y); + f(x != y); + //- f(!x); + //- f(x && y); + //- f(x || y); + // Bitwise operators: + x = (short) ~ y; + x = (short)(x & y); + x = (short)(x | y); + x = (short)(x ^ y); + x = (short)(x << 1); + x = (short)(x >> 1); + x = (short)(x >>> 1); + // Compound assignment: + x += y; + x -= y; + x *= y; + x /= y; + x %= y; + x <<= 1; + x >>= 1; + x >>>= 1; + x &= y; + x ^= y; + x |= y; + // Casting: + //- boolean bl = (boolean)x; + char c = (char)x; + byte b = (byte)x; + int i = (int)x; + long l = (long)x; + float f = (float)x; + double d = (double)x; + } + void intTest(int x, int y) { + // Arithmetic operators: + x = x * y; + x = x / y; + x = x % y; + x = x + y; + x = x - y; + x++; + x--; + x = +y; + x = -y; + // Relational and logical: + f(x > y); + f(x >= y); + f(x < y); + f(x <= y); + f(x == y); + f(x != y); + //- f(!x); + //- f(x && y); + //- f(x || y); + // Bitwise operators: + x = ~y; + x = x & y; + x = x | y; + x = x ^ y; + x = x << 1; + x = x >> 1; + x = x >>> 1; + // Compound assignment: + x += y; + x -= y; + x *= y; + x /= y; + x %= y; + x <<= 1; + x >>= 1; + x >>>= 1; + x &= y; + x ^= y; + x |= y; + // Casting: + //- boolean bl = (boolean)x; + char c = (char)x; + byte b = (byte)x; + short s = (short)x; + long l = (long)x; + float f = (float)x; + double d = (double)x; + } + void longTest(long x, long y) { + // Arithmetic operators: + x = x * y; + x = x / y; + x = x % y; + x = x + y; + x = x - y; + x++; + x--; + x = +y; + x = -y; + // Relational and logical: + f(x > y); + f(x >= y); + f(x < y); + f(x <= y); + f(x == y); + f(x != y); + //- f(!x); + //- f(x && y); + //- f(x || y); + // Bitwise operators: + x = ~y; + x = x & y; + x = x | y; + x = x ^ y; + x = x << 1; + x = x >> 1; + x = x >>> 1; + // Compound assignment: + x += y; + x -= y; + x *= y; + x /= y; + x %= y; + x <<= 1; + x >>= 1; + x >>>= 1; + x &= y; + x ^= y; + x |= y; + // Casting: + //- boolean bl = (boolean)x; + char c = (char)x; + byte b = (byte)x; + short s = (short)x; + int i = (int)x; + float f = (float)x; + double d = (double)x; + } + void floatTest(float x, float y) { + // Arithmetic operators: + x = x * y; + x = x / y; + x = x % y; + x = x + y; + x = x - y; + x++; + x--; + x = +y; + x = -y; + // Relational and logical: + f(x > y); + f(x >= y); + f(x < y); + f(x <= y); + f(x == y); + f(x != y); + //- f(!x); + //- f(x && y); + //- f(x || y); + // Bitwise operators: + //- x = ~y; + //- x = x & y; + //- x = x | y; + //- x = x ^ y; + //- x = x << 1; + //- x = x >> 1; + //- x = x >>> 1; + // Compound assignment: + x += y; + x -= y; + x *= y; + x /= y; + x %= y; + //- x <<= 1; + //- x >>= 1; + //- x >>>= 1; + //- x &= y; + //- x ^= y; + //- x |= y; + // Casting: + //- boolean bl = (boolean)x; + char c = (char)x; + byte b = (byte)x; + short s = (short)x; + int i = (int)x; + long l = (long)x; + double d = (double)x; + } + void doubleTest(double x, double y) { + // Arithmetic operators: + x = x * y; + x = x / y; + x = x % y; + x = x + y; + x = x - y; + x++; + x--; + x = +y; + x = -y; + // Relational and logical: + f(x > y); + f(x >= y); + f(x < y); + f(x <= y); + f(x == y); + f(x != y); + //- f(!x); + //- f(x && y); + //- f(x || y); + // Bitwise operators: + //- x = ~y; + //- x = x & y; + //- x = x | y; + //- x = x ^ y; + //- x = x << 1; + //- x = x >> 1; + //- x = x >>> 1; + // Compound assignment: + x += y; + x -= y; + x *= y; + x /= y; + x %= y; + //- x <<= 1; + //- x >>= 1; + //- x >>>= 1; + //- x &= y; + //- x ^= y; + //- x |= y; + // Casting: + //- boolean bl = (boolean)x; + char c = (char)x; + byte b = (byte)x; + short s = (short)x; + int i = (int)x; + long l = (long)x; + float f = (float)x; + } +} diff --git a/code/operators/Assignment.java b/code/operators/Assignment.java new file mode 100644 index 00000000..7a573a39 --- /dev/null +++ b/code/operators/Assignment.java @@ -0,0 +1,31 @@ +// operators/Assignment.java +// (c)2020 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. +// Assignment with objects is a bit tricky + +class Tank { + int level; +} + +public class Assignment { + public static void main(String[] args) { + Tank t1 = new Tank(); + Tank t2 = new Tank(); + t1.level = 9; + t2.level = 47; + System.out.println("1: t1.level: " + t1.level + + ", t2.level: " + t2.level); + t1 = t2; + System.out.println("2: t1.level: " + t1.level + + ", t2.level: " + t2.level); + t1.level = 27; + System.out.println("3: t1.level: " + t1.level + + ", t2.level: " + t2.level); + } +} +/* Output: +1: t1.level: 9, t2.level: 47 +2: t1.level: 47, t2.level: 47 +3: t1.level: 27, t2.level: 27 +*/ diff --git a/code/operators/AutoInc.java b/code/operators/AutoInc.java new file mode 100644 index 00000000..835875de --- /dev/null +++ b/code/operators/AutoInc.java @@ -0,0 +1,27 @@ +// operators/AutoInc.java +// (c)2020 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. +// Demonstrates the ++ and -- operators + +public class AutoInc { + public static void main(String[] args) { + int i = 1; + System.out.println("i: " + i); + System.out.println("++i: " + ++i); // Pre-increment + System.out.println("i++: " + i++); // Post-increment + System.out.println("i: " + i); + System.out.println("--i: " + --i); // Pre-decrement + System.out.println("i--: " + i--); // Post-decrement + System.out.println("i: " + i); + } +} +/* Output: +i: 1 +++i: 2 +i++: 2 +i: 3 +--i: 2 +i--: 2 +i: 1 +*/ diff --git a/code/operators/BitManipulation.java b/code/operators/BitManipulation.java new file mode 100644 index 00000000..dc30c442 --- /dev/null +++ b/code/operators/BitManipulation.java @@ -0,0 +1,98 @@ +// operators/BitManipulation.java +// (c)2020 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. +// Using the bitwise operators +import java.util.*; + +public class BitManipulation { + public static void main(String[] args) { + Random rand = new Random(47); + int i = rand.nextInt(); + int j = rand.nextInt(); + printBinaryInt("-1", -1); + printBinaryInt("+1", +1); + int maxpos = 2147483647; + printBinaryInt("maxpos", maxpos); + int maxneg = -2147483648; + printBinaryInt("maxneg", maxneg); + printBinaryInt("i", i); + printBinaryInt("~i", ~i); + printBinaryInt("-i", -i); + printBinaryInt("j", j); + printBinaryInt("i & j", i & j); + printBinaryInt("i | j", i | j); + printBinaryInt("i ^ j", i ^ j); + printBinaryInt("i << 5", i << 5); + printBinaryInt("i >> 5", i >> 5); + printBinaryInt("(~i) >> 5", (~i) >> 5); + printBinaryInt("i >>> 5", i >>> 5); + printBinaryInt("(~i) >>> 5", (~i) >>> 5); + + long l = rand.nextLong(); + long m = rand.nextLong(); + printBinaryLong("-1L", -1L); + printBinaryLong("+1L", +1L); + long ll = 9223372036854775807L; + printBinaryLong("maxpos", ll); + long lln = -9223372036854775808L; + printBinaryLong("maxneg", lln); + printBinaryLong("l", l); + printBinaryLong("~l", ~l); + printBinaryLong("-l", -l); + printBinaryLong("m", m); + printBinaryLong("l & m", l & m); + printBinaryLong("l | m", l | m); + printBinaryLong("l ^ m", l ^ m); + printBinaryLong("l << 5", l << 5); + printBinaryLong("l >> 5", l >> 5); + printBinaryLong("(~l) >> 5", (~l) >> 5); + printBinaryLong("l >>> 5", l >>> 5); + printBinaryLong("(~l) >>> 5", (~l) >>> 5); + } + static void printBinaryInt(String s, int i) { + System.out.println( + s + ", int: " + i + ", binary:\n " + + Integer.toBinaryString(i)); + } + static void printBinaryLong(String s, long l) { + System.out.println( + s + ", long: " + l + ", binary:\n " + + Long.toBinaryString(l)); + } +} +/* Output: (First 32 Lines) +-1, int: -1, binary: + 11111111111111111111111111111111 ++1, int: 1, binary: + 1 +maxpos, int: 2147483647, binary: + 1111111111111111111111111111111 +maxneg, int: -2147483648, binary: + 10000000000000000000000000000000 +i, int: -1172028779, binary: + 10111010001001000100001010010101 +~i, int: 1172028778, binary: + 1000101110110111011110101101010 +-i, int: 1172028779, binary: + 1000101110110111011110101101011 +j, int: 1717241110, binary: + 1100110010110110000010100010110 +i & j, int: 570425364, binary: + 100010000000000000000000010100 +i | j, int: -25213033, binary: + 11111110011111110100011110010111 +i ^ j, int: -595638397, binary: + 11011100011111110100011110000011 +i << 5, int: 1149784736, binary: + 1000100100010000101001010100000 +i >> 5, int: -36625900, binary: + 11111101110100010010001000010100 +(~i) >> 5, int: 36625899, binary: + 10001011101101110111101011 +i >>> 5, int: 97591828, binary: + 101110100010010001000010100 +(~i) >>> 5, int: 36625899, binary: + 10001011101101110111101011 + ... +*/ diff --git a/code/operators/Bool.java b/code/operators/Bool.java new file mode 100644 index 00000000..e9984adb --- /dev/null +++ b/code/operators/Bool.java @@ -0,0 +1,42 @@ +// operators/Bool.java +// (c)2020 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. +// Relational and logical operators +import java.util.*; + +public class Bool { + public static void main(String[] args) { + Random rand = new Random(47); + int i = rand.nextInt(100); + int j = rand.nextInt(100); + System.out.println("i = " + i); + System.out.println("j = " + j); + System.out.println("i > j is " + (i > j)); + System.out.println("i < j is " + (i < j)); + System.out.println("i >= j is " + (i >= j)); + System.out.println("i <= j is " + (i <= j)); + System.out.println("i == j is " + (i == j)); + System.out.println("i != j is " + (i != j)); + // Treating an int as a boolean is not legal Java: + //- System.out.println("i && j is " + (i && j)); + //- System.out.println("i || j is " + (i || j)); + //- System.out.println("!i is " + !i); + System.out.println("(i < 10) && (j < 10) is " + + ((i < 10) && (j < 10)) ); + System.out.println("(i < 10) || (j < 10) is " + + ((i < 10) || (j < 10)) ); + } +} +/* Output: +i = 58 +j = 55 +i > j is true +i < j is false +i >= j is true +i <= j is false +i == j is false +i != j is true +(i < 10) && (j < 10) is false +(i < 10) || (j < 10) is false +*/ diff --git a/code/operators/Casting.java b/code/operators/Casting.java new file mode 100644 index 00000000..337b24fd --- /dev/null +++ b/code/operators/Casting.java @@ -0,0 +1,16 @@ +// operators/Casting.java +// (c)2020 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. + +public class Casting { + public static void main(String[] args) { + int i = 200; + long lng = (long)i; + lng = i; // "Widening," so a cast is not required + long lng2 = (long)200; + lng2 = 200; + // A "narrowing conversion": + i = (int)lng2; // Cast required + } +} diff --git a/code/operators/CastingNumbers.java b/code/operators/CastingNumbers.java new file mode 100644 index 00000000..a6c04c6e --- /dev/null +++ b/code/operators/CastingNumbers.java @@ -0,0 +1,23 @@ +// operators/CastingNumbers.java +// (c)2020 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 happens when you cast a float +// or double to an integral value? + +public class CastingNumbers { + public static void main(String[] args) { + double above = 0.7, below = 0.4; + float fabove = 0.7f, fbelow = 0.4f; + System.out.println("(int)above: " + (int)above); + System.out.println("(int)below: " + (int)below); + System.out.println("(int)fabove: " + (int)fabove); + System.out.println("(int)fbelow: " + (int)fbelow); + } +} +/* Output: +(int)above: 0 +(int)below: 0 +(int)fabove: 0 +(int)fbelow: 0 +*/ diff --git a/code/operators/EqualsMethod.java b/code/operators/EqualsMethod.java new file mode 100644 index 00000000..f55b1b57 --- /dev/null +++ b/code/operators/EqualsMethod.java @@ -0,0 +1,15 @@ +// operators/EqualsMethod.java +// (c)2020 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. + +public class EqualsMethod { + public static void main(String[] args) { + Integer n1 = 47; + Integer n2 = 47; + System.out.println(n1.equals(n2)); + } +} +/* Output: +true +*/ diff --git a/code/operators/EqualsMethod2.java b/code/operators/EqualsMethod2.java new file mode 100644 index 00000000..21393060 --- /dev/null +++ b/code/operators/EqualsMethod2.java @@ -0,0 +1,21 @@ +// operators/EqualsMethod2.java +// (c)2020 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. +// Default equals() does not compare contents + +class Value { + int i; +} + +public class EqualsMethod2 { + public static void main(String[] args) { + Value v1 = new Value(); + Value v2 = new Value(); + v1.i = v2.i = 100; + System.out.println(v1.equals(v2)); + } +} +/* Output: +false +*/ diff --git a/code/operators/Equivalence.java b/code/operators/Equivalence.java new file mode 100644 index 00000000..cef07d64 --- /dev/null +++ b/code/operators/Equivalence.java @@ -0,0 +1,17 @@ +// operators/Equivalence.java +// (c)2020 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. + +public class Equivalence { + public static void main(String[] args) { + Integer n1 = 47; + Integer n2 = 47; + System.out.println(n1 == n2); + System.out.println(n1 != n2); + } +} +/* Output: +true +false +*/ diff --git a/code/operators/Exponents.java b/code/operators/Exponents.java new file mode 100644 index 00000000..924340df --- /dev/null +++ b/code/operators/Exponents.java @@ -0,0 +1,21 @@ +// operators/Exponents.java +// (c)2020 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. +// "e" means "10 to the power." + +public class Exponents { + public static void main(String[] args) { + // Uppercase and lowercase 'e' are the same: + float expFloat = 1.39e-43f; + expFloat = 1.39E-43f; + System.out.println(expFloat); + double expDouble = 47e47d; // 'd' is optional + double expDouble2 = 47e47; // Automatically double + System.out.println(expDouble); + } +} +/* Output: +1.39E-43 +4.7E48 +*/ diff --git a/code/operators/Literals.java b/code/operators/Literals.java new file mode 100644 index 00000000..ad00e0b8 --- /dev/null +++ b/code/operators/Literals.java @@ -0,0 +1,61 @@ +// operators/Literals.java +// (c)2020 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. + +public class Literals { + public static void main(String[] args) { + int i1 = 0x2f; // Hexadecimal (lowercase) + System.out.println( + "i1: " + Integer.toBinaryString(i1)); + int i2 = 0X2F; // Hexadecimal (uppercase) + System.out.println( + "i2: " + Integer.toBinaryString(i2)); + int i3 = 0177; // Octal (leading zero) + System.out.println( + "i3: " + Integer.toBinaryString(i3)); + char c = 0xffff; // max char hex value + System.out.println( + "c: " + Integer.toBinaryString(c)); + byte b = 0x7f; // max byte hex value 10101111; + System.out.println( + "b: " + Integer.toBinaryString(b)); + short s = 0x7fff; // max short hex value + System.out.println( + "s: " + Integer.toBinaryString(s)); + long n1 = 200L; // long suffix + long n2 = 200l; // long suffix (can be confusing) + long n3 = 200; + // Java 7 Binary Literals: + byte blb = (byte)0b00110101; + System.out.println( + "blb: " + Integer.toBinaryString(blb)); + short bls = (short)0B0010111110101111; + System.out.println( + "bls: " + Integer.toBinaryString(bls)); + int bli = 0b00101111101011111010111110101111; + System.out.println( + "bli: " + Integer.toBinaryString(bli)); + long bll = 0b00101111101011111010111110101111; + System.out.println( + "bll: " + Long.toBinaryString(bll)); + float f1 = 1; + float f2 = 1F; // float suffix + float f3 = 1f; // float suffix + double d1 = 1d; // double suffix + double d2 = 1D; // double suffix + // (Hex and Octal also work with long) + } +} +/* Output: +i1: 101111 +i2: 101111 +i3: 1111111 +c: 1111111111111111 +b: 1111111 +s: 111111111111111 +blb: 110101 +bls: 10111110101111 +bli: 101111101011111010111110101111 +bll: 101111101011111010111110101111 +*/ diff --git a/code/operators/MathOps.java b/code/operators/MathOps.java new file mode 100644 index 00000000..a9b08938 --- /dev/null +++ b/code/operators/MathOps.java @@ -0,0 +1,75 @@ +// operators/MathOps.java +// (c)2020 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. +// The mathematical operators +import java.util.*; + +public class MathOps { + public static void main(String[] args) { + // Create a seeded random number generator: + Random rand = new Random(47); + int i, j, k; + // Choose value from 1 to 100: + j = rand.nextInt(100) + 1; + System.out.println("j : " + j); + k = rand.nextInt(100) + 1; + System.out.println("k : " + k); + i = j + k; + System.out.println("j + k : " + i); + i = j - k; + System.out.println("j - k : " + i); + i = k / j; + System.out.println("k / j : " + i); + i = k * j; + System.out.println("k * j : " + i); + i = k % j; + System.out.println("k % j : " + i); + j %= k; + System.out.println("j %= k : " + j); + // Floating-point number tests: + float u, v, w; // Applies to doubles, too + v = rand.nextFloat(); + System.out.println("v : " + v); + w = rand.nextFloat(); + System.out.println("w : " + w); + u = v + w; + System.out.println("v + w : " + u); + u = v - w; + System.out.println("v - w : " + u); + u = v * w; + System.out.println("v * w : " + u); + u = v / w; + System.out.println("v / w : " + u); + // The following also works for char, + // byte, short, int, long, and double: + u += v; + System.out.println("u += v : " + u); + u -= v; + System.out.println("u -= v : " + u); + u *= v; + System.out.println("u *= v : " + u); + u /= v; + System.out.println("u /= v : " + u); + } +} +/* Output: +j : 59 +k : 56 +j + k : 115 +j - k : 3 +k / j : 0 +k * j : 3304 +k % j : 56 +j %= k : 3 +v : 0.5309454 +w : 0.0534122 +v + w : 0.5843576 +v - w : 0.47753322 +v * w : 0.028358962 +v / w : 9.940527 +u += v : 10.471473 +u -= v : 9.940527 +u *= v : 5.2778773 +u /= v : 9.940527 +*/ diff --git a/code/operators/Overflow.java b/code/operators/Overflow.java new file mode 100644 index 00000000..851c1456 --- /dev/null +++ b/code/operators/Overflow.java @@ -0,0 +1,18 @@ +// operators/Overflow.java +// (c)2020 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. +// Surprise! Java lets you overflow + +public class Overflow { + public static void main(String[] args) { + int big = Integer.MAX_VALUE; + System.out.println("big = " + big); + int bigger = big * 4; + System.out.println("bigger = " + bigger); + } +} +/* Output: +big = 2147483647 +bigger = -4 +*/ diff --git a/code/operators/PassObject.java b/code/operators/PassObject.java new file mode 100644 index 00000000..af53ab56 --- /dev/null +++ b/code/operators/PassObject.java @@ -0,0 +1,27 @@ +// operators/PassObject.java +// (c)2020 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. +// Passing objects to methods might not be +// what you're used to + +class Letter { + char c; +} + +public class PassObject { + static void f(Letter y) { + y.c = 'z'; + } + public static void main(String[] args) { + Letter x = new Letter(); + x.c = 'a'; + System.out.println("1: x.c: " + x.c); + f(x); + System.out.println("2: x.c: " + x.c); + } +} +/* Output: +1: x.c: a +2: x.c: z +*/ diff --git a/code/operators/Precedence.java b/code/operators/Precedence.java new file mode 100644 index 00000000..f0f8140c --- /dev/null +++ b/code/operators/Precedence.java @@ -0,0 +1,18 @@ +// operators/Precedence.java +// (c)2020 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. + +public class Precedence { + public static void main(String[] args) { + int x = 1, y = 2, z = 3; + int a = x + y - 2/2 + z; // [1] + int b = x + (y - 2)/(2 + z); // [2] + System.out.println("a = " + a); + System.out.println("b = " + b); + } +} +/* Output: +a = 5 +b = 1 +*/ diff --git a/code/operators/RoundingNumbers.java b/code/operators/RoundingNumbers.java new file mode 100644 index 00000000..e46a2056 --- /dev/null +++ b/code/operators/RoundingNumbers.java @@ -0,0 +1,26 @@ +// operators/RoundingNumbers.java +// (c)2020 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. +// Rounding floats and doubles + +public class RoundingNumbers { + public static void main(String[] args) { + double above = 0.7, below = 0.4; + float fabove = 0.7f, fbelow = 0.4f; + System.out.println( + "Math.round(above): " + Math.round(above)); + System.out.println( + "Math.round(below): " + Math.round(below)); + System.out.println( + "Math.round(fabove): " + Math.round(fabove)); + System.out.println( + "Math.round(fbelow): " + Math.round(fbelow)); + } +} +/* Output: +Math.round(above): 1 +Math.round(below): 0 +Math.round(fabove): 1 +Math.round(fbelow): 0 +*/ diff --git a/code/operators/ShortCircuit.java b/code/operators/ShortCircuit.java new file mode 100644 index 00000000..8fc96711 --- /dev/null +++ b/code/operators/ShortCircuit.java @@ -0,0 +1,34 @@ +// operators/ShortCircuit.java +// (c)2020 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. +// Short-circuiting behavior with logical operators + +public class ShortCircuit { + static boolean test1(int val) { + System.out.println("test1(" + val + ")"); + System.out.println("result: " + (val < 1)); + return val < 1; + } + static boolean test2(int val) { + System.out.println("test2(" + val + ")"); + System.out.println("result: " + (val < 2)); + return val < 2; + } + static boolean test3(int val) { + System.out.println("test3(" + val + ")"); + System.out.println("result: " + (val < 3)); + return val < 3; + } + public static void main(String[] args) { + boolean b = test1(0) && test2(2) && test3(2); + System.out.println("expression is " + b); + } +} +/* Output: +test1(0) +result: true +test2(2) +result: false +expression is false +*/ diff --git a/code/operators/StringOperators.java b/code/operators/StringOperators.java new file mode 100644 index 00000000..b1eb211f --- /dev/null +++ b/code/operators/StringOperators.java @@ -0,0 +1,24 @@ +// operators/StringOperators.java +// (c)2020 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. + +public class StringOperators { + public static void main(String[] args) { + int x = 0, y = 1, z = 2; + String s = "x, y, z "; + System.out.println(s + x + y + z); + // Converts x to a String: + System.out.println(x + " " + s); + s += "(summed) = "; // Concatenation operator + System.out.println(s + (x + y + z)); + // Shorthand for Integer.toString(): + System.out.println("" + x); + } +} +/* Output: +x, y, z 012 +0 x, y, z +x, y, z (summed) = 3 +0 +*/ diff --git a/code/operators/TernaryIfElse.java b/code/operators/TernaryIfElse.java new file mode 100644 index 00000000..d11d4e24 --- /dev/null +++ b/code/operators/TernaryIfElse.java @@ -0,0 +1,28 @@ +// operators/TernaryIfElse.java +// (c)2020 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. + +public class TernaryIfElse { + static int ternary(int i) { + return i < 10 ? i * 100 : i * 10; + } + static int standardIfElse(int i) { + if(i < 10) + return i * 100; + else + return i * 10; + } + public static void main(String[] args) { + System.out.println(ternary(9)); + System.out.println(ternary(10)); + System.out.println(standardIfElse(9)); + System.out.println(standardIfElse(10)); + } +} +/* Output: +900 +100 +900 +100 +*/ diff --git a/code/operators/URShift.java b/code/operators/URShift.java new file mode 100644 index 00000000..8d24f94b --- /dev/null +++ b/code/operators/URShift.java @@ -0,0 +1,42 @@ +// operators/URShift.java +// (c)2020 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. +// Test of unsigned right shift + +public class URShift { + public static void main(String[] args) { + int i = -1; + System.out.println(Integer.toBinaryString(i)); + i >>>= 10; + System.out.println(Integer.toBinaryString(i)); + long l = -1; + System.out.println(Long.toBinaryString(l)); + l >>>= 10; + System.out.println(Long.toBinaryString(l)); + short s = -1; + System.out.println(Integer.toBinaryString(s)); + s >>>= 10; + System.out.println(Integer.toBinaryString(s)); + byte b = -1; + System.out.println(Integer.toBinaryString(b)); + b >>>= 10; + System.out.println(Integer.toBinaryString(b)); + b = -1; + System.out.println(Integer.toBinaryString(b)); + System.out.println(Integer.toBinaryString(b>>>10)); + } +} +/* Output: +11111111111111111111111111111111 +1111111111111111111111 +1111111111111111111111111111111111111111111111111111111 +111111111 +111111111111111111111111111111111111111111111111111111 +11111111111111111111111111111111 +11111111111111111111111111111111 +11111111111111111111111111111111 +11111111111111111111111111111111 +11111111111111111111111111111111 +1111111111111111111111 +*/ diff --git a/code/operators/Underscores.java b/code/operators/Underscores.java new file mode 100644 index 00000000..4d78cd50 --- /dev/null +++ b/code/operators/Underscores.java @@ -0,0 +1,22 @@ +// operators/Underscores.java +// (c)2020 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. + +public class Underscores { + public static void main(String[] args) { + double d = 341_435_936.445_667; + System.out.println(d); + int bin = 0b0010_1111_1010_1111_1010_1111_1010_1111; + System.out.println(Integer.toBinaryString(bin)); + System.out.printf("%x%n", bin); // [1] + long hex = 0x7f_e9_b7_aa; + System.out.printf("%x%n", hex); + } +} +/* Output: +3.41435936445667E8 +101111101011111010111110101111 +2fafafaf +7fe9b7aa +*/ diff --git a/code/patterns/BoxObserver.java b/code/patterns/BoxObserver.java new file mode 100644 index 00000000..c6f9ec65 --- /dev/null +++ b/code/patterns/BoxObserver.java @@ -0,0 +1,94 @@ +// patterns/BoxObserver.java +// (c)2020 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. +// Demonstration of Observer pattern using +// Java's built-in observer classes. +// {ExcludeFromGradle} // Won't work under WSL2 +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import onjava.*; +import onjava.MouseClick; + +// You must inherit a new type of Observable: +@SuppressWarnings("deprecation") +class BoxObservable extends Observable { + @Override + public void notifyObservers(Object b) { + // Otherwise it won't propagate changes: + setChanged(); + super.notifyObservers(b); + } +} + +@SuppressWarnings("deprecation") +public class BoxObserver extends JFrame { + Observable notifier = new BoxObservable(); + public BoxObserver(int grid) { + setTitle("Demonstrates Observer pattern"); + Container cp = getContentPane(); + cp.setLayout(new GridLayout(grid, grid)); + for(int x = 0; x < grid; x++) + for(int y = 0; y < grid; y++) + cp.add(new OCBox(x, y, notifier)); + } + public static void main(String[] args) { + // For automated test runs: + // new TimedAbort(4); + int grid = 8; + if(args.length > 0) + grid = Integer.parseInt(args[0]); + JFrame f = new BoxObserver(grid); + f.setSize(500, 400); + f.setVisible(true); + f.setDefaultCloseOperation(DISPOSE_ON_CLOSE); + } +} + +@SuppressWarnings("deprecation") +class OCBox extends JPanel implements Observer { + Observable notifier; + int x, y; // Locations in grid + Color cColor = newColor(); + static final Color[] COLORS = { + Color.black, Color.blue, Color.cyan, + Color.darkGray, Color.gray, Color.green, + Color.lightGray, Color.magenta, + Color.orange, Color.pink, Color.red, + Color.white, Color.yellow + }; + static Color newColor() { + return COLORS[ + (int)(Math.random() * COLORS.length) + ]; + } + OCBox(int x, int y, Observable notifier) { + this.x = x; + this.y = y; + notifier.addObserver(this); + this.notifier = notifier; + addMouseListener((MouseClick) + e -> notifier.notifyObservers(OCBox.this)); + } + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + g.setColor(cColor); + Dimension s = getSize(); + g.fillRect(0, 0, s.width, s.height); + } + @Override + public void update(Observable o, Object arg) { + OCBox clicked = (OCBox)arg; + if(nextTo(clicked)) { + cColor = clicked.cColor; + repaint(); + } + } + private boolean nextTo(OCBox b) { + return Math.abs(x - b.x) <= 1 && + Math.abs(y - b.y) <= 1; + } +} diff --git a/code/patterns/CommandPattern.java b/code/patterns/CommandPattern.java new file mode 100644 index 00000000..f84533aa --- /dev/null +++ b/code/patterns/CommandPattern.java @@ -0,0 +1,19 @@ +// patterns/CommandPattern.java +// (c)2020 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. +import java.util.*; + +public class CommandPattern { + public static void main(String[] args) { + List macro = Arrays.asList( + () -> System.out.print("Hello "), + () -> System.out.print("World! "), + () -> System.out.print("I'm the command pattern!") + ); + macro.forEach(Runnable::run); + } +} +/* Output: +Hello World! I'm the command pattern! +*/ diff --git a/code/patterns/Facade.java b/code/patterns/Facade.java new file mode 100644 index 00000000..0c1accf2 --- /dev/null +++ b/code/patterns/Facade.java @@ -0,0 +1,24 @@ +// patterns/Facade.java +// (c)2020 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. + +class A { A(int x) {} } +class B { B(long x) {} } +class C { C(double x) {} } + +// Other classes that aren't exposed by the +// facade go here ... + +public class Facade { + static A makeA(int x) { return new A(x); } + static B makeB(long x) { return new B(x); } + static C makeC(double x) { return new C(x); } + public static void main(String[] args) { + // The client programmer gets the objects + // by calling the static methods: + A a = Facade.makeA(1); + B b = Facade.makeB(1); + C c = Facade.makeC(1.0); + } +} diff --git a/code/patterns/PaperScissorsRock.java b/code/patterns/PaperScissorsRock.java new file mode 100644 index 00000000..e7a7c44e --- /dev/null +++ b/code/patterns/PaperScissorsRock.java @@ -0,0 +1,135 @@ +// patterns/PaperScissorsRock.java +// (c)2020 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. +// Demonstration of multiple dispatching +import java.util.*; +import java.util.function.*; +import java.util.stream.*; +import onjava.*; +import static onjava.Tuple.*; + +enum Outcome { WIN, LOSE, DRAW } + +interface Item { + Outcome compete(Item it); + Outcome eval(Paper p); + Outcome eval(Scissors s); + Outcome eval(Rock r); +} + +class Paper implements Item { + @Override + public Outcome compete(Item it) { + return it.eval(this); + } + @Override + public Outcome eval(Paper p) { + return Outcome.DRAW; + } + @Override + public Outcome eval(Scissors s) { + return Outcome.WIN; + } + @Override + public Outcome eval(Rock r) { + return Outcome.LOSE; + } + @Override + public String toString() { return "Paper"; } +} + +class Scissors implements Item { + @Override + public Outcome compete(Item it) { + return it.eval(this); + } + @Override + public Outcome eval(Paper p) { + return Outcome.LOSE; + } + @Override + public Outcome eval(Scissors s) { + return Outcome.DRAW; + } + @Override + public Outcome eval(Rock r) { + return Outcome.WIN; + } + @Override + public String toString() { return "Scissors"; } +} + +class Rock implements Item { + @Override + public Outcome compete(Item it) { + return it.eval(this); + } + @Override + public Outcome eval(Paper p) { + return Outcome.WIN; + } + @Override + public Outcome eval(Scissors s) { + return Outcome.LOSE; + } + @Override + public Outcome eval(Rock r) { + return Outcome.DRAW; + } + @Override + public String toString() { return "Rock"; } +} + +class ItemFactory { + static List> items = + Arrays.asList( + Scissors::new, Paper::new, Rock::new); + static final int SZ = items.size(); + private static SplittableRandom rand = + new SplittableRandom(47); + public static Item newItem() { + return items.get(rand.nextInt(SZ)).get(); + } + public static Tuple2 newPair() { + return tuple(newItem(), newItem()); + } +} + +class Compete { + public static Outcome match(Tuple2 p) { + System.out.print(p.a1 + " -> " + p.a2 + " : "); + return p.a1.compete(p.a2); + } +} + +public class PaperScissorsRock { + public static void main(String[] args) { + Stream.generate(ItemFactory::newPair) + .limit(20) + .map(Compete::match) + .forEach(System.out::println); + } +} +/* Output: +Scissors -> Rock : LOSE +Scissors -> Paper : WIN +Rock -> Paper : LOSE +Rock -> Rock : DRAW +Rock -> Paper : LOSE +Paper -> Scissors : LOSE +Rock -> Paper : LOSE +Scissors -> Scissors : DRAW +Scissors -> Rock : LOSE +Scissors -> Paper : WIN +Scissors -> Rock : LOSE +Paper -> Scissors : LOSE +Rock -> Rock : DRAW +Scissors -> Scissors : DRAW +Paper -> Paper : DRAW +Scissors -> Paper : WIN +Scissors -> Rock : LOSE +Scissors -> Paper : WIN +Rock -> Paper : LOSE +Rock -> Scissors : WIN +*/ diff --git a/code/patterns/ProxyDemo.java b/code/patterns/ProxyDemo.java new file mode 100644 index 00000000..58b0e3a8 --- /dev/null +++ b/code/patterns/ProxyDemo.java @@ -0,0 +1,51 @@ +// patterns/ProxyDemo.java +// (c)2020 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. +// Simple demonstration of the Proxy pattern + +interface ProxyBase { + void f(); + void g(); + void h(); +} + +class Proxy implements ProxyBase { + private ProxyBase implementation; + Proxy() { + implementation = new Implementation(); + } + // Pass method calls to the implementation: + @Override + public void f() { implementation.f(); } + @Override + public void g() { implementation.g(); } + @Override + public void h() { implementation.h(); } +} + +class Implementation implements ProxyBase { + public void f() { + System.out.println("Implementation.f()"); + } + public void g() { + System.out.println("Implementation.g()"); + } + public void h() { + System.out.println("Implementation.h()"); + } +} + +public class ProxyDemo { + public static void main(String[] args) { + Proxy p = new Proxy(); + p.f(); + p.g(); + p.h(); + } +} +/* Output: +Implementation.f() +Implementation.g() +Implementation.h() +*/ diff --git a/code/patterns/ShapeFactory1.java b/code/patterns/ShapeFactory1.java new file mode 100644 index 00000000..dc6f8690 --- /dev/null +++ b/code/patterns/ShapeFactory1.java @@ -0,0 +1,39 @@ +// patterns/ShapeFactory1.java +// (c)2020 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. +// A simple static factory method +import java.util.*; +import java.util.stream.*; +import patterns.shapes.*; + +public class ShapeFactory1 implements FactoryMethod { + public Shape create(String type) { + switch(type) { + case "Circle": return new Circle(); + case "Square": return new Square(); + case "Triangle": return new Triangle(); + default: + throw new BadShapeCreation(type); + } + } + public static void main(String[] args) { + FactoryTest.test(new ShapeFactory1()); + } +} +/* Output: +Circle[0] draw +Circle[0] erase +Square[1] draw +Square[1] erase +Triangle[2] draw +Triangle[2] erase +Square[3] draw +Square[3] erase +Circle[4] draw +Circle[4] erase +Circle[5] draw +Circle[5] erase +Triangle[6] draw +Triangle[6] erase +*/ diff --git a/code/patterns/ShapeFactory2.java b/code/patterns/ShapeFactory2.java new file mode 100644 index 00000000..23881105 --- /dev/null +++ b/code/patterns/ShapeFactory2.java @@ -0,0 +1,54 @@ +// patterns/ShapeFactory2.java +// (c)2020 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. +import java.util.*; +import java.lang.reflect.*; +import java.util.stream.*; +import patterns.shapes.*; + +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(ClassNotFoundException | + NoSuchMethodException e) { + throw new BadShapeCreation(id); + } + } + public Shape create(String id) { + try { + return (Shape)factories + .computeIfAbsent(id, ShapeFactory2::load) + .newInstance(); + } catch(Exception e) { + throw new BadShapeCreation(id); + } + } + public static void main(String[] args) { + FactoryTest.test(new ShapeFactory2()); + } +} +/* Output: +loading Circle +Circle[0] draw +Circle[0] erase +loading Square +Square[1] draw +Square[1] erase +loading Triangle +Triangle[2] draw +Triangle[2] erase +Square[3] draw +Square[3] erase +Circle[4] draw +Circle[4] erase +Circle[5] draw +Circle[5] erase +Triangle[6] draw +Triangle[6] erase +*/ diff --git a/code/patterns/ShapeFactory3.java b/code/patterns/ShapeFactory3.java new file mode 100644 index 00000000..b735a81d --- /dev/null +++ b/code/patterns/ShapeFactory3.java @@ -0,0 +1,52 @@ +// patterns/ShapeFactory3.java +// (c)2020 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. +// Polymorphic factory methods +import java.util.*; +import java.util.function.*; +import java.util.stream.*; +import patterns.shapes.*; + +interface PolymorphicFactory { + Shape create(); +} + +class RandomShapes implements Supplier { + private final PolymorphicFactory[] factories; + private Random rand = new Random(42); + RandomShapes(PolymorphicFactory... factories) { + this.factories = factories; + } + public Shape get() { + return factories[ + rand.nextInt(factories.length)].create(); + } +} + +public class ShapeFactory3 { + public static void main(String[] args) { + RandomShapes rs = new RandomShapes( + Circle::new, Square::new, Triangle::new + ); + Stream.generate(rs) + .limit(6) + .peek(Shape::draw) + .peek(Shape::erase) + .count(); + } +} +/* Output: +Triangle[0] draw +Triangle[0] erase +Circle[1] draw +Circle[1] erase +Circle[2] draw +Circle[2] erase +Triangle[3] draw +Triangle[3] erase +Circle[4] draw +Circle[4] erase +Square[5] draw +Square[5] erase +*/ diff --git a/code/patterns/SingletonPattern.java b/code/patterns/SingletonPattern.java new file mode 100644 index 00000000..c2ca1a5f --- /dev/null +++ b/code/patterns/SingletonPattern.java @@ -0,0 +1,58 @@ +// patterns/SingletonPattern.java +// (c)2020 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. + +interface Resource { + int getValue(); + void setValue(int x); +} + +// This isn't inherited from a Cloneable +// base class and cloneability isn't added so +// making it final prevents cloneability from +// being added through inheritance. This also +// implements thread-safe lazy initialization: + +final class Singleton { + private static final class + ResourceImpl implements Resource { + private int i; + private ResourceImpl(int i) { + this.i = i; + } + public synchronized int getValue() { + return i; + } + public synchronized void setValue(int x) { + i = x; + } + } + private static class ResourceHolder { + private static Resource resource = + new ResourceImpl(47); + } + public static Resource getResource() { + return ResourceHolder.resource; + } +} + +public class SingletonPattern { + public static void main(String[] args) { + Resource r = Singleton.getResource(); + System.out.println(r.getValue()); + Resource s2 = Singleton.getResource(); + s2.setValue(9); + System.out.println(r.getValue()); + try { + // Can't do this: compile-time error. + // Singleton s3 = (Singleton)s2.clone(); + } catch(Exception e) { + throw new RuntimeException(e); + } + } +} +/* Output: +47 +9 +*/ diff --git a/code/patterns/StateDemo.java b/code/patterns/StateDemo.java new file mode 100644 index 00000000..9efab5b4 --- /dev/null +++ b/code/patterns/StateDemo.java @@ -0,0 +1,87 @@ +// patterns/StateDemo.java +// (c)2020 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. +// Simple demonstration of the State pattern + +interface StateBase { + void f(); + void g(); + void h(); + void changeImp(StateBase newImp); +} + +class State implements StateBase { + private StateBase implementation; + State(StateBase imp) { + implementation = imp; + } + @Override + public void changeImp(StateBase newImp) { + implementation = newImp; + } + // Pass method calls to the implementation: + @Override + public void f() { implementation.f(); } + @Override + public void g() { implementation.g(); } + @Override + public void h() { implementation.h(); } +} + +class Implementation1 implements StateBase { + @Override + public void f() { + System.out.println("Implementation1.f()"); + } + @Override + public void g() { + System.out.println("Implementation1.g()"); + } + @Override + public void h() { + System.out.println("Implementation1.h()"); + } + @Override + public void changeImp(StateBase newImp) {} +} + +class Implementation2 implements StateBase { + @Override + public void f() { + System.out.println("Implementation2.f()"); + } + @Override + public void g() { + System.out.println("Implementation2.g()"); + } + @Override + public void h() { + System.out.println("Implementation2.h()"); + } + @Override + public void changeImp(StateBase newImp) {} +} + +public class StateDemo { + static void test(StateBase b) { + b.f(); + b.g(); + b.h(); + } + public static void main(String[] args) { + StateBase b = + new State(new Implementation1()); + test(b); + b.changeImp(new Implementation2()); + test(b); + } +} +/* Output: +Implementation1.f() +Implementation1.g() +Implementation1.h() +Implementation2.f() +Implementation2.g() +Implementation2.h() +*/ diff --git a/code/patterns/TemplateMethod.java b/code/patterns/TemplateMethod.java new file mode 100644 index 00000000..eff6d279 --- /dev/null +++ b/code/patterns/TemplateMethod.java @@ -0,0 +1,44 @@ +// patterns/TemplateMethod.java +// (c)2020 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. +// Simple demonstration of Template Method +import java.util.stream.*; + +abstract class ApplicationFramework { + ApplicationFramework() { + templateMethod(); + } + abstract void customize1(); + abstract void customize2(); + // "private" means automatically "final": + private void templateMethod() { + IntStream.range(0, 5).forEach( + n -> { customize1(); customize2(); }); + } +} + +// Create a new "application": +class MyApp extends ApplicationFramework { + @Override + void customize1() { + System.out.print("Hello "); + } + @Override + void customize2() { + System.out.println("World!"); + } +} + +public class TemplateMethod { + public static void main(String[] args) { + new MyApp(); + } +} +/* Output: +Hello World! +Hello World! +Hello World! +Hello World! +Hello World! +*/ diff --git a/code/patterns/abstractfactory/GameEnvironment.java b/code/patterns/abstractfactory/GameEnvironment.java new file mode 100644 index 00000000..8c0abf7b --- /dev/null +++ b/code/patterns/abstractfactory/GameEnvironment.java @@ -0,0 +1,96 @@ +// patterns/abstractfactory/GameEnvironment.java +// (c)2020 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. +// An example of the Abstract Factory pattern +// {java patterns.abstractfactory.GameEnvironment} +package patterns.abstractfactory; +import java.util.function.*; + +interface Obstacle { + void action(); +} + +interface Player { + void interactWith(Obstacle o); +} + +class Kitty implements Player { + @Override + public void interactWith(Obstacle ob) { + System.out.print("Kitty has encountered a "); + ob.action(); + } +} + +class KungFuGuy implements Player { + @Override + public void interactWith(Obstacle ob) { + System.out.print("KungFuGuy now battles a "); + ob.action(); + } +} + +class Puzzle implements Obstacle { + @Override + public void action() { + System.out.println("Puzzle"); + } +} + +class NastyWeapon implements Obstacle { + @Override + public void action() { + System.out.println("NastyWeapon"); + } +} + +// The Abstract Factory: +class GameElementFactory { + Supplier player; + Supplier obstacle; +} + +// Concrete factories: +class KittiesAndPuzzles +extends GameElementFactory { + KittiesAndPuzzles() { + player = Kitty::new; + obstacle = Puzzle::new; + } +} + +class KillAndDismember +extends GameElementFactory { + KillAndDismember() { + player = KungFuGuy::new; + obstacle = NastyWeapon::new; + } +} + +public class GameEnvironment { + private Player p; + private Obstacle ob; + public + GameEnvironment(GameElementFactory factory) { + p = factory.player.get(); + ob = factory.obstacle.get(); + } + public void play() { + p.interactWith(ob); + } + public static void main(String[] args) { + GameElementFactory + kp = new KittiesAndPuzzles(), + kd = new KillAndDismember(); + GameEnvironment + g1 = new GameEnvironment(kp), + g2 = new GameEnvironment(kd); + g1.play(); + g2.play(); + } +} +/* Output: +Kitty has encountered a Puzzle +KungFuGuy now battles a NastyWeapon +*/ diff --git a/code/patterns/adapt/Adapter.java b/code/patterns/adapt/Adapter.java new file mode 100644 index 00000000..5bfcd6bf --- /dev/null +++ b/code/patterns/adapt/Adapter.java @@ -0,0 +1,85 @@ +// patterns/adapt/Adapter.java +// (c)2020 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. +// Variations on the Adapter pattern +// {java patterns.adapt.Adapter} +package patterns.adapt; + +class WhatIHave { + public void g() {} + public void h() {} +} + +interface WhatIWant { + void f(); +} + +class ProxyAdapter implements WhatIWant { + WhatIHave whatIHave; + ProxyAdapter(WhatIHave wih) { + whatIHave = wih; + } + @Override + public void f() { + // Implement behavior using + // methods in WhatIHave: + whatIHave.g(); + whatIHave.h(); + } +} + +class WhatIUse { + public void op(WhatIWant wiw) { + wiw.f(); + } +} + +// Approach 2: build adapter use into op(): +class WhatIUse2 extends WhatIUse { + public void op(WhatIHave wih) { + new ProxyAdapter(wih).f(); + } +} + +// Approach 3: build adapter into WhatIHave: +class WhatIHave2 extends WhatIHave +implements WhatIWant { + @Override + public void f() { + g(); + h(); + } +} + +// Approach 4: use an inner class: +class WhatIHave3 extends WhatIHave { + private class InnerAdapter implements WhatIWant{ + @Override + public void f() { + g(); + h(); + } + } + public WhatIWant whatIWant() { + return new InnerAdapter(); + } +} + +public class Adapter { + public static void main(String[] args) { + WhatIUse whatIUse = new WhatIUse(); + WhatIHave whatIHave = new WhatIHave(); + WhatIWant adapt= new ProxyAdapter(whatIHave); + whatIUse.op(adapt); + // Approach 2: + WhatIUse2 whatIUse2 = new WhatIUse2(); + whatIUse2.op(whatIHave); + // Approach 3: + WhatIHave2 whatIHave2 = new WhatIHave2(); + whatIUse.op(whatIHave2); + // Approach 4: + WhatIHave3 whatIHave3 = new WhatIHave3(); + whatIUse.op(whatIHave3.whatIWant()); + } +} diff --git a/code/patterns/chain/ChainOfResponsibility.java b/code/patterns/chain/ChainOfResponsibility.java new file mode 100644 index 00000000..b733e71c --- /dev/null +++ b/code/patterns/chain/ChainOfResponsibility.java @@ -0,0 +1,90 @@ +// patterns/chain/ChainOfResponsibility.java +// (c)2020 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. +// Using the Functional interface +// {java patterns.chain.ChainOfResponsibility} +package patterns.chain; +import java.util.*; +import java.util.function.*; + +class Result { + boolean success; + List line; + Result(List data) { + success = true; + line = data; + } + Result() { + success = false; + line = Collections.emptyList(); + } +} + +class Fail extends Result {} + +interface Algorithm { + Result algorithm(List line); +} + +class FindMinima { + public static Result leastSquares(List line) { + System.out.println("LeastSquares.algorithm"); + boolean weSucceed = false; + if(weSucceed) // Actual test/calculation here + return new Result(Arrays.asList(1.1, 2.2)); + else // Try the next one in the chain: + return new Fail(); + } + public static Result perturbation(List line) { + System.out.println("Perturbation.algorithm"); + boolean weSucceed = false; + if(weSucceed) // Actual test/calculation here + return new Result(Arrays.asList(3.3, 4.4)); + else + return new Fail(); + } + public static Result bisection(List line) { + System.out.println("Bisection.algorithm"); + boolean weSucceed = true; + if(weSucceed) // Actual test/calculation here + return new Result(Arrays.asList(5.5, 6.6)); + else + return new Fail(); + } + static List, Result>> + algorithms = Arrays.asList( + FindMinima::leastSquares, + FindMinima::perturbation, + FindMinima::bisection + ); + public static Result minima(List line) { + for(Function, Result> alg : + algorithms) { + Result result = alg.apply(line); + if(result.success) + return result; + } + return new Fail(); + } +} + +public class ChainOfResponsibility { + public static void main(String[] args) { + FindMinima solver = new FindMinima(); + List line = Arrays.asList( + 1.0, 2.0, 1.0, 2.0, -1.0, + 3.0, 4.0, 5.0, 4.0); + Result result = solver.minima(line); + if(result.success) + System.out.println(result.line); + else + System.out.println("No algorithm found"); + } +} +/* Output: +LeastSquares.algorithm +Perturbation.algorithm +Bisection.algorithm +[5.5, 6.6] +*/ diff --git a/code/patterns/doubledispatch/Aluminum.java b/code/patterns/doubledispatch/Aluminum.java new file mode 100644 index 00000000..5037fac5 --- /dev/null +++ b/code/patterns/doubledispatch/Aluminum.java @@ -0,0 +1,18 @@ +// patterns/doubledispatch/Aluminum.java +// (c)2020 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. +// Aluminum for double dispatching +package patterns.doubledispatch; +import patterns.trash.*; +import java.util.*; + +public class Aluminum extends patterns.trash.Aluminum + implements TypedBinMember { + public Aluminum(double wt) { super(wt); } + @Override + public boolean addToBin(List tbins) { + return tbins.stream() + .anyMatch(tb -> tb.add(this)); + } +} diff --git a/code/patterns/doubledispatch/Cardboard.java b/code/patterns/doubledispatch/Cardboard.java new file mode 100644 index 00000000..5046ddaa --- /dev/null +++ b/code/patterns/doubledispatch/Cardboard.java @@ -0,0 +1,18 @@ +// patterns/doubledispatch/Cardboard.java +// (c)2020 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. +// Cardboard for double dispatching +package patterns.doubledispatch; +import patterns.trash.*; +import java.util.*; + +public class Cardboard extends patterns.trash.Cardboard + implements TypedBinMember { + public Cardboard(double wt) { super(wt); } + @Override + public boolean addToBin(List tbins) { + return tbins.stream() + .anyMatch(tb -> tb.add(this)); + } +} diff --git a/code/patterns/doubledispatch/DoubleDispatch.java b/code/patterns/doubledispatch/DoubleDispatch.java new file mode 100644 index 00000000..91bee562 --- /dev/null +++ b/code/patterns/doubledispatch/DoubleDispatch.java @@ -0,0 +1,96 @@ +// patterns/doubledispatch/DoubleDispatch.java +// (c)2020 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. +// Using multiple dispatching to handle more +// than one unknown type during a method call +// {java patterns.doubledispatch.DoubleDispatch} +package patterns.doubledispatch; +import patterns.trash.*; +import java.util.*; + +class AluminumBin extends TypedBin { + @Override + public boolean add(Aluminum a) { + return addIt(a); + } +} + +class PaperBin extends TypedBin { + @Override + public boolean add(Paper a) { + return addIt(a); + } +} + +class GlassBin extends TypedBin { + @Override + public boolean add(Glass a) { + return addIt(a); + } +} + +class CardboardBin extends TypedBin { + @Override + public boolean add(Cardboard a) { + return addIt(a); + } +} + +class TrashBinSet { + private List binSet = Arrays.asList( + new AluminumBin(), + new PaperBin(), + new GlassBin(), + new CardboardBin() + ); + @SuppressWarnings("unchecked") + public void sortIntoBins(List bin) { + bin.forEach( aBin -> { + TypedBinMember t = (TypedBinMember)aBin; + if(!t.addToBin(binSet)) + System.err.println("Couldn't add " + t); + }); + } + public List binSet() { return binSet; } +} + +public class DoubleDispatch { + public static void main(String[] args) { + List bin = new ArrayList<>(); + TrashBinSet bins = new TrashBinSet(); + // ParseTrash still works, without changes: + ParseTrash.fillBin("doubledispatch", bin); + // Sort from the master bin into the + // individually-typed bins: + bins.sortIntoBins(bin); + // Perform sumValue for each bin... + bins.binSet() + .forEach(tb -> Trash.sumValue(tb.v)); + // ... and for the master bin + Trash.sumValue(bin); + } +} +/* Output: (First and Last 10 Lines) +Loading patterns.doubledispatch.Glass +Loading patterns.doubledispatch.Paper +Loading patterns.doubledispatch.Aluminum +Loading patterns.doubledispatch.Cardboard +weight of patterns.doubledispatch.Aluminum = 89.0 +weight of patterns.doubledispatch.Aluminum = 76.0 +weight of patterns.doubledispatch.Aluminum = 25.0 +weight of patterns.doubledispatch.Aluminum = 34.0 +weight of patterns.doubledispatch.Aluminum = 27.0 +weight of patterns.doubledispatch.Aluminum = 18.0 +...________...________...________...________... +weight of patterns.doubledispatch.Aluminum = 93.0 +weight of patterns.doubledispatch.Glass = 93.0 +weight of patterns.doubledispatch.Paper = 80.0 +weight of patterns.doubledispatch.Glass = 36.0 +weight of patterns.doubledispatch.Glass = 12.0 +weight of patterns.doubledispatch.Glass = 60.0 +weight of patterns.doubledispatch.Paper = 66.0 +weight of patterns.doubledispatch.Aluminum = 36.0 +weight of patterns.doubledispatch.Cardboard = 22.0 +Total value = 1086.0599818825722 +*/ diff --git a/code/patterns/doubledispatch/Glass.java b/code/patterns/doubledispatch/Glass.java new file mode 100644 index 00000000..79cf7fa2 --- /dev/null +++ b/code/patterns/doubledispatch/Glass.java @@ -0,0 +1,18 @@ +// patterns/doubledispatch/Glass.java +// (c)2020 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. +// Glass for double dispatching +package patterns.doubledispatch; +import patterns.trash.*; +import java.util.*; + +public class Glass extends patterns.trash.Glass + implements TypedBinMember { + public Glass(double wt) { super(wt); } + @Override + public boolean addToBin(List tbins) { + return tbins.stream() + .anyMatch(tb -> tb.add(this)); + } +} diff --git a/code/patterns/doubledispatch/Paper.java b/code/patterns/doubledispatch/Paper.java new file mode 100644 index 00000000..b542dfd6 --- /dev/null +++ b/code/patterns/doubledispatch/Paper.java @@ -0,0 +1,18 @@ +// patterns/doubledispatch/Paper.java +// (c)2020 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. +// Paper for double dispatching +package patterns.doubledispatch; +import patterns.trash.*; +import java.util.*; + +public class Paper extends patterns.trash.Paper + implements TypedBinMember { + public Paper(double wt) { super(wt); } + @Override + public boolean addToBin(List tbins) { + return tbins.stream() + .anyMatch(tb -> tb.add(this)); + } +} diff --git a/code/patterns/doubledispatch/TypedBin.java b/code/patterns/doubledispatch/TypedBin.java new file mode 100644 index 00000000..265874cc --- /dev/null +++ b/code/patterns/doubledispatch/TypedBin.java @@ -0,0 +1,28 @@ +// patterns/doubledispatch/TypedBin.java +// (c)2020 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. +// A List that can grab the right type +package patterns.doubledispatch; +import patterns.trash.*; +import java.util.*; + +public class TypedBin { + List v = new ArrayList<>(); + protected boolean addIt(Trash t) { + v.add(t); + return true; + } + public boolean add(Aluminum a) { + return false; + } + public boolean add(Paper a) { + return false; + } + public boolean add(Glass a) { + return false; + } + public boolean add(Cardboard a) { + return false; + } +} diff --git a/code/patterns/doubledispatch/TypedBinMember.java b/code/patterns/doubledispatch/TypedBinMember.java new file mode 100644 index 00000000..c7ce960a --- /dev/null +++ b/code/patterns/doubledispatch/TypedBinMember.java @@ -0,0 +1,14 @@ +// patterns/doubledispatch/TypedBinMember.java +// (c)2020 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. +// An interface for adding the double dispatching +// method to the trash hierarchy without +// modifying the original hierarchy +package patterns.doubledispatch; +import java.util.*; + +public interface TypedBinMember { + // The new method: + boolean addToBin(List bins); +} diff --git a/code/patterns/dynatrash/DynaTrash.java b/code/patterns/dynatrash/DynaTrash.java new file mode 100644 index 00000000..6ce33d8f --- /dev/null +++ b/code/patterns/dynatrash/DynaTrash.java @@ -0,0 +1,74 @@ +// patterns/dynatrash/DynaTrash.java +// (c)2020 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. +// Using a Map of Lists and RTTI to automatically +// sort trash into Lists. This solution, despite +// the use of RTTI, is extensible. +// {java patterns.dynatrash.DynaTrash} +package patterns.dynatrash; +import patterns.trash.*; +import java.util.*; +import java.util.stream.*; + +// Generic TypeMap works in any situation: +class TypeMap { + private Map> t = new HashMap<>(); + public void add(T o) { + Class type = o.getClass(); + if(t.containsKey(type)) + t.get(type).add(o); + else { + List v = new ArrayList<>(); + v.add(o); + t.put(type,v); + } + } + public Stream> values() { + return t.values().stream(); + } +} + +// Adapter class for callbacks +// from ParseTrash.fillBin(): +class TypeMapAdapter implements Fillable { + TypeMap map; + TypeMapAdapter(TypeMap tm) { + map = tm; + } + @Override + public void addTrash(Trash t) { map.add(t); } +} + +public class DynaTrash { + @SuppressWarnings("unchecked") + public static void main(String[] args) { + TypeMap bin = new TypeMap<>(); + ParseTrash.fillBin( + "trash", new TypeMapAdapter(bin)); + bin.values().forEach(Trash::sumValue); + } +} +/* Output: (First and Last 10 Lines) +Loading patterns.trash.Glass +Loading patterns.trash.Paper +Loading patterns.trash.Aluminum +Loading patterns.trash.Cardboard +weight of patterns.trash.Paper = 22.0 +weight of patterns.trash.Paper = 11.0 +weight of patterns.trash.Paper = 88.0 +weight of patterns.trash.Paper = 91.0 +weight of patterns.trash.Paper = 80.0 +weight of patterns.trash.Paper = 66.0 +...________...________...________...________... +weight of patterns.trash.Aluminum = 81.0 +weight of patterns.trash.Aluminum = 36.0 +weight of patterns.trash.Aluminum = 93.0 +weight of patterns.trash.Aluminum = 36.0 +Total value = 860.0499778985977 +weight of patterns.trash.Cardboard = 96.0 +weight of patterns.trash.Cardboard = 44.0 +weight of patterns.trash.Cardboard = 12.0 +weight of patterns.trash.Cardboard = 22.0 +Total value = 40.02000072598457 +*/ diff --git a/code/patterns/observer/ObservedFlower.java b/code/patterns/observer/ObservedFlower.java new file mode 100644 index 00000000..009da63e --- /dev/null +++ b/code/patterns/observer/ObservedFlower.java @@ -0,0 +1,125 @@ +// patterns/observer/ObservedFlower.java +// (c)2020 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. +// Demonstration of "Observer" pattern +// {java patterns.observer.ObservedFlower} +package patterns.observer; +import java.util.*; + +@SuppressWarnings("deprecation") +class Flower { + private boolean isOpen; + private boolean alreadyOpen; + private boolean alreadyClosed; + Flower() { isOpen = false; } + OpenNotifier opening = new OpenNotifier(); + CloseNotifier closing = new CloseNotifier(); + public void open() { // Opens its petals + isOpen = true; + opening.notifyObservers(); + alreadyClosed = false; + } + public void close() { // Closes its petals + isOpen = false; + closing.notifyObservers(); + alreadyOpen = false; + } + class OpenNotifier extends Observable { + @Override + public void notifyObservers() { + if(isOpen && !alreadyOpen) { + setChanged(); + super.notifyObservers(); + alreadyOpen = true; + } + } + } + class CloseNotifier extends Observable{ + @Override + public void notifyObservers() { + if(!isOpen && !alreadyClosed) { + setChanged(); + super.notifyObservers(); + alreadyClosed = true; + } + } + } +} + +@SuppressWarnings("deprecation") +class Bee { + private String name; + Bee(String nm) { name = nm; } + // Observe openings: + public Observer openObserver() { + return (ob, a) -> System.out.println( + "Bee " + name + "'s breakfast time!"); + } + // Observe closings: + public Observer closeObserver() { + return (ob, a) -> System.out.println( + "Bee " + name + "'s bed time!"); + } +} + +@SuppressWarnings("deprecation") +class Hummingbird { + private String name; + Hummingbird(String nm) { name = nm; } + public Observer openObserver() { + return (ob, a) -> System.out.println( + "Hummingbird " + name + + "'s breakfast time!"); + } + public Observer closeObserver() { + return (ob, a) -> System.out.println( + "Hummingbird " + name + "'s bed time!"); + } +} + +public class ObservedFlower { + public static void main(String[] args) { + Flower f = new Flower(); + Bee + ba = new Bee("A"), + bb = new Bee("B"); + Hummingbird + ha = new Hummingbird("A"), + hb = new Hummingbird("B"); + f.opening.addObserver(ha.openObserver()); + f.opening.addObserver(hb.openObserver()); + f.opening.addObserver(ba.openObserver()); + f.opening.addObserver(bb.openObserver()); + f.closing.addObserver(ha.closeObserver()); + f.closing.addObserver(hb.closeObserver()); + f.closing.addObserver(ba.closeObserver()); + f.closing.addObserver(bb.closeObserver()); + // Hummingbird B decides to sleep in: + f.opening.deleteObserver(hb.openObserver()); + // A change that interests observers: + f.open(); + f.open(); // It's already open, no change. + // Bee A doesn't want to go to bed: + f.closing.deleteObserver(ba.closeObserver()); + f.close(); + f.close(); // It's already closed; no change + f.opening.deleteObservers(); + f.open(); + f.close(); + } +} +/* Output: +Bee B's breakfast time! +Bee A's breakfast time! +Hummingbird B's breakfast time! +Hummingbird A's breakfast time! +Bee B's bed time! +Bee A's bed time! +Hummingbird B's bed time! +Hummingbird A's bed time! +Bee B's bed time! +Bee A's bed time! +Hummingbird B's bed time! +Hummingbird A's bed time! +*/ diff --git a/code/patterns/recyclea/RecycleA.java b/code/patterns/recyclea/RecycleA.java new file mode 100644 index 00000000..a73f39e7 --- /dev/null +++ b/code/patterns/recyclea/RecycleA.java @@ -0,0 +1,127 @@ +// patterns/recyclea/RecycleA.java +// (c)2020 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. +// Recycling with RTTI +// {java patterns.recyclea.RecycleA} +package patterns.recyclea; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +abstract class Trash { + double weight; + Trash(double wt) { weight = wt; } + abstract double value(); + // Sums the value of Trash in a bin: + private static double val; + static void sumValue(List bin) { + val = 0.0f; + bin.forEach( t -> { + // Polymorphism in action: + val += t.weight * t.value(); + System.out.println( + "weight of " + + // Using RTTI to get type + // information about the class: + t.getClass().getSimpleName() + + " = " + t.weight); + }); + System.out.println("Total value = " + val); + } +} + +class Aluminum extends Trash { + static double val = 1.67f; + Aluminum(double wt) { super(wt); } + @Override + double value() { return val; } + static void value(double newval) { + val = newval; + } +} + +class Paper extends Trash { + static double val = 0.10f; + Paper(double wt) { super(wt); } + @Override + double value() { return val; } + static void value(double newval) { + val = newval; + } +} + +class Glass extends Trash { + static double val = 0.23f; + Glass(double wt) { super(wt); } + @Override + double value() { return val; } + static void value(double newval) { + val = newval; + } +} + +class TrashFactory { + static List> ttypes = + Arrays.asList( + Aluminum::new, Paper::new, Glass::new); + static final int SZ = ttypes.size(); + private static SplittableRandom rand = + new SplittableRandom(47); + public static Trash newTrash() { + return ttypes + .get(rand.nextInt(SZ)) + .apply(rand.nextDouble()); + } +} + +public class RecycleA { + public static void main(String[] args) { + List bin = + Stream.generate(TrashFactory::newTrash) + .limit(25) + .collect(Collectors.toList()); + List glassBin = new ArrayList<>(); + List paperBin = new ArrayList<>(); + List alBin = new ArrayList<>(); + // Sort the Trash: + bin.forEach( t -> { + // RTTI to discover Trash type: + if(t instanceof Aluminum) + alBin.add((Aluminum)t); + if(t instanceof Paper) + paperBin.add((Paper)t); + if(t instanceof Glass) + glassBin.add((Glass)t); + }); + Trash.sumValue(alBin); + Trash.sumValue(paperBin); + Trash.sumValue(glassBin); + Trash.sumValue(bin); + } +} +/* Output: (First and Last 11 Lines) +weight of Aluminum = 0.2893030122276371 +weight of Aluminum = 0.1970234961398979 +weight of Aluminum = 0.36295525806274787 +weight of Aluminum = 0.4825532324565849 +weight of Aluminum = 0.8036398273294586 +weight of Aluminum = 0.510430896154935 +weight of Aluminum = 0.6703377164093444 +weight of Aluminum = 0.41477933066243455 +weight of Aluminum = 0.3603022312124007 +weight of Aluminum = 0.43690089841661006 +weight of Aluminum = 0.6708820087907101 +...________...________...________...________... +weight of Aluminum = 0.41477933066243455 +weight of Aluminum = 0.3603022312124007 +weight of Aluminum = 0.43690089841661006 +weight of Glass = 0.5999637765664924 +weight of Glass = 0.7748836191212746 +weight of Paper = 0.5735994548427199 +weight of Glass = 0.5362827750851034 +weight of Aluminum = 0.6708820087907101 +weight of Paper = 0.8370669795210507 +weight of Glass = 0.3397919679731668 +Total value = 9.90671597531968 +*/ diff --git a/code/patterns/recycleb/RecycleB.java b/code/patterns/recycleb/RecycleB.java new file mode 100644 index 00000000..1ca38314 --- /dev/null +++ b/code/patterns/recycleb/RecycleB.java @@ -0,0 +1,56 @@ +// patterns/recycleb/RecycleB.java +// (c)2020 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. +// {java patterns.recycleb.RecycleB} +package patterns.recycleb; +import patterns.trash.*; +import java.util.*; + +public class RecycleB { + public static void main(String[] args) { + List bin = new ArrayList<>(); + // Fill up the Trash bin: + ParseTrash.fillBin("trash", bin); + List glassBin = new ArrayList<>(); + List paperBin = new ArrayList<>(); + List alBin = new ArrayList<>(); + // Sort the Trash: + bin.forEach( t -> { + // RTTI to discover Trash type: + if(t instanceof Aluminum) + alBin.add((Aluminum)t); + if(t instanceof Paper) + paperBin.add((Paper)t); + if(t instanceof Glass) + glassBin.add((Glass)t); + }); + Trash.sumValue(alBin); + Trash.sumValue(paperBin); + Trash.sumValue(glassBin); + Trash.sumValue(bin); + } +} +/* Output: (First and Last 10 Lines) +Loading patterns.trash.Glass +Loading patterns.trash.Paper +Loading patterns.trash.Aluminum +Loading patterns.trash.Cardboard +weight of patterns.trash.Aluminum = 89.0 +weight of patterns.trash.Aluminum = 76.0 +weight of patterns.trash.Aluminum = 25.0 +weight of patterns.trash.Aluminum = 34.0 +weight of patterns.trash.Aluminum = 27.0 +weight of patterns.trash.Aluminum = 18.0 +...________...________...________...________... +weight of patterns.trash.Aluminum = 93.0 +weight of patterns.trash.Glass = 93.0 +weight of patterns.trash.Paper = 80.0 +weight of patterns.trash.Glass = 36.0 +weight of patterns.trash.Glass = 12.0 +weight of patterns.trash.Glass = 60.0 +weight of patterns.trash.Paper = 66.0 +weight of patterns.trash.Aluminum = 36.0 +weight of patterns.trash.Cardboard = 22.0 +Total value = 1086.0599818825722 +*/ diff --git a/code/patterns/recyclec/RecycleC.java b/code/patterns/recyclec/RecycleC.java new file mode 100644 index 00000000..239e8e79 --- /dev/null +++ b/code/patterns/recyclec/RecycleC.java @@ -0,0 +1,84 @@ +// patterns/recyclec/RecycleC.java +// (c)2020 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. +// Adding more objects to the recycling problem +// {java patterns.recyclec.RecycleC} +package patterns.recyclec; +import patterns.trash.*; +import java.util.*; + +// A List that admits only the right type: +class Tbin extends ArrayList { + Class binType; + Tbin(Class type) { + binType = type; + } + @SuppressWarnings("unchecked") + boolean grab(Trash t) { + // Comparing class types: + if(t.getClass().equals(binType)) { + add((T)t); // Downcast to this TBin's type + return true; // Object grabbed + } + return false; // Object not grabbed + } +} + +class TbinList +extends ArrayList> { // [1] + boolean sort(T t) { + for(Tbin ts : this) + if(ts.grab(t)) + return true; + return false; // bin not found for t + } + void sortBin(Tbin bin) { // [2] + for(T aBin : bin) + if(!sort(aBin)) + System.err.println("Bin not found"); + } +} + +public class RecycleC { + static Tbin bin = new Tbin<>(Trash.class); + public static void main(String[] args) { + // Fill up the Trash bin: + ParseTrash.fillBin("trash", bin); + + TbinList trashBins = new TbinList<>(); + trashBins.add(new Tbin<>(Aluminum.class)); + trashBins.add(new Tbin<>(Paper.class)); + trashBins.add(new Tbin<>(Glass.class)); + // add one line here: [*3*] + trashBins.add(new Tbin<>(Cardboard.class)); + + trashBins.sortBin(bin); // [4] + + trashBins.forEach(Trash::sumValue); + Trash.sumValue(bin); + } +} +/* Output: (First and Last 10 Lines) +Loading patterns.trash.Glass +Loading patterns.trash.Paper +Loading patterns.trash.Aluminum +Loading patterns.trash.Cardboard +weight of patterns.trash.Aluminum = 89.0 +weight of patterns.trash.Aluminum = 76.0 +weight of patterns.trash.Aluminum = 25.0 +weight of patterns.trash.Aluminum = 34.0 +weight of patterns.trash.Aluminum = 27.0 +weight of patterns.trash.Aluminum = 18.0 +...________...________...________...________... +weight of patterns.trash.Aluminum = 93.0 +weight of patterns.trash.Glass = 93.0 +weight of patterns.trash.Paper = 80.0 +weight of patterns.trash.Glass = 36.0 +weight of patterns.trash.Glass = 12.0 +weight of patterns.trash.Glass = 60.0 +weight of patterns.trash.Paper = 66.0 +weight of patterns.trash.Aluminum = 36.0 +weight of patterns.trash.Cardboard = 22.0 +Total value = 1086.0599818825722 +*/ diff --git a/code/patterns/shapes/BadShapeCreation.java b/code/patterns/shapes/BadShapeCreation.java new file mode 100644 index 00000000..2ebda8e5 --- /dev/null +++ b/code/patterns/shapes/BadShapeCreation.java @@ -0,0 +1,12 @@ +// patterns/shapes/BadShapeCreation.java +// (c)2020 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 class BadShapeCreation +extends RuntimeException { + public BadShapeCreation(String msg) { + super(msg); + } +} diff --git a/code/patterns/shapes/Circle.java b/code/patterns/shapes/Circle.java new file mode 100644 index 00000000..461d55e2 --- /dev/null +++ b/code/patterns/shapes/Circle.java @@ -0,0 +1,7 @@ +// patterns/shapes/Circle.java +// (c)2020 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 class Circle extends Shape {} diff --git a/code/patterns/shapes/FactoryMethod.java b/code/patterns/shapes/FactoryMethod.java new file mode 100644 index 00000000..c3b22b1f --- /dev/null +++ b/code/patterns/shapes/FactoryMethod.java @@ -0,0 +1,9 @@ +// patterns/shapes/FactoryMethod.java +// (c)2020 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/code/patterns/shapes/FactoryTest.java b/code/patterns/shapes/FactoryTest.java new file mode 100644 index 00000000..301bb1ab --- /dev/null +++ b/code/patterns/shapes/FactoryTest.java @@ -0,0 +1,17 @@ +// patterns/shapes/FactoryTest.java +// (c)2020 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/code/patterns/shapes/Shape.java b/code/patterns/shapes/Shape.java new file mode 100644 index 00000000..12fdf3e7 --- /dev/null +++ b/code/patterns/shapes/Shape.java @@ -0,0 +1,21 @@ +// patterns/shapes/Shape.java +// (c)2020 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 class Shape { + private static int counter = 0; + private int id = counter++; + @Override + public String toString() { + return + getClass().getSimpleName() + "[" + id + "]"; + } + public void draw() { + System.out.println(this + " draw"); + } + public void erase() { + System.out.println(this + " erase"); + } +} diff --git a/code/patterns/shapes/Square.java b/code/patterns/shapes/Square.java new file mode 100644 index 00000000..610dd3e4 --- /dev/null +++ b/code/patterns/shapes/Square.java @@ -0,0 +1,7 @@ +// patterns/shapes/Square.java +// (c)2020 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 class Square extends Shape {} diff --git a/code/patterns/shapes/Triangle.java b/code/patterns/shapes/Triangle.java new file mode 100644 index 00000000..9fed3d93 --- /dev/null +++ b/code/patterns/shapes/Triangle.java @@ -0,0 +1,7 @@ +// patterns/shapes/Triangle.java +// (c)2020 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 class Triangle extends Shape {} diff --git a/code/patterns/state/StateMachineDemo.java b/code/patterns/state/StateMachineDemo.java new file mode 100644 index 00000000..29f8a876 --- /dev/null +++ b/code/patterns/state/StateMachineDemo.java @@ -0,0 +1,80 @@ +// patterns/state/StateMachineDemo.java +// (c)2020 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. +// The StateMachine pattern and Template method +// {java patterns.state.StateMachineDemo} +package patterns.state; +import onjava.Nap; + +interface State { + void run(); +} + +abstract class StateMachine { + protected State currentState; + protected abstract boolean changeState(); + // Template method: + protected final void runAll() { + while(changeState()) // Customizable + currentState.run(); + } +} + +// A different subclass for each state: + +class Wash implements State { + @Override + public void run() { + System.out.println("Washing"); + new Nap(0.5); + } +} + +class Spin implements State { + @Override + public void run() { + System.out.println("Spinning"); + new Nap(0.5); + } +} + +class Rinse implements State { + @Override + public void run() { + System.out.println("Rinsing"); + new Nap(0.5); + } +} + +class Washer extends StateMachine { + private int i = 0; + // The state table: + private State[] states = { + new Wash(), new Spin(), + new Rinse(), new Spin(), + }; + Washer() { runAll(); } + @Override + public boolean changeState() { + if(i < states.length) { + // Change the state by setting the + // surrogate reference to a new object: + currentState = states[i++]; + return true; + } else + return false; + } +} + +public class StateMachineDemo { + public static void main(String[] args) { + new Washer(); + } +} +/* Output: +Washing +Spinning +Rinsing +Spinning +*/ diff --git a/code/patterns/strategy/StrategyPattern.java b/code/patterns/strategy/StrategyPattern.java new file mode 100644 index 00000000..52561b4b --- /dev/null +++ b/code/patterns/strategy/StrategyPattern.java @@ -0,0 +1,64 @@ +// patterns/strategy/StrategyPattern.java +// (c)2020 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. +// {java patterns.strategy.StrategyPattern} +package patterns.strategy; +import java.util.function.*; +import java.util.*; + +// The common strategy base type: +class FindMinima { + Function, List> algorithm; +} + +// The various strategies: +class LeastSquares extends FindMinima { + LeastSquares() { + // Line is a sequence of points (Dummy data): + algorithm = (line) -> Arrays.asList(1.1, 2.2); + } +} + +class Perturbation extends FindMinima { + Perturbation() { + algorithm = (line) -> Arrays.asList(3.3, 4.4); + } +} + +class Bisection extends FindMinima { + Bisection() { + algorithm = (line) -> Arrays.asList(5.5, 6.6); + } +} + +// The "Context" controls the strategy: +class MinimaSolver { + private FindMinima strategy; + MinimaSolver(FindMinima strat) { + strategy = strat; + } + List minima(List line) { + return strategy.algorithm.apply(line); + } + void changeAlgorithm(FindMinima newAlgorithm) { + strategy = newAlgorithm; + } +} + +public class StrategyPattern { + public static void main(String[] args) { + MinimaSolver solver = + new MinimaSolver(new LeastSquares()); + List line = Arrays.asList( + 1.0, 2.0, 1.0, 2.0, -1.0, + 3.0, 4.0, 5.0, 4.0 ); + System.out.println(solver.minima(line)); + solver.changeAlgorithm(new Bisection()); + System.out.println(solver.minima(line)); + } +} +/* Output: +[1.1, 2.2] +[5.5, 6.6] +*/ diff --git a/code/patterns/strategy/StrategyPattern2.java b/code/patterns/strategy/StrategyPattern2.java new file mode 100644 index 00000000..09465f3a --- /dev/null +++ b/code/patterns/strategy/StrategyPattern2.java @@ -0,0 +1,43 @@ +// patterns/strategy/StrategyPattern2.java +// (c)2020 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. +// {java patterns.strategy.StrategyPattern2} +package patterns.strategy; +import java.util.function.*; +import java.util.*; + +// "Context" is now incorporated: +class FindMinima2 { + Function, List> algorithm; + FindMinima2() { leastSquares(); } // default + // The various strategies: + void leastSquares() { + algorithm = (line) -> Arrays.asList(1.1, 2.2); + } + void perturbation() { + algorithm = (line) -> Arrays.asList(3.3, 4.4); + } + void bisection() { + algorithm = (line) -> Arrays.asList(5.5, 6.6); + } + List minima(List line) { + return algorithm.apply(line); + } +} + +public class StrategyPattern2 { + public static void main(String[] args) { + FindMinima2 solver = new FindMinima2(); + List line = Arrays.asList( + 1.0, 2.0, 1.0, 2.0, -1.0, + 3.0, 4.0, 5.0, 4.0 ); + System.out.println(solver.minima(line)); + solver.bisection(); + System.out.println(solver.minima(line)); + } +} +/* Output: +[1.1, 2.2] +[5.5, 6.6] +*/ diff --git a/code/patterns/trash/Aluminum.java b/code/patterns/trash/Aluminum.java new file mode 100644 index 00000000..0065e964 --- /dev/null +++ b/code/patterns/trash/Aluminum.java @@ -0,0 +1,15 @@ +// patterns/trash/Aluminum.java +// (c)2020 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.trash; + +public class Aluminum extends Trash { + private static double val = 1.67f; + public Aluminum(double wt) { super(wt); } + @Override + public double value() { return val; } + public static void value(double newVal) { + val = newVal; + } +} diff --git a/code/patterns/trash/Cardboard.java b/code/patterns/trash/Cardboard.java new file mode 100644 index 00000000..0b54d135 --- /dev/null +++ b/code/patterns/trash/Cardboard.java @@ -0,0 +1,15 @@ +// patterns/trash/Cardboard.java +// (c)2020 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.trash; + +public class Cardboard extends Trash { + private static double val = 0.23f; + public Cardboard(double wt) { super(wt); } + @Override + public double value() { return val; } + public static void value(double newVal) { + val = newVal; + } +} diff --git a/code/patterns/trash/Fillable.java b/code/patterns/trash/Fillable.java new file mode 100644 index 00000000..a61cb111 --- /dev/null +++ b/code/patterns/trash/Fillable.java @@ -0,0 +1,10 @@ +// patterns/trash/Fillable.java +// (c)2020 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. +// Any object that can be filled with Trash +package patterns.trash; + +public interface Fillable { + void addTrash(T t); +} diff --git a/code/patterns/trash/FillableList.java b/code/patterns/trash/FillableList.java new file mode 100644 index 00000000..989a33ec --- /dev/null +++ b/code/patterns/trash/FillableList.java @@ -0,0 +1,17 @@ +// patterns/trash/FillableList.java +// (c)2020 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. +// Adapter that makes a List Fillable +package patterns.trash; +import java.util.*; + +public class FillableList +implements Fillable { + private List v; + public FillableList(List vv) { + v = vv; + } + @Override + public void addTrash(T t) { v.add(t); } +} diff --git a/code/patterns/trash/Glass.java b/code/patterns/trash/Glass.java new file mode 100644 index 00000000..f7563dc4 --- /dev/null +++ b/code/patterns/trash/Glass.java @@ -0,0 +1,15 @@ +// patterns/trash/Glass.java +// (c)2020 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.trash; + +public class Glass extends Trash { + private static double val = 0.23f; + public Glass(double wt) { super(wt); } + @Override + public double value() { return val; } + public static void value(double newVal) { + val = newVal; + } +} diff --git a/code/patterns/trash/Paper.java b/code/patterns/trash/Paper.java new file mode 100644 index 00000000..2f0b3666 --- /dev/null +++ b/code/patterns/trash/Paper.java @@ -0,0 +1,15 @@ +// patterns/trash/Paper.java +// (c)2020 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.trash; + +public class Paper extends Trash { + private static double val = 0.10f; + public Paper(double wt) { super(wt); } + @Override + public double value() { return val; } + public static void value(double newVal) { + val = newVal; + } +} diff --git a/code/patterns/trash/ParseTrash.java b/code/patterns/trash/ParseTrash.java new file mode 100644 index 00000000..fc0c0416 --- /dev/null +++ b/code/patterns/trash/ParseTrash.java @@ -0,0 +1,91 @@ +// patterns/trash/ParseTrash.java +// (c)2020 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. +// Open a file and parse its contents into +// Trash objects, placing each into a List +// {java patterns.trash.ParseTrash} +package patterns.trash; +import java.util.*; +import java.util.stream.*; +import java.io.*; +import java.nio.file.*; +import java.nio.file.Files; + +public class ParseTrash { + public static void + fillBin(String pckg, Fillable bin) { + try { + Files.lines(Paths.get("trash", "Trash.dat")) + // Remove empty lines and comment lines: + .filter(line -> line.trim().length() != 0) + .filter(line -> !line.startsWith("//")) + .forEach( line -> { + String type = "patterns." + pckg + "." + + line.substring( + 0, line.indexOf(':')).trim(); + double weight = Double.valueOf( + line.substring(line.indexOf(':') + 1) + .trim()); + bin.addTrash(Trash.factory( + new Trash.Info(type, weight))); + }); + } catch(IOException | + NumberFormatException | + Trash.TrashClassNotFoundException | + Trash.CannotCreateTrashException e) { + throw new RuntimeException(e); + } + } + // Special case to handle List: + public static void + fillBin(String pckg, List bin) { + fillBin(pckg, new FillableList<>(bin)); + } + // Basic test: + public static void main(String[] args) { + List t = new ArrayList<>(); + fillBin("trash", t); + t.forEach(System.out::println); + } +} +/* Output: +Loading patterns.trash.Glass +Loading patterns.trash.Paper +Loading patterns.trash.Aluminum +Loading patterns.trash.Cardboard +patterns.trash.Glass w:54.0 v:0.23 +patterns.trash.Paper w:22.0 v:0.10 +patterns.trash.Paper w:11.0 v:0.10 +patterns.trash.Glass w:17.0 v:0.23 +patterns.trash.Aluminum w:89.0 v:1.67 +patterns.trash.Paper w:88.0 v:0.10 +patterns.trash.Aluminum w:76.0 v:1.67 +patterns.trash.Cardboard w:96.0 v:0.23 +patterns.trash.Aluminum w:25.0 v:1.67 +patterns.trash.Aluminum w:34.0 v:1.67 +patterns.trash.Glass w:11.0 v:0.23 +patterns.trash.Glass w:68.0 v:0.23 +patterns.trash.Glass w:43.0 v:0.23 +patterns.trash.Aluminum w:27.0 v:1.67 +patterns.trash.Cardboard w:44.0 v:0.23 +patterns.trash.Aluminum w:18.0 v:1.67 +patterns.trash.Paper w:91.0 v:0.10 +patterns.trash.Glass w:63.0 v:0.23 +patterns.trash.Glass w:50.0 v:0.23 +patterns.trash.Glass w:80.0 v:0.23 +patterns.trash.Aluminum w:81.0 v:1.67 +patterns.trash.Cardboard w:12.0 v:0.23 +patterns.trash.Glass w:12.0 v:0.23 +patterns.trash.Glass w:54.0 v:0.23 +patterns.trash.Aluminum w:36.0 v:1.67 +patterns.trash.Aluminum w:93.0 v:1.67 +patterns.trash.Glass w:93.0 v:0.23 +patterns.trash.Paper w:80.0 v:0.10 +patterns.trash.Glass w:36.0 v:0.23 +patterns.trash.Glass w:12.0 v:0.23 +patterns.trash.Glass w:60.0 v:0.23 +patterns.trash.Paper w:66.0 v:0.10 +patterns.trash.Aluminum w:36.0 v:1.67 +patterns.trash.Cardboard w:22.0 v:0.23 +*/ diff --git a/code/patterns/trash/Trash.dat b/code/patterns/trash/Trash.dat new file mode 100644 index 00000000..436a7a71 --- /dev/null +++ b/code/patterns/trash/Trash.dat @@ -0,0 +1,35 @@ +// patterns/trash/Trash.dat +Glass:54 +Paper:22 +Paper:11 +Glass:17 +Aluminum:89 +Paper:88 +Aluminum:76 +Cardboard:96 +Aluminum:25 +Aluminum:34 +Glass:11 +Glass:68 +Glass:43 +Aluminum:27 +Cardboard:44 +Aluminum:18 +Paper:91 +Glass:63 +Glass:50 +Glass:80 +Aluminum:81 +Cardboard:12 +Glass:12 +Glass:54 +Aluminum:36 +Aluminum:93 +Glass:93 +Paper:80 +Glass:36 +Glass:12 +Glass:60 +Paper:66 +Aluminum:36 +Cardboard:22 diff --git a/code/patterns/trash/Trash.java b/code/patterns/trash/Trash.java new file mode 100644 index 00000000..7d01de8c --- /dev/null +++ b/code/patterns/trash/Trash.java @@ -0,0 +1,92 @@ +// patterns/trash/Trash.java +// (c)2020 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. +// Base class for Trash recycling examples +package patterns.trash; +import java.util.*; +import java.lang.reflect.*; + +public abstract class Trash { + private double weight; + public Trash(double wt) { weight = wt; } + public Trash() {} + public abstract double value(); + public double weight() { return weight; } + // Sums the value of Trash in a bin: + static double val; + public static + void sumValue(List bin) { + val = 0.0f; + bin.forEach( t -> { + val += t.weight() * t.value(); + System.out.println("weight of " + + // RTTI gets type information + // about the class: + t.getClass().getName() + + " = " + t.weight()); + }); + System.out.println("Total value = " + val); + } + @Override + public String toString() { + // Print correct subclass name: + return getClass().getName() + + " w:" + weight() + " v:" + + String.format("%.2f", value()); + } + // Remainder of class supports dynamic creation: + public static class CannotCreateTrashException + extends RuntimeException { + public CannotCreateTrashException(Exception why) { + super(why); + } + } + public static class TrashClassNotFoundException + extends RuntimeException { + public TrashClassNotFoundException(Exception why) { + super(why); + } + } + public static class Info { + public String id; + public double data; + public Info(String name, double data) { + id = name; + this.data = data; + } + } + private static List trashTypes = + new ArrayList<>(); + @SuppressWarnings("unchecked") + public static T factory(Info info) { + for(Class trashType : trashTypes) { + // Determine the type and create one: + if(trashType.getName().contains(info.id)) { + try { + // Get the dynamic constructor method + // that takes a double argument: + Constructor ctor = + trashType.getConstructor(double.class); + // Call the constructor to create a + // new object: + return + (T)ctor.newInstance(info.data); + } catch(Exception e) { + throw new CannotCreateTrashException(e); + } + } + } + // The necessary Class was not in the list. Try to + // load it, but it must be in your class path! + try { + System.out.println("Loading " + info.id); + trashTypes.add(Class.forName(info.id)); + } catch(Exception e) { + throw new TrashClassNotFoundException(e); + } + // Loaded successfully. Recursive call + // should work this time: + return factory(info); + } +} diff --git a/code/patterns/trashvisitor/Aluminum.java b/code/patterns/trashvisitor/Aluminum.java new file mode 100644 index 00000000..85d5fa14 --- /dev/null +++ b/code/patterns/trashvisitor/Aluminum.java @@ -0,0 +1,16 @@ +// patterns/trashvisitor/Aluminum.java +// (c)2020 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. +// Aluminum for the visitor pattern +package patterns.trashvisitor; +import patterns.trash.*; + +public class Aluminum extends patterns.trash.Aluminum + implements Visitable { + public Aluminum(double wt) { super(wt); } + @Override + public void accept(Visitor v) { + v.visit(this); + } +} diff --git a/code/patterns/trashvisitor/Cardboard.java b/code/patterns/trashvisitor/Cardboard.java new file mode 100644 index 00000000..978202ef --- /dev/null +++ b/code/patterns/trashvisitor/Cardboard.java @@ -0,0 +1,16 @@ +// patterns/trashvisitor/Cardboard.java +// (c)2020 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. +// Cardboard for the visitor pattern +package patterns.trashvisitor; +import patterns.trash.*; + +public class Cardboard extends patterns.trash.Cardboard + implements Visitable { + public Cardboard(double wt) { super(wt); } + @Override + public void accept(Visitor v) { + v.visit(this); + } +} diff --git a/code/patterns/trashvisitor/Glass.java b/code/patterns/trashvisitor/Glass.java new file mode 100644 index 00000000..fbcf4949 --- /dev/null +++ b/code/patterns/trashvisitor/Glass.java @@ -0,0 +1,16 @@ +// patterns/trashvisitor/Glass.java +// (c)2020 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. +// Glass for the visitor pattern +package patterns.trashvisitor; +import patterns.trash.*; + +public class Glass extends patterns.trash.Glass + implements Visitable { + public Glass(double wt) { super(wt); } + @Override + public void accept(Visitor v) { + v.visit(this); + } +} diff --git a/code/patterns/trashvisitor/Paper.java b/code/patterns/trashvisitor/Paper.java new file mode 100644 index 00000000..6e9999f1 --- /dev/null +++ b/code/patterns/trashvisitor/Paper.java @@ -0,0 +1,16 @@ +// patterns/trashvisitor/Paper.java +// (c)2020 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. +// Paper for the visitor pattern +package patterns.trashvisitor; +import patterns.trash.*; + +public class Paper extends patterns.trash.Paper + implements Visitable { + public Paper(double wt) { super(wt); } + @Override + public void accept(Visitor v) { + v.visit(this); + } +} diff --git a/code/patterns/trashvisitor/TrashVisitor.java b/code/patterns/trashvisitor/TrashVisitor.java new file mode 100644 index 00000000..8f956623 --- /dev/null +++ b/code/patterns/trashvisitor/TrashVisitor.java @@ -0,0 +1,127 @@ +// patterns/trashvisitor/TrashVisitor.java +// (c)2020 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. +// {java patterns.trashvisitor.TrashVisitor} +package patterns.trashvisitor; +import patterns.trash.*; +import java.util.*; + +// Specific group of algorithms packaged +// in each implementation of Visitor: +class PriceVisitor implements Visitor { + private double alSum; // Aluminum + private double pSum; // Paper + private double gSum; // Glass + private double cSum; // Cardboard + public static void show(String s) { + System.out.println(s); + } + @Override + public void visit(Aluminum al) { + double v = al.weight() * al.value(); + show("value of Aluminum= " + v); + alSum += v; + } + @Override + public void visit(Paper p) { + double v = p.weight() * p.value(); + show("value of Paper= " + v); + pSum += v; + } + @Override + public void visit(Glass g) { + double v = g.weight() * g.value(); + show("value of Glass= " + v); + gSum += v; + } + @Override + public void visit(Cardboard c) { + double v = c.weight() * c.value(); + show("value of Cardboard = " + v); + cSum += v; + } + @Override + public void total() { + show( + "Total Aluminum: $" + alSum + "\n" + + "Total Paper: $" + pSum + "\n" + + "Total Glass: $" + gSum + "\n" + + "Total Cardboard: $" + cSum); + } +} + +class WeightVisitor implements Visitor { + private double alSum; // Aluminum + private double pSum; // Paper + private double gSum; // Glass + private double cSum; // Cardboard + public static void show(String s) { + System.out.println(s); + } + @Override + public void visit(Aluminum al) { + alSum += al.weight(); + show("Aluminum weight = " + al.weight()); + } + @Override + public void visit(Paper p) { + pSum += p.weight(); + show("Paper weight = " + p.weight()); + } + @Override + public void visit(Glass g) { + gSum += g.weight(); + show("Glass weight = " + g.weight()); + } + @Override + public void visit(Cardboard c) { + cSum += c.weight(); + show("Cardboard weight = " + c.weight()); + } + @Override + public void total() { + show("Total weight Aluminum:" + alSum); + show("Total weight Paper:" + pSum); + show("Total weight Glass:" + gSum); + show("Total weight Cardboard:" + cSum); + } +} + +public class TrashVisitor { + public static void main(String[] args) { + List bin = new ArrayList<>(); + // ParseTrash still works, without changes: + ParseTrash.fillBin("trashvisitor", bin); + List visitors = Arrays.asList( + new PriceVisitor(), new WeightVisitor()); + bin.forEach( t -> { + Visitable v = (Visitable) t; + visitors.forEach(visitor -> v.accept(visitor)); + }); + visitors.forEach(Visitor::total); + } +} +/* Output: (First and Last 10 Lines) +Loading patterns.trashvisitor.Glass +Loading patterns.trashvisitor.Paper +Loading patterns.trashvisitor.Aluminum +Loading patterns.trashvisitor.Cardboard +value of Glass= 12.420000225305557 +Glass weight = 54.0 +value of Paper= 2.2000000327825546 +Paper weight = 22.0 +value of Paper= 1.1000000163912773 +Paper weight = 11.0 +...________...________...________...________... +value of Cardboard = 5.060000091791153 +Cardboard weight = 22.0 +Total Aluminum: $860.0499778985977 +Total Paper: $35.80000053346157 +Total Glass: $150.1900027245283 +Total Cardboard: $40.02000072598457 +Total weight Aluminum:515.0 +Total weight Paper:358.0 +Total weight Glass:653.0 +Total weight Cardboard:174.0 +*/ diff --git a/code/patterns/trashvisitor/Visitable.java b/code/patterns/trashvisitor/Visitable.java new file mode 100644 index 00000000..f1f9f1da --- /dev/null +++ b/code/patterns/trashvisitor/Visitable.java @@ -0,0 +1,12 @@ +// patterns/trashvisitor/Visitable.java +// (c)2020 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. +// An interface to add visitor functionality to the +// Trash hierarchy without modifying the base class +package patterns.trashvisitor; + +public interface Visitable { + // The new method: + void accept(Visitor v); +} diff --git a/code/patterns/trashvisitor/Visitor.java b/code/patterns/trashvisitor/Visitor.java new file mode 100644 index 00000000..07ef4622 --- /dev/null +++ b/code/patterns/trashvisitor/Visitor.java @@ -0,0 +1,14 @@ +// patterns/trashvisitor/Visitor.java +// (c)2020 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. +// The base interface for visitors +package patterns.trashvisitor; + +public interface Visitor { + void visit(Aluminum a); + void visit(Paper p); + void visit(Glass g); + void visit(Cardboard c); + void total(); +} diff --git a/code/patterns/visitor/BeeAndFlowers.java b/code/patterns/visitor/BeeAndFlowers.java new file mode 100644 index 00000000..aa86ebfc --- /dev/null +++ b/code/patterns/visitor/BeeAndFlowers.java @@ -0,0 +1,122 @@ +// patterns/visitor/BeeAndFlowers.java +// (c)2020 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. +// Demonstration of "visitor" pattern +// {java patterns.visitor.BeeAndFlowers} +package patterns.visitor; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +interface Visitor { + void visit(Gladiolus g); + void visit(Renuculus r); + void visit(Chrysanthemum c); +} + +// The Flower hierarchy cannot be changed: +interface Flower { + void accept(Visitor v); +} + +class Gladiolus implements Flower { + @Override + public void accept(Visitor v) { v.visit(this);} +} + +class Renuculus implements Flower { + @Override + public void accept(Visitor v) { v.visit(this);} +} + +class Chrysanthemum implements Flower { + @Override + public void accept(Visitor v) { v.visit(this);} +} + +// Add the ability to produce a String: +class StringVal implements Visitor { + String s; + @Override + public String toString() { return s; } + @Override + public void visit(Gladiolus g) { + s = "Gladiolus"; + } + @Override + public void visit(Renuculus r) { + s = "Renuculus"; + } + @Override + public void visit(Chrysanthemum c) { + s = "Chrysanthemum"; + } +} + +// Add the ability to do "Bee" activities: +class Bee implements Visitor { + @Override + public void visit(Gladiolus g) { + System.out.println("Bee and Gladiolus"); + } + @Override + public void visit(Renuculus r) { + System.out.println("Bee and Renuculus"); + } + @Override + public void visit(Chrysanthemum c) { + System.out.println("Bee and Chrysanthemum"); + } +} + +class FlowerFactory { + static List> flowers = + Arrays.asList(Gladiolus::new, + Renuculus::new, Chrysanthemum::new); + static final int SZ = flowers.size(); + private static SplittableRandom rand = + new SplittableRandom(47); + public static Flower newFlower() { + return flowers.get(rand.nextInt(SZ)).get(); + } +} + +public class BeeAndFlowers { + public static void main(String[] args) { + List flowers = + Stream.generate(FlowerFactory::newFlower) + .limit(10) + .collect(Collectors.toList()); + StringVal sval = new StringVal(); + flowers.forEach(f -> { + f.accept(sval); + System.out.println(sval); + }); + // Perform "Bee" operation on all Flowers: + Bee bee = new Bee(); + flowers.forEach(f -> f.accept(bee)); + } +} +/* Output: +Gladiolus +Chrysanthemum +Gladiolus +Renuculus +Chrysanthemum +Renuculus +Chrysanthemum +Chrysanthemum +Chrysanthemum +Renuculus +Bee and Gladiolus +Bee and Chrysanthemum +Bee and Gladiolus +Bee and Renuculus +Bee and Chrysanthemum +Bee and Renuculus +Bee and Chrysanthemum +Bee and Chrysanthemum +Bee and Chrysanthemum +Bee and Renuculus +*/ diff --git a/code/polymorphism/CovariantReturn.java b/code/polymorphism/CovariantReturn.java new file mode 100644 index 00000000..e88fe590 --- /dev/null +++ b/code/polymorphism/CovariantReturn.java @@ -0,0 +1,38 @@ +// polymorphism/CovariantReturn.java +// (c)2020 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. + +class Grain { + @Override + public String toString() { return "Grain"; } +} + +class Wheat extends Grain { + @Override + public String toString() { return "Wheat"; } +} + +class Mill { + Grain process() { return new Grain(); } +} + +class WheatMill extends Mill { + @Override + Wheat process() { return new Wheat(); } +} + +public class CovariantReturn { + public static void main(String[] args) { + Mill m = new Mill(); + Grain g = m.process(); + System.out.println(g); + m = new WheatMill(); + g = m.process(); + System.out.println(g); + } +} +/* Output: +Grain +Wheat +*/ diff --git a/code/polymorphism/FieldAccess.java b/code/polymorphism/FieldAccess.java new file mode 100644 index 00000000..95e47c5e --- /dev/null +++ b/code/polymorphism/FieldAccess.java @@ -0,0 +1,36 @@ +// polymorphism/FieldAccess.java +// (c)2020 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. +// Direct field access is determined at compile time + +class Super { + public int field = 0; + public int getField() { return field; } +} + +class Sub extends Super { + public int field = 1; + @Override + public int getField() { return field; } + public int getSuperField() { return super.field; } +} + +public class FieldAccess { + public static void main(String[] args) { + Super sup = new Sub(); // Upcast + System.out.println("sup.field = " + sup.field + + ", sup.getField() = " + sup.getField()); + Sub sub = new Sub(); + System.out.println("sub.field = " + + sub.field + ", sub.getField() = " + + sub.getField() + + ", sub.getSuperField() = " + + sub.getSuperField()); + } +} +/* Output: +sup.field = 0, sup.getField() = 1 +sub.field = 1, sub.getField() = 1, sub.getSuperField() += 0 +*/ diff --git a/code/polymorphism/Frog.java b/code/polymorphism/Frog.java new file mode 100644 index 00000000..9226910d --- /dev/null +++ b/code/polymorphism/Frog.java @@ -0,0 +1,122 @@ +// polymorphism/Frog.java +// (c)2020 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. +// Cleanup and inheritance +// {java polymorphism.Frog} +package polymorphism; + +class Characteristic { + private String s; + Characteristic(String s) { + this.s = s; + System.out.println("Creating Characteristic " + s); + } + protected void dispose() { + System.out.println("disposing Characteristic " + s); + } +} + +class Description { + private String s; + Description(String s) { + this.s = s; + System.out.println("Creating Description " + s); + } + protected void dispose() { + System.out.println("disposing Description " + s); + } +} + +class LivingCreature { + private Characteristic p = + new Characteristic("is alive"); + private Description t = + new Description("Basic Living Creature"); + LivingCreature() { + System.out.println("LivingCreature()"); + } + protected void dispose() { + System.out.println("LivingCreature dispose"); + t.dispose(); + p.dispose(); + } +} + +class Animal extends LivingCreature { + private Characteristic p = + new Characteristic("has heart"); + private Description t = + new Description("Animal not Vegetable"); + Animal() { System.out.println("Animal()"); } + @Override + protected void dispose() { + System.out.println("Animal dispose"); + t.dispose(); + p.dispose(); + super.dispose(); + } +} + +class Amphibian extends Animal { + private Characteristic p = + new Characteristic("can live in water"); + private Description t = + new Description("Both water and land"); + Amphibian() { + System.out.println("Amphibian()"); + } + @Override + protected void dispose() { + System.out.println("Amphibian dispose"); + t.dispose(); + p.dispose(); + super.dispose(); + } +} + +public class Frog extends Amphibian { + private Characteristic p = + new Characteristic("Croaks"); + private Description t = new Description("Eats Bugs"); + public Frog() { System.out.println("Frog()"); } + @Override + protected void dispose() { + System.out.println("Frog dispose"); + t.dispose(); + p.dispose(); + super.dispose(); + } + public static void main(String[] args) { + Frog frog = new Frog(); + System.out.println("Bye!"); + frog.dispose(); + } +} +/* Output: +Creating Characteristic is alive +Creating Description Basic Living Creature +LivingCreature() +Creating Characteristic has heart +Creating Description Animal not Vegetable +Animal() +Creating Characteristic can live in water +Creating Description Both water and land +Amphibian() +Creating Characteristic Croaks +Creating Description Eats Bugs +Frog() +Bye! +Frog dispose +disposing Description Eats Bugs +disposing Characteristic Croaks +Amphibian dispose +disposing Description Both water and land +disposing Characteristic can live in water +Animal dispose +disposing Description Animal not Vegetable +disposing Characteristic has heart +LivingCreature dispose +disposing Description Basic Living Creature +disposing Characteristic is alive +*/ diff --git a/code/polymorphism/PolyConstructors.java b/code/polymorphism/PolyConstructors.java new file mode 100644 index 00000000..3a99f08b --- /dev/null +++ b/code/polymorphism/PolyConstructors.java @@ -0,0 +1,41 @@ +// polymorphism/PolyConstructors.java +// (c)2020 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. +// Constructors and polymorphism +// don't produce what you might expect + +class Glyph { + void draw() { System.out.println("Glyph.draw()"); } + Glyph() { + System.out.println("Glyph() before draw()"); + draw(); + System.out.println("Glyph() after draw()"); + } +} + +class RoundGlyph extends Glyph { + private int radius = 1; + RoundGlyph(int r) { + radius = r; + System.out.println( + "RoundGlyph.RoundGlyph(), radius = " + radius); + } + @Override + void draw() { + System.out.println( + "RoundGlyph.draw(), radius = " + radius); + } +} + +public class PolyConstructors { + public static void main(String[] args) { + new RoundGlyph(5); + } +} +/* Output: +Glyph() before draw() +RoundGlyph.draw(), radius = 0 +Glyph() after draw() +RoundGlyph.RoundGlyph(), radius = 5 +*/ diff --git a/code/polymorphism/PrivateOverride.java b/code/polymorphism/PrivateOverride.java new file mode 100644 index 00000000..9873e03d --- /dev/null +++ b/code/polymorphism/PrivateOverride.java @@ -0,0 +1,24 @@ +// polymorphism/PrivateOverride.java +// (c)2020 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. +// Trying to override a private method +// {java polymorphism.PrivateOverride} +package polymorphism; + +public class PrivateOverride { + private void f() { + System.out.println("private f()"); + } + public static void main(String[] args) { + PrivateOverride po = new Derived(); + po.f(); + } +} + +class Derived extends PrivateOverride { + public void f() { System.out.println("public f()"); } +} +/* Output: +private f() +*/ diff --git a/code/polymorphism/PrivateOverride2.java b/code/polymorphism/PrivateOverride2.java new file mode 100644 index 00000000..664672bc --- /dev/null +++ b/code/polymorphism/PrivateOverride2.java @@ -0,0 +1,22 @@ +// polymorphism/PrivateOverride2.java +// (c)2020 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. +// Detecting a mistaken override using @Override +// {WillNotCompile} +package polymorphism; + +public class PrivateOverride2 { + private void f() { + System.out.println("private f()"); + } + public static void main(String[] args) { + PrivateOverride2 po = new Derived2(); + po.f(); + } +} + +class Derived2 extends PrivateOverride2 { + @Override + public void f() { System.out.println("public f()"); } +} diff --git a/code/polymorphism/RTTI.java b/code/polymorphism/RTTI.java new file mode 100644 index 00000000..39c9029b --- /dev/null +++ b/code/polymorphism/RTTI.java @@ -0,0 +1,43 @@ +// polymorphism/RTTI.java +// (c)2020 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. +// Downcasting & Runtime type information (RTTI) +// {ThrowsException} + +class Useful { + public void f() {} + public void g() {} +} + +class MoreUseful extends Useful { + @Override + public void f() {} + @Override + public void g() {} + public void u() {} + public void v() {} + public void w() {} +} + +public class RTTI { + public static void main(String[] args) { + Useful[] x = { + new Useful(), + new MoreUseful() + }; + x[0].f(); + x[1].g(); + // Compile time: method not found in Useful: + //- x[1].u(); + ((MoreUseful)x[1]).u(); // Downcast/RTTI + ((MoreUseful)x[0]).u(); // Exception thrown + } +} +/* Output: +___[ Error Output ]___ +Exception in thread "main" +java.lang.ClassCastException: Useful cannot be cast to +MoreUseful + at RTTI.main(RTTI.java:31) +*/ diff --git a/code/polymorphism/ReferenceCounting.java b/code/polymorphism/ReferenceCounting.java new file mode 100644 index 00000000..b378117f --- /dev/null +++ b/code/polymorphism/ReferenceCounting.java @@ -0,0 +1,71 @@ +// polymorphism/ReferenceCounting.java +// (c)2020 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. +// Cleaning up shared member objects + +class Shared { + private int refcount = 0; + private static long counter = 0; + private final long id = counter++; + Shared() { + System.out.println("Creating " + this); + } + public void addRef() { refcount++; } + protected void dispose() { + if(--refcount == 0) + System.out.println("Disposing " + this); + } + @Override + public String toString() { + return "Shared " + id; + } +} + +class Composing { + private Shared shared; + private static long counter = 0; + private final long id = counter++; + Composing(Shared shared) { + System.out.println("Creating " + this); + this.shared = shared; + this.shared.addRef(); + } + protected void dispose() { + System.out.println("disposing " + this); + shared.dispose(); + } + @Override + public String toString() { + return "Composing " + id; + } +} + +public class ReferenceCounting { + public static void main(String[] args) { + Shared shared = new Shared(); + Composing[] composing = { + new Composing(shared), + new Composing(shared), + new Composing(shared), + new Composing(shared), + new Composing(shared) + }; + for(Composing c : composing) + c.dispose(); + } +} +/* Output: +Creating Shared 0 +Creating Composing 0 +Creating Composing 1 +Creating Composing 2 +Creating Composing 3 +Creating Composing 4 +disposing Composing 0 +disposing Composing 1 +disposing Composing 2 +disposing Composing 3 +disposing Composing 4 +Disposing Shared 0 +*/ diff --git a/code/polymorphism/Sandwich.java b/code/polymorphism/Sandwich.java new file mode 100644 index 00000000..97f80d53 --- /dev/null +++ b/code/polymorphism/Sandwich.java @@ -0,0 +1,54 @@ +// polymorphism/Sandwich.java +// (c)2020 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. +// Order of constructor calls +// {java polymorphism.Sandwich} +package polymorphism; + +class Meal { + Meal() { System.out.println("Meal()"); } +} + +class Bread { + Bread() { System.out.println("Bread()"); } +} + +class Cheese { + Cheese() { System.out.println("Cheese()"); } +} + +class Lettuce { + Lettuce() { System.out.println("Lettuce()"); } +} + +class Lunch extends Meal { + Lunch() { System.out.println("Lunch()"); } +} + +class PortableLunch extends Lunch { + PortableLunch() { + System.out.println("PortableLunch()"); + } +} + +public class Sandwich extends PortableLunch { + private Bread b = new Bread(); + private Cheese c = new Cheese(); + private Lettuce l = new Lettuce(); + public Sandwich() { + System.out.println("Sandwich()"); + } + public static void main(String[] args) { + new Sandwich(); + } +} +/* Output: +Meal() +Lunch() +PortableLunch() +Bread() +Cheese() +Lettuce() +Sandwich() +*/ diff --git a/code/polymorphism/Shapes.java b/code/polymorphism/Shapes.java new file mode 100644 index 00000000..4d051e70 --- /dev/null +++ b/code/polymorphism/Shapes.java @@ -0,0 +1,26 @@ +// polymorphism/Shapes.java +// (c)2020 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. +// Polymorphism in Java +import polymorphism.shape.*; + +public class Shapes { + public static void main(String[] args) { + RandomShapes gen = new RandomShapes(); + // Make polymorphic method calls: + for(Shape shape : gen.array(9)) + shape.draw(); + } +} +/* Output: +Triangle.draw() +Triangle.draw() +Square.draw() +Triangle.draw() +Square.draw() +Triangle.draw() +Square.draw() +Triangle.draw() +Circle.draw() +*/ diff --git a/code/polymorphism/StaticPolymorphism.java b/code/polymorphism/StaticPolymorphism.java new file mode 100644 index 00000000..1ebe733b --- /dev/null +++ b/code/polymorphism/StaticPolymorphism.java @@ -0,0 +1,36 @@ +// polymorphism/StaticPolymorphism.java +// (c)2020 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. +// Static methods are not polymorphic + +class StaticSuper { + public static String staticGet() { + return "Base staticGet()"; + } + public String dynamicGet() { + return "Base dynamicGet()"; + } +} + +class StaticSub extends StaticSuper { + public static String staticGet() { + return "Derived staticGet()"; + } + @Override + public String dynamicGet() { + return "Derived dynamicGet()"; + } +} + +public class StaticPolymorphism { + public static void main(String[] args) { + StaticSuper sup = new StaticSub(); // Upcast + System.out.println(StaticSuper.staticGet()); + System.out.println(sup.dynamicGet()); + } +} +/* Output: +Base staticGet() +Derived dynamicGet() +*/ diff --git a/code/polymorphism/Transmogrify.java b/code/polymorphism/Transmogrify.java new file mode 100644 index 00000000..09877d53 --- /dev/null +++ b/code/polymorphism/Transmogrify.java @@ -0,0 +1,43 @@ +// polymorphism/Transmogrify.java +// (c)2020 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. +// Dynamically changing the behavior of an object +// via composition (the "State" design pattern) + +class Actor { + public void act() {} +} + +class HappyActor extends Actor { + @Override + public void act() { + System.out.println("HappyActor"); + } +} + +class SadActor extends Actor { + @Override + public void act() { + System.out.println("SadActor"); + } +} + +class Stage { + private Actor actor = new HappyActor(); + public void change() { actor = new SadActor(); } + public void performPlay() { actor.act(); } +} + +public class Transmogrify { + public static void main(String[] args) { + Stage stage = new Stage(); + stage.performPlay(); + stage.change(); + stage.performPlay(); + } +} +/* Output: +HappyActor +SadActor +*/ diff --git a/code/polymorphism/music/Instrument.java b/code/polymorphism/music/Instrument.java new file mode 100644 index 00000000..fb6c77e3 --- /dev/null +++ b/code/polymorphism/music/Instrument.java @@ -0,0 +1,11 @@ +// polymorphism/music/Instrument.java +// (c)2020 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 polymorphism.music; + +class Instrument { + public void play(Note n) { + System.out.println("Instrument.play()"); + } +} diff --git a/code/polymorphism/music/Music.java b/code/polymorphism/music/Music.java new file mode 100644 index 00000000..8e903ec0 --- /dev/null +++ b/code/polymorphism/music/Music.java @@ -0,0 +1,21 @@ +// polymorphism/music/Music.java +// (c)2020 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. +// Inheritance & upcasting +// {java polymorphism.music.Music} +package polymorphism.music; + +public class Music { + public static void tune(Instrument i) { + // ... + i.play(Note.MIDDLE_C); + } + public static void main(String[] args) { + Wind flute = new Wind(); + tune(flute); // Upcasting + } +} +/* Output: +Wind.play() MIDDLE_C +*/ diff --git a/code/polymorphism/music/Music2.java b/code/polymorphism/music/Music2.java new file mode 100644 index 00000000..a5bff54b --- /dev/null +++ b/code/polymorphism/music/Music2.java @@ -0,0 +1,46 @@ +// polymorphism/music/Music2.java +// (c)2020 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. +// Overloading instead of upcasting +// {java polymorphism.music.Music2} +package polymorphism.music; + +class Stringed extends Instrument { + @Override + public void play(Note n) { + System.out.println("Stringed.play() " + n); + } +} + +class Brass extends Instrument { + @Override + public void play(Note n) { + System.out.println("Brass.play() " + n); + } +} + +public class Music2 { + public static void tune(Wind i) { + i.play(Note.MIDDLE_C); + } + public static void tune(Stringed i) { + i.play(Note.MIDDLE_C); + } + public static void tune(Brass i) { + i.play(Note.MIDDLE_C); + } + public static void main(String[] args) { + Wind flute = new Wind(); + Stringed violin = new Stringed(); + Brass frenchHorn = new Brass(); + tune(flute); // No upcasting + tune(violin); + tune(frenchHorn); + } +} +/* Output: +Wind.play() MIDDLE_C +Stringed.play() MIDDLE_C +Brass.play() MIDDLE_C +*/ diff --git a/code/polymorphism/music/Note.java b/code/polymorphism/music/Note.java new file mode 100644 index 00000000..414367a9 --- /dev/null +++ b/code/polymorphism/music/Note.java @@ -0,0 +1,10 @@ +// polymorphism/music/Note.java +// (c)2020 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. +// Notes to play on musical instruments +package polymorphism.music; + +public enum Note { + MIDDLE_C, C_SHARP, B_FLAT; // Etc. +} diff --git a/code/polymorphism/music/Wind.java b/code/polymorphism/music/Wind.java new file mode 100644 index 00000000..c38ac497 --- /dev/null +++ b/code/polymorphism/music/Wind.java @@ -0,0 +1,15 @@ +// polymorphism/music/Wind.java +// (c)2020 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 polymorphism.music; + +// Wind objects are instruments +// because they have the same interface: +public class Wind extends Instrument { + // Redefine interface method: + @Override + public void play(Note n) { + System.out.println("Wind.play() " + n); + } +} diff --git a/code/polymorphism/music3/Music3.java b/code/polymorphism/music3/Music3.java new file mode 100644 index 00000000..da3eb364 --- /dev/null +++ b/code/polymorphism/music3/Music3.java @@ -0,0 +1,108 @@ +// polymorphism/music3/Music3.java +// (c)2020 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. +// An extensible program +// {java polymorphism.music3.Music3} +package polymorphism.music3; +import polymorphism.music.Note; + +class Instrument { + void play(Note n) { + System.out.println("Instrument.play() " + n); + } + String what() { return "Instrument"; } + void adjust() { + System.out.println("Adjusting Instrument"); + } +} + +class Wind extends Instrument { + @Override + void play(Note n) { + System.out.println("Wind.play() " + n); + } + @Override + String what() { return "Wind"; } + @Override + void adjust() { + System.out.println("Adjusting Wind"); + } +} + +class Percussion extends Instrument { + @Override + void play(Note n) { + System.out.println("Percussion.play() " + n); + } + @Override + String what() { return "Percussion"; } + @Override + void adjust() { + System.out.println("Adjusting Percussion"); + } +} + +class Stringed extends Instrument { + @Override + void play(Note n) { + System.out.println("Stringed.play() " + n); + } + @Override + String what() { return "Stringed"; } + @Override + void adjust() { + System.out.println("Adjusting Stringed"); + } +} + +class Brass extends Wind { + @Override + void play(Note n) { + System.out.println("Brass.play() " + n); + } + @Override + void adjust() { + System.out.println("Adjusting Brass"); + } +} + +class Woodwind extends Wind { + @Override + void play(Note n) { + System.out.println("Woodwind.play() " + n); + } + @Override + String what() { return "Woodwind"; } +} + +public class Music3 { + // Doesn't care about type, so new types + // added to the system still work right: + public static void tune(Instrument i) { + // ... + i.play(Note.MIDDLE_C); + } + public static void tuneAll(Instrument[] e) { + for(Instrument i : e) + tune(i); + } + public static void main(String[] args) { + // Upcasting during addition to the array: + Instrument[] orchestra = { + new Wind(), + new Percussion(), + new Stringed(), + new Brass(), + new Woodwind() + }; + tuneAll(orchestra); + } +} +/* Output: +Wind.play() MIDDLE_C +Percussion.play() MIDDLE_C +Stringed.play() MIDDLE_C +Brass.play() MIDDLE_C +Woodwind.play() MIDDLE_C +*/ diff --git a/code/polymorphism/shape/Circle.java b/code/polymorphism/shape/Circle.java new file mode 100644 index 00000000..fc857950 --- /dev/null +++ b/code/polymorphism/shape/Circle.java @@ -0,0 +1,16 @@ +// polymorphism/shape/Circle.java +// (c)2020 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 polymorphism.shape; + +public class Circle extends Shape { + @Override + public void draw() { + System.out.println("Circle.draw()"); + } + @Override + public void erase() { + System.out.println("Circle.erase()"); + } +} diff --git a/code/polymorphism/shape/RandomShapes.java b/code/polymorphism/shape/RandomShapes.java new file mode 100644 index 00000000..c1419f4e --- /dev/null +++ b/code/polymorphism/shape/RandomShapes.java @@ -0,0 +1,26 @@ +// polymorphism/shape/RandomShapes.java +// (c)2020 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. +// A "factory" that randomly creates shapes +package polymorphism.shape; +import java.util.*; + +public class RandomShapes { + private Random rand = new Random(47); + public Shape get() { + switch(rand.nextInt(3)) { + default: + case 0: return new Circle(); + case 1: return new Square(); + case 2: return new Triangle(); + } + } + public Shape[] array(int sz) { + Shape[] shapes = new Shape[sz]; + // Fill up the array with shapes: + for(int i = 0; i < shapes.length; i++) + shapes[i] = get(); + return shapes; + } +} diff --git a/code/polymorphism/shape/Shape.java b/code/polymorphism/shape/Shape.java new file mode 100644 index 00000000..4be93c86 --- /dev/null +++ b/code/polymorphism/shape/Shape.java @@ -0,0 +1,10 @@ +// polymorphism/shape/Shape.java +// (c)2020 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 polymorphism.shape; + +public class Shape { + public void draw() {} + public void erase() {} +} diff --git a/code/polymorphism/shape/Square.java b/code/polymorphism/shape/Square.java new file mode 100644 index 00000000..4938335b --- /dev/null +++ b/code/polymorphism/shape/Square.java @@ -0,0 +1,16 @@ +// polymorphism/shape/Square.java +// (c)2020 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 polymorphism.shape; + +public class Square extends Shape { + @Override + public void draw() { + System.out.println("Square.draw()"); + } + @Override + public void erase() { + System.out.println("Square.erase()"); + } +} diff --git a/code/polymorphism/shape/Triangle.java b/code/polymorphism/shape/Triangle.java new file mode 100644 index 00000000..db7394a3 --- /dev/null +++ b/code/polymorphism/shape/Triangle.java @@ -0,0 +1,16 @@ +// polymorphism/shape/Triangle.java +// (c)2020 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 polymorphism.shape; + +public class Triangle extends Shape { + @Override + public void draw() { + System.out.println("Triangle.draw()"); + } + @Override + public void erase() { + System.out.println("Triangle.erase()"); + } +} diff --git a/code/references/AddingClone.java b/code/references/AddingClone.java new file mode 100644 index 00000000..4f03cf06 --- /dev/null +++ b/code/references/AddingClone.java @@ -0,0 +1,67 @@ +// references/AddingClone.java +// (c)2020 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. +// You must go through a few gyrations +// to add cloning to your own class +import java.util.*; +import java.util.stream.*; + +class Int2 implements Cloneable { + private int i; + Int2(int ii) { i = ii; } + public void increment() { i++; } + @Override + public String toString() { + return Integer.toString(i); + } + @Override + public Int2 clone() { + try { + return (Int2)super.clone(); + } catch(CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } +} + +// Inheritance doesn't remove cloneability: +class Int3 extends Int2 { + private int j; // Automatically duplicated + Int3(int i) { super(i); } +} + +public class AddingClone { + @SuppressWarnings("unchecked") + public static void main(String[] args) { + Int2 x = new Int2(10); + Int2 x2 = x.clone(); + x2.increment(); + System.out.println( + "x = " + x + ", x2 = " + x2); + // Anything inherited is also cloneable: + Int3 x3 = new Int3(7); + x3 = (Int3)x3.clone(); + ArrayList v = IntStream.range(0, 10) + .mapToObj(Int2::new) + .collect(Collectors + .toCollection(ArrayList::new)); + System.out.println("v: " + v); + ArrayList v2 = + (ArrayList)v.clone(); + // Now clone each element: + IntStream.range(0, v.size()) + .forEach(i -> v2.set(i, v.get(i).clone())); + // Increment all v2's elements: + v2.forEach(Int2::increment); + System.out.println("v2: " + v2); + // See if it changed v's elements: + System.out.println("v: " + v); + } +} +/* Output: +x = 10, x2 = 11 +v: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +v2: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +v: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +*/ diff --git a/code/references/Alias1.java b/code/references/Alias1.java new file mode 100644 index 00000000..1af594ec --- /dev/null +++ b/code/references/Alias1.java @@ -0,0 +1,27 @@ +// references/Alias1.java +// (c)2020 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. +// Aliasing two references to one object + +public class Alias1 { + private int i; + public Alias1(int ii) { i = ii; } + public static void main(String[] args) { + Alias1 x = new Alias1(7); + Alias1 y = x; // Assign the reference (1) + System.out.println("x: " + x.i); + System.out.println("y: " + y.i); + System.out.println("Incrementing x"); + x.i++; // [2] + System.out.println("x: " + x.i); + System.out.println("y: " + y.i); + } +} +/* Output: +x: 7 +y: 7 +Incrementing x +x: 8 +y: 8 +*/ diff --git a/code/references/Alias2.java b/code/references/Alias2.java new file mode 100644 index 00000000..aa37e1a2 --- /dev/null +++ b/code/references/Alias2.java @@ -0,0 +1,25 @@ +// references/Alias2.java +// (c)2020 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. +// Method calls implicitly alias their arguments + +public class Alias2 { + private int i; + public Alias2(int i) { this.i = i; } + public static void f(Alias2 reference) { + reference.i++; + } + public static void main(String[] args) { + Alias2 x = new Alias2(7); + System.out.println("x: " + x.i); + System.out.println("Calling f(x)"); + f(x); + System.out.println("x: " + x.i); + } +} +/* Output: +x: 7 +Calling f(x) +x: 8 +*/ diff --git a/code/references/CheckCloneable.java b/code/references/CheckCloneable.java new file mode 100644 index 00000000..137937a9 --- /dev/null +++ b/code/references/CheckCloneable.java @@ -0,0 +1,113 @@ +// references/CheckCloneable.java +// (c)2020 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. +// Check to see if a reference can be cloned + +// Can't clone this -- doesn't override clone(): +class Ordinary {} + +// Overrides clone, doesn't implement Cloneable: +class WrongClone extends Ordinary { + @Override public Object clone() + throws CloneNotSupportedException { + return super.clone(); // Throws exception + } +} + +// Does all the right things for cloning: +class IsCloneable extends Ordinary +implements Cloneable { + @Override public Object clone() + throws CloneNotSupportedException { + return super.clone(); + } +} + +// Turn off cloning by throwing the exception: +class NoMore extends IsCloneable { + @Override public Object clone() + throws CloneNotSupportedException { + throw new CloneNotSupportedException(); + } +} + +class TryMore extends NoMore { + @Override public Object clone() + throws CloneNotSupportedException { + // Calls NoMore.clone(), throws exception: + return super.clone(); + } +} + +class BackOn extends NoMore { + private BackOn duplicate(BackOn b) { + // Somehow make a copy of b and return that + // copy. A dummy copy, just to make a point: + return new BackOn(); + } + @Override + public Object clone() { + // Doesn't call NoMore.clone(): + return duplicate(this); + } +} + +// You can't inherit from this, so you can't +// override clone() as you can in BackOn: +final class ReallyNoMore extends NoMore {} + +public class CheckCloneable { + public static + Ordinary tryToClone(Ordinary ord) { + String id = ord.getClass().getName(); + System.out.println("Attempting " + id); + Ordinary x = null; + if(ord instanceof Cloneable) { + try { + x = (Ordinary)((IsCloneable)ord).clone(); + System.out.println("Cloned " + id); + } catch(CloneNotSupportedException e) { + System.out.println( + "Could not clone " + id); + } + } else { + System.out.println("Doesn't implement Cloneable"); + } + return x; + } + public static void main(String[] args) { + // Upcasting: + Ordinary[] ord = { + new IsCloneable(), + new WrongClone(), + new NoMore(), + new TryMore(), + new BackOn(), + new ReallyNoMore(), + }; + Ordinary x = new Ordinary(); + // This won't compile because + // clone() is protected in Object: + //- x = (Ordinary)x.clone(); + // Checks first to see if the class + // implements Cloneable: + for(Ordinary ord1 : ord) { + tryToClone(ord1); + } + } +} +/* Output: +Attempting IsCloneable +Cloned IsCloneable +Attempting WrongClone +Doesn't implement Cloneable +Attempting NoMore +Could not clone NoMore +Attempting TryMore +Could not clone TryMore +Attempting BackOn +Cloned BackOn +Attempting ReallyNoMore +Could not clone ReallyNoMore +*/ diff --git a/code/references/CloneArrayList.java b/code/references/CloneArrayList.java new file mode 100644 index 00000000..601673c2 --- /dev/null +++ b/code/references/CloneArrayList.java @@ -0,0 +1,38 @@ +// references/CloneArrayList.java +// (c)2020 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. +// The clone() operation works for only a few +// items in the standard Java library +import java.util.*; +import java.util.stream.*; + +class Int { + private int i; + Int(int ii) { i = ii; } + public void increment() { i++; } + @Override + public String toString() { + return Integer.toString(i); + } +} + +public class CloneArrayList { + public static void main(String[] args) { + ArrayList v = IntStream.range(0, 10) + .mapToObj(Int::new) + .collect(Collectors + .toCollection(ArrayList::new)); + System.out.println("v: " + v); + @SuppressWarnings("unchecked") + ArrayList v2 = (ArrayList)v.clone(); + // Increment all v2's elements: + v2.forEach(Int::increment); + // See if it changed v's elements: + System.out.println("v: " + v); + } +} +/* Output: +v: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +v: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +*/ diff --git a/code/references/Compete.java b/code/references/Compete.java new file mode 100644 index 00000000..9e77f3a7 --- /dev/null +++ b/code/references/Compete.java @@ -0,0 +1,89 @@ +// references/Compete.java +// (c)2020 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. +import java.io.*; +import onjava.Timer; + +class Thing1 implements Serializable {} +class Thing2 implements Serializable { + Thing1 t1 = new Thing1(); +} + +class Thing3 implements Cloneable { + @Override + public Thing3 clone() { + try { + return (Thing3)super.clone(); + } catch(CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } +} + +class Thing4 implements Cloneable { + private Thing3 t3 = new Thing3(); + @Override + public Thing4 clone() { + Thing4 t4 = null; + try { + t4 = (Thing4)super.clone(); + } catch(CloneNotSupportedException e) { + throw new RuntimeException(e); + } + // Clone the field, too: + t4.t3 = t3.clone(); + return t4; + } +} + +public class Compete { + public static final int SIZE = 100000; + public static void + main(String[] args) throws Exception { + Thing2[] a = new Thing2[SIZE]; + for(int i = 0; i < SIZE; i++) + a[i] = new Thing2(); + Thing4[] b = new Thing4[SIZE]; + for(int i = 0; i < SIZE; i++) + b[i] = new Thing4(); + Timer timer = new Timer(); + try( + ByteArrayOutputStream buf = + new ByteArrayOutputStream(); + ObjectOutputStream oos = + new ObjectOutputStream(buf) + ) { + for(Thing2 a1 : a) { + oos.writeObject(a1); + } + // Now get copies: + try( + ObjectInputStream in = + new ObjectInputStream( + new ByteArrayInputStream( + buf.toByteArray())) + ) { + Thing2[] c = new Thing2[SIZE]; + for(int i = 0; i < SIZE; i++) + c[i] = (Thing2)in.readObject(); + } + } + System.out.println( + "Duplication via serialization: " + + timer.duration() + " Milliseconds"); + + // Now try cloning: + timer = new Timer(); + Thing4[] d = new Thing4[SIZE]; + for(int i = 0; i < SIZE; i++) + d[i] = b[i].clone(); + System.out.println( + "Duplication via cloning: " + + timer.duration() + " Milliseconds"); + } +} +/* Output: +Duplication via serialization: 516 Milliseconds +Duplication via cloning: 71 Milliseconds +*/ diff --git a/code/references/CopyConstructor.java b/code/references/CopyConstructor.java new file mode 100644 index 00000000..2617f48b --- /dev/null +++ b/code/references/CopyConstructor.java @@ -0,0 +1,188 @@ +// references/CopyConstructor.java +// (c)2020 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. +// A constructor to copy an object of the same +// type, as an attempt to create a local copy +import java.lang.reflect.*; + +class FruitQualities { + private int weight; + private int color; + private int firmness; + private int ripeness; + private int smell; + // etc. + // No-arg constructor: + FruitQualities() { + // Do something meaningful... + } + // Other constructors: + // ... + // Copy constructor: + FruitQualities(FruitQualities f) { + weight = f.weight; + color = f.color; + firmness = f.firmness; + ripeness = f.ripeness; + smell = f.smell; + // etc. + } +} + +class Seed { + // Members... + Seed() { /* No-arg constructor */ } + Seed(Seed s) { /* Copy constructor */ } +} + +class Fruit { + private FruitQualities fq; + private int seeds; + private Seed[] s; + Fruit(FruitQualities q, int seedCount) { + fq = q; + seeds = seedCount; + s = new Seed[seeds]; + for(int i = 0; i < seeds; i++) + s[i] = new Seed(); + } + // Other constructors: + // ... + // Copy constructor: + Fruit(Fruit f) { + fq = new FruitQualities(f.fq); + seeds = f.seeds; + s = new Seed[seeds]; + // Call all Seed copy-constructors: + for(int i = 0; i < seeds; i++) + s[i] = new Seed(f.s[i]); + // Other copy-construction activities... + } + // This allows derived constructors (or other + // methods) to put in different qualities: + protected void addQualities(FruitQualities q) { + fq = q; + } + protected FruitQualities getQualities() { + return fq; + } +} + +class Tomato extends Fruit { + Tomato() { + super(new FruitQualities(), 100); + } + Tomato(Tomato t) { // Copy-constructor + super(t); // Upcast to base copy-constructor + // Other copy-construction activities... + } +} + +class ZebraQualities extends FruitQualities { + private int stripedness; + // No-arg constructor: + ZebraQualities() { + super(); + // do something meaningful... + } + ZebraQualities(ZebraQualities z) { + super(z); + stripedness = z.stripedness; + } +} + +class GreenZebra extends Tomato { + GreenZebra() { + addQualities(new ZebraQualities()); + } + GreenZebra(GreenZebra g) { + super(g); // Calls Tomato(Tomato) + // Restore the right qualities: + addQualities(new ZebraQualities()); + } + public void evaluate() { + ZebraQualities zq = + (ZebraQualities)getQualities(); + // Do something with the qualities + // ... + } +} + +public class CopyConstructor { + public static void ripen(Tomato t) { + // Use the "copy constructor": + t = new Tomato(t); // [1] + System.out.println("In ripen, t is a " + + t.getClass().getName()); + } + public static void slice(Fruit f) { + f = new Fruit(f); // [2] Hmmm... will this work? + System.out.println("In slice, f is a " + + f.getClass().getName()); + } + @SuppressWarnings("unchecked") + public static void ripen2(Tomato t) { + try { + Class c = t.getClass(); + // Use the "copy constructor": + Constructor ct = + c.getConstructor(new Class[] { c }); + Object obj = + ct.newInstance(new Object[] { t }); + System.out.println("In ripen2, t is a " + + obj.getClass().getName()); + } catch(NoSuchMethodException | + SecurityException | + InstantiationException | + IllegalAccessException | + IllegalArgumentException | + InvocationTargetException e) { + System.out.println(e); + } + } + @SuppressWarnings("unchecked") + public static void slice2(Fruit f) { + try { + Class c = f.getClass(); + Constructor ct = + c.getConstructor(new Class[] { c }); + Object obj = + ct.newInstance(new Object[] { f }); + System.out.println("In slice2, f is a " + + obj.getClass().getName()); + } catch(NoSuchMethodException | + SecurityException | + InstantiationException | + IllegalAccessException | + IllegalArgumentException | + InvocationTargetException e) { + System.out.println(e); + } + } + public static void main(String[] args) { + Tomato tomato = new Tomato(); + ripen(tomato); // OK + slice(tomato); // OOPS! + ripen2(tomato); // OK + slice2(tomato); // OK + GreenZebra g = new GreenZebra(); + ripen(g); // OOPS! + slice(g); // OOPS! + ripen2(g); // OK + slice2(g); // OK + g.evaluate(); + } +} +/* Output: +In ripen, t is a Tomato +In slice, f is a Fruit +java.lang.NoSuchMethodException: Tomato.(Tomato) +java.lang.NoSuchMethodException: Tomato.(Tomato) +In ripen, t is a Tomato +In slice, f is a Fruit +java.lang.NoSuchMethodException: +GreenZebra.(GreenZebra) +java.lang.NoSuchMethodException: +GreenZebra.(GreenZebra) +*/ diff --git a/code/references/DepthReading.java b/code/references/DepthReading.java new file mode 100644 index 00000000..00d9dfda --- /dev/null +++ b/code/references/DepthReading.java @@ -0,0 +1,29 @@ +// references/DepthReading.java +// (c)2020 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. +// Cloning a composed object +package references; + +public class DepthReading implements Cloneable { + private double depth; + public DepthReading(double depth) { + this.depth = depth; + } + @Override + public DepthReading clone() { + try { + return (DepthReading)super.clone(); + } catch(CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } + public double getDepth() { return depth; } + public void setDepth(double depth) { + this.depth = depth; + } + @Override + public String toString() { + return String.valueOf(depth); + } +} diff --git a/code/references/HorrorFlick.java b/code/references/HorrorFlick.java new file mode 100644 index 00000000..709d15bf --- /dev/null +++ b/code/references/HorrorFlick.java @@ -0,0 +1,35 @@ +// references/HorrorFlick.java +// (c)2020 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. +// Insert Cloneability at any level of inheritance + +class Person {} + +class Hero extends Person {} + +class Scientist extends Person implements Cloneable { + @Override + public Scientist clone() { + try { + return (Scientist)super.clone(); + } catch(CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } +} + +class MadScientist extends Scientist {} + +public class HorrorFlick { + public static void main(String[] args) { + Person p = new Person(); + Hero h = new Hero(); + Scientist s = new Scientist(); + MadScientist m = new MadScientist(); + //- p = (Person)p.clone(); // Compile error + //- h = (Hero)h.clone(); // Compile error + s = s.clone(); + m = (MadScientist)m.clone(); + } +} diff --git a/code/references/Immutable1.java b/code/references/Immutable1.java new file mode 100644 index 00000000..55ac1f6a --- /dev/null +++ b/code/references/Immutable1.java @@ -0,0 +1,34 @@ +// references/Immutable1.java +// (c)2020 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. +// Immutable objects are immune to aliasing + +public class Immutable1 { + private int data; + public Immutable1(int initVal) { + data = initVal; + } + public int read() { return data; } + public boolean nonzero() { return data != 0; } + public Immutable1 multiply(int multiplier) { + return new Immutable1(data * multiplier); + } + public static void f(Immutable1 i1) { + Immutable1 quad = i1.multiply(4); + System.out.println("i1 = " + i1.read()); + System.out.println("quad = " + quad.read()); + } + public static void main(String[] args) { + Immutable1 x = new Immutable1(47); + System.out.println("x = " + x.read()); + f(x); + System.out.println("x = " + x.read()); + } +} +/* Output: +x = 47 +i1 = 47 +quad = 188 +x = 47 +*/ diff --git a/code/references/Immutable2.java b/code/references/Immutable2.java new file mode 100644 index 00000000..a565f86a --- /dev/null +++ b/code/references/Immutable2.java @@ -0,0 +1,71 @@ +// references/Immutable2.java +// (c)2020 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. +// A companion class to modify immutable objects + +class Mutable { + private int data; + Mutable(int initVal) { + data = initVal; + } + public Mutable add(int x) { + data += x; + return this; + } + public Mutable multiply(int x) { + data *= x; + return this; + } + public Immutable2 makeImmutable2() { + return new Immutable2(data); + } +} + +public class Immutable2 { + private int data; + public Immutable2(int initVal) { + data = initVal; + } + public int read() { return data; } + public boolean nonzero() { + return data != 0; + } + public Immutable2 add(int x) { + return new Immutable2(data + x); + } + public Immutable2 multiply(int x) { + return new Immutable2(data * x); + } + public Mutable makeMutable() { + return new Mutable(data); + } + public static + Immutable2 modify1(Immutable2 y) { + Immutable2 val = y.add(12); + val = val.multiply(3); + val = val.add(11); + val = val.multiply(2); + return val; + } + // This produces the same result: + public static + Immutable2 modify2(Immutable2 y) { + Mutable m = y.makeMutable(); + m.add(12).multiply(3).add(11).multiply(2); + return m.makeImmutable2(); + } + public static void main(String[] args) { + Immutable2 i2 = new Immutable2(47); + Immutable2 r1 = modify1(i2); + Immutable2 r2 = modify2(i2); + System.out.println("i2 = " + i2.read()); + System.out.println("r1 = " + r1.read()); + System.out.println("r2 = " + r2.read()); + } +} +/* Output: +i2 = 47 +r1 = 376 +r2 = 376 +*/ diff --git a/code/references/ImmutableInteger.java b/code/references/ImmutableInteger.java new file mode 100644 index 00000000..906aa7ef --- /dev/null +++ b/code/references/ImmutableInteger.java @@ -0,0 +1,22 @@ +// references/ImmutableInteger.java +// (c)2020 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. +// The Integer class cannot be changed +import java.util.*; +import java.util.stream.*; + +public class ImmutableInteger { + public static void main(String[] args) { + @SuppressWarnings("deprecation") + List v = IntStream.range(0, 10) + .mapToObj(Integer::new) + .collect(Collectors.toList()); + System.out.println(v); + // But how do you change the int + // inside the Integer? + } +} +/* Output: +[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +*/ diff --git a/code/references/ImmutableStrings.java b/code/references/ImmutableStrings.java new file mode 100644 index 00000000..ad954e3f --- /dev/null +++ b/code/references/ImmutableStrings.java @@ -0,0 +1,25 @@ +// references/ImmutableStrings.java +// (c)2020 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. +// Demonstrating StringBuilder + +public class ImmutableStrings { + public static void main(String[] args) { + String foo = "foo"; + String s = "abc" + foo + "def" + + Integer.toString(47); + System.out.println(s); + // The "equivalent" using StringBuilder: + StringBuilder sb = + new StringBuilder("abc"); // Creates String + sb.append(foo); + sb.append("def"); // Creates String + sb.append(Integer.toString(47)); + System.out.println(sb); + } +} +/* Output: +abcfoodef47 +abcfoodef47 +*/ diff --git a/code/references/LocalCopy.java b/code/references/LocalCopy.java new file mode 100644 index 00000000..9c01c09e --- /dev/null +++ b/code/references/LocalCopy.java @@ -0,0 +1,57 @@ +// references/LocalCopy.java +// (c)2020 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. +// Creating local copies with clone() + +class Duplo implements Cloneable { + private int n; + Duplo(int n) { this.n = n; } + @Override + public Duplo clone() { // [1] + try { + return (Duplo)super.clone(); + } catch(CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } + public int getValue() { return n; } + public void setValue(int n) { this.n = n; } + public void increment() { n++; } + @Override + public String toString() { + return Integer.toString(n); + } +} + +public class LocalCopy { + public static Duplo g(Duplo v) { + // Passing a reference, modifies outside object: + v.increment(); + return v; + } + public static Duplo f(Duplo v) { + v = v.clone(); // [2] Local copy + v.increment(); + return v; + } + public static void main(String[] args) { + Duplo a = new Duplo(11); + Duplo b = g(a); + // Reference equivalence, not object equivalence: + System.out.println("a == b: " + (a == b) + + "\na = " + a + "\nb = " + b); + Duplo c = new Duplo(47); + Duplo d = f(c); + System.out.println("c == d: " + (c == d) + + "\nc = " + c + "\nd = " + d); + } +} +/* Output: +a == b: true +a = 12 +b = 12 +c == d: false +c = 47 +d = 48 +*/ diff --git a/code/references/MutableInteger.java b/code/references/MutableInteger.java new file mode 100644 index 00000000..dfe0cc7b --- /dev/null +++ b/code/references/MutableInteger.java @@ -0,0 +1,34 @@ +// references/MutableInteger.java +// (c)2020 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. +// A changeable wrapper class +import java.util.*; +import java.util.stream.*; + +class IntValue { + private int n; + IntValue(int x) { n = x; } + public int getValue() { return n; } + public void setValue(int n) { this.n = n; } + public void increment() { n++; } + @Override + public String toString() { + return Integer.toString(n); + } +} + +public class MutableInteger { + public static void main(String[] args) { + List v = IntStream.range(0, 10) + .mapToObj(IntValue::new) + .collect(Collectors.toList()); + System.out.println(v); + v.forEach(IntValue::increment); + System.out.println(v); + } +} +/* Output: +[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +*/ diff --git a/code/references/OceanReading.java b/code/references/OceanReading.java new file mode 100644 index 00000000..b89f1b04 --- /dev/null +++ b/code/references/OceanReading.java @@ -0,0 +1,48 @@ +// references/OceanReading.java +// (c)2020 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. +// Cloning a composed object +package references; + +public class OceanReading implements Cloneable { + private DepthReading depth; + private TemperatureReading temperature; + public + OceanReading(double tdata, double ddata) { + temperature = new TemperatureReading(tdata); + depth = new DepthReading(ddata); + } + @Override + public OceanReading clone() { + OceanReading or = null; + try { + or = (OceanReading)super.clone(); + } catch(CloneNotSupportedException e) { + throw new RuntimeException(e); + } + // Must clone references: + or.depth = (DepthReading)or.depth.clone(); + or.temperature = + (TemperatureReading)or.temperature.clone(); + return or; + } + public TemperatureReading getTemperatureReading() { + return temperature; + } + public void + setTemperatureReading(TemperatureReading tr) { + temperature = tr; + } + public DepthReading getDepthReading() { + return depth; + } + public void setDepthReading(DepthReading dr) { + this.depth = dr; + } + @Override + public String toString() { + return "temperature: " + temperature + + ", depth: " + depth; + } +} diff --git a/code/references/PassReferences.java b/code/references/PassReferences.java new file mode 100644 index 00000000..2a163008 --- /dev/null +++ b/code/references/PassReferences.java @@ -0,0 +1,19 @@ +// references/PassReferences.java +// (c)2020 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. + +public class PassReferences { + public static void f(PassReferences h) { + System.out.println("h inside f(): " + h); + } + public static void main(String[] args) { + PassReferences p = new PassReferences(); + System.out.println("p inside main(): " + p); + f(p); + } +} +/* Output: +p inside main(): PassReferences@15db9742 +h inside f(): PassReferences@15db9742 +*/ diff --git a/code/references/SimplerMutableInteger.java b/code/references/SimplerMutableInteger.java new file mode 100644 index 00000000..191068ca --- /dev/null +++ b/code/references/SimplerMutableInteger.java @@ -0,0 +1,30 @@ +// references/SimplerMutableInteger.java +// (c)2020 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. +// A trivial wrapper class +import java.util.*; +import java.util.stream.*; + +class IntValue2 { + public int n; + IntValue2(int n) { this.n = n; } +} + +public class SimplerMutableInteger { + public static void main(String[] args) { + List v = IntStream.range(0, 10) + .mapToObj(IntValue2::new) + .collect(Collectors.toList()); + v.forEach(iv2 -> + System.out.print(iv2.n + " ")); + System.out.println(); + v.forEach(iv2 -> iv2.n += 1); + v.forEach(iv2 -> + System.out.print(iv2.n + " ")); + } +} +/* Output: +0 1 2 3 4 5 6 7 8 9 +1 2 3 4 5 6 7 8 9 10 +*/ diff --git a/code/references/Snake.java b/code/references/Snake.java new file mode 100644 index 00000000..004f7e76 --- /dev/null +++ b/code/references/Snake.java @@ -0,0 +1,51 @@ +// references/Snake.java +// (c)2020 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. +// Tests cloning to see if reference +// destinations are also cloned + +public class Snake implements Cloneable { + private Snake next; + private char c; + // Value of i == number of segments + public Snake(int i, char x) { + c = x; + if(--i > 0) + next = new Snake(i, (char)(x + 1)); + } + public void increment() { + c++; + if(next != null) + next.increment(); + } + @Override + public String toString() { + String s = ":" + c; + if(next != null) + s += next.toString(); + return s; + } + @Override + public Snake clone() { + try { + return (Snake)super.clone(); + } catch(CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } + public static void main(String[] args) { + Snake s = new Snake(5, 'a'); + System.out.println("s = " + s); + Snake s2 = s.clone(); + System.out.println("s2 = " + s2); + s.increment(); + System.out.println( + "after s.increment, s2 = " + s2); + } +} +/* Output: +s = :a:b:c:d:e +s2 = :a:b:c:d:e +after s.increment, s2 = :a:c:d:e:f +*/ diff --git a/code/references/Stringer.java b/code/references/Stringer.java new file mode 100644 index 00000000..72663bb5 --- /dev/null +++ b/code/references/Stringer.java @@ -0,0 +1,22 @@ +// references/Stringer.java +// (c)2020 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. + +public class Stringer { + public static String upcase(String s) { + return s.toUpperCase(); + } + public static void main(String[] args) { + String q = new String("howdy"); + System.out.println(q); // howdy + String qq = upcase(q); + System.out.println(qq); // HOWDY + System.out.println(q); // howdy + } +} +/* Output: +howdy +HOWDY +howdy +*/ diff --git a/code/references/TemperatureReading.java b/code/references/TemperatureReading.java new file mode 100644 index 00000000..9b77cfb2 --- /dev/null +++ b/code/references/TemperatureReading.java @@ -0,0 +1,33 @@ +// references/TemperatureReading.java +// (c)2020 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. +// Cloning a composed object +package references; + +public class TemperatureReading implements Cloneable { + private long time; + private double temperature; + public TemperatureReading(double temperature) { + time = System.currentTimeMillis(); + this.temperature = temperature; + } + @Override + public TemperatureReading clone() { + try { + return (TemperatureReading)super.clone(); + } catch(CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } + public double getTemperature() { + return temperature; + } + public void setTemperature(double temp) { + this.temperature = temp; + } + @Override + public String toString() { + return String.valueOf(temperature); + } +} diff --git a/code/references/tests/DeepCopyTest.java b/code/references/tests/DeepCopyTest.java new file mode 100644 index 00000000..b65a8d89 --- /dev/null +++ b/code/references/tests/DeepCopyTest.java @@ -0,0 +1,28 @@ +// references/tests/DeepCopyTest.java +// (c)2020 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 references; +import org.junit.jupiter.api.*; +import static org.junit.jupiter.api.Assertions.*; + +public class DeepCopyTest { + @Test + public void testClone() { + OceanReading reading = + new OceanReading(33.9, 100.5); + // Now clone it: + OceanReading clone = reading.clone(); + TemperatureReading tr = + clone.getTemperatureReading(); + tr.setTemperature(tr.getTemperature() + 1); + clone.setTemperatureReading(tr); + DepthReading dr = clone.getDepthReading(); + dr.setDepth(dr.getDepth() + 1); + clone.setDepthReading(dr); + assertEquals(reading.toString(), + "temperature: 33.9, depth: 100.5"); + assertEquals(clone.toString(), + "temperature: 34.9, depth: 101.5"); + } +} diff --git a/code/reuse/Bath.java b/code/reuse/Bath.java new file mode 100644 index 00000000..38e5e819 --- /dev/null +++ b/code/reuse/Bath.java @@ -0,0 +1,61 @@ +// reuse/Bath.java +// (c)2020 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. +// Constructor initialization with composition + +class Soap { + private String s; + Soap() { + System.out.println("Soap()"); + s = "Constructed"; + } + @Override + public String toString() { return s; } +} + +public class Bath { + private String // Initializing at point of definition: + s1 = "Happy", + s2 = "Happy", + s3, s4; + private Soap castille; + private int i; + private float toy; + public Bath() { + System.out.println("Inside Bath()"); + s3 = "Joy"; + toy = 3.14f; + castille = new Soap(); + } + // Instance initialization: + { i = 47; } + @Override + public String toString() { + if(s4 == null) // Delayed initialization: + s4 = "Joy"; + return + "s1 = " + s1 + "\n" + + "s2 = " + s2 + "\n" + + "s3 = " + s3 + "\n" + + "s4 = " + s4 + "\n" + + "i = " + i + "\n" + + "toy = " + toy + "\n" + + "castille = " + castille; + } + public static void main(String[] args) { + Bath b = new Bath(); + System.out.println(b); + } +} +/* Output: +Inside Bath() +Soap() +s1 = Happy +s2 = Happy +s3 = Joy +s4 = Joy +i = 47 +toy = 3.14 +castille = Constructed +*/ diff --git a/code/reuse/Beetle.java b/code/reuse/Beetle.java new file mode 100644 index 00000000..0a41bc17 --- /dev/null +++ b/code/reuse/Beetle.java @@ -0,0 +1,43 @@ +// reuse/Beetle.java +// (c)2020 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. +// The full process of initialization + +class Insect { + private int i = 9; + protected int j; + Insect() { + System.out.println("i = " + i + ", j = " + j); + j = 39; + } + private static int x1 = + printInit("static Insect.x1 initialized"); + static int printInit(String s) { + System.out.println(s); + return 47; + } +} + +public class Beetle extends Insect { + private int k = printInit("Beetle.k initialized"); + public Beetle() { + System.out.println("k = " + k); + System.out.println("j = " + j); + } + private static int x2 = + printInit("static Beetle.x2 initialized"); + public static void main(String[] args) { + System.out.println("Beetle constructor"); + Beetle b = new Beetle(); + } +} +/* Output: +static Insect.x1 initialized +static Beetle.x2 initialized +Beetle constructor +i = 9, j = 0 +Beetle.k initialized +k = 47 +j = 39 +*/ diff --git a/code/reuse/BlankFinal.java b/code/reuse/BlankFinal.java new file mode 100644 index 00000000..93818a06 --- /dev/null +++ b/code/reuse/BlankFinal.java @@ -0,0 +1,29 @@ +// reuse/BlankFinal.java +// (c)2020 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. +// "Blank" final fields + +class Poppet { + private int i; + Poppet(int ii) { i = ii; } +} + +public class BlankFinal { + private final int i = 0; // Initialized final + private final int j; // Blank final + private final Poppet p; // Blank final reference + // Blank finals MUST be initialized in constructor: + public BlankFinal() { + j = 1; // Initialize blank final + p = new Poppet(1); // Init blank final reference + } + public BlankFinal(int x) { + j = x; // Initialize blank final + p = new Poppet(x); // Init blank final reference + } + public static void main(String[] args) { + new BlankFinal(); + new BlankFinal(47); + } +} diff --git a/code/reuse/CADSystem.java b/code/reuse/CADSystem.java new file mode 100644 index 00000000..55fbe0d8 --- /dev/null +++ b/code/reuse/CADSystem.java @@ -0,0 +1,116 @@ +// reuse/CADSystem.java +// (c)2020 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. +// Ensuring proper cleanup +// {java reuse.CADSystem} +package reuse; + +class Shape { + Shape(int i) { + System.out.println("Shape constructor"); + } + void dispose() { + System.out.println("Shape dispose"); + } +} + +class Circle extends Shape { + Circle(int i) { + super(i); + System.out.println("Drawing Circle"); + } + @Override + void dispose() { + System.out.println("Erasing Circle"); + super.dispose(); + } +} + +class Triangle extends Shape { + Triangle(int i) { + super(i); + System.out.println("Drawing Triangle"); + } + @Override + void dispose() { + System.out.println("Erasing Triangle"); + super.dispose(); + } +} + +class Line extends Shape { + private int start, end; + Line(int start, int end) { + super(start); + this.start = start; + this.end = end; + System.out.println( + "Drawing Line: " + start + ", " + end); + } + @Override + void dispose() { + System.out.println( + "Erasing Line: " + start + ", " + end); + super.dispose(); + } +} + +public class CADSystem extends Shape { + private Circle c; + private Triangle t; + private Line[] lines = new Line[3]; + public CADSystem(int i) { + super(i + 1); + for(int j = 0; j < lines.length; j++) + lines[j] = new Line(j, j*j); + c = new Circle(1); + t = new Triangle(1); + System.out.println("Combined constructor"); + } + @Override + public void dispose() { + System.out.println("CADSystem.dispose()"); + // The order of cleanup is the reverse + // of the order of initialization: + t.dispose(); + c.dispose(); + for(int i = lines.length - 1; i >= 0; i--) + lines[i].dispose(); + super.dispose(); + } + public static void main(String[] args) { + CADSystem x = new CADSystem(47); + try { + // Code and exception handling... + } finally { + x.dispose(); + } + } +} +/* Output: +Shape constructor +Shape constructor +Drawing Line: 0, 0 +Shape constructor +Drawing Line: 1, 1 +Shape constructor +Drawing Line: 2, 4 +Shape constructor +Drawing Circle +Shape constructor +Drawing Triangle +Combined constructor +CADSystem.dispose() +Erasing Triangle +Shape dispose +Erasing Circle +Shape dispose +Erasing Line: 2, 4 +Shape dispose +Erasing Line: 1, 1 +Shape dispose +Erasing Line: 0, 0 +Shape dispose +Shape dispose +*/ diff --git a/code/reuse/Car.java b/code/reuse/Car.java new file mode 100644 index 00000000..1bc4377b --- /dev/null +++ b/code/reuse/Car.java @@ -0,0 +1,43 @@ +// reuse/Car.java +// (c)2020 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. +// Composition with public objects + +class Engine { + public void start() {} + public void rev() {} + public void stop() {} +} + +class Wheel { + public void inflate(int psi) {} +} + +class Window { + public void rollup() {} + public void rolldown() {} +} + +class Door { + public Window window = new Window(); + public void open() {} + public void close() {} +} + +public class Car { + public Engine engine = new Engine(); + public Wheel[] wheel = new Wheel[4]; + public Door + left = new Door(), + right = new Door(); // 2-door + public Car() { + for(int i = 0; i < 4; i++) + wheel[i] = new Wheel(); + } + public static void main(String[] args) { + Car car = new Car(); + car.left.window.rollup(); + car.wheel[0].inflate(72); + } +} diff --git a/code/reuse/Cartoon.java b/code/reuse/Cartoon.java new file mode 100644 index 00000000..48741baf --- /dev/null +++ b/code/reuse/Cartoon.java @@ -0,0 +1,31 @@ +// reuse/Cartoon.java +// (c)2020 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. +// Constructor calls during inheritance + +class Art { + Art() { + System.out.println("Art constructor"); + } +} + +class Drawing extends Art { + Drawing() { + System.out.println("Drawing constructor"); + } +} + +public class Cartoon extends Drawing { + public Cartoon() { + System.out.println("Cartoon constructor"); + } + public static void main(String[] args) { + Cartoon x = new Cartoon(); + } +} +/* Output: +Art constructor +Drawing constructor +Cartoon constructor +*/ diff --git a/code/reuse/Chess.java b/code/reuse/Chess.java new file mode 100644 index 00000000..30f2685b --- /dev/null +++ b/code/reuse/Chess.java @@ -0,0 +1,33 @@ +// reuse/Chess.java +// (c)2020 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. +// Inheritance, constructors and arguments + +class Game { + Game(int i) { + System.out.println("Game constructor"); + } +} + +class BoardGame extends Game { + BoardGame(int i) { + super(i); + System.out.println("BoardGame constructor"); + } +} + +public class Chess extends BoardGame { + Chess() { + super(11); + System.out.println("Chess constructor"); + } + public static void main(String[] args) { + Chess x = new Chess(); + } +} +/* Output: +Game constructor +BoardGame constructor +Chess constructor +*/ diff --git a/code/reuse/DerivedSpaceShip.java b/code/reuse/DerivedSpaceShip.java new file mode 100644 index 00000000..dfbe20ac --- /dev/null +++ b/code/reuse/DerivedSpaceShip.java @@ -0,0 +1,19 @@ +// reuse/DerivedSpaceShip.java +// (c)2020 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. + +public class +DerivedSpaceShip extends SpaceShipControls { + private String name; + public DerivedSpaceShip(String name) { + this.name = name; + } + @Override + public String toString() { return name; } + public static void main(String[] args) { + DerivedSpaceShip protector = + new DerivedSpaceShip("NSEA Protector"); + protector.forward(100); + } +} diff --git a/code/reuse/Detergent.java b/code/reuse/Detergent.java new file mode 100644 index 00000000..99f4e7cc --- /dev/null +++ b/code/reuse/Detergent.java @@ -0,0 +1,48 @@ +// reuse/Detergent.java +// (c)2020 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. +// Inheritance syntax & properties + +class Cleanser { + private String s = "Cleanser"; + public void append(String a) { s += a; } + public void dilute() { append(" dilute()"); } + public void apply() { append(" apply()"); } + public void scrub() { append(" scrub()"); } + @Override + public String toString() { return s; } + public static void main(String[] args) { + Cleanser x = new Cleanser(); + x.dilute(); x.apply(); x.scrub(); + System.out.println(x); + } +} + +public class Detergent extends Cleanser { + // Change a method: + @Override + public void scrub() { + append(" Detergent.scrub()"); + super.scrub(); // Call base-class version + } + // Add methods to the interface: + public void foam() { append(" foam()"); } + // Test the new class: + public static void main(String[] args) { + Detergent x = new Detergent(); + x.dilute(); + x.apply(); + x.scrub(); + x.foam(); + System.out.println(x); + System.out.println("Testing base class:"); + Cleanser.main(args); + } +} +/* Output: +Cleanser dilute() apply() Detergent.scrub() scrub() +foam() +Testing base class: +Cleanser dilute() apply() scrub() +*/ diff --git a/code/reuse/FinalArguments.java b/code/reuse/FinalArguments.java new file mode 100644 index 00000000..46efed7e --- /dev/null +++ b/code/reuse/FinalArguments.java @@ -0,0 +1,27 @@ +// reuse/FinalArguments.java +// (c)2020 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. +// Using "final" with method arguments + +class Gizmo { + public void spin() {} +} + +public class FinalArguments { + void with(final Gizmo g) { + //- g = new Gizmo(); // Illegal -- g is final + } + void without(Gizmo g) { + g = new Gizmo(); // OK -- g not final + g.spin(); + } + // void f(final int i) { i++; } // Can't change + // You can only read from a final primitive: + int g(final int i) { return i + 1; } + public static void main(String[] args) { + FinalArguments bf = new FinalArguments(); + bf.without(null); + bf.with(null); + } +} diff --git a/code/reuse/FinalData.java b/code/reuse/FinalData.java new file mode 100644 index 00000000..4376f5c3 --- /dev/null +++ b/code/reuse/FinalData.java @@ -0,0 +1,57 @@ +// reuse/FinalData.java +// (c)2020 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. +// The effect of final on fields +import java.util.*; + +class Value { + int i; // Package access + Value(int i) { this.i = i; } +} + +public class FinalData { + private static Random rand = new Random(47); + private String id; + public FinalData(String id) { this.id = id; } + // Can be compile-time constants: + private final int valueOne = 9; + private static final int VALUE_TWO = 99; + // Typical public constant: + public static final int VALUE_THREE = 39; + // Cannot be compile-time constants: + private final int i4 = rand.nextInt(20); + static final int INT_5 = rand.nextInt(20); + private Value v1 = new Value(11); + private final Value v2 = new Value(22); + private static final Value VAL_3 = new Value(33); + // Arrays: + private final int[] a = { 1, 2, 3, 4, 5, 6 }; + @Override + public String toString() { + return id + ": " + "i4 = " + i4 + + ", INT_5 = " + INT_5; + } + public static void main(String[] args) { + FinalData fd1 = new FinalData("fd1"); + //- fd1.valueOne++; // Error: can't change value + fd1.v2.i++; // Object isn't constant! + fd1.v1 = new Value(9); // OK -- not final + for(int i = 0; i < fd1.a.length; i++) + fd1.a[i]++; // Object isn't constant! + //- fd1.v2 = new Value(0); // Error: Can't + //- fd1.VAL_3 = new Value(1); // change reference + //- fd1.a = new int[3]; + System.out.println(fd1); + System.out.println("Creating new FinalData"); + FinalData fd2 = new FinalData("fd2"); + System.out.println(fd1); + System.out.println(fd2); + } +} +/* Output: +fd1: i4 = 15, INT_5 = 18 +Creating new FinalData +fd1: i4 = 15, INT_5 = 18 +fd2: i4 = 13, INT_5 = 18 +*/ diff --git a/code/reuse/FinalOverridingIllusion.java b/code/reuse/FinalOverridingIllusion.java new file mode 100644 index 00000000..e5c19ece --- /dev/null +++ b/code/reuse/FinalOverridingIllusion.java @@ -0,0 +1,56 @@ +// reuse/FinalOverridingIllusion.java +// (c)2020 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. +// It only looks like you can override +// a private or private final method + +class WithFinals { + // Identical to "private" alone: + private final void f() { + System.out.println("WithFinals.f()"); + } + // Also automatically "final": + private void g() { + System.out.println("WithFinals.g()"); + } +} + +class OverridingPrivate extends WithFinals { + private final void f() { + System.out.println("OverridingPrivate.f()"); + } + private void g() { + System.out.println("OverridingPrivate.g()"); + } +} + +class OverridingPrivate2 extends OverridingPrivate { + public final void f() { + System.out.println("OverridingPrivate2.f()"); + } + public void g() { + System.out.println("OverridingPrivate2.g()"); + } +} + +public class FinalOverridingIllusion { + public static void main(String[] args) { + OverridingPrivate2 op2 = new OverridingPrivate2(); + op2.f(); + op2.g(); + // You can upcast: + OverridingPrivate op = op2; + // But you can't call the methods: + //- op.f(); + //- op.g(); + // Same here: + WithFinals wf = op2; + //- wf.f(); + //- wf.g(); + } +} +/* Output: +OverridingPrivate2.f() +OverridingPrivate2.g() +*/ diff --git a/code/reuse/Hide.java b/code/reuse/Hide.java new file mode 100644 index 00000000..f718e4b0 --- /dev/null +++ b/code/reuse/Hide.java @@ -0,0 +1,41 @@ +// reuse/Hide.java +// (c)2020 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. +// Overloading a base-class method name in a derived +// class does not hide the base-class versions + +class Homer { + char doh(char c) { + System.out.println("doh(char)"); + return 'd'; + } + float doh(float f) { + System.out.println("doh(float)"); + return 1.0f; + } +} + +class Milhouse {} + +class Bart extends Homer { + void doh(Milhouse m) { + System.out.println("doh(Milhouse)"); + } +} + +public class Hide { + public static void main(String[] args) { + Bart b = new Bart(); + b.doh(1); + b.doh('x'); + b.doh(1.0f); + b.doh(new Milhouse()); + } +} +/* Output: +doh(float) +doh(char) +doh(float) +doh(Milhouse) +*/ diff --git a/code/reuse/Jurassic.java b/code/reuse/Jurassic.java new file mode 100644 index 00000000..04b7d61c --- /dev/null +++ b/code/reuse/Jurassic.java @@ -0,0 +1,26 @@ +// reuse/Jurassic.java +// (c)2020 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. +// Making an entire class final + +class SmallBrain {} + +final class Dinosaur { + int i = 7; + int j = 1; + SmallBrain x = new SmallBrain(); + void f() {} +} + +//- class Further extends Dinosaur {} +// error: Cannot extend final class 'Dinosaur' + +public class Jurassic { + public static void main(String[] args) { + Dinosaur n = new Dinosaur(); + n.f(); + n.i = 40; + n.j++; + } +} diff --git a/code/reuse/Lisa.java b/code/reuse/Lisa.java new file mode 100644 index 00000000..85ec5cc9 --- /dev/null +++ b/code/reuse/Lisa.java @@ -0,0 +1,11 @@ +// reuse/Lisa.java +// (c)2020 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. +// {WillNotCompile} + +class Lisa extends Homer { + @Override void doh(Milhouse m) { + System.out.println("doh(Milhouse)"); + } +} diff --git a/code/reuse/Orc.java b/code/reuse/Orc.java new file mode 100644 index 00000000..c3ba40a8 --- /dev/null +++ b/code/reuse/Orc.java @@ -0,0 +1,41 @@ +// reuse/Orc.java +// (c)2020 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. +// The protected keyword + +class Villain { + private String name; + protected void set(String nm) { name = nm; } + Villain(String name) { this.name = name; } + @Override + public String toString() { + return "I'm a Villain and my name is " + name; + } +} + +public class Orc extends Villain { + private int orcNumber; + public Orc(String name, int orcNumber) { + super(name); + this.orcNumber = orcNumber; + } + public void change(String name, int orcNumber) { + set(name); // Available because it's protected + this.orcNumber = orcNumber; + } + @Override + public String toString() { + return "Orc " + orcNumber + ": " + super.toString(); + } + public static void main(String[] args) { + Orc orc = new Orc("Limburger", 12); + System.out.println(orc); + orc.change("Bob", 19); + System.out.println(orc); + } +} +/* Output: +Orc 12: I'm a Villain and my name is Limburger +Orc 19: I'm a Villain and my name is Bob +*/ diff --git a/code/reuse/PlaceSetting.java b/code/reuse/PlaceSetting.java new file mode 100644 index 00000000..b57d6383 --- /dev/null +++ b/code/reuse/PlaceSetting.java @@ -0,0 +1,82 @@ +// reuse/PlaceSetting.java +// (c)2020 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. +// Combining composition & inheritance + +class Plate { + Plate(int i) { + System.out.println("Plate constructor"); + } +} + +class DinnerPlate extends Plate { + DinnerPlate(int i) { + super(i); + System.out.println("DinnerPlate constructor"); + } +} + +class Utensil { + Utensil(int i) { + System.out.println("Utensil constructor"); + } +} + +class Spoon extends Utensil { + Spoon(int i) { + super(i); + System.out.println("Spoon constructor"); + } +} + +class Fork extends Utensil { + Fork(int i) { + super(i); + System.out.println("Fork constructor"); + } +} + +class Knife extends Utensil { + Knife(int i) { + super(i); + System.out.println("Knife constructor"); + } +} + +// A cultural way of doing something: +class Custom { + Custom(int i) { + System.out.println("Custom constructor"); + } +} + +public class PlaceSetting extends Custom { + private Spoon sp; + private Fork frk; + private Knife kn; + private DinnerPlate pl; + public PlaceSetting(int i) { + super(i + 1); + sp = new Spoon(i + 2); + frk = new Fork(i + 3); + kn = new Knife(i + 4); + pl = new DinnerPlate(i + 5); + System.out.println("PlaceSetting constructor"); + } + public static void main(String[] args) { + PlaceSetting x = new PlaceSetting(9); + } +} +/* Output: +Custom constructor +Utensil constructor +Spoon constructor +Utensil constructor +Fork constructor +Utensil constructor +Knife constructor +Plate constructor +DinnerPlate constructor +PlaceSetting constructor +*/ diff --git a/code/reuse/SpaceShipControls.java b/code/reuse/SpaceShipControls.java new file mode 100644 index 00000000..6fde7086 --- /dev/null +++ b/code/reuse/SpaceShipControls.java @@ -0,0 +1,14 @@ +// reuse/SpaceShipControls.java +// (c)2020 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. + +public class SpaceShipControls { + void up(int velocity) {} + void down(int velocity) {} + void left(int velocity) {} + void right(int velocity) {} + void forward(int velocity) {} + void back(int velocity) {} + void turboBoost() {} +} diff --git a/code/reuse/SpaceShipDelegation.java b/code/reuse/SpaceShipDelegation.java new file mode 100644 index 00000000..c31316b2 --- /dev/null +++ b/code/reuse/SpaceShipDelegation.java @@ -0,0 +1,40 @@ +// reuse/SpaceShipDelegation.java +// (c)2020 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. + +public class SpaceShipDelegation { + private String name; + private SpaceShipControls controls = + new SpaceShipControls(); + public SpaceShipDelegation(String name) { + this.name = name; + } + // Delegated methods: + public void back(int velocity) { + controls.back(velocity); + } + public void down(int velocity) { + controls.down(velocity); + } + public void forward(int velocity) { + controls.forward(velocity); + } + public void left(int velocity) { + controls.left(velocity); + } + public void right(int velocity) { + controls.right(velocity); + } + public void turboBoost() { + controls.turboBoost(); + } + public void up(int velocity) { + controls.up(velocity); + } + public static void main(String[] args) { + SpaceShipDelegation protector = + new SpaceShipDelegation("NSEA Protector"); + protector.forward(100); + } +} diff --git a/code/reuse/SprinklerSystem.java b/code/reuse/SprinklerSystem.java new file mode 100644 index 00000000..e0ccbe66 --- /dev/null +++ b/code/reuse/SprinklerSystem.java @@ -0,0 +1,41 @@ +// reuse/SprinklerSystem.java +// (c)2020 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. +// Composition for code reuse + +class WaterSource { + private String s; + WaterSource() { + System.out.println("WaterSource()"); + s = "Constructed"; + } + @Override + public String toString() { return s; } +} + +public class SprinklerSystem { + private String valve1, valve2, valve3, valve4; + private WaterSource source = new WaterSource(); + private int i; + private float f; + @Override + public String toString() { + return + "valve1 = " + valve1 + " " + + "valve2 = " + valve2 + " " + + "valve3 = " + valve3 + " " + + "valve4 = " + valve4 + "\n" + + "i = " + i + " " + "f = " + f + " " + + "source = " + source; // [1] + } + public static void main(String[] args) { + SprinklerSystem sprinklers = new SprinklerSystem(); + System.out.println(sprinklers); + } +} +/* Output: +WaterSource() +valve1 = null valve2 = null valve3 = null valve4 = null +i = 0 f = 0.0 source = Constructed +*/ diff --git a/code/reuse/Wind.java b/code/reuse/Wind.java new file mode 100644 index 00000000..3e9a05f6 --- /dev/null +++ b/code/reuse/Wind.java @@ -0,0 +1,22 @@ +// reuse/Wind.java +// (c)2020 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. +// Inheritance & upcasting + +class Instrument { + public void play() {} + static void tune(Instrument i) { + // ... + i.play(); + } +} + +// Wind objects are instruments +// because they have the same interface: +public class Wind extends Instrument { + public static void main(String[] args) { + Wind flute = new Wind(); + Instrument.tune(flute); // Upcasting + } +} diff --git a/code/serialization/APerson.java b/code/serialization/APerson.java new file mode 100644 index 00000000..1f67eb1c --- /dev/null +++ b/code/serialization/APerson.java @@ -0,0 +1,83 @@ +// serialization/APerson.java +// (c)2020 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. +// Use the XOM library to write and read XML +// nu.xom.Node comes from http://www.xom.nu +import nu.xom.*; +import java.io.*; +import java.util.*; + +public class APerson { + private String first, last; + public APerson(String first, String last) { + this.first = first; + this.last = last; + } + // Produce an XML Element from this APerson object: + public Element getXML() { + Element person = new Element("person"); + Element firstName = new Element("first"); + firstName.appendChild(first); + Element lastName = new Element("last"); + lastName.appendChild(last); + person.appendChild(firstName); + person.appendChild(lastName); + return person; + } + // Constructor restores a APerson from XML: + public APerson(Element person) { + first = person + .getFirstChildElement("first").getValue(); + last = person + .getFirstChildElement("last").getValue(); + } + @Override + public String toString() { + return first + " " + last; + } + // Make it human-readable: + public static void + format(OutputStream os, Document doc) + throws Exception { + Serializer serializer = + new Serializer(os,"ISO-8859-1"); + serializer.setIndent(4); + serializer.setMaxLength(60); + serializer.write(doc); + serializer.flush(); + } + public static void + main(String[] args) throws Exception { + List people = Arrays.asList( + new APerson("Dr. Bunsen", "Honeydew"), + new APerson("Gonzo", "The Great"), + new APerson("Phillip J.", "Fry")); + System.out.println(people); + Element root = new Element("people"); + for(APerson p : people) + root.appendChild(p.getXML()); + Document doc = new Document(root); + format(System.out, doc); + format(new BufferedOutputStream( + new FileOutputStream("People.xml")), doc); + } +} +/* Output: +[Dr. Bunsen Honeydew, Gonzo The Great, Phillip J. Fry] + + + + Dr. Bunsen + Honeydew + + + Gonzo + The Great + + + Phillip J. + Fry + + +*/ diff --git a/code/serialization/AStoreCADState.java b/code/serialization/AStoreCADState.java new file mode 100644 index 00000000..0ce8858a --- /dev/null +++ b/code/serialization/AStoreCADState.java @@ -0,0 +1,120 @@ +// serialization/AStoreCADState.java +// (c)2020 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. +// Saving the state of a fictitious CAD system +import java.io.*; +import java.util.*; +import java.util.stream.*; + +enum Color { RED, BLUE, GREEN } + +abstract class Shape implements Serializable { + private int xPos, yPos, dimension; + private static Random rand = new Random(47); + private static int counter = 0; + public abstract void setColor(Color newColor); + public abstract Color getColor(); + Shape(int xVal, int yVal, int dim) { + xPos = xVal; + yPos = yVal; + dimension = dim; + } + public String toString() { + return getClass() + "color[" + getColor() + + "] xPos[" + xPos + "] yPos[" + yPos + + "] dim[" + dimension + "]\n"; + } + public static Shape randomFactory() { + int xVal = rand.nextInt(100); + int yVal = rand.nextInt(100); + int dim = rand.nextInt(100); + switch(counter++ % 3) { + default: + case 0: return new Circle(xVal, yVal, dim); + case 1: return new Square(xVal, yVal, dim); + case 2: return new Line(xVal, yVal, dim); + } + } +} + +class Circle extends Shape { + private static Color color = Color.RED; + Circle(int xVal, int yVal, int dim) { + super(xVal, yVal, dim); + } + public void setColor(Color newColor) { + color = newColor; + } + public Color getColor() { return color; } +} + +class Square extends Shape { + private static Color color = Color.RED; + Square(int xVal, int yVal, int dim) { + super(xVal, yVal, dim); + } + public void setColor(Color newColor) { + color = newColor; + } + public Color getColor() { return color; } +} + +class Line extends Shape { + private static Color color = Color.RED; + public static void + serializeStaticState(ObjectOutputStream os) + throws IOException { os.writeObject(color); } + public static void + deserializeStaticState(ObjectInputStream os) + throws IOException, ClassNotFoundException { + color = (Color)os.readObject(); + } + Line(int xVal, int yVal, int dim) { + super(xVal, yVal, dim); + } + public void setColor(Color newColor) { + color = newColor; + } + public Color getColor() { return color; } +} + +public class AStoreCADState { + public static void main(String[] args) { + List> shapeTypes = + Arrays.asList( + Circle.class, Square.class, Line.class); + List shapes = IntStream.range(0, 10) + .mapToObj(i -> Shape.randomFactory()) + .collect(Collectors.toList()); + // Set all the static colors to GREEN: + shapes.forEach(s -> s.setColor(Color.GREEN)); + // Save the state vector: + try( + ObjectOutputStream out = + new ObjectOutputStream( + new FileOutputStream("CADState.dat")) + ) { + out.writeObject(shapeTypes); + Line.serializeStaticState(out); + out.writeObject(shapes); + } catch(IOException e) { + throw new RuntimeException(e); + } + // Display the shapes: + System.out.println(shapes); + } +} +/* Output: +[class Circlecolor[GREEN] xPos[58] yPos[55] dim[93] +, class Squarecolor[GREEN] xPos[61] yPos[61] dim[29] +, class Linecolor[GREEN] xPos[68] yPos[0] dim[22] +, class Circlecolor[GREEN] xPos[7] yPos[88] dim[28] +, class Squarecolor[GREEN] xPos[51] yPos[89] dim[9] +, class Linecolor[GREEN] xPos[78] yPos[98] dim[61] +, class Circlecolor[GREEN] xPos[20] yPos[58] dim[16] +, class Squarecolor[GREEN] xPos[40] yPos[11] dim[22] +, class Linecolor[GREEN] xPos[4] yPos[83] dim[6] +, class Circlecolor[GREEN] xPos[75] yPos[10] dim[42] +] +*/ diff --git a/code/serialization/Alien.java b/code/serialization/Alien.java new file mode 100644 index 00000000..d0b0f5bf --- /dev/null +++ b/code/serialization/Alien.java @@ -0,0 +1,7 @@ +// serialization/Alien.java +// (c)2020 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. +// A serializable class +import java.io.*; +public class Alien implements Serializable {} diff --git a/code/serialization/Blip3.java b/code/serialization/Blip3.java new file mode 100644 index 00000000..6741298c --- /dev/null +++ b/code/serialization/Blip3.java @@ -0,0 +1,75 @@ +// serialization/Blip3.java +// (c)2020 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. +// Reconstructing an externalizable object +import java.io.*; + +public class Blip3 implements Externalizable { + private int i; + private String s; // No initialization + public Blip3() { + System.out.println("Blip3 Constructor"); + // s, i not initialized + } + public Blip3(String x, int a) { + System.out.println("Blip3(String x, int a)"); + s = x; + i = a; + // s & i initialized only in non-no-arg constructor. + } + @Override + public String toString() { return s + i; } + @Override + public void writeExternal(ObjectOutput out) + throws IOException { + System.out.println("Blip3.writeExternal"); + // You must do this: + out.writeObject(s); + out.writeInt(i); + } + @Override + public void readExternal(ObjectInput in) + throws IOException, ClassNotFoundException { + System.out.println("Blip3.readExternal"); + // You must do this: + s = (String)in.readObject(); + i = in.readInt(); + } + public static void main(String[] args) { + System.out.println("Constructing objects:"); + Blip3 b3 = new Blip3("A String ", 47); + System.out.println(b3); + try( + ObjectOutputStream o = new ObjectOutputStream( + new FileOutputStream("Blip3.serialized")) + ) { + System.out.println("Saving object:"); + o.writeObject(b3); + } catch(IOException e) { + throw new RuntimeException(e); + } + // Now get it back: + System.out.println("Recovering b3:"); + try( + ObjectInputStream in = new ObjectInputStream( + new FileInputStream("Blip3.serialized")) + ) { + b3 = (Blip3)in.readObject(); + } catch(IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + System.out.println(b3); + } +} +/* Output: +Constructing objects: +Blip3(String x, int a) +A String 47 +Saving object: +Blip3.writeExternal +Recovering b3: +Blip3 Constructor +Blip3.readExternal +A String 47 +*/ diff --git a/code/serialization/Blips.java b/code/serialization/Blips.java new file mode 100644 index 00000000..88116d84 --- /dev/null +++ b/code/serialization/Blips.java @@ -0,0 +1,80 @@ +// serialization/Blips.java +// (c)2020 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. +// Simple use of Externalizable & a pitfall +import java.io.*; + +class Blip1 implements Externalizable { + public Blip1() { + System.out.println("Blip1 Constructor"); + } + @Override + public void writeExternal(ObjectOutput out) + throws IOException { + System.out.println("Blip1.writeExternal"); + } + @Override + public void readExternal(ObjectInput in) + throws IOException, ClassNotFoundException { + System.out.println("Blip1.readExternal"); + } +} + +class Blip2 implements Externalizable { + Blip2() { + System.out.println("Blip2 Constructor"); + } + @Override + public void writeExternal(ObjectOutput out) + throws IOException { + System.out.println("Blip2.writeExternal"); + } + @Override + public void readExternal(ObjectInput in) + throws IOException, ClassNotFoundException { + System.out.println("Blip2.readExternal"); + } +} + +public class Blips { + public static void main(String[] args) { + System.out.println("Constructing objects:"); + Blip1 b1 = new Blip1(); + Blip2 b2 = new Blip2(); + try( + ObjectOutputStream o = new ObjectOutputStream( + new FileOutputStream("Blips.serialized")) + ) { + System.out.println("Saving objects:"); + o.writeObject(b1); + o.writeObject(b2); + } catch(IOException e) { + throw new RuntimeException(e); + } + // Now get them back: + System.out.println("Recovering b1:"); + try( + ObjectInputStream in = new ObjectInputStream( + new FileInputStream("Blips.serialized")) + ) { + b1 = (Blip1)in.readObject(); + } catch(IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + // OOPS! Throws an exception: + //- System.out.println("Recovering b2:"); + //- b2 = (Blip2)in.readObject(); + } +} +/* Output: +Constructing objects: +Blip1 Constructor +Blip2 Constructor +Saving objects: +Blip1.writeExternal +Blip2.writeExternal +Recovering b1: +Blip1 Constructor +Blip1.readExternal +*/ diff --git a/code/serialization/FreezeAlien.java b/code/serialization/FreezeAlien.java new file mode 100644 index 00000000..0fe8e831 --- /dev/null +++ b/code/serialization/FreezeAlien.java @@ -0,0 +1,19 @@ +// serialization/FreezeAlien.java +// (c)2020 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. +// Create a serialized output file +import java.io.*; + +public class FreezeAlien { + public static void + main(String[] args) throws Exception { + try( + ObjectOutputStream out = new ObjectOutputStream( + new FileOutputStream("X.file")); + ) { + Alien quellek = new Alien(); + out.writeObject(quellek); + } + } +} diff --git a/code/serialization/Logon.java b/code/serialization/Logon.java new file mode 100644 index 00000000..3b910968 --- /dev/null +++ b/code/serialization/Logon.java @@ -0,0 +1,62 @@ +// serialization/Logon.java +// (c)2020 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. +// Demonstrates the "transient" keyword +import java.util.concurrent.*; +import java.io.*; +import java.util.*; +import onjava.Nap; + +public class Logon implements Serializable { + private Date date = new Date(); + private String username; + private transient String password; + public Logon(String name, String pwd) { + username = name; + password = pwd; + } + @Override + public String toString() { + return "logon info: \n username: " + + username + "\n date: " + date + + "\n password: " + password; + } + public static void main(String[] args) { + Logon a = new Logon("Hulk", "myLittlePony"); + System.out.println("logon a = " + a); + try( + ObjectOutputStream o = + new ObjectOutputStream( + new FileOutputStream("Logon.dat")) + ) { + o.writeObject(a); + } catch(IOException e) { + throw new RuntimeException(e); + } + new Nap(1); + // Now get them back: + try( + ObjectInputStream in = new ObjectInputStream( + new FileInputStream("Logon.dat")) + ) { + System.out.println( + "Recovering object at " + new Date()); + a = (Logon)in.readObject(); + } catch(IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + System.out.println("logon a = " + a); + } +} +/* Output: +logon a = logon info: + username: Hulk + date: Tue May 09 06:07:47 MDT 2017 + password: myLittlePony +Recovering object at Tue May 09 06:07:49 MDT 2017 +logon a = logon info: + username: Hulk + date: Tue May 09 06:07:47 MDT 2017 + password: null +*/ diff --git a/code/serialization/MyWorld.java b/code/serialization/MyWorld.java new file mode 100644 index 00000000..99e39de3 --- /dev/null +++ b/code/serialization/MyWorld.java @@ -0,0 +1,100 @@ +// serialization/MyWorld.java +// (c)2020 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. +import java.io.*; +import java.util.*; + +class House implements Serializable {} + +class Animal implements Serializable { + private String name; + private House preferredHouse; + Animal(String nm, House h) { + name = nm; + preferredHouse = h; + } + @Override + public String toString() { + return name + "[" + super.toString() + + "], " + preferredHouse + "\n"; + } +} + +public class MyWorld { + public static void main(String[] args) { + House house = new House(); + List animals = new ArrayList<>(); + animals.add( + new Animal("Bosco the dog", house)); + animals.add( + new Animal("Ralph the hamster", house)); + animals.add( + new Animal("Molly the cat", house)); + System.out.println("animals: " + animals); + try( + ByteArrayOutputStream buf1 = + new ByteArrayOutputStream(); + ObjectOutputStream o1 = + new ObjectOutputStream(buf1) + ) { + o1.writeObject(animals); + o1.writeObject(animals); // Write a 2nd set + // Write to a different stream: + try( + ByteArrayOutputStream buf2 = + new ByteArrayOutputStream(); + ObjectOutputStream o2 = + new ObjectOutputStream(buf2) + ) { + o2.writeObject(animals); + // Now get them back: + try( + ObjectInputStream in1 = + new ObjectInputStream( + new ByteArrayInputStream( + buf1.toByteArray())); + ObjectInputStream in2 = + new ObjectInputStream( + new ByteArrayInputStream( + buf2.toByteArray())) + ) { + List + animals1 = (List)in1.readObject(), + animals2 = (List)in1.readObject(), + animals3 = (List)in2.readObject(); + System.out.println( + "animals1: " + animals1); + System.out.println( + "animals2: " + animals2); + System.out.println( + "animals3: " + animals3); + } + } + } catch(IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + } +} +/* Output: +animals: [Bosco the dog[Animal@15db9742], +House@6d06d69c +, Ralph the hamster[Animal@7852e922], House@6d06d69c +, Molly the cat[Animal@4e25154f], House@6d06d69c +] +animals1: [Bosco the dog[Animal@7ba4f24f], +House@3b9a45b3 +, Ralph the hamster[Animal@7699a589], House@3b9a45b3 +, Molly the cat[Animal@58372a00], House@3b9a45b3 +] +animals2: [Bosco the dog[Animal@7ba4f24f], +House@3b9a45b3 +, Ralph the hamster[Animal@7699a589], House@3b9a45b3 +, Molly the cat[Animal@58372a00], House@3b9a45b3 +] +animals3: [Bosco the dog[Animal@4dd8dc3], +House@6d03e736 +, Ralph the hamster[Animal@568db2f2], House@6d03e736 +, Molly the cat[Animal@378bf509], House@6d03e736 +] +*/ diff --git a/code/serialization/People.java b/code/serialization/People.java new file mode 100644 index 00000000..0e588749 --- /dev/null +++ b/code/serialization/People.java @@ -0,0 +1,28 @@ +// serialization/People.java +// (c)2020 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. +// nu.xom.Node comes from http://www.xom.nu +// {RunFirst: APerson} +import nu.xom.*; +import java.io.File; +import java.util.*; + +public class People extends ArrayList { + public People(String fileName) throws Exception { + Document doc = + new Builder().build(new File(fileName)); + Elements elements = + doc.getRootElement().getChildElements(); + for(int i = 0; i < elements.size(); i++) + add(new APerson(elements.get(i))); + } + public static void + main(String[] args) throws Exception { + People p = new People("People.xml"); + System.out.println(p); + } +} +/* Output: +[Dr. Bunsen Honeydew, Gonzo The Great, Phillip J. Fry] +*/ diff --git a/code/serialization/RecoverCADState.java b/code/serialization/RecoverCADState.java new file mode 100644 index 00000000..612f501c --- /dev/null +++ b/code/serialization/RecoverCADState.java @@ -0,0 +1,42 @@ +// serialization/RecoverCADState.java +// (c)2020 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. +// Restoring the state of the fictitious CAD system +// {RunFirst: AStoreCADState} +import java.io.*; +import java.util.*; + +public class RecoverCADState { + @SuppressWarnings("unchecked") + public static void main(String[] args) { + try( + ObjectInputStream in = + new ObjectInputStream( + new FileInputStream("CADState.dat")) + ) { + // Read in the same order they were written: + List> shapeTypes = + (List>)in.readObject(); + Line.deserializeStaticState(in); + List shapes = + (List)in.readObject(); + System.out.println(shapes); + } catch(IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + } +} +/* Output: +[class Circlecolor[RED] xPos[58] yPos[55] dim[93] +, class Squarecolor[RED] xPos[61] yPos[61] dim[29] +, class Linecolor[GREEN] xPos[68] yPos[0] dim[22] +, class Circlecolor[RED] xPos[7] yPos[88] dim[28] +, class Squarecolor[RED] xPos[51] yPos[89] dim[9] +, class Linecolor[GREEN] xPos[78] yPos[98] dim[61] +, class Circlecolor[RED] xPos[20] yPos[58] dim[16] +, class Squarecolor[RED] xPos[40] yPos[11] dim[22] +, class Linecolor[GREEN] xPos[4] yPos[83] dim[6] +, class Circlecolor[RED] xPos[75] yPos[10] dim[42] +] +*/ diff --git a/code/serialization/SerialCtl.java b/code/serialization/SerialCtl.java new file mode 100644 index 00000000..ed891633 --- /dev/null +++ b/code/serialization/SerialCtl.java @@ -0,0 +1,60 @@ +// serialization/SerialCtl.java +// (c)2020 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. +// Controlling serialization by adding your own +// writeObject() and readObject() methods +import java.io.*; + +public class SerialCtl implements Serializable { + private String a; + private transient String b; + public SerialCtl(String aa, String bb) { + a = "Not Transient: " + aa; + b = "Transient: " + bb; + } + @Override + public String toString() { return a + "\n" + b; } + private void writeObject(ObjectOutputStream stream) + throws IOException { + stream.defaultWriteObject(); + stream.writeObject(b); + } + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + b = (String)stream.readObject(); + } + public static void main(String[] args) { + SerialCtl sc = new SerialCtl("Test1", "Test2"); + System.out.println("Before:\n" + sc); + try ( + ByteArrayOutputStream buf = + new ByteArrayOutputStream(); + ObjectOutputStream o = + new ObjectOutputStream(buf); + ) { + o.writeObject(sc); + // Now get it back: + try ( + ObjectInputStream in = + new ObjectInputStream( + new ByteArrayInputStream( + buf.toByteArray())); + ) { + SerialCtl sc2 = (SerialCtl)in.readObject(); + System.out.println("After:\n" + sc2); + } + } catch(IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + } +} +/* Output: +Before: +Not Transient: Test1 +Transient: Test2 +After: +Not Transient: Test1 +Transient: Test2 +*/ diff --git a/code/serialization/Worm.java b/code/serialization/Worm.java new file mode 100644 index 00000000..666beb87 --- /dev/null +++ b/code/serialization/Worm.java @@ -0,0 +1,102 @@ +// serialization/Worm.java +// (c)2020 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. +// Demonstrates object serialization +import java.io.*; +import java.util.*; + +class Data implements Serializable { + private int n; + Data(int n) { this.n = n; } + @Override + public String toString() { + return Integer.toString(n); + } +} + +public class Worm implements Serializable { + private static Random rand = new Random(47); + private Data[] d = { + new Data(rand.nextInt(10)), + new Data(rand.nextInt(10)), + new Data(rand.nextInt(10)) + }; + private Worm next; + private char c; + // Value of i == number of segments + public Worm(int i, char x) { + System.out.println("Worm constructor: " + i); + c = x; + if(--i > 0) + next = new Worm(i, (char)(x + 1)); + } + public Worm() { + System.out.println("No-arg constructor"); + } + @Override + public String toString() { + StringBuilder result = new StringBuilder(":"); + result.append(c); + result.append("("); + for(Data dat : d) + result.append(dat); + result.append(")"); + if(next != null) + result.append(next); + return result.toString(); + } + public static void + main(String[] args) throws ClassNotFoundException, + IOException { + Worm w = new Worm(6, 'a'); + System.out.println("w = " + w); + try( + ObjectOutputStream out = new ObjectOutputStream( + new FileOutputStream("worm.dat")) + ) { + out.writeObject("Worm storage\n"); + out.writeObject(w); + } + try( + ObjectInputStream in = new ObjectInputStream( + new FileInputStream("worm.dat")) + ) { + String s = (String)in.readObject(); + Worm w2 = (Worm)in.readObject(); + System.out.println(s + "w2 = " + w2); + } + try( + ByteArrayOutputStream bout = + new ByteArrayOutputStream(); + ObjectOutputStream out2 = + new ObjectOutputStream(bout) + ) { + out2.writeObject("Worm storage\n"); + out2.writeObject(w); + out2.flush(); + try( + ObjectInputStream in2 = new ObjectInputStream( + new ByteArrayInputStream( + bout.toByteArray())) + ) { + String s = (String)in2.readObject(); + Worm w3 = (Worm)in2.readObject(); + System.out.println(s + "w3 = " + w3); + } + } + } +} +/* Output: +Worm constructor: 6 +Worm constructor: 5 +Worm constructor: 4 +Worm constructor: 3 +Worm constructor: 2 +Worm constructor: 1 +w = :a(853):b(119):c(802):d(788):e(199):f(881) +Worm storage +w2 = :a(853):b(119):c(802):d(788):e(199):f(881) +Worm storage +w3 = :a(853):b(119):c(802):d(788):e(199):f(881) +*/ diff --git a/code/serialization/xfiles/ThawAlien.java b/code/serialization/xfiles/ThawAlien.java new file mode 100644 index 00000000..1de6ce6a --- /dev/null +++ b/code/serialization/xfiles/ThawAlien.java @@ -0,0 +1,22 @@ +// serialization/xfiles/ThawAlien.java +// (c)2020 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. +// Recover a serialized file +// {java serialization.xfiles.ThawAlien} +// {RunFirst: FreezeAlien} +package serialization.xfiles; +import java.io.*; + +public class ThawAlien { + public static void + main(String[] args) throws Exception { + ObjectInputStream in = new ObjectInputStream( + new FileInputStream(new File("X.file"))); + Object mystery = in.readObject(); + System.out.println(mystery.getClass()); + } +} +/* Output: +class Alien +*/ diff --git a/code/settings.gradle b/code/settings.gradle new file mode 100644 index 00000000..376ca105 --- /dev/null +++ b/code/settings.gradle @@ -0,0 +1,13 @@ +def isSubproject = { File file -> + file.isDirectory() && + !file.name.contains('.git') && + !file.name.contains('.gradle') && + !file.name.contains('.idea') && + !file.name.contains('build') && + !file.name.contains('gradle') && + !file.name.contains('test') +} + +String[] subprojects = rootDir.listFiles().findAll(isSubproject).collect { it.name } + +include subprojects diff --git a/code/standardio/ChangeSystemOut.java b/code/standardio/ChangeSystemOut.java new file mode 100644 index 00000000..2b37acb8 --- /dev/null +++ b/code/standardio/ChangeSystemOut.java @@ -0,0 +1,17 @@ +// standardio/ChangeSystemOut.java +// (c)2020 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. +// Turn System.out into a PrintWriter +import java.io.*; + +public class ChangeSystemOut { + public static void main(String[] args) { + PrintWriter out = + new PrintWriter(System.out, true); + out.println("Hello, world"); + } +} +/* Output: +Hello, world +*/ diff --git a/code/standardio/Echo.java b/code/standardio/Echo.java new file mode 100644 index 00000000..d1a6103e --- /dev/null +++ b/code/standardio/Echo.java @@ -0,0 +1,20 @@ +// standardio/Echo.java +// (c)2020 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. +// How to read from standard input +import java.io.*; +import onjava.TimedAbort; + +public class Echo { + public static void main(String[] args) { + TimedAbort abort = new TimedAbort(2); + new BufferedReader( + new InputStreamReader(System.in)) + .lines() + .peek(ln -> abort.restart()) + .forEach(System.out::println); + // Ctrl-Z or two seconds inactivity + // terminates the program + } +} diff --git a/code/standardio/OSExecuteDemo.java b/code/standardio/OSExecuteDemo.java new file mode 100644 index 00000000..cc2fd4b0 --- /dev/null +++ b/code/standardio/OSExecuteDemo.java @@ -0,0 +1,16 @@ +// standardio/OSExecuteDemo.java +// (c)2020 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. +// Demonstrates standard I/O redirection +// javap -cp build/classes/java/main OSExecuteDemo +// {ExcludeFromGradle} +import onjava.*; + +public class OSExecuteDemo {} +/* Output: +Compiled from "OSExecuteDemo.java" +public class OSExecuteDemo { + public OSExecuteDemo(); +} +*/ diff --git a/code/standardio/Redirecting.java b/code/standardio/Redirecting.java new file mode 100644 index 00000000..c2986a2b --- /dev/null +++ b/code/standardio/Redirecting.java @@ -0,0 +1,31 @@ +// standardio/Redirecting.java +// (c)2020 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. +// Demonstrates standard I/O redirection +import java.io.*; + +public class Redirecting { + public static void main(String[] args) { + PrintStream console = System.out; + try( + BufferedInputStream in = new BufferedInputStream( + new FileInputStream("Redirecting.java")); + PrintStream out = new PrintStream( + new BufferedOutputStream( + new FileOutputStream("Redirecting.txt"))) + ) { + System.setIn(in); + System.setOut(out); + System.setErr(out); + new BufferedReader( + new InputStreamReader(System.in)) + .lines() + .forEach(System.out::println); + } catch(IOException e) { + throw new RuntimeException(e); + } finally { + System.setOut(console); + } + } +} diff --git a/code/staticchecking/DogsAndRobots.cpp b/code/staticchecking/DogsAndRobots.cpp new file mode 100644 index 00000000..03b69a96 --- /dev/null +++ b/code/staticchecking/DogsAndRobots.cpp @@ -0,0 +1,33 @@ +// staticchecking/DogsAndRobots.cpp +// (c)2020 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. +#include +using namespace std; + +class Dog { +public: + void talk() { cout << "Arf!" << endl; } + void reproduce() {} +}; + +class Robot { +public: + void talk() { cout << "Click!" << endl; } + void oilChange() {} +}; + +template void speak(T speaker) { + speaker.talk(); +} + +int main() { + Dog d; + Robot r; + speak(d); + speak(r); +} +/* Output: +Arf! +Click! +*/ diff --git a/code/staticchecking/DogsAndRobots.py b/code/staticchecking/DogsAndRobots.py new file mode 100644 index 00000000..a6b239da --- /dev/null +++ b/code/staticchecking/DogsAndRobots.py @@ -0,0 +1,26 @@ +# staticchecking/DogsAndRobots.py +# (c)2020 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. + +def speak(anything): + anything.talk() + +class Dog: + def talk(self): print("Arf!") + def reproduce(self): pass + +class Robot: + def talk(self): print("Click!") + def oilChange(self): pass + +a = Dog() +b = Robot() + +speak(a) +speak(b) + +output = """ +Arf! +Click! +""" diff --git a/code/staticchecking/NoBasePetSpeak.py b/code/staticchecking/NoBasePetSpeak.py new file mode 100644 index 00000000..cbe6c82b --- /dev/null +++ b/code/staticchecking/NoBasePetSpeak.py @@ -0,0 +1,35 @@ +# staticchecking/NoBasePetSpeak.py +# (c)2020 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. +#- Speaking pets without base classes + +class Cat: + def speak(self): + print("meow!") + +class Dog: + def speak(self): + print("woof!") + +class Bob: + def bow(self): + print("thank you, thank you!") + def speak(self): + print("Welcome to the neighborhood!") + def drive(self): + print("beep, beep!") + +def command(pet): + pet.speak() + +pets = [ Cat(), Dog(), Bob() ] + +for pet in pets: + command(pet) + +output = """ +meow! +woof! +Welcome to the neighborhood! +""" diff --git a/code/staticchecking/PetSpeak.py b/code/staticchecking/PetSpeak.py new file mode 100644 index 00000000..e3734e2f --- /dev/null +++ b/code/staticchecking/PetSpeak.py @@ -0,0 +1,28 @@ +# staticchecking/PetSpeak.py +# (c)2020 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. +#- Speaking pets in Python + +class Pet: + def speak(self): pass + +class Cat(Pet): + def speak(self): + print("meow!") + +class Dog(Pet): + def speak(self): + print("woof!") + +def command(pet): + pet.speak() + +pets = [ Cat(), Dog() ] # (1) +for pet in pets: # (2) + command(pet) + +output = """ +meow! +woof! +""" diff --git a/code/staticchecking/dogsandrobots.go b/code/staticchecking/dogsandrobots.go new file mode 100644 index 00000000..d3dd10cb --- /dev/null +++ b/code/staticchecking/dogsandrobots.go @@ -0,0 +1,27 @@ +// staticchecking/dogsandrobots.go +// (c)2020 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 main +import "fmt" + +type Dog struct {} +func (this Dog) talk() { fmt.Printf("woof!\n")} +func (this Dog) reproduce() {} + +type Robot struct {} +func (this Robot) talk() { fmt.Printf("Click!\n") } +func (this Robot) oilChange() {} + +func speak(speaker interface { talk() }) { + speaker.talk(); +} + +func main() { + speak(Dog{}) + speak(Robot{}) +} +/* Output: +woof! +Click! +*/ diff --git a/code/staticchecking/dr/DogsAndRobots.java b/code/staticchecking/dr/DogsAndRobots.java new file mode 100644 index 00000000..9bede804 --- /dev/null +++ b/code/staticchecking/dr/DogsAndRobots.java @@ -0,0 +1,42 @@ +// staticchecking/dr/DogsAndRobots.java +// (c)2020 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. +// {java staticchecking.dr.DogsAndRobots} +package staticchecking.dr; + +interface Speaks { void talk(); } + +class Dog implements Speaks { + public void talk() { + System.out.println("Woof!"); + } + public void reproduce() { } +} + +class Robot implements Speaks { + public void talk() { + System.out.println("Click!"); + } + public void oilChange() { } +} + +class Communicate { + public static + void speak(T speaker) { + speaker.talk(); + } +} + +public class DogsAndRobots { + public static void main(String[] args) { + Dog d = new Dog(); + Robot r = new Robot(); + Communicate.speak(d); + Communicate.speak(r); + } +} +/* Output: +Woof! +Click! +*/ diff --git a/code/staticchecking/drc/DogAndRobotCollections.java b/code/staticchecking/drc/DogAndRobotCollections.java new file mode 100644 index 00000000..16a82ed5 --- /dev/null +++ b/code/staticchecking/drc/DogAndRobotCollections.java @@ -0,0 +1,58 @@ +// staticchecking/drc/DogAndRobotCollections.java +// (c)2020 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. +// {java staticchecking.drc.DogAndRobotCollections} +package staticchecking.drc; +import java.util.*; + +class Dog { + public void talk() { + System.out.println("Woof!"); + } + public void reproduce() { } +} + +class Robot { + public void talk() { + System.out.println("Click!"); + } + public void oilChange() { } +} + +public class DogAndRobotCollections { + public static void main(String[] args) { + List dogList = new ArrayList<>(); + List robotList = new ArrayList<>(); + for(int i = 0; i < 10; i++) + dogList.add(new Dog()); + //- dogList.add(new Robot()); // Compile-time error + for(int i = 0; i < 10; i++) + robotList.add(new Robot()); + //- robotList.add(new Dog()); // Compile-time error + dogList.forEach(Dog::talk); + robotList.forEach(Robot::talk); + } +} +/* Output: +Woof! +Woof! +Woof! +Woof! +Woof! +Woof! +Woof! +Woof! +Woof! +Woof! +Click! +Click! +Click! +Click! +Click! +Click! +Click! +Click! +Click! +Click! +*/ diff --git a/code/staticchecking/latent/Latent.java b/code/staticchecking/latent/Latent.java new file mode 100644 index 00000000..29e53713 --- /dev/null +++ b/code/staticchecking/latent/Latent.java @@ -0,0 +1,60 @@ +// staticchecking/latent/Latent.java +// (c)2020 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. +// {java staticchecking.latent.Latent} +package staticchecking.latent; +import java.lang.reflect.*; + +class Dog { + public void talk() { + System.out.println("Woof!"); + } + public void reproduce() {} +} + +class Robot { + public void talk() { + System.out.println("Click!"); + } + public void oilChange() {} +} + +class Mime { + public void walkAgainstTheWind() {} + public String toString() { return "Mime"; } +} + +class Communicate { + public static void speak(Object speaker) { + try { + Class spkr = + speaker.getClass(); + Method talk = + spkr.getMethod("talk", (Class[])null); + talk.invoke(speaker, new Object[]{}); + } catch(NoSuchMethodException e) { + System.out.println( + speaker + " cannot talk"); + } catch(IllegalAccessException e) { + System.out.println( + speaker + " IllegalAccessException"); + } catch(InvocationTargetException e) { + System.out.println( + speaker + " InvocationTargetException"); + } + } +} + +public class Latent { + public static void main(String[] args) { + Communicate.speak(new Dog()); + Communicate.speak(new Robot()); + Communicate.speak(new Mime()); + } +} +/* Output: +Woof! +Click! +Mime cannot talk +*/ diff --git a/code/staticchecking/petspeak.go b/code/staticchecking/petspeak.go new file mode 100644 index 00000000..1d5c5e46 --- /dev/null +++ b/code/staticchecking/petspeak.go @@ -0,0 +1,51 @@ +// staticchecking/petspeak.go +// (c)2020 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 main +import "fmt" + +type Cat struct {} +func (this Cat) speak() { fmt.Printf("meow!\n")} + +type Dog struct {} +func (this Dog) speak() { fmt.Printf("woof!\n")} + +type Bob struct {} +func (this Bob) bow() { + fmt.Printf("thank you, thank you!\n") +} +func (this Bob) speak() { + fmt.Printf("Welcome to the neighborhood!\n") +} +func (this Bob) drive() { + fmt.Printf("beep, beep!\n") +} + +type Speaker interface { + speak() +} + +func command(s Speaker) { s.speak() } + +// If "Speaker" is never used +// anywhere else, it can be anonymous: +func command2(s interface { speak() }) { s.speak() } + +func main() { + command(Cat{}) + command(Dog{}) + command(Bob{}) + command2(Cat{}) + command2(Dog{}) + command2(Bob{}) +} + +/* Output: +meow! +woof! +Welcome to the neighborhood! +meow! +woof! +Welcome to the neighborhood! +*/ diff --git a/code/staticchecking/petspeak/PetSpeak.java b/code/staticchecking/petspeak/PetSpeak.java new file mode 100644 index 00000000..0b850c3b --- /dev/null +++ b/code/staticchecking/petspeak/PetSpeak.java @@ -0,0 +1,36 @@ +// staticchecking/petspeak/PetSpeak.java +// (c)2020 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. +// Speaking pets in Java +// {java staticchecking.petspeak.PetSpeak} +package staticchecking.petspeak; + +interface Pet { + void speak(); +} + +class Cat implements Pet { + public void speak() { + System.out.println("meow!"); + } +} + +class Dog implements Pet { + public void speak() { + System.out.println("woof!"); + } +} + +public class PetSpeak { + static void command(Pet p) { p.speak(); } + public static void main(String[] args) { + Pet[] pets = { new Cat(), new Dog() }; + for(Pet pet : pets) + command(pet); + } +} +/* Output: +meow! +woof! +*/ diff --git a/code/streams/ArrayStreams.java b/code/streams/ArrayStreams.java new file mode 100644 index 00000000..dfed6e83 --- /dev/null +++ b/code/streams/ArrayStreams.java @@ -0,0 +1,31 @@ +// streams/ArrayStreams.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; + +public class ArrayStreams { + public static void main(String[] args) { + Arrays.stream( + new double[] { 3.14159, 2.718, 1.618 }) + .forEach(n -> System.out.format("%f ", n)); + System.out.println(); + Arrays.stream(new int[] { 1, 3, 5 }) + .forEach(n -> System.out.format("%d ", n)); + System.out.println(); + Arrays.stream(new long[] { 11, 22, 44, 66 }) + .forEach(n -> System.out.format("%d ", n)); + System.out.println(); + // Select a subrange: + Arrays.stream( + new int[] { 1, 3, 5, 7, 15, 28, 37 }, 3, 6) + .forEach(n -> System.out.format("%d ", n)); + } +} +/* Output: +3.141590 2.718000 1.618000 +1 3 5 +11 22 44 66 +7 15 28 +*/ diff --git a/code/streams/Bubble.java b/code/streams/Bubble.java new file mode 100644 index 00000000..5650e5ae --- /dev/null +++ b/code/streams/Bubble.java @@ -0,0 +1,18 @@ +// streams/Bubble.java +// (c)2020 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. +import java.util.function.*; + +public class Bubble { + public final int i; + public Bubble(int n) { i = n; } + @Override + public String toString() { + return "Bubble(" + i + ")"; + } + private static int count = 0; + public static Bubble bubbler() { + return new Bubble(count++); + } +} diff --git a/code/streams/Bubbles.java b/code/streams/Bubbles.java new file mode 100644 index 00000000..1b3bd2b9 --- /dev/null +++ b/code/streams/Bubbles.java @@ -0,0 +1,20 @@ +// streams/Bubbles.java +// (c)2020 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. +import java.util.stream.*; + +public class Bubbles { + public static void main(String[] args) { + Stream.generate(Bubble::bubbler) + .limit(5) + .forEach(System.out::println); + } +} +/* Output: +Bubble(0) +Bubble(1) +Bubble(2) +Bubble(3) +Bubble(4) +*/ diff --git a/code/streams/Cheese.dat b/code/streams/Cheese.dat new file mode 100644 index 00000000..936666ed --- /dev/null +++ b/code/streams/Cheese.dat @@ -0,0 +1,6 @@ +// streams/Cheese.dat +Not much of a cheese shop really, is it? +Finest in the district, sir. +And what leads you to that conclusion? +Well, it's so clean. +It's certainly uncontaminated by cheese. diff --git a/code/streams/CollectionToStream.java b/code/streams/CollectionToStream.java new file mode 100644 index 00000000..93236ef1 --- /dev/null +++ b/code/streams/CollectionToStream.java @@ -0,0 +1,39 @@ +// streams/CollectionToStream.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; + +public class CollectionToStream { + public static void main(String[] args) { + List bubbles = Arrays.asList( + new Bubble(1), new Bubble(2), new Bubble(3)); + System.out.println( + bubbles.stream() + .mapToInt(b -> b.i) + .sum()); + + Set w = new HashSet<>(Arrays.asList( + "It's a wonderful day for pie!".split(" "))); + w.stream() + .map(x -> x + " ") + .forEach(System.out::print); + System.out.println(); + + Map m = new HashMap<>(); + m.put("pi", 3.14159); + m.put("e", 2.718); + m.put("phi", 1.618); + m.entrySet().stream() + .map(e -> e.getKey() + ": " + e.getValue()) + .forEach(System.out::println); + } +} +/* Output: +6 +a pie! It's for wonderful day +phi: 1.618 +e: 2.718 +pi: 3.14159 +*/ diff --git a/code/streams/CreatingOptionals.java b/code/streams/CreatingOptionals.java new file mode 100644 index 00000000..7e886ddc --- /dev/null +++ b/code/streams/CreatingOptionals.java @@ -0,0 +1,37 @@ +// streams/CreatingOptionals.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import java.util.function.*; + +class CreatingOptionals { + static void + test(String testName, Optional opt) { + System.out.println(" === " + testName + " === "); + System.out.println(opt.orElse("Null")); + } + public static void main(String[] args) { + test("empty", Optional.empty()); + test("of", Optional.of("Howdy")); + try { + test("of", Optional.of(null)); + } catch(Exception e) { + System.out.println(e); + } + test("ofNullable", Optional.ofNullable("Hi")); + test("ofNullable", Optional.ofNullable(null)); + } +} +/* Output: + === empty === +Null + === of === +Howdy +java.lang.NullPointerException + === ofNullable === +Hi + === ofNullable === +Null +*/ diff --git a/code/streams/Duplicator.java b/code/streams/Duplicator.java new file mode 100644 index 00000000..267279c7 --- /dev/null +++ b/code/streams/Duplicator.java @@ -0,0 +1,18 @@ +// streams/Duplicator.java +// (c)2020 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. +import java.util.stream.*; + +public class Duplicator { + public static void main(String[] args) { + Stream.generate(() -> "duplicate") + .limit(3) + .forEach(System.out::println); + } +} +/* Output: +duplicate +duplicate +duplicate +*/ diff --git a/code/streams/Fibonacci.java b/code/streams/Fibonacci.java new file mode 100644 index 00000000..fa53c687 --- /dev/null +++ b/code/streams/Fibonacci.java @@ -0,0 +1,34 @@ +// streams/Fibonacci.java +// (c)2020 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. +import java.util.stream.*; + +public class Fibonacci { + int x = 1; + Stream numbers() { + return Stream.iterate(0, i -> { + int result = x + i; + x = i; + return result; + }); + } + public static void main(String[] args) { + new Fibonacci().numbers() + .skip(20) // Don't use the first 20 + .limit(10) // Then take 10 of them + .forEach(System.out::println); + } +} +/* Output: +6765 +10946 +17711 +28657 +46368 +75025 +121393 +196418 +317811 +514229 +*/ diff --git a/code/streams/FileToWords.java b/code/streams/FileToWords.java new file mode 100644 index 00000000..7f7174cb --- /dev/null +++ b/code/streams/FileToWords.java @@ -0,0 +1,17 @@ +// streams/FileToWords.java +// (c)2020 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. +import java.nio.file.*; +import java.util.stream.*; +import java.util.regex.Pattern; + +public class FileToWords { + public static Stream stream(String filePath) + throws Exception { + return Files.lines(Paths.get(filePath)) + .skip(1) // First (comment) line + .flatMap(line -> + Pattern.compile("\\W+").splitAsStream(line)); + } +} diff --git a/code/streams/FileToWordsBuilder.java b/code/streams/FileToWordsBuilder.java new file mode 100644 index 00000000..d5ac62be --- /dev/null +++ b/code/streams/FileToWordsBuilder.java @@ -0,0 +1,31 @@ +// streams/FileToWordsBuilder.java +// (c)2020 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. +import java.io.*; +import java.nio.file.*; +import java.util.stream.*; + +public class FileToWordsBuilder { + Stream.Builder builder = Stream.builder(); + public FileToWordsBuilder(String filePath) + throws Exception { + Files.lines(Paths.get(filePath)) + .skip(1) // Skip the comment line at the beginning + .forEach(line -> { + for(String w : line.split("[ .?,]+")) + builder.add(w); + }); + } + Stream stream() { return builder.build(); } + public static void + main(String[] args) throws Exception { + new FileToWordsBuilder("Cheese.dat").stream() + .limit(7) + .map(w -> w + " ") + .forEach(System.out::print); + } +} +/* Output: +Not much of a cheese shop really +*/ diff --git a/code/streams/FileToWordsRegexp.java b/code/streams/FileToWordsRegexp.java new file mode 100644 index 00000000..dfff507e --- /dev/null +++ b/code/streams/FileToWordsRegexp.java @@ -0,0 +1,39 @@ +// streams/FileToWordsRegexp.java +// (c)2020 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. +import java.io.*; +import java.nio.file.*; +import java.util.stream.*; +import java.util.regex.Pattern; + +public class FileToWordsRegexp { + private String all; + public FileToWordsRegexp(String filePath) + throws Exception { + all = Files.lines(Paths.get(filePath)) + .skip(1) // First (comment) line + .collect(Collectors.joining(" ")); + } + public Stream stream() { + return Pattern + .compile("[ .,?]+").splitAsStream(all); + } + public static void + main(String[] args) throws Exception { + FileToWordsRegexp fw = + new FileToWordsRegexp("Cheese.dat"); + fw.stream() + .limit(7) + .map(w -> w + " ") + .forEach(System.out::print); + fw.stream() + .skip(7) + .limit(2) + .map(w -> w + " ") + .forEach(System.out::print); + } +} +/* Output: +Not much of a cheese shop really is it +*/ diff --git a/code/streams/FileToWordsTest.java b/code/streams/FileToWordsTest.java new file mode 100644 index 00000000..a81f7209 --- /dev/null +++ b/code/streams/FileToWordsTest.java @@ -0,0 +1,23 @@ +// streams/FileToWordsTest.java +// (c)2020 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. +import java.util.stream.*; + +public class FileToWordsTest { + public static void + main(String[] args) throws Exception { + FileToWords.stream("Cheese.dat") + .limit(7) + .forEach(s -> System.out.format("%s ", s)); + System.out.println(); + FileToWords.stream("Cheese.dat") + .skip(7) + .limit(2) + .forEach(s -> System.out.format("%s ", s)); + } +} +/* Output: +Not much of a cheese shop really +is it +*/ diff --git a/code/streams/FlatMap.java b/code/streams/FlatMap.java new file mode 100644 index 00000000..e2b3137f --- /dev/null +++ b/code/streams/FlatMap.java @@ -0,0 +1,25 @@ +// streams/FlatMap.java +// (c)2020 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. +import java.util.stream.*; + +public class FlatMap { + public static void main(String[] args) { + Stream.of(1, 2, 3) + .flatMap( + i -> Stream.of("Gonzo", "Fozzie", "Beaker")) + .forEach(System.out::println); + } +} +/* Output: +Gonzo +Fozzie +Beaker +Gonzo +Fozzie +Beaker +Gonzo +Fozzie +Beaker +*/ diff --git a/code/streams/ForEach.java b/code/streams/ForEach.java new file mode 100644 index 00000000..f0abe255 --- /dev/null +++ b/code/streams/ForEach.java @@ -0,0 +1,28 @@ +// streams/ForEach.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import static streams.RandInts.*; + +public class ForEach { + static final int SZ = 14; + public static void main(String[] args) { + rands().limit(SZ) + .forEach(n -> System.out.format("%d ", n)); + System.out.println(); + rands().limit(SZ) + .parallel() + .forEach(n -> System.out.format("%d ", n)); + System.out.println(); + rands().limit(SZ) + .parallel() + .forEachOrdered(n -> System.out.format("%d ", n)); + } +} +/* Output: +258 555 693 861 961 429 868 200 522 207 288 128 551 589 +551 861 429 589 200 522 555 693 258 128 868 288 961 207 +258 555 693 861 961 429 868 200 522 207 288 128 551 589 +*/ diff --git a/code/streams/FunctionMap.java b/code/streams/FunctionMap.java new file mode 100644 index 00000000..3c7c90e7 --- /dev/null +++ b/code/streams/FunctionMap.java @@ -0,0 +1,60 @@ +// streams/FunctionMap.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import java.util.function.*; + +class FunctionMap { + static String[] elements = { "12", "", "23", "45" }; + static Stream testStream() { + return Arrays.stream(elements); + } + static void + test(String descr, Function func) { + System.out.println(" ---( " + descr + " )---"); + testStream() + .map(func) + .forEach(System.out::println); + } + public static void main(String[] args) { + + test("add brackets", s -> "[" + s + "]"); + + test("Increment", s -> { + try { + return Integer.parseInt(s) + 1 + ""; + } catch(NumberFormatException e) { + return s; + } + }); + + test("Replace", s -> s.replace("2", "9")); + + test("Take last digit", s -> s.length() > 0 ? + s.charAt(s.length() - 1) + "" : s); + } +} +/* Output: + ---( add brackets )--- +[12] +[] +[23] +[45] + ---( Increment )--- +13 + +24 +46 + ---( Replace )--- +19 + +93 +45 + ---( Take last digit )--- +2 + +3 +5 +*/ diff --git a/code/streams/FunctionMap2.java b/code/streams/FunctionMap2.java new file mode 100644 index 00000000..4d9f2972 --- /dev/null +++ b/code/streams/FunctionMap2.java @@ -0,0 +1,32 @@ +// streams/FunctionMap2.java +// (c)2020 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. +// Different input and output types +import java.util.*; +import java.util.stream.*; + +class Numbered { + final int n; + Numbered(int n) { this.n = n; } + @Override + public String toString() { + return "Numbered(" + n + ")"; + } +} + +class FunctionMap2 { + public static void main(String[] args) { + Stream.of(1, 5, 7, 9, 11, 13) + .map(Numbered::new) + .forEach(System.out::println); + } +} +/* Output: +Numbered(1) +Numbered(5) +Numbered(7) +Numbered(9) +Numbered(11) +Numbered(13) +*/ diff --git a/code/streams/FunctionMap3.java b/code/streams/FunctionMap3.java new file mode 100644 index 00000000..74236af3 --- /dev/null +++ b/code/streams/FunctionMap3.java @@ -0,0 +1,28 @@ +// streams/FunctionMap3.java +// (c)2020 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. +// Producing numeric output streams +import java.util.*; +import java.util.stream.*; + +class FunctionMap3 { + public static void main(String[] args) { + Stream.of("5", "7", "9") + .mapToInt(Integer::parseInt) + .forEach(n -> System.out.format("%d ", n)); + System.out.println(); + Stream.of("17", "19", "23") + .mapToLong(Long::parseLong) + .forEach(n -> System.out.format("%d ", n)); + System.out.println(); + Stream.of("17", "1.9", ".23") + .mapToDouble(Double::parseDouble) + .forEach(n -> System.out.format("%f ", n)); + } +} +/* Output: +5 7 9 +17 19 23 +17.000000 1.900000 0.230000 +*/ diff --git a/code/streams/Generator.java b/code/streams/Generator.java new file mode 100644 index 00000000..c9aba740 --- /dev/null +++ b/code/streams/Generator.java @@ -0,0 +1,25 @@ +// streams/Generator.java +// (c)2020 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. +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +public class Generator implements Supplier { + Random rand = new Random(47); + char[] letters = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); + public String get() { + return "" + letters[rand.nextInt(letters.length)]; + } + public static void main(String[] args) { + String word = Stream.generate(new Generator()) + .limit(30) + .collect(Collectors.joining()); + System.out.println(word); + } +} +/* Output: +YNZBRNYGCFOWZNTCQRGSEGZMMJMROE +*/ diff --git a/code/streams/ImperativeRandoms.java b/code/streams/ImperativeRandoms.java new file mode 100644 index 00000000..f9baaca5 --- /dev/null +++ b/code/streams/ImperativeRandoms.java @@ -0,0 +1,21 @@ +// streams/ImperativeRandoms.java +// (c)2020 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. +import java.util.*; + +public class ImperativeRandoms { + public static void main(String[] args) { + Random rand = new Random(47); + SortedSet rints = new TreeSet<>(); + while(rints.size() < 7) { + int r = rand.nextInt(20); + if(r < 5) continue; + rints.add(r); + } + System.out.println(rints); + } +} +/* Output: +[7, 8, 9, 11, 13, 15, 18] +*/ diff --git a/code/streams/Informational.java b/code/streams/Informational.java new file mode 100644 index 00000000..dd80585c --- /dev/null +++ b/code/streams/Informational.java @@ -0,0 +1,27 @@ +// streams/Informational.java +// (c)2020 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. +import java.util.stream.*; +import java.util.function.*; + +public class Informational { + public static void + main(String[] args) throws Exception { + System.out.println( + FileToWords.stream("Cheese.dat").count()); + System.out.println( + FileToWords.stream("Cheese.dat") + .min(String.CASE_INSENSITIVE_ORDER) + .orElse("NONE")); + System.out.println( + FileToWords.stream("Cheese.dat") + .max(String.CASE_INSENSITIVE_ORDER) + .orElse("NONE")); + } +} +/* Output: +32 +a +you +*/ diff --git a/code/streams/LastElement.java b/code/streams/LastElement.java new file mode 100644 index 00000000..398b0488 --- /dev/null +++ b/code/streams/LastElement.java @@ -0,0 +1,24 @@ +// streams/LastElement.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; + +public class LastElement { + public static void main(String[] args) { + OptionalInt last = IntStream.range(10, 20) + .reduce((n1, n2) -> n2); + System.out.println(last.orElse(-1)); + // Non-numeric object: + Optional lastobj = + Stream.of("one", "two", "three") + .reduce((n1, n2) -> n2); + System.out.println( + lastobj.orElse("Nothing there!")); + } +} +/* Output: +19 +three +*/ diff --git a/code/streams/Looping.java b/code/streams/Looping.java new file mode 100644 index 00000000..715ad052 --- /dev/null +++ b/code/streams/Looping.java @@ -0,0 +1,20 @@ +// streams/Looping.java +// (c)2020 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. +import static onjava.Repeat.*; + +public class Looping { + static void hi() { System.out.println("Hi!"); } + public static void main(String[] args) { + repeat(3, () -> System.out.println("Looping!")); + repeat(2, Looping::hi); + } +} +/* Output: +Looping! +Looping! +Looping! +Hi! +Hi! +*/ diff --git a/code/streams/Machine2.java b/code/streams/Machine2.java new file mode 100644 index 00000000..3d407185 --- /dev/null +++ b/code/streams/Machine2.java @@ -0,0 +1,23 @@ +// streams/Machine2.java +// (c)2020 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. +import java.util.*; +import onjava.Operations; + +public class Machine2 { + public static void main(String[] args) { + Arrays.stream(new Operations[] { + () -> Operations.show("Bing"), + () -> Operations.show("Crack"), + () -> Operations.show("Twist"), + () -> Operations.show("Pop") + }).forEach(Operations::execute); + } +} +/* Output: +Bing +Crack +Twist +Pop +*/ diff --git a/code/streams/MapCollector.java b/code/streams/MapCollector.java new file mode 100644 index 00000000..95811e4b --- /dev/null +++ b/code/streams/MapCollector.java @@ -0,0 +1,48 @@ +// streams/MapCollector.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; + +class Pair { + public final Character c; + public final Integer i; + Pair(Character c, Integer i) { + this.c = c; + this.i = i; + } + public Character getC() { return c; } + public Integer getI() { return i; } + @Override + public String toString() { + return "Pair(" + c + ", " + i + ")"; + } +} + +class RandomPair { + Random rand = new Random(47); + // An infinite iterator of random capital letters: + Iterator capChars = rand.ints(65,91) + .mapToObj(i -> (char)i) + .iterator(); + public Stream stream() { + return rand.ints(100, 1000).distinct() + .mapToObj(i -> new Pair(capChars.next(), i)); + } +} + +public class MapCollector { + public static void main(String[] args) { + Map map = + new RandomPair().stream() + .limit(8) + .collect( + Collectors.toMap(Pair::getI, Pair::getC)); + System.out.println(map); + } +} +/* Output: +{688=W, 309=C, 293=B, 761=N, 858=N, 668=G, 622=F, +751=N} +*/ diff --git a/code/streams/Matching.java b/code/streams/Matching.java new file mode 100644 index 00000000..f5c01bc6 --- /dev/null +++ b/code/streams/Matching.java @@ -0,0 +1,38 @@ +// streams/Matching.java +// (c)2020 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. +// Demonstrates short-circuiting of *Match() operations +import java.util.stream.*; +import java.util.function.*; +import static streams.RandInts.*; + +interface Matcher extends + BiPredicate, Predicate> {} + +public class Matching { + static void show(Matcher match, int val) { + System.out.println( + match.test( + IntStream.rangeClosed(1, 9) + .boxed() + .peek(n -> System.out.format("%d ", n)), + n -> n < val)); + } + public static void main(String[] args) { + show(Stream::allMatch, 10); + show(Stream::allMatch, 4); + show(Stream::anyMatch, 2); + show(Stream::anyMatch, 0); + show(Stream::noneMatch, 5); + show(Stream::noneMatch, 0); + } +} +/* Output: +1 2 3 4 5 6 7 8 9 true +1 2 3 4 false +1 true +1 2 3 4 5 6 7 8 9 false +1 false +1 2 3 4 5 6 7 8 9 true +*/ diff --git a/code/streams/NumericStreamInfo.java b/code/streams/NumericStreamInfo.java new file mode 100644 index 00000000..0d04b6ef --- /dev/null +++ b/code/streams/NumericStreamInfo.java @@ -0,0 +1,24 @@ +// streams/NumericStreamInfo.java +// (c)2020 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. +import java.util.stream.*; +import static streams.RandInts.*; + +public class NumericStreamInfo { + public static void main(String[] args) { + System.out.println(rands().average().getAsDouble()); + System.out.println(rands().max().getAsInt()); + System.out.println(rands().min().getAsInt()); + System.out.println(rands().sum()); + System.out.println(rands().summaryStatistics()); + } +} +/* Output: +507.94 +998 +8 +50794 +IntSummaryStatistics{count=100, sum=50794, min=8, +average=507.940000, max=998} +*/ diff --git a/code/streams/OptionalBasics.java b/code/streams/OptionalBasics.java new file mode 100644 index 00000000..625c450a --- /dev/null +++ b/code/streams/OptionalBasics.java @@ -0,0 +1,23 @@ +// streams/OptionalBasics.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; + +class OptionalBasics { + static void test(Optional optString) { + if(optString.isPresent()) + System.out.println(optString.get()); + else + System.out.println("Nothing inside!"); + } + public static void main(String[] args) { + test(Stream.of("Epithets").findFirst()); + test(Stream.empty().findFirst()); + } +} +/* Output: +Epithets +Nothing inside! +*/ diff --git a/code/streams/OptionalFilter.java b/code/streams/OptionalFilter.java new file mode 100644 index 00000000..a2095ec3 --- /dev/null +++ b/code/streams/OptionalFilter.java @@ -0,0 +1,72 @@ +// streams/OptionalFilter.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import java.util.function.*; + +class OptionalFilter { + static String[] elements = { + "Foo", "", "Bar", "Baz", "Bingo" + }; + static Stream testStream() { + return Arrays.stream(elements); + } + static void + test(String descr, Predicate pred) { + System.out.println(" ---( " + descr + " )---"); + for(int i = 0; i <= elements.length; i++) { + System.out.println( + testStream() + .skip(i) + .findFirst() + .filter(pred)); + } + } + public static void main(String[] args) { + test("true", str -> true); + test("false", str -> false); + test("str != \"\"", str -> str != ""); + test("str.length() == 3", str -> str.length() == 3); + test("startsWith(\"B\")", + str -> str.startsWith("B")); + } +} +/* Output: + ---( true )--- +Optional[Foo] +Optional[] +Optional[Bar] +Optional[Baz] +Optional[Bingo] +Optional.empty + ---( false )--- +Optional.empty +Optional.empty +Optional.empty +Optional.empty +Optional.empty +Optional.empty + ---( str != "" )--- +Optional[Foo] +Optional.empty +Optional[Bar] +Optional[Baz] +Optional[Bingo] +Optional.empty + ---( str.length() == 3 )--- +Optional[Foo] +Optional.empty +Optional[Bar] +Optional[Baz] +Optional.empty +Optional.empty + ---( startsWith("B") )--- +Optional.empty +Optional.empty +Optional[Bar] +Optional[Baz] +Optional[Bingo] +Optional.empty +*/ diff --git a/code/streams/OptionalFlatMap.java b/code/streams/OptionalFlatMap.java new file mode 100644 index 00000000..52e8e81e --- /dev/null +++ b/code/streams/OptionalFlatMap.java @@ -0,0 +1,73 @@ +// streams/OptionalFlatMap.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import java.util.function.*; + +class OptionalFlatMap { + static String[] elements = { "12", "", "23", "45" }; + static Stream testStream() { + return Arrays.stream(elements); + } + static void test(String descr, + Function> func) { + System.out.println(" ---( " + descr + " )---"); + for(int i = 0; i <= elements.length; i++) { + System.out.println( + testStream() + .skip(i) + .findFirst() + .flatMap(func)); + } + } + public static void main(String[] args) { + + test("Add brackets", + s -> Optional.of("[" + s + "]")); + + test("Increment", s -> { + try { + return Optional.of( + Integer.parseInt(s) + 1 + ""); + } catch(NumberFormatException e) { + return Optional.of(s); + } + }); + + test("Replace", + s -> Optional.of(s.replace("2", "9"))); + + test("Take last digit", + s -> Optional.of(s.length() > 0 ? + s.charAt(s.length() - 1) + "" + : s)); + } +} +/* Output: + ---( Add brackets )--- +Optional[[12]] +Optional[[]] +Optional[[23]] +Optional[[45]] +Optional.empty + ---( Increment )--- +Optional[13] +Optional[] +Optional[24] +Optional[46] +Optional.empty + ---( Replace )--- +Optional[19] +Optional[] +Optional[93] +Optional[45] +Optional.empty + ---( Take last digit )--- +Optional[2] +Optional[] +Optional[3] +Optional[5] +Optional.empty +*/ diff --git a/code/streams/OptionalMap.java b/code/streams/OptionalMap.java new file mode 100644 index 00000000..83ae4396 --- /dev/null +++ b/code/streams/OptionalMap.java @@ -0,0 +1,74 @@ +// streams/OptionalMap.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import java.util.function.*; + +class OptionalMap { + static String[] elements = { "12", "", "23", "45" }; + static Stream testStream() { + return Arrays.stream(elements); + } + static void + test(String descr, Function func) { + System.out.println(" ---( " + descr + " )---"); + for(int i = 0; i <= elements.length; i++) { + System.out.println( + testStream() + .skip(i) + .findFirst() // Produces an Optional + .map(func)); + } + } + public static void main(String[] args) { + + // If Optional is not empty, map() first extracts + // the contents which it then passes + // to the function: + + test("Add brackets", s -> "[" + s + "]"); + + test("Increment", s -> { + try { + return Integer.parseInt(s) + 1 + ""; + } catch(NumberFormatException e) { + return s; + } + }); + + test("Replace", s -> s.replace("2", "9")); + + test("Take last digit", s -> s.length() > 0 ? + s.charAt(s.length() - 1) + "" : s); + } + // After the function is finished, map() wraps the + // result in an Optional before returning it: +} +/* Output: + ---( Add brackets )--- +Optional[[12]] +Optional[[]] +Optional[[23]] +Optional[[45]] +Optional.empty + ---( Increment )--- +Optional[13] +Optional[] +Optional[24] +Optional[46] +Optional.empty + ---( Replace )--- +Optional[19] +Optional[] +Optional[93] +Optional[45] +Optional.empty + ---( Take last digit )--- +Optional[2] +Optional[] +Optional[3] +Optional[5] +Optional.empty +*/ diff --git a/code/streams/Optionals.java b/code/streams/Optionals.java new file mode 100644 index 00000000..4d0d96cb --- /dev/null +++ b/code/streams/Optionals.java @@ -0,0 +1,63 @@ +// streams/Optionals.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import java.util.function.*; + +public class Optionals { + static void basics(Optional optString) { + if(optString.isPresent()) + System.out.println(optString.get()); + else + System.out.println("Nothing inside!"); + } + static void ifPresent(Optional optString) { + optString.ifPresent(System.out::println); + } + static void orElse(Optional optString) { + System.out.println(optString.orElse("Nada")); + } + static void orElseGet(Optional optString) { + System.out.println( + optString.orElseGet(() -> "Generated")); + } + static void orElseThrow(Optional optString) { + try { + System.out.println(optString.orElseThrow( + () -> new Exception("Supplied"))); + } catch(Exception e) { + System.out.println("Caught " + e); + } + } + static void test(String testName, + Consumer> cos) { + System.out.println(" === " + testName + " === "); + cos.accept(Stream.of("Epithets").findFirst()); + cos.accept(Stream.empty().findFirst()); + } + public static void main(String[] args) { + test("basics", Optionals::basics); + test("ifPresent", Optionals::ifPresent); + test("orElse", Optionals::orElse); + test("orElseGet", Optionals::orElseGet); + test("orElseThrow", Optionals::orElseThrow); + } +} +/* Output: + === basics === +Epithets +Nothing inside! + === ifPresent === +Epithets + === orElse === +Epithets +Nada + === orElseGet === +Epithets +Generated + === orElseThrow === +Epithets +Caught java.lang.Exception: Supplied +*/ diff --git a/code/streams/OptionalsFromEmptyStreams.java b/code/streams/OptionalsFromEmptyStreams.java new file mode 100644 index 00000000..771a84c0 --- /dev/null +++ b/code/streams/OptionalsFromEmptyStreams.java @@ -0,0 +1,31 @@ +// streams/OptionalsFromEmptyStreams.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; + +class OptionalsFromEmptyStreams { + public static void main(String[] args) { + System.out.println(Stream.empty() + .findFirst()); + System.out.println(Stream.empty() + .findAny()); + System.out.println(Stream.empty() + .max(String.CASE_INSENSITIVE_ORDER)); + System.out.println(Stream.empty() + .min(String.CASE_INSENSITIVE_ORDER)); + System.out.println(Stream.empty() + .reduce((s1, s2) -> s1 + s2)); + System.out.println(IntStream.empty() + .average()); + } +} +/* Output: +Optional.empty +Optional.empty +Optional.empty +Optional.empty +Optional.empty +OptionalDouble.empty +*/ diff --git a/code/streams/Peeking.java b/code/streams/Peeking.java new file mode 100644 index 00000000..d8800515 --- /dev/null +++ b/code/streams/Peeking.java @@ -0,0 +1,22 @@ +// streams/Peeking.java +// (c)2020 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. + +class Peeking { + public static void + main(String[] args) throws Exception { + FileToWords.stream("Cheese.dat") + .skip(21) + .limit(4) + .map(w -> w + " ") + .peek(System.out::print) + .map(String::toUpperCase) + .peek(System.out::print) + .map(String::toLowerCase) + .forEach(System.out::print); + } +} +/* Output: +Well WELL well it IT it s S s so SO so +*/ diff --git a/code/streams/Prime.java b/code/streams/Prime.java new file mode 100644 index 00000000..e14459d1 --- /dev/null +++ b/code/streams/Prime.java @@ -0,0 +1,31 @@ +// streams/Prime.java +// (c)2020 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. +import java.util.stream.*; +import static java.util.stream.LongStream.*; + +public class Prime { + public static boolean isPrime(long n) { + return rangeClosed(2, (long)Math.sqrt(n)) + .noneMatch(i -> n % i == 0); + } + public LongStream numbers() { + return iterate(2, i -> i + 1) + .filter(Prime::isPrime); + } + public static void main(String[] args) { + new Prime().numbers() + .limit(10) + .forEach(n -> System.out.format("%d ", n)); + System.out.println(); + new Prime().numbers() + .skip(90) + .limit(10) + .forEach(n -> System.out.format("%d ", n)); + } +} +/* Output: +2 3 5 7 11 13 17 19 23 29 +467 479 487 491 499 503 509 521 523 541 +*/ diff --git a/code/streams/RandInts.java b/code/streams/RandInts.java new file mode 100644 index 00000000..8adfc60e --- /dev/null +++ b/code/streams/RandInts.java @@ -0,0 +1,15 @@ +// streams/RandInts.java +// (c)2020 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 streams; +import java.util.*; +import java.util.stream.*; + +public class RandInts { + private static int[] rints = + new Random(47).ints(0, 1000).limit(100).toArray(); + public static IntStream rands() { + return Arrays.stream(rints); + } +} diff --git a/code/streams/RandomGenerators.java b/code/streams/RandomGenerators.java new file mode 100644 index 00000000..904216ac --- /dev/null +++ b/code/streams/RandomGenerators.java @@ -0,0 +1,86 @@ +// streams/RandomGenerators.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; + +public class RandomGenerators { + public static void show(Stream stream) { + stream + .limit(4) + .forEach(System.out::println); + System.out.println("++++++++"); + } + public static void main(String[] args) { + Random rand = new Random(47); + show(rand.ints().boxed()); + show(rand.longs().boxed()); + show(rand.doubles().boxed()); + // Control the lower and upper bounds: + show(rand.ints(10, 20).boxed()); + show(rand.longs(50, 100).boxed()); + show(rand.doubles(20, 30).boxed()); + // Control the stream size: + show(rand.ints(2).boxed()); + show(rand.longs(2).boxed()); + show(rand.doubles(2).boxed()); + // Control the stream size and bounds: + show(rand.ints(3, 3, 9).boxed()); + show(rand.longs(3, 12, 22).boxed()); + show(rand.doubles(3, 11.5, 12.3).boxed()); + } +} +/* Output: +-1172028779 +1717241110 +-2014573909 +229403722 +++++++++ +2955289354441303771 +3476817843704654257 +-8917117694134521474 +4941259272818818752 +++++++++ +0.2613610344283964 +0.0508673570556899 +0.8037155449603999 +0.7620665811558285 +++++++++ +16 +10 +11 +12 +++++++++ +65 +99 +54 +58 +++++++++ +29.86777681078574 +24.83968447804611 +20.09247112332014 +24.046793846338723 +++++++++ +1169976606 +1947946283 +++++++++ +2970202997824602425 +-2325326920272830366 +++++++++ +0.7024254510631527 +0.6648552384607359 +++++++++ +6 +7 +7 +++++++++ +17 +12 +20 +++++++++ +12.27872414236691 +11.732085449736195 +12.196509449817267 +++++++++ +*/ diff --git a/code/streams/RandomWords.java b/code/streams/RandomWords.java new file mode 100644 index 00000000..3bf2e51b --- /dev/null +++ b/code/streams/RandomWords.java @@ -0,0 +1,41 @@ +// streams/RandomWords.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import java.util.function.*; +import java.io.*; +import java.nio.file.*; + +public class RandomWords implements Supplier { + List words = new ArrayList<>(); + Random rand = new Random(47); + RandomWords(String fname) throws IOException { + List lines = + Files.readAllLines(Paths.get(fname)); + // Skip the first line: + for(String line : lines.subList(1, lines.size())) { + for(String word : line.split("[ .?,]+")) + words.add(word.toLowerCase()); + } + } + public String get() { + return words.get(rand.nextInt(words.size())); + } + @Override + public String toString() { + return words.stream() + .collect(Collectors.joining(" ")); + } + public static void + main(String[] args) throws Exception { + System.out.println( + Stream.generate(new RandomWords("Cheese.dat")) + .limit(10) + .collect(Collectors.joining(" "))); + } +} +/* Output: +it shop sir the much cheese by conclusion district is +*/ diff --git a/code/streams/Randoms.java b/code/streams/Randoms.java new file mode 100644 index 00000000..f2b5f6a8 --- /dev/null +++ b/code/streams/Randoms.java @@ -0,0 +1,25 @@ +// streams/Randoms.java +// (c)2020 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. +import java.util.*; + +public class Randoms { + public static void main(String[] args) { + new Random(47) + .ints(5, 20) + .distinct() + .limit(7) + .sorted() + .forEach(System.out::println); + } +} +/* Output: +6 +10 +13 +16 +17 +18 +19 +*/ diff --git a/code/streams/Ranges.java b/code/streams/Ranges.java new file mode 100644 index 00000000..d8fc681a --- /dev/null +++ b/code/streams/Ranges.java @@ -0,0 +1,29 @@ +// streams/Ranges.java +// (c)2020 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. +import static java.util.stream.IntStream.*; + +public class Ranges { + public static void main(String[] args) { + // The traditional way: + int result = 0; + for(int i = 10; i < 20; i++) + result += i; + System.out.println(result); + + // for-in with a range: + result = 0; + for(int i : range(10, 20).toArray()) + result += i; + System.out.println(result); + + // Use streams: + System.out.println(range(10, 20).sum()); + } +} +/* Output: +145 +145 +145 +*/ diff --git a/code/streams/Reduce.java b/code/streams/Reduce.java new file mode 100644 index 00000000..0e9f07ba --- /dev/null +++ b/code/streams/Reduce.java @@ -0,0 +1,44 @@ +// streams/Reduce.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; + +class Frobnitz { + int size; + Frobnitz(int sz) { size = sz; } + @Override + public String toString() { + return "Frobnitz(" + size + ")"; + } + // Generator: + static Random rand = new Random(47); + static final int BOUND = 100; + static Frobnitz supply() { + return new Frobnitz(rand.nextInt(BOUND)); + } +} + +public class Reduce { + public static void main(String[] args) { + Stream.generate(Frobnitz::supply) + .limit(10) + .peek(System.out::println) + .reduce((fr0, fr1) -> fr0.size < 50 ? fr0 : fr1) + .ifPresent(System.out::println); + } +} +/* Output: +Frobnitz(58) +Frobnitz(55) +Frobnitz(93) +Frobnitz(61) +Frobnitz(61) +Frobnitz(29) +Frobnitz(68) +Frobnitz(0) +Frobnitz(22) +Frobnitz(7) +Frobnitz(29) +*/ diff --git a/code/streams/SelectElement.java b/code/streams/SelectElement.java new file mode 100644 index 00000000..86846e40 --- /dev/null +++ b/code/streams/SelectElement.java @@ -0,0 +1,24 @@ +// streams/SelectElement.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import static streams.RandInts.*; + +public class SelectElement { + public static void main(String[] args) { + System.out.println(rands().findFirst().getAsInt()); + System.out.println( + rands().parallel().findFirst().getAsInt()); + System.out.println(rands().findAny().getAsInt()); + System.out.println( + rands().parallel().findAny().getAsInt()); + } +} +/* Output: +258 +258 +258 +242 +*/ diff --git a/code/streams/Signal.java b/code/streams/Signal.java new file mode 100644 index 00000000..9dc2a9f4 --- /dev/null +++ b/code/streams/Signal.java @@ -0,0 +1,29 @@ +// streams/Signal.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import java.util.function.*; + +public class Signal { + private final String msg; + public Signal(String msg) { this.msg = msg; } + public String getMsg() { return msg; } + @Override + public String toString() { + return "Signal(" + msg + ")"; + } + static Random rand = new Random(47); + public static Signal morse() { + switch(rand.nextInt(4)) { + case 1: return new Signal("dot"); + case 2: return new Signal("dash"); + default: return null; + } + } + public static Stream> stream() { + return Stream.generate(Signal::morse) + .map(signal -> Optional.ofNullable(signal)); + } +} diff --git a/code/streams/SortedComparator.java b/code/streams/SortedComparator.java new file mode 100644 index 00000000..070d60a7 --- /dev/null +++ b/code/streams/SortedComparator.java @@ -0,0 +1,20 @@ +// streams/SortedComparator.java +// (c)2020 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. +import java.util.*; + +public class SortedComparator { + public static void + main(String[] args) throws Exception { + FileToWords.stream("Cheese.dat") + .skip(10) + .limit(10) + .sorted(Comparator.reverseOrder()) + .map(w -> w + " ") + .forEach(System.out::print); + } +} +/* Output: +you what to the that sir leads in district And +*/ diff --git a/code/streams/SpecialCollector.java b/code/streams/SpecialCollector.java new file mode 100644 index 00000000..9526a73e --- /dev/null +++ b/code/streams/SpecialCollector.java @@ -0,0 +1,24 @@ +// streams/SpecialCollector.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; + +public class SpecialCollector { + public static void + main(String[] args) throws Exception { + ArrayList words = + FileToWords.stream("Cheese.dat") + .collect(ArrayList::new, + ArrayList::add, + ArrayList::addAll); + words.stream() + .filter(s -> s.equals("cheese")) + .forEach(System.out::println); + } +} +/* Output: +cheese +cheese +*/ diff --git a/code/streams/StreamOf.java b/code/streams/StreamOf.java new file mode 100644 index 00000000..c143388a --- /dev/null +++ b/code/streams/StreamOf.java @@ -0,0 +1,28 @@ +// streams/StreamOf.java +// (c)2020 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. +import java.util.stream.*; + +public class StreamOf { + public static void main(String[] args) { + Stream.of( + new Bubble(1), new Bubble(2), new Bubble(3)) + .forEach(System.out::println); + Stream.of("It's ", "a ", "wonderful ", + "day ", "for ", "pie!") + .forEach(System.out::print); + System.out.println(); + Stream.of(3.14159, 2.718, 1.618) + .forEach(System.out::println); + } +} +/* Output: +Bubble(1) +Bubble(2) +Bubble(3) +It's a wonderful day for pie! +3.14159 +2.718 +1.618 +*/ diff --git a/code/streams/StreamOfOptionals.java b/code/streams/StreamOfOptionals.java new file mode 100644 index 00000000..f725df57 --- /dev/null +++ b/code/streams/StreamOfOptionals.java @@ -0,0 +1,37 @@ +// streams/StreamOfOptionals.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; + +public class StreamOfOptionals { + public static void main(String[] args) { + Signal.stream() + .limit(10) + .forEach(System.out::println); + System.out.println(" ---"); + Signal.stream() + .limit(10) + .filter(Optional::isPresent) + .map(Optional::get) + .forEach(System.out::println); + } +} +/* Output: +Optional[Signal(dash)] +Optional[Signal(dot)] +Optional[Signal(dash)] +Optional.empty +Optional.empty +Optional[Signal(dash)] +Optional.empty +Optional[Signal(dot)] +Optional[Signal(dash)] +Optional[Signal(dash)] + --- +Signal(dot) +Signal(dot) +Signal(dash) +Signal(dash) +*/ diff --git a/code/streams/StreamOfRandoms.java b/code/streams/StreamOfRandoms.java new file mode 100644 index 00000000..66bf2bc7 --- /dev/null +++ b/code/streams/StreamOfRandoms.java @@ -0,0 +1,20 @@ +// streams/StreamOfRandoms.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; + +public class StreamOfRandoms { + static Random rand = new Random(47); + public static void main(String[] args) { + Stream.of(1, 2, 3, 4, 5) + .flatMapToInt(i -> IntStream.concat( + rand.ints(0, 100).limit(i), IntStream.of(-1))) + .forEach(n -> System.out.format("%d ", n)); + } +} +/* Output: +58 -1 55 93 -1 61 61 29 -1 68 0 22 7 -1 88 28 51 89 9 +-1 +*/ diff --git a/code/streams/StreamOfStreams.java b/code/streams/StreamOfStreams.java new file mode 100644 index 00000000..973d83a6 --- /dev/null +++ b/code/streams/StreamOfStreams.java @@ -0,0 +1,19 @@ +// streams/StreamOfStreams.java +// (c)2020 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. +import java.util.stream.*; + +public class StreamOfStreams { + public static void main(String[] args) { + Stream.of(1, 2, 3) + .map(i -> Stream.of("Gonzo", "Kermit", "Beaker")) + .map(e-> e.getClass().getName()) + .forEach(System.out::println); + } +} +/* Output: +java.util.stream.ReferencePipeline$Head +java.util.stream.ReferencePipeline$Head +java.util.stream.ReferencePipeline$Head +*/ diff --git a/code/streams/TreeSetOfWords.java b/code/streams/TreeSetOfWords.java new file mode 100644 index 00000000..feaa56a2 --- /dev/null +++ b/code/streams/TreeSetOfWords.java @@ -0,0 +1,31 @@ +// streams/TreeSetOfWords.java +// (c)2020 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. +import java.util.*; +import java.nio.file.*; +import java.util.stream.*; + +public class TreeSetOfWords { + public static void + main(String[] args) throws Exception { + Set words2 = + Files.lines(Paths.get("TreeSetOfWords.java")) + .flatMap(s -> Arrays.stream(s.split("\\W+"))) + .filter(s -> !s.matches("\\d+")) // No numbers + .map(String::trim) + .filter(s -> s.length() > 2) + .limit(100) + .collect(Collectors.toCollection(TreeSet::new)); + System.out.println(words2); + } +} +/* Output: +[Arrays, Collectors, Exception, Files, Output, Paths, +Set, String, System, TreeSet, TreeSetOfWords, args, +class, collect, file, filter, flatMap, get, import, +java, length, limit, lines, main, map, matches, new, +nio, numbers, out, println, public, split, static, +stream, streams, throws, toCollection, trim, util, +void, words2] +*/ diff --git a/code/strings/ArrayListDisplay.java b/code/strings/ArrayListDisplay.java new file mode 100644 index 00000000..7b83296f --- /dev/null +++ b/code/strings/ArrayListDisplay.java @@ -0,0 +1,22 @@ +// strings/ArrayListDisplay.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; +import generics.coffee.*; + +public class ArrayListDisplay { + public static void main(String[] args) { + List coffees = + Stream.generate(new CoffeeSupplier()) + .limit(10) + .collect(Collectors.toList()); + System.out.println(coffees); + } +} +/* Output: +[Americano 0, Latte 1, Americano 2, Mocha 3, Mocha 4, +Breve 5, Americano 6, Latte 7, Cappuccino 8, Cappuccino +9] +*/ diff --git a/code/strings/BetterRead.java b/code/strings/BetterRead.java new file mode 100644 index 00000000..a3b7aaa2 --- /dev/null +++ b/code/strings/BetterRead.java @@ -0,0 +1,37 @@ +// strings/BetterRead.java +// (c)2020 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. +import java.util.*; + +public class BetterRead { + public static void main(String[] args) { + Scanner stdin = new Scanner(SimpleRead.input); + System.out.println("What is your name?"); + String name = stdin.nextLine(); + System.out.println(name); + System.out.println( + "How old are you? What is your favorite double?"); + System.out.println("(input: )"); + int age = stdin.nextInt(); + double favorite = stdin.nextDouble(); + System.out.println(age); + System.out.println(favorite); + System.out.format("Hi %s.%n", name); + System.out.format("In 5 years you will be %d.%n", + age + 5); + System.out.format("My favorite double is %f.", + favorite / 2); + } +} +/* Output: +What is your name? +Sir Robin of Camelot +How old are you? What is your favorite double? +(input: ) +22 +1.61803 +Hi Sir Robin of Camelot. +In 5 years you will be 27. +My favorite double is 0.809015. +*/ diff --git a/code/strings/Concatenation.java b/code/strings/Concatenation.java new file mode 100644 index 00000000..685f4dbb --- /dev/null +++ b/code/strings/Concatenation.java @@ -0,0 +1,15 @@ +// strings/Concatenation.java +// (c)2020 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. + +public class Concatenation { + public static void main(String[] args) { + String mango = "mango"; + String s = "abc" + mango + "def" + 47; + System.out.println(s); + } +} +/* Output: +abcmangodef47 +*/ diff --git a/code/strings/Conversion.java b/code/strings/Conversion.java new file mode 100644 index 00000000..f839e81a --- /dev/null +++ b/code/strings/Conversion.java @@ -0,0 +1,113 @@ +// strings/Conversion.java +// (c)2020 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. +import java.math.*; +import java.util.*; + +public class Conversion { + public static void main(String[] args) { + Formatter f = new Formatter(System.out); + + char u = 'a'; + System.out.println("u = 'a'"); + f.format("s: %s%n", u); + // f.format("d: %d%n", u); + f.format("c: %c%n", u); + f.format("b: %b%n", u); + // f.format("f: %f%n", u); + // f.format("e: %e%n", u); + // f.format("x: %x%n", u); + f.format("h: %h%n", u); + + int v = 121; + System.out.println("v = 121"); + f.format("d: %d%n", v); + f.format("c: %c%n", v); + f.format("b: %b%n", v); + f.format("s: %s%n", v); + // f.format("f: %f%n", v); + // f.format("e: %e%n", v); + f.format("x: %x%n", v); + f.format("h: %h%n", v); + + BigInteger w = new BigInteger("50000000000000"); + System.out.println( + "w = new BigInteger(\"50000000000000\")"); + f.format("d: %d%n", w); + // f.format("c: %c%n", w); + f.format("b: %b%n", w); + f.format("s: %s%n", w); + // f.format("f: %f%n", w); + // f.format("e: %e%n", w); + f.format("x: %x%n", w); + f.format("h: %h%n", w); + + double x = 179.543; + System.out.println("x = 179.543"); + // f.format("d: %d%n", x); + // f.format("c: %c%n", x); + f.format("b: %b%n", x); + f.format("s: %s%n", x); + f.format("f: %f%n", x); + f.format("e: %e%n", x); + // f.format("x: %x%n", x); + f.format("h: %h%n", x); + + Conversion y = new Conversion(); + System.out.println("y = new Conversion()"); + // f.format("d: %d%n", y); + // f.format("c: %c%n", y); + f.format("b: %b%n", y); + f.format("s: %s%n", y); + // f.format("f: %f%n", y); + // f.format("e: %e%n", y); + // f.format("x: %x%n", y); + f.format("h: %h%n", y); + + boolean z = false; + System.out.println("z = false"); + // f.format("d: %d%n", z); + // f.format("c: %c%n", z); + f.format("b: %b%n", z); + f.format("s: %s%n", z); + // f.format("f: %f%n", z); + // f.format("e: %e%n", z); + // f.format("x: %x%n", z); + f.format("h: %h%n", z); + } +} +/* Output: +u = 'a' +s: a +c: a +b: true +h: 61 +v = 121 +d: 121 +c: y +b: true +s: 121 +x: 79 +h: 79 +w = new BigInteger("50000000000000") +d: 50000000000000 +b: true +s: 50000000000000 +x: 2d79883d2000 +h: 8842a1a7 +x = 179.543 +b: true +s: 179.543 +f: 179.543000 +e: 1.795430e+02 +h: 1ef462c +y = new Conversion() +b: true +s: Conversion@15db9742 +h: 15db9742 +z = false +b: false +s: false +h: 4d5 +*/ diff --git a/code/strings/DatabaseException.java b/code/strings/DatabaseException.java new file mode 100644 index 00000000..e8441254 --- /dev/null +++ b/code/strings/DatabaseException.java @@ -0,0 +1,22 @@ +// strings/DatabaseException.java +// (c)2020 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. + +public class DatabaseException extends Exception { + public DatabaseException(int transactionID, + int queryID, String message) { + super(String.format("(t%d, q%d) %s", transactionID, + queryID, message)); + } + public static void main(String[] args) { + try { + throw new DatabaseException(3, 7, "Write failed"); + } catch(Exception e) { + System.out.println(e); + } + } +} +/* Output: +DatabaseException: (t3, q7) Write failed +*/ diff --git a/code/strings/Finding.java b/code/strings/Finding.java new file mode 100644 index 00000000..f8d7cbbc --- /dev/null +++ b/code/strings/Finding.java @@ -0,0 +1,27 @@ +// strings/Finding.java +// (c)2020 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. +import java.util.regex.*; + +public class Finding { + public static void main(String[] args) { + Matcher m = Pattern.compile("\\w+") + .matcher( + "Evening is full of the linnet's wings"); + while(m.find()) + System.out.print(m.group() + " "); + System.out.println(); + int i = 0; + while(m.find(i)) { + System.out.print(m.group() + " "); + i++; + } + } +} +/* Output: +Evening is full of the linnet s wings +Evening vening ening ning ing ng g is is s full full +ull ll l of of f the the he e linnet linnet innet nnet +net et t s s wings wings ings ngs gs s +*/ diff --git a/code/strings/Groups.java b/code/strings/Groups.java new file mode 100644 index 00000000..298caf62 --- /dev/null +++ b/code/strings/Groups.java @@ -0,0 +1,40 @@ +// strings/Groups.java +// (c)2020 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. +import java.util.regex.*; + +public class Groups { + public static final String POEM = + "Twas brillig, and the slithy toves\n" + + "Did gyre and gimble in the wabe.\n" + + "All mimsy were the borogoves,\n" + + "And the mome raths outgrabe.\n\n" + + "Beware the Jabberwock, my son,\n" + + "The jaws that bite, the claws that catch.\n" + + "Beware the Jubjub bird, and shun\n" + + "The frumious Bandersnatch."; + public static void main(String[] args) { + Matcher m = Pattern.compile( + "(?m)(\\S+)\\s+((\\S+)\\s+(\\S+))$") + .matcher(POEM); + while(m.find()) { + for(int j = 0; j <= m.groupCount(); j++) + System.out.print("[" + m.group(j) + "]"); + System.out.println(); + } + } +} +/* Output: +[the slithy toves][the][slithy toves][slithy][toves] +[in the wabe.][in][the wabe.][the][wabe.] +[were the borogoves,][were][the +borogoves,][the][borogoves,] +[mome raths outgrabe.][mome][raths +outgrabe.][raths][outgrabe.] +[Jabberwock, my son,][Jabberwock,][my son,][my][son,] +[claws that catch.][claws][that catch.][that][catch.] +[bird, and shun][bird,][and shun][and][shun] +[The frumious Bandersnatch.][The][frumious +Bandersnatch.][frumious][Bandersnatch.] +*/ diff --git a/code/strings/Hex.java b/code/strings/Hex.java new file mode 100644 index 00000000..0fbcea8e --- /dev/null +++ b/code/strings/Hex.java @@ -0,0 +1,44 @@ +// strings/Hex.java +// (c)2020 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. +// {java onjava.Hex} +package onjava; +import java.io.*; +import java.nio.file.*; + +public class Hex { + public static String format(byte[] data) { + StringBuilder result = new StringBuilder(); + int n = 0; + for(byte b : data) { + if(n % 16 == 0) + result.append(String.format("%05X: ", n)); + result.append(String.format("%02X ", b)); + n++; + if(n % 16 == 0) result.append("\n"); + } + result.append("\n"); + return result.toString(); + } + public static void + main(String[] args) throws Exception { + if(args.length == 0) + // Test by displaying this class file: + System.out.println(format( + Files.readAllBytes(Paths.get( + "build/classes/java/main/onjava/Hex.class")))); + else + System.out.println(format( + Files.readAllBytes(Paths.get(args[0])))); + } +} +/* Output: (First 6 Lines) +00000: CA FE BA BE 00 00 00 34 00 61 0A 00 05 00 31 07 +00010: 00 32 0A 00 02 00 31 08 00 33 07 00 34 0A 00 35 +00020: 00 36 0A 00 0F 00 37 0A 00 02 00 38 08 00 39 0A +00030: 00 3A 00 3B 08 00 3C 0A 00 02 00 3D 09 00 3E 00 +00040: 3F 08 00 40 07 00 41 0A 00 42 00 43 0A 00 44 00 +00050: 45 0A 00 14 00 46 0A 00 47 00 48 07 00 49 01 00 + ... +*/ diff --git a/code/strings/Immutable.java b/code/strings/Immutable.java new file mode 100644 index 00000000..4c8b529e --- /dev/null +++ b/code/strings/Immutable.java @@ -0,0 +1,22 @@ +// strings/Immutable.java +// (c)2020 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. + +public class Immutable { + public static String upcase(String s) { + return s.toUpperCase(); + } + public static void main(String[] args) { + String q = "howdy"; + System.out.println(q); // howdy + String qq = upcase(q); + System.out.println(qq); // HOWDY + System.out.println(q); // howdy + } +} +/* Output: +howdy +HOWDY +howdy +*/ diff --git a/code/strings/InfiniteRecursion.java b/code/strings/InfiniteRecursion.java new file mode 100644 index 00000000..6941490a --- /dev/null +++ b/code/strings/InfiniteRecursion.java @@ -0,0 +1,22 @@ +// strings/InfiniteRecursion.java +// (c)2020 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. +// Accidental recursion +// {ThrowsException} +// {VisuallyInspectOutput} Throws very long exception +import java.util.*; +import java.util.stream.*; + +public class InfiniteRecursion { + @Override + public String toString() { + return + " InfiniteRecursion address: " + this + "\n"; + } + public static void main(String[] args) { + Stream.generate(InfiniteRecursion::new) + .limit(10) + .forEach(System.out::println); + } +} diff --git a/code/strings/IntegerMatch.java b/code/strings/IntegerMatch.java new file mode 100644 index 00000000..5a3a38ac --- /dev/null +++ b/code/strings/IntegerMatch.java @@ -0,0 +1,19 @@ +// strings/IntegerMatch.java +// (c)2020 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. + +public class IntegerMatch { + public static void main(String[] args) { + System.out.println("-1234".matches("-?\\d+")); + System.out.println("5678".matches("-?\\d+")); + System.out.println("+911".matches("-?\\d+")); + System.out.println("+911".matches("(-|\\+)?\\d+")); + } +} +/* Output: +true +true +false +true +*/ diff --git a/code/strings/JGrep.java b/code/strings/JGrep.java new file mode 100644 index 00000000..49cec954 --- /dev/null +++ b/code/strings/JGrep.java @@ -0,0 +1,36 @@ +// strings/JGrep.java +// (c)2020 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. +// A very simple version of the "grep" program +// {java JGrep +// WhitherStringBuilder.java 'return|for|String'} +import java.util.regex.*; +import java.nio.file.*; +import java.util.stream.*; + +public class JGrep { + public static void + main(String[] args) throws Exception { + if(args.length < 2) { + System.out.println( + "Usage: java JGrep file regex"); + System.exit(0); + } + Pattern p = Pattern.compile(args[1]); + // Iterate through the lines of the input file: + int index = 0; + Matcher m = p.matcher(""); + for(String line : + Files.readAllLines(Paths.get(args[0]))) { + m.reset(line); + while(m.find()) + System.out.println(index++ + ": " + + m.group() + ": " + m.start()); + } + } +} +/* Output: +0: for: 4 +1: for: 4 +*/ diff --git a/code/strings/ReFlags.java b/code/strings/ReFlags.java new file mode 100644 index 00000000..856806ee --- /dev/null +++ b/code/strings/ReFlags.java @@ -0,0 +1,23 @@ +// strings/ReFlags.java +// (c)2020 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. +import java.util.regex.*; + +public class ReFlags { + public static void main(String[] args) { + Pattern p = Pattern.compile("^java", + Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + Matcher m = p.matcher( + "java has regex\nJava has regex\n" + + "JAVA has pretty good regular expressions\n" + + "Regular expressions are in Java"); + while(m.find()) + System.out.println(m.group()); + } +} +/* Output: +java +Java +JAVA +*/ diff --git a/code/strings/ReceiptBuilder.java b/code/strings/ReceiptBuilder.java new file mode 100644 index 00000000..234ca1e6 --- /dev/null +++ b/code/strings/ReceiptBuilder.java @@ -0,0 +1,48 @@ +// strings/ReceiptBuilder.java +// (c)2020 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. +import java.util.*; + +public class ReceiptBuilder { + private double total = 0; + private Formatter f = + new Formatter(new StringBuilder()); + public ReceiptBuilder() { + f.format( + "%-15s %5s %10s%n", "Item", "Qty", "Price"); + f.format( + "%-15s %5s %10s%n", "----", "---", "-----"); + } + public void add(String name, int qty, double price) { + f.format("%-15.15s %5d %10.2f%n", name, qty, price); + total += price * qty; + } + public String build() { + f.format("%-15s %5s %10.2f%n", "Tax", "", + total * 0.06); + f.format("%-15s %5s %10s%n", "", "", "-----"); + f.format("%-15s %5s %10.2f%n", "Total", "", + total * 1.06); + return f.toString(); + } + public static void main(String[] args) { + ReceiptBuilder receiptBuilder = + new ReceiptBuilder(); + receiptBuilder.add("Jack's Magic Beans", 4, 4.25); + receiptBuilder.add("Princess Peas", 3, 5.1); + receiptBuilder.add( + "Three Bears Porridge", 1, 14.29); + System.out.println(receiptBuilder.build()); + } +} +/* Output: +Item Qty Price +---- --- ----- +Jack's Magic Be 4 4.25 +Princess Peas 3 5.10 +Three Bears Por 1 14.29 +Tax 2.80 + ----- +Total 49.39 +*/ diff --git a/code/strings/Replacing.java b/code/strings/Replacing.java new file mode 100644 index 00000000..dbc21afe --- /dev/null +++ b/code/strings/Replacing.java @@ -0,0 +1,21 @@ +// strings/Replacing.java +// (c)2020 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. + +public class Replacing { + static String s = Splitting.knights; + public static void main(String[] args) { + System.out.println( + s.replaceFirst("f\\w+", "located")); + System.out.println( + s.replaceAll("shrubbery|tree|herring","banana")); + } +} +/* Output: +Then, when you have located the shrubbery, you must cut +down the mightiest tree in the forest...with... a +herring! +Then, when you have found the banana, you must cut down +the mightiest banana in the forest...with... a banana! +*/ diff --git a/code/strings/ReplacingStringTokenizer.java b/code/strings/ReplacingStringTokenizer.java new file mode 100644 index 00000000..60fad184 --- /dev/null +++ b/code/strings/ReplacingStringTokenizer.java @@ -0,0 +1,26 @@ +// strings/ReplacingStringTokenizer.java +// (c)2020 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. +import java.util.*; + +public class ReplacingStringTokenizer { + public static void main(String[] args) { + String input = + "But I'm not dead yet! I feel happy!"; + StringTokenizer stoke = new StringTokenizer(input); + while(stoke.hasMoreElements()) + System.out.print(stoke.nextToken() + " "); + System.out.println(); + System.out.println( + Arrays.toString(input.split(" "))); + Scanner scanner = new Scanner(input); + while(scanner.hasNext()) + System.out.print(scanner.next() + " "); + } +} +/* Output: +But I'm not dead yet! I feel happy! +[But, I'm, not, dead, yet!, I, feel, happy!] +But I'm not dead yet! I feel happy! +*/ diff --git a/code/strings/Resetting.java b/code/strings/Resetting.java new file mode 100644 index 00000000..f1565390 --- /dev/null +++ b/code/strings/Resetting.java @@ -0,0 +1,23 @@ +// strings/Resetting.java +// (c)2020 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. +import java.util.regex.*; + +public class Resetting { + public static void + main(String[] args) throws Exception { + Matcher m = Pattern.compile("[frb][aiu][gx]") + .matcher("fix the rug with bags"); + while(m.find()) + System.out.print(m.group() + " "); + System.out.println(); + m.reset("fix the rig with rags"); + while(m.find()) + System.out.print(m.group() + " "); + } +} +/* Output: +fix rug bag +fix rig rag +*/ diff --git a/code/strings/Rudolph.java b/code/strings/Rudolph.java new file mode 100644 index 00000000..7a338510 --- /dev/null +++ b/code/strings/Rudolph.java @@ -0,0 +1,21 @@ +// strings/Rudolph.java +// (c)2020 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. + +public class Rudolph { + public static void main(String[] args) { + for(String pattern : new String[]{ + "Rudolph", + "[rR]udolph", + "[rR][aeiou][a-z]ol.*", + "R.*" }) + System.out.println("Rudolph".matches(pattern)); + } +} +/* Output: +true +true +true +true +*/ diff --git a/code/strings/ScannerDelimiter.java b/code/strings/ScannerDelimiter.java new file mode 100644 index 00000000..a06ed990 --- /dev/null +++ b/code/strings/ScannerDelimiter.java @@ -0,0 +1,21 @@ +// strings/ScannerDelimiter.java +// (c)2020 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. +import java.util.*; + +public class ScannerDelimiter { + public static void main(String[] args) { + Scanner scanner = new Scanner("12, 42, 78, 99, 42"); + scanner.useDelimiter("\\s*,\\s*"); + while(scanner.hasNextInt()) + System.out.println(scanner.nextInt()); + } +} +/* Output: +12 +42 +78 +99 +42 +*/ diff --git a/code/strings/SimpleFormat.java b/code/strings/SimpleFormat.java new file mode 100644 index 00000000..a3a6e52f --- /dev/null +++ b/code/strings/SimpleFormat.java @@ -0,0 +1,22 @@ +// strings/SimpleFormat.java +// (c)2020 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. + +public class SimpleFormat { + public static void main(String[] args) { + int x = 5; + double y = 5.332542; + // The old way: + System.out.println("Row 1: [" + x + " " + y + "]"); + // The new way: + System.out.format("Row 1: [%d %f]%n", x, y); + // or + System.out.printf("Row 1: [%d %f]%n", x, y); + } +} +/* Output: +Row 1: [5 5.332542] +Row 1: [5 5.332542] +Row 1: [5 5.332542] +*/ diff --git a/code/strings/SimpleRead.java b/code/strings/SimpleRead.java new file mode 100644 index 00000000..e85a058a --- /dev/null +++ b/code/strings/SimpleRead.java @@ -0,0 +1,43 @@ +// strings/SimpleRead.java +// (c)2020 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. +import java.io.*; + +public class SimpleRead { + public static BufferedReader input = + new BufferedReader(new StringReader( + "Sir Robin of Camelot\n22 1.61803")); + public static void main(String[] args) { + try { + System.out.println("What is your name?"); + String name = input.readLine(); + System.out.println(name); + System.out.println("How old are you? " + + "What is your favorite double?"); + System.out.println("(input: )"); + String numbers = input.readLine(); + System.out.println(numbers); + String[] numArray = numbers.split(" "); + int age = Integer.parseInt(numArray[0]); + double favorite = Double.parseDouble(numArray[1]); + System.out.format("Hi %s.%n", name); + System.out.format("In 5 years you will be %d.%n", + age + 5); + System.out.format("My favorite double is %f.", + favorite / 2); + } catch(IOException e) { + System.err.println("I/O exception"); + } + } +} +/* Output: +What is your name? +Sir Robin of Camelot +How old are you? What is your favorite double? +(input: ) +22 1.61803 +Hi Sir Robin of Camelot. +In 5 years you will be 27. +My favorite double is 0.809015. +*/ diff --git a/code/strings/SplitDemo.java b/code/strings/SplitDemo.java new file mode 100644 index 00000000..65745392 --- /dev/null +++ b/code/strings/SplitDemo.java @@ -0,0 +1,22 @@ +// strings/SplitDemo.java +// (c)2020 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. +import java.util.regex.*; +import java.util.*; + +public class SplitDemo { + public static void main(String[] args) { + String input = + "This!!unusual use!!of exclamation!!points"; + System.out.println(Arrays.toString( + Pattern.compile("!!").split(input))); + // Only do the first three: + System.out.println(Arrays.toString( + Pattern.compile("!!").split(input, 3))); + } +} +/* Output: +[This, unusual use, of exclamation, points] +[This, unusual use, of exclamation!!points] +*/ diff --git a/code/strings/Splitting.java b/code/strings/Splitting.java new file mode 100644 index 00000000..0afe3a40 --- /dev/null +++ b/code/strings/Splitting.java @@ -0,0 +1,32 @@ +// strings/Splitting.java +// (c)2020 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. +import java.util.*; + +public class Splitting { + public static String knights = + "Then, when you have found the shrubbery, " + + "you must cut down the mightiest tree in the " + + "forest...with... a herring!"; + public static void split(String regex) { + System.out.println( + Arrays.toString(knights.split(regex))); + } + public static void main(String[] args) { + split(" "); // Doesn't have to contain regex chars + split("\\W+"); // Non-word characters + split("n\\W+"); // 'n' followed by non-words + } +} +/* Output: +[Then,, when, you, have, found, the, shrubbery,, you, +must, cut, down, the, mightiest, tree, in, the, +forest...with..., a, herring!] +[Then, when, you, have, found, the, shrubbery, you, +must, cut, down, the, mightiest, tree, in, the, forest, +with, a, herring] +[The, whe, you have found the shrubbery, you must cut +dow, the mightiest tree i, the forest...with... a +herring!] +*/ diff --git a/code/strings/StartEnd.java b/code/strings/StartEnd.java new file mode 100644 index 00000000..03caf520 --- /dev/null +++ b/code/strings/StartEnd.java @@ -0,0 +1,82 @@ +// strings/StartEnd.java +// (c)2020 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. +import java.util.regex.*; + +public class StartEnd { + public static String input = + "As long as there is injustice, whenever a\n" + + "Targathian baby cries out, wherever a distress\n" + + "signal sounds among the stars " + + "... We'll be there.\n"+ + "This fine ship, and this fine crew ...\n" + + "Never give up! Never surrender!"; + private static class Display { + private boolean regexPrinted = false; + private String regex; + Display(String regex) { this.regex = regex; } + void display(String message) { + if(!regexPrinted) { + System.out.println(regex); + regexPrinted = true; + } + System.out.println(message); + } + } + static void examine(String s, String regex) { + Display d = new Display(regex); + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(s); + while(m.find()) + d.display("find() '" + m.group() + + "' start = "+ m.start() + " end = " + m.end()); + if(m.lookingAt()) // No reset() necessary + d.display("lookingAt() start = " + + m.start() + " end = " + m.end()); + if(m.matches()) // No reset() necessary + d.display("matches() start = " + + m.start() + " end = " + m.end()); + } + public static void main(String[] args) { + for(String in : input.split("\n")) { + System.out.println("input : " + in); + for(String regex : new String[]{"\\w*ere\\w*", + "\\w*ever", "T\\w+", "Never.*?!"}) + examine(in, regex); + } + } +} +/* Output: +input : As long as there is injustice, whenever a +\w*ere\w* +find() 'there' start = 11 end = 16 +\w*ever +find() 'whenever' start = 31 end = 39 +input : Targathian baby cries out, wherever a distress +\w*ere\w* +find() 'wherever' start = 27 end = 35 +\w*ever +find() 'wherever' start = 27 end = 35 +T\w+ +find() 'Targathian' start = 0 end = 10 +lookingAt() start = 0 end = 10 +input : signal sounds among the stars ... We'll be +there. +\w*ere\w* +find() 'there' start = 43 end = 48 +input : This fine ship, and this fine crew ... +T\w+ +find() 'This' start = 0 end = 4 +lookingAt() start = 0 end = 4 +input : Never give up! Never surrender! +\w*ever +find() 'Never' start = 0 end = 5 +find() 'Never' start = 15 end = 20 +lookingAt() start = 0 end = 5 +Never.*?! +find() 'Never give up!' start = 0 end = 14 +find() 'Never surrender!' start = 15 end = 31 +lookingAt() start = 0 end = 14 +matches() start = 0 end = 31 +*/ diff --git a/code/strings/TestRegularExpression.java b/code/strings/TestRegularExpression.java new file mode 100644 index 00000000..fe79ce8b --- /dev/null +++ b/code/strings/TestRegularExpression.java @@ -0,0 +1,44 @@ +// strings/TestRegularExpression.java +// (c)2020 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. +// Simple regular expression demonstration +// {java TestRegularExpression +// abcabcabcdefabc "abc+" "(abc)+" } +import java.util.regex.*; + +public class TestRegularExpression { + public static void main(String[] args) { + if(args.length < 2) { + System.out.println( + "Usage:\njava TestRegularExpression " + + "characterSequence regularExpression+"); + System.exit(0); + } + System.out.println("Input: \"" + args[0] + "\""); + for(String arg : args) { + System.out.println( + "Regular expression: \"" + arg + "\""); + Pattern p = Pattern.compile(arg); + Matcher m = p.matcher(args[0]); + while(m.find()) { + System.out.println( + "Match \"" + m.group() + "\" at positions " + + m.start() + "-" + (m.end() - 1)); + } + } + } +} +/* Output: +Input: "abcabcabcdefabc" +Regular expression: "abcabcabcdefabc" +Match "abcabcabcdefabc" at positions 0-14 +Regular expression: "abc+" +Match "abc" at positions 0-2 +Match "abc" at positions 3-5 +Match "abc" at positions 6-8 +Match "abc" at positions 12-14 +Regular expression: "(abc)+" +Match "abcabcabc" at positions 0-8 +Match "abc" at positions 12-14 +*/ diff --git a/code/strings/TheReplacements.java b/code/strings/TheReplacements.java new file mode 100644 index 00000000..2319552f --- /dev/null +++ b/code/strings/TheReplacements.java @@ -0,0 +1,57 @@ +// strings/TheReplacements.java +// (c)2020 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. +import java.util.regex.*; +import java.nio.file.*; +import java.util.stream.*; + +/*! Here's a block of text to use as input to + the regular expression matcher. Note that we + first extract the block of text by looking for + the special delimiters, then process the + extracted block. !*/ + +public class TheReplacements { + public static void + main(String[] args) throws Exception { + String s = Files.lines( + Paths.get("TheReplacements.java")) + .collect(Collectors.joining("\n")); + // Match specially commented block of text above: + Matcher mInput = Pattern.compile( + "/\\*!(.*)!\\*/", Pattern.DOTALL).matcher(s); + if(mInput.find()) + s = mInput.group(1); // Captured by parentheses + // Replace two or more spaces with a single space: + s = s.replaceAll(" {2,}", " "); + // Replace 1+ spaces at the beginning of each + // line with no spaces. Must enable MULTILINE mode: + s = s.replaceAll("(?m)^ +", ""); + System.out.println(s); + s = s.replaceFirst("[aeiou]", "(VOWEL1)"); + StringBuffer sbuf = new StringBuffer(); + Pattern p = Pattern.compile("[aeiou]"); + Matcher m = p.matcher(s); + // Process the find information as you + // perform the replacements: + while(m.find()) + m.appendReplacement( + sbuf, m.group().toUpperCase()); + // Put in the remainder of the text: + m.appendTail(sbuf); + System.out.println(sbuf); + } +} +/* Output: +Here's a block of text to use as input to +the regular expression matcher. Note that we +first extract the block of text by looking for +the special delimiters, then process the +extracted block. +H(VOWEL1)rE's A blOck Of tExt tO UsE As InpUt tO +thE rEgUlAr ExprEssIOn mAtchEr. NOtE thAt wE +fIrst ExtrAct thE blOck Of tExt by lOOkIng fOr +thE spEcIAl dElImItErs, thEn prOcEss thE +ExtrActEd blOck. +*/ diff --git a/code/strings/ThreatAnalyzer.java b/code/strings/ThreatAnalyzer.java new file mode 100644 index 00000000..fc145c86 --- /dev/null +++ b/code/strings/ThreatAnalyzer.java @@ -0,0 +1,36 @@ +// strings/ThreatAnalyzer.java +// (c)2020 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. +import java.util.regex.*; +import java.util.*; + +public class ThreatAnalyzer { + static String threatData = + "58.27.82.161@08/10/2015\n" + + "204.45.234.40@08/11/2015\n" + + "58.27.82.161@08/11/2015\n" + + "58.27.82.161@08/12/2015\n" + + "58.27.82.161@08/12/2015\n" + + "[Next log section with different data format]"; + public static void main(String[] args) { + Scanner scanner = new Scanner(threatData); + String pattern = "(\\d+[.]\\d+[.]\\d+[.]\\d+)@" + + "(\\d{2}/\\d{2}/\\d{4})"; + while(scanner.hasNext(pattern)) { + scanner.next(pattern); + MatchResult match = scanner.match(); + String ip = match.group(1); + String date = match.group(2); + System.out.format( + "Threat on %s from %s%n", date,ip); + } + } +} +/* Output: +Threat on 08/10/2015 from 58.27.82.161 +Threat on 08/11/2015 from 204.45.234.40 +Threat on 08/11/2015 from 58.27.82.161 +Threat on 08/12/2015 from 58.27.82.161 +Threat on 08/12/2015 from 58.27.82.161 +*/ diff --git a/code/strings/Turtle.java b/code/strings/Turtle.java new file mode 100644 index 00000000..68977bfc --- /dev/null +++ b/code/strings/Turtle.java @@ -0,0 +1,40 @@ +// strings/Turtle.java +// (c)2020 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. +import java.io.*; +import java.util.*; + +public class Turtle { + private String name; + private Formatter f; + public Turtle(String name, Formatter f) { + this.name = name; + this.f = f; + } + public void move(int x, int y) { + f.format("%s The Turtle is at (%d,%d)%n", + name, x, y); + } + public static void main(String[] args) { + PrintStream outAlias = System.out; + Turtle tommy = new Turtle("Tommy", + new Formatter(System.out)); + Turtle terry = new Turtle("Terry", + new Formatter(outAlias)); + tommy.move(0,0); + terry.move(4,8); + tommy.move(3,4); + terry.move(2,5); + tommy.move(3,3); + terry.move(3,3); + } +} +/* Output: +Tommy The Turtle is at (0,0) +Terry The Turtle is at (4,8) +Tommy The Turtle is at (3,4) +Terry The Turtle is at (2,5) +Tommy The Turtle is at (3,3) +Terry The Turtle is at (3,3) +*/ diff --git a/code/strings/UsingStringBuilder.java b/code/strings/UsingStringBuilder.java new file mode 100644 index 00000000..0ff32410 --- /dev/null +++ b/code/strings/UsingStringBuilder.java @@ -0,0 +1,37 @@ +// strings/UsingStringBuilder.java +// (c)2020 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. +import java.util.*; +import java.util.stream.*; + +public class UsingStringBuilder { + public static String string1() { + Random rand = new Random(47); + StringBuilder result = new StringBuilder("["); + for(int i = 0; i < 25; i++) { + result.append(rand.nextInt(100)); + result.append(", "); + } + result.delete(result.length()-2, result.length()); + result.append("]"); + return result.toString(); + } + public static String string2() { + String result = new Random(47) + .ints(25, 0, 100) + .mapToObj(Integer::toString) + .collect(Collectors.joining(", ")); + return "[" + result + "]"; + } + public static void main(String[] args) { + System.out.println(string1()); + System.out.println(string2()); + } +} +/* Output: +[58, 55, 93, 61, 61, 29, 68, 0, 22, 7, 88, 28, 51, 89, +9, 78, 98, 61, 20, 58, 16, 40, 11, 22, 4] +[58, 55, 93, 61, 61, 29, 68, 0, 22, 7, 88, 28, 51, 89, +9, 78, 98, 61, 20, 58, 16, 40, 11, 22, 4] +*/ diff --git a/code/strings/WhitherStringBuilder.java b/code/strings/WhitherStringBuilder.java new file mode 100644 index 00000000..0c46cae3 --- /dev/null +++ b/code/strings/WhitherStringBuilder.java @@ -0,0 +1,21 @@ +// strings/WhitherStringBuilder.java +// (c)2020 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. + +public class WhitherStringBuilder { + public String implicit(String[] fields) { + String result = ""; + for(String field : fields) { + result += field; + } + return result; + } + public String explicit(String[] fields) { + StringBuilder result = new StringBuilder(); + for(String field : fields) { + result.append(field); + } + return result.toString(); + } +} diff --git a/code/typeinfo/AnonymousImplementation.java b/code/typeinfo/AnonymousImplementation.java new file mode 100644 index 00000000..34fa7832 --- /dev/null +++ b/code/typeinfo/AnonymousImplementation.java @@ -0,0 +1,50 @@ +// typeinfo/AnonymousImplementation.java +// (c)2020 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. +// Anonymous inner classes can't hide from reflection +import typeinfo.interfacea.*; + +class AnonymousA { + public static A makeA() { + return new A() { + public void f() { + System.out.println("public C.f()"); + } + public void g() { + System.out.println("public C.g()"); + } + void u() { + System.out.println("package C.u()"); + } + protected void v() { + System.out.println("protected C.v()"); + } + private void w() { + System.out.println("private C.w()"); + } + }; + } +} + +public class AnonymousImplementation { + public static void + main(String[] args) throws Exception { + A a = AnonymousA.makeA(); + a.f(); + System.out.println(a.getClass().getName()); + // Reflection still gets into the anonymous class: + HiddenImplementation.callHiddenMethod(a, "g"); + HiddenImplementation.callHiddenMethod(a, "u"); + HiddenImplementation.callHiddenMethod(a, "v"); + HiddenImplementation.callHiddenMethod(a, "w"); + } +} +/* Output: +public C.f() +AnonymousA$1 +public C.g() +package C.u() +protected C.v() +private C.w() +*/ diff --git a/code/typeinfo/BoundedClassReferences.java b/code/typeinfo/BoundedClassReferences.java new file mode 100644 index 00000000..ed0945e6 --- /dev/null +++ b/code/typeinfo/BoundedClassReferences.java @@ -0,0 +1,13 @@ +// typeinfo/BoundedClassReferences.java +// (c)2020 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. + +public class BoundedClassReferences { + public static void main(String[] args) { + Class bounded = int.class; + bounded = double.class; + bounded = Number.class; + // Or anything else derived from Number. + } +} diff --git a/code/typeinfo/ClassCasts.java b/code/typeinfo/ClassCasts.java new file mode 100644 index 00000000..fd0e17cf --- /dev/null +++ b/code/typeinfo/ClassCasts.java @@ -0,0 +1,16 @@ +// typeinfo/ClassCasts.java +// (c)2020 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. + +class Building {} +class House extends Building {} + +public class ClassCasts { + public static void main(String[] args) { + Building b = new House(); + Class houseType = House.class; + House h = houseType.cast(b); + h = (House)b; // ... or just do this. + } +} diff --git a/code/typeinfo/ClassInitialization.java b/code/typeinfo/ClassInitialization.java new file mode 100644 index 00000000..ba1d50e8 --- /dev/null +++ b/code/typeinfo/ClassInitialization.java @@ -0,0 +1,57 @@ +// typeinfo/ClassInitialization.java +// (c)2020 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. +import java.util.*; + +class Initable { + static final int STATIC_FINAL = 47; + static final int STATIC_FINAL2 = + ClassInitialization.rand.nextInt(1000); + static { + System.out.println("Initializing Initable"); + } +} + +class Initable2 { + static int staticNonFinal = 147; + static { + System.out.println("Initializing Initable2"); + } +} + +class Initable3 { + static int staticNonFinal = 74; + static { + System.out.println("Initializing Initable3"); + } +} + +public class ClassInitialization { + public static Random rand = new Random(47); + public static void + main(String[] args) throws Exception { + Class initable = Initable.class; + System.out.println("After creating Initable ref"); + // Does not trigger initialization: + System.out.println(Initable.STATIC_FINAL); + // Does trigger initialization: + System.out.println(Initable.STATIC_FINAL2); + // Does trigger initialization: + System.out.println(Initable2.staticNonFinal); + Class initable3 = Class.forName("Initable3"); + System.out.println("After creating Initable3 ref"); + System.out.println(Initable3.staticNonFinal); + } +} +/* Output: +After creating Initable ref +47 +Initializing Initable +258 +Initializing Initable2 +147 +Initializing Initable3 +After creating Initable3 ref +74 +*/ diff --git a/code/typeinfo/DynamicSupplier.java b/code/typeinfo/DynamicSupplier.java new file mode 100644 index 00000000..271af639 --- /dev/null +++ b/code/typeinfo/DynamicSupplier.java @@ -0,0 +1,42 @@ +// typeinfo/DynamicSupplier.java +// (c)2020 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. +import java.util.function.*; +import java.util.stream.*; + +class CountedInteger { + private static long counter; + private final long id = counter++; + @Override + public String toString() { return Long.toString(id); } +} + +public class DynamicSupplier implements Supplier { + private Class type; + public DynamicSupplier(Class type) { + this.type = type; + } + @SuppressWarnings("deprecation") + public T get() { + try { + return type.newInstance(); + } catch(Exception e) { + throw new RuntimeException(e); + } + } + public static void main(String[] args) { + Stream.generate( + new DynamicSupplier<>(CountedInteger.class)) + .skip(10) + .limit(5) + .forEach(System.out::println); + } +} +/* Output: +10 +11 +12 +13 +14 +*/ diff --git a/code/typeinfo/FamilyVsExactType.java b/code/typeinfo/FamilyVsExactType.java new file mode 100644 index 00000000..5981bbe6 --- /dev/null +++ b/code/typeinfo/FamilyVsExactType.java @@ -0,0 +1,62 @@ +// typeinfo/FamilyVsExactType.java +// (c)2020 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. +// The difference between instanceof and class +// {java typeinfo.FamilyVsExactType} +package typeinfo; + +class Base {} +class Derived extends Base {} + +public class FamilyVsExactType { + static void test(Object x) { + System.out.println( + "Testing x of type " + x.getClass()); + System.out.println( + "x instanceof Base " + (x instanceof Base)); + System.out.println( + "x instanceof Derived " + (x instanceof Derived)); + System.out.println( + "Base.isInstance(x) " + Base.class.isInstance(x)); + System.out.println( + "Derived.isInstance(x) " + + Derived.class.isInstance(x)); + System.out.println( + "x.getClass() == Base.class " + + (x.getClass() == Base.class)); + System.out.println( + "x.getClass() == Derived.class " + + (x.getClass() == Derived.class)); + System.out.println( + "x.getClass().equals(Base.class)) "+ + (x.getClass().equals(Base.class))); + System.out.println( + "x.getClass().equals(Derived.class)) " + + (x.getClass().equals(Derived.class))); + } + public static void main(String[] args) { + test(new Base()); + test(new Derived()); + } +} +/* Output: +Testing x of type class typeinfo.Base +x instanceof Base true +x instanceof Derived false +Base.isInstance(x) true +Derived.isInstance(x) false +x.getClass() == Base.class true +x.getClass() == Derived.class false +x.getClass().equals(Base.class)) true +x.getClass().equals(Derived.class)) false +Testing x of type class typeinfo.Derived +x instanceof Base true +x instanceof Derived true +Base.isInstance(x) true +Derived.isInstance(x) true +x.getClass() == Base.class false +x.getClass() == Derived.class true +x.getClass().equals(Base.class)) false +x.getClass().equals(Derived.class)) true +*/ diff --git a/code/typeinfo/GenericClassReferences.java b/code/typeinfo/GenericClassReferences.java new file mode 100644 index 00000000..81ba7f7d --- /dev/null +++ b/code/typeinfo/GenericClassReferences.java @@ -0,0 +1,14 @@ +// typeinfo/GenericClassReferences.java +// (c)2020 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. + +public class GenericClassReferences { + public static void main(String[] args) { + Class intClass = int.class; + Class genericIntClass = int.class; + genericIntClass = Integer.class; // Same thing + intClass = double.class; + // genericIntClass = double.class; // Illegal + } +} diff --git a/code/typeinfo/HiddenImplementation.java b/code/typeinfo/HiddenImplementation.java new file mode 100644 index 00000000..7b41f657 --- /dev/null +++ b/code/typeinfo/HiddenImplementation.java @@ -0,0 +1,44 @@ +// typeinfo/HiddenImplementation.java +// (c)2020 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. +// Sneaking around package hiding +import typeinfo.interfacea.*; +import typeinfo.packageaccess.*; +import java.lang.reflect.*; + +public class HiddenImplementation { + public static void + main(String[] args) throws Exception { + A a = HiddenC.makeA(); + a.f(); + System.out.println(a.getClass().getName()); + // Compile error: cannot find symbol 'C': + /* if(a instanceof C) { + C c = (C)a; + c.g(); + } */ + // Oops! Reflection still allows us to call g(): + callHiddenMethod(a, "g"); + // And even less accessible methods! + callHiddenMethod(a, "u"); + callHiddenMethod(a, "v"); + callHiddenMethod(a, "w"); + } + static void + callHiddenMethod(Object a, String methodName) + throws Exception { + Method g = + a.getClass().getDeclaredMethod(methodName); + g.setAccessible(true); + g.invoke(a); + } +} +/* Output: +public C.f() +typeinfo.packageaccess.C +public C.g() +package C.u() +protected C.v() +private C.w() +*/ diff --git a/code/typeinfo/InnerImplementation.java b/code/typeinfo/InnerImplementation.java new file mode 100644 index 00000000..2b6541fa --- /dev/null +++ b/code/typeinfo/InnerImplementation.java @@ -0,0 +1,49 @@ +// typeinfo/InnerImplementation.java +// (c)2020 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. +// Private inner classes can't hide from reflection +import typeinfo.interfacea.*; + +class InnerA { + private static class C implements A { + public void f() { + System.out.println("public C.f()"); + } + public void g() { + System.out.println("public C.g()"); + } + void u() { + System.out.println("package C.u()"); + } + protected void v() { + System.out.println("protected C.v()"); + } + private void w() { + System.out.println("private C.w()"); + } + } + public static A makeA() { return new C(); } +} + +public class InnerImplementation { + public static void + main(String[] args) throws Exception { + A a = InnerA.makeA(); + a.f(); + System.out.println(a.getClass().getName()); + // Reflection still gets into the private class: + HiddenImplementation.callHiddenMethod(a, "g"); + HiddenImplementation.callHiddenMethod(a, "u"); + HiddenImplementation.callHiddenMethod(a, "v"); + HiddenImplementation.callHiddenMethod(a, "w"); + } +} +/* Output: +public C.f() +InnerA$C +public C.g() +package C.u() +protected C.v() +private C.w() +*/ diff --git a/code/typeinfo/InterfaceViolation.java b/code/typeinfo/InterfaceViolation.java new file mode 100644 index 00000000..06b13f65 --- /dev/null +++ b/code/typeinfo/InterfaceViolation.java @@ -0,0 +1,27 @@ +// typeinfo/InterfaceViolation.java +// (c)2020 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. +// Sneaking around an interface +import typeinfo.interfacea.*; + +class B implements A { + public void f() {} + public void g() {} +} + +public class InterfaceViolation { + public static void main(String[] args) { + A a = new B(); + a.f(); + // a.g(); // Compile error + System.out.println(a.getClass().getName()); + if(a instanceof B) { + B b = (B)a; + b.g(); + } + } +} +/* Output: +B +*/ diff --git a/code/typeinfo/ModifyingPrivateFields.java b/code/typeinfo/ModifyingPrivateFields.java new file mode 100644 index 00000000..fa1a175d --- /dev/null +++ b/code/typeinfo/ModifyingPrivateFields.java @@ -0,0 +1,49 @@ +// typeinfo/ModifyingPrivateFields.java +// (c)2020 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. +import java.lang.reflect.*; + +class WithPrivateFinalField { + private int i = 1; + private final String s = "I'm totally safe"; + private String s2 = "Am I safe?"; + @Override + public String toString() { + return "i = " + i + ", " + s + ", " + s2; + } +} + +public class ModifyingPrivateFields { + public static void + main(String[] args) throws Exception { + WithPrivateFinalField pf = + new WithPrivateFinalField(); + System.out.println(pf); + Field f = pf.getClass().getDeclaredField("i"); + f.setAccessible(true); + System.out.println( + "f.getInt(pf): " + f.getInt(pf)); + f.setInt(pf, 47); + System.out.println(pf); + f = pf.getClass().getDeclaredField("s"); + f.setAccessible(true); + System.out.println("f.get(pf): " + f.get(pf)); + f.set(pf, "No, you're not!"); + System.out.println(pf); + f = pf.getClass().getDeclaredField("s2"); + f.setAccessible(true); + System.out.println("f.get(pf): " + f.get(pf)); + f.set(pf, "No, you're not!"); + System.out.println(pf); + } +} +/* Output: +i = 1, I'm totally safe, Am I safe? +f.getInt(pf): 1 +i = 47, I'm totally safe, Am I safe? +f.get(pf): I'm totally safe +i = 47, I'm totally safe, Am I safe? +f.get(pf): Am I safe? +i = 47, I'm totally safe, No, you're not! +*/ diff --git a/code/typeinfo/NullRobot.java b/code/typeinfo/NullRobot.java new file mode 100644 index 00000000..d174ca94 --- /dev/null +++ b/code/typeinfo/NullRobot.java @@ -0,0 +1,63 @@ +// typeinfo/NullRobot.java +// (c)2020 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. +// Using a dynamic proxy to create an Optional +import java.lang.reflect.*; +import java.util.*; +import java.util.stream.*; +import onjava.*; + +class NullRobotProxyHandler +implements InvocationHandler { + private String nullName; + private Robot proxied = new NRobot(); + NullRobotProxyHandler(Class type) { + nullName = type.getSimpleName() + " NullRobot"; + } + private class NRobot implements Null, Robot { + @Override + public String name() { return nullName; } + @Override + public String model() { return nullName; } + @Override + public List operations() { + return Collections.emptyList(); + } + } + @Override + public Object + invoke(Object proxy, Method method, Object[] args) + throws Throwable { + return method.invoke(proxied, args); + } +} + +public class NullRobot { + public static Robot + newNullRobot(Class type) { + return (Robot)Proxy.newProxyInstance( + NullRobot.class.getClassLoader(), + new Class[]{ Null.class, Robot.class }, + new NullRobotProxyHandler(type)); + } + public static void main(String[] args) { + Stream.of( + new SnowRemovalRobot("SnowBee"), + newNullRobot(SnowRemovalRobot.class) + ).forEach(Robot::test); + } +} +/* Output: +Robot name: SnowBee +Robot model: SnowBot Series 11 +SnowBee can shovel snow +SnowBee shoveling snow +SnowBee can chip ice +SnowBee chipping ice +SnowBee can clear the roof +SnowBee clearing roof +[Null Robot] +Robot name: SnowRemovalRobot NullRobot +Robot model: SnowRemovalRobot NullRobot +*/ diff --git a/code/typeinfo/Operation.java b/code/typeinfo/Operation.java new file mode 100644 index 00000000..dc872230 --- /dev/null +++ b/code/typeinfo/Operation.java @@ -0,0 +1,15 @@ +// typeinfo/Operation.java +// (c)2020 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. +import java.util.function.*; + +public class Operation { + public final Supplier description; + public final Runnable command; + public + Operation(Supplier descr, Runnable cmd) { + description = descr; + command = cmd; + } +} diff --git a/code/typeinfo/Person.java b/code/typeinfo/Person.java new file mode 100644 index 00000000..7a9807c0 --- /dev/null +++ b/code/typeinfo/Person.java @@ -0,0 +1,49 @@ +// typeinfo/Person.java +// (c)2020 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. +// Using Optional with regular classes +import onjava.*; +import java.util.*; + +class Person { + public final Optional first; + public final Optional last; + public final Optional address; + // etc. + public final boolean empty; + Person(String first, String last, String address) { + this.first = Optional.ofNullable(first); + this.last = Optional.ofNullable(last); + this.address = Optional.ofNullable(address); + empty = !this.first.isPresent() + && !this.last.isPresent() + && !this.address.isPresent(); + } + Person(String first, String last) { + this(first, last, null); + } + Person(String last) { this(null, last, null); } + Person() { this(null, null, null); } + @Override + public String toString() { + if(empty) + return ""; + return (first.orElse("") + + " " + last.orElse("") + + " " + address.orElse("")).trim(); + } + public static void main(String[] args) { + System.out.println(new Person()); + System.out.println(new Person("Smith")); + System.out.println(new Person("Bob", "Smith")); + System.out.println(new Person("Bob", "Smith", + "11 Degree Lane, Frostbite Falls, MN")); + } +} +/* Output: + +Smith +Bob Smith +Bob Smith 11 Degree Lane, Frostbite Falls, MN +*/ diff --git a/code/typeinfo/PetCount.java b/code/typeinfo/PetCount.java new file mode 100644 index 00000000..53438d29 --- /dev/null +++ b/code/typeinfo/PetCount.java @@ -0,0 +1,65 @@ +// typeinfo/PetCount.java +// (c)2020 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. +// Using instanceof +import typeinfo.pets.*; +import java.util.*; + +public class PetCount { + static class Counter extends HashMap { + public void count(String type) { + Integer quantity = get(type); + if(quantity == null) + put(type, 1); + else + put(type, quantity + 1); + } + } + public static void + countPets(PetCreator creator) { + Counter counter = new Counter(); + for(Pet pet : Pets.array(20)) { + // List each individual pet: + System.out.print( + pet.getClass().getSimpleName() + " "); + if(pet instanceof Pet) + counter.count("Pet"); + if(pet instanceof Dog) + counter.count("Dog"); + if(pet instanceof Mutt) + counter.count("Mutt"); + if(pet instanceof Pug) + counter.count("Pug"); + if(pet instanceof Cat) + counter.count("Cat"); + if(pet instanceof EgyptianMau) + counter.count("EgyptianMau"); + if(pet instanceof Manx) + counter.count("Manx"); + if(pet instanceof Cymric) + counter.count("Cymric"); + if(pet instanceof Rodent) + counter.count("Rodent"); + if(pet instanceof Rat) + counter.count("Rat"); + if(pet instanceof Mouse) + counter.count("Mouse"); + if(pet instanceof Hamster) + counter.count("Hamster"); + } + // Show the counts: + System.out.println(); + System.out.println(counter); + } + public static void main(String[] args) { + countPets(new ForNameCreator()); + } +} +/* Output: +Rat Manx Cymric Mutt Pug Cymric Pug Manx Cymric Rat +EgyptianMau Hamster EgyptianMau Mutt Mutt Cymric Mouse +Pug Mouse Cymric +{EgyptianMau=2, Pug=3, Rat=2, Cymric=5, Mouse=2, Cat=9, +Manx=7, Rodent=5, Mutt=3, Dog=6, Pet=20, Hamster=1} +*/ diff --git a/code/typeinfo/PetCount2.java b/code/typeinfo/PetCount2.java new file mode 100644 index 00000000..c65e0138 --- /dev/null +++ b/code/typeinfo/PetCount2.java @@ -0,0 +1,18 @@ +// typeinfo/PetCount2.java +// (c)2020 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. +import typeinfo.pets.*; + +public class PetCount2 { + public static void main(String[] args) { + PetCount.countPets(Pets.CREATOR); + } +} +/* Output: +Rat Manx Cymric Mutt Pug Cymric Pug Manx Cymric Rat +EgyptianMau Hamster EgyptianMau Mutt Mutt Cymric Mouse +Pug Mouse Cymric +{EgyptianMau=2, Pug=3, Rat=2, Cymric=5, Mouse=2, Cat=9, +Manx=7, Rodent=5, Mutt=3, Dog=6, Pet=20, Hamster=1} +*/ diff --git a/code/typeinfo/PetCount3.java b/code/typeinfo/PetCount3.java new file mode 100644 index 00000000..5b08fb66 --- /dev/null +++ b/code/typeinfo/PetCount3.java @@ -0,0 +1,53 @@ +// typeinfo/PetCount3.java +// (c)2020 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. +// Using isInstance() +import java.util.*; +import java.util.stream.*; +import onjava.*; +import typeinfo.pets.*; + +public class PetCount3 { + static class Counter extends + LinkedHashMap, Integer> { + Counter() { + super(LiteralPetCreator.ALL_TYPES.stream() + .map(lpc -> Pair.make(lpc, 0)) + .collect( + Collectors.toMap(Pair::key, Pair::value))); + } + public void count(Pet pet) { + // Class.isInstance() eliminates instanceofs: + entrySet().stream() + .filter(pair -> pair.getKey().isInstance(pet)) + .forEach(pair -> + put(pair.getKey(), pair.getValue() + 1)); + } + @Override + public String toString() { + String result = entrySet().stream() + .map(pair -> String.format("%s=%s", + pair.getKey().getSimpleName(), + pair.getValue())) + .collect(Collectors.joining(", ")); + return "{" + result + "}"; + } + } + public static void main(String[] args) { + Counter petCount = new Counter(); + Pets.stream() + .limit(20) + .peek(petCount::count) + .forEach(p -> System.out.print( + p.getClass().getSimpleName() + " ")); + System.out.println("\n" + petCount); + } +} +/* Output: +Rat Manx Cymric Mutt Pug Cymric Pug Manx Cymric Rat +EgyptianMau Hamster EgyptianMau Mutt Mutt Cymric Mouse +Pug Mouse Cymric +{Rat=2, Pug=3, Mutt=3, Mouse=2, Cat=9, Dog=6, Cymric=5, +EgyptianMau=2, Rodent=5, Hamster=1, Manx=7, Pet=20} +*/ diff --git a/code/typeinfo/PetCount4.java b/code/typeinfo/PetCount4.java new file mode 100644 index 00000000..1ea4873a --- /dev/null +++ b/code/typeinfo/PetCount4.java @@ -0,0 +1,26 @@ +// typeinfo/PetCount4.java +// (c)2020 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. +import typeinfo.pets.*; +import onjava.*; + +public class PetCount4 { + public static void main(String[] args) { + TypeCounter counter = new TypeCounter(Pet.class); + Pets.stream() + .limit(20) + .peek(counter::count) + .forEach(p -> System.out.print( + p.getClass().getSimpleName() + " ")); + System.out.println("\n" + counter); + } +} +/* Output: +Rat Manx Cymric Mutt Pug Cymric Pug Manx Cymric Rat +EgyptianMau Hamster EgyptianMau Mutt Mutt Cymric Mouse +Pug Mouse Cymric +{Dog=6, Manx=7, Cat=9, Rodent=5, Hamster=1, Rat=2, +Pug=3, Mutt=3, Cymric=5, EgyptianMau=2, Pet=20, +Mouse=2} +*/ diff --git a/code/typeinfo/Position.java b/code/typeinfo/Position.java new file mode 100644 index 00000000..ca81643b --- /dev/null +++ b/code/typeinfo/Position.java @@ -0,0 +1,51 @@ +// typeinfo/Position.java +// (c)2020 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. +import java.util.*; + +class EmptyTitleException extends RuntimeException {} + +class Position { + private String title; + private Person person; + Position(String jobTitle, Person employee) { + setTitle(jobTitle); + setPerson(employee); + } + Position(String jobTitle) { + this(jobTitle, null); + } + public String getTitle() { return title; } + public void setTitle(String newTitle) { + // Throws EmptyTitleException if newTitle is null: + title = Optional.ofNullable(newTitle) + .orElseThrow(EmptyTitleException::new); + } + public Person getPerson() { return person; } + public void setPerson(Person newPerson) { + // Uses empty Person if newPerson is null: + person = Optional.ofNullable(newPerson) + .orElse(new Person()); + } + @Override + public String toString() { + return "Position: " + title + + ", Employee: " + person; + } + public static void main(String[] args) { + System.out.println(new Position("CEO")); + System.out.println(new Position("Programmer", + new Person("Arthur", "Fonzarelli"))); + try { + new Position(null); + } catch(Exception e) { + System.out.println("caught " + e); + } + } +} +/* Output: +Position: CEO, Employee: +Position: Programmer, Employee: Arthur Fonzarelli +caught EmptyTitleException +*/ diff --git a/code/typeinfo/RegisteredFactories.java b/code/typeinfo/RegisteredFactories.java new file mode 100644 index 00000000..7708cc4e --- /dev/null +++ b/code/typeinfo/RegisteredFactories.java @@ -0,0 +1,95 @@ +// typeinfo/RegisteredFactories.java +// (c)2020 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. +// Registering Factories in the base class +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +class Part implements Supplier { + @Override + public String toString() { + return getClass().getSimpleName(); + } + static List> prototypes = + Arrays.asList( + new FuelFilter(), + new AirFilter(), + new CabinAirFilter(), + new OilFilter(), + new FanBelt(), + new PowerSteeringBelt(), + new GeneratorBelt() + ); + private static Random rand = new Random(47); + public Part get() { + int n = rand.nextInt(prototypes.size()); + return prototypes.get(n).get(); + } +} + +class Filter extends Part {} + +class FuelFilter extends Filter { + @Override + public FuelFilter get() { return new FuelFilter(); } +} + +class AirFilter extends Filter { + @Override + public AirFilter get() { return new AirFilter(); } +} + +class CabinAirFilter extends Filter { + @Override + public CabinAirFilter get() { + return new CabinAirFilter(); + } +} + +class OilFilter extends Filter { + @Override + public OilFilter get() { return new OilFilter(); } +} + +class Belt extends Part {} + +class FanBelt extends Belt { + @Override + public FanBelt get() { return new FanBelt(); } +} + +class GeneratorBelt extends Belt { + @Override + public GeneratorBelt get() { + return new GeneratorBelt(); + } +} + +class PowerSteeringBelt extends Belt { + @Override + public PowerSteeringBelt get() { + return new PowerSteeringBelt(); + } +} + +public class RegisteredFactories { + public static void main(String[] args) { + Stream.generate(new Part()) + .limit(10) + .forEach(System.out::println); + } +} +/* Output: +GeneratorBelt +CabinAirFilter +GeneratorBelt +AirFilter +PowerSteeringBelt +CabinAirFilter +FuelFilter +PowerSteeringBelt +PowerSteeringBelt +FuelFilter +*/ diff --git a/code/typeinfo/Robot.java b/code/typeinfo/Robot.java new file mode 100644 index 00000000..803ee9fe --- /dev/null +++ b/code/typeinfo/Robot.java @@ -0,0 +1,22 @@ +// typeinfo/Robot.java +// (c)2020 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. +import onjava.*; +import java.util.*; + +public interface Robot { + String name(); + String model(); + List operations(); + static void test(Robot r) { + if(r instanceof Null) + System.out.println("[Null Robot]"); + System.out.println("Robot name: " + r.name()); + System.out.println("Robot model: " + r.model()); + for(Operation operation : r.operations()) { + System.out.println(operation.description.get()); + operation.command.run(); + } + } +} diff --git a/code/typeinfo/SelectingMethods.java b/code/typeinfo/SelectingMethods.java new file mode 100644 index 00000000..d87e928b --- /dev/null +++ b/code/typeinfo/SelectingMethods.java @@ -0,0 +1,69 @@ +// typeinfo/SelectingMethods.java +// (c)2020 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. +// Looking for particular methods in a dynamic proxy +import java.lang.reflect.*; + +class MethodSelector implements InvocationHandler { + private Object proxied; + MethodSelector(Object proxied) { + this.proxied = proxied; + } + @Override + public Object + invoke(Object proxy, Method method, Object[] args) + throws Throwable { + if(method.getName().equals("interesting")) + System.out.println( + "Proxy detected the interesting method"); + return method.invoke(proxied, args); + } +} + +interface SomeMethods { + void boring1(); + void boring2(); + void interesting(String arg); + void boring3(); +} + +class Implementation implements SomeMethods { + @Override + public void boring1() { + System.out.println("boring1"); + } + @Override + public void boring2() { + System.out.println("boring2"); + } + @Override + public void interesting(String arg) { + System.out.println("interesting " + arg); + } + @Override + public void boring3() { + System.out.println("boring3"); + } +} + +class SelectingMethods { + public static void main(String[] args) { + SomeMethods proxy = + (SomeMethods)Proxy.newProxyInstance( + SomeMethods.class.getClassLoader(), + new Class[]{ SomeMethods.class }, + new MethodSelector(new Implementation())); + proxy.boring1(); + proxy.boring2(); + proxy.interesting("bonobo"); + proxy.boring3(); + } +} +/* Output: +boring1 +boring2 +Proxy detected the interesting method +interesting bonobo +boring3 +*/ diff --git a/code/typeinfo/Shapes.java b/code/typeinfo/Shapes.java new file mode 100644 index 00000000..34a2bc56 --- /dev/null +++ b/code/typeinfo/Shapes.java @@ -0,0 +1,39 @@ +// typeinfo/Shapes.java +// (c)2020 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. +import java.util.stream.*; + +abstract class Shape { + void draw() { System.out.println(this + ".draw()"); } + @Override + public abstract String toString(); +} + +class Circle extends Shape { + @Override + public String toString() { return "Circle"; } +} + +class Square extends Shape { + @Override + public String toString() { return "Square"; } +} + +class Triangle extends Shape { + @Override + public String toString() { return "Triangle"; } +} + +public class Shapes { + public static void main(String[] args) { + Stream.of( + new Circle(), new Square(), new Triangle()) + .forEach(Shape::draw); + } +} +/* Output: +Circle.draw() +Square.draw() +Triangle.draw() +*/ diff --git a/code/typeinfo/ShowMethods.java b/code/typeinfo/ShowMethods.java new file mode 100644 index 00000000..be1b635b --- /dev/null +++ b/code/typeinfo/ShowMethods.java @@ -0,0 +1,71 @@ +// typeinfo/ShowMethods.java +// (c)2020 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. +// Using reflection to show all the methods of a class, +// even if the methods are defined in the base class +// {java ShowMethods ShowMethods} +import java.lang.reflect.*; +import java.util.regex.*; + +public class ShowMethods { + private static String usage = + "usage:\n" + + "ShowMethods qualified.class.name\n" + + "To show all methods in class or:\n" + + "ShowMethods qualified.class.name word\n" + + "To search for methods involving 'word'"; + private static Pattern p = Pattern.compile("\\w+\\."); + public static void main(String[] args) { + if(args.length < 1) { + System.out.println(usage); + System.exit(0); + } + int lines = 0; + try { + Class c = Class.forName(args[0]); + Method[] methods = c.getMethods(); + Constructor[] ctors = c.getConstructors(); + if(args.length == 1) { + for(Method method : methods) + System.out.println( + p.matcher( + method.toString()).replaceAll("")); + for(Constructor ctor : ctors) + System.out.println( + p.matcher(ctor.toString()).replaceAll("")); + lines = methods.length + ctors.length; + } else { + for(Method method : methods) + if(method.toString().contains(args[1])) { + System.out.println(p.matcher( + method.toString()).replaceAll("")); + lines++; + } + for(Constructor ctor : ctors) + if(ctor.toString().contains(args[1])) { + System.out.println(p.matcher( + ctor.toString()).replaceAll("")); + lines++; + } + } + } catch(ClassNotFoundException e) { + System.out.println("No such class: " + e); + } + } +} +/* Output: +public static void main(String[]) +public final void wait() throws InterruptedException +public final void wait(long,int) throws +InterruptedException +public final native void wait(long) throws +InterruptedException +public boolean equals(Object) +public String toString() +public native int hashCode() +public final native Class getClass() +public final native void notify() +public final native void notifyAll() +public ShowMethods() +*/ diff --git a/code/typeinfo/SimpleDynamicProxy.java b/code/typeinfo/SimpleDynamicProxy.java new file mode 100644 index 00000000..bece57f8 --- /dev/null +++ b/code/typeinfo/SimpleDynamicProxy.java @@ -0,0 +1,53 @@ +// typeinfo/SimpleDynamicProxy.java +// (c)2020 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. +import java.lang.reflect.*; + +class DynamicProxyHandler implements InvocationHandler { + private Object proxied; + DynamicProxyHandler(Object proxied) { + this.proxied = proxied; + } + @Override + public Object + invoke(Object proxy, Method method, Object[] args) + throws Throwable { + System.out.println( + "**** proxy: " + proxy.getClass() + + ", method: " + method + ", args: " + args); + if(args != null) + for(Object arg : args) + System.out.println(" " + arg); + return method.invoke(proxied, args); + } +} + +class SimpleDynamicProxy { + public static void consumer(Interface iface) { + iface.doSomething(); + iface.somethingElse("bonobo"); + } + public static void main(String[] args) { + RealObject real = new RealObject(); + consumer(real); + // Insert a proxy and call again: + Interface proxy = (Interface)Proxy.newProxyInstance( + Interface.class.getClassLoader(), + new Class[]{ Interface.class }, + new DynamicProxyHandler(real)); + consumer(proxy); + } +} +/* Output: +doSomething +somethingElse bonobo +**** proxy: class $Proxy0, method: public abstract void +Interface.doSomething(), args: null +doSomething +**** proxy: class $Proxy0, method: public abstract void +Interface.somethingElse(java.lang.String), args: +[Ljava.lang.Object;@6bc7c054 + bonobo +somethingElse bonobo +*/ diff --git a/code/typeinfo/SimpleProxyDemo.java b/code/typeinfo/SimpleProxyDemo.java new file mode 100644 index 00000000..24c3c2c2 --- /dev/null +++ b/code/typeinfo/SimpleProxyDemo.java @@ -0,0 +1,57 @@ +// typeinfo/SimpleProxyDemo.java +// (c)2020 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. + +interface Interface { + void doSomething(); + void somethingElse(String arg); +} + +class RealObject implements Interface { + @Override + public void doSomething() { + System.out.println("doSomething"); + } + @Override + public void somethingElse(String arg) { + System.out.println("somethingElse " + arg); + } +} + +class SimpleProxy implements Interface { + private Interface proxied; + SimpleProxy(Interface proxied) { + this.proxied = proxied; + } + @Override + public void doSomething() { + System.out.println("SimpleProxy doSomething"); + proxied.doSomething(); + } + @Override + public void somethingElse(String arg) { + System.out.println( + "SimpleProxy somethingElse " + arg); + proxied.somethingElse(arg); + } +} + +class SimpleProxyDemo { + public static void consumer(Interface iface) { + iface.doSomething(); + iface.somethingElse("bonobo"); + } + public static void main(String[] args) { + consumer(new RealObject()); + consumer(new SimpleProxy(new RealObject())); + } +} +/* Output: +doSomething +somethingElse bonobo +SimpleProxy doSomething +doSomething +SimpleProxy somethingElse bonobo +somethingElse bonobo +*/ diff --git a/code/typeinfo/SnowRemovalRobot.java b/code/typeinfo/SnowRemovalRobot.java new file mode 100644 index 00000000..af5b46cd --- /dev/null +++ b/code/typeinfo/SnowRemovalRobot.java @@ -0,0 +1,42 @@ +// typeinfo/SnowRemovalRobot.java +// (c)2020 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. +import java.util.*; + +public class SnowRemovalRobot implements Robot { + private String name; + public SnowRemovalRobot(String name) { + this.name = name; + } + @Override + public String name() { return name; } + @Override + public String model() { return "SnowBot Series 11"; } + private List ops = Arrays.asList( + new Operation( + () -> name + " can shovel snow", + () -> System.out.println( + name + " shoveling snow")), + new Operation( + () -> name + " can chip ice", + () -> System.out.println(name + " chipping ice")), + new Operation( + () -> name + " can clear the roof", + () -> System.out.println( + name + " clearing roof"))); + public List operations() { return ops; } + public static void main(String[] args) { + Robot.test(new SnowRemovalRobot("Slusher")); + } +} +/* Output: +Robot name: Slusher +Robot model: SnowBot Series 11 +Slusher can shovel snow +Slusher shoveling snow +Slusher can chip ice +Slusher chipping ice +Slusher can clear the roof +Slusher clearing roof +*/ diff --git a/code/typeinfo/Staff.java b/code/typeinfo/Staff.java new file mode 100644 index 00000000..569e598f --- /dev/null +++ b/code/typeinfo/Staff.java @@ -0,0 +1,63 @@ +// typeinfo/Staff.java +// (c)2020 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. +import java.util.*; + +public class Staff extends ArrayList { + public void add(String title, Person person) { + add(new Position(title, person)); + } + public void add(String... titles) { + for(String title : titles) + add(new Position(title)); + } + public Staff(String... titles) { add(titles); } + public boolean positionAvailable(String title) { + for(Position position : this) + if(position.getTitle().equals(title) && + position.getPerson().empty) + return true; + return false; + } + public void fillPosition(String title, Person hire) { + for(Position position : this) + if(position.getTitle().equals(title) && + position.getPerson().empty) { + position.setPerson(hire); + return; + } + throw new RuntimeException( + "Position " + title + " not available"); + } + public static void main(String[] args) { + Staff staff = new Staff("President", "CTO", + "Marketing Manager", "Product Manager", + "Project Lead", "Software Engineer", + "Software Engineer", "Software Engineer", + "Software Engineer", "Test Engineer", + "Technical Writer"); + staff.fillPosition("President", + new Person("Me", "Last", "The Top, Lonely At")); + staff.fillPosition("Project Lead", + new Person("Janet", "Planner", "The Burbs")); + if(staff.positionAvailable("Software Engineer")) + staff.fillPosition("Software Engineer", + new Person( + "Bob", "Coder", "Bright Light City")); + System.out.println(staff); + } +} +/* Output: +[Position: President, Employee: Me Last The Top, Lonely +At, Position: CTO, Employee: , Position: +Marketing Manager, Employee: , Position: Product +Manager, Employee: , Position: Project Lead, +Employee: Janet Planner The Burbs, Position: Software +Engineer, Employee: Bob Coder Bright Light City, +Position: Software Engineer, Employee: , +Position: Software Engineer, Employee: , +Position: Software Engineer, Employee: , +Position: Test Engineer, Employee: , Position: +Technical Writer, Employee: ] +*/ diff --git a/code/typeinfo/SweetShop.java b/code/typeinfo/SweetShop.java new file mode 100644 index 00000000..f85b8c3f --- /dev/null +++ b/code/typeinfo/SweetShop.java @@ -0,0 +1,42 @@ +// typeinfo/SweetShop.java +// (c)2020 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. +// Examination of the way the class loader works + +class Cookie { + static { System.out.println("Loading Cookie"); } +} + +class Gum { + static { System.out.println("Loading Gum"); } +} + +class Candy { + static { System.out.println("Loading Candy"); } +} + +public class SweetShop { + public static void main(String[] args) { + System.out.println("inside main"); + new Candy(); + System.out.println("After creating Candy"); + try { + Class.forName("Gum"); + } catch(ClassNotFoundException e) { + System.out.println("Couldn't find Gum"); + } + System.out.println("After Class.forName(\"Gum\")"); + new Cookie(); + System.out.println("After creating Cookie"); + } +} +/* Output: +inside main +Loading Candy +After creating Candy +Loading Gum +After Class.forName("Gum") +Loading Cookie +After creating Cookie +*/ diff --git a/code/typeinfo/WildcardClassReferences.java b/code/typeinfo/WildcardClassReferences.java new file mode 100644 index 00000000..32d75e86 --- /dev/null +++ b/code/typeinfo/WildcardClassReferences.java @@ -0,0 +1,11 @@ +// typeinfo/WildcardClassReferences.java +// (c)2020 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. + +public class WildcardClassReferences { + public static void main(String[] args) { + Class intClass = int.class; + intClass = double.class; + } +} diff --git a/code/typeinfo/interfacea/A.java b/code/typeinfo/interfacea/A.java new file mode 100644 index 00000000..2ebb99d3 --- /dev/null +++ b/code/typeinfo/interfacea/A.java @@ -0,0 +1,9 @@ +// typeinfo/interfacea/A.java +// (c)2020 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 typeinfo.interfacea; + +public interface A { + void f(); +} diff --git a/code/typeinfo/packageaccess/HiddenC.java b/code/typeinfo/packageaccess/HiddenC.java new file mode 100644 index 00000000..9fb8ffde --- /dev/null +++ b/code/typeinfo/packageaccess/HiddenC.java @@ -0,0 +1,29 @@ +// typeinfo/packageaccess/HiddenC.java +// (c)2020 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 typeinfo.packageaccess; +import typeinfo.interfacea.*; + +class C implements A { + @Override + public void f() { + System.out.println("public C.f()"); + } + public void g() { + System.out.println("public C.g()"); + } + void u() { + System.out.println("package C.u()"); + } + protected void v() { + System.out.println("protected C.v()"); + } + private void w() { + System.out.println("private C.w()"); + } +} + +public class HiddenC { + public static A makeA() { return new C(); } +} diff --git a/code/typeinfo/pets/Cat.java b/code/typeinfo/pets/Cat.java new file mode 100644 index 00000000..75781fd7 --- /dev/null +++ b/code/typeinfo/pets/Cat.java @@ -0,0 +1,10 @@ +// typeinfo/pets/Cat.java +// (c)2020 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 typeinfo.pets; + +public class Cat extends Pet { + public Cat(String name) { super(name); } + public Cat() { super(); } +} diff --git a/code/typeinfo/pets/Cymric.java b/code/typeinfo/pets/Cymric.java new file mode 100644 index 00000000..fd86fa95 --- /dev/null +++ b/code/typeinfo/pets/Cymric.java @@ -0,0 +1,10 @@ +// typeinfo/pets/Cymric.java +// (c)2020 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 typeinfo.pets; + +public class Cymric extends Manx { + public Cymric(String name) { super(name); } + public Cymric() { super(); } +} diff --git a/code/typeinfo/pets/Dog.java b/code/typeinfo/pets/Dog.java new file mode 100644 index 00000000..68f43a32 --- /dev/null +++ b/code/typeinfo/pets/Dog.java @@ -0,0 +1,10 @@ +// typeinfo/pets/Dog.java +// (c)2020 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 typeinfo.pets; + +public class Dog extends Pet { + public Dog(String name) { super(name); } + public Dog() { super(); } +} diff --git a/code/typeinfo/pets/EgyptianMau.java b/code/typeinfo/pets/EgyptianMau.java new file mode 100644 index 00000000..adbdfbb1 --- /dev/null +++ b/code/typeinfo/pets/EgyptianMau.java @@ -0,0 +1,10 @@ +// typeinfo/pets/EgyptianMau.java +// (c)2020 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 typeinfo.pets; + +public class EgyptianMau extends Cat { + public EgyptianMau(String name) { super(name); } + public EgyptianMau() { super(); } +} diff --git a/code/typeinfo/pets/ForNameCreator.java b/code/typeinfo/pets/ForNameCreator.java new file mode 100644 index 00000000..29351efa --- /dev/null +++ b/code/typeinfo/pets/ForNameCreator.java @@ -0,0 +1,37 @@ +// typeinfo/pets/ForNameCreator.java +// (c)2020 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 typeinfo.pets; +import java.util.*; + +public class ForNameCreator extends PetCreator { + private static List> types = + new ArrayList<>(); + // Types you want randomly created: + private static String[] typeNames = { + "typeinfo.pets.Mutt", + "typeinfo.pets.Pug", + "typeinfo.pets.EgyptianMau", + "typeinfo.pets.Manx", + "typeinfo.pets.Cymric", + "typeinfo.pets.Rat", + "typeinfo.pets.Mouse", + "typeinfo.pets.Hamster" + }; + @SuppressWarnings("unchecked") + private static void loader() { + try { + for(String name : typeNames) + types.add( + (Class)Class.forName(name)); + } catch(ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + static { loader(); } + @Override + public List> types() { + return types; + } +} diff --git a/code/typeinfo/pets/Hamster.java b/code/typeinfo/pets/Hamster.java new file mode 100644 index 00000000..8408ef62 --- /dev/null +++ b/code/typeinfo/pets/Hamster.java @@ -0,0 +1,10 @@ +// typeinfo/pets/Hamster.java +// (c)2020 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 typeinfo.pets; + +public class Hamster extends Rodent { + public Hamster(String name) { super(name); } + public Hamster() { super(); } +} diff --git a/code/typeinfo/pets/Individual.java b/code/typeinfo/pets/Individual.java new file mode 100644 index 00000000..e3c87dac --- /dev/null +++ b/code/typeinfo/pets/Individual.java @@ -0,0 +1,46 @@ +// typeinfo/pets/Individual.java +// (c)2020 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 typeinfo.pets; +import java.util.*; + +public class +Individual implements Comparable { + private static long counter = 0; + private final long id = counter++; + private String name; + public Individual(String name) { this.name = name; } + // 'name' is optional: + public Individual() {} + @Override + public String toString() { + return getClass().getSimpleName() + + (name == null ? "" : " " + name); + } + public long id() { return id; } + @Override + public boolean equals(Object o) { + return o instanceof Individual && + Objects.equals(id, ((Individual)o).id); + } + @Override + public int hashCode() { + return Objects.hash(name, id); + } + @Override + public int compareTo(Individual arg) { + // Compare by class name first: + String first = getClass().getSimpleName(); + String argFirst = arg.getClass().getSimpleName(); + int firstCompare = first.compareTo(argFirst); + if(firstCompare != 0) + return firstCompare; + if(name != null && arg.name != null) { + int secondCompare = name.compareTo(arg.name); + if(secondCompare != 0) + return secondCompare; + } + return (arg.id < id ? -1 : (arg.id == id ? 0 : 1)); + } +} diff --git a/code/typeinfo/pets/LiteralPetCreator.java b/code/typeinfo/pets/LiteralPetCreator.java new file mode 100644 index 00000000..398baac8 --- /dev/null +++ b/code/typeinfo/pets/LiteralPetCreator.java @@ -0,0 +1,39 @@ +// typeinfo/pets/LiteralPetCreator.java +// (c)2020 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. +// Using class literals +// {java typeinfo.pets.LiteralPetCreator} +package typeinfo.pets; +import java.util.*; + +public class LiteralPetCreator extends PetCreator { + // No try block needed. + @SuppressWarnings("unchecked") + public static + final List> ALL_TYPES = + Collections.unmodifiableList(Arrays.asList( + Pet.class, Dog.class, Cat.class, Rodent.class, + Mutt.class, Pug.class, EgyptianMau.class, + Manx.class, Cymric.class, Rat.class, + Mouse.class, Hamster.class)); + // Types for random creation: + private static final + List> TYPES = + ALL_TYPES.subList(ALL_TYPES.indexOf(Mutt.class), + ALL_TYPES.size()); + @Override + public List> types() { + return TYPES; + } + public static void main(String[] args) { + System.out.println(TYPES); + } +} +/* Output: +[class typeinfo.pets.Mutt, class typeinfo.pets.Pug, +class typeinfo.pets.EgyptianMau, class +typeinfo.pets.Manx, class typeinfo.pets.Cymric, class +typeinfo.pets.Rat, class typeinfo.pets.Mouse, class +typeinfo.pets.Hamster] +*/ diff --git a/code/typeinfo/pets/Manx.java b/code/typeinfo/pets/Manx.java new file mode 100644 index 00000000..6a5534b1 --- /dev/null +++ b/code/typeinfo/pets/Manx.java @@ -0,0 +1,10 @@ +// typeinfo/pets/Manx.java +// (c)2020 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 typeinfo.pets; + +public class Manx extends Cat { + public Manx(String name) { super(name); } + public Manx() { super(); } +} diff --git a/code/typeinfo/pets/Mouse.java b/code/typeinfo/pets/Mouse.java new file mode 100644 index 00000000..bbb97cda --- /dev/null +++ b/code/typeinfo/pets/Mouse.java @@ -0,0 +1,10 @@ +// typeinfo/pets/Mouse.java +// (c)2020 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 typeinfo.pets; + +public class Mouse extends Rodent { + public Mouse(String name) { super(name); } + public Mouse() { super(); } +} diff --git a/code/typeinfo/pets/Mutt.java b/code/typeinfo/pets/Mutt.java new file mode 100644 index 00000000..f51814b9 --- /dev/null +++ b/code/typeinfo/pets/Mutt.java @@ -0,0 +1,10 @@ +// typeinfo/pets/Mutt.java +// (c)2020 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 typeinfo.pets; + +public class Mutt extends Dog { + public Mutt(String name) { super(name); } + public Mutt() { super(); } +} diff --git a/code/typeinfo/pets/Person.java b/code/typeinfo/pets/Person.java new file mode 100644 index 00000000..4dcfff2c --- /dev/null +++ b/code/typeinfo/pets/Person.java @@ -0,0 +1,9 @@ +// typeinfo/pets/Person.java +// (c)2020 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 typeinfo.pets; + +public class Person extends Individual { + public Person(String name) { super(name); } +} diff --git a/code/typeinfo/pets/Pet.java b/code/typeinfo/pets/Pet.java new file mode 100644 index 00000000..dcbfd4ab --- /dev/null +++ b/code/typeinfo/pets/Pet.java @@ -0,0 +1,10 @@ +// typeinfo/pets/Pet.java +// (c)2020 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 typeinfo.pets; + +public class Pet extends Individual { + public Pet(String name) { super(name); } + public Pet() { super(); } +} diff --git a/code/typeinfo/pets/PetCreator.java b/code/typeinfo/pets/PetCreator.java new file mode 100644 index 00000000..76909aa9 --- /dev/null +++ b/code/typeinfo/pets/PetCreator.java @@ -0,0 +1,28 @@ +// typeinfo/pets/PetCreator.java +// (c)2020 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. +// Creates random sequences of Pets +package typeinfo.pets; +import java.util.*; +import java.util.function.*; +import java.lang.reflect.InvocationTargetException; + +public abstract +class PetCreator implements Supplier { + private Random rand = new Random(47); + // The List of the different types of Pet to create: + public abstract List> types(); + public Pet get() { // Create one random Pet + int n = rand.nextInt(types().size()); + try { + return types().get(n) + .getConstructor().newInstance(); + } catch(InstantiationException | + NoSuchMethodException | + InvocationTargetException | + IllegalAccessException e) { + throw new RuntimeException(e); + } + } +} diff --git a/code/typeinfo/pets/Pets.java b/code/typeinfo/pets/Pets.java new file mode 100644 index 00000000..be3037a1 --- /dev/null +++ b/code/typeinfo/pets/Pets.java @@ -0,0 +1,30 @@ +// typeinfo/pets/Pets.java +// (c)2020 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. +// Facade to produce a default PetCreator +package typeinfo.pets; +import java.util.*; +import java.util.stream.*; + +public class Pets { + public static final PetCreator CREATOR = + new LiteralPetCreator(); + public static Pet get() { + return CREATOR.get(); + } + public static Pet[] array(int size) { + Pet[] result = new Pet[size]; + for(int i = 0; i < size; i++) + result[i] = CREATOR.get(); + return result; + } + public static List list(int size) { + List result = new ArrayList<>(); + Collections.addAll(result, array(size)); + return result; + } + public static Stream stream() { + return Stream.generate(CREATOR); + } +} diff --git a/code/typeinfo/pets/Pug.java b/code/typeinfo/pets/Pug.java new file mode 100644 index 00000000..9d8ab467 --- /dev/null +++ b/code/typeinfo/pets/Pug.java @@ -0,0 +1,10 @@ +// typeinfo/pets/Pug.java +// (c)2020 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 typeinfo.pets; + +public class Pug extends Dog { + public Pug(String name) { super(name); } + public Pug() { super(); } +} diff --git a/code/typeinfo/pets/Rat.java b/code/typeinfo/pets/Rat.java new file mode 100644 index 00000000..2ce5534b --- /dev/null +++ b/code/typeinfo/pets/Rat.java @@ -0,0 +1,10 @@ +// typeinfo/pets/Rat.java +// (c)2020 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 typeinfo.pets; + +public class Rat extends Rodent { + public Rat(String name) { super(name); } + public Rat() { super(); } +} diff --git a/code/typeinfo/pets/Rodent.java b/code/typeinfo/pets/Rodent.java new file mode 100644 index 00000000..7b998d0a --- /dev/null +++ b/code/typeinfo/pets/Rodent.java @@ -0,0 +1,10 @@ +// typeinfo/pets/Rodent.java +// (c)2020 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 typeinfo.pets; + +public class Rodent extends Pet { + public Rodent(String name) { super(name); } + public Rodent() { super(); } +} diff --git a/code/typeinfo/toys/GenericToyTest.java b/code/typeinfo/toys/GenericToyTest.java new file mode 100644 index 00000000..7dc016cd --- /dev/null +++ b/code/typeinfo/toys/GenericToyTest.java @@ -0,0 +1,23 @@ +// typeinfo/toys/GenericToyTest.java +// (c)2020 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. +// Testing class Class +// {java typeinfo.toys.GenericToyTest} +package typeinfo.toys; + +public class GenericToyTest { + @SuppressWarnings("deprecation") + public static void + main(String[] args) throws Exception { + Class ftClass = FancyToy.class; + // Produces exact type: + FancyToy fancyToy = ftClass.newInstance(); + Class up = + ftClass.getSuperclass(); + // This won't compile: + // Class up2 = ftClass.getSuperclass(); + // Only produces Object: + Object obj = up.newInstance(); + } +} diff --git a/code/typeinfo/toys/ToyTest.java b/code/typeinfo/toys/ToyTest.java new file mode 100644 index 00000000..e4e5e92d --- /dev/null +++ b/code/typeinfo/toys/ToyTest.java @@ -0,0 +1,78 @@ +// typeinfo/toys/ToyTest.java +// (c)2020 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. +// Testing class Class +// {java typeinfo.toys.ToyTest} +package typeinfo.toys; +import java.lang.reflect.InvocationTargetException; + +interface HasBatteries {} +interface Waterproof {} +interface Shoots {} + +class Toy { + // Comment out the following no-arg + // constructor to see NoSuchMethodError + Toy() {} + Toy(int i) {} +} + +class FancyToy extends Toy +implements HasBatteries, Waterproof, Shoots { + FancyToy() { super(1); } +} + +public class ToyTest { + static void printInfo(Class cc) { + System.out.println("Class name: " + cc.getName() + + " is interface? [" + cc.isInterface() + "]"); + System.out.println( + "Simple name: " + cc.getSimpleName()); + System.out.println( + "Canonical name : " + cc.getCanonicalName()); + } + @SuppressWarnings("deprecation") + public static void main(String[] args) { + Class c = null; + try { + c = Class.forName("typeinfo.toys.FancyToy"); + } catch(ClassNotFoundException e) { + System.out.println("Can't find FancyToy"); + System.exit(1); + } + printInfo(c); + for(Class face : c.getInterfaces()) + printInfo(face); + Class up = c.getSuperclass(); + Object obj = null; + try { + // Requires no-arg constructor: + obj = up.newInstance(); + } catch(Exception e) { + throw new + RuntimeException("Cannot instantiate"); + } + printInfo(obj.getClass()); + } +} +/* Output: +Class name: typeinfo.toys.FancyToy is interface? +[false] +Simple name: FancyToy +Canonical name : typeinfo.toys.FancyToy +Class name: typeinfo.toys.HasBatteries is interface? +[true] +Simple name: HasBatteries +Canonical name : typeinfo.toys.HasBatteries +Class name: typeinfo.toys.Waterproof is interface? +[true] +Simple name: Waterproof +Canonical name : typeinfo.toys.Waterproof +Class name: typeinfo.toys.Shoots is interface? [true] +Simple name: Shoots +Canonical name : typeinfo.toys.Shoots +Class name: typeinfo.toys.Toy is interface? [false] +Simple name: Toy +Canonical name : typeinfo.toys.Toy +*/ diff --git a/code/validating/Assert1.java b/code/validating/Assert1.java new file mode 100644 index 00000000..013a72f6 --- /dev/null +++ b/code/validating/Assert1.java @@ -0,0 +1,19 @@ +// validating/Assert1.java +// (c)2020 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. +// Non-informative style of assert +// Must run using -ea flag: +// {java -ea Assert1} +// {ThrowsException} + +public class Assert1 { + public static void main(String[] args) { + assert false; + } +} +/* Output: +___[ Error Output ]___ +Exception in thread "main" java.lang.AssertionError + at Assert1.main(Assert1.java:9) +*/ diff --git a/code/validating/Assert2.java b/code/validating/Assert2.java new file mode 100644 index 00000000..61b4827d --- /dev/null +++ b/code/validating/Assert2.java @@ -0,0 +1,20 @@ +// validating/Assert2.java +// (c)2020 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. +// Assert with an information-expression +// {java Assert2 -ea} +// {ThrowsException} + +public class Assert2 { + public static void main(String[] args) { + assert false: + "Here's a message saying what happened"; + } +} +/* Output: +___[ Error Output ]___ +Exception in thread "main" java.lang.AssertionError: +Here's a message saying what happened + at Assert2.main(Assert2.java:8) +*/ diff --git a/code/validating/BadMicroBenchmark.java b/code/validating/BadMicroBenchmark.java new file mode 100644 index 00000000..2634e67c --- /dev/null +++ b/code/validating/BadMicroBenchmark.java @@ -0,0 +1,29 @@ +// validating/BadMicroBenchmark.java +// (c)2020 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. +// {ExcludeFromTravisCI} +import java.util.*; +import onjava.Timer; + +public class BadMicroBenchmark { + static final int SIZE = 250_000_000; + public static void main(String[] args) { + try { // For machines with insufficient memory + long[] la = new long[SIZE]; + System.out.println("setAll: " + + Timer.duration(() -> + Arrays.setAll(la, n -> n))); + System.out.println("parallelSetAll: " + + Timer.duration(() -> + Arrays.parallelSetAll(la, n -> n))); + } catch(OutOfMemoryError e) { + System.out.println("Insufficient memory"); + System.exit(0); + } + } +} +/* Output: +setAll: 272 +parallelSetAll: 301 +*/ diff --git a/code/validating/BadMicroBenchmark2.java b/code/validating/BadMicroBenchmark2.java new file mode 100644 index 00000000..123036a0 --- /dev/null +++ b/code/validating/BadMicroBenchmark2.java @@ -0,0 +1,35 @@ +// validating/BadMicroBenchmark2.java +// (c)2020 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. +// Relying on a common resource +import java.util.*; +import onjava.Timer; + +public class BadMicroBenchmark2 { + // SIZE reduced to make it run faster: + static final int SIZE = 5_000_000; + public static void main(String[] args) { + long[] la = new long[SIZE]; + Random r = new Random(); + System.out.println("parallelSetAll: " + + Timer.duration(() -> + Arrays.parallelSetAll(la, n -> r.nextLong()))); + System.out.println("setAll: " + + Timer.duration(() -> + Arrays.setAll(la, n -> r.nextLong()))); + SplittableRandom sr = new SplittableRandom(); + System.out.println("parallelSetAll: " + + Timer.duration(() -> + Arrays.parallelSetAll(la, n -> sr.nextLong()))); + System.out.println("setAll: " + + Timer.duration(() -> + Arrays.setAll(la, n -> sr.nextLong()))); + } +} +/* Output: +parallelSetAll: 1147 +setAll: 174 +parallelSetAll: 86 +setAll: 39 +*/ diff --git a/code/validating/CircularQueue.java b/code/validating/CircularQueue.java new file mode 100644 index 00000000..405e4410 --- /dev/null +++ b/code/validating/CircularQueue.java @@ -0,0 +1,91 @@ +// validating/CircularQueue.java +// (c)2020 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. +// Demonstration of Design by Contract (DbC) +package validating; +import java.util.*; + +public class CircularQueue { + private Object[] data; + private int + in = 0, // Next available storage space + out = 0; // Next gettable object + // Has it wrapped around the circular queue? + private boolean wrapped = false; + public CircularQueue(int size) { + data = new Object[size]; + // Must be true after construction: + assert invariant(); + } + public boolean empty() { + return !wrapped && in == out; + } + public boolean full() { + return wrapped && in == out; + } + public boolean isWrapped() { return wrapped; } + public void put(Object item) { + precondition(item != null, "put() null item"); + precondition(!full(), + "put() into full CircularQueue"); + assert invariant(); + data[in++] = item; + if(in >= data.length) { + in = 0; + wrapped = true; + } + assert invariant(); + } + public Object get() { + precondition(!empty(), + "get() from empty CircularQueue"); + assert invariant(); + Object returnVal = data[out]; + data[out] = null; + out++; + if(out >= data.length) { + out = 0; + wrapped = false; + } + assert postcondition( + returnVal != null, + "Null item in CircularQueue"); + assert invariant(); + return returnVal; + } + // Design-by-contract support methods: + private static void + precondition(boolean cond, String msg) { + if(!cond) throw new CircularQueueException(msg); + } + private static boolean + postcondition(boolean cond, String msg) { + if(!cond) throw new CircularQueueException(msg); + return true; + } + private boolean invariant() { + // Guarantee that no null values are in the + // region of 'data' that holds objects: + for(int i = out; i != in; i = (i + 1) % data.length) + if(data[i] == null) + throw new CircularQueueException( + "null in CircularQueue"); + // Guarantee that only null values are outside the + // region of 'data' that holds objects: + if(full()) return true; + for(int i = in; i != out; i = (i + 1) % data.length) + if(data[i] != null) + throw new CircularQueueException( + "non-null outside of CircularQueue range: " + + dump()); + return true; + } + public String dump() { + return "in = " + in + + ", out = " + out + + ", full() = " + full() + + ", empty() = " + empty() + + ", CircularQueue = " + Arrays.asList(data); + } +} diff --git a/code/validating/CircularQueueException.java b/code/validating/CircularQueueException.java new file mode 100644 index 00000000..142b8ece --- /dev/null +++ b/code/validating/CircularQueueException.java @@ -0,0 +1,12 @@ +// validating/CircularQueueException.java +// (c)2020 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 validating; + +public class +CircularQueueException extends RuntimeException { + public CircularQueueException(String why) { + super(why); + } +} diff --git a/code/validating/CountedList.java b/code/validating/CountedList.java new file mode 100644 index 00000000..6c780f21 --- /dev/null +++ b/code/validating/CountedList.java @@ -0,0 +1,16 @@ +// validating/CountedList.java +// (c)2020 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. +// Keeps track of how many of itself are created. +package validating; +import java.util.*; + +public class CountedList extends ArrayList { + private static int counter = 0; + private int id = counter++; + public CountedList() { + System.out.println("CountedList #" + id); + } + public int getId() { return id; } +} diff --git a/code/validating/GuavaAssertions.java b/code/validating/GuavaAssertions.java new file mode 100644 index 00000000..a499f079 --- /dev/null +++ b/code/validating/GuavaAssertions.java @@ -0,0 +1,49 @@ +// validating/GuavaAssertions.java +// (c)2020 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. +// Assertions that are always enabled. +import com.google.common.base.*; +import static com.google.common.base.Verify.*; + +public class GuavaAssertions { + public static void main(String[] args) { + verify(2 + 2 == 4); + try { + verify(1 + 2 == 4); + } catch(VerifyException e) { + System.out.println(e); + } + try { + verify(1 + 2 == 4, "Bad math"); + } catch(VerifyException e) { + System.out.println(e.getMessage()); + } + try { + verify(1 + 2 == 4, "Bad math: %s", "not 4"); + } catch(VerifyException e) { + System.out.println(e.getMessage()); + } + String s = ""; + s = verifyNotNull(s); + s = null; + try { + verifyNotNull(s); + } catch(VerifyException e) { + System.out.println(e.getMessage()); + } + try { + verifyNotNull( + s, "Shouldn't be null: %s", "arg s"); + } catch(VerifyException e) { + System.out.println(e.getMessage()); + } + } +} +/* Output: +com.google.common.base.VerifyException +Bad math +Bad math: not 4 +expected a non-null reference +Shouldn't be null: arg s +*/ diff --git a/code/validating/GuavaPreconditions.java b/code/validating/GuavaPreconditions.java new file mode 100644 index 00000000..3cfc66ae --- /dev/null +++ b/code/validating/GuavaPreconditions.java @@ -0,0 +1,125 @@ +// validating/GuavaPreconditions.java +// (c)2020 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. +// Demonstrating Guava Preconditions +import java.util.function.*; +import static com.google.common.base.Preconditions.*; + +public class GuavaPreconditions { + static void test(Consumer c, String s) { + try { + System.out.println(s); + c.accept(s); + System.out.println("Success"); + } catch(Exception e) { + String type = e.getClass().getSimpleName(); + String msg = e.getMessage(); + System.out.println(type + + (msg == null ? "" : ": " + msg)); + } + } + public static void main(String[] args) { + test(s -> s = checkNotNull(s), "X"); + test(s -> s = checkNotNull(s), null); + test(s -> s = checkNotNull(s, "s was null"), null); + test(s -> s = checkNotNull( + s, "s was null, %s %s", "arg2", "arg3"), null); + + test(s -> checkArgument(s == "Fozzie"), "Fozzie"); + test(s -> checkArgument(s == "Fozzie"), "X"); + test(s -> checkArgument(s == "Fozzie"), null); + test(s -> checkArgument( + s == "Fozzie", "Bear Left!"), null); + test(s -> checkArgument( + s == "Fozzie", "Bear Left! %s Right!", "Frog"), + null); + + test(s -> checkState(s.length() > 6), "Mortimer"); + test(s -> checkState(s.length() > 6), "Mort"); + test(s -> checkState(s.length() > 6), null); + + test(s -> + checkElementIndex(6, s.length()), "Robert"); + test(s -> + checkElementIndex(6, s.length()), "Bob"); + test(s -> + checkElementIndex(6, s.length()), null); + + test(s -> + checkPositionIndex(6, s.length()), "Robert"); + test(s -> + checkPositionIndex(6, s.length()), "Bob"); + test(s -> + checkPositionIndex(6, s.length()), null); + + test(s -> checkPositionIndexes( + 0, 6, s.length()), "Hieronymus"); + test(s -> checkPositionIndexes( + 0, 10, s.length()), "Hieronymus"); + test(s -> checkPositionIndexes( + 0, 11, s.length()), "Hieronymus"); + test(s -> checkPositionIndexes( + -1, 6, s.length()), "Hieronymus"); + test(s -> checkPositionIndexes( + 7, 6, s.length()), "Hieronymus"); + test(s -> checkPositionIndexes( + 0, 6, s.length()), null); + } +} +/* Output: +X +Success +null +NullPointerException +null +NullPointerException: s was null +null +NullPointerException: s was null, arg2 arg3 +Fozzie +Success +X +IllegalArgumentException +null +IllegalArgumentException +null +IllegalArgumentException: Bear Left! +null +IllegalArgumentException: Bear Left! Frog Right! +Mortimer +Success +Mort +IllegalStateException +null +NullPointerException +Robert +IndexOutOfBoundsException: index (6) must be less than +size (6) +Bob +IndexOutOfBoundsException: index (6) must be less than +size (3) +null +NullPointerException +Robert +Success +Bob +IndexOutOfBoundsException: index (6) must not be +greater than size (3) +null +NullPointerException +Hieronymus +Success +Hieronymus +Success +Hieronymus +IndexOutOfBoundsException: end index (11) must not be +greater than size (10) +Hieronymus +IndexOutOfBoundsException: start index (-1) must not be +negative +Hieronymus +IndexOutOfBoundsException: end index (6) must not be +less than start index (7) +null +NullPointerException +*/ diff --git a/code/validating/Inverter1.java b/code/validating/Inverter1.java new file mode 100644 index 00000000..8ef828d6 --- /dev/null +++ b/code/validating/Inverter1.java @@ -0,0 +1,9 @@ +// validating/Inverter1.java +// (c)2020 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 validating; + +public class Inverter1 implements StringInverter { + public String invert(String str) { return str; } +} diff --git a/code/validating/Inverter2.java b/code/validating/Inverter2.java new file mode 100644 index 00000000..3fb862fd --- /dev/null +++ b/code/validating/Inverter2.java @@ -0,0 +1,19 @@ +// validating/Inverter2.java +// (c)2020 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 validating; +import static java.lang.Character.*; + +public class Inverter2 implements StringInverter { + public String invert(String str) { + String result = ""; + for(int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + result += isUpperCase(c) ? + toLowerCase(c) : + toUpperCase(c); + } + return result; + } +} diff --git a/code/validating/Inverter3.java b/code/validating/Inverter3.java new file mode 100644 index 00000000..4bd53c82 --- /dev/null +++ b/code/validating/Inverter3.java @@ -0,0 +1,21 @@ +// validating/Inverter3.java +// (c)2020 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 validating; +import static java.lang.Character.*; + +public class Inverter3 implements StringInverter { + public String invert(String str) { + if(str.length() > 30) + throw new RuntimeException("argument too long!"); + String result = ""; + for(int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + result += isUpperCase(c) ? + toLowerCase(c) : + toUpperCase(c); + } + return result; + } +} diff --git a/code/validating/Inverter4.java b/code/validating/Inverter4.java new file mode 100644 index 00000000..0b787059 --- /dev/null +++ b/code/validating/Inverter4.java @@ -0,0 +1,26 @@ +// validating/Inverter4.java +// (c)2020 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 validating; +import static java.lang.Character.*; + +public class Inverter4 implements StringInverter { + static final String ALLOWED = + "abcdefghijklmnopqrstuvwxyz ,." + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + public String invert(String str) { + if(str.length() > 30) + throw new RuntimeException("argument too long!"); + String result = ""; + for(int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if(ALLOWED.indexOf(c) == -1) + throw new RuntimeException(c + " Not allowed"); + result += isUpperCase(c) ? + toLowerCase(c) : + toUpperCase(c); + } + return result; + } +} diff --git a/code/validating/LoaderAssertions.java b/code/validating/LoaderAssertions.java new file mode 100644 index 00000000..52cac347 --- /dev/null +++ b/code/validating/LoaderAssertions.java @@ -0,0 +1,28 @@ +// validating/LoaderAssertions.java +// (c)2020 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. +// Using the class loader to enable assertions +// {ThrowsException} + +public class LoaderAssertions { + public static void main(String[] args) { + ClassLoader.getSystemClassLoader() + .setDefaultAssertionStatus(true); + new Loaded().go(); + } +} + +class Loaded { + public void go() { + assert false: "Loaded.go()"; + } +} +/* Output: +___[ Error Output ]___ +Exception in thread "main" java.lang.AssertionError: +Loaded.go() + at Loaded.go(LoaderAssertions.java:15) + at +LoaderAssertions.main(LoaderAssertions.java:9) +*/ diff --git a/code/validating/NonNullConstruction.java b/code/validating/NonNullConstruction.java new file mode 100644 index 00000000..a95483dd --- /dev/null +++ b/code/validating/NonNullConstruction.java @@ -0,0 +1,18 @@ +// validating/NonNullConstruction.java +// (c)2020 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. +import static com.google.common.base.Preconditions.*; + +public class NonNullConstruction { + private Integer n; + private String s; + NonNullConstruction(Integer n, String s) { + this.n = checkNotNull(n); + this.s = checkNotNull(s); + } + public static void main(String[] args) { + NonNullConstruction nnc = + new NonNullConstruction(3, "Trousers"); + } +} diff --git a/code/validating/SLF4JLevels.java b/code/validating/SLF4JLevels.java new file mode 100644 index 00000000..c851e7c3 --- /dev/null +++ b/code/validating/SLF4JLevels.java @@ -0,0 +1,29 @@ +// validating/SLF4JLevels.java +// (c)2020 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. +import org.slf4j.*; + +public class SLF4JLevels { + private static Logger log = + LoggerFactory.getLogger(SLF4JLevels.class); + public static void main(String[] args) { + log.trace("Hello"); + log.debug("Logging"); + log.info("Using"); + log.warn("the SLF4J"); + log.error("Facade"); + } +} +/* Output: +2017-05-09T06:07:52.846 +[main] TRACE SLF4JLevels - Hello +2017-05-09T06:07:52.849 +[main] DEBUG SLF4JLevels - Logging +2017-05-09T06:07:52.849 +[main] INFO SLF4JLevels - Using +2017-05-09T06:07:52.850 +[main] WARN SLF4JLevels - the SLF4J +2017-05-09T06:07:52.851 +[main] ERROR SLF4JLevels - Facade +*/ diff --git a/code/validating/SLF4JLogging.java b/code/validating/SLF4JLogging.java new file mode 100644 index 00000000..f2e94d6e --- /dev/null +++ b/code/validating/SLF4JLogging.java @@ -0,0 +1,17 @@ +// validating/SLF4JLogging.java +// (c)2020 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. +import org.slf4j.*; + +public class SLF4JLogging { + private static Logger log = + LoggerFactory.getLogger(SLF4JLogging.class); + public static void main(String[] args) { + log.info("hello logging"); + } +} +/* Output: +2017-05-09T06:07:53.418 +[main] INFO SLF4JLogging - hello logging +*/ diff --git a/code/validating/SimpleDebugging.java b/code/validating/SimpleDebugging.java new file mode 100644 index 00000000..863e7de3 --- /dev/null +++ b/code/validating/SimpleDebugging.java @@ -0,0 +1,40 @@ +// validating/SimpleDebugging.java +// (c)2020 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. +// {ThrowsException} + +public class SimpleDebugging { + private static void foo1() { + System.out.println("In foo1"); + foo2(); + } + private static void foo2() { + System.out.println("In foo2"); + foo3(); + } + private static void foo3() { + System.out.println("In foo3"); + int j = 1; + j--; + int i = 5 / j; + } + public static void main(String[] args) { + foo1(); + } +} +/* Output: +In foo1 +In foo2 +In foo3 +___[ Error Output ]___ +Exception in thread "main" +java.lang.ArithmeticException: / by zero + at +SimpleDebugging.foo3(SimpleDebugging.java:17) + at +SimpleDebugging.foo2(SimpleDebugging.java:11) + at SimpleDebugging.foo1(SimpleDebugging.java:7) + at +SimpleDebugging.main(SimpleDebugging.java:20) +*/ diff --git a/code/validating/StringInverter.java b/code/validating/StringInverter.java new file mode 100644 index 00000000..34c933a7 --- /dev/null +++ b/code/validating/StringInverter.java @@ -0,0 +1,9 @@ +// validating/StringInverter.java +// (c)2020 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 validating; + +interface StringInverter { + String invert(String str); +} diff --git a/code/validating/jmh/JMH1.java b/code/validating/jmh/JMH1.java new file mode 100644 index 00000000..79eb749a --- /dev/null +++ b/code/validating/jmh/JMH1.java @@ -0,0 +1,31 @@ +// validating/jmh/JMH1.java +// (c)2020 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 validating.jmh; +import java.util.*; +import org.openjdk.jmh.annotations.*; +import java.util.concurrent.TimeUnit; + +@State(Scope.Thread) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +// Increase these three for more accuracy: +@Warmup(iterations = 5) +@Measurement(iterations = 5) +@Fork(1) +public class JMH1 { + private long[] la; + @Setup + public void setup() { + la = new long[250_000_000]; + } + @Benchmark + public void setAll() { + Arrays.setAll(la, n -> n); + } + @Benchmark + public void parallelSetAll() { + Arrays.parallelSetAll(la, n -> n); + } +} diff --git a/code/validating/jmh/JMH2.java b/code/validating/jmh/JMH2.java new file mode 100644 index 00000000..ae7b56f9 --- /dev/null +++ b/code/validating/jmh/JMH2.java @@ -0,0 +1,44 @@ +// validating/jmh/JMH2.java +// (c)2020 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 validating.jmh; +import java.util.*; +import org.openjdk.jmh.annotations.*; +import java.util.concurrent.TimeUnit; + +@State(Scope.Thread) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Warmup(iterations = 5) +@Measurement(iterations = 5) +@Fork(1) +public class JMH2 { + private long[] la; + @Param({ + "1", + "10", + "100", + "1000", + "10000", + "100000", + "1000000", + "10000000", + "100000000", + "250000000" + }) + int size; + + @Setup + public void setup() { + la = new long[size]; + } + @Benchmark + public void setAll() { + Arrays.setAll(la, n -> n); + } + @Benchmark + public void parallelSetAll() { + Arrays.parallelSetAll(la, n -> n); + } +} diff --git a/code/validating/jmh/JMH3.java b/code/validating/jmh/JMH3.java new file mode 100644 index 00000000..8ce9bb0c --- /dev/null +++ b/code/validating/jmh/JMH3.java @@ -0,0 +1,48 @@ +// validating/jmh/JMH3.java +// (c)2020 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 validating.jmh; +import java.util.*; +import org.openjdk.jmh.annotations.*; +import java.util.concurrent.TimeUnit; + +@State(Scope.Thread) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Warmup(iterations = 5) +@Measurement(iterations = 5) +@Fork(1) +public class JMH3 { + private long[] la; + @Param({ + "1", + "10", + "100", + "1000", + "10000", + "100000", + "1000000", + "10000000", + "100000000", + "250000000" + }) + int size; + + @Setup + public void setup() { + la = new long[size]; + } + public static long f(long x) { + long quadratic = 42 * x * x + 19 * x + 47; + return Long.divideUnsigned(quadratic, x + 1); + } + @Benchmark + public void setAll() { + Arrays.setAll(la, n -> f(n)); + } + @Benchmark + public void parallelSetAll() { + Arrays.parallelSetAll(la, n -> f(n)); + } +} diff --git a/code/validating/logback.xml b/code/validating/logback.xml new file mode 100644 index 00000000..0a774e44 --- /dev/null +++ b/code/validating/logback.xml @@ -0,0 +1,15 @@ + + + + + +%d{yyyy-MM-dd'T'HH:mm:ss.SSS} +[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/code/validating/tests/CircularQueueTest.java b/code/validating/tests/CircularQueueTest.java new file mode 100644 index 00000000..8da6dc27 --- /dev/null +++ b/code/validating/tests/CircularQueueTest.java @@ -0,0 +1,150 @@ +// validating/tests/CircularQueueTest.java +// (c)2020 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 validating; +import org.junit.jupiter.api.*; +import static org.junit.jupiter.api.Assertions.*; + +public class CircularQueueTest { + private CircularQueue queue = new CircularQueue(10); + private int i = 0; + @BeforeEach + public void initialize() { + while(i < 5) // Pre-load with some data + queue.put(Integer.toString(i++)); + } + // Support methods: + private void showFullness() { + assertTrue(queue.full()); + assertFalse(queue.empty()); + System.out.println(queue.dump()); + } + private void showEmptiness() { + assertFalse(queue.full()); + assertTrue(queue.empty()); + System.out.println(queue.dump()); + } + @Test + public void full() { + System.out.println("testFull"); + System.out.println(queue.dump()); + System.out.println(queue.get()); + System.out.println(queue.get()); + while(!queue.full()) + queue.put(Integer.toString(i++)); + String msg = ""; + try { + queue.put(""); + } catch(CircularQueueException e) { + msg = e.getMessage(); + System.out.println(msg); + } + assertEquals(msg, "put() into full CircularQueue"); + showFullness(); + } + @Test + public void empty() { + System.out.println("testEmpty"); + while(!queue.empty()) + System.out.println(queue.get()); + String msg = ""; + try { + queue.get(); + } catch(CircularQueueException e) { + msg = e.getMessage(); + System.out.println(msg); + } + assertEquals(msg, "get() from empty CircularQueue"); + showEmptiness(); + } + @Test + public void nullPut() { + System.out.println("testNullPut"); + String msg = ""; + try { + queue.put(null); + } catch(CircularQueueException e) { + msg = e.getMessage(); + System.out.println(msg); + } + assertEquals(msg, "put() null item"); + } + @Test + public void circularity() { + System.out.println("testCircularity"); + while(!queue.full()) + queue.put(Integer.toString(i++)); + showFullness(); + assertTrue(queue.isWrapped()); + while(!queue.empty()) + System.out.println(queue.get()); + showEmptiness(); + while(!queue.full()) + queue.put(Integer.toString(i++)); + showFullness(); + while(!queue.empty()) + System.out.println(queue.get()); + showEmptiness(); + } +} +/* Output: +testNullPut +put() null item +testCircularity +in = 0, out = 0, full() = true, empty() = false, +CircularQueue = +[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +in = 0, out = 0, full() = false, empty() = true, +CircularQueue = +[null, null, null, null, null, null, null, null, null, +null] +in = 0, out = 0, full() = true, empty() = false, +CircularQueue = +[10, 11, 12, 13, 14, 15, 16, 17, 18, 19] +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +in = 0, out = 0, full() = false, empty() = true, +CircularQueue = +[null, null, null, null, null, null, null, null, null, +null] +testFull +in = 5, out = 0, full() = false, empty() = false, +CircularQueue = +[0, 1, 2, 3, 4, null, null, null, null, null] +0 +1 +put() into full CircularQueue +in = 2, out = 2, full() = true, empty() = false, +CircularQueue = +[10, 11, 2, 3, 4, 5, 6, 7, 8, 9] +testEmpty +0 +1 +2 +3 +4 +get() from empty CircularQueue +in = 5, out = 5, full() = false, empty() = true, +CircularQueue = +[null, null, null, null, null, null, null, null, null, +null] +*/ diff --git a/code/validating/tests/CountedListTest.java b/code/validating/tests/CountedListTest.java new file mode 100644 index 00000000..a9dc0c71 --- /dev/null +++ b/code/validating/tests/CountedListTest.java @@ -0,0 +1,101 @@ +// validating/tests/CountedListTest.java +// (c)2020 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. +// Simple use of JUnit to test CountedList. +package validating; +import java.util.*; +import org.junit.jupiter.api.*; +import static org.junit.jupiter.api.Assertions.*; + +public class CountedListTest { + private CountedList list; + @BeforeAll + static void beforeAllMsg() { + System.out.println(">>> Starting CountedListTest"); + } + @AfterAll + static void afterAllMsg() { + System.out.println(">>> Finished CountedListTest"); + } + @BeforeEach + public void initialize() { + list = new CountedList(); + System.out.println("Set up for " + list.getId()); + for(int i = 0; i < 3; i++) + list.add(Integer.toString(i)); + } + @AfterEach + public void cleanup() { + System.out.println("Cleaning up " + list.getId()); + } + @Test + public void insert() { + System.out.println("Running testInsert()"); + assertEquals(list.size(), 3); + list.add(1, "Insert"); + assertEquals(list.size(), 4); + assertEquals(list.get(1), "Insert"); + } + @Test + public void replace() { + System.out.println("Running testReplace()"); + assertEquals(list.size(), 3); + list.set(1, "Replace"); + assertEquals(list.size(), 3); + assertEquals(list.get(1), "Replace"); + } + // A helper method to simplify the code. As + // long as it's not annotated with @Test, it will + // not be automatically executed by JUnit. + private + void compare(List lst, String[] strs) { + assertArrayEquals(lst.toArray(new String[0]), strs); + } + @Test + public void order() { + System.out.println("Running testOrder()"); + compare(list, new String[] { "0", "1", "2" }); + } + @Test + public void remove() { + System.out.println("Running testRemove()"); + assertEquals(list.size(), 3); + list.remove(1); + assertEquals(list.size(), 2); + compare(list, new String[] { "0", "2" }); + } + @Test + public void addAll() { + System.out.println("Running testAddAll()"); + list.addAll(Arrays.asList(new String[] { + "An", "African", "Swallow"})); + assertEquals(list.size(), 6); + compare(list, new String[] { "0", "1", "2", + "An", "African", "Swallow" }); + } +} +/* Output: +>>> Starting CountedListTest +CountedList #0 +Set up for 0 +Running testRemove() +Cleaning up 0 +CountedList #1 +Set up for 1 +Running testReplace() +Cleaning up 1 +CountedList #2 +Set up for 2 +Running testAddAll() +Cleaning up 2 +CountedList #3 +Set up for 3 +Running testInsert() +Cleaning up 3 +CountedList #4 +Set up for 4 +Running testOrder() +Cleaning up 4 +>>> Finished CountedListTest +*/ diff --git a/code/validating/tests/DynamicStringInverterTests.java b/code/validating/tests/DynamicStringInverterTests.java new file mode 100644 index 00000000..dc980971 --- /dev/null +++ b/code/validating/tests/DynamicStringInverterTests.java @@ -0,0 +1,122 @@ +// validating/tests/DynamicStringInverterTests.java +// (c)2020 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 validating; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; +import org.junit.jupiter.api.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.DynamicTest.*; + +class DynamicStringInverterTests { + // Combine operations to prevent code duplication: + Stream testVersions(String id, + Function test) { + List versions = Arrays.asList( + new Inverter1(), new Inverter2(), + new Inverter3(), new Inverter4()); + return DynamicTest.stream( + versions.iterator(), + inverter -> inverter.getClass().getSimpleName(), + inverter -> { + System.out.println( + inverter.getClass().getSimpleName() + + ": " + id); + try { + if(test.apply(inverter) != "fail") + System.out.println("Success"); + } catch(Exception | Error e) { + System.out.println( + "Exception: " + e.getMessage()); + } + } + ); + } + String isEqual(String lval, String rval) { + if(lval.equals(rval)) + return "success"; + System.out.println("FAIL: " + lval + " != " + rval); + return "fail"; + } + @BeforeAll + static void startMsg() { + System.out.println( + ">>> Starting DynamicStringInverterTests <<<"); + } + @AfterAll + static void endMsg() { + System.out.println( + ">>> Finished DynamicStringInverterTests <<<"); + } + @TestFactory + Stream basicInversion1() { + String in = "Exit, Pursued by a Bear."; + String out = "eXIT, pURSUED BY A bEAR."; + return testVersions( + "Basic inversion (should succeed)", + inverter -> isEqual(inverter.invert(in), out) + ); + } + @TestFactory + Stream basicInversion2() { + return testVersions( + "Basic inversion (should fail)", + inverter -> isEqual(inverter.invert("X"), "X")); + } + @TestFactory + Stream disallowedCharacters() { + String disallowed = ";-_()*&^%$#@!~`0123456789"; + return testVersions( + "Disallowed characters", + inverter -> { + String result = disallowed.chars() + .mapToObj(c -> { + String cc = Character.toString((char)c); + try { + inverter.invert(cc); + return ""; + } catch(RuntimeException e) { + return cc; + } + }).collect(Collectors.joining("")); + if(result.length() == 0) + return "success"; + System.out.println("Bad characters: " + result); + return "fail"; + } + ); + } + @TestFactory + Stream allowedCharacters() { + String lowcase = "abcdefghijklmnopqrstuvwxyz ,."; + String upcase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ ,."; + return testVersions( + "Allowed characters (should succeed)", + inverter -> { + assertEquals(inverter.invert(lowcase), upcase); + assertEquals(inverter.invert(upcase), lowcase); + return "success"; + } + ); + } + @TestFactory + Stream lengthNoGreaterThan30() { + String str = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; + assertTrue(str.length() > 30); + return testVersions( + "Length must be less than 31 (throws exception)", + inverter -> inverter.invert(str) + ); + } + @TestFactory + Stream lengthLessThan31() { + String str = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; + assertTrue(str.length() < 31); + return testVersions( + "Length must be less than 31 (should succeed)", + inverter -> inverter.invert(str) + ); + } +} diff --git a/code/validating/tests/StringInverterTests.java b/code/validating/tests/StringInverterTests.java new file mode 100644 index 00000000..e32873b8 --- /dev/null +++ b/code/validating/tests/StringInverterTests.java @@ -0,0 +1,65 @@ +// validating/tests/StringInverterTests.java +// (c)2020 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 validating; +import java.util.*; +import java.util.stream.*; +import org.junit.jupiter.api.*; +import static org.junit.jupiter.api.Assertions.*; + +public class StringInverterTests { + StringInverter inverter = new Inverter4(); + @BeforeAll + static void startMsg() { + System.out.println(">>> StringInverterTests <<<"); + } + @Test + void basicInversion1() { + String in = "Exit, Pursued by a Bear."; + String out = "eXIT, pURSUED BY A bEAR."; + assertEquals(inverter.invert(in), out); + } + @Test + void basicInversion2() { + assertThrows(Error.class, () -> { + assertEquals(inverter.invert("X"), "X"); + }); + } + @Test + void disallowedCharacters() { + String disallowed = ";-_()*&^%$#@!~`0123456789"; + String result = disallowed.chars() + .mapToObj(c -> { + String cc = Character.toString((char)c); + try { + inverter.invert(cc); + return ""; + } catch(RuntimeException e) { + return cc; + } + }).collect(Collectors.joining("")); + assertEquals(result, disallowed); + } + @Test + void allowedCharacters() { + String lowcase = "abcdefghijklmnopqrstuvwxyz ,."; + String upcase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ ,."; + assertEquals(inverter.invert(lowcase), upcase); + assertEquals(inverter.invert(upcase), lowcase); + } + @Test + void lengthNoGreaterThan30() { + String str = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; + assertTrue(str.length() > 30); + assertThrows(RuntimeException.class, () -> { + inverter.invert(str); + }); + } + @Test + void lengthLessThan31() { + String str = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; + assertTrue(str.length() < 31); + inverter.invert(str); + } +} From ec2e1fad5edca8e513f5f2dd4549e622aa1e31d3 Mon Sep 17 00:00:00 2001 From: "jim.deng" Date: Tue, 24 Nov 2020 14:31:15 +0800 Subject: [PATCH 02/12] 2 --- code/.gitattributes | 17 - code/.gitignore | 111 ----- code/.travisXX.yml | 8 - code/CI.txt | 5 - code/Copyright.txt | 72 --- code/README.md | 43 -- code/annotations/AUComposition.java | 30 -- code/annotations/AUExternalTest.java | 29 -- code/annotations/AtUnitExample1.java | 48 -- code/annotations/AtUnitExample2.java | 57 --- code/annotations/AtUnitExample3.java | 42 -- code/annotations/AtUnitExample4.java | 83 ---- code/annotations/AtUnitExample5.java | 63 --- code/annotations/DemoProcessFiles.java | 43 -- code/annotations/HashSetTest.java | 36 -- code/annotations/PasswordUtils.java | 24 - code/annotations/SimulatingNull.java | 12 - code/annotations/StackL.java | 14 - code/annotations/StackLStringTst.java | 42 -- code/annotations/Testable.java | 14 - code/annotations/UseCase.java | 12 - code/annotations/UseCaseTracker.java | 37 -- code/annotations/database/Constraints.java | 14 - code/annotations/database/DBTable.java | 12 - code/annotations/database/Member.java | 22 - code/annotations/database/SQLInteger.java | 13 - code/annotations/database/SQLString.java | 14 - code/annotations/database/TableCreator.java | 106 ----- code/annotations/database/Uniqueness.java | 11 - code/annotations/ifx/ExtractInterface.java | 13 - .../ifx/IfaceExtractorProcessor.java | 91 ---- code/annotations/ifx/Multiplier.java | 34 -- code/annotations/simplest/Simple.java | 20 - .../annotations/simplest/SimpleProcessor.java | 47 -- code/annotations/simplest/SimpleTest.java | 32 -- code/appveyorXX.yml | 4 - code/arrays/AlphabeticSearch.java | 29 -- code/arrays/ArrayCopying.java | 81 ---- code/arrays/ArrayOfGenericType.java | 16 - code/arrays/ArrayOfGenerics.java | 33 -- code/arrays/ArrayOptions.java | 79 ---- code/arrays/ArraySearching.java | 33 -- .../AssemblingMultidimensionalArrays.java | 22 - code/arrays/AutoboxingArrays.java | 22 - code/arrays/CollectionComparison.java | 53 --- code/arrays/CompType.java | 56 --- code/arrays/ComparatorTest.java | 39 -- code/arrays/ComparingArrays.java | 62 --- code/arrays/CountUpward.java | 24 - code/arrays/FillingArrays.java | 55 --- code/arrays/IceCreamFlavors.java | 45 -- code/arrays/ModifyExisting.java | 22 - code/arrays/MultiDimWrapperArray.java | 38 -- code/arrays/MultidimensionalObjectArrays.java | 25 -- .../MultidimensionalPrimitiveArray.java | 18 - code/arrays/ParallelPrefix1.java | 27 -- code/arrays/ParallelPrefix2.java | 20 - code/arrays/ParallelPrefix3.java | 23 - code/arrays/ParallelSetAll.java | 24 - code/arrays/ParameterizedArrayType.java | 25 -- code/arrays/PythonLists.py | 36 -- code/arrays/RaggedArray.java | 26 -- code/arrays/Reverse.java | 32 -- code/arrays/SimpleSetAll.java | 56 --- code/arrays/StreamFromArray.java | 51 --- code/arrays/StringSorting.java | 39 -- code/arrays/TestConvertTo.java | 87 ---- code/arrays/TestCount.java | 167 ------- code/arrays/TestRand.java | 192 -------- code/arrays/ThreeDWithNew.java | 17 - code/arrays/jmh/ParallelSort.java | 25 -- code/build.gradle | 23 - code/checkstyle.xml | 179 -------- code/chkstyle.bat | 2 - code/collections/AdapterMethodIdiom.java | 48 -- code/collections/AddingGroups.java | 24 - .../ApplesAndOrangesWithGenerics.java | 23 - .../ApplesAndOrangesWithoutGenerics.java | 38 -- code/collections/ArrayIsNotIterable.java | 23 - code/collections/AsListInference.java | 34 -- code/collections/CollectionDifferences.java | 71 --- code/collections/CollectionSequence.java | 40 -- .../collections/CrossCollectionIteration.java | 36 -- .../CrossCollectionIteration2.java | 37 -- code/collections/EnvironmentVariables.java | 15 - code/collections/ForInCollections.java | 19 - code/collections/GenericsAndUpcasting.java | 28 -- code/collections/InterfaceVsIterator.java | 55 --- code/collections/IterableClass.java | 35 -- code/collections/LinkedListFeatures.java | 54 --- code/collections/ListFeatures.java | 93 ---- code/collections/ListIteration.java | 37 -- code/collections/MapOfList.java | 65 --- code/collections/ModifyingArraysAsList.java | 32 -- code/collections/MultiIterableClass.java | 53 --- code/collections/NonCollectionSequence.java | 37 -- code/collections/PetMap.java | 27 -- code/collections/PrintingCollections.java | 44 -- code/collections/PriorityQueueDemo.java | 53 --- code/collections/QueueDemo.java | 29 -- code/collections/SetOfInteger.java | 19 - code/collections/SetOfString.java | 25 -- code/collections/SetOperations.java | 40 -- code/collections/SimpleCollection.java | 18 - code/collections/SimpleIteration.java | 36 -- code/collections/SortedSetOfString.java | 25 -- code/collections/StackCollision.java | 25 -- code/collections/StackTest.java | 18 - code/collections/StackTest2.java | 18 - code/collections/Statistics.java | 25 -- code/collections/UniqueWords.java | 29 -- code/collections/UniqueWordsAlphabetic.java | 30 -- code/collectiontopics/AssociativeArray.java | 64 --- code/collectiontopics/Bits.java | 79 ---- code/collectiontopics/CanonicalMapping.java | 56 --- code/collectiontopics/CollectionMethods.java | 135 ------ code/collectiontopics/Enumerations.java | 24 - code/collectiontopics/FailFast.java | 22 - code/collectiontopics/FillMapTest.java | 32 -- code/collectiontopics/FillingLists.java | 35 -- code/collectiontopics/FunctionalMap.java | 38 -- code/collectiontopics/HTMLColorTest.java | 103 ----- code/collectiontopics/LinkedHashMapDemo.java | 31 -- code/collectiontopics/ListOps.java | 167 ------- code/collectiontopics/ListSortSearch.java | 57 --- code/collectiontopics/MapOps.java | 76 ---- code/collectiontopics/NavMap.java | 96 ---- code/collectiontopics/QueueBehavior.java | 50 --- code/collectiontopics/ReadOnly.java | 56 --- code/collectiontopics/References.java | 92 ---- code/collectiontopics/SetOrder.java | 92 ---- code/collectiontopics/SimpleDeques.java | 70 --- code/collectiontopics/SortedMapDemo.java | 42 -- code/collectiontopics/SortedSetDemo.java | 42 -- code/collectiontopics/Stacks.java | 61 --- code/collectiontopics/StreamFillMaps.java | 55 --- .../SuppliersCollectionTest.java | 67 --- code/collectiontopics/Synchronization.java | 24 - code/collectiontopics/ToDoList.java | 56 --- code/collectiontopics/TypesForSets.java | 93 ---- code/collectiontopics/Unsupported.java | 60 --- code/collectiontopics/Utilities.java | 88 ---- code/com/mindviewinc/simple/List.java | 12 - code/com/mindviewinc/simple/Vector.java | 12 - code/compression/GZIPcompress.java | 45 -- code/compression/ZipCompress.java | 83 ---- code/concurrent/Baked.java | 31 -- code/concurrent/Batter.java | 34 -- code/concurrent/Breakable.java | 29 -- code/concurrent/CachedThreadPool.java | 29 -- code/concurrent/CachedThreadPool2.java | 29 -- code/concurrent/CachedThreadPool3.java | 47 -- .../CatchCompletableExceptions.java | 81 ---- code/concurrent/CollectionIntoStream.java | 36 -- code/concurrent/CompletableApply.java | 27 -- code/concurrent/CompletableApplyAsync.java | 31 -- code/concurrent/CompletableApplyChained.java | 27 -- code/concurrent/CompletableExceptions.java | 75 ---- code/concurrent/CompletableOperations.java | 74 ---- code/concurrent/CompletablePizza.java | 87 ---- code/concurrent/CompletableUtilities.java | 27 -- code/concurrent/CompletedMachina.java | 19 - code/concurrent/CountingStream.java | 32 -- code/concurrent/CountingTask.java | 19 - code/concurrent/DiningPhilosophers.java | 33 -- .../concurrent/DualCompletableOperations.java | 115 ----- code/concurrent/FrostedCake.java | 32 -- code/concurrent/Futures.java | 23 - code/concurrent/GuardedIDField.java | 18 - code/concurrent/HasID.java | 8 - code/concurrent/IDChecker.java | 41 -- code/concurrent/InterferingTask.java | 17 - .../LambdasAndMethodReferences.java | 40 -- code/concurrent/Machina.java | 31 -- code/concurrent/MoreTasksAfterShutdown.java | 27 -- code/concurrent/NapTask.java | 20 - code/concurrent/OnePizza.java | 26 -- code/concurrent/ParallelPrime.java | 35 -- code/concurrent/ParallelStreamPuzzle.java | 28 -- code/concurrent/ParallelStreamPuzzle2.java | 38 -- code/concurrent/ParallelStreamPuzzle3.java | 33 -- code/concurrent/Philosopher.java | 30 -- code/concurrent/Pizza.java | 49 --- code/concurrent/PizzaParallelSteps.java | 69 --- code/concurrent/PizzaStreams.java | 60 --- code/concurrent/QuittableTask.java | 20 - code/concurrent/QuittingCompletable.java | 35 -- code/concurrent/QuittingTasks.java | 35 -- .../concurrent/SharedConstructorArgument.java | 44 -- code/concurrent/SingleThreadExecutor.java | 49 --- code/concurrent/SingleThreadExecutor2.java | 30 -- code/concurrent/SingleThreadExecutor3.java | 30 -- code/concurrent/StaticIDField.java | 10 - code/concurrent/StickHolder.java | 27 -- code/concurrent/StreamExceptions.java | 40 -- code/concurrent/Summing.java | 47 -- code/concurrent/Summing2.java | 44 -- code/concurrent/Summing3.java | 42 -- code/concurrent/Summing4.java | 23 - code/concurrent/SynchronizedConstructor.java | 29 -- code/concurrent/SynchronizedFactory.java | 29 -- code/concurrent/TestStaticIDField.java | 13 - code/concurrent/ThrowsChecked.java | 42 -- code/concurrent/Workable.java | 32 -- code/control/BreakAndContinue.java | 38 -- code/control/CommaOperator.java | 18 - code/control/ForInFloat.java | 28 -- code/control/ForInInt.java | 28 -- code/control/ForInString.java | 14 - code/control/IfElse.java | 29 -- code/control/LabeledFor.java | 65 --- code/control/LabeledWhile.java | 51 --- code/control/ListCharacters.java | 27 -- code/control/RandomBounds.java | 30 -- code/control/StringSwitch.java | 44 -- code/control/TestWithReturn.java | 24 - code/control/TrueFalse.java | 15 - code/control/VowelsAndConsonants.java | 44 -- code/control/WhileTest.java | 31 -- code/enums/AlarmPoints.java | 9 - code/enums/BigEnumSet.java | 29 -- code/enums/Burrito2.java | 28 -- code/enums/CarWash.java | 88 ---- code/enums/Competitor.java | 10 - code/enums/ConstantSpecificMethod.java | 41 -- code/enums/EnumClass.java | 51 --- code/enums/EnumMaps.java | 37 -- code/enums/EnumSets.java | 39 -- code/enums/Input.java | 33 -- code/enums/NonEnum.java | 19 - code/enums/NotClasses.java | 50 --- code/enums/Outcome.java | 6 - code/enums/OverrideConstantSpecific.java | 28 -- code/enums/OzWitch.java | 32 -- code/enums/PostOffice.java | 197 --------- code/enums/RandomTest.java | 21 - code/enums/Reflection.java | 71 --- code/enums/RoShamBo.java | 21 - code/enums/RoShamBo1.java | 104 ----- code/enums/RoShamBo2.java | 55 --- code/enums/RoShamBo3.java | 71 --- code/enums/RoShamBo4.java | 57 --- code/enums/RoShamBo5.java | 59 --- code/enums/RoShamBo6.java | 46 -- code/enums/SecurityCategory.java | 46 -- code/enums/SpaceShip.java | 28 -- code/enums/SpicinessEnum.java | 9 - code/enums/TrafficLight.java | 44 -- code/enums/UpcastEnum.java | 21 - code/enums/VendingMachine.java | 183 -------- code/enums/VendingMachineInput.txt | 8 - code/enums/cartoons/EnumImplementation.java | 37 -- code/enums/menu/Course.java | 20 - code/enums/menu/Food.java | 24 - code/enums/menu/Meal.java | 45 -- code/enums/menu/Meal2.java | 74 ---- code/enums/menu/TypeOfFood.java | 16 - code/equalshashcode/ComposedEquality.java | 66 --- code/equalshashcode/CountedString.java | 72 --- code/equalshashcode/DefaultComparison.java | 24 - code/equalshashcode/Equality.java | 77 ---- code/equalshashcode/EqualityFactory.java | 9 - code/equalshashcode/Groundhog.java | 14 - code/equalshashcode/Groundhog2.java | 19 - code/equalshashcode/IndividualTest.java | 31 -- code/equalshashcode/MapEntry.java | 42 -- code/equalshashcode/Prediction.java | 15 - code/equalshashcode/SimpleHashMap.java | 90 ---- code/equalshashcode/SlowMap.java | 64 --- code/equalshashcode/SpringDetector.java | 62 --- code/equalshashcode/SpringDetector2.java | 25 -- code/equalshashcode/StringHashCode.java | 16 - code/equalshashcode/SubtypeEquality.java | 60 --- code/equalshashcode/SubtypeEquality2.java | 40 -- code/equalshashcode/SuccinctEquality.java | 46 -- code/exceptions/AlwaysFinally.java | 33 -- code/exceptions/AutoCloseableDetails.java | 33 -- code/exceptions/BodyException.java | 32 -- code/exceptions/Cleanup.java | 30 -- code/exceptions/CleanupIdiom.java | 72 --- code/exceptions/CloseExceptions.java | 48 -- code/exceptions/ConstructorException.java | 33 -- code/exceptions/DynamicFields.java | 130 ------ code/exceptions/ExceptionMethods.java | 32 -- code/exceptions/ExceptionSilencer.java | 16 - code/exceptions/ExtraFeatures.java | 72 --- code/exceptions/FinallyWorks.java | 32 -- code/exceptions/FullConstructors.java | 44 -- code/exceptions/Human.java | 31 -- code/exceptions/InheritingExceptions.java | 28 -- code/exceptions/InputFile.java | 47 -- code/exceptions/InputFile2.java | 28 -- code/exceptions/LoggingExceptions.java | 48 -- code/exceptions/LoggingExceptions2.java | 32 -- code/exceptions/LostMessage.java | 44 -- code/exceptions/MainException.java | 17 - code/exceptions/MessyExceptions.java | 27 -- code/exceptions/MultiCatch.java | 16 - code/exceptions/MultiCatch2.java | 19 - code/exceptions/MultipleReturns.java | 47 -- code/exceptions/NeverCaught.java | 26 -- code/exceptions/OnOffException1.java | 5 - code/exceptions/OnOffException2.java | 5 - code/exceptions/OnOffSwitch.java | 29 -- code/exceptions/PreciseRethrow.java | 17 - code/exceptions/RethrowNew.java | 47 -- code/exceptions/Rethrowing.java | 70 --- code/exceptions/SameHandler.java | 31 -- code/exceptions/StormyInning.java | 83 ---- code/exceptions/StreamsAreAutoCloseable.java | 24 - code/exceptions/Switch.java | 21 - code/exceptions/TryAnything.java | 16 - code/exceptions/TryWithResources.java | 19 - code/exceptions/TurnOffChecking.java | 64 --- code/exceptions/WhoCalled.java | 39 -- code/exceptions/WithFinally.java | 26 -- code/files/AddAndSubtractPaths.java | 87 ---- code/files/Directories.java | 94 ---- code/files/FileSystemDemo.java | 41 -- code/files/Find.java | 60 --- code/files/ListOfLines.java | 26 -- code/files/PartsOfPaths.java | 45 -- code/files/PathAnalysis.java | 56 --- code/files/PathInfo.java | 102 ----- code/files/PathWatcher.java | 61 --- code/files/ReadLineStream.java | 18 - code/files/StreamInAndOut.java | 24 - code/files/TreeWatcher.java | 51 --- code/files/Writing.java | 31 -- code/functional/AnonymousClosure.java | 17 - code/functional/BiConsumerPermutations.java | 24 - code/functional/ClassFunctionals.java | 45 -- code/functional/Closure1.java | 12 - code/functional/Closure2.java | 12 - code/functional/Closure3.java | 14 - code/functional/Closure4.java | 12 - code/functional/Closure5.java | 15 - code/functional/Closure6.java | 16 - code/functional/Closure7.java | 14 - code/functional/Closure8.java | 32 -- code/functional/Closure9.java | 15 - code/functional/ConsumeFunction.java | 17 - code/functional/CtorReference.java | 36 -- code/functional/CurriedIntAdd.java | 17 - code/functional/Curry3Args.java | 23 - code/functional/CurryingAndPartials.java | 35 -- code/functional/FunctionComposition.java | 24 - code/functional/FunctionVariants.java | 65 --- code/functional/FunctionWithWrapped.java | 12 - code/functional/FunctionalAnnotation.java | 40 -- code/functional/IntCall.java | 8 - code/functional/LambdaExpressions.java | 48 -- code/functional/MethodConversion.java | 31 -- code/functional/MethodReferences.java | 53 --- code/functional/MultiUnbound.java | 36 -- code/functional/PredicateComposition.java | 23 - code/functional/ProduceFunction.java | 21 - code/functional/RecursiveFactorial.java | 26 -- code/functional/RecursiveFibonacci.java | 32 -- code/functional/RunnableMethodReference.java | 33 -- code/functional/SharedStorage.java | 22 - code/functional/Strategize.java | 58 --- code/functional/TransformFunction.java | 35 -- code/functional/TriFunction.java | 9 - code/functional/TriFunctionTest.java | 13 - code/functional/UnboundMethodReference.java | 31 -- code/generics/Amphibian.java | 5 - code/generics/Apply.java | 21 - code/generics/ApplyFunctional.java | 49 --- code/generics/ApplyTest.java | 65 --- code/generics/ArrayMaker.java | 24 - code/generics/ArrayOfGeneric.java | 28 -- code/generics/ArrayOfGenericReference.java | 10 - code/generics/BankTeller.java | 71 --- code/generics/BasicBounds.java | 63 --- code/generics/BasicHolder.java | 14 - code/generics/BasicSupplierDemo.java | 22 - code/generics/ByteSet.java | 14 - code/generics/CRGWithBasicHolder.java | 20 - code/generics/CaptureConversion.java | 62 --- code/generics/CheckedList.java | 35 -- code/generics/ClassCasting.java | 18 - code/generics/ClassTypeCapture.java | 33 -- code/generics/ComparablePet.java | 12 - code/generics/CompilerIntelligence.java | 15 - code/generics/CountedObject.java | 14 - code/generics/CovariantArrays.java | 30 -- code/generics/CovariantReturnTypes.java | 23 - code/generics/CreatorGeneric.java | 31 -- code/generics/CuriouslyRecurringGeneric.java | 9 - code/generics/Diamond.java | 13 - .../DogsAndRobotMethodReferences.java | 45 -- code/generics/DogsAndRobots.cpp | 38 -- code/generics/DogsAndRobots.java | 41 -- code/generics/DogsAndRobots.py | 36 -- code/generics/DynamicProxyMixin.java | 66 --- code/generics/EpicBattle.java | 74 ---- code/generics/Erased.java | 24 - code/generics/ErasedTypeEquivalence.java | 16 - code/generics/ErasureAndInheritance.java | 28 -- code/generics/FactoryConstraint.java | 62 --- code/generics/Fibonacci.java | 27 -- code/generics/FilledList.java | 28 -- code/generics/GenericArray.java | 32 -- code/generics/GenericArray2.java | 39 -- code/generics/GenericArrayWithTypeToken.java | 27 -- code/generics/GenericCast.java | 47 -- code/generics/GenericHolder.java | 19 - code/generics/GenericHolder2.java | 16 - code/generics/GenericMethods.java | 27 -- code/generics/GenericReading.java | 46 -- code/generics/GenericVarargs.java | 30 -- code/generics/GenericsAndCovariance.java | 19 - code/generics/GenericsAndReturnTypes.java | 17 - code/generics/HasF.java | 10 - code/generics/HijackedInterface.java | 16 - code/generics/Holder.java | 42 -- code/generics/Holder1.java | 12 - code/generics/InheritBounds.java | 40 -- code/generics/InstantiateGenericType.cpp | 20 - code/generics/InstantiateGenericType.java | 46 -- code/generics/IterableFibonacci.java | 36 -- code/generics/LatentReflection.java | 65 --- code/generics/LinkedStack.java | 43 -- code/generics/ListMaker.java | 13 - code/generics/ListOfGenerics.java | 11 - code/generics/ListOfInt.java | 20 - code/generics/LostInformation.java | 33 -- code/generics/Manipulation.java | 21 - code/generics/Manipulator2.java | 10 - code/generics/Manipulator3.java | 10 - code/generics/Mixins.cpp | 47 -- code/generics/Mixins.java | 71 --- code/generics/MultipleInterfaceVariants.java | 13 - code/generics/NeedCasting.java | 15 - code/generics/NonCovariantGenerics.java | 11 - code/generics/NotSelfBounded.java | 24 - code/generics/ObjectHolder.java | 20 - code/generics/OrdinaryArguments.java | 31 -- code/generics/Performs.java | 9 - code/generics/PlainGenericInheritance.java | 30 -- code/generics/PrimitiveGenericTest.java | 42 -- code/generics/RandomList.java | 26 -- code/generics/RestrictedComparablePets.java | 19 - code/generics/ReturnGenericType.java | 10 - code/generics/SelfBounding.java | 40 -- .../SelfBoundingAndCovariantArguments.java | 31 -- code/generics/SelfBoundingMethods.java | 13 - code/generics/Shape.java | 19 - code/generics/SimpleDogsAndRobots.java | 25 -- code/generics/SimpleHolder.java | 15 - code/generics/SimpleQueue.java | 16 - code/generics/Square.java | 5 - code/generics/Store.java | 90 ---- code/generics/SuperTypeWildcards.java | 13 - code/generics/Templates.cpp | 27 -- code/generics/ThrowGenericException.java | 82 ---- code/generics/TupleList.java | 23 - code/generics/TupleTest.java | 42 -- code/generics/TupleTest2.java | 42 -- code/generics/UnboundedWildcards1.java | 58 --- code/generics/UnboundedWildcards2.java | 35 -- code/generics/Unconstrained.java | 20 - code/generics/UseList.java | 11 - code/generics/UseList2.java | 10 - code/generics/Vehicle.java | 5 - code/generics/WatercolorSets.java | 54 --- code/generics/Wildcards.java | 285 ------------ code/generics/coffee/Americano.java | 6 - code/generics/coffee/Breve.java | 6 - code/generics/coffee/Cappuccino.java | 6 - code/generics/coffee/Coffee.java | 14 - code/generics/coffee/CoffeeSupplier.java | 72 --- code/generics/coffee/Latte.java | 6 - code/generics/coffee/Mocha.java | 6 - code/generics/decorator/Decoration.java | 51 --- code/generics/dogsandrobots.go | 32 -- code/generics/watercolors/Watercolors.java | 15 - code/gradle.properties | 1 - code/gradle/checkstyle.gradle | 14 - code/gradle/findbugs.gradle | 15 - code/gradle/java.gradle | 39 -- code/gradle/jmh.gradle | 17 - code/gradle/junit-jupiter.gradle | 72 --- code/gradle/subprojects.gradle | 67 --- code/gradle/wrapper/gradle-wrapper.jar | Bin 59203 -> 0 bytes code/gradle/wrapper/gradle-wrapper.properties | 5 - code/gradlew | 185 -------- code/gradlew.bat | 89 ---- code/hiding/Cake.java | 15 - code/hiding/ChocolateChip.java | 23 - code/hiding/ChocolateChip2.java | 21 - code/hiding/CreatePackageAccessObject.java | 12 - code/hiding/Dinner.java | 16 - code/hiding/FullQualification.java | 11 - code/hiding/IceCream.java | 19 - code/hiding/ImportedMyClass.java | 11 - code/hiding/LibTest.java | 17 - code/hiding/Lunch.java | 36 -- code/hiding/OrganizedByAccess.java | 15 - code/hiding/Pie.java | 9 - code/hiding/QualifiedMyClass.java | 11 - code/hiding/SingleImport.java | 11 - code/hiding/cookie2/Cookie.java | 14 - code/hiding/dessert/Cookie.java | 13 - code/hiding/mypackage/MyClass.java | 9 - .../packageaccess/PublicConstructor.java | 9 - code/housekeeping/Apricot.java | 8 - code/housekeeping/ArrayClassObj.java | 22 - code/housekeeping/ArrayInit.java | 25 -- code/housekeeping/ArrayNew.java | 20 - code/housekeeping/ArraysOfPrimitives.java | 23 - code/housekeeping/AutoboxingVarargs.java | 22 - code/housekeeping/BananaPeel.java | 15 - code/housekeeping/Burrito.java | 39 -- code/housekeeping/Counter.java | 9 - code/housekeeping/DefaultConstructor.java | 12 - code/housekeeping/Demotion.java | 43 -- code/housekeeping/DynamicArray.java | 21 - code/housekeeping/EnumOrder.java | 19 - code/housekeeping/ExplicitStatic.java | 41 -- code/housekeeping/Flower.java | 46 -- code/housekeeping/InitialValues.java | 44 -- code/housekeeping/InitialValues2.java | 16 - code/housekeeping/Leaf.java | 23 - code/housekeeping/Measurement.java | 10 - code/housekeeping/MethodInit.java | 8 - code/housekeeping/MethodInit2.java | 10 - code/housekeeping/MethodInit3.java | 10 - code/housekeeping/Mugs.java | 47 -- code/housekeeping/NewVarArgs.java | 30 -- code/housekeeping/NoSynthesis.java | 17 - .../OptionalTrailingArguments.java | 23 - code/housekeeping/OrderOfInitialization.java | 40 -- code/housekeeping/Overloading.java | 56 --- code/housekeeping/OverloadingOrder.java | 22 - code/housekeeping/OverloadingVarargs.java | 37 -- code/housekeeping/OverloadingVarargs2.java | 18 - code/housekeeping/OverloadingVarargs3.java | 21 - code/housekeeping/PassingThis.java | 31 -- code/housekeeping/PrimitiveOverloading.java | 120 ----- code/housekeeping/SimpleConstructor.java | 21 - code/housekeeping/SimpleConstructor2.java | 21 - code/housekeeping/SimpleEnumUse.java | 14 - code/housekeeping/Spiciness.java | 8 - code/housekeeping/Spoon.java | 10 - code/housekeeping/StaticInitialization.java | 73 ---- code/housekeeping/TerminationCondition.java | 41 -- code/housekeeping/VarArgs.java | 26 -- code/housekeeping/VarargType.java | 30 -- code/innerclasses/AnonymousConstructor.java | 34 -- code/innerclasses/BigEgg.java | 33 -- code/innerclasses/BigEgg2.java | 44 -- code/innerclasses/Callbacks.java | 84 ---- code/innerclasses/ClassInInterface.java | 21 - code/innerclasses/Contents.java | 7 - code/innerclasses/Destination.java | 7 - code/innerclasses/DotNew.java | 13 - code/innerclasses/DotThis.java | 24 - code/innerclasses/GreenhouseController.java | 54 --- code/innerclasses/GreenhouseControls.java | 150 ------- code/innerclasses/InheritInner.java | 20 - code/innerclasses/LocalInnerClass.java | 67 --- code/innerclasses/MultiImplementation.java | 25 -- code/innerclasses/MultiNestingAccess.java | 28 -- code/innerclasses/Parcel1.java | 33 -- code/innerclasses/Parcel10.java | 31 -- code/innerclasses/Parcel11.java | 40 -- code/innerclasses/Parcel2.java | 41 -- code/innerclasses/Parcel3.java | 25 -- code/innerclasses/Parcel5.java | 23 - code/innerclasses/Parcel6.java | 28 -- code/innerclasses/Parcel7.java | 19 - code/innerclasses/Parcel7b.java | 20 - code/innerclasses/Parcel8.java | 21 - code/innerclasses/Parcel9.java | 20 - code/innerclasses/Sequence.java | 48 -- code/innerclasses/TestBed.java | 19 - code/innerclasses/TestParcel.java | 37 -- code/innerclasses/Wrapping.java | 9 - code/innerclasses/controller/Controller.java | 24 - code/innerclasses/controller/Event.java | 23 - code/innerclasses/mui/MultiInterfaces.java | 32 -- code/interfaces/AbstractAccess.java | 15 - code/interfaces/AbstractWithoutAbstracts.java | 14 - code/interfaces/AdaptedRandomDoubles.java | 35 -- code/interfaces/Adventure.java | 41 -- code/interfaces/AnImplementation.java | 22 - code/interfaces/AnInterface.java | 9 - code/interfaces/Applicator.java | 58 --- code/interfaces/AttemptToUseBasic.java | 10 - code/interfaces/Basic.java | 8 - code/interfaces/Basic2.java | 10 - code/interfaces/Factories.java | 67 --- code/interfaces/Games.java | 59 --- code/interfaces/HorrorShow.java | 57 --- code/interfaces/Implementation2.java | 26 -- code/interfaces/ImplementingAnInterface.java | 14 - code/interfaces/Instantiable.java | 19 - code/interfaces/InterfaceCollision.java | 31 -- code/interfaces/InterfaceWithDefault.java | 12 - code/interfaces/Jim.java | 28 -- code/interfaces/MICollision.java | 60 --- code/interfaces/Machine.java | 36 -- code/interfaces/Months.java | 13 - code/interfaces/MultipleInheritance.java | 35 -- code/interfaces/PureInterface.java | 11 - code/interfaces/RandVals.java | 15 - code/interfaces/RandomDoubles.java | 21 - code/interfaces/RandomStrings.java | 50 --- code/interfaces/TestRandVals.java | 19 - code/interfaces/filters/BandPass.java | 17 - code/interfaces/filters/Filter.java | 14 - code/interfaces/filters/HighPass.java | 16 - code/interfaces/filters/LowPass.java | 16 - code/interfaces/filters/Waveform.java | 14 - .../interfaceprocessor/Applicator.java | 12 - .../interfaceprocessor/FilterProcessor.java | 40 -- .../interfaceprocessor/Processor.java | 12 - .../interfaceprocessor/StringProcessor.java | 50 --- code/interfaces/music4/Music4.java | 105 ----- code/interfaces/music5/Music5.java | 74 ---- .../interfaces/nesting/NestingInterfaces.java | 105 ----- code/iostreams/BasicFileOutput.java | 26 -- code/iostreams/BufferedInputFile.java | 23 - code/iostreams/FileOutputShortcut.java | 24 - code/iostreams/FormattedMemoryInput.java | 25 -- code/iostreams/MemoryInput.java | 17 - code/iostreams/StoringAndRecoveringData.java | 42 -- code/iostreams/TestEOF.java | 22 - code/iostreams/UsingRandomAccessFile.java | 65 --- code/javadoc/Documentation1.java | 11 - code/javadoc/Documentation2.java | 9 - code/javadoc/Documentation3.java | 12 - code/javadoc/HelloDateDoc.java | 26 -- code/lowlevel/AtomicEvenProducer.java | 21 - code/lowlevel/AtomicIntegerTest.java | 20 - code/lowlevel/AtomicSerialNumbers.java | 21 - code/lowlevel/Atomicity.java | 20 - code/lowlevel/AttemptLocking.java | 57 --- code/lowlevel/CaptureUncaughtException.java | 56 --- code/lowlevel/CircularSet.java | 29 -- code/lowlevel/DelayQueueDemo.java | 99 ----- code/lowlevel/EvenChecker.java | 41 -- code/lowlevel/EvenProducer.java | 26 -- code/lowlevel/ExceptionThread.java | 30 -- code/lowlevel/IntGenerator.java | 15 - code/lowlevel/IntTestable.java | 15 - code/lowlevel/MutexEvenProducer.java | 30 -- code/lowlevel/NaiveExceptionHandling.java | 32 -- code/lowlevel/NotAtomic.java | 49 --- code/lowlevel/NumberOfProcessors.java | 14 - code/lowlevel/PriorityBlockingQueueDemo.java | 139 ------ code/lowlevel/ReOrdering.java | 19 - code/lowlevel/SafeReturn.java | 20 - code/lowlevel/SerialNumberChecker.java | 32 -- code/lowlevel/SerialNumberTest.java | 13 - code/lowlevel/SerialNumbers.java | 11 - code/lowlevel/SettingDefaultHandler.java | 19 - code/lowlevel/SwallowedException.java | 17 - code/lowlevel/SyncOnObject.java | 70 --- code/lowlevel/SynchronizedComparison.java | 89 ---- code/lowlevel/SynchronizedEvenProducer.java | 24 - code/lowlevel/SynchronizedSerialNumbers.java | 19 - code/lowlevel/TestAbort.java | 17 - code/lowlevel/ThreadSize.java | 31 -- code/lowlevel/UnsafeReturn.java | 20 - code/lowlevel/WorkStealingPool.java | 41 -- code/newio/AvailableCharSets.java | 43 -- code/newio/BufferToText.java | 93 ---- code/newio/ChannelCopy.java | 35 -- code/newio/Endians.java | 28 -- code/newio/FileLocking.java | 30 -- code/newio/GetChannel.java | 53 --- code/newio/GetData.java | 56 --- code/newio/IntBufferDemo.java | 35 -- code/newio/LargeMappedFiles.java | 31 -- code/newio/LockingMappedFiles.java | 60 --- code/newio/MappedIO.java | 145 ------ code/newio/TransferTo.java | 30 -- code/newio/UsingBuffers.java | 35 -- code/newio/ViewBuffers.java | 69 --- code/objects/HelloDate.java | 12 - code/objects/ShowProperties.java | 39 -- code/onjava/ArrayShow.java | 73 ---- code/onjava/BasicSupplier.java | 31 -- code/onjava/CollectionMethodDifferences.java | 117 ----- code/onjava/ConvertTo.java | 105 ----- code/onjava/Count.java | 220 ---------- code/onjava/CountMap.java | 97 ----- code/onjava/CountingIntegerList.java | 34 -- code/onjava/Countries.java | 351 --------------- code/onjava/Enums.java | 17 - code/onjava/FillMap.java | 38 -- code/onjava/HTMLColors.java | 236 ---------- code/onjava/MouseClick.java | 19 - code/onjava/Nap.java | 20 - code/onjava/Null.java | 6 - code/onjava/OSExecute.java | 37 -- code/onjava/OSExecuteException.java | 12 - code/onjava/Operations.java | 17 - code/onjava/Pair.java | 19 - code/onjava/ProcessFiles.java | 48 -- code/onjava/Rand.java | 248 ----------- code/onjava/Range.java | 34 -- code/onjava/Repeat.java | 12 - code/onjava/RmDir.java | 31 -- code/onjava/Sets.java | 32 -- code/onjava/Stack.java | 20 - code/onjava/Suppliers.java | 36 -- code/onjava/TimedAbort.java | 30 -- code/onjava/Timer.java | 19 - code/onjava/Tuple.java | 24 - code/onjava/Tuple2.java | 16 - code/onjava/Tuple3.java | 17 - code/onjava/Tuple4.java | 18 - code/onjava/Tuple5.java | 18 - code/onjava/TypeCounter.java | 41 -- code/onjava/atunit/AtUnit.java | 177 -------- code/onjava/atunit/ClassNameFinder.java | 180 -------- code/onjava/atunit/Test.java | 11 - code/onjava/atunit/TestObjectCleanup.java | 11 - code/onjava/atunit/TestObjectCreate.java | 11 - code/onjava/atunit/TestProperty.java | 12 - code/operators/AllOps.java | 411 ------------------ code/operators/Assignment.java | 31 -- code/operators/AutoInc.java | 27 -- code/operators/BitManipulation.java | 98 ----- code/operators/Bool.java | 42 -- code/operators/Casting.java | 16 - code/operators/CastingNumbers.java | 23 - code/operators/EqualsMethod.java | 15 - code/operators/EqualsMethod2.java | 21 - code/operators/Equivalence.java | 17 - code/operators/Exponents.java | 21 - code/operators/Literals.java | 61 --- code/operators/MathOps.java | 75 ---- code/operators/Overflow.java | 18 - code/operators/PassObject.java | 27 -- code/operators/Precedence.java | 18 - code/operators/RoundingNumbers.java | 26 -- code/operators/ShortCircuit.java | 34 -- code/operators/StringOperators.java | 24 - code/operators/TernaryIfElse.java | 28 -- code/operators/URShift.java | 42 -- code/operators/Underscores.java | 22 - code/patterns/BoxObserver.java | 94 ---- code/patterns/CommandPattern.java | 19 - code/patterns/Facade.java | 24 - code/patterns/PaperScissorsRock.java | 135 ------ code/patterns/ProxyDemo.java | 51 --- code/patterns/ShapeFactory1.java | 39 -- code/patterns/ShapeFactory2.java | 54 --- code/patterns/ShapeFactory3.java | 52 --- code/patterns/SingletonPattern.java | 58 --- code/patterns/StateDemo.java | 87 ---- code/patterns/TemplateMethod.java | 44 -- .../abstractfactory/GameEnvironment.java | 96 ---- code/patterns/adapt/Adapter.java | 85 ---- .../patterns/chain/ChainOfResponsibility.java | 90 ---- code/patterns/doubledispatch/Aluminum.java | 18 - code/patterns/doubledispatch/Cardboard.java | 18 - .../doubledispatch/DoubleDispatch.java | 96 ---- code/patterns/doubledispatch/Glass.java | 18 - code/patterns/doubledispatch/Paper.java | 18 - code/patterns/doubledispatch/TypedBin.java | 28 -- .../doubledispatch/TypedBinMember.java | 14 - code/patterns/dynatrash/DynaTrash.java | 74 ---- code/patterns/observer/ObservedFlower.java | 125 ------ code/patterns/recyclea/RecycleA.java | 127 ------ code/patterns/recycleb/RecycleB.java | 56 --- code/patterns/recyclec/RecycleC.java | 84 ---- code/patterns/shapes/BadShapeCreation.java | 12 - code/patterns/shapes/Circle.java | 7 - code/patterns/shapes/FactoryMethod.java | 9 - code/patterns/shapes/FactoryTest.java | 17 - code/patterns/shapes/Shape.java | 21 - code/patterns/shapes/Square.java | 7 - code/patterns/shapes/Triangle.java | 7 - code/patterns/state/StateMachineDemo.java | 80 ---- code/patterns/strategy/StrategyPattern.java | 64 --- code/patterns/strategy/StrategyPattern2.java | 43 -- code/patterns/trash/Aluminum.java | 15 - code/patterns/trash/Cardboard.java | 15 - code/patterns/trash/Fillable.java | 10 - code/patterns/trash/FillableList.java | 17 - code/patterns/trash/Glass.java | 15 - code/patterns/trash/Paper.java | 15 - code/patterns/trash/ParseTrash.java | 91 ---- code/patterns/trash/Trash.dat | 35 -- code/patterns/trash/Trash.java | 92 ---- code/patterns/trashvisitor/Aluminum.java | 16 - code/patterns/trashvisitor/Cardboard.java | 16 - code/patterns/trashvisitor/Glass.java | 16 - code/patterns/trashvisitor/Paper.java | 16 - code/patterns/trashvisitor/TrashVisitor.java | 127 ------ code/patterns/trashvisitor/Visitable.java | 12 - code/patterns/trashvisitor/Visitor.java | 14 - code/patterns/visitor/BeeAndFlowers.java | 122 ------ code/polymorphism/CovariantReturn.java | 38 -- code/polymorphism/FieldAccess.java | 36 -- code/polymorphism/Frog.java | 122 ------ code/polymorphism/PolyConstructors.java | 41 -- code/polymorphism/PrivateOverride.java | 24 - code/polymorphism/PrivateOverride2.java | 22 - code/polymorphism/RTTI.java | 43 -- code/polymorphism/ReferenceCounting.java | 71 --- code/polymorphism/Sandwich.java | 54 --- code/polymorphism/Shapes.java | 26 -- code/polymorphism/StaticPolymorphism.java | 36 -- code/polymorphism/Transmogrify.java | 43 -- code/polymorphism/music/Instrument.java | 11 - code/polymorphism/music/Music.java | 21 - code/polymorphism/music/Music2.java | 46 -- code/polymorphism/music/Note.java | 10 - code/polymorphism/music/Wind.java | 15 - code/polymorphism/music3/Music3.java | 108 ----- code/polymorphism/shape/Circle.java | 16 - code/polymorphism/shape/RandomShapes.java | 26 -- code/polymorphism/shape/Shape.java | 10 - code/polymorphism/shape/Square.java | 16 - code/polymorphism/shape/Triangle.java | 16 - code/references/AddingClone.java | 67 --- code/references/Alias1.java | 27 -- code/references/Alias2.java | 25 -- code/references/CheckCloneable.java | 113 ----- code/references/CloneArrayList.java | 38 -- code/references/Compete.java | 89 ---- code/references/CopyConstructor.java | 188 -------- code/references/DepthReading.java | 29 -- code/references/HorrorFlick.java | 35 -- code/references/Immutable1.java | 34 -- code/references/Immutable2.java | 71 --- code/references/ImmutableInteger.java | 22 - code/references/ImmutableStrings.java | 25 -- code/references/LocalCopy.java | 57 --- code/references/MutableInteger.java | 34 -- code/references/OceanReading.java | 48 -- code/references/PassReferences.java | 19 - code/references/SimplerMutableInteger.java | 30 -- code/references/Snake.java | 51 --- code/references/Stringer.java | 22 - code/references/TemperatureReading.java | 33 -- code/references/tests/DeepCopyTest.java | 28 -- code/reuse/Bath.java | 61 --- code/reuse/Beetle.java | 43 -- code/reuse/BlankFinal.java | 29 -- code/reuse/CADSystem.java | 116 ----- code/reuse/Car.java | 43 -- code/reuse/Cartoon.java | 31 -- code/reuse/Chess.java | 33 -- code/reuse/DerivedSpaceShip.java | 19 - code/reuse/Detergent.java | 48 -- code/reuse/FinalArguments.java | 27 -- code/reuse/FinalData.java | 57 --- code/reuse/FinalOverridingIllusion.java | 56 --- code/reuse/Hide.java | 41 -- code/reuse/Jurassic.java | 26 -- code/reuse/Lisa.java | 11 - code/reuse/Orc.java | 41 -- code/reuse/PlaceSetting.java | 82 ---- code/reuse/SpaceShipControls.java | 14 - code/reuse/SpaceShipDelegation.java | 40 -- code/reuse/SprinklerSystem.java | 41 -- code/reuse/Wind.java | 22 - code/serialization/APerson.java | 83 ---- code/serialization/AStoreCADState.java | 120 ----- code/serialization/Alien.java | 7 - code/serialization/Blip3.java | 75 ---- code/serialization/Blips.java | 80 ---- code/serialization/FreezeAlien.java | 19 - code/serialization/Logon.java | 62 --- code/serialization/MyWorld.java | 100 ----- code/serialization/People.java | 28 -- code/serialization/RecoverCADState.java | 42 -- code/serialization/SerialCtl.java | 60 --- code/serialization/Worm.java | 102 ----- code/serialization/xfiles/ThawAlien.java | 22 - code/settings.gradle | 13 - code/standardio/ChangeSystemOut.java | 17 - code/standardio/Echo.java | 20 - code/standardio/OSExecuteDemo.java | 16 - code/standardio/Redirecting.java | 31 -- code/staticchecking/DogsAndRobots.cpp | 33 -- code/staticchecking/DogsAndRobots.py | 26 -- code/staticchecking/NoBasePetSpeak.py | 35 -- code/staticchecking/PetSpeak.py | 28 -- code/staticchecking/dogsandrobots.go | 27 -- code/staticchecking/dr/DogsAndRobots.java | 42 -- .../drc/DogAndRobotCollections.java | 58 --- code/staticchecking/latent/Latent.java | 60 --- code/staticchecking/petspeak.go | 51 --- code/staticchecking/petspeak/PetSpeak.java | 36 -- code/streams/ArrayStreams.java | 31 -- code/streams/Bubble.java | 18 - code/streams/Bubbles.java | 20 - code/streams/Cheese.dat | 6 - code/streams/CollectionToStream.java | 39 -- code/streams/CreatingOptionals.java | 37 -- code/streams/Duplicator.java | 18 - code/streams/Fibonacci.java | 34 -- code/streams/FileToWords.java | 17 - code/streams/FileToWordsBuilder.java | 31 -- code/streams/FileToWordsRegexp.java | 39 -- code/streams/FileToWordsTest.java | 23 - code/streams/FlatMap.java | 25 -- code/streams/ForEach.java | 28 -- code/streams/FunctionMap.java | 60 --- code/streams/FunctionMap2.java | 32 -- code/streams/FunctionMap3.java | 28 -- code/streams/Generator.java | 25 -- code/streams/ImperativeRandoms.java | 21 - code/streams/Informational.java | 27 -- code/streams/LastElement.java | 24 - code/streams/Looping.java | 20 - code/streams/Machine2.java | 23 - code/streams/MapCollector.java | 48 -- code/streams/Matching.java | 38 -- code/streams/NumericStreamInfo.java | 24 - code/streams/OptionalBasics.java | 23 - code/streams/OptionalFilter.java | 72 --- code/streams/OptionalFlatMap.java | 73 ---- code/streams/OptionalMap.java | 74 ---- code/streams/Optionals.java | 63 --- code/streams/OptionalsFromEmptyStreams.java | 31 -- code/streams/Peeking.java | 22 - code/streams/Prime.java | 31 -- code/streams/RandInts.java | 15 - code/streams/RandomGenerators.java | 86 ---- code/streams/RandomWords.java | 41 -- code/streams/Randoms.java | 25 -- code/streams/Ranges.java | 29 -- code/streams/Reduce.java | 44 -- code/streams/SelectElement.java | 24 - code/streams/Signal.java | 29 -- code/streams/SortedComparator.java | 20 - code/streams/SpecialCollector.java | 24 - code/streams/StreamOf.java | 28 -- code/streams/StreamOfOptionals.java | 37 -- code/streams/StreamOfRandoms.java | 20 - code/streams/StreamOfStreams.java | 19 - code/streams/TreeSetOfWords.java | 31 -- code/strings/ArrayListDisplay.java | 22 - code/strings/BetterRead.java | 37 -- code/strings/Concatenation.java | 15 - code/strings/Conversion.java | 113 ----- code/strings/DatabaseException.java | 22 - code/strings/Finding.java | 27 -- code/strings/Groups.java | 40 -- code/strings/Hex.java | 44 -- code/strings/Immutable.java | 22 - code/strings/InfiniteRecursion.java | 22 - code/strings/IntegerMatch.java | 19 - code/strings/JGrep.java | 36 -- code/strings/ReFlags.java | 23 - code/strings/ReceiptBuilder.java | 48 -- code/strings/Replacing.java | 21 - code/strings/ReplacingStringTokenizer.java | 26 -- code/strings/Resetting.java | 23 - code/strings/Rudolph.java | 21 - code/strings/ScannerDelimiter.java | 21 - code/strings/SimpleFormat.java | 22 - code/strings/SimpleRead.java | 43 -- code/strings/SplitDemo.java | 22 - code/strings/Splitting.java | 32 -- code/strings/StartEnd.java | 82 ---- code/strings/TestRegularExpression.java | 44 -- code/strings/TheReplacements.java | 57 --- code/strings/ThreatAnalyzer.java | 36 -- code/strings/Turtle.java | 40 -- code/strings/UsingStringBuilder.java | 37 -- code/strings/WhitherStringBuilder.java | 21 - code/typeinfo/AnonymousImplementation.java | 50 --- code/typeinfo/BoundedClassReferences.java | 13 - code/typeinfo/ClassCasts.java | 16 - code/typeinfo/ClassInitialization.java | 57 --- code/typeinfo/DynamicSupplier.java | 42 -- code/typeinfo/FamilyVsExactType.java | 62 --- code/typeinfo/GenericClassReferences.java | 14 - code/typeinfo/HiddenImplementation.java | 44 -- code/typeinfo/InnerImplementation.java | 49 --- code/typeinfo/InterfaceViolation.java | 27 -- code/typeinfo/ModifyingPrivateFields.java | 49 --- code/typeinfo/NullRobot.java | 63 --- code/typeinfo/Operation.java | 15 - code/typeinfo/Person.java | 49 --- code/typeinfo/PetCount.java | 65 --- code/typeinfo/PetCount2.java | 18 - code/typeinfo/PetCount3.java | 53 --- code/typeinfo/PetCount4.java | 26 -- code/typeinfo/Position.java | 51 --- code/typeinfo/RegisteredFactories.java | 95 ---- code/typeinfo/Robot.java | 22 - code/typeinfo/SelectingMethods.java | 69 --- code/typeinfo/Shapes.java | 39 -- code/typeinfo/ShowMethods.java | 71 --- code/typeinfo/SimpleDynamicProxy.java | 53 --- code/typeinfo/SimpleProxyDemo.java | 57 --- code/typeinfo/SnowRemovalRobot.java | 42 -- code/typeinfo/Staff.java | 63 --- code/typeinfo/SweetShop.java | 42 -- code/typeinfo/WildcardClassReferences.java | 11 - code/typeinfo/interfacea/A.java | 9 - code/typeinfo/packageaccess/HiddenC.java | 29 -- code/typeinfo/pets/Cat.java | 10 - code/typeinfo/pets/Cymric.java | 10 - code/typeinfo/pets/Dog.java | 10 - code/typeinfo/pets/EgyptianMau.java | 10 - code/typeinfo/pets/ForNameCreator.java | 37 -- code/typeinfo/pets/Hamster.java | 10 - code/typeinfo/pets/Individual.java | 46 -- code/typeinfo/pets/LiteralPetCreator.java | 39 -- code/typeinfo/pets/Manx.java | 10 - code/typeinfo/pets/Mouse.java | 10 - code/typeinfo/pets/Mutt.java | 10 - code/typeinfo/pets/Person.java | 9 - code/typeinfo/pets/Pet.java | 10 - code/typeinfo/pets/PetCreator.java | 28 -- code/typeinfo/pets/Pets.java | 30 -- code/typeinfo/pets/Pug.java | 10 - code/typeinfo/pets/Rat.java | 10 - code/typeinfo/pets/Rodent.java | 10 - code/typeinfo/toys/GenericToyTest.java | 23 - code/typeinfo/toys/ToyTest.java | 78 ---- code/validating/Assert1.java | 19 - code/validating/Assert2.java | 20 - code/validating/BadMicroBenchmark.java | 29 -- code/validating/BadMicroBenchmark2.java | 35 -- code/validating/CircularQueue.java | 91 ---- code/validating/CircularQueueException.java | 12 - code/validating/CountedList.java | 16 - code/validating/GuavaAssertions.java | 49 --- code/validating/GuavaPreconditions.java | 125 ------ code/validating/Inverter1.java | 9 - code/validating/Inverter2.java | 19 - code/validating/Inverter3.java | 21 - code/validating/Inverter4.java | 26 -- code/validating/LoaderAssertions.java | 28 -- code/validating/NonNullConstruction.java | 18 - code/validating/SLF4JLevels.java | 29 -- code/validating/SLF4JLogging.java | 17 - code/validating/SimpleDebugging.java | 40 -- code/validating/StringInverter.java | 9 - code/validating/jmh/JMH1.java | 31 -- code/validating/jmh/JMH2.java | 44 -- code/validating/jmh/JMH3.java | 48 -- code/validating/logback.xml | 15 - code/validating/tests/CircularQueueTest.java | 150 ------- code/validating/tests/CountedListTest.java | 101 ----- .../tests/DynamicStringInverterTests.java | 122 ------ .../validating/tests/StringInverterTests.java | 65 --- 1051 files changed, 40784 deletions(-) delete mode 100644 code/.gitattributes delete mode 100644 code/.gitignore delete mode 100644 code/.travisXX.yml delete mode 100644 code/CI.txt delete mode 100644 code/Copyright.txt delete mode 100644 code/README.md delete mode 100644 code/annotations/AUComposition.java delete mode 100644 code/annotations/AUExternalTest.java delete mode 100644 code/annotations/AtUnitExample1.java delete mode 100644 code/annotations/AtUnitExample2.java delete mode 100644 code/annotations/AtUnitExample3.java delete mode 100644 code/annotations/AtUnitExample4.java delete mode 100644 code/annotations/AtUnitExample5.java delete mode 100644 code/annotations/DemoProcessFiles.java delete mode 100644 code/annotations/HashSetTest.java delete mode 100644 code/annotations/PasswordUtils.java delete mode 100644 code/annotations/SimulatingNull.java delete mode 100644 code/annotations/StackL.java delete mode 100644 code/annotations/StackLStringTst.java delete mode 100644 code/annotations/Testable.java delete mode 100644 code/annotations/UseCase.java delete mode 100644 code/annotations/UseCaseTracker.java delete mode 100644 code/annotations/database/Constraints.java delete mode 100644 code/annotations/database/DBTable.java delete mode 100644 code/annotations/database/Member.java delete mode 100644 code/annotations/database/SQLInteger.java delete mode 100644 code/annotations/database/SQLString.java delete mode 100644 code/annotations/database/TableCreator.java delete mode 100644 code/annotations/database/Uniqueness.java delete mode 100644 code/annotations/ifx/ExtractInterface.java delete mode 100644 code/annotations/ifx/IfaceExtractorProcessor.java delete mode 100644 code/annotations/ifx/Multiplier.java delete mode 100644 code/annotations/simplest/Simple.java delete mode 100644 code/annotations/simplest/SimpleProcessor.java delete mode 100644 code/annotations/simplest/SimpleTest.java delete mode 100644 code/appveyorXX.yml delete mode 100644 code/arrays/AlphabeticSearch.java delete mode 100644 code/arrays/ArrayCopying.java delete mode 100644 code/arrays/ArrayOfGenericType.java delete mode 100644 code/arrays/ArrayOfGenerics.java delete mode 100644 code/arrays/ArrayOptions.java delete mode 100644 code/arrays/ArraySearching.java delete mode 100644 code/arrays/AssemblingMultidimensionalArrays.java delete mode 100644 code/arrays/AutoboxingArrays.java delete mode 100644 code/arrays/CollectionComparison.java delete mode 100644 code/arrays/CompType.java delete mode 100644 code/arrays/ComparatorTest.java delete mode 100644 code/arrays/ComparingArrays.java delete mode 100644 code/arrays/CountUpward.java delete mode 100644 code/arrays/FillingArrays.java delete mode 100644 code/arrays/IceCreamFlavors.java delete mode 100644 code/arrays/ModifyExisting.java delete mode 100644 code/arrays/MultiDimWrapperArray.java delete mode 100644 code/arrays/MultidimensionalObjectArrays.java delete mode 100644 code/arrays/MultidimensionalPrimitiveArray.java delete mode 100644 code/arrays/ParallelPrefix1.java delete mode 100644 code/arrays/ParallelPrefix2.java delete mode 100644 code/arrays/ParallelPrefix3.java delete mode 100644 code/arrays/ParallelSetAll.java delete mode 100644 code/arrays/ParameterizedArrayType.java delete mode 100644 code/arrays/PythonLists.py delete mode 100644 code/arrays/RaggedArray.java delete mode 100644 code/arrays/Reverse.java delete mode 100644 code/arrays/SimpleSetAll.java delete mode 100644 code/arrays/StreamFromArray.java delete mode 100644 code/arrays/StringSorting.java delete mode 100644 code/arrays/TestConvertTo.java delete mode 100644 code/arrays/TestCount.java delete mode 100644 code/arrays/TestRand.java delete mode 100644 code/arrays/ThreeDWithNew.java delete mode 100644 code/arrays/jmh/ParallelSort.java delete mode 100644 code/build.gradle delete mode 100644 code/checkstyle.xml delete mode 100644 code/chkstyle.bat delete mode 100644 code/collections/AdapterMethodIdiom.java delete mode 100644 code/collections/AddingGroups.java delete mode 100644 code/collections/ApplesAndOrangesWithGenerics.java delete mode 100644 code/collections/ApplesAndOrangesWithoutGenerics.java delete mode 100644 code/collections/ArrayIsNotIterable.java delete mode 100644 code/collections/AsListInference.java delete mode 100644 code/collections/CollectionDifferences.java delete mode 100644 code/collections/CollectionSequence.java delete mode 100644 code/collections/CrossCollectionIteration.java delete mode 100644 code/collections/CrossCollectionIteration2.java delete mode 100644 code/collections/EnvironmentVariables.java delete mode 100644 code/collections/ForInCollections.java delete mode 100644 code/collections/GenericsAndUpcasting.java delete mode 100644 code/collections/InterfaceVsIterator.java delete mode 100644 code/collections/IterableClass.java delete mode 100644 code/collections/LinkedListFeatures.java delete mode 100644 code/collections/ListFeatures.java delete mode 100644 code/collections/ListIteration.java delete mode 100644 code/collections/MapOfList.java delete mode 100644 code/collections/ModifyingArraysAsList.java delete mode 100644 code/collections/MultiIterableClass.java delete mode 100644 code/collections/NonCollectionSequence.java delete mode 100644 code/collections/PetMap.java delete mode 100644 code/collections/PrintingCollections.java delete mode 100644 code/collections/PriorityQueueDemo.java delete mode 100644 code/collections/QueueDemo.java delete mode 100644 code/collections/SetOfInteger.java delete mode 100644 code/collections/SetOfString.java delete mode 100644 code/collections/SetOperations.java delete mode 100644 code/collections/SimpleCollection.java delete mode 100644 code/collections/SimpleIteration.java delete mode 100644 code/collections/SortedSetOfString.java delete mode 100644 code/collections/StackCollision.java delete mode 100644 code/collections/StackTest.java delete mode 100644 code/collections/StackTest2.java delete mode 100644 code/collections/Statistics.java delete mode 100644 code/collections/UniqueWords.java delete mode 100644 code/collections/UniqueWordsAlphabetic.java delete mode 100644 code/collectiontopics/AssociativeArray.java delete mode 100644 code/collectiontopics/Bits.java delete mode 100644 code/collectiontopics/CanonicalMapping.java delete mode 100644 code/collectiontopics/CollectionMethods.java delete mode 100644 code/collectiontopics/Enumerations.java delete mode 100644 code/collectiontopics/FailFast.java delete mode 100644 code/collectiontopics/FillMapTest.java delete mode 100644 code/collectiontopics/FillingLists.java delete mode 100644 code/collectiontopics/FunctionalMap.java delete mode 100644 code/collectiontopics/HTMLColorTest.java delete mode 100644 code/collectiontopics/LinkedHashMapDemo.java delete mode 100644 code/collectiontopics/ListOps.java delete mode 100644 code/collectiontopics/ListSortSearch.java delete mode 100644 code/collectiontopics/MapOps.java delete mode 100644 code/collectiontopics/NavMap.java delete mode 100644 code/collectiontopics/QueueBehavior.java delete mode 100644 code/collectiontopics/ReadOnly.java delete mode 100644 code/collectiontopics/References.java delete mode 100644 code/collectiontopics/SetOrder.java delete mode 100644 code/collectiontopics/SimpleDeques.java delete mode 100644 code/collectiontopics/SortedMapDemo.java delete mode 100644 code/collectiontopics/SortedSetDemo.java delete mode 100644 code/collectiontopics/Stacks.java delete mode 100644 code/collectiontopics/StreamFillMaps.java delete mode 100644 code/collectiontopics/SuppliersCollectionTest.java delete mode 100644 code/collectiontopics/Synchronization.java delete mode 100644 code/collectiontopics/ToDoList.java delete mode 100644 code/collectiontopics/TypesForSets.java delete mode 100644 code/collectiontopics/Unsupported.java delete mode 100644 code/collectiontopics/Utilities.java delete mode 100644 code/com/mindviewinc/simple/List.java delete mode 100644 code/com/mindviewinc/simple/Vector.java delete mode 100644 code/compression/GZIPcompress.java delete mode 100644 code/compression/ZipCompress.java delete mode 100644 code/concurrent/Baked.java delete mode 100644 code/concurrent/Batter.java delete mode 100644 code/concurrent/Breakable.java delete mode 100644 code/concurrent/CachedThreadPool.java delete mode 100644 code/concurrent/CachedThreadPool2.java delete mode 100644 code/concurrent/CachedThreadPool3.java delete mode 100644 code/concurrent/CatchCompletableExceptions.java delete mode 100644 code/concurrent/CollectionIntoStream.java delete mode 100644 code/concurrent/CompletableApply.java delete mode 100644 code/concurrent/CompletableApplyAsync.java delete mode 100644 code/concurrent/CompletableApplyChained.java delete mode 100644 code/concurrent/CompletableExceptions.java delete mode 100644 code/concurrent/CompletableOperations.java delete mode 100644 code/concurrent/CompletablePizza.java delete mode 100644 code/concurrent/CompletableUtilities.java delete mode 100644 code/concurrent/CompletedMachina.java delete mode 100644 code/concurrent/CountingStream.java delete mode 100644 code/concurrent/CountingTask.java delete mode 100644 code/concurrent/DiningPhilosophers.java delete mode 100644 code/concurrent/DualCompletableOperations.java delete mode 100644 code/concurrent/FrostedCake.java delete mode 100644 code/concurrent/Futures.java delete mode 100644 code/concurrent/GuardedIDField.java delete mode 100644 code/concurrent/HasID.java delete mode 100644 code/concurrent/IDChecker.java delete mode 100644 code/concurrent/InterferingTask.java delete mode 100644 code/concurrent/LambdasAndMethodReferences.java delete mode 100644 code/concurrent/Machina.java delete mode 100644 code/concurrent/MoreTasksAfterShutdown.java delete mode 100644 code/concurrent/NapTask.java delete mode 100644 code/concurrent/OnePizza.java delete mode 100644 code/concurrent/ParallelPrime.java delete mode 100644 code/concurrent/ParallelStreamPuzzle.java delete mode 100644 code/concurrent/ParallelStreamPuzzle2.java delete mode 100644 code/concurrent/ParallelStreamPuzzle3.java delete mode 100644 code/concurrent/Philosopher.java delete mode 100644 code/concurrent/Pizza.java delete mode 100644 code/concurrent/PizzaParallelSteps.java delete mode 100644 code/concurrent/PizzaStreams.java delete mode 100644 code/concurrent/QuittableTask.java delete mode 100644 code/concurrent/QuittingCompletable.java delete mode 100644 code/concurrent/QuittingTasks.java delete mode 100644 code/concurrent/SharedConstructorArgument.java delete mode 100644 code/concurrent/SingleThreadExecutor.java delete mode 100644 code/concurrent/SingleThreadExecutor2.java delete mode 100644 code/concurrent/SingleThreadExecutor3.java delete mode 100644 code/concurrent/StaticIDField.java delete mode 100644 code/concurrent/StickHolder.java delete mode 100644 code/concurrent/StreamExceptions.java delete mode 100644 code/concurrent/Summing.java delete mode 100644 code/concurrent/Summing2.java delete mode 100644 code/concurrent/Summing3.java delete mode 100644 code/concurrent/Summing4.java delete mode 100644 code/concurrent/SynchronizedConstructor.java delete mode 100644 code/concurrent/SynchronizedFactory.java delete mode 100644 code/concurrent/TestStaticIDField.java delete mode 100644 code/concurrent/ThrowsChecked.java delete mode 100644 code/concurrent/Workable.java delete mode 100644 code/control/BreakAndContinue.java delete mode 100644 code/control/CommaOperator.java delete mode 100644 code/control/ForInFloat.java delete mode 100644 code/control/ForInInt.java delete mode 100644 code/control/ForInString.java delete mode 100644 code/control/IfElse.java delete mode 100644 code/control/LabeledFor.java delete mode 100644 code/control/LabeledWhile.java delete mode 100644 code/control/ListCharacters.java delete mode 100644 code/control/RandomBounds.java delete mode 100644 code/control/StringSwitch.java delete mode 100644 code/control/TestWithReturn.java delete mode 100644 code/control/TrueFalse.java delete mode 100644 code/control/VowelsAndConsonants.java delete mode 100644 code/control/WhileTest.java delete mode 100644 code/enums/AlarmPoints.java delete mode 100644 code/enums/BigEnumSet.java delete mode 100644 code/enums/Burrito2.java delete mode 100644 code/enums/CarWash.java delete mode 100644 code/enums/Competitor.java delete mode 100644 code/enums/ConstantSpecificMethod.java delete mode 100644 code/enums/EnumClass.java delete mode 100644 code/enums/EnumMaps.java delete mode 100644 code/enums/EnumSets.java delete mode 100644 code/enums/Input.java delete mode 100644 code/enums/NonEnum.java delete mode 100644 code/enums/NotClasses.java delete mode 100644 code/enums/Outcome.java delete mode 100644 code/enums/OverrideConstantSpecific.java delete mode 100644 code/enums/OzWitch.java delete mode 100644 code/enums/PostOffice.java delete mode 100644 code/enums/RandomTest.java delete mode 100644 code/enums/Reflection.java delete mode 100644 code/enums/RoShamBo.java delete mode 100644 code/enums/RoShamBo1.java delete mode 100644 code/enums/RoShamBo2.java delete mode 100644 code/enums/RoShamBo3.java delete mode 100644 code/enums/RoShamBo4.java delete mode 100644 code/enums/RoShamBo5.java delete mode 100644 code/enums/RoShamBo6.java delete mode 100644 code/enums/SecurityCategory.java delete mode 100644 code/enums/SpaceShip.java delete mode 100644 code/enums/SpicinessEnum.java delete mode 100644 code/enums/TrafficLight.java delete mode 100644 code/enums/UpcastEnum.java delete mode 100644 code/enums/VendingMachine.java delete mode 100644 code/enums/VendingMachineInput.txt delete mode 100644 code/enums/cartoons/EnumImplementation.java delete mode 100644 code/enums/menu/Course.java delete mode 100644 code/enums/menu/Food.java delete mode 100644 code/enums/menu/Meal.java delete mode 100644 code/enums/menu/Meal2.java delete mode 100644 code/enums/menu/TypeOfFood.java delete mode 100644 code/equalshashcode/ComposedEquality.java delete mode 100644 code/equalshashcode/CountedString.java delete mode 100644 code/equalshashcode/DefaultComparison.java delete mode 100644 code/equalshashcode/Equality.java delete mode 100644 code/equalshashcode/EqualityFactory.java delete mode 100644 code/equalshashcode/Groundhog.java delete mode 100644 code/equalshashcode/Groundhog2.java delete mode 100644 code/equalshashcode/IndividualTest.java delete mode 100644 code/equalshashcode/MapEntry.java delete mode 100644 code/equalshashcode/Prediction.java delete mode 100644 code/equalshashcode/SimpleHashMap.java delete mode 100644 code/equalshashcode/SlowMap.java delete mode 100644 code/equalshashcode/SpringDetector.java delete mode 100644 code/equalshashcode/SpringDetector2.java delete mode 100644 code/equalshashcode/StringHashCode.java delete mode 100644 code/equalshashcode/SubtypeEquality.java delete mode 100644 code/equalshashcode/SubtypeEquality2.java delete mode 100644 code/equalshashcode/SuccinctEquality.java delete mode 100644 code/exceptions/AlwaysFinally.java delete mode 100644 code/exceptions/AutoCloseableDetails.java delete mode 100644 code/exceptions/BodyException.java delete mode 100644 code/exceptions/Cleanup.java delete mode 100644 code/exceptions/CleanupIdiom.java delete mode 100644 code/exceptions/CloseExceptions.java delete mode 100644 code/exceptions/ConstructorException.java delete mode 100644 code/exceptions/DynamicFields.java delete mode 100644 code/exceptions/ExceptionMethods.java delete mode 100644 code/exceptions/ExceptionSilencer.java delete mode 100644 code/exceptions/ExtraFeatures.java delete mode 100644 code/exceptions/FinallyWorks.java delete mode 100644 code/exceptions/FullConstructors.java delete mode 100644 code/exceptions/Human.java delete mode 100644 code/exceptions/InheritingExceptions.java delete mode 100644 code/exceptions/InputFile.java delete mode 100644 code/exceptions/InputFile2.java delete mode 100644 code/exceptions/LoggingExceptions.java delete mode 100644 code/exceptions/LoggingExceptions2.java delete mode 100644 code/exceptions/LostMessage.java delete mode 100644 code/exceptions/MainException.java delete mode 100644 code/exceptions/MessyExceptions.java delete mode 100644 code/exceptions/MultiCatch.java delete mode 100644 code/exceptions/MultiCatch2.java delete mode 100644 code/exceptions/MultipleReturns.java delete mode 100644 code/exceptions/NeverCaught.java delete mode 100644 code/exceptions/OnOffException1.java delete mode 100644 code/exceptions/OnOffException2.java delete mode 100644 code/exceptions/OnOffSwitch.java delete mode 100644 code/exceptions/PreciseRethrow.java delete mode 100644 code/exceptions/RethrowNew.java delete mode 100644 code/exceptions/Rethrowing.java delete mode 100644 code/exceptions/SameHandler.java delete mode 100644 code/exceptions/StormyInning.java delete mode 100644 code/exceptions/StreamsAreAutoCloseable.java delete mode 100644 code/exceptions/Switch.java delete mode 100644 code/exceptions/TryAnything.java delete mode 100644 code/exceptions/TryWithResources.java delete mode 100644 code/exceptions/TurnOffChecking.java delete mode 100644 code/exceptions/WhoCalled.java delete mode 100644 code/exceptions/WithFinally.java delete mode 100644 code/files/AddAndSubtractPaths.java delete mode 100644 code/files/Directories.java delete mode 100644 code/files/FileSystemDemo.java delete mode 100644 code/files/Find.java delete mode 100644 code/files/ListOfLines.java delete mode 100644 code/files/PartsOfPaths.java delete mode 100644 code/files/PathAnalysis.java delete mode 100644 code/files/PathInfo.java delete mode 100644 code/files/PathWatcher.java delete mode 100644 code/files/ReadLineStream.java delete mode 100644 code/files/StreamInAndOut.java delete mode 100644 code/files/TreeWatcher.java delete mode 100644 code/files/Writing.java delete mode 100644 code/functional/AnonymousClosure.java delete mode 100644 code/functional/BiConsumerPermutations.java delete mode 100644 code/functional/ClassFunctionals.java delete mode 100644 code/functional/Closure1.java delete mode 100644 code/functional/Closure2.java delete mode 100644 code/functional/Closure3.java delete mode 100644 code/functional/Closure4.java delete mode 100644 code/functional/Closure5.java delete mode 100644 code/functional/Closure6.java delete mode 100644 code/functional/Closure7.java delete mode 100644 code/functional/Closure8.java delete mode 100644 code/functional/Closure9.java delete mode 100644 code/functional/ConsumeFunction.java delete mode 100644 code/functional/CtorReference.java delete mode 100644 code/functional/CurriedIntAdd.java delete mode 100644 code/functional/Curry3Args.java delete mode 100644 code/functional/CurryingAndPartials.java delete mode 100644 code/functional/FunctionComposition.java delete mode 100644 code/functional/FunctionVariants.java delete mode 100644 code/functional/FunctionWithWrapped.java delete mode 100644 code/functional/FunctionalAnnotation.java delete mode 100644 code/functional/IntCall.java delete mode 100644 code/functional/LambdaExpressions.java delete mode 100644 code/functional/MethodConversion.java delete mode 100644 code/functional/MethodReferences.java delete mode 100644 code/functional/MultiUnbound.java delete mode 100644 code/functional/PredicateComposition.java delete mode 100644 code/functional/ProduceFunction.java delete mode 100644 code/functional/RecursiveFactorial.java delete mode 100644 code/functional/RecursiveFibonacci.java delete mode 100644 code/functional/RunnableMethodReference.java delete mode 100644 code/functional/SharedStorage.java delete mode 100644 code/functional/Strategize.java delete mode 100644 code/functional/TransformFunction.java delete mode 100644 code/functional/TriFunction.java delete mode 100644 code/functional/TriFunctionTest.java delete mode 100644 code/functional/UnboundMethodReference.java delete mode 100644 code/generics/Amphibian.java delete mode 100644 code/generics/Apply.java delete mode 100644 code/generics/ApplyFunctional.java delete mode 100644 code/generics/ApplyTest.java delete mode 100644 code/generics/ArrayMaker.java delete mode 100644 code/generics/ArrayOfGeneric.java delete mode 100644 code/generics/ArrayOfGenericReference.java delete mode 100644 code/generics/BankTeller.java delete mode 100644 code/generics/BasicBounds.java delete mode 100644 code/generics/BasicHolder.java delete mode 100644 code/generics/BasicSupplierDemo.java delete mode 100644 code/generics/ByteSet.java delete mode 100644 code/generics/CRGWithBasicHolder.java delete mode 100644 code/generics/CaptureConversion.java delete mode 100644 code/generics/CheckedList.java delete mode 100644 code/generics/ClassCasting.java delete mode 100644 code/generics/ClassTypeCapture.java delete mode 100644 code/generics/ComparablePet.java delete mode 100644 code/generics/CompilerIntelligence.java delete mode 100644 code/generics/CountedObject.java delete mode 100644 code/generics/CovariantArrays.java delete mode 100644 code/generics/CovariantReturnTypes.java delete mode 100644 code/generics/CreatorGeneric.java delete mode 100644 code/generics/CuriouslyRecurringGeneric.java delete mode 100644 code/generics/Diamond.java delete mode 100644 code/generics/DogsAndRobotMethodReferences.java delete mode 100644 code/generics/DogsAndRobots.cpp delete mode 100644 code/generics/DogsAndRobots.java delete mode 100644 code/generics/DogsAndRobots.py delete mode 100644 code/generics/DynamicProxyMixin.java delete mode 100644 code/generics/EpicBattle.java delete mode 100644 code/generics/Erased.java delete mode 100644 code/generics/ErasedTypeEquivalence.java delete mode 100644 code/generics/ErasureAndInheritance.java delete mode 100644 code/generics/FactoryConstraint.java delete mode 100644 code/generics/Fibonacci.java delete mode 100644 code/generics/FilledList.java delete mode 100644 code/generics/GenericArray.java delete mode 100644 code/generics/GenericArray2.java delete mode 100644 code/generics/GenericArrayWithTypeToken.java delete mode 100644 code/generics/GenericCast.java delete mode 100644 code/generics/GenericHolder.java delete mode 100644 code/generics/GenericHolder2.java delete mode 100644 code/generics/GenericMethods.java delete mode 100644 code/generics/GenericReading.java delete mode 100644 code/generics/GenericVarargs.java delete mode 100644 code/generics/GenericsAndCovariance.java delete mode 100644 code/generics/GenericsAndReturnTypes.java delete mode 100644 code/generics/HasF.java delete mode 100644 code/generics/HijackedInterface.java delete mode 100644 code/generics/Holder.java delete mode 100644 code/generics/Holder1.java delete mode 100644 code/generics/InheritBounds.java delete mode 100644 code/generics/InstantiateGenericType.cpp delete mode 100644 code/generics/InstantiateGenericType.java delete mode 100644 code/generics/IterableFibonacci.java delete mode 100644 code/generics/LatentReflection.java delete mode 100644 code/generics/LinkedStack.java delete mode 100644 code/generics/ListMaker.java delete mode 100644 code/generics/ListOfGenerics.java delete mode 100644 code/generics/ListOfInt.java delete mode 100644 code/generics/LostInformation.java delete mode 100644 code/generics/Manipulation.java delete mode 100644 code/generics/Manipulator2.java delete mode 100644 code/generics/Manipulator3.java delete mode 100644 code/generics/Mixins.cpp delete mode 100644 code/generics/Mixins.java delete mode 100644 code/generics/MultipleInterfaceVariants.java delete mode 100644 code/generics/NeedCasting.java delete mode 100644 code/generics/NonCovariantGenerics.java delete mode 100644 code/generics/NotSelfBounded.java delete mode 100644 code/generics/ObjectHolder.java delete mode 100644 code/generics/OrdinaryArguments.java delete mode 100644 code/generics/Performs.java delete mode 100644 code/generics/PlainGenericInheritance.java delete mode 100644 code/generics/PrimitiveGenericTest.java delete mode 100644 code/generics/RandomList.java delete mode 100644 code/generics/RestrictedComparablePets.java delete mode 100644 code/generics/ReturnGenericType.java delete mode 100644 code/generics/SelfBounding.java delete mode 100644 code/generics/SelfBoundingAndCovariantArguments.java delete mode 100644 code/generics/SelfBoundingMethods.java delete mode 100644 code/generics/Shape.java delete mode 100644 code/generics/SimpleDogsAndRobots.java delete mode 100644 code/generics/SimpleHolder.java delete mode 100644 code/generics/SimpleQueue.java delete mode 100644 code/generics/Square.java delete mode 100644 code/generics/Store.java delete mode 100644 code/generics/SuperTypeWildcards.java delete mode 100644 code/generics/Templates.cpp delete mode 100644 code/generics/ThrowGenericException.java delete mode 100644 code/generics/TupleList.java delete mode 100644 code/generics/TupleTest.java delete mode 100644 code/generics/TupleTest2.java delete mode 100644 code/generics/UnboundedWildcards1.java delete mode 100644 code/generics/UnboundedWildcards2.java delete mode 100644 code/generics/Unconstrained.java delete mode 100644 code/generics/UseList.java delete mode 100644 code/generics/UseList2.java delete mode 100644 code/generics/Vehicle.java delete mode 100644 code/generics/WatercolorSets.java delete mode 100644 code/generics/Wildcards.java delete mode 100644 code/generics/coffee/Americano.java delete mode 100644 code/generics/coffee/Breve.java delete mode 100644 code/generics/coffee/Cappuccino.java delete mode 100644 code/generics/coffee/Coffee.java delete mode 100644 code/generics/coffee/CoffeeSupplier.java delete mode 100644 code/generics/coffee/Latte.java delete mode 100644 code/generics/coffee/Mocha.java delete mode 100644 code/generics/decorator/Decoration.java delete mode 100644 code/generics/dogsandrobots.go delete mode 100644 code/generics/watercolors/Watercolors.java delete mode 100644 code/gradle.properties delete mode 100644 code/gradle/checkstyle.gradle delete mode 100644 code/gradle/findbugs.gradle delete mode 100644 code/gradle/java.gradle delete mode 100644 code/gradle/jmh.gradle delete mode 100644 code/gradle/junit-jupiter.gradle delete mode 100644 code/gradle/subprojects.gradle delete mode 100644 code/gradle/wrapper/gradle-wrapper.jar delete mode 100644 code/gradle/wrapper/gradle-wrapper.properties delete mode 100644 code/gradlew delete mode 100644 code/gradlew.bat delete mode 100644 code/hiding/Cake.java delete mode 100644 code/hiding/ChocolateChip.java delete mode 100644 code/hiding/ChocolateChip2.java delete mode 100644 code/hiding/CreatePackageAccessObject.java delete mode 100644 code/hiding/Dinner.java delete mode 100644 code/hiding/FullQualification.java delete mode 100644 code/hiding/IceCream.java delete mode 100644 code/hiding/ImportedMyClass.java delete mode 100644 code/hiding/LibTest.java delete mode 100644 code/hiding/Lunch.java delete mode 100644 code/hiding/OrganizedByAccess.java delete mode 100644 code/hiding/Pie.java delete mode 100644 code/hiding/QualifiedMyClass.java delete mode 100644 code/hiding/SingleImport.java delete mode 100644 code/hiding/cookie2/Cookie.java delete mode 100644 code/hiding/dessert/Cookie.java delete mode 100644 code/hiding/mypackage/MyClass.java delete mode 100644 code/hiding/packageaccess/PublicConstructor.java delete mode 100644 code/housekeeping/Apricot.java delete mode 100644 code/housekeeping/ArrayClassObj.java delete mode 100644 code/housekeeping/ArrayInit.java delete mode 100644 code/housekeeping/ArrayNew.java delete mode 100644 code/housekeeping/ArraysOfPrimitives.java delete mode 100644 code/housekeeping/AutoboxingVarargs.java delete mode 100644 code/housekeeping/BananaPeel.java delete mode 100644 code/housekeeping/Burrito.java delete mode 100644 code/housekeeping/Counter.java delete mode 100644 code/housekeeping/DefaultConstructor.java delete mode 100644 code/housekeeping/Demotion.java delete mode 100644 code/housekeeping/DynamicArray.java delete mode 100644 code/housekeeping/EnumOrder.java delete mode 100644 code/housekeeping/ExplicitStatic.java delete mode 100644 code/housekeeping/Flower.java delete mode 100644 code/housekeeping/InitialValues.java delete mode 100644 code/housekeeping/InitialValues2.java delete mode 100644 code/housekeeping/Leaf.java delete mode 100644 code/housekeeping/Measurement.java delete mode 100644 code/housekeeping/MethodInit.java delete mode 100644 code/housekeeping/MethodInit2.java delete mode 100644 code/housekeeping/MethodInit3.java delete mode 100644 code/housekeeping/Mugs.java delete mode 100644 code/housekeeping/NewVarArgs.java delete mode 100644 code/housekeeping/NoSynthesis.java delete mode 100644 code/housekeeping/OptionalTrailingArguments.java delete mode 100644 code/housekeeping/OrderOfInitialization.java delete mode 100644 code/housekeeping/Overloading.java delete mode 100644 code/housekeeping/OverloadingOrder.java delete mode 100644 code/housekeeping/OverloadingVarargs.java delete mode 100644 code/housekeeping/OverloadingVarargs2.java delete mode 100644 code/housekeeping/OverloadingVarargs3.java delete mode 100644 code/housekeeping/PassingThis.java delete mode 100644 code/housekeeping/PrimitiveOverloading.java delete mode 100644 code/housekeeping/SimpleConstructor.java delete mode 100644 code/housekeeping/SimpleConstructor2.java delete mode 100644 code/housekeeping/SimpleEnumUse.java delete mode 100644 code/housekeeping/Spiciness.java delete mode 100644 code/housekeeping/Spoon.java delete mode 100644 code/housekeeping/StaticInitialization.java delete mode 100644 code/housekeeping/TerminationCondition.java delete mode 100644 code/housekeeping/VarArgs.java delete mode 100644 code/housekeeping/VarargType.java delete mode 100644 code/innerclasses/AnonymousConstructor.java delete mode 100644 code/innerclasses/BigEgg.java delete mode 100644 code/innerclasses/BigEgg2.java delete mode 100644 code/innerclasses/Callbacks.java delete mode 100644 code/innerclasses/ClassInInterface.java delete mode 100644 code/innerclasses/Contents.java delete mode 100644 code/innerclasses/Destination.java delete mode 100644 code/innerclasses/DotNew.java delete mode 100644 code/innerclasses/DotThis.java delete mode 100644 code/innerclasses/GreenhouseController.java delete mode 100644 code/innerclasses/GreenhouseControls.java delete mode 100644 code/innerclasses/InheritInner.java delete mode 100644 code/innerclasses/LocalInnerClass.java delete mode 100644 code/innerclasses/MultiImplementation.java delete mode 100644 code/innerclasses/MultiNestingAccess.java delete mode 100644 code/innerclasses/Parcel1.java delete mode 100644 code/innerclasses/Parcel10.java delete mode 100644 code/innerclasses/Parcel11.java delete mode 100644 code/innerclasses/Parcel2.java delete mode 100644 code/innerclasses/Parcel3.java delete mode 100644 code/innerclasses/Parcel5.java delete mode 100644 code/innerclasses/Parcel6.java delete mode 100644 code/innerclasses/Parcel7.java delete mode 100644 code/innerclasses/Parcel7b.java delete mode 100644 code/innerclasses/Parcel8.java delete mode 100644 code/innerclasses/Parcel9.java delete mode 100644 code/innerclasses/Sequence.java delete mode 100644 code/innerclasses/TestBed.java delete mode 100644 code/innerclasses/TestParcel.java delete mode 100644 code/innerclasses/Wrapping.java delete mode 100644 code/innerclasses/controller/Controller.java delete mode 100644 code/innerclasses/controller/Event.java delete mode 100644 code/innerclasses/mui/MultiInterfaces.java delete mode 100644 code/interfaces/AbstractAccess.java delete mode 100644 code/interfaces/AbstractWithoutAbstracts.java delete mode 100644 code/interfaces/AdaptedRandomDoubles.java delete mode 100644 code/interfaces/Adventure.java delete mode 100644 code/interfaces/AnImplementation.java delete mode 100644 code/interfaces/AnInterface.java delete mode 100644 code/interfaces/Applicator.java delete mode 100644 code/interfaces/AttemptToUseBasic.java delete mode 100644 code/interfaces/Basic.java delete mode 100644 code/interfaces/Basic2.java delete mode 100644 code/interfaces/Factories.java delete mode 100644 code/interfaces/Games.java delete mode 100644 code/interfaces/HorrorShow.java delete mode 100644 code/interfaces/Implementation2.java delete mode 100644 code/interfaces/ImplementingAnInterface.java delete mode 100644 code/interfaces/Instantiable.java delete mode 100644 code/interfaces/InterfaceCollision.java delete mode 100644 code/interfaces/InterfaceWithDefault.java delete mode 100644 code/interfaces/Jim.java delete mode 100644 code/interfaces/MICollision.java delete mode 100644 code/interfaces/Machine.java delete mode 100644 code/interfaces/Months.java delete mode 100644 code/interfaces/MultipleInheritance.java delete mode 100644 code/interfaces/PureInterface.java delete mode 100644 code/interfaces/RandVals.java delete mode 100644 code/interfaces/RandomDoubles.java delete mode 100644 code/interfaces/RandomStrings.java delete mode 100644 code/interfaces/TestRandVals.java delete mode 100644 code/interfaces/filters/BandPass.java delete mode 100644 code/interfaces/filters/Filter.java delete mode 100644 code/interfaces/filters/HighPass.java delete mode 100644 code/interfaces/filters/LowPass.java delete mode 100644 code/interfaces/filters/Waveform.java delete mode 100644 code/interfaces/interfaceprocessor/Applicator.java delete mode 100644 code/interfaces/interfaceprocessor/FilterProcessor.java delete mode 100644 code/interfaces/interfaceprocessor/Processor.java delete mode 100644 code/interfaces/interfaceprocessor/StringProcessor.java delete mode 100644 code/interfaces/music4/Music4.java delete mode 100644 code/interfaces/music5/Music5.java delete mode 100644 code/interfaces/nesting/NestingInterfaces.java delete mode 100644 code/iostreams/BasicFileOutput.java delete mode 100644 code/iostreams/BufferedInputFile.java delete mode 100644 code/iostreams/FileOutputShortcut.java delete mode 100644 code/iostreams/FormattedMemoryInput.java delete mode 100644 code/iostreams/MemoryInput.java delete mode 100644 code/iostreams/StoringAndRecoveringData.java delete mode 100644 code/iostreams/TestEOF.java delete mode 100644 code/iostreams/UsingRandomAccessFile.java delete mode 100644 code/javadoc/Documentation1.java delete mode 100644 code/javadoc/Documentation2.java delete mode 100644 code/javadoc/Documentation3.java delete mode 100644 code/javadoc/HelloDateDoc.java delete mode 100644 code/lowlevel/AtomicEvenProducer.java delete mode 100644 code/lowlevel/AtomicIntegerTest.java delete mode 100644 code/lowlevel/AtomicSerialNumbers.java delete mode 100644 code/lowlevel/Atomicity.java delete mode 100644 code/lowlevel/AttemptLocking.java delete mode 100644 code/lowlevel/CaptureUncaughtException.java delete mode 100644 code/lowlevel/CircularSet.java delete mode 100644 code/lowlevel/DelayQueueDemo.java delete mode 100644 code/lowlevel/EvenChecker.java delete mode 100644 code/lowlevel/EvenProducer.java delete mode 100644 code/lowlevel/ExceptionThread.java delete mode 100644 code/lowlevel/IntGenerator.java delete mode 100644 code/lowlevel/IntTestable.java delete mode 100644 code/lowlevel/MutexEvenProducer.java delete mode 100644 code/lowlevel/NaiveExceptionHandling.java delete mode 100644 code/lowlevel/NotAtomic.java delete mode 100644 code/lowlevel/NumberOfProcessors.java delete mode 100644 code/lowlevel/PriorityBlockingQueueDemo.java delete mode 100644 code/lowlevel/ReOrdering.java delete mode 100644 code/lowlevel/SafeReturn.java delete mode 100644 code/lowlevel/SerialNumberChecker.java delete mode 100644 code/lowlevel/SerialNumberTest.java delete mode 100644 code/lowlevel/SerialNumbers.java delete mode 100644 code/lowlevel/SettingDefaultHandler.java delete mode 100644 code/lowlevel/SwallowedException.java delete mode 100644 code/lowlevel/SyncOnObject.java delete mode 100644 code/lowlevel/SynchronizedComparison.java delete mode 100644 code/lowlevel/SynchronizedEvenProducer.java delete mode 100644 code/lowlevel/SynchronizedSerialNumbers.java delete mode 100644 code/lowlevel/TestAbort.java delete mode 100644 code/lowlevel/ThreadSize.java delete mode 100644 code/lowlevel/UnsafeReturn.java delete mode 100644 code/lowlevel/WorkStealingPool.java delete mode 100644 code/newio/AvailableCharSets.java delete mode 100644 code/newio/BufferToText.java delete mode 100644 code/newio/ChannelCopy.java delete mode 100644 code/newio/Endians.java delete mode 100644 code/newio/FileLocking.java delete mode 100644 code/newio/GetChannel.java delete mode 100644 code/newio/GetData.java delete mode 100644 code/newio/IntBufferDemo.java delete mode 100644 code/newio/LargeMappedFiles.java delete mode 100644 code/newio/LockingMappedFiles.java delete mode 100644 code/newio/MappedIO.java delete mode 100644 code/newio/TransferTo.java delete mode 100644 code/newio/UsingBuffers.java delete mode 100644 code/newio/ViewBuffers.java delete mode 100644 code/objects/HelloDate.java delete mode 100644 code/objects/ShowProperties.java delete mode 100644 code/onjava/ArrayShow.java delete mode 100644 code/onjava/BasicSupplier.java delete mode 100644 code/onjava/CollectionMethodDifferences.java delete mode 100644 code/onjava/ConvertTo.java delete mode 100644 code/onjava/Count.java delete mode 100644 code/onjava/CountMap.java delete mode 100644 code/onjava/CountingIntegerList.java delete mode 100644 code/onjava/Countries.java delete mode 100644 code/onjava/Enums.java delete mode 100644 code/onjava/FillMap.java delete mode 100644 code/onjava/HTMLColors.java delete mode 100644 code/onjava/MouseClick.java delete mode 100644 code/onjava/Nap.java delete mode 100644 code/onjava/Null.java delete mode 100644 code/onjava/OSExecute.java delete mode 100644 code/onjava/OSExecuteException.java delete mode 100644 code/onjava/Operations.java delete mode 100644 code/onjava/Pair.java delete mode 100644 code/onjava/ProcessFiles.java delete mode 100644 code/onjava/Rand.java delete mode 100644 code/onjava/Range.java delete mode 100644 code/onjava/Repeat.java delete mode 100644 code/onjava/RmDir.java delete mode 100644 code/onjava/Sets.java delete mode 100644 code/onjava/Stack.java delete mode 100644 code/onjava/Suppliers.java delete mode 100644 code/onjava/TimedAbort.java delete mode 100644 code/onjava/Timer.java delete mode 100644 code/onjava/Tuple.java delete mode 100644 code/onjava/Tuple2.java delete mode 100644 code/onjava/Tuple3.java delete mode 100644 code/onjava/Tuple4.java delete mode 100644 code/onjava/Tuple5.java delete mode 100644 code/onjava/TypeCounter.java delete mode 100644 code/onjava/atunit/AtUnit.java delete mode 100644 code/onjava/atunit/ClassNameFinder.java delete mode 100644 code/onjava/atunit/Test.java delete mode 100644 code/onjava/atunit/TestObjectCleanup.java delete mode 100644 code/onjava/atunit/TestObjectCreate.java delete mode 100644 code/onjava/atunit/TestProperty.java delete mode 100644 code/operators/AllOps.java delete mode 100644 code/operators/Assignment.java delete mode 100644 code/operators/AutoInc.java delete mode 100644 code/operators/BitManipulation.java delete mode 100644 code/operators/Bool.java delete mode 100644 code/operators/Casting.java delete mode 100644 code/operators/CastingNumbers.java delete mode 100644 code/operators/EqualsMethod.java delete mode 100644 code/operators/EqualsMethod2.java delete mode 100644 code/operators/Equivalence.java delete mode 100644 code/operators/Exponents.java delete mode 100644 code/operators/Literals.java delete mode 100644 code/operators/MathOps.java delete mode 100644 code/operators/Overflow.java delete mode 100644 code/operators/PassObject.java delete mode 100644 code/operators/Precedence.java delete mode 100644 code/operators/RoundingNumbers.java delete mode 100644 code/operators/ShortCircuit.java delete mode 100644 code/operators/StringOperators.java delete mode 100644 code/operators/TernaryIfElse.java delete mode 100644 code/operators/URShift.java delete mode 100644 code/operators/Underscores.java delete mode 100644 code/patterns/BoxObserver.java delete mode 100644 code/patterns/CommandPattern.java delete mode 100644 code/patterns/Facade.java delete mode 100644 code/patterns/PaperScissorsRock.java delete mode 100644 code/patterns/ProxyDemo.java delete mode 100644 code/patterns/ShapeFactory1.java delete mode 100644 code/patterns/ShapeFactory2.java delete mode 100644 code/patterns/ShapeFactory3.java delete mode 100644 code/patterns/SingletonPattern.java delete mode 100644 code/patterns/StateDemo.java delete mode 100644 code/patterns/TemplateMethod.java delete mode 100644 code/patterns/abstractfactory/GameEnvironment.java delete mode 100644 code/patterns/adapt/Adapter.java delete mode 100644 code/patterns/chain/ChainOfResponsibility.java delete mode 100644 code/patterns/doubledispatch/Aluminum.java delete mode 100644 code/patterns/doubledispatch/Cardboard.java delete mode 100644 code/patterns/doubledispatch/DoubleDispatch.java delete mode 100644 code/patterns/doubledispatch/Glass.java delete mode 100644 code/patterns/doubledispatch/Paper.java delete mode 100644 code/patterns/doubledispatch/TypedBin.java delete mode 100644 code/patterns/doubledispatch/TypedBinMember.java delete mode 100644 code/patterns/dynatrash/DynaTrash.java delete mode 100644 code/patterns/observer/ObservedFlower.java delete mode 100644 code/patterns/recyclea/RecycleA.java delete mode 100644 code/patterns/recycleb/RecycleB.java delete mode 100644 code/patterns/recyclec/RecycleC.java delete mode 100644 code/patterns/shapes/BadShapeCreation.java delete mode 100644 code/patterns/shapes/Circle.java delete mode 100644 code/patterns/shapes/FactoryMethod.java delete mode 100644 code/patterns/shapes/FactoryTest.java delete mode 100644 code/patterns/shapes/Shape.java delete mode 100644 code/patterns/shapes/Square.java delete mode 100644 code/patterns/shapes/Triangle.java delete mode 100644 code/patterns/state/StateMachineDemo.java delete mode 100644 code/patterns/strategy/StrategyPattern.java delete mode 100644 code/patterns/strategy/StrategyPattern2.java delete mode 100644 code/patterns/trash/Aluminum.java delete mode 100644 code/patterns/trash/Cardboard.java delete mode 100644 code/patterns/trash/Fillable.java delete mode 100644 code/patterns/trash/FillableList.java delete mode 100644 code/patterns/trash/Glass.java delete mode 100644 code/patterns/trash/Paper.java delete mode 100644 code/patterns/trash/ParseTrash.java delete mode 100644 code/patterns/trash/Trash.dat delete mode 100644 code/patterns/trash/Trash.java delete mode 100644 code/patterns/trashvisitor/Aluminum.java delete mode 100644 code/patterns/trashvisitor/Cardboard.java delete mode 100644 code/patterns/trashvisitor/Glass.java delete mode 100644 code/patterns/trashvisitor/Paper.java delete mode 100644 code/patterns/trashvisitor/TrashVisitor.java delete mode 100644 code/patterns/trashvisitor/Visitable.java delete mode 100644 code/patterns/trashvisitor/Visitor.java delete mode 100644 code/patterns/visitor/BeeAndFlowers.java delete mode 100644 code/polymorphism/CovariantReturn.java delete mode 100644 code/polymorphism/FieldAccess.java delete mode 100644 code/polymorphism/Frog.java delete mode 100644 code/polymorphism/PolyConstructors.java delete mode 100644 code/polymorphism/PrivateOverride.java delete mode 100644 code/polymorphism/PrivateOverride2.java delete mode 100644 code/polymorphism/RTTI.java delete mode 100644 code/polymorphism/ReferenceCounting.java delete mode 100644 code/polymorphism/Sandwich.java delete mode 100644 code/polymorphism/Shapes.java delete mode 100644 code/polymorphism/StaticPolymorphism.java delete mode 100644 code/polymorphism/Transmogrify.java delete mode 100644 code/polymorphism/music/Instrument.java delete mode 100644 code/polymorphism/music/Music.java delete mode 100644 code/polymorphism/music/Music2.java delete mode 100644 code/polymorphism/music/Note.java delete mode 100644 code/polymorphism/music/Wind.java delete mode 100644 code/polymorphism/music3/Music3.java delete mode 100644 code/polymorphism/shape/Circle.java delete mode 100644 code/polymorphism/shape/RandomShapes.java delete mode 100644 code/polymorphism/shape/Shape.java delete mode 100644 code/polymorphism/shape/Square.java delete mode 100644 code/polymorphism/shape/Triangle.java delete mode 100644 code/references/AddingClone.java delete mode 100644 code/references/Alias1.java delete mode 100644 code/references/Alias2.java delete mode 100644 code/references/CheckCloneable.java delete mode 100644 code/references/CloneArrayList.java delete mode 100644 code/references/Compete.java delete mode 100644 code/references/CopyConstructor.java delete mode 100644 code/references/DepthReading.java delete mode 100644 code/references/HorrorFlick.java delete mode 100644 code/references/Immutable1.java delete mode 100644 code/references/Immutable2.java delete mode 100644 code/references/ImmutableInteger.java delete mode 100644 code/references/ImmutableStrings.java delete mode 100644 code/references/LocalCopy.java delete mode 100644 code/references/MutableInteger.java delete mode 100644 code/references/OceanReading.java delete mode 100644 code/references/PassReferences.java delete mode 100644 code/references/SimplerMutableInteger.java delete mode 100644 code/references/Snake.java delete mode 100644 code/references/Stringer.java delete mode 100644 code/references/TemperatureReading.java delete mode 100644 code/references/tests/DeepCopyTest.java delete mode 100644 code/reuse/Bath.java delete mode 100644 code/reuse/Beetle.java delete mode 100644 code/reuse/BlankFinal.java delete mode 100644 code/reuse/CADSystem.java delete mode 100644 code/reuse/Car.java delete mode 100644 code/reuse/Cartoon.java delete mode 100644 code/reuse/Chess.java delete mode 100644 code/reuse/DerivedSpaceShip.java delete mode 100644 code/reuse/Detergent.java delete mode 100644 code/reuse/FinalArguments.java delete mode 100644 code/reuse/FinalData.java delete mode 100644 code/reuse/FinalOverridingIllusion.java delete mode 100644 code/reuse/Hide.java delete mode 100644 code/reuse/Jurassic.java delete mode 100644 code/reuse/Lisa.java delete mode 100644 code/reuse/Orc.java delete mode 100644 code/reuse/PlaceSetting.java delete mode 100644 code/reuse/SpaceShipControls.java delete mode 100644 code/reuse/SpaceShipDelegation.java delete mode 100644 code/reuse/SprinklerSystem.java delete mode 100644 code/reuse/Wind.java delete mode 100644 code/serialization/APerson.java delete mode 100644 code/serialization/AStoreCADState.java delete mode 100644 code/serialization/Alien.java delete mode 100644 code/serialization/Blip3.java delete mode 100644 code/serialization/Blips.java delete mode 100644 code/serialization/FreezeAlien.java delete mode 100644 code/serialization/Logon.java delete mode 100644 code/serialization/MyWorld.java delete mode 100644 code/serialization/People.java delete mode 100644 code/serialization/RecoverCADState.java delete mode 100644 code/serialization/SerialCtl.java delete mode 100644 code/serialization/Worm.java delete mode 100644 code/serialization/xfiles/ThawAlien.java delete mode 100644 code/settings.gradle delete mode 100644 code/standardio/ChangeSystemOut.java delete mode 100644 code/standardio/Echo.java delete mode 100644 code/standardio/OSExecuteDemo.java delete mode 100644 code/standardio/Redirecting.java delete mode 100644 code/staticchecking/DogsAndRobots.cpp delete mode 100644 code/staticchecking/DogsAndRobots.py delete mode 100644 code/staticchecking/NoBasePetSpeak.py delete mode 100644 code/staticchecking/PetSpeak.py delete mode 100644 code/staticchecking/dogsandrobots.go delete mode 100644 code/staticchecking/dr/DogsAndRobots.java delete mode 100644 code/staticchecking/drc/DogAndRobotCollections.java delete mode 100644 code/staticchecking/latent/Latent.java delete mode 100644 code/staticchecking/petspeak.go delete mode 100644 code/staticchecking/petspeak/PetSpeak.java delete mode 100644 code/streams/ArrayStreams.java delete mode 100644 code/streams/Bubble.java delete mode 100644 code/streams/Bubbles.java delete mode 100644 code/streams/Cheese.dat delete mode 100644 code/streams/CollectionToStream.java delete mode 100644 code/streams/CreatingOptionals.java delete mode 100644 code/streams/Duplicator.java delete mode 100644 code/streams/Fibonacci.java delete mode 100644 code/streams/FileToWords.java delete mode 100644 code/streams/FileToWordsBuilder.java delete mode 100644 code/streams/FileToWordsRegexp.java delete mode 100644 code/streams/FileToWordsTest.java delete mode 100644 code/streams/FlatMap.java delete mode 100644 code/streams/ForEach.java delete mode 100644 code/streams/FunctionMap.java delete mode 100644 code/streams/FunctionMap2.java delete mode 100644 code/streams/FunctionMap3.java delete mode 100644 code/streams/Generator.java delete mode 100644 code/streams/ImperativeRandoms.java delete mode 100644 code/streams/Informational.java delete mode 100644 code/streams/LastElement.java delete mode 100644 code/streams/Looping.java delete mode 100644 code/streams/Machine2.java delete mode 100644 code/streams/MapCollector.java delete mode 100644 code/streams/Matching.java delete mode 100644 code/streams/NumericStreamInfo.java delete mode 100644 code/streams/OptionalBasics.java delete mode 100644 code/streams/OptionalFilter.java delete mode 100644 code/streams/OptionalFlatMap.java delete mode 100644 code/streams/OptionalMap.java delete mode 100644 code/streams/Optionals.java delete mode 100644 code/streams/OptionalsFromEmptyStreams.java delete mode 100644 code/streams/Peeking.java delete mode 100644 code/streams/Prime.java delete mode 100644 code/streams/RandInts.java delete mode 100644 code/streams/RandomGenerators.java delete mode 100644 code/streams/RandomWords.java delete mode 100644 code/streams/Randoms.java delete mode 100644 code/streams/Ranges.java delete mode 100644 code/streams/Reduce.java delete mode 100644 code/streams/SelectElement.java delete mode 100644 code/streams/Signal.java delete mode 100644 code/streams/SortedComparator.java delete mode 100644 code/streams/SpecialCollector.java delete mode 100644 code/streams/StreamOf.java delete mode 100644 code/streams/StreamOfOptionals.java delete mode 100644 code/streams/StreamOfRandoms.java delete mode 100644 code/streams/StreamOfStreams.java delete mode 100644 code/streams/TreeSetOfWords.java delete mode 100644 code/strings/ArrayListDisplay.java delete mode 100644 code/strings/BetterRead.java delete mode 100644 code/strings/Concatenation.java delete mode 100644 code/strings/Conversion.java delete mode 100644 code/strings/DatabaseException.java delete mode 100644 code/strings/Finding.java delete mode 100644 code/strings/Groups.java delete mode 100644 code/strings/Hex.java delete mode 100644 code/strings/Immutable.java delete mode 100644 code/strings/InfiniteRecursion.java delete mode 100644 code/strings/IntegerMatch.java delete mode 100644 code/strings/JGrep.java delete mode 100644 code/strings/ReFlags.java delete mode 100644 code/strings/ReceiptBuilder.java delete mode 100644 code/strings/Replacing.java delete mode 100644 code/strings/ReplacingStringTokenizer.java delete mode 100644 code/strings/Resetting.java delete mode 100644 code/strings/Rudolph.java delete mode 100644 code/strings/ScannerDelimiter.java delete mode 100644 code/strings/SimpleFormat.java delete mode 100644 code/strings/SimpleRead.java delete mode 100644 code/strings/SplitDemo.java delete mode 100644 code/strings/Splitting.java delete mode 100644 code/strings/StartEnd.java delete mode 100644 code/strings/TestRegularExpression.java delete mode 100644 code/strings/TheReplacements.java delete mode 100644 code/strings/ThreatAnalyzer.java delete mode 100644 code/strings/Turtle.java delete mode 100644 code/strings/UsingStringBuilder.java delete mode 100644 code/strings/WhitherStringBuilder.java delete mode 100644 code/typeinfo/AnonymousImplementation.java delete mode 100644 code/typeinfo/BoundedClassReferences.java delete mode 100644 code/typeinfo/ClassCasts.java delete mode 100644 code/typeinfo/ClassInitialization.java delete mode 100644 code/typeinfo/DynamicSupplier.java delete mode 100644 code/typeinfo/FamilyVsExactType.java delete mode 100644 code/typeinfo/GenericClassReferences.java delete mode 100644 code/typeinfo/HiddenImplementation.java delete mode 100644 code/typeinfo/InnerImplementation.java delete mode 100644 code/typeinfo/InterfaceViolation.java delete mode 100644 code/typeinfo/ModifyingPrivateFields.java delete mode 100644 code/typeinfo/NullRobot.java delete mode 100644 code/typeinfo/Operation.java delete mode 100644 code/typeinfo/Person.java delete mode 100644 code/typeinfo/PetCount.java delete mode 100644 code/typeinfo/PetCount2.java delete mode 100644 code/typeinfo/PetCount3.java delete mode 100644 code/typeinfo/PetCount4.java delete mode 100644 code/typeinfo/Position.java delete mode 100644 code/typeinfo/RegisteredFactories.java delete mode 100644 code/typeinfo/Robot.java delete mode 100644 code/typeinfo/SelectingMethods.java delete mode 100644 code/typeinfo/Shapes.java delete mode 100644 code/typeinfo/ShowMethods.java delete mode 100644 code/typeinfo/SimpleDynamicProxy.java delete mode 100644 code/typeinfo/SimpleProxyDemo.java delete mode 100644 code/typeinfo/SnowRemovalRobot.java delete mode 100644 code/typeinfo/Staff.java delete mode 100644 code/typeinfo/SweetShop.java delete mode 100644 code/typeinfo/WildcardClassReferences.java delete mode 100644 code/typeinfo/interfacea/A.java delete mode 100644 code/typeinfo/packageaccess/HiddenC.java delete mode 100644 code/typeinfo/pets/Cat.java delete mode 100644 code/typeinfo/pets/Cymric.java delete mode 100644 code/typeinfo/pets/Dog.java delete mode 100644 code/typeinfo/pets/EgyptianMau.java delete mode 100644 code/typeinfo/pets/ForNameCreator.java delete mode 100644 code/typeinfo/pets/Hamster.java delete mode 100644 code/typeinfo/pets/Individual.java delete mode 100644 code/typeinfo/pets/LiteralPetCreator.java delete mode 100644 code/typeinfo/pets/Manx.java delete mode 100644 code/typeinfo/pets/Mouse.java delete mode 100644 code/typeinfo/pets/Mutt.java delete mode 100644 code/typeinfo/pets/Person.java delete mode 100644 code/typeinfo/pets/Pet.java delete mode 100644 code/typeinfo/pets/PetCreator.java delete mode 100644 code/typeinfo/pets/Pets.java delete mode 100644 code/typeinfo/pets/Pug.java delete mode 100644 code/typeinfo/pets/Rat.java delete mode 100644 code/typeinfo/pets/Rodent.java delete mode 100644 code/typeinfo/toys/GenericToyTest.java delete mode 100644 code/typeinfo/toys/ToyTest.java delete mode 100644 code/validating/Assert1.java delete mode 100644 code/validating/Assert2.java delete mode 100644 code/validating/BadMicroBenchmark.java delete mode 100644 code/validating/BadMicroBenchmark2.java delete mode 100644 code/validating/CircularQueue.java delete mode 100644 code/validating/CircularQueueException.java delete mode 100644 code/validating/CountedList.java delete mode 100644 code/validating/GuavaAssertions.java delete mode 100644 code/validating/GuavaPreconditions.java delete mode 100644 code/validating/Inverter1.java delete mode 100644 code/validating/Inverter2.java delete mode 100644 code/validating/Inverter3.java delete mode 100644 code/validating/Inverter4.java delete mode 100644 code/validating/LoaderAssertions.java delete mode 100644 code/validating/NonNullConstruction.java delete mode 100644 code/validating/SLF4JLevels.java delete mode 100644 code/validating/SLF4JLogging.java delete mode 100644 code/validating/SimpleDebugging.java delete mode 100644 code/validating/StringInverter.java delete mode 100644 code/validating/jmh/JMH1.java delete mode 100644 code/validating/jmh/JMH2.java delete mode 100644 code/validating/jmh/JMH3.java delete mode 100644 code/validating/logback.xml delete mode 100644 code/validating/tests/CircularQueueTest.java delete mode 100644 code/validating/tests/CountedListTest.java delete mode 100644 code/validating/tests/DynamicStringInverterTests.java delete mode 100644 code/validating/tests/StringInverterTests.java diff --git a/code/.gitattributes b/code/.gitattributes deleted file mode 100644 index bdb0cabc..00000000 --- a/code/.gitattributes +++ /dev/null @@ -1,17 +0,0 @@ -# Auto detect text files and perform LF normalization -* text=auto - -# Custom for Visual Studio -*.cs diff=csharp - -# Standard to msysgit -*.doc diff=astextplain -*.DOC diff=astextplain -*.docx diff=astextplain -*.DOCX diff=astextplain -*.dot diff=astextplain -*.DOT diff=astextplain -*.pdf diff=astextplain -*.PDF diff=astextplain -*.rtf diff=astextplain -*.RTF diff=astextplain diff --git a/code/.gitignore b/code/.gitignore deleted file mode 100644 index 48292956..00000000 --- a/code/.gitignore +++ /dev/null @@ -1,111 +0,0 @@ -# Windows image file caches -Thumbs.db -ehthumbs.db - -# Folder config file -Desktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msm -*.msp - -# Windows shortcuts -*.lnk - -# ========================= -# Operating System Files -# ========================= - -# OSX -# ========================= - -.DS_Store -.AppleDouble -.LSOverride - -# Thumbnails -._* - -# Files that might appear on external disk -.Spotlight-V100 -.Trashes - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - -*.class -*output.txt -Generated.txt -*-control.txt -*-results.txt -*-out.txt -OutputErrors.txt -report.txt -failures -People.xml -annotations/Test0.txt -annotations/Test1.txt -annotations/Test2.txt -io/*.out -io/*.txt -io/*.dat -io/*.tmp -io/test.zip -io/test.gz -io/X.file -*.pyc - -*.out -*.err -/files/bytes.dat -/files/test/ -/exceptions/Results.txt -/files/Cheese.txt -/files/StreamInAndOut.txt - -.gradle -/*.iml -/.idea/ - -/serialization/Blip3.serialized -/serialization/Blips.serialized - -build/ -buildSrc/ - -/compression/test.gz -/compression/test.zip -/iostreams/BasicFileOutput.dat -/iostreams/Data.txt -/iostreams/FileOutputShortcut.dat -/iostreams/rtest.dat -/logging/LogToFile.xml -/logging/LogToFile2.txt -/logging/MultipleHandlers.xml -/logging/MultipleHandlers2.xml -/logging/java0.log -/logging/java1.log -/logging/java2.log -/newio/TransferTo.txt -/newio/data2.txt -/newio/file.txt -/newio/test.dat -/newio/test.txt -/serialization/CADState.dat -/serialization/worm.dat -/serialization/Logon.dat -/serialization/X.file -/standardio/Redirecting.txt -/threads/PSP2.txt -/threads/primes.txt -_* -config.py diff --git a/code/.travisXX.yml b/code/.travisXX.yml deleted file mode 100644 index 54fee659..00000000 --- a/code/.travisXX.yml +++ /dev/null @@ -1,8 +0,0 @@ -language: java -jdk: - - oraclejdk11 -install: true -script: - - ./gradlew --no-daemon --stacktrace run -# - ./gradlew --parallel --stacktrace run -# - ./gradlew --parallel --stacktrace :validating:jmh diff --git a/code/CI.txt b/code/CI.txt deleted file mode 100644 index 524ee206..00000000 --- a/code/CI.txt +++ /dev/null @@ -1,5 +0,0 @@ -Links formerly in the README. Both of these mysteriously started breaking. - -[![](https://travis-ci.org/BruceEckel/OnJava8-Examples.svg?branch=master)](https://travis-ci.org/BruceEckel/OnJava8-Examples) - -[![](https://ci.appveyor.com/api/projects/status/github/BruceEckel/OnJava8-Examples)](https://ci.appveyor.com/project/BruceEckel/onjava-examples) diff --git a/code/Copyright.txt b/code/Copyright.txt deleted file mode 100644 index f0d35035..00000000 --- a/code/Copyright.txt +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright.txt -This computer source code is Copyright �2020 MindView LLC. -All Rights Reserved. - -Permission to use, copy, modify, and distribute this -computer source code (Source Code) and its documentation -without fee and without a written agreement for the -purposes set forth below is hereby granted, provided that -the above copyright notice, this paragraph and the -following five numbered paragraphs appear in all copies. - -1. Permission is granted to compile the Source Code and to -include the compiled code, in executable format only, in -personal and commercial software programs. - -2. Permission is granted to use the Source Code without -modification in classroom situations, including in -presentation materials, provided that the book "On -Java 8" is cited as the origin. - -3. Permission to incorporate the Source Code into printed -media may be obtained by contacting: - -MindView LLC, PO Box 969, Crested Butte, CO 81224 -MindViewInc@gmail.com - -4. The Source Code and documentation are copyrighted by -MindView LLC. The Source code is provided without express -or implied warranty of any kind, including any implied -warranty of merchantability, fitness for a particular -purpose or non-infringement. MindView LLC does not -warrant that the operation of any program that includes the -Source Code will be uninterrupted or error-free. MindView -LLC makes no representation about the suitability of the -Source Code or of any software that includes the Source -Code for any purpose. The entire risk as to the quality -and performance of any program that includes the Source -Code is with the user of the Source Code. The user -understands that the Source Code was developed for research -and instructional purposes and is advised not to rely -exclusively for any reason on the Source Code or any -program that includes the Source Code. Should the Source -Code or any resulting software prove defective, the user -assumes the cost of all necessary servicing, repair, or -correction. - -5. IN NO EVENT SHALL MINDVIEW LLC, OR ITS PUBLISHER BE -LIABLE TO ANY PARTY UNDER ANY LEGAL THEORY FOR DIRECT, -INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, -INCLUDING LOST PROFITS, BUSINESS INTERRUPTION, LOSS OF -BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS, OR FOR -PERSONAL INJURIES, ARISING OUT OF THE USE OF THIS SOURCE -CODE AND ITS DOCUMENTATION, OR ARISING OUT OF THE INABILITY -TO USE ANY RESULTING PROGRAM, EVEN IF MINDVIEW LLC, OR -ITS PUBLISHER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. MINDVIEW LLC SPECIFICALLY DISCLAIMS ANY -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE SOURCE CODE AND DOCUMENTATION PROVIDED -HEREUNDER IS ON AN "AS IS" BASIS, WITHOUT ANY ACCOMPANYING -SERVICES FROM MINDVIEW LLC, AND MINDVIEW LLC HAS NO -OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, -ENHANCEMENTS, OR MODIFICATIONS. - -Please note that MindView LLC maintains a Web site which -is the sole distribution point for electronic copies of the -Source Code, https://github.com/BruceEckel/OnJava8-examples, -where it is freely available under the terms stated above. - -If you think you've found an error in the Source Code, -please submit a correction at: -https://github.com/BruceEckel/OnJava8-examples/issues diff --git a/code/README.md b/code/README.md deleted file mode 100644 index 985dbbe4..00000000 --- a/code/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Example Source Code for the Book "On Java 8" by Bruce Eckel - -Download release from [here](https://github.com/BruceEckel/OnJava8-Examples/releases/tag/v1.0). - -To compile and run these programs, you only need JDK 8 installed. -Invoking `gradlew` will automatically download and install Gradle. -Gradle will also install all additional libraries necessary to compile -and run the Java examples in the book. - -To compile and run everything, the command is: - -`gradlew run` - -If you are on a Unix/Linux based system, you must select the local directory for all commands, for example: - -`./gradlew run` - -To only compile everything, the command is: - -`gradlew compileJava` - -To compile only a single chapter (including dependencies), use for example: - -`gradlew :strings:compileJava` - -To run only a single chapter, say: - -`gradlew :strings:run` - -Gradle can also be used to run a single program. Here, we run the **ReplacingStringTokenizer.java** -program in the **strings** chapter subdirectory: - -`gradlew :strings:ReplacingStringTokenizer` - -However, if the file name is unique throughout the book (the majority are), you can just give the -program name, like this: - -`gradlew ReplacingStringTokenizer` - -Note that all commands are run from the base directory where the example code is installed, and where you find the -`gradlew` script. - -You can learn about other options by just typing `gradlew` with no arguments. diff --git a/code/annotations/AUComposition.java b/code/annotations/AUComposition.java deleted file mode 100644 index ee43e88d..00000000 --- a/code/annotations/AUComposition.java +++ /dev/null @@ -1,30 +0,0 @@ -// annotations/AUComposition.java -// (c)2020 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. -// Creating non-embedded tests -// {java onjava.atunit.AtUnit -// build/classes/java/main/annotations/AUComposition.class} -package annotations; -import onjava.atunit.*; -import onjava.*; - -public class AUComposition { - AtUnitExample1 testObject = new AtUnitExample1(); - @Test - boolean tMethodOne() { - return testObject.methodOne() - .equals("This is methodOne"); - } - @Test - boolean tMethodTwo() { - return testObject.methodTwo() == 2; - } -} -/* Output: -annotations.AUComposition - . tMethodTwo This is methodTwo - - . tMethodOne -OK (2 tests) -*/ diff --git a/code/annotations/AUExternalTest.java b/code/annotations/AUExternalTest.java deleted file mode 100644 index cce5c429..00000000 --- a/code/annotations/AUExternalTest.java +++ /dev/null @@ -1,29 +0,0 @@ -// annotations/AUExternalTest.java -// (c)2020 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. -// Creating non-embedded tests -// {java onjava.atunit.AtUnit -// build/classes/java/main/annotations/AUExternalTest.class} -package annotations; -import onjava.atunit.*; -import onjava.*; - -public class -AUExternalTest extends AtUnitExample1 { - @Test - boolean tMethodOne() { - return methodOne().equals("This is methodOne"); - } - @Test - boolean tMethodTwo() { - return methodTwo() == 2; - } -} -/* Output: -annotations.AUExternalTest - . tMethodOne - . tMethodTwo This is methodTwo - -OK (2 tests) -*/ diff --git a/code/annotations/AtUnitExample1.java b/code/annotations/AtUnitExample1.java deleted file mode 100644 index 3b1f6fec..00000000 --- a/code/annotations/AtUnitExample1.java +++ /dev/null @@ -1,48 +0,0 @@ -// annotations/AtUnitExample1.java -// (c)2020 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. -// {java onjava.atunit.AtUnit -// build/classes/java/main/annotations/AtUnitExample1.class} -package annotations; -import onjava.atunit.*; -import onjava.*; - -public class AtUnitExample1 { - public String methodOne() { - return "This is methodOne"; - } - public int methodTwo() { - System.out.println("This is methodTwo"); - return 2; - } - @Test - boolean methodOneTest() { - return methodOne().equals("This is methodOne"); - } - @Test - boolean m2() { return methodTwo() == 2; } - @Test - private boolean m3() { return true; } - // Shows output for failure: - @Test - boolean failureTest() { return false; } - @Test - boolean anotherDisappointment() { - return false; - } -} -/* Output: -annotations.AtUnitExample1 - . m3 - . methodOneTest - . m2 This is methodTwo - - . failureTest (failed) - . anotherDisappointment (failed) -(5 tests) - ->>> 2 FAILURES <<< - annotations.AtUnitExample1: failureTest - annotations.AtUnitExample1: anotherDisappointment -*/ diff --git a/code/annotations/AtUnitExample2.java b/code/annotations/AtUnitExample2.java deleted file mode 100644 index bf3f1d5c..00000000 --- a/code/annotations/AtUnitExample2.java +++ /dev/null @@ -1,57 +0,0 @@ -// annotations/AtUnitExample2.java -// (c)2020 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. -// Assertions and exceptions can be used in @Tests -// {java onjava.atunit.AtUnit -// build/classes/java/main/annotations/AtUnitExample2.class} -package annotations; -import java.io.*; -import onjava.atunit.*; -import onjava.*; - -public class AtUnitExample2 { - public String methodOne() { - return "This is methodOne"; - } - public int methodTwo() { - System.out.println("This is methodTwo"); - return 2; - } - @Test - void assertExample() { - assert methodOne().equals("This is methodOne"); - } - @Test - void assertFailureExample() { - assert 1 == 2: "What a surprise!"; - } - @Test - void exceptionExample() throws IOException { - try(FileInputStream fis = - new FileInputStream("nofile.txt")) {} // Throws - } - @Test - boolean assertAndReturn() { - // Assertion with message: - assert methodTwo() == 2: "methodTwo must equal 2"; - return methodOne().equals("This is methodOne"); - } -} -/* Output: -annotations.AtUnitExample2 - . exceptionExample java.io.FileNotFoundException: -nofile.txt (The system cannot find the file specified) -(failed) - . assertExample - . assertAndReturn This is methodTwo - - . assertFailureExample java.lang.AssertionError: What -a surprise! -(failed) -(4 tests) - ->>> 2 FAILURES <<< - annotations.AtUnitExample2: exceptionExample - annotations.AtUnitExample2: assertFailureExample -*/ diff --git a/code/annotations/AtUnitExample3.java b/code/annotations/AtUnitExample3.java deleted file mode 100644 index 02092591..00000000 --- a/code/annotations/AtUnitExample3.java +++ /dev/null @@ -1,42 +0,0 @@ -// annotations/AtUnitExample3.java -// (c)2020 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. -// {java onjava.atunit.AtUnit -// build/classes/java/main/annotations/AtUnitExample3.class} -package annotations; -import onjava.atunit.*; -import onjava.*; - -public class AtUnitExample3 { - private int n; - public AtUnitExample3(int n) { this.n = n; } - public int getN() { return n; } - public String methodOne() { - return "This is methodOne"; - } - public int methodTwo() { - System.out.println("This is methodTwo"); - return 2; - } - @TestObjectCreate - static AtUnitExample3 create() { - return new AtUnitExample3(47); - } - @Test - boolean initialization() { return n == 47; } - @Test - boolean methodOneTest() { - return methodOne().equals("This is methodOne"); - } - @Test - boolean m2() { return methodTwo() == 2; } -} -/* Output: -annotations.AtUnitExample3 - . initialization - . m2 This is methodTwo - - . methodOneTest -OK (3 tests) -*/ diff --git a/code/annotations/AtUnitExample4.java b/code/annotations/AtUnitExample4.java deleted file mode 100644 index 6b644b17..00000000 --- a/code/annotations/AtUnitExample4.java +++ /dev/null @@ -1,83 +0,0 @@ -// annotations/AtUnitExample4.java -// (c)2020 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. -// {java onjava.atunit.AtUnit -// build/classes/java/main/annotations/AtUnitExample4.class} -// {VisuallyInspectOutput} -package annotations; -import java.util.*; -import onjava.atunit.*; -import onjava.*; - -public class AtUnitExample4 { - static String theory = "All brontosauruses " + - "are thin at one end, much MUCH thicker in the " + - "middle, and then thin again at the far end."; - private String word; - private Random rand = new Random(); // Time-based seed - public AtUnitExample4(String word) { - this.word = word; - } - public String getWord() { return word; } - public String scrambleWord() { - List chars = Arrays.asList( - ConvertTo.boxed(word.toCharArray())); - Collections.shuffle(chars, rand); - StringBuilder result = new StringBuilder(); - for(char ch : chars) - result.append(ch); - return result.toString(); - } - @TestProperty - static List input = - Arrays.asList(theory.split(" ")); - @TestProperty - static Iterator words = input.iterator(); - @TestObjectCreate - static AtUnitExample4 create() { - if(words.hasNext()) - return new AtUnitExample4(words.next()); - else - return null; - } - @Test - boolean words() { - System.out.println("'" + getWord() + "'"); - return getWord().equals("are"); - } - @Test - boolean scramble1() { - // Use specific seed to get verifiable results: - rand = new Random(47); - System.out.println("'" + getWord() + "'"); - String scrambled = scrambleWord(); - System.out.println(scrambled); - return scrambled.equals("lAl"); - } - @Test - boolean scramble2() { - rand = new Random(74); - System.out.println("'" + getWord() + "'"); - String scrambled = scrambleWord(); - System.out.println(scrambled); - return scrambled.equals("tsaeborornussu"); - } -} -/* Output: -annotations.AtUnitExample4 - . words 'All' -(failed) - . scramble1 'brontosauruses' -ntsaueorosurbs -(failed) - . scramble2 'are' -are -(failed) -(3 tests) - ->>> 3 FAILURES <<< - annotations.AtUnitExample4: words - annotations.AtUnitExample4: scramble1 - annotations.AtUnitExample4: scramble2 -*/ diff --git a/code/annotations/AtUnitExample5.java b/code/annotations/AtUnitExample5.java deleted file mode 100644 index d7cf95df..00000000 --- a/code/annotations/AtUnitExample5.java +++ /dev/null @@ -1,63 +0,0 @@ -// annotations/AtUnitExample5.java -// (c)2020 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. -// {java onjava.atunit.AtUnit -// build/classes/java/main/annotations/AtUnitExample5.class} -package annotations; -import java.io.*; -import onjava.atunit.*; -import onjava.*; - -public class AtUnitExample5 { - private String text; - public AtUnitExample5(String text) { - this.text = text; - } - @Override - public String toString() { return text; } - @TestProperty - static PrintWriter output; - @TestProperty - static int counter; - @TestObjectCreate - static AtUnitExample5 create() { - String id = Integer.toString(counter++); - try { - output = new PrintWriter("Test" + id + ".txt"); - } catch(IOException e) { - throw new RuntimeException(e); - } - return new AtUnitExample5(id); - } - @TestObjectCleanup - static void cleanup(AtUnitExample5 tobj) { - System.out.println("Running cleanup"); - output.close(); - } - @Test - boolean test1() { - output.print("test1"); - return true; - } - @Test - boolean test2() { - output.print("test2"); - return true; - } - @Test - boolean test3() { - output.print("test3"); - return true; - } -} -/* Output: -annotations.AtUnitExample5 - . test1 -Running cleanup - . test3 -Running cleanup - . test2 -Running cleanup -OK (3 tests) -*/ diff --git a/code/annotations/DemoProcessFiles.java b/code/annotations/DemoProcessFiles.java deleted file mode 100644 index 6e250537..00000000 --- a/code/annotations/DemoProcessFiles.java +++ /dev/null @@ -1,43 +0,0 @@ -// annotations/DemoProcessFiles.java -// (c)2020 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. -import onjava.ProcessFiles; - -public class DemoProcessFiles { - public static void main(String[] args) { - new ProcessFiles(file -> System.out.println(file), - "java").start(args); - } -} -/* Output: -.\AtUnitExample1.java -.\AtUnitExample2.java -.\AtUnitExample3.java -.\AtUnitExample4.java -.\AtUnitExample5.java -.\AUComposition.java -.\AUExternalTest.java -.\database\Constraints.java -.\database\DBTable.java -.\database\Member.java -.\database\SQLInteger.java -.\database\SQLString.java -.\database\TableCreator.java -.\database\Uniqueness.java -.\DemoProcessFiles.java -.\HashSetTest.java -.\ifx\ExtractInterface.java -.\ifx\IfaceExtractorProcessor.java -.\ifx\Multiplier.java -.\PasswordUtils.java -.\simplest\Simple.java -.\simplest\SimpleProcessor.java -.\simplest\SimpleTest.java -.\SimulatingNull.java -.\StackL.java -.\StackLStringTst.java -.\Testable.java -.\UseCase.java -.\UseCaseTracker.java -*/ diff --git a/code/annotations/HashSetTest.java b/code/annotations/HashSetTest.java deleted file mode 100644 index 8dfa8a9c..00000000 --- a/code/annotations/HashSetTest.java +++ /dev/null @@ -1,36 +0,0 @@ -// annotations/HashSetTest.java -// (c)2020 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. -// {java onjava.atunit.AtUnit -// build/classes/java/main/annotations/HashSetTest.class} -package annotations; -import java.util.*; -import onjava.atunit.*; -import onjava.*; - -public class HashSetTest { - HashSet testObject = new HashSet<>(); - @Test - void initialization() { - assert testObject.isEmpty(); - } - @Test - void tContains() { - testObject.add("one"); - assert testObject.contains("one"); - } - @Test - void tRemove() { - testObject.add("one"); - testObject.remove("one"); - assert testObject.isEmpty(); - } -} -/* Output: -annotations.HashSetTest - . initialization - . tRemove - . tContains -OK (3 tests) -*/ diff --git a/code/annotations/PasswordUtils.java b/code/annotations/PasswordUtils.java deleted file mode 100644 index 74a6df78..00000000 --- a/code/annotations/PasswordUtils.java +++ /dev/null @@ -1,24 +0,0 @@ -// annotations/PasswordUtils.java -// (c)2020 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. -import java.util.*; - -public class PasswordUtils { - @UseCase(id = 47, description = - "Passwords must contain at least one numeric") - public boolean validatePassword(String passwd) { - return (passwd.matches("\\w*\\d\\w*")); - } - @UseCase(id = 48) - public String encryptPassword(String passwd) { - return new StringBuilder(passwd) - .reverse().toString(); - } - @UseCase(id = 49, description = - "New passwords can't equal previously used ones") - public boolean checkForNewPassword( - List prevPasswords, String passwd) { - return !prevPasswords.contains(passwd); - } -} diff --git a/code/annotations/SimulatingNull.java b/code/annotations/SimulatingNull.java deleted file mode 100644 index 8166802b..00000000 --- a/code/annotations/SimulatingNull.java +++ /dev/null @@ -1,12 +0,0 @@ -// annotations/SimulatingNull.java -// (c)2020 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. -import java.lang.annotation.*; - -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface SimulatingNull { - int id() default -1; - String description() default ""; -} diff --git a/code/annotations/StackL.java b/code/annotations/StackL.java deleted file mode 100644 index 6ff806af..00000000 --- a/code/annotations/StackL.java +++ /dev/null @@ -1,14 +0,0 @@ -// annotations/StackL.java -// (c)2020 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. -// A stack built on a LinkedList -package annotations; -import java.util.*; - -public class StackL { - private LinkedList list = new LinkedList<>(); - public void push(T v) { list.addFirst(v); } - public T top() { return list.getFirst(); } - public T pop() { return list.removeFirst(); } -} diff --git a/code/annotations/StackLStringTst.java b/code/annotations/StackLStringTst.java deleted file mode 100644 index 49aef9b7..00000000 --- a/code/annotations/StackLStringTst.java +++ /dev/null @@ -1,42 +0,0 @@ -// annotations/StackLStringTst.java -// (c)2020 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. -// Applying @Unit to generics -// {java onjava.atunit.AtUnit -// build/classes/java/main/annotations/StackLStringTst.class} -package annotations; -import onjava.atunit.*; -import onjava.*; - -public class -StackLStringTst extends StackL { - @Test - void tPush() { - push("one"); - assert top().equals("one"); - push("two"); - assert top().equals("two"); - } - @Test - void tPop() { - push("one"); - push("two"); - assert pop().equals("two"); - assert pop().equals("one"); - } - @Test - void tTop() { - push("A"); - push("B"); - assert top().equals("B"); - assert top().equals("B"); - } -} -/* Output: -annotations.StackLStringTst - . tTop - . tPush - . tPop -OK (3 tests) -*/ diff --git a/code/annotations/Testable.java b/code/annotations/Testable.java deleted file mode 100644 index bc48f416..00000000 --- a/code/annotations/Testable.java +++ /dev/null @@ -1,14 +0,0 @@ -// annotations/Testable.java -// (c)2020 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 annotations; -import onjava.atunit.*; - -public class Testable { - public void execute() { - System.out.println("Executing.."); - } - @Test - void testExecute() { execute(); } -} diff --git a/code/annotations/UseCase.java b/code/annotations/UseCase.java deleted file mode 100644 index dfce3149..00000000 --- a/code/annotations/UseCase.java +++ /dev/null @@ -1,12 +0,0 @@ -// annotations/UseCase.java -// (c)2020 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. -import java.lang.annotation.*; - -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface UseCase { - int id(); - String description() default "no description"; -} diff --git a/code/annotations/UseCaseTracker.java b/code/annotations/UseCaseTracker.java deleted file mode 100644 index 5489b762..00000000 --- a/code/annotations/UseCaseTracker.java +++ /dev/null @@ -1,37 +0,0 @@ -// annotations/UseCaseTracker.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import java.lang.reflect.*; - -public class UseCaseTracker { - public static void - trackUseCases(List useCases, Class cl) { - for(Method m : cl.getDeclaredMethods()) { - UseCase uc = m.getAnnotation(UseCase.class); - if(uc != null) { - System.out.println("Found Use Case " + - uc.id() + "\n " + uc.description()); - useCases.remove(Integer.valueOf(uc.id())); - } - } - useCases.forEach(i -> - System.out.println("Missing use case " + i)); - } - public static void main(String[] args) { - List useCases = IntStream.range(47, 51) - .boxed().collect(Collectors.toList()); - trackUseCases(useCases, PasswordUtils.class); - } -} -/* Output: -Found Use Case 48 - no description -Found Use Case 47 - Passwords must contain at least one numeric -Found Use Case 49 - New passwords can't equal previously used ones -Missing use case 50 -*/ diff --git a/code/annotations/database/Constraints.java b/code/annotations/database/Constraints.java deleted file mode 100644 index 4e4e40fc..00000000 --- a/code/annotations/database/Constraints.java +++ /dev/null @@ -1,14 +0,0 @@ -// annotations/database/Constraints.java -// (c)2020 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 annotations.database; -import java.lang.annotation.*; - -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.RUNTIME) -public @interface Constraints { - boolean primaryKey() default false; - boolean allowNull() default true; - boolean unique() default false; -} diff --git a/code/annotations/database/DBTable.java b/code/annotations/database/DBTable.java deleted file mode 100644 index 9aa5562f..00000000 --- a/code/annotations/database/DBTable.java +++ /dev/null @@ -1,12 +0,0 @@ -// annotations/database/DBTable.java -// (c)2020 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 annotations.database; -import java.lang.annotation.*; - -@Target(ElementType.TYPE) // Applies to classes only -@Retention(RetentionPolicy.RUNTIME) -public @interface DBTable { - String name() default ""; -} diff --git a/code/annotations/database/Member.java b/code/annotations/database/Member.java deleted file mode 100644 index d722a3b1..00000000 --- a/code/annotations/database/Member.java +++ /dev/null @@ -1,22 +0,0 @@ -// annotations/database/Member.java -// (c)2020 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 annotations.database; - -@DBTable(name = "MEMBER") -public class Member { - @SQLString(30) String firstName; - @SQLString(50) String lastName; - @SQLInteger Integer age; - @SQLString(value = 30, - constraints = @Constraints(primaryKey = true)) - String reference; - static int memberCount; - public String getReference() { return reference; } - public String getFirstName() { return firstName; } - public String getLastName() { return lastName; } - @Override - public String toString() { return reference; } - public Integer getAge() { return age; } -} diff --git a/code/annotations/database/SQLInteger.java b/code/annotations/database/SQLInteger.java deleted file mode 100644 index 635a907c..00000000 --- a/code/annotations/database/SQLInteger.java +++ /dev/null @@ -1,13 +0,0 @@ -// annotations/database/SQLInteger.java -// (c)2020 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 annotations.database; -import java.lang.annotation.*; - -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.RUNTIME) -public @interface SQLInteger { - String name() default ""; - Constraints constraints() default @Constraints; -} diff --git a/code/annotations/database/SQLString.java b/code/annotations/database/SQLString.java deleted file mode 100644 index dac9919f..00000000 --- a/code/annotations/database/SQLString.java +++ /dev/null @@ -1,14 +0,0 @@ -// annotations/database/SQLString.java -// (c)2020 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 annotations.database; -import java.lang.annotation.*; - -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.RUNTIME) -public @interface SQLString { - int value() default 0; - String name() default ""; - Constraints constraints() default @Constraints; -} diff --git a/code/annotations/database/TableCreator.java b/code/annotations/database/TableCreator.java deleted file mode 100644 index 53322fc7..00000000 --- a/code/annotations/database/TableCreator.java +++ /dev/null @@ -1,106 +0,0 @@ -// annotations/database/TableCreator.java -// (c)2020 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. -// Reflection-based annotation processor -// {java annotations.database.TableCreator -// annotations.database.Member} -package annotations.database; -import java.lang.annotation.*; -import java.lang.reflect.*; -import java.util.*; - -public class TableCreator { - public static void - main(String[] args) throws Exception { - if(args.length < 1) { - System.out.println( - "arguments: annotated classes"); - System.exit(0); - } - for(String className : args) { - Class cl = Class.forName(className); - DBTable dbTable = cl.getAnnotation(DBTable.class); - if(dbTable == null) { - System.out.println( - "No DBTable annotations in class " + - className); - continue; - } - String tableName = dbTable.name(); - // If the name is empty, use the Class name: - if(tableName.length() < 1) - tableName = cl.getName().toUpperCase(); - List columnDefs = new ArrayList<>(); - for(Field field : cl.getDeclaredFields()) { - String columnName = null; - Annotation[] anns = - field.getDeclaredAnnotations(); - if(anns.length < 1) - continue; // Not a db table column - if(anns[0] instanceof SQLInteger) { - SQLInteger sInt = (SQLInteger) anns[0]; - // Use field name if name not specified - if(sInt.name().length() < 1) - columnName = field.getName().toUpperCase(); - else - columnName = sInt.name(); - columnDefs.add(columnName + " INT" + - getConstraints(sInt.constraints())); - } - if(anns[0] instanceof SQLString) { - SQLString sString = (SQLString) anns[0]; - // Use field name if name not specified. - if(sString.name().length() < 1) - columnName = field.getName().toUpperCase(); - else - columnName = sString.name(); - columnDefs.add(columnName + " VARCHAR(" + - sString.value() + ")" + - getConstraints(sString.constraints())); - } - StringBuilder createCommand = new StringBuilder( - "CREATE TABLE " + tableName + "("); - for(String columnDef : columnDefs) - createCommand.append( - "\n " + columnDef + ","); - // Remove trailing comma - String tableCreate = createCommand.substring( - 0, createCommand.length() - 1) + ");"; - System.out.println("Table Creation SQL for " + - className + " is:\n" + tableCreate); - } - } - } - private static - String getConstraints(Constraints con) { - String constraints = ""; - if(!con.allowNull()) - constraints += " NOT NULL"; - if(con.primaryKey()) - constraints += " PRIMARY KEY"; - if(con.unique()) - constraints += " UNIQUE"; - return constraints; - } -} -/* Output: -Table Creation SQL for annotations.database.Member is: -CREATE TABLE MEMBER( - FIRSTNAME VARCHAR(30)); -Table Creation SQL for annotations.database.Member is: -CREATE TABLE MEMBER( - FIRSTNAME VARCHAR(30), - LASTNAME VARCHAR(50)); -Table Creation SQL for annotations.database.Member is: -CREATE TABLE MEMBER( - FIRSTNAME VARCHAR(30), - LASTNAME VARCHAR(50), - AGE INT); -Table Creation SQL for annotations.database.Member is: -CREATE TABLE MEMBER( - FIRSTNAME VARCHAR(30), - LASTNAME VARCHAR(50), - AGE INT, - REFERENCE VARCHAR(30) PRIMARY KEY); -*/ diff --git a/code/annotations/database/Uniqueness.java b/code/annotations/database/Uniqueness.java deleted file mode 100644 index 1aa1a36c..00000000 --- a/code/annotations/database/Uniqueness.java +++ /dev/null @@ -1,11 +0,0 @@ -// annotations/database/Uniqueness.java -// (c)2020 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. -// Sample of nested annotations -package annotations.database; - -public @interface Uniqueness { - Constraints constraints() - default @Constraints(unique = true); -} diff --git a/code/annotations/ifx/ExtractInterface.java b/code/annotations/ifx/ExtractInterface.java deleted file mode 100644 index 70a94bf5..00000000 --- a/code/annotations/ifx/ExtractInterface.java +++ /dev/null @@ -1,13 +0,0 @@ -// annotations/ifx/ExtractInterface.java -// (c)2020 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. -// javac-based annotation processing -package annotations.ifx; -import java.lang.annotation.*; - -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.SOURCE) -public @interface ExtractInterface { - String interfaceName() default "-!!-"; -} diff --git a/code/annotations/ifx/IfaceExtractorProcessor.java b/code/annotations/ifx/IfaceExtractorProcessor.java deleted file mode 100644 index d17156f8..00000000 --- a/code/annotations/ifx/IfaceExtractorProcessor.java +++ /dev/null @@ -1,91 +0,0 @@ -// annotations/ifx/IfaceExtractorProcessor.java -// (c)2020 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. -// javac-based annotation processing -package annotations.ifx; -import javax.annotation.processing.*; -import javax.lang.model.SourceVersion; -import javax.lang.model.element.*; -import javax.lang.model.util.*; -import java.util.*; -import java.util.stream.*; -import java.io.*; - -@SupportedAnnotationTypes( - "annotations.ifx.ExtractInterface") -@SupportedSourceVersion(SourceVersion.RELEASE_8) -public class IfaceExtractorProcessor -extends AbstractProcessor { - private ArrayList - interfaceMethods = new ArrayList<>(); - Elements elementUtils; - private ProcessingEnvironment processingEnv; - @Override - public void init( - ProcessingEnvironment processingEnv) { - this.processingEnv = processingEnv; - elementUtils = processingEnv.getElementUtils(); - } - @Override - public boolean process( - Set annotations, - RoundEnvironment env) { - for(Element elem:env.getElementsAnnotatedWith( - ExtractInterface.class)) { - String interfaceName = elem.getAnnotation( - ExtractInterface.class).interfaceName(); - for(Element enclosed : - elem.getEnclosedElements()) { - if(enclosed.getKind() - .equals(ElementKind.METHOD) && - enclosed.getModifiers() - .contains(Modifier.PUBLIC) && - !enclosed.getModifiers() - .contains(Modifier.STATIC)) { - interfaceMethods.add(enclosed); - } - } - if(interfaceMethods.size() > 0) - writeInterfaceFile(interfaceName); - } - return false; - } - private void - writeInterfaceFile(String interfaceName) { - try( - Writer writer = processingEnv.getFiler() - .createSourceFile(interfaceName) - .openWriter() - ) { - String packageName = elementUtils - .getPackageOf(interfaceMethods - .get(0)).toString(); - writer.write( - "package " + packageName + ";\n"); - writer.write("public interface " + - interfaceName + " {\n"); - for(Element elem : interfaceMethods) { - ExecutableElement method = - (ExecutableElement)elem; - String signature = " public "; - signature += method.getReturnType() + " "; - signature += method.getSimpleName(); - signature += createArgList( - method.getParameters()); - System.out.println(signature); - writer.write(signature + ";\n"); - } - writer.write("}"); - } catch(Exception e) { - throw new RuntimeException(e); - } - } - private String createArgList( - List parameters) { - String args = parameters.stream() - .map(p -> p.asType() + " " + p.getSimpleName()) - .collect(Collectors.joining(", ")); - return "(" + args + ")"; - } -} diff --git a/code/annotations/ifx/Multiplier.java b/code/annotations/ifx/Multiplier.java deleted file mode 100644 index b5b99a1b..00000000 --- a/code/annotations/ifx/Multiplier.java +++ /dev/null @@ -1,34 +0,0 @@ -// annotations/ifx/Multiplier.java -// (c)2020 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. -// javac-based annotation processing -// {java annotations.ifx.Multiplier} -package annotations.ifx; - -@ExtractInterface(interfaceName="IMultiplier") -public class Multiplier { - public boolean flag = false; - private int n = 0; - public int multiply(int x, int y) { - int total = 0; - for(int i = 0; i < x; i++) - total = add(total, y); - return total; - } - public int fortySeven() { return 47; } - private int add(int x, int y) { - return x + y; - } - public double timesTen(double arg) { - return arg * 10; - } - public static void main(String[] args) { - Multiplier m = new Multiplier(); - System.out.println( - "11 * 16 = " + m.multiply(11, 16)); - } -} -/* Output: -11 * 16 = 176 -*/ diff --git a/code/annotations/simplest/Simple.java b/code/annotations/simplest/Simple.java deleted file mode 100644 index 0dc555ce..00000000 --- a/code/annotations/simplest/Simple.java +++ /dev/null @@ -1,20 +0,0 @@ -// annotations/simplest/Simple.java -// (c)2020 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. -// A bare-bones annotation -package annotations.simplest; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.annotation.ElementType; - -@Retention(RetentionPolicy.SOURCE) -@Target({ElementType.TYPE, ElementType.METHOD, - ElementType.CONSTRUCTOR, - ElementType.ANNOTATION_TYPE, - ElementType.PACKAGE, ElementType.FIELD, - ElementType.LOCAL_VARIABLE}) -public @interface Simple { - String value() default "-default-"; -} diff --git a/code/annotations/simplest/SimpleProcessor.java b/code/annotations/simplest/SimpleProcessor.java deleted file mode 100644 index a85d8987..00000000 --- a/code/annotations/simplest/SimpleProcessor.java +++ /dev/null @@ -1,47 +0,0 @@ -// annotations/simplest/SimpleProcessor.java -// (c)2020 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. -// A bare-bones annotation processor -package annotations.simplest; -import javax.annotation.processing.*; -import javax.lang.model.SourceVersion; -import javax.lang.model.element.*; -import java.util.*; - -@SupportedAnnotationTypes( - "annotations.simplest.Simple") -@SupportedSourceVersion(SourceVersion.RELEASE_8) -public class SimpleProcessor -extends AbstractProcessor { - @Override - public boolean process( - Set annotations, - RoundEnvironment env) { - for(TypeElement t : annotations) - System.out.println(t); - for(Element el : - env.getElementsAnnotatedWith(Simple.class)) - display(el); - return false; - } - private void display(Element el) { - System.out.println("==== " + el + " ===="); - System.out.println(el.getKind() + - " : " + el.getModifiers() + - " : " + el.getSimpleName() + - " : " + el.asType()); - if(el.getKind().equals(ElementKind.CLASS)) { - TypeElement te = (TypeElement)el; - System.out.println(te.getQualifiedName()); - System.out.println(te.getSuperclass()); - System.out.println(te.getEnclosedElements()); - } - if(el.getKind().equals(ElementKind.METHOD)) { - ExecutableElement ex = (ExecutableElement)el; - System.out.print(ex.getReturnType() + " "); - System.out.print(ex.getSimpleName() + "("); - System.out.println(ex.getParameters() + ")"); - } - } -} diff --git a/code/annotations/simplest/SimpleTest.java b/code/annotations/simplest/SimpleTest.java deleted file mode 100644 index 689d12fd..00000000 --- a/code/annotations/simplest/SimpleTest.java +++ /dev/null @@ -1,32 +0,0 @@ -// annotations/simplest/SimpleTest.java -// (c)2020 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. -// Test the "Simple" annotation -// {java annotations.simplest.SimpleTest} -package annotations.simplest; - -@Simple -public class SimpleTest { - @Simple - int i; - @Simple - public SimpleTest() {} - @Simple - public void foo() { - System.out.println("SimpleTest.foo()"); - } - @Simple - public void bar(String s, int i, float f) { - System.out.println("SimpleTest.bar()"); - } - @Simple - public static void main(String[] args) { - @Simple - SimpleTest st = new SimpleTest(); - st.foo(); - } -} -/* Output: -SimpleTest.foo() -*/ diff --git a/code/appveyorXX.yml b/code/appveyorXX.yml deleted file mode 100644 index 5e586b07..00000000 --- a/code/appveyorXX.yml +++ /dev/null @@ -1,4 +0,0 @@ -build_script: - - gradlew.bat --no-daemon --stacktrace run - -test: off diff --git a/code/arrays/AlphabeticSearch.java b/code/arrays/AlphabeticSearch.java deleted file mode 100644 index 70adc8ff..00000000 --- a/code/arrays/AlphabeticSearch.java +++ /dev/null @@ -1,29 +0,0 @@ -// arrays/AlphabeticSearch.java -// (c)2020 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. -// Searching with a Comparator import -import java.util.*; -import onjava.*; -import static onjava.ArrayShow.*; - -public class AlphabeticSearch { - public static void main(String[] args) { - String[] sa = new Rand.String().array(30); - Arrays.sort(sa, String.CASE_INSENSITIVE_ORDER); - show(sa); - int index = Arrays.binarySearch(sa, - sa[10], String.CASE_INSENSITIVE_ORDER); - System.out.println( - "Index: "+ index + "\n"+ sa[index]); - } -} -/* Output: -[anmkkyh, bhmupju, btpenpc, cjwzmmr, cuxszgv, eloztdv, -ewcippc, ezdeklu, fcjpthl, fqmlgsh, gmeinne, hyoubzl, -jbvlgwc, jlxpqds, ljlbynx, mvducuj, qgekgly, skddcat, -taprwxz, uybypgp, vjsszkn, vniyapk, vqqakbm, vwodhcf, -ydpulcq, ygpoalk, yskvett, zehpfmm, zofmmvm, zrxmclh] -Index: 10 -gmeinne -*/ diff --git a/code/arrays/ArrayCopying.java b/code/arrays/ArrayCopying.java deleted file mode 100644 index c68c2a0d..00000000 --- a/code/arrays/ArrayCopying.java +++ /dev/null @@ -1,81 +0,0 @@ -// arrays/ArrayCopying.java -// (c)2020 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. -// Demonstrate Arrays.copy() and Arrays.copyOf() -import java.util.*; -import onjava.*; -import static onjava.ArrayShow.*; - -class Sup { // Superclass - private int id; - Sup(int n) { id = n; } - @Override - public String toString() { - return getClass().getSimpleName() + id; - } -} - -class Sub extends Sup { // Subclass - Sub(int n) { super(n); } -} - -public class ArrayCopying { - public static final int SZ = 15; - public static void main(String[] args) { - int[] a1 = new int[SZ]; - Arrays.setAll(a1, new Count.Integer()::get); - show("a1", a1); - int[] a2 = Arrays.copyOf(a1, a1.length); // [1] - // Prove they are distinct arrays: - Arrays.fill(a1, 1); - show("a1", a1); - show("a2", a2); - - // Create a shorter result: - a2 = Arrays.copyOf(a2, a2.length/2); // [2] - show("a2", a2); - // Allocate more space: - a2 = Arrays.copyOf(a2, a2.length + 5); - show("a2", a2); - - // Also copies wrapped arrays: - Integer[] a3 = new Integer[SZ]; // [3] - Arrays.setAll(a3, new Count.Integer()::get); - Integer[] a4 = Arrays.copyOfRange(a3, 4, 12); - show("a4", a4); - - Sub[] d = new Sub[SZ/2]; - Arrays.setAll(d, Sub::new); - // Produce Sup[] from Sub[]: - Sup[] b = - Arrays.copyOf(d, d.length, Sup[].class); // [4] - show(b); - - // This "downcast" works fine: - Sub[] d2 = - Arrays.copyOf(b, b.length, Sub[].class); // [5] - show(d2); - - // Bad "downcast" compiles but throws exception: - Sup[] b2 = new Sup[SZ/2]; - Arrays.setAll(b2, Sup::new); - try { - Sub[] d3 = Arrays.copyOf( - b2, b2.length, Sub[].class); // [6] - } catch(Exception e) { - System.out.println(e); - } - } -} -/* Output: -a1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] -a1: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] -a2: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] -a2: [0, 1, 2, 3, 4, 5, 6] -a2: [0, 1, 2, 3, 4, 5, 6, 0, 0, 0, 0, 0] -a4: [4, 5, 6, 7, 8, 9, 10, 11] -[Sub0, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6] -[Sub0, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6] -java.lang.ArrayStoreException -*/ diff --git a/code/arrays/ArrayOfGenericType.java b/code/arrays/ArrayOfGenericType.java deleted file mode 100644 index 68f9e8de..00000000 --- a/code/arrays/ArrayOfGenericType.java +++ /dev/null @@ -1,16 +0,0 @@ -// arrays/ArrayOfGenericType.java -// (c)2020 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. - -public class ArrayOfGenericType { - T[] array; // OK - @SuppressWarnings("unchecked") - public ArrayOfGenericType(int size) { - // error: generic array creation: - //- array = new T[size]; - array = (T[])new Object[size]; // unchecked cast - } - // error: generic array creation: - //- public U[] makeArray() { return new U[10]; } -} diff --git a/code/arrays/ArrayOfGenerics.java b/code/arrays/ArrayOfGenerics.java deleted file mode 100644 index 79971d7a..00000000 --- a/code/arrays/ArrayOfGenerics.java +++ /dev/null @@ -1,33 +0,0 @@ -// arrays/ArrayOfGenerics.java -// (c)2020 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. -import java.util.*; - -public class ArrayOfGenerics { - @SuppressWarnings("unchecked") - public static void main(String[] args) { - List[] ls; - List[] la = new List[10]; - ls = (List[])la; // Unchecked cast - ls[0] = new ArrayList<>(); - - //- ls[1] = new ArrayList(); - // error: incompatible types: ArrayList - // cannot be converted to List - // ls[1] = new ArrayList(); - // ^ - - // The problem: List is a subtype of Object - Object[] objects = ls; // So assignment is OK - // Compiles and runs without complaint: - objects[1] = new ArrayList<>(); - - // However, if your needs are straightforward it is - // possible to create an array of generics, albeit - // with an "unchecked cast" warning: - List[] spheres = - (List[])new List[10]; - Arrays.setAll(spheres, n -> new ArrayList<>()); - } -} diff --git a/code/arrays/ArrayOptions.java b/code/arrays/ArrayOptions.java deleted file mode 100644 index bb6cbfbb..00000000 --- a/code/arrays/ArrayOptions.java +++ /dev/null @@ -1,79 +0,0 @@ -// arrays/ArrayOptions.java -// (c)2020 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. -// Initialization & re-assignment of arrays -import java.util.*; -import static onjava.ArrayShow.*; - -public class ArrayOptions { - public static void main(String[] args) { - // Arrays of objects: - BerylliumSphere[] a; // Uninitialized local - BerylliumSphere[] b = new BerylliumSphere[5]; - - // The references inside the array are - // automatically initialized to null: - show("b", b); - BerylliumSphere[] c = new BerylliumSphere[4]; - for(int i = 0; i < c.length; i++) - if(c[i] == null) // Can test for null reference - c[i] = new BerylliumSphere(); - - // Aggregate initialization: - BerylliumSphere[] d = { - new BerylliumSphere(), - new BerylliumSphere(), - new BerylliumSphere() - }; - - // Dynamic aggregate initialization: - a = new BerylliumSphere[]{ - new BerylliumSphere(), new BerylliumSphere(), - }; - // (Trailing comma is optional) - - System.out.println("a.length = " + a.length); - System.out.println("b.length = " + b.length); - System.out.println("c.length = " + c.length); - System.out.println("d.length = " + d.length); - a = d; - System.out.println("a.length = " + a.length); - - // Arrays of primitives: - int[] e; // Null reference - int[] f = new int[5]; - - // The primitives inside the array are - // automatically initialized to zero: - show("f", f); - int[] g = new int[4]; - for(int i = 0; i < g.length; i++) - g[i] = i*i; - int[] h = { 11, 47, 93 }; - - // Compile error: variable e not initialized: - //- System.out.println("e.length = " + e.length); - System.out.println("f.length = " + f.length); - System.out.println("g.length = " + g.length); - System.out.println("h.length = " + h.length); - e = h; - System.out.println("e.length = " + e.length); - e = new int[]{ 1, 2 }; - System.out.println("e.length = " + e.length); - } -} -/* Output: -b: [null, null, null, null, null] -a.length = 2 -b.length = 5 -c.length = 4 -d.length = 3 -a.length = 3 -f: [0, 0, 0, 0, 0] -f.length = 5 -g.length = 4 -h.length = 3 -e.length = 3 -e.length = 2 -*/ diff --git a/code/arrays/ArraySearching.java b/code/arrays/ArraySearching.java deleted file mode 100644 index fb4085e9..00000000 --- a/code/arrays/ArraySearching.java +++ /dev/null @@ -1,33 +0,0 @@ -// arrays/ArraySearching.java -// (c)2020 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. -// Using Arrays.binarySearch() -import java.util.*; -import onjava.*; -import static onjava.ArrayShow.*; - -public class ArraySearching { - public static void main(String[] args) { - Rand.Pint rand = new Rand.Pint(); - int[] a = new Rand.Pint().array(25); - Arrays.sort(a); - show("Sorted array", a); - while(true) { - int r = rand.getAsInt(); - int location = Arrays.binarySearch(a, r); - if(location >= 0) { - System.out.println( - "Location of " + r + " is " + location + - ", a[" + location + "] is " + a[location]); - break; // Out of while loop - } - } - } -} -/* Output: -Sorted array: [125, 267, 635, 650, 1131, 1506, 1634, -2400, 2766, 3063, 3768, 3941, 4720, 4762, 4948, 5070, -5682, 5807, 6177, 6193, 6656, 7021, 8479, 8737, 9954] -Location of 635 is 2, a[2] is 635 -*/ diff --git a/code/arrays/AssemblingMultidimensionalArrays.java b/code/arrays/AssemblingMultidimensionalArrays.java deleted file mode 100644 index e79302b3..00000000 --- a/code/arrays/AssemblingMultidimensionalArrays.java +++ /dev/null @@ -1,22 +0,0 @@ -// arrays/AssemblingMultidimensionalArrays.java -// (c)2020 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. -// Creating multidimensional arrays -import java.util.*; - -public class AssemblingMultidimensionalArrays { - public static void main(String[] args) { - Integer[][] a; - a = new Integer[3][]; - for(int i = 0; i < a.length; i++) { - a[i] = new Integer[3]; - for(int j = 0; j < a[i].length; j++) - a[i][j] = i * j; // Autoboxing - } - System.out.println(Arrays.deepToString(a)); - } -} -/* Output: -[[0, 0, 0], [0, 1, 2], [0, 2, 4]] -*/ diff --git a/code/arrays/AutoboxingArrays.java b/code/arrays/AutoboxingArrays.java deleted file mode 100644 index 25b3a0e8..00000000 --- a/code/arrays/AutoboxingArrays.java +++ /dev/null @@ -1,22 +0,0 @@ -// arrays/AutoboxingArrays.java -// (c)2020 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. -import java.util.*; - -public class AutoboxingArrays { - public static void main(String[] args) { - Integer[][] a = { // Autoboxing: - { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, - { 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }, - { 51, 52, 53, 54, 55, 56, 57, 58, 59, 60 }, - { 71, 72, 73, 74, 75, 76, 77, 78, 79, 80 }, - }; - System.out.println(Arrays.deepToString(a)); - } -} -/* Output: -[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [21, 22, 23, 24, 25, -26, 27, 28, 29, 30], [51, 52, 53, 54, 55, 56, 57, 58, -59, 60], [71, 72, 73, 74, 75, 76, 77, 78, 79, 80]] -*/ diff --git a/code/arrays/CollectionComparison.java b/code/arrays/CollectionComparison.java deleted file mode 100644 index fc703c0a..00000000 --- a/code/arrays/CollectionComparison.java +++ /dev/null @@ -1,53 +0,0 @@ -// arrays/CollectionComparison.java -// (c)2020 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. -import java.util.*; -import onjava.*; -import static onjava.ArrayShow.*; - -class BerylliumSphere { - private static long counter; - private final long id = counter++; - @Override - public String toString() { - return "Sphere " + id; - } -} - -public class CollectionComparison { - public static void main(String[] args) { - BerylliumSphere[] spheres = - new BerylliumSphere[10]; - for(int i = 0; i < 5; i++) - spheres[i] = new BerylliumSphere(); - show(spheres); - System.out.println(spheres[4]); - - List sphereList = Suppliers.create( - ArrayList::new, BerylliumSphere::new, 5); - System.out.println(sphereList); - System.out.println(sphereList.get(4)); - - int[] integers = { 0, 1, 2, 3, 4, 5 }; - show(integers); - System.out.println(integers[4]); - - List intList = new ArrayList<>( - Arrays.asList(0, 1, 2, 3, 4, 5)); - intList.add(97); - System.out.println(intList); - System.out.println(intList.get(4)); - } -} -/* Output: -[Sphere 0, Sphere 1, Sphere 2, Sphere 3, Sphere 4, -null, null, null, null, null] -Sphere 4 -[Sphere 5, Sphere 6, Sphere 7, Sphere 8, Sphere 9] -Sphere 9 -[0, 1, 2, 3, 4, 5] -4 -[0, 1, 2, 3, 4, 5, 97] -4 -*/ diff --git a/code/arrays/CompType.java b/code/arrays/CompType.java deleted file mode 100644 index 621b33d1..00000000 --- a/code/arrays/CompType.java +++ /dev/null @@ -1,56 +0,0 @@ -// arrays/CompType.java -// (c)2020 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. -// Implementing Comparable in a class -import java.util.*; -import java.util.function.*; -import onjava.*; -import static onjava.ArrayShow.*; - -public class CompType implements Comparable { - int i; - int j; - private static int count = 1; - public CompType(int n1, int n2) { - i = n1; - j = n2; - } - @Override - public String toString() { - String result = "[i = " + i + ", j = " + j + "]"; - if(count++ % 3 == 0) - result += "\n"; - return result; - } - @Override - public int compareTo(CompType rv) { - return (i < rv.i ? -1 : (i == rv.i ? 0 : 1)); - } - private static SplittableRandom r = - new SplittableRandom(47); - public static CompType get() { - return new CompType(r.nextInt(100), r.nextInt(100)); - } - public static void main(String[] args) { - CompType[] a = new CompType[12]; - Arrays.setAll(a, n -> get()); - show("Before sorting", a); - Arrays.sort(a); - show("After sorting", a); - } -} -/* Output: -Before sorting: [[i = 35, j = 37], [i = 41, j = 20], [i -= 77, j = 79] -, [i = 56, j = 68], [i = 48, j = 93], [i = 70, j = 7] -, [i = 0, j = 25], [i = 62, j = 34], [i = 50, j = 82] -, [i = 31, j = 67], [i = 66, j = 54], [i = 21, j = 6] -] -After sorting: [[i = 0, j = 25], [i = 21, j = 6], [i = -31, j = 67] -, [i = 35, j = 37], [i = 41, j = 20], [i = 48, j = 93] -, [i = 50, j = 82], [i = 56, j = 68], [i = 62, j = 34] -, [i = 66, j = 54], [i = 70, j = 7], [i = 77, j = 79] -] -*/ diff --git a/code/arrays/ComparatorTest.java b/code/arrays/ComparatorTest.java deleted file mode 100644 index 68f7e380..00000000 --- a/code/arrays/ComparatorTest.java +++ /dev/null @@ -1,39 +0,0 @@ -// arrays/ComparatorTest.java -// (c)2020 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. -// Implementing a Comparator for a class -import java.util.*; -import onjava.*; -import static onjava.ArrayShow.*; - -class CompTypeComparator -implements Comparator { - public int compare(CompType o1, CompType o2) { - return (o1.j < o2.j ? -1 : (o1.j == o2.j ? 0 : 1)); - } -} - -public class ComparatorTest { - public static void main(String[] args) { - CompType[] a = new CompType[12]; - Arrays.setAll(a, n -> CompType.get()); - show("Before sorting", a); - Arrays.sort(a, new CompTypeComparator()); - show("After sorting", a); - } -} -/* Output: -Before sorting: [[i = 35, j = 37], [i = 41, j = 20], [i -= 77, j = 79] -, [i = 56, j = 68], [i = 48, j = 93], [i = 70, j = 7] -, [i = 0, j = 25], [i = 62, j = 34], [i = 50, j = 82] -, [i = 31, j = 67], [i = 66, j = 54], [i = 21, j = 6] -] -After sorting: [[i = 21, j = 6], [i = 70, j = 7], [i = -41, j = 20] -, [i = 0, j = 25], [i = 62, j = 34], [i = 35, j = 37] -, [i = 66, j = 54], [i = 31, j = 67], [i = 56, j = 68] -, [i = 77, j = 79], [i = 50, j = 82], [i = 48, j = 93] -] -*/ diff --git a/code/arrays/ComparingArrays.java b/code/arrays/ComparingArrays.java deleted file mode 100644 index 9ddad69d..00000000 --- a/code/arrays/ComparingArrays.java +++ /dev/null @@ -1,62 +0,0 @@ -// arrays/ComparingArrays.java -// (c)2020 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. -// Using Arrays.equals() -import java.util.*; -import onjava.*; - -public class ComparingArrays { - public static final int SZ = 15; - static String[][] twoDArray() { - String[][] md = new String[5][]; - Arrays.setAll(md, n -> new String[n]); - for(int i = 0; i < md.length; i++) - Arrays.setAll(md[i], new Rand.String()::get); - return md; - } - public static void main(String[] args) { - int[] a1 = new int[SZ], a2 = new int[SZ]; - Arrays.setAll(a1, new Count.Integer()::get); - Arrays.setAll(a2, new Count.Integer()::get); - System.out.println( - "a1 == a2: " + Arrays.equals(a1, a2)); - a2[3] = 11; - System.out.println( - "a1 == a2: " + Arrays.equals(a1, a2)); - - Integer[] a1w = new Integer[SZ], - a2w = new Integer[SZ]; - Arrays.setAll(a1w, new Count.Integer()::get); - Arrays.setAll(a2w, new Count.Integer()::get); - System.out.println( - "a1w == a2w: " + Arrays.equals(a1w, a2w)); - a2w[3] = 11; - System.out.println( - "a1w == a2w: " + Arrays.equals(a1w, a2w)); - - String[][] md1 = twoDArray(), md2 = twoDArray(); - System.out.println(Arrays.deepToString(md1)); - System.out.println("deepEquals(md1, md2): " + - Arrays.deepEquals(md1, md2)); - System.out.println( - "md1 == md2: " + Arrays.equals(md1, md2)); - md1[4][1] = "#$#$#$#"; - System.out.println(Arrays.deepToString(md1)); - System.out.println("deepEquals(md1, md2): " + - Arrays.deepEquals(md1, md2)); - } -} -/* Output: -a1 == a2: true -a1 == a2: false -a1w == a2w: true -a1w == a2w: false -[[], [btpenpc], [btpenpc, cuxszgv], [btpenpc, cuxszgv, -gmeinne], [btpenpc, cuxszgv, gmeinne, eloztdv]] -deepEquals(md1, md2): true -md1 == md2: false -[[], [btpenpc], [btpenpc, cuxszgv], [btpenpc, cuxszgv, -gmeinne], [btpenpc, #$#$#$#, gmeinne, eloztdv]] -deepEquals(md1, md2): false -*/ diff --git a/code/arrays/CountUpward.java b/code/arrays/CountUpward.java deleted file mode 100644 index bbeb02ba..00000000 --- a/code/arrays/CountUpward.java +++ /dev/null @@ -1,24 +0,0 @@ -// arrays/CountUpward.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import static onjava.ArrayShow.*; - -public class CountUpward { - static long[] fillCounted(int size) { - return LongStream.iterate(0, i -> i + 1) - .limit(size).toArray(); - } - public static void main(String[] args) { - long[] l1 = fillCounted(20); // No problem - show(l1); - // On my machine, this runs out of heap space: - //- long[] l2 = fillCounted(10_000_000); - } -} -/* Output: -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -16, 17, 18, 19] -*/ diff --git a/code/arrays/FillingArrays.java b/code/arrays/FillingArrays.java deleted file mode 100644 index df54e62f..00000000 --- a/code/arrays/FillingArrays.java +++ /dev/null @@ -1,55 +0,0 @@ -// arrays/FillingArrays.java -// (c)2020 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. -// Using Arrays.fill() -import java.util.*; -import static onjava.ArrayShow.*; - -public class FillingArrays { - public static void main(String[] args) { - int size = 6; - boolean[] a1 = new boolean[size]; - byte[] a2 = new byte[size]; - char[] a3 = new char[size]; - short[] a4 = new short[size]; - int[] a5 = new int[size]; - long[] a6 = new long[size]; - float[] a7 = new float[size]; - double[] a8 = new double[size]; - String[] a9 = new String[size]; - Arrays.fill(a1, true); - show("a1", a1); - Arrays.fill(a2, (byte)11); - show("a2", a2); - Arrays.fill(a3, 'x'); - show("a3", a3); - Arrays.fill(a4, (short)17); - show("a4", a4); - Arrays.fill(a5, 19); - show("a5", a5); - Arrays.fill(a6, 23); - show("a6", a6); - Arrays.fill(a7, 29); - show("a7", a7); - Arrays.fill(a8, 47); - show("a8", a8); - Arrays.fill(a9, "Hello"); - show("a9", a9); - // Manipulating ranges: - Arrays.fill(a9, 3, 5, "World"); - show("a9", a9); - } -} -/* Output: -a1: [true, true, true, true, true, true] -a2: [11, 11, 11, 11, 11, 11] -a3: [x, x, x, x, x, x] -a4: [17, 17, 17, 17, 17, 17] -a5: [19, 19, 19, 19, 19, 19] -a6: [23, 23, 23, 23, 23, 23] -a7: [29.0, 29.0, 29.0, 29.0, 29.0, 29.0] -a8: [47.0, 47.0, 47.0, 47.0, 47.0, 47.0] -a9: [Hello, Hello, Hello, Hello, Hello, Hello] -a9: [Hello, Hello, Hello, World, World, Hello] -*/ diff --git a/code/arrays/IceCreamFlavors.java b/code/arrays/IceCreamFlavors.java deleted file mode 100644 index 5e9d2b61..00000000 --- a/code/arrays/IceCreamFlavors.java +++ /dev/null @@ -1,45 +0,0 @@ -// arrays/IceCreamFlavors.java -// (c)2020 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. -// Returning arrays from methods -import java.util.*; -import static onjava.ArrayShow.*; - -public class IceCreamFlavors { - private static SplittableRandom rand = - new SplittableRandom(47); - static final String[] FLAVORS = { - "Chocolate", "Strawberry", "Vanilla Fudge Swirl", - "Mint Chip", "Mocha Almond Fudge", "Rum Raisin", - "Praline Cream", "Mud Pie" - }; - public static String[] flavorSet(int n) { - if(n > FLAVORS.length) - throw new IllegalArgumentException("Set too big"); - String[] results = new String[n]; - boolean[] picked = new boolean[FLAVORS.length]; - for(int i = 0; i < n; i++) { - int t; - do - t = rand.nextInt(FLAVORS.length); - while(picked[t]); - results[i] = FLAVORS[t]; - picked[t] = true; - } - return results; - } - public static void main(String[] args) { - for(int i = 0; i < 7; i++) - show(flavorSet(3)); - } -} -/* Output: -[Praline Cream, Mint Chip, Vanilla Fudge Swirl] -[Strawberry, Vanilla Fudge Swirl, Mud Pie] -[Chocolate, Strawberry, Vanilla Fudge Swirl] -[Rum Raisin, Praline Cream, Chocolate] -[Mint Chip, Rum Raisin, Mocha Almond Fudge] -[Mocha Almond Fudge, Mud Pie, Vanilla Fudge Swirl] -[Mocha Almond Fudge, Mud Pie, Mint Chip] -*/ diff --git a/code/arrays/ModifyExisting.java b/code/arrays/ModifyExisting.java deleted file mode 100644 index d74df78e..00000000 --- a/code/arrays/ModifyExisting.java +++ /dev/null @@ -1,22 +0,0 @@ -// arrays/ModifyExisting.java -// (c)2020 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. -import java.util.*; -import onjava.*; -import static onjava.ArrayShow.*; - -public class ModifyExisting { - public static void main(String[] args) { - double[] da = new double[7]; - Arrays.setAll(da, new Rand.Double()::get); - show(da); - Arrays.setAll(da, n -> da[n] / 100); // [1] - show(da); - } -} -/* Output: -[4.83, 2.89, 2.9, 1.97, 3.01, 0.18, 0.99] -[0.0483, 0.028900000000000002, 0.028999999999999998, -0.0197, 0.0301, 0.0018, 0.009899999999999999] -*/ diff --git a/code/arrays/MultiDimWrapperArray.java b/code/arrays/MultiDimWrapperArray.java deleted file mode 100644 index 1185d0f9..00000000 --- a/code/arrays/MultiDimWrapperArray.java +++ /dev/null @@ -1,38 +0,0 @@ -// arrays/MultiDimWrapperArray.java -// (c)2020 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. -// Multidimensional arrays of "wrapper" objects -import java.util.*; - -public class MultiDimWrapperArray { - public static void main(String[] args) { - Integer[][] a1 = { // Autoboxing - { 1, 2, 3, }, - { 4, 5, 6, }, - }; - Double[][][] a2 = { // Autoboxing - { { 1.1, 2.2 }, { 3.3, 4.4 } }, - { { 5.5, 6.6 }, { 7.7, 8.8 } }, - { { 9.9, 1.2 }, { 2.3, 3.4 } }, - }; - String[][] a3 = { - { "The", "Quick", "Sly", "Fox" }, - { "Jumped", "Over" }, - { "The", "Lazy", "Brown", "Dog", "&", "friend" }, - }; - System.out.println( - "a1: " + Arrays.deepToString(a1)); - System.out.println( - "a2: " + Arrays.deepToString(a2)); - System.out.println( - "a3: " + Arrays.deepToString(a3)); - } -} -/* Output: -a1: [[1, 2, 3], [4, 5, 6]] -a2: [[[1.1, 2.2], [3.3, 4.4]], [[5.5, 6.6], [7.7, -8.8]], [[9.9, 1.2], [2.3, 3.4]]] -a3: [[The, Quick, Sly, Fox], [Jumped, Over], [The, -Lazy, Brown, Dog, &, friend]] -*/ diff --git a/code/arrays/MultidimensionalObjectArrays.java b/code/arrays/MultidimensionalObjectArrays.java deleted file mode 100644 index 998e7c99..00000000 --- a/code/arrays/MultidimensionalObjectArrays.java +++ /dev/null @@ -1,25 +0,0 @@ -// arrays/MultidimensionalObjectArrays.java -// (c)2020 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. -import java.util.*; - -public class MultidimensionalObjectArrays { - public static void main(String[] args) { - BerylliumSphere[][] spheres = { - { new BerylliumSphere(), new BerylliumSphere() }, - { new BerylliumSphere(), new BerylliumSphere(), - new BerylliumSphere(), new BerylliumSphere() }, - { new BerylliumSphere(), new BerylliumSphere(), - new BerylliumSphere(), new BerylliumSphere(), - new BerylliumSphere(), new BerylliumSphere(), - new BerylliumSphere(), new BerylliumSphere() }, - }; - System.out.println(Arrays.deepToString(spheres)); - } -} -/* Output: -[[Sphere 0, Sphere 1], [Sphere 2, Sphere 3, Sphere 4, -Sphere 5], [Sphere 6, Sphere 7, Sphere 8, Sphere 9, -Sphere 10, Sphere 11, Sphere 12, Sphere 13]] -*/ diff --git a/code/arrays/MultidimensionalPrimitiveArray.java b/code/arrays/MultidimensionalPrimitiveArray.java deleted file mode 100644 index 8ed5884f..00000000 --- a/code/arrays/MultidimensionalPrimitiveArray.java +++ /dev/null @@ -1,18 +0,0 @@ -// arrays/MultidimensionalPrimitiveArray.java -// (c)2020 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. -import java.util.*; - -public class MultidimensionalPrimitiveArray { - public static void main(String[] args) { - int[][] a = { - { 1, 2, 3, }, - { 4, 5, 6, }, - }; - System.out.println(Arrays.deepToString(a)); - } -} -/* Output: -[[1, 2, 3], [4, 5, 6]] -*/ diff --git a/code/arrays/ParallelPrefix1.java b/code/arrays/ParallelPrefix1.java deleted file mode 100644 index e180d019..00000000 --- a/code/arrays/ParallelPrefix1.java +++ /dev/null @@ -1,27 +0,0 @@ -// arrays/ParallelPrefix1.java -// (c)2020 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. -import java.util.*; -import onjava.*; -import static onjava.ArrayShow.*; - -public class ParallelPrefix1 { - public static void main(String[] args) { - int[] nums = new Count.Pint().array(10); - show(nums); - System.out.println(Arrays.stream(nums) - .reduce(Integer::sum).getAsInt()); - Arrays.parallelPrefix(nums, Integer::sum); - show(nums); - System.out.println(Arrays.stream( - new Count.Pint().array(6)) - .reduce(Integer::sum).getAsInt()); - } -} -/* Output: -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -45 -[0, 1, 3, 6, 10, 15, 21, 28, 36, 45] -15 -*/ diff --git a/code/arrays/ParallelPrefix2.java b/code/arrays/ParallelPrefix2.java deleted file mode 100644 index 5288d3ce..00000000 --- a/code/arrays/ParallelPrefix2.java +++ /dev/null @@ -1,20 +0,0 @@ -// arrays/ParallelPrefix2.java -// (c)2020 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. -import java.util.*; -import onjava.*; -import static onjava.ArrayShow.*; - -public class ParallelPrefix2 { - public static void main(String[] args) { - String[] strings = new Rand.String(1).array(8); - show(strings); - Arrays.parallelPrefix(strings, (a, b) -> a + b); - show(strings); - } -} -/* Output: -[b, t, p, e, n, p, c, c] -[b, bt, btp, btpe, btpen, btpenp, btpenpc, btpenpcc] -*/ diff --git a/code/arrays/ParallelPrefix3.java b/code/arrays/ParallelPrefix3.java deleted file mode 100644 index ed2751dc..00000000 --- a/code/arrays/ParallelPrefix3.java +++ /dev/null @@ -1,23 +0,0 @@ -// arrays/ParallelPrefix3.java -// (c)2020 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. -// {ExcludeFromTravisCI} -import java.util.*; - -public class ParallelPrefix3 { - static final int SIZE = 10_000_000; - public static void main(String[] args) { - long[] nums = new long[SIZE]; - Arrays.setAll(nums, n -> n); - Arrays.parallelPrefix(nums, Long::sum); - System.out.println("First 20: " + nums[19]); - System.out.println("First 200: " + nums[199]); - System.out.println("All: " + nums[nums.length-1]); - } -} -/* Output: -First 20: 190 -First 200: 19900 -All: 49999995000000 -*/ diff --git a/code/arrays/ParallelSetAll.java b/code/arrays/ParallelSetAll.java deleted file mode 100644 index f6c47ff5..00000000 --- a/code/arrays/ParallelSetAll.java +++ /dev/null @@ -1,24 +0,0 @@ -// arrays/ParallelSetAll.java -// (c)2020 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. -import java.util.*; -import onjava.*; - -public class ParallelSetAll { - static final int SIZE = 10_000_000; - static void intArray() { - int[] ia = new int[SIZE]; - Arrays.setAll(ia, new Rand.Pint()::get); - Arrays.parallelSetAll(ia, new Rand.Pint()::get); - } - static void longArray() { - long[] la = new long[SIZE]; - Arrays.setAll(la, new Rand.Plong()::get); - Arrays.parallelSetAll(la, new Rand.Plong()::get); - } - public static void main(String[] args) { - intArray(); - longArray(); - } -} diff --git a/code/arrays/ParameterizedArrayType.java b/code/arrays/ParameterizedArrayType.java deleted file mode 100644 index 06c1021c..00000000 --- a/code/arrays/ParameterizedArrayType.java +++ /dev/null @@ -1,25 +0,0 @@ -// arrays/ParameterizedArrayType.java -// (c)2020 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. - -class ClassParameter { - public T[] f(T[] arg) { return arg; } -} - -class MethodParameter { - public static T[] f(T[] arg) { return arg; } -} - -public class ParameterizedArrayType { - public static void main(String[] args) { - Integer[] ints = { 1, 2, 3, 4, 5 }; - Double[] doubles = { 1.1, 2.2, 3.3, 4.4, 5.5 }; - Integer[] ints2 = - new ClassParameter().f(ints); - Double[] doubles2 = - new ClassParameter().f(doubles); - ints2 = MethodParameter.f(ints); - doubles2 = MethodParameter.f(doubles); - } -} diff --git a/code/arrays/PythonLists.py b/code/arrays/PythonLists.py deleted file mode 100644 index 910daf18..00000000 --- a/code/arrays/PythonLists.py +++ /dev/null @@ -1,36 +0,0 @@ -# arrays/PythonLists.py -# (c)2020 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. - -aList = [1, 2, 3, 4, 5] -print(type(aList)) # -print(aList) # [1, 2, 3, 4, 5] -print(aList[4]) # 5 Basic list indexing -aList.append(6) # lists can be resized -aList += [7, 8] # Add a list to a list -print(aList) # [1, 2, 3, 4, 5, 6, 7, 8] -aSlice = aList[2:4] -print(aSlice) # [3, 4] - -class MyList(list): # Inherit from list - # Define a method; 'this' pointer is explicit: - def getReversed(self): - reversed = self[:] # Copy list using slices - reversed.reverse() # Built-in list method - return reversed - -# No 'new' necessary for object creation: -list2 = MyList(aList) -print(type(list2)) # -print(list2.getReversed()) # [8, 7, 6, 5, 4, 3, 2, 1] - -output = """ - -[1, 2, 3, 4, 5] -5 -[1, 2, 3, 4, 5, 6, 7, 8] -[3, 4] - -[8, 7, 6, 5, 4, 3, 2, 1] -""" diff --git a/code/arrays/RaggedArray.java b/code/arrays/RaggedArray.java deleted file mode 100644 index bd7d625b..00000000 --- a/code/arrays/RaggedArray.java +++ /dev/null @@ -1,26 +0,0 @@ -// arrays/RaggedArray.java -// (c)2020 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. -import java.util.*; - -public class RaggedArray { - static int val = 1; - public static void main(String[] args) { - SplittableRandom rand = new SplittableRandom(47); - // 3-D array with varied-length vectors: - int[][][] a = new int[rand.nextInt(7)][][]; - for(int i = 0; i < a.length; i++) { - a[i] = new int[rand.nextInt(5)][]; - for(int j = 0; j < a[i].length; j++) { - a[i][j] = new int[rand.nextInt(5)]; - Arrays.setAll(a[i][j], n -> val++); // [1] - } - } - System.out.println(Arrays.deepToString(a)); - } -} -/* Output: -[[[1], []], [[2, 3, 4, 5], [6]], [[7, 8, 9], [10, 11, -12], []]] -*/ diff --git a/code/arrays/Reverse.java b/code/arrays/Reverse.java deleted file mode 100644 index 9a7de678..00000000 --- a/code/arrays/Reverse.java +++ /dev/null @@ -1,32 +0,0 @@ -// arrays/Reverse.java -// (c)2020 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. -// The Collections.reverseOrder() Comparator -import java.util.*; -import onjava.*; -import static onjava.ArrayShow.*; - -public class Reverse { - public static void main(String[] args) { - CompType[] a = new CompType[12]; - Arrays.setAll(a, n -> CompType.get()); - show("Before sorting", a); - Arrays.sort(a, Collections.reverseOrder()); - show("After sorting", a); - } -} -/* Output: -Before sorting: [[i = 35, j = 37], [i = 41, j = 20], [i -= 77, j = 79] -, [i = 56, j = 68], [i = 48, j = 93], [i = 70, j = 7] -, [i = 0, j = 25], [i = 62, j = 34], [i = 50, j = 82] -, [i = 31, j = 67], [i = 66, j = 54], [i = 21, j = 6] -] -After sorting: [[i = 77, j = 79], [i = 70, j = 7], [i = -66, j = 54] -, [i = 62, j = 34], [i = 56, j = 68], [i = 50, j = 82] -, [i = 48, j = 93], [i = 41, j = 20], [i = 35, j = 37] -, [i = 31, j = 67], [i = 21, j = 6], [i = 0, j = 25] -] -*/ diff --git a/code/arrays/SimpleSetAll.java b/code/arrays/SimpleSetAll.java deleted file mode 100644 index 70336e79..00000000 --- a/code/arrays/SimpleSetAll.java +++ /dev/null @@ -1,56 +0,0 @@ -// arrays/SimpleSetAll.java -// (c)2020 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. -import java.util.*; -import static onjava.ArrayShow.*; - -class Bob { - final int id; - Bob(int n) { id = n; } - @Override - public String toString() { return "Bob" + id; } -} - -public class SimpleSetAll { - public static final int SZ = 8; - static int val = 1; - static char[] chars = "abcdefghijklmnopqrstuvwxyz" - .toCharArray(); - static char getChar(int n) { return chars[n]; } - public static void main(String[] args) { - int[] ia = new int[SZ]; - long[] la = new long[SZ]; - double[] da = new double[SZ]; - Arrays.setAll(ia, n -> n); // [1] - Arrays.setAll(la, n -> n); - Arrays.setAll(da, n -> n); - show(ia); - show(la); - show(da); - Arrays.setAll(ia, n -> val++); // [2] - Arrays.setAll(la, n -> val++); - Arrays.setAll(da, n -> val++); - show(ia); - show(la); - show(da); - - Bob[] ba = new Bob[SZ]; - Arrays.setAll(ba, Bob::new); // [3] - show(ba); - - Character[] ca = new Character[SZ]; - Arrays.setAll(ca, SimpleSetAll::getChar); // [4] - show(ca); - } -} -/* Output: -[0, 1, 2, 3, 4, 5, 6, 7] -[0, 1, 2, 3, 4, 5, 6, 7] -[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] -[1, 2, 3, 4, 5, 6, 7, 8] -[9, 10, 11, 12, 13, 14, 15, 16] -[17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0] -[Bob0, Bob1, Bob2, Bob3, Bob4, Bob5, Bob6, Bob7] -[a, b, c, d, e, f, g, h] -*/ diff --git a/code/arrays/StreamFromArray.java b/code/arrays/StreamFromArray.java deleted file mode 100644 index 69628703..00000000 --- a/code/arrays/StreamFromArray.java +++ /dev/null @@ -1,51 +0,0 @@ -// arrays/StreamFromArray.java -// (c)2020 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. -import java.util.*; -import onjava.*; - -public class StreamFromArray { - public static void main(String[] args) { - String[] s = new Rand.String().array(10); - Arrays.stream(s) - .skip(3) - .limit(5) - .map(ss -> ss + "!") - .forEach(System.out::println); - - int[] ia = new Rand.Pint().array(10); - Arrays.stream(ia) - .skip(3) - .limit(5) - .map(i -> i * 10) - .forEach(System.out::println); - - Arrays.stream(new long[10]); - Arrays.stream(new double[10]); - - // Only int, long and double work: - //- Arrays.stream(new boolean[10]); - //- Arrays.stream(new byte[10]); - //- Arrays.stream(new char[10]); - //- Arrays.stream(new short[10]); - //- Arrays.stream(new float[10]); - - // For the other types you must use wrapped arrays: - float[] fa = new Rand.Pfloat().array(10); - Arrays.stream(ConvertTo.boxed(fa)); - Arrays.stream(new Rand.Float().array(10)); - } -} -/* Output: -eloztdv! -ewcippc! -ygpoalk! -ljlbynx! -taprwxz! -47200 -61770 -84790 -66560 -37680 -*/ diff --git a/code/arrays/StringSorting.java b/code/arrays/StringSorting.java deleted file mode 100644 index 0da5c733..00000000 --- a/code/arrays/StringSorting.java +++ /dev/null @@ -1,39 +0,0 @@ -// arrays/StringSorting.java -// (c)2020 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. -// Sorting an array of Strings -import java.util.*; -import onjava.*; -import static onjava.ArrayShow.*; - -public class StringSorting { - public static void main(String[] args) { - String[] sa = new Rand.String().array(20); - show("Before sort", sa); - Arrays.sort(sa); - show("After sort", sa); - Arrays.sort(sa, Collections.reverseOrder()); - show("Reverse sort", sa); - Arrays.sort(sa, String.CASE_INSENSITIVE_ORDER); - show("Case-insensitive sort", sa); - } -} -/* Output: -Before sort: [btpenpc, cuxszgv, gmeinne, eloztdv, -ewcippc, ygpoalk, ljlbynx, taprwxz, bhmupju, cjwzmmr, -anmkkyh, fcjpthl, skddcat, jbvlgwc, mvducuj, ydpulcq, -zehpfmm, zrxmclh, qgekgly, hyoubzl] -After sort: [anmkkyh, bhmupju, btpenpc, cjwzmmr, -cuxszgv, eloztdv, ewcippc, fcjpthl, gmeinne, hyoubzl, -jbvlgwc, ljlbynx, mvducuj, qgekgly, skddcat, taprwxz, -ydpulcq, ygpoalk, zehpfmm, zrxmclh] -Reverse sort: [zrxmclh, zehpfmm, ygpoalk, ydpulcq, -taprwxz, skddcat, qgekgly, mvducuj, ljlbynx, jbvlgwc, -hyoubzl, gmeinne, fcjpthl, ewcippc, eloztdv, cuxszgv, -cjwzmmr, btpenpc, bhmupju, anmkkyh] -Case-insensitive sort: [anmkkyh, bhmupju, btpenpc, -cjwzmmr, cuxszgv, eloztdv, ewcippc, fcjpthl, gmeinne, -hyoubzl, jbvlgwc, ljlbynx, mvducuj, qgekgly, skddcat, -taprwxz, ydpulcq, ygpoalk, zehpfmm, zrxmclh] -*/ diff --git a/code/arrays/TestConvertTo.java b/code/arrays/TestConvertTo.java deleted file mode 100644 index 8ecb72a6..00000000 --- a/code/arrays/TestConvertTo.java +++ /dev/null @@ -1,87 +0,0 @@ -// arrays/TestConvertTo.java -// (c)2020 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. -import java.util.*; -import onjava.*; -import static onjava.ArrayShow.*; -import static onjava.ConvertTo.*; - -public class TestConvertTo { - static final int SIZE = 6; - public static void main(String[] args) { - Boolean[] a1 = new Boolean[SIZE]; - Arrays.setAll(a1, new Rand.Boolean()::get); - boolean[] a1p = primitive(a1); - show("a1p", a1p); - Boolean[] a1b = boxed(a1p); - show("a1b", a1b); - - Byte[] a2 = new Byte[SIZE]; - Arrays.setAll(a2, new Rand.Byte()::get); - byte[] a2p = primitive(a2); - show("a2p", a2p); - Byte[] a2b = boxed(a2p); - show("a2b", a2b); - - Character[] a3 = new Character[SIZE]; - Arrays.setAll(a3, new Rand.Character()::get); - char[] a3p = primitive(a3); - show("a3p", a3p); - Character[] a3b = boxed(a3p); - show("a3b", a3b); - - Short[] a4 = new Short[SIZE]; - Arrays.setAll(a4, new Rand.Short()::get); - short[] a4p = primitive(a4); - show("a4p", a4p); - Short[] a4b = boxed(a4p); - show("a4b", a4b); - - Integer[] a5 = new Integer[SIZE]; - Arrays.setAll(a5, new Rand.Integer()::get); - int[] a5p = primitive(a5); - show("a5p", a5p); - Integer[] a5b = boxed(a5p); - show("a5b", a5b); - - Long[] a6 = new Long[SIZE]; - Arrays.setAll(a6, new Rand.Long()::get); - long[] a6p = primitive(a6); - show("a6p", a6p); - Long[] a6b = boxed(a6p); - show("a6b", a6b); - - Float[] a7 = new Float[SIZE]; - Arrays.setAll(a7, new Rand.Float()::get); - float[] a7p = primitive(a7); - show("a7p", a7p); - Float[] a7b = boxed(a7p); - show("a7b", a7b); - - Double[] a8 = new Double[SIZE]; - Arrays.setAll(a8, new Rand.Double()::get); - double[] a8p = primitive(a8); - show("a8p", a8p); - Double[] a8b = boxed(a8p); - show("a8b", a8b); - } -} -/* Output: -a1p: [true, false, true, true, true, false] -a1b: [true, false, true, true, true, false] -a2p: [123, 33, 101, 112, 33, 31] -a2b: [123, 33, 101, 112, 33, 31] -a3p: [b, t, p, e, n, p] -a3b: [b, t, p, e, n, p] -a4p: [635, 8737, 3941, 4720, 6177, 8479] -a4b: [635, 8737, 3941, 4720, 6177, 8479] -a5p: [635, 8737, 3941, 4720, 6177, 8479] -a5b: [635, 8737, 3941, 4720, 6177, 8479] -a6p: [6882, 3765, 692, 9575, 4439, 2638] -a6b: [6882, 3765, 692, 9575, 4439, 2638] -a7p: [4.83, 2.89, 2.9, 1.97, 3.01, 0.18] -a7b: [4.83, 2.89, 2.9, 1.97, 3.01, 0.18] -a8p: [4.83, 2.89, 2.9, 1.97, 3.01, 0.18] -a8b: [4.83, 2.89, 2.9, 1.97, 3.01, 0.18] -*/ diff --git a/code/arrays/TestCount.java b/code/arrays/TestCount.java deleted file mode 100644 index a77e00f7..00000000 --- a/code/arrays/TestCount.java +++ /dev/null @@ -1,167 +0,0 @@ -// arrays/TestCount.java -// (c)2020 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. -// Test counting generators -import java.util.*; -import java.util.stream.*; -import onjava.*; -import static onjava.ArrayShow.*; - -public class TestCount { - static final int SZ = 5; - public static void main(String[] args) { - System.out.println("Boolean"); - Boolean[] a1 = new Boolean[SZ]; - Arrays.setAll(a1, new Count.Boolean()::get); - show(a1); - a1 = Stream.generate(new Count.Boolean()) - .limit(SZ + 1).toArray(Boolean[]::new); - show(a1); - a1 = new Count.Boolean().array(SZ + 2); - show(a1); - boolean[] a1b = - new Count.Pboolean().array(SZ + 3); - show(a1b); - - System.out.println("Byte"); - Byte[] a2 = new Byte[SZ]; - Arrays.setAll(a2, new Count.Byte()::get); - show(a2); - a2 = Stream.generate(new Count.Byte()) - .limit(SZ + 1).toArray(Byte[]::new); - show(a2); - a2 = new Count.Byte().array(SZ + 2); - show(a2); - byte[] a2b = new Count.Pbyte().array(SZ + 3); - show(a2b); - - System.out.println("Character"); - Character[] a3 = new Character[SZ]; - Arrays.setAll(a3, new Count.Character()::get); - show(a3); - a3 = Stream.generate(new Count.Character()) - .limit(SZ + 1).toArray(Character[]::new); - show(a3); - a3 = new Count.Character().array(SZ + 2); - show(a3); - char[] a3b = new Count.Pchar().array(SZ + 3); - show(a3b); - - System.out.println("Short"); - Short[] a4 = new Short[SZ]; - Arrays.setAll(a4, new Count.Short()::get); - show(a4); - a4 = Stream.generate(new Count.Short()) - .limit(SZ + 1).toArray(Short[]::new); - show(a4); - a4 = new Count.Short().array(SZ + 2); - show(a4); - short[] a4b = new Count.Pshort().array(SZ + 3); - show(a4b); - - System.out.println("Integer"); - int[] a5 = new int[SZ]; - Arrays.setAll(a5, new Count.Integer()::get); - show(a5); - Integer[] a5b = - Stream.generate(new Count.Integer()) - .limit(SZ + 1).toArray(Integer[]::new); - show(a5b); - a5b = new Count.Integer().array(SZ + 2); - show(a5b); - a5 = IntStream.generate(new Count.Pint()) - .limit(SZ + 1).toArray(); - show(a5); - a5 = new Count.Pint().array(SZ + 3); - show(a5); - - System.out.println("Long"); - long[] a6 = new long[SZ]; - Arrays.setAll(a6, new Count.Long()::get); - show(a6); - Long[] a6b = Stream.generate(new Count.Long()) - .limit(SZ + 1).toArray(Long[]::new); - show(a6b); - a6b = new Count.Long().array(SZ + 2); - show(a6b); - a6 = LongStream.generate(new Count.Plong()) - .limit(SZ + 1).toArray(); - show(a6); - a6 = new Count.Plong().array(SZ + 3); - show(a6); - - System.out.println("Float"); - Float[] a7 = new Float[SZ]; - Arrays.setAll(a7, new Count.Float()::get); - show(a7); - a7 = Stream.generate(new Count.Float()) - .limit(SZ + 1).toArray(Float[]::new); - show(a7); - a7 = new Count.Float().array(SZ + 2); - show(a7); - float[] a7b = new Count.Pfloat().array(SZ + 3); - show(a7b); - - System.out.println("Double"); - double[] a8 = new double[SZ]; - Arrays.setAll(a8, new Count.Double()::get); - show(a8); - Double[] a8b = - Stream.generate(new Count.Double()) - .limit(SZ + 1).toArray(Double[]::new); - show(a8b); - a8b = new Count.Double().array(SZ + 2); - show(a8b); - a8 = DoubleStream.generate(new Count.Pdouble()) - .limit(SZ + 1).toArray(); - show(a8); - a8 = new Count.Pdouble().array(SZ + 3); - show(a8); - } -} -/* Output: -Boolean -[false, true, false, true, false] -[false, true, false, true, false, true] -[false, true, false, true, false, true, false] -[false, true, false, true, false, true, false, true] -Byte -[0, 1, 2, 3, 4] -[0, 1, 2, 3, 4, 5] -[0, 1, 2, 3, 4, 5, 6] -[0, 1, 2, 3, 4, 5, 6, 7] -Character -[b, c, d, e, f] -[b, c, d, e, f, g] -[b, c, d, e, f, g, h] -[b, c, d, e, f, g, h, i] -Short -[0, 1, 2, 3, 4] -[0, 1, 2, 3, 4, 5] -[0, 1, 2, 3, 4, 5, 6] -[0, 1, 2, 3, 4, 5, 6, 7] -Integer -[0, 1, 2, 3, 4] -[0, 1, 2, 3, 4, 5] -[0, 1, 2, 3, 4, 5, 6] -[0, 1, 2, 3, 4, 5] -[0, 1, 2, 3, 4, 5, 6, 7] -Long -[0, 1, 2, 3, 4] -[0, 1, 2, 3, 4, 5] -[0, 1, 2, 3, 4, 5, 6] -[0, 1, 2, 3, 4, 5] -[0, 1, 2, 3, 4, 5, 6, 7] -Float -[0.0, 1.0, 2.0, 3.0, 4.0] -[0.0, 1.0, 2.0, 3.0, 4.0, 5.0] -[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0] -[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] -Double -[0.0, 1.0, 2.0, 3.0, 4.0] -[0.0, 1.0, 2.0, 3.0, 4.0, 5.0] -[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0] -[0.0, 1.0, 2.0, 3.0, 4.0, 5.0] -[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] -*/ diff --git a/code/arrays/TestRand.java b/code/arrays/TestRand.java deleted file mode 100644 index 17e0718f..00000000 --- a/code/arrays/TestRand.java +++ /dev/null @@ -1,192 +0,0 @@ -// arrays/TestRand.java -// (c)2020 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. -// Test random generators -import java.util.*; -import java.util.stream.*; -import onjava.*; -import static onjava.ArrayShow.*; - -public class TestRand { - static final int SZ = 5; - public static void main(String[] args) { - System.out.println("Boolean"); - Boolean[] a1 = new Boolean[SZ]; - Arrays.setAll(a1, new Rand.Boolean()::get); - show(a1); - a1 = Stream.generate(new Rand.Boolean()) - .limit(SZ + 1).toArray(Boolean[]::new); - show(a1); - a1 = new Rand.Boolean().array(SZ + 2); - show(a1); - boolean[] a1b = - new Rand.Pboolean().array(SZ + 3); - show(a1b); - - System.out.println("Byte"); - Byte[] a2 = new Byte[SZ]; - Arrays.setAll(a2, new Rand.Byte()::get); - show(a2); - a2 = Stream.generate(new Rand.Byte()) - .limit(SZ + 1).toArray(Byte[]::new); - show(a2); - a2 = new Rand.Byte().array(SZ + 2); - show(a2); - byte[] a2b = new Rand.Pbyte().array(SZ + 3); - show(a2b); - - System.out.println("Character"); - Character[] a3 = new Character[SZ]; - Arrays.setAll(a3, new Rand.Character()::get); - show(a3); - a3 = Stream.generate(new Rand.Character()) - .limit(SZ + 1).toArray(Character[]::new); - show(a3); - a3 = new Rand.Character().array(SZ + 2); - show(a3); - char[] a3b = new Rand.Pchar().array(SZ + 3); - show(a3b); - - System.out.println("Short"); - Short[] a4 = new Short[SZ]; - Arrays.setAll(a4, new Rand.Short()::get); - show(a4); - a4 = Stream.generate(new Rand.Short()) - .limit(SZ + 1).toArray(Short[]::new); - show(a4); - a4 = new Rand.Short().array(SZ + 2); - show(a4); - short[] a4b = new Rand.Pshort().array(SZ + 3); - show(a4b); - - System.out.println("Integer"); - int[] a5 = new int[SZ]; - Arrays.setAll(a5, new Rand.Integer()::get); - show(a5); - Integer[] a5b = - Stream.generate(new Rand.Integer()) - .limit(SZ + 1).toArray(Integer[]::new); - show(a5b); - a5b = new Rand.Integer().array(SZ + 2); - show(a5b); - a5 = IntStream.generate(new Rand.Pint()) - .limit(SZ + 1).toArray(); - show(a5); - a5 = new Rand.Pint().array(SZ + 3); - show(a5); - - System.out.println("Long"); - long[] a6 = new long[SZ]; - Arrays.setAll(a6, new Rand.Long()::get); - show(a6); - Long[] a6b = Stream.generate(new Rand.Long()) - .limit(SZ + 1).toArray(Long[]::new); - show(a6b); - a6b = new Rand.Long().array(SZ + 2); - show(a6b); - a6 = LongStream.generate(new Rand.Plong()) - .limit(SZ + 1).toArray(); - show(a6); - a6 = new Rand.Plong().array(SZ + 3); - show(a6); - - System.out.println("Float"); - Float[] a7 = new Float[SZ]; - Arrays.setAll(a7, new Rand.Float()::get); - show(a7); - a7 = Stream.generate(new Rand.Float()) - .limit(SZ + 1).toArray(Float[]::new); - show(a7); - a7 = new Rand.Float().array(SZ + 2); - show(a7); - float[] a7b = new Rand.Pfloat().array(SZ + 3); - show(a7b); - - System.out.println("Double"); - double[] a8 = new double[SZ]; - Arrays.setAll(a8, new Rand.Double()::get); - show(a8); - Double[] a8b = - Stream.generate(new Rand.Double()) - .limit(SZ + 1).toArray(Double[]::new); - show(a8b); - a8b = new Rand.Double().array(SZ + 2); - show(a8b); - a8 = DoubleStream.generate(new Rand.Pdouble()) - .limit(SZ + 1).toArray(); - show(a8); - a8 = new Rand.Pdouble().array(SZ + 3); - show(a8); - - System.out.println("String"); - String[] s = new String[SZ - 1]; - Arrays.setAll(s, new Rand.String()::get); - show(s); - s = Stream.generate(new Rand.String()) - .limit(SZ).toArray(String[]::new); - show(s); - s = new Rand.String().array(SZ + 1); - show(s); - - Arrays.setAll(s, new Rand.String(4)::get); - show(s); - s = Stream.generate(new Rand.String(4)) - .limit(SZ).toArray(String[]::new); - show(s); - s = new Rand.String(4).array(SZ + 1); - show(s); - } -} -/* Output: -Boolean -[true, false, true, true, true] -[true, false, true, true, true, false] -[true, false, true, true, true, false, false] -[true, false, true, true, true, false, false, true] -Byte -[123, 33, 101, 112, 33] -[123, 33, 101, 112, 33, 31] -[123, 33, 101, 112, 33, 31, 0] -[123, 33, 101, 112, 33, 31, 0, -72] -Character -[b, t, p, e, n] -[b, t, p, e, n, p] -[b, t, p, e, n, p, c] -[b, t, p, e, n, p, c, c] -Short -[635, 8737, 3941, 4720, 6177] -[635, 8737, 3941, 4720, 6177, 8479] -[635, 8737, 3941, 4720, 6177, 8479, 6656] -[635, 8737, 3941, 4720, 6177, 8479, 6656, 3768] -Integer -[635, 8737, 3941, 4720, 6177] -[635, 8737, 3941, 4720, 6177, 8479] -[635, 8737, 3941, 4720, 6177, 8479, 6656] -[635, 8737, 3941, 4720, 6177, 8479] -[635, 8737, 3941, 4720, 6177, 8479, 6656, 3768] -Long -[6882, 3765, 692, 9575, 4439] -[6882, 3765, 692, 9575, 4439, 2638] -[6882, 3765, 692, 9575, 4439, 2638, 4011] -[6882, 3765, 692, 9575, 4439, 2638] -[6882, 3765, 692, 9575, 4439, 2638, 4011, 9610] -Float -[4.83, 2.89, 2.9, 1.97, 3.01] -[4.83, 2.89, 2.9, 1.97, 3.01, 0.18] -[4.83, 2.89, 2.9, 1.97, 3.01, 0.18, 0.99] -[4.83, 2.89, 2.9, 1.97, 3.01, 0.18, 0.99, 8.28] -Double -[4.83, 2.89, 2.9, 1.97, 3.01] -[4.83, 2.89, 2.9, 1.97, 3.01, 0.18] -[4.83, 2.89, 2.9, 1.97, 3.01, 0.18, 0.99] -[4.83, 2.89, 2.9, 1.97, 3.01, 0.18] -[4.83, 2.89, 2.9, 1.97, 3.01, 0.18, 0.99, 8.28] -String -[btpenpc, cuxszgv, gmeinne, eloztdv] -[btpenpc, cuxszgv, gmeinne, eloztdv, ewcippc] -[btpenpc, cuxszgv, gmeinne, eloztdv, ewcippc, ygpoalk] -[btpe, npcc, uxsz, gvgm, einn, eelo] -[btpe, npcc, uxsz, gvgm, einn] -[btpe, npcc, uxsz, gvgm, einn, eelo] -*/ diff --git a/code/arrays/ThreeDWithNew.java b/code/arrays/ThreeDWithNew.java deleted file mode 100644 index 7aaef069..00000000 --- a/code/arrays/ThreeDWithNew.java +++ /dev/null @@ -1,17 +0,0 @@ -// arrays/ThreeDWithNew.java -// (c)2020 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. -import java.util.*; - -public class ThreeDWithNew { - public static void main(String[] args) { - // 3-D array with fixed length: - int[][][] a = new int[2][2][4]; - System.out.println(Arrays.deepToString(a)); - } -} -/* Output: -[[[0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, -0]]] -*/ diff --git a/code/arrays/jmh/ParallelSort.java b/code/arrays/jmh/ParallelSort.java deleted file mode 100644 index fe0b505b..00000000 --- a/code/arrays/jmh/ParallelSort.java +++ /dev/null @@ -1,25 +0,0 @@ -// arrays/jmh/ParallelSort.java -// (c)2020 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 arrays.jmh; -import java.util.*; -import onjava.*; -import org.openjdk.jmh.annotations.*; - -@State(Scope.Thread) -public class ParallelSort { - private long[] la; - @Setup - public void setup() { - la = new Rand.Plong().array(100_000); - } - @Benchmark - public void sort() { - Arrays.sort(la); - } - @Benchmark - public void parallelSort() { - Arrays.parallelSort(la); - } -} diff --git a/code/build.gradle b/code/build.gradle deleted file mode 100644 index b4feb13d..00000000 --- a/code/build.gradle +++ /dev/null @@ -1,23 +0,0 @@ -buildscript { - repositories { - maven { - url 'https://plugins.gradle.org/m2/' - } - } - dependencies { - classpath 'me.champeau.gradle:jmh-gradle-plugin:0.5.2' - } -} - -apply plugin: 'com.mindviewinc.example-output-verification' - -subprojects { - apply from: "$rootProject.projectDir/gradle/java.gradle" - apply from: "$rootProject.projectDir/gradle/junit-jupiter.gradle" - apply from: "$rootProject.projectDir/gradle/jmh.gradle" - // apply from: "$rootProject.projectDir/gradle/checkstyle.gradle" - apply from: "$rootProject.projectDir/gradle/findbugs.gradle" - apply plugin: 'com.mindviewinc.tagging' -} - -apply from: 'gradle/subprojects.gradle' diff --git a/code/checkstyle.xml b/code/checkstyle.xml deleted file mode 100644 index aabea2c4..00000000 --- a/code/checkstyle.xml +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/code/chkstyle.bat b/code/chkstyle.bat deleted file mode 100644 index 24838fc0..00000000 --- a/code/chkstyle.bat +++ /dev/null @@ -1,2 +0,0 @@ -@echo run gradlew clean first! -gradlew checkstyleMain 1> checkstyleout.txt 2>&1 diff --git a/code/collections/AdapterMethodIdiom.java b/code/collections/AdapterMethodIdiom.java deleted file mode 100644 index a97abb41..00000000 --- a/code/collections/AdapterMethodIdiom.java +++ /dev/null @@ -1,48 +0,0 @@ -// collections/AdapterMethodIdiom.java -// (c)2020 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. -// The "Adapter Method" idiom uses for-in -// with additional kinds of Iterables -import java.util.*; - -class ReversibleArrayList extends ArrayList { - ReversibleArrayList(Collection c) { - super(c); - } - public Iterable reversed() { - return new Iterable() { - public Iterator iterator() { - return new Iterator() { - int current = size() - 1; - public boolean hasNext() { - return current > -1; - } - public T next() { return get(current--); } - public void remove() { // Not implemented - throw new UnsupportedOperationException(); - } - }; - } - }; - } -} - -public class AdapterMethodIdiom { - public static void main(String[] args) { - ReversibleArrayList ral = - new ReversibleArrayList( - Arrays.asList("To be or not to be".split(" "))); - // Grabs the ordinary iterator via iterator(): - for(String s : ral) - System.out.print(s + " "); - System.out.println(); - // Hand it the Iterable of your choice - for(String s : ral.reversed()) - System.out.print(s + " "); - } -} -/* Output: -To be or not to be -be to not or be To -*/ diff --git a/code/collections/AddingGroups.java b/code/collections/AddingGroups.java deleted file mode 100644 index ecfc8a5a..00000000 --- a/code/collections/AddingGroups.java +++ /dev/null @@ -1,24 +0,0 @@ -// collections/AddingGroups.java -// (c)2020 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. -// Adding groups of elements to Collection objects -import java.util.*; - -public class AddingGroups { - public static void main(String[] args) { - Collection collection = - new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5)); - Integer[] moreInts = { 6, 7, 8, 9, 10 }; - collection.addAll(Arrays.asList(moreInts)); - // Runs significantly faster, but you can't - // construct a Collection this way: - Collections.addAll(collection, 11, 12, 13, 14, 15); - Collections.addAll(collection, moreInts); - // Produces a list "backed by" an array: - List list = Arrays.asList(16,17,18,19,20); - list.set(1, 99); // OK -- modify an element - // list.add(21); // Runtime error; the underlying - // array cannot be resized. - } -} diff --git a/code/collections/ApplesAndOrangesWithGenerics.java b/code/collections/ApplesAndOrangesWithGenerics.java deleted file mode 100644 index c251672c..00000000 --- a/code/collections/ApplesAndOrangesWithGenerics.java +++ /dev/null @@ -1,23 +0,0 @@ -// collections/ApplesAndOrangesWithGenerics.java -// (c)2020 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. -import java.util.*; - -public class ApplesAndOrangesWithGenerics { - public static void main(String[] args) { - ArrayList apples = new ArrayList<>(); - for(int i = 0; i < 3; i++) - apples.add(new Apple()); - // Compile-time error: - // apples.add(new Orange()); - for(Apple apple : apples) { - System.out.println(apple.id()); - } - } -} -/* Output: -0 -1 -2 -*/ diff --git a/code/collections/ApplesAndOrangesWithoutGenerics.java b/code/collections/ApplesAndOrangesWithoutGenerics.java deleted file mode 100644 index 6afacd12..00000000 --- a/code/collections/ApplesAndOrangesWithoutGenerics.java +++ /dev/null @@ -1,38 +0,0 @@ -// collections/ApplesAndOrangesWithoutGenerics.java -// (c)2020 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. -// Simple collection use (suppressing compiler warnings) -// {ThrowsException} -import java.util.*; - -class Apple { - private static long counter; - private final long id = counter++; - public long id() { return id; } -} - -class Orange {} - -public class ApplesAndOrangesWithoutGenerics { - @SuppressWarnings("unchecked") - public static void main(String[] args) { - ArrayList apples = new ArrayList(); - for(int i = 0; i < 3; i++) - apples.add(new Apple()); - // No problem adding an Orange to apples: - apples.add(new Orange()); - for(Object apple : apples) { - ((Apple) apple).id(); - // Orange is detected only at run time - } - } -} -/* Output: -___[ Error Output ]___ -Exception in thread "main" -java.lang.ClassCastException: Orange cannot be cast to -Apple - at ApplesAndOrangesWithoutGenerics.main(ApplesA -ndOrangesWithoutGenerics.java:23) -*/ diff --git a/code/collections/ArrayIsNotIterable.java b/code/collections/ArrayIsNotIterable.java deleted file mode 100644 index d496feb1..00000000 --- a/code/collections/ArrayIsNotIterable.java +++ /dev/null @@ -1,23 +0,0 @@ -// collections/ArrayIsNotIterable.java -// (c)2020 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. -import java.util.*; - -public class ArrayIsNotIterable { - static void test(Iterable ib) { - for(T t : ib) - System.out.print(t + " "); - } - public static void main(String[] args) { - test(Arrays.asList(1, 2, 3)); - String[] strings = { "A", "B", "C" }; - // An array works in for-in, but it's not Iterable: - //- test(strings); - // You must explicitly convert it to an Iterable: - test(Arrays.asList(strings)); - } -} -/* Output: -1 2 3 A B C -*/ diff --git a/code/collections/AsListInference.java b/code/collections/AsListInference.java deleted file mode 100644 index ef813708..00000000 --- a/code/collections/AsListInference.java +++ /dev/null @@ -1,34 +0,0 @@ -// collections/AsListInference.java -// (c)2020 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. -import java.util.*; - -class Snow {} -class Powder extends Snow {} -class Light extends Powder {} -class Heavy extends Powder {} -class Crusty extends Snow {} -class Slush extends Snow {} - -public class AsListInference { - public static void main(String[] args) { - List snow1 = Arrays.asList( - new Crusty(), new Slush(), new Powder()); - //- snow1.add(new Heavy()); // Exception - - List snow2 = Arrays.asList( - new Light(), new Heavy()); - //- snow2.add(new Slush()); // Exception - - List snow3 = new ArrayList<>(); - Collections.addAll(snow3, - new Light(), new Heavy(), new Powder()); - snow3.add(new Crusty()); - - // Hint with explicit type argument specification: - List snow4 = Arrays.asList( - new Light(), new Heavy(), new Slush()); - //- snow4.add(new Powder()); // Exception - } -} diff --git a/code/collections/CollectionDifferences.java b/code/collections/CollectionDifferences.java deleted file mode 100644 index 711f7bd7..00000000 --- a/code/collections/CollectionDifferences.java +++ /dev/null @@ -1,71 +0,0 @@ -// collections/CollectionDifferences.java -// (c)2020 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. -import onjava.*; - -public class CollectionDifferences { - public static void main(String[] args) { - CollectionMethodDifferences.main(args); - } -} -/* Output: -Collection: [add, addAll, clear, contains, containsAll, -equals, forEach, hashCode, isEmpty, iterator, -parallelStream, remove, removeAll, removeIf, retainAll, -size, spliterator, stream, toArray] -Interfaces in Collection: [Iterable] -Set extends Collection, adds: [] -Interfaces in Set: [Collection] -HashSet extends Set, adds: [] -Interfaces in HashSet: [Set, Cloneable, Serializable] -LinkedHashSet extends HashSet, adds: [] -Interfaces in LinkedHashSet: [Set, Cloneable, -Serializable] -TreeSet extends Set, adds: [headSet, -descendingIterator, descendingSet, pollLast, subSet, -floor, tailSet, ceiling, last, lower, comparator, -pollFirst, first, higher] -Interfaces in TreeSet: [NavigableSet, Cloneable, -Serializable] -List extends Collection, adds: [replaceAll, get, -indexOf, subList, set, sort, lastIndexOf, listIterator] -Interfaces in List: [Collection] -ArrayList extends List, adds: [trimToSize, -ensureCapacity] -Interfaces in ArrayList: [List, RandomAccess, -Cloneable, Serializable] -LinkedList extends List, adds: [offerFirst, poll, -getLast, offer, getFirst, removeFirst, element, -removeLastOccurrence, peekFirst, peekLast, push, -pollFirst, removeFirstOccurrence, descendingIterator, -pollLast, removeLast, pop, addLast, peek, offerLast, -addFirst] -Interfaces in LinkedList: [List, Deque, Cloneable, -Serializable] -Queue extends Collection, adds: [poll, peek, offer, -element] -Interfaces in Queue: [Collection] -PriorityQueue extends Queue, adds: [comparator] -Interfaces in PriorityQueue: [Serializable] -Map: [clear, compute, computeIfAbsent, -computeIfPresent, containsKey, containsValue, entrySet, -equals, forEach, get, getOrDefault, hashCode, isEmpty, -keySet, merge, put, putAll, putIfAbsent, remove, -replace, replaceAll, size, values] -HashMap extends Map, adds: [] -Interfaces in HashMap: [Map, Cloneable, Serializable] -LinkedHashMap extends HashMap, adds: [] -Interfaces in LinkedHashMap: [Map] -SortedMap extends Map, adds: [lastKey, subMap, -comparator, firstKey, headMap, tailMap] -Interfaces in SortedMap: [Map] -TreeMap extends Map, adds: [descendingKeySet, -navigableKeySet, higherEntry, higherKey, floorKey, -subMap, ceilingKey, pollLastEntry, firstKey, lowerKey, -headMap, tailMap, lowerEntry, ceilingEntry, -descendingMap, pollFirstEntry, lastKey, firstEntry, -floorEntry, comparator, lastEntry] -Interfaces in TreeMap: [NavigableMap, Cloneable, -Serializable] -*/ diff --git a/code/collections/CollectionSequence.java b/code/collections/CollectionSequence.java deleted file mode 100644 index 6a12ed69..00000000 --- a/code/collections/CollectionSequence.java +++ /dev/null @@ -1,40 +0,0 @@ -// collections/CollectionSequence.java -// (c)2020 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. -import typeinfo.pets.*; -import java.util.*; - -public class CollectionSequence -extends AbstractCollection { - private Pet[] pets = Pets.array(8); - @Override - public int size() { return pets.length; } - @Override - public Iterator iterator() { - return new Iterator() { // [1] - private int index = 0; - @Override - public boolean hasNext() { - return index < pets.length; - } - @Override - public Pet next() { return pets[index++]; } - @Override - public void remove() { // Not implemented - throw new UnsupportedOperationException(); - } - }; - } - public static void main(String[] args) { - CollectionSequence c = new CollectionSequence(); - InterfaceVsIterator.display(c); - InterfaceVsIterator.display(c.iterator()); - } -} -/* Output: -0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug -7:Manx -0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug -7:Manx -*/ diff --git a/code/collections/CrossCollectionIteration.java b/code/collections/CrossCollectionIteration.java deleted file mode 100644 index 99769fe2..00000000 --- a/code/collections/CrossCollectionIteration.java +++ /dev/null @@ -1,36 +0,0 @@ -// collections/CrossCollectionIteration.java -// (c)2020 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. -import typeinfo.pets.*; -import java.util.*; - -public class CrossCollectionIteration { - public static void display(Iterator it) { - while(it.hasNext()) { - Pet p = it.next(); - System.out.print(p.id() + ":" + p + " "); - } - System.out.println(); - } - public static void main(String[] args) { - List pets = Pets.list(8); - LinkedList petsLL = new LinkedList<>(pets); - HashSet petsHS = new HashSet<>(pets); - TreeSet petsTS = new TreeSet<>(pets); - display(pets.iterator()); - display(petsLL.iterator()); - display(petsHS.iterator()); - display(petsTS.iterator()); - } -} -/* Output: -0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug -7:Manx -0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug -7:Manx -0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug -7:Manx -5:Cymric 2:Cymric 7:Manx 1:Manx 3:Mutt 6:Pug 4:Pug -0:Rat -*/ diff --git a/code/collections/CrossCollectionIteration2.java b/code/collections/CrossCollectionIteration2.java deleted file mode 100644 index c7da143f..00000000 --- a/code/collections/CrossCollectionIteration2.java +++ /dev/null @@ -1,37 +0,0 @@ -// collections/CrossCollectionIteration2.java -// (c)2020 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. -import typeinfo.pets.*; -import java.util.*; - -public class CrossCollectionIteration2 { - public static void display(Iterable ip) { - Iterator it = ip.iterator(); - while(it.hasNext()) { - Pet p = it.next(); - System.out.print(p.id() + ":" + p + " "); - } - System.out.println(); - } - public static void main(String[] args) { - List pets = Pets.list(8); - LinkedList petsLL = new LinkedList<>(pets); - HashSet petsHS = new HashSet<>(pets); - TreeSet petsTS = new TreeSet<>(pets); - display(pets); - display(petsLL); - display(petsHS); - display(petsTS); - } -} -/* Output: -0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug -7:Manx -0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug -7:Manx -0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug -7:Manx -5:Cymric 2:Cymric 7:Manx 1:Manx 3:Mutt 6:Pug 4:Pug -0:Rat -*/ diff --git a/code/collections/EnvironmentVariables.java b/code/collections/EnvironmentVariables.java deleted file mode 100644 index af89e5a2..00000000 --- a/code/collections/EnvironmentVariables.java +++ /dev/null @@ -1,15 +0,0 @@ -// collections/EnvironmentVariables.java -// (c)2020 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. -// {VisuallyInspectOutput} -import java.util.*; - -public class EnvironmentVariables { - public static void main(String[] args) { - for(Map.Entry entry: System.getenv().entrySet()) { - System.out.println(entry.getKey() + ": " + - entry.getValue()); - } - } -} diff --git a/code/collections/ForInCollections.java b/code/collections/ForInCollections.java deleted file mode 100644 index a8ddd792..00000000 --- a/code/collections/ForInCollections.java +++ /dev/null @@ -1,19 +0,0 @@ -// collections/ForInCollections.java -// (c)2020 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. -// All collections work with for-in -import java.util.*; - -public class ForInCollections { - public static void main(String[] args) { - Collection cs = new LinkedList<>(); - Collections.addAll(cs, - "Take the long way home".split(" ")); - for(String s : cs) - System.out.print("'" + s + "' "); - } -} -/* Output: -'Take' 'the' 'long' 'way' 'home' -*/ diff --git a/code/collections/GenericsAndUpcasting.java b/code/collections/GenericsAndUpcasting.java deleted file mode 100644 index ed8d3f55..00000000 --- a/code/collections/GenericsAndUpcasting.java +++ /dev/null @@ -1,28 +0,0 @@ -// collections/GenericsAndUpcasting.java -// (c)2020 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. -import java.util.*; - -class GrannySmith extends Apple {} -class Gala extends Apple {} -class Fuji extends Apple {} -class Braeburn extends Apple {} - -public class GenericsAndUpcasting { - public static void main(String[] args) { - ArrayList apples = new ArrayList<>(); - apples.add(new GrannySmith()); - apples.add(new Gala()); - apples.add(new Fuji()); - apples.add(new Braeburn()); - for(Apple apple : apples) - System.out.println(apple); - } -} -/* Output: -GrannySmith@15db9742 -Gala@6d06d69c -Fuji@7852e922 -Braeburn@4e25154f -*/ diff --git a/code/collections/InterfaceVsIterator.java b/code/collections/InterfaceVsIterator.java deleted file mode 100644 index b5a8663d..00000000 --- a/code/collections/InterfaceVsIterator.java +++ /dev/null @@ -1,55 +0,0 @@ -// collections/InterfaceVsIterator.java -// (c)2020 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. -import typeinfo.pets.*; -import java.util.*; - -public class InterfaceVsIterator { - public static void display(Iterator it) { - while(it.hasNext()) { - Pet p = it.next(); - System.out.print(p.id() + ":" + p + " "); - } - System.out.println(); - } - public static void display(Collection pets) { - for(Pet p : pets) - System.out.print(p.id() + ":" + p + " "); - System.out.println(); - } - public static void main(String[] args) { - List petList = Pets.list(8); - Set petSet = new HashSet<>(petList); - Map petMap = new LinkedHashMap<>(); - String[] names = ("Ralph, Eric, Robin, Lacey, " + - "Britney, Sam, Spot, Fluffy").split(", "); - for(int i = 0; i < names.length; i++) - petMap.put(names[i], petList.get(i)); - display(petList); - display(petSet); - display(petList.iterator()); - display(petSet.iterator()); - System.out.println(petMap); - System.out.println(petMap.keySet()); - display(petMap.values()); - display(petMap.values().iterator()); - } -} -/* Output: -0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug -7:Manx -0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug -7:Manx -0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug -7:Manx -0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug -7:Manx -{Ralph=Rat, Eric=Manx, Robin=Cymric, Lacey=Mutt, -Britney=Pug, Sam=Cymric, Spot=Pug, Fluffy=Manx} -[Ralph, Eric, Robin, Lacey, Britney, Sam, Spot, Fluffy] -0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug -7:Manx -0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug -7:Manx -*/ diff --git a/code/collections/IterableClass.java b/code/collections/IterableClass.java deleted file mode 100644 index 260edc7d..00000000 --- a/code/collections/IterableClass.java +++ /dev/null @@ -1,35 +0,0 @@ -// collections/IterableClass.java -// (c)2020 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. -// Anything Iterable works with for-in -import java.util.*; - -public class IterableClass implements Iterable { - protected String[] words = ("And that is how " + - "we know the Earth to be banana-shaped." - ).split(" "); - @Override - public Iterator iterator() { - return new Iterator() { - private int index = 0; - @Override - public boolean hasNext() { - return index < words.length; - } - @Override - public String next() { return words[index++]; } - @Override - public void remove() { // Not implemented - throw new UnsupportedOperationException(); - } - }; - } - public static void main(String[] args) { - for(String s : new IterableClass()) - System.out.print(s + " "); - } -} -/* Output: -And that is how we know the Earth to be banana-shaped. -*/ diff --git a/code/collections/LinkedListFeatures.java b/code/collections/LinkedListFeatures.java deleted file mode 100644 index 3c10ff4e..00000000 --- a/code/collections/LinkedListFeatures.java +++ /dev/null @@ -1,54 +0,0 @@ -// collections/LinkedListFeatures.java -// (c)2020 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. -import typeinfo.pets.*; -import java.util.*; - -public class LinkedListFeatures { - public static void main(String[] args) { - LinkedList pets = - new LinkedList<>(Pets.list(5)); - System.out.println(pets); - // Identical: - System.out.println( - "pets.getFirst(): " + pets.getFirst()); - System.out.println( - "pets.element(): " + pets.element()); - // Only differs in empty-list behavior: - System.out.println("pets.peek(): " + pets.peek()); - // Identical; remove and return the first element: - System.out.println( - "pets.remove(): " + pets.remove()); - System.out.println( - "pets.removeFirst(): " + pets.removeFirst()); - // Only differs in empty-list behavior: - System.out.println("pets.poll(): " + pets.poll()); - System.out.println(pets); - pets.addFirst(new Rat()); - System.out.println("After addFirst(): " + pets); - pets.offer(Pets.get()); - System.out.println("After offer(): " + pets); - pets.add(Pets.get()); - System.out.println("After add(): " + pets); - pets.addLast(new Hamster()); - System.out.println("After addLast(): " + pets); - System.out.println( - "pets.removeLast(): " + pets.removeLast()); - } -} -/* Output: -[Rat, Manx, Cymric, Mutt, Pug] -pets.getFirst(): Rat -pets.element(): Rat -pets.peek(): Rat -pets.remove(): Rat -pets.removeFirst(): Manx -pets.poll(): Cymric -[Mutt, Pug] -After addFirst(): [Rat, Mutt, Pug] -After offer(): [Rat, Mutt, Pug, Cymric] -After add(): [Rat, Mutt, Pug, Cymric, Pug] -After addLast(): [Rat, Mutt, Pug, Cymric, Pug, Hamster] -pets.removeLast(): Hamster -*/ diff --git a/code/collections/ListFeatures.java b/code/collections/ListFeatures.java deleted file mode 100644 index b4ee16ab..00000000 --- a/code/collections/ListFeatures.java +++ /dev/null @@ -1,93 +0,0 @@ -// collections/ListFeatures.java -// (c)2020 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. -import typeinfo.pets.*; -import java.util.*; - -public class ListFeatures { - public static void main(String[] args) { - Random rand = new Random(47); - List pets = Pets.list(7); - System.out.println("1: " + pets); - Hamster h = new Hamster(); - pets.add(h); // Automatically resizes - System.out.println("2: " + pets); - System.out.println("3: " + pets.contains(h)); - pets.remove(h); // Remove by object - Pet p = pets.get(2); - System.out.println( - "4: " + p + " " + pets.indexOf(p)); - Pet cymric = new Cymric(); - System.out.println("5: " + pets.indexOf(cymric)); - System.out.println("6: " + pets.remove(cymric)); - // Must be the exact object: - System.out.println("7: " + pets.remove(p)); - System.out.println("8: " + pets); - pets.add(3, new Mouse()); // Insert at an index - System.out.println("9: " + pets); - List sub = pets.subList(1, 4); - System.out.println("subList: " + sub); - System.out.println("10: " + pets.containsAll(sub)); - Collections.sort(sub); // In-place sort - System.out.println("sorted subList: " + sub); - // Order is not important in containsAll(): - System.out.println("11: " + pets.containsAll(sub)); - Collections.shuffle(sub, rand); // Mix it up - System.out.println("shuffled subList: " + sub); - System.out.println("12: " + pets.containsAll(sub)); - List copy = new ArrayList<>(pets); - sub = Arrays.asList(pets.get(1), pets.get(4)); - System.out.println("sub: " + sub); - copy.retainAll(sub); - System.out.println("13: " + copy); - copy = new ArrayList<>(pets); // Get a fresh copy - copy.remove(2); // Remove by index - System.out.println("14: " + copy); - copy.removeAll(sub); // Only removes exact objects - System.out.println("15: " + copy); - copy.set(1, new Mouse()); // Replace an element - System.out.println("16: " + copy); - copy.addAll(2, sub); // Insert a list in the middle - System.out.println("17: " + copy); - System.out.println("18: " + pets.isEmpty()); - pets.clear(); // Remove all elements - System.out.println("19: " + pets); - System.out.println("20: " + pets.isEmpty()); - pets.addAll(Pets.list(4)); - System.out.println("21: " + pets); - Object[] o = pets.toArray(); - System.out.println("22: " + o[3]); - Pet[] pa = pets.toArray(new Pet[0]); - System.out.println("23: " + pa[3].id()); - } -} -/* Output: -1: [Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug] -2: [Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug, Hamster] -3: true -4: Cymric 2 -5: -1 -6: false -7: true -8: [Rat, Manx, Mutt, Pug, Cymric, Pug] -9: [Rat, Manx, Mutt, Mouse, Pug, Cymric, Pug] -subList: [Manx, Mutt, Mouse] -10: true -sorted subList: [Manx, Mouse, Mutt] -11: true -shuffled subList: [Mouse, Manx, Mutt] -12: true -sub: [Mouse, Pug] -13: [Mouse, Pug] -14: [Rat, Mouse, Mutt, Pug, Cymric, Pug] -15: [Rat, Mutt, Cymric, Pug] -16: [Rat, Mouse, Cymric, Pug] -17: [Rat, Mouse, Mouse, Pug, Cymric, Pug] -18: false -19: [] -20: true -21: [Manx, Cymric, Rat, EgyptianMau] -22: EgyptianMau -23: 14 -*/ diff --git a/code/collections/ListIteration.java b/code/collections/ListIteration.java deleted file mode 100644 index 95d2786c..00000000 --- a/code/collections/ListIteration.java +++ /dev/null @@ -1,37 +0,0 @@ -// collections/ListIteration.java -// (c)2020 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. -import typeinfo.pets.*; -import java.util.*; - -public class ListIteration { - public static void main(String[] args) { - List pets = Pets.list(8); - ListIterator it = pets.listIterator(); - while(it.hasNext()) - System.out.print(it.next() + - ", " + it.nextIndex() + - ", " + it.previousIndex() + "; "); - System.out.println(); - // Backwards: - while(it.hasPrevious()) - System.out.print(it.previous().id() + " "); - System.out.println(); - System.out.println(pets); - it = pets.listIterator(3); - while(it.hasNext()) { - it.next(); - it.set(Pets.get()); - } - System.out.println(pets); - } -} -/* Output: -Rat, 1, 0; Manx, 2, 1; Cymric, 3, 2; Mutt, 4, 3; Pug, -5, 4; Cymric, 6, 5; Pug, 7, 6; Manx, 8, 7; -7 6 5 4 3 2 1 0 -[Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug, Manx] -[Rat, Manx, Cymric, Cymric, Rat, EgyptianMau, Hamster, -EgyptianMau] -*/ diff --git a/code/collections/MapOfList.java b/code/collections/MapOfList.java deleted file mode 100644 index 3a985dd9..00000000 --- a/code/collections/MapOfList.java +++ /dev/null @@ -1,65 +0,0 @@ -// collections/MapOfList.java -// (c)2020 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. -// {java collections.MapOfList} -package collections; -import typeinfo.pets.*; -import java.util.*; - -public class MapOfList { - public static final Map> - petPeople = new HashMap<>(); - static { - petPeople.put(new Person("Dawn"), - Arrays.asList( - new Cymric("Molly"), - new Mutt("Spot"))); - petPeople.put(new Person("Kate"), - Arrays.asList(new Cat("Shackleton"), - new Cat("Elsie May"), new Dog("Margrett"))); - petPeople.put(new Person("Marilyn"), - Arrays.asList( - new Pug("Louie aka Louis Snorkelstein Dupree"), - new Cat("Stanford"), - new Cat("Pinkola"))); - petPeople.put(new Person("Luke"), - Arrays.asList( - new Rat("Fuzzy"), new Rat("Fizzy"))); - petPeople.put(new Person("Isaac"), - Arrays.asList(new Rat("Freckly"))); - } - public static void main(String[] args) { - System.out.println("People: " + petPeople.keySet()); - System.out.println("Pets: " + petPeople.values()); - for(Person person : petPeople.keySet()) { - System.out.println(person + " has:"); - for(Pet pet : petPeople.get(person)) - System.out.println(" " + pet); - } - } -} -/* Output: -People: [Person Dawn, Person Kate, Person Isaac, Person -Marilyn, Person Luke] -Pets: [[Cymric Molly, Mutt Spot], [Cat Shackleton, Cat -Elsie May, Dog Margrett], [Rat Freckly], [Pug Louie aka -Louis Snorkelstein Dupree, Cat Stanford, Cat Pinkola], -[Rat Fuzzy, Rat Fizzy]] -Person Dawn has: - Cymric Molly - Mutt Spot -Person Kate has: - Cat Shackleton - Cat Elsie May - Dog Margrett -Person Isaac has: - Rat Freckly -Person Marilyn has: - Pug Louie aka Louis Snorkelstein Dupree - Cat Stanford - Cat Pinkola -Person Luke has: - Rat Fuzzy - Rat Fizzy -*/ diff --git a/code/collections/ModifyingArraysAsList.java b/code/collections/ModifyingArraysAsList.java deleted file mode 100644 index fea3da42..00000000 --- a/code/collections/ModifyingArraysAsList.java +++ /dev/null @@ -1,32 +0,0 @@ -// collections/ModifyingArraysAsList.java -// (c)2020 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. -import java.util.*; - -public class ModifyingArraysAsList { - public static void main(String[] args) { - Random rand = new Random(47); - Integer[] ia = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; - List list1 = - new ArrayList<>(Arrays.asList(ia)); - System.out.println("Before shuffling: " + list1); - Collections.shuffle(list1, rand); - System.out.println("After shuffling: " + list1); - System.out.println("array: " + Arrays.toString(ia)); - - List list2 = Arrays.asList(ia); - System.out.println("Before shuffling: " + list2); - Collections.shuffle(list2, rand); - System.out.println("After shuffling: " + list2); - System.out.println("array: " + Arrays.toString(ia)); - } -} -/* Output: -Before shuffling: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] -After shuffling: [4, 6, 3, 1, 8, 7, 2, 5, 10, 9] -array: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] -Before shuffling: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] -After shuffling: [9, 1, 6, 3, 7, 2, 5, 10, 4, 8] -array: [9, 1, 6, 3, 7, 2, 5, 10, 4, 8] -*/ diff --git a/code/collections/MultiIterableClass.java b/code/collections/MultiIterableClass.java deleted file mode 100644 index 1d7376e5..00000000 --- a/code/collections/MultiIterableClass.java +++ /dev/null @@ -1,53 +0,0 @@ -// collections/MultiIterableClass.java -// (c)2020 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. -// Adding several Adapter Methods -import java.util.*; - -public class MultiIterableClass extends IterableClass { - public Iterable reversed() { - return new Iterable() { - public Iterator iterator() { - return new Iterator() { - int current = words.length - 1; - public boolean hasNext() { - return current > -1; - } - public String next() { - return words[current--]; - } - public void remove() { // Not implemented - throw new UnsupportedOperationException(); - } - }; - } - }; - } - public Iterable randomized() { - return new Iterable() { - public Iterator iterator() { - List shuffled = - new ArrayList(Arrays.asList(words)); - Collections.shuffle(shuffled, new Random(47)); - return shuffled.iterator(); - } - }; - } - public static void main(String[] args) { - MultiIterableClass mic = new MultiIterableClass(); - for(String s : mic.reversed()) - System.out.print(s + " "); - System.out.println(); - for(String s : mic.randomized()) - System.out.print(s + " "); - System.out.println(); - for(String s : mic) - System.out.print(s + " "); - } -} -/* Output: -banana-shaped. be to Earth the know we how is that And -is banana-shaped. Earth that how the be And we know to -And that is how we know the Earth to be banana-shaped. -*/ diff --git a/code/collections/NonCollectionSequence.java b/code/collections/NonCollectionSequence.java deleted file mode 100644 index ed1ae6f6..00000000 --- a/code/collections/NonCollectionSequence.java +++ /dev/null @@ -1,37 +0,0 @@ -// collections/NonCollectionSequence.java -// (c)2020 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. -import typeinfo.pets.*; -import java.util.*; - -class PetSequence { - protected Pet[] pets = Pets.array(8); -} - -public class NonCollectionSequence extends PetSequence { - public Iterator iterator() { - return new Iterator() { - private int index = 0; - @Override - public boolean hasNext() { - return index < pets.length; - } - @Override - public Pet next() { return pets[index++]; } - @Override - public void remove() { // Not implemented - throw new UnsupportedOperationException(); - } - }; - } - public static void main(String[] args) { - NonCollectionSequence nc = - new NonCollectionSequence(); - InterfaceVsIterator.display(nc.iterator()); - } -} -/* Output: -0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug -7:Manx -*/ diff --git a/code/collections/PetMap.java b/code/collections/PetMap.java deleted file mode 100644 index 18d02ef0..00000000 --- a/code/collections/PetMap.java +++ /dev/null @@ -1,27 +0,0 @@ -// collections/PetMap.java -// (c)2020 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. -import typeinfo.pets.*; -import java.util.*; - -public class PetMap { - public static void main(String[] args) { - Map petMap = new HashMap<>(); - petMap.put("My Cat", new Cat("Molly")); - petMap.put("My Dog", new Dog("Ginger")); - petMap.put("My Hamster", new Hamster("Bosco")); - System.out.println(petMap); - Pet dog = petMap.get("My Dog"); - System.out.println(dog); - System.out.println(petMap.containsKey("My Dog")); - System.out.println(petMap.containsValue(dog)); - } -} -/* Output: -{My Dog=Dog Ginger, My Cat=Cat Molly, My -Hamster=Hamster Bosco} -Dog Ginger -true -true -*/ diff --git a/code/collections/PrintingCollections.java b/code/collections/PrintingCollections.java deleted file mode 100644 index c5746fc3..00000000 --- a/code/collections/PrintingCollections.java +++ /dev/null @@ -1,44 +0,0 @@ -// collections/PrintingCollections.java -// (c)2020 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. -// Collections print themselves automatically -import java.util.*; - -public class PrintingCollections { - static Collection - fill(Collection collection) { - collection.add("rat"); - collection.add("cat"); - collection.add("dog"); - collection.add("dog"); - return collection; - } - static Map fill(Map map) { - map.put("rat", "Fuzzy"); - map.put("cat", "Rags"); - map.put("dog", "Bosco"); - map.put("dog", "Spot"); - return map; - } - public static void main(String[] args) { - System.out.println(fill(new ArrayList<>())); - System.out.println(fill(new LinkedList<>())); - System.out.println(fill(new HashSet<>())); - System.out.println(fill(new TreeSet<>())); - System.out.println(fill(new LinkedHashSet<>())); - System.out.println(fill(new HashMap<>())); - System.out.println(fill(new TreeMap<>())); - System.out.println(fill(new LinkedHashMap<>())); - } -} -/* Output: -[rat, cat, dog, dog] -[rat, cat, dog, dog] -[rat, cat, dog] -[cat, dog, rat] -[rat, cat, dog] -{rat=Fuzzy, cat=Rags, dog=Spot} -{cat=Rags, dog=Spot, rat=Fuzzy} -{rat=Fuzzy, cat=Rags, dog=Spot} -*/ diff --git a/code/collections/PriorityQueueDemo.java b/code/collections/PriorityQueueDemo.java deleted file mode 100644 index 4f71ab0e..00000000 --- a/code/collections/PriorityQueueDemo.java +++ /dev/null @@ -1,53 +0,0 @@ -// collections/PriorityQueueDemo.java -// (c)2020 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. -import java.util.*; - -public class PriorityQueueDemo { - public static void main(String[] args) { - PriorityQueue priorityQueue = - new PriorityQueue<>(); - Random rand = new Random(47); - for(int i = 0; i < 10; i++) - priorityQueue.offer(rand.nextInt(i + 10)); - QueueDemo.printQ(priorityQueue); - - List ints = Arrays.asList(25, 22, 20, - 18, 14, 9, 3, 1, 1, 2, 3, 9, 14, 18, 21, 23, 25); - priorityQueue = new PriorityQueue<>(ints); - QueueDemo.printQ(priorityQueue); - priorityQueue = new PriorityQueue<>( - ints.size(), Collections.reverseOrder()); - priorityQueue.addAll(ints); - QueueDemo.printQ(priorityQueue); - - String fact = "EDUCATION SHOULD ESCHEW OBFUSCATION"; - List strings = - Arrays.asList(fact.split("")); - PriorityQueue stringPQ = - new PriorityQueue<>(strings); - QueueDemo.printQ(stringPQ); - stringPQ = new PriorityQueue<>( - strings.size(), Collections.reverseOrder()); - stringPQ.addAll(strings); - QueueDemo.printQ(stringPQ); - - Set charSet = new HashSet<>(); - for(char c : fact.toCharArray()) - charSet.add(c); // Autoboxing - PriorityQueue characterPQ = - new PriorityQueue<>(charSet); - QueueDemo.printQ(characterPQ); - } -} -/* Output: -0 1 1 1 1 1 3 5 8 14 -1 1 2 3 3 9 9 14 14 18 18 20 21 22 23 25 25 -25 25 23 22 21 20 18 18 14 14 9 9 3 3 2 1 1 - A A B C C C D D E E E F H H I I L N N O O O O S S -S T T U U U W -W U U U T T S S S O O O O N N L I I H H F E E E D D C C -C B A A - A B C D E F H I L N O S T U W -*/ diff --git a/code/collections/QueueDemo.java b/code/collections/QueueDemo.java deleted file mode 100644 index f807e89a..00000000 --- a/code/collections/QueueDemo.java +++ /dev/null @@ -1,29 +0,0 @@ -// collections/QueueDemo.java -// (c)2020 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. -// Upcasting to a Queue from a LinkedList -import java.util.*; - -public class QueueDemo { - public static void printQ(Queue queue) { - while(queue.peek() != null) - System.out.print(queue.remove() + " "); - System.out.println(); - } - public static void main(String[] args) { - Queue queue = new LinkedList<>(); - Random rand = new Random(47); - for(int i = 0; i < 10; i++) - queue.offer(rand.nextInt(i + 10)); - printQ(queue); - Queue qc = new LinkedList<>(); - for(char c : "Brontosaurus".toCharArray()) - qc.offer(c); - printQ(qc); - } -} -/* Output: -8 1 1 1 5 14 3 1 0 1 -B r o n t o s a u r u s -*/ diff --git a/code/collections/SetOfInteger.java b/code/collections/SetOfInteger.java deleted file mode 100644 index 78157d5c..00000000 --- a/code/collections/SetOfInteger.java +++ /dev/null @@ -1,19 +0,0 @@ -// collections/SetOfInteger.java -// (c)2020 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. -import java.util.*; - -public class SetOfInteger { - public static void main(String[] args) { - Random rand = new Random(47); - Set intset = new HashSet<>(); - for(int i = 0; i < 10000; i++) - intset.add(rand.nextInt(30)); - System.out.println(intset); - } -} -/* Output: -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29] -*/ diff --git a/code/collections/SetOfString.java b/code/collections/SetOfString.java deleted file mode 100644 index 01d9455e..00000000 --- a/code/collections/SetOfString.java +++ /dev/null @@ -1,25 +0,0 @@ -// collections/SetOfString.java -// (c)2020 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. -import java.util.*; - -public class SetOfString { - public static void main(String[] args) { - Set colors = new HashSet<>(); - for(int i = 0; i < 100; i++) { - colors.add("Yellow"); - colors.add("Blue"); - colors.add("Red"); - colors.add("Red"); - colors.add("Orange"); - colors.add("Yellow"); - colors.add("Blue"); - colors.add("Purple"); - } - System.out.println(colors); - } -} -/* Output: -[Red, Yellow, Blue, Purple, Orange] -*/ diff --git a/code/collections/SetOperations.java b/code/collections/SetOperations.java deleted file mode 100644 index f716f965..00000000 --- a/code/collections/SetOperations.java +++ /dev/null @@ -1,40 +0,0 @@ -// collections/SetOperations.java -// (c)2020 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. -import java.util.*; - -public class SetOperations { - public static void main(String[] args) { - Set set1 = new HashSet<>(); - Collections.addAll(set1, - "A B C D E F G H I J K L".split(" ")); - set1.add("M"); - System.out.println("H: " + set1.contains("H")); - System.out.println("N: " + set1.contains("N")); - Set set2 = new HashSet<>(); - Collections.addAll(set2, "H I J K L".split(" ")); - System.out.println( - "set2 in set1: " + set1.containsAll(set2)); - set1.remove("H"); - System.out.println("set1: " + set1); - System.out.println( - "set2 in set1: " + set1.containsAll(set2)); - set1.removeAll(set2); - System.out.println( - "set2 removed from set1: " + set1); - Collections.addAll(set1, "X Y Z".split(" ")); - System.out.println( - "'X Y Z' added to set1: " + set1); - } -} -/* Output: -H: true -N: false -set2 in set1: true -set1: [A, B, C, D, E, F, G, I, J, K, L, M] -set2 in set1: false -set2 removed from set1: [A, B, C, D, E, F, G, M] -'X Y Z' added to set1: [A, B, C, D, E, F, G, M, X, Y, -Z] -*/ diff --git a/code/collections/SimpleCollection.java b/code/collections/SimpleCollection.java deleted file mode 100644 index 8915e259..00000000 --- a/code/collections/SimpleCollection.java +++ /dev/null @@ -1,18 +0,0 @@ -// collections/SimpleCollection.java -// (c)2020 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. -import java.util.*; - -public class SimpleCollection { - public static void main(String[] args) { - Collection c = new ArrayList<>(); - for(int i = 0; i < 10; i++) - c.add(i); // Autoboxing - for(Integer i : c) - System.out.print(i + ", "); - } -} -/* Output: -0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -*/ diff --git a/code/collections/SimpleIteration.java b/code/collections/SimpleIteration.java deleted file mode 100644 index a65a2a71..00000000 --- a/code/collections/SimpleIteration.java +++ /dev/null @@ -1,36 +0,0 @@ -// collections/SimpleIteration.java -// (c)2020 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. -import typeinfo.pets.*; -import java.util.*; - -public class SimpleIteration { - public static void main(String[] args) { - List pets = Pets.list(12); - Iterator it = pets.iterator(); - while(it.hasNext()) { - Pet p = it.next(); - System.out.print(p.id() + ":" + p + " "); - } - System.out.println(); - // A simpler approach, when possible: - for(Pet p : pets) - System.out.print(p.id() + ":" + p + " "); - System.out.println(); - // An Iterator can also remove elements: - it = pets.iterator(); - for(int i = 0; i < 6; i++) { - it.next(); - it.remove(); - } - System.out.println(pets); - } -} -/* Output: -0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug -7:Manx 8:Cymric 9:Rat 10:EgyptianMau 11:Hamster -0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug -7:Manx 8:Cymric 9:Rat 10:EgyptianMau 11:Hamster -[Pug, Manx, Cymric, Rat, EgyptianMau, Hamster] -*/ diff --git a/code/collections/SortedSetOfString.java b/code/collections/SortedSetOfString.java deleted file mode 100644 index a043b791..00000000 --- a/code/collections/SortedSetOfString.java +++ /dev/null @@ -1,25 +0,0 @@ -// collections/SortedSetOfString.java -// (c)2020 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. -import java.util.*; - -public class SortedSetOfString { - public static void main(String[] args) { - Set colors = new TreeSet<>(); - for(int i = 0; i < 100; i++) { - colors.add("Yellow"); - colors.add("Blue"); - colors.add("Red"); - colors.add("Red"); - colors.add("Orange"); - colors.add("Yellow"); - colors.add("Blue"); - colors.add("Purple"); - } - System.out.println(colors); - } -} -/* Output: -[Blue, Orange, Purple, Red, Yellow] -*/ diff --git a/code/collections/StackCollision.java b/code/collections/StackCollision.java deleted file mode 100644 index 67ee4d90..00000000 --- a/code/collections/StackCollision.java +++ /dev/null @@ -1,25 +0,0 @@ -// collections/StackCollision.java -// (c)2020 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. - -public class StackCollision { - public static void main(String[] args) { - onjava.Stack stack = new onjava.Stack<>(); - for(String s : "My dog has fleas".split(" ")) - stack.push(s); - while(!stack.isEmpty()) - System.out.print(stack.pop() + " "); - System.out.println(); - java.util.Stack stack2 = - new java.util.Stack<>(); - for(String s : "My dog has fleas".split(" ")) - stack2.push(s); - while(!stack2.empty()) - System.out.print(stack2.pop() + " "); - } -} -/* Output: -fleas has dog My -fleas has dog My -*/ diff --git a/code/collections/StackTest.java b/code/collections/StackTest.java deleted file mode 100644 index dc1663cc..00000000 --- a/code/collections/StackTest.java +++ /dev/null @@ -1,18 +0,0 @@ -// collections/StackTest.java -// (c)2020 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. -import java.util.*; - -public class StackTest { - public static void main(String[] args) { - Deque stack = new ArrayDeque<>(); - for(String s : "My dog has fleas".split(" ")) - stack.push(s); - while(!stack.isEmpty()) - System.out.print(stack.pop() + " "); - } -} -/* Output: -fleas has dog My -*/ diff --git a/code/collections/StackTest2.java b/code/collections/StackTest2.java deleted file mode 100644 index 2464d7a9..00000000 --- a/code/collections/StackTest2.java +++ /dev/null @@ -1,18 +0,0 @@ -// collections/StackTest2.java -// (c)2020 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. -import onjava.*; - -public class StackTest2 { - public static void main(String[] args) { - Stack stack = new Stack<>(); - for(String s : "My dog has fleas".split(" ")) - stack.push(s); - while(!stack.isEmpty()) - System.out.print(stack.pop() + " "); - } -} -/* Output: -fleas has dog My -*/ diff --git a/code/collections/Statistics.java b/code/collections/Statistics.java deleted file mode 100644 index f888db58..00000000 --- a/code/collections/Statistics.java +++ /dev/null @@ -1,25 +0,0 @@ -// collections/Statistics.java -// (c)2020 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. -// Simple demonstration of HashMap -import java.util.*; - -public class Statistics { - public static void main(String[] args) { - Random rand = new Random(47); - Map m = new HashMap<>(); - for(int i = 0; i < 10000; i++) { - // Produce a number between 0 and 20: - int r = rand.nextInt(20); - Integer freq = m.get(r); // [1] - m.put(r, freq == null ? 1 : freq + 1); - } - System.out.println(m); - } -} -/* Output: -{0=481, 1=502, 2=489, 3=508, 4=481, 5=503, 6=519, -7=471, 8=468, 9=549, 10=513, 11=531, 12=521, 13=506, -14=477, 15=497, 16=533, 17=509, 18=478, 19=464} -*/ diff --git a/code/collections/UniqueWords.java b/code/collections/UniqueWords.java deleted file mode 100644 index c6c3681d..00000000 --- a/code/collections/UniqueWords.java +++ /dev/null @@ -1,29 +0,0 @@ -// collections/UniqueWords.java -// (c)2020 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. -import java.util.*; -import java.nio.file.*; - -public class UniqueWords { - public static void - main(String[] args) throws Exception { - List lines = Files.readAllLines( - Paths.get("SetOperations.java")); - Set words = new TreeSet<>(); - for(String line : lines) - for(String word : line.split("\\W+")) - if(word.trim().length() > 0) - words.add(word); - System.out.println(words); - } -} -/* Output: -[A, B, C, Collections, D, E, F, G, H, HashSet, I, J, K, -L, M, N, Output, Set, SetOperations, String, System, X, -Y, Z, add, addAll, added, args, class, collections, -contains, containsAll, false, from, import, in, java, -main, new, out, println, public, remove, removeAll, -removed, set1, set2, split, static, to, true, util, -void] -*/ diff --git a/code/collections/UniqueWordsAlphabetic.java b/code/collections/UniqueWordsAlphabetic.java deleted file mode 100644 index 66a7fecf..00000000 --- a/code/collections/UniqueWordsAlphabetic.java +++ /dev/null @@ -1,30 +0,0 @@ -// collections/UniqueWordsAlphabetic.java -// (c)2020 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. -// Producing an alphabetic listing -import java.util.*; -import java.nio.file.*; - -public class UniqueWordsAlphabetic { - public static void - main(String[] args) throws Exception { - List lines = Files.readAllLines( - Paths.get("SetOperations.java")); - Set words = - new TreeSet<>(String.CASE_INSENSITIVE_ORDER); - for(String line : lines) - for(String word : line.split("\\W+")) - if(word.trim().length() > 0) - words.add(word); - System.out.println(words); - } -} -/* Output: -[A, add, addAll, added, args, B, C, class, collections, -contains, containsAll, D, E, F, false, from, G, H, -HashSet, I, import, in, J, java, K, L, M, main, N, new, -out, Output, println, public, remove, removeAll, -removed, Set, set1, set2, SetOperations, split, static, -String, System, to, true, util, void, X, Y, Z] -*/ diff --git a/code/collectiontopics/AssociativeArray.java b/code/collectiontopics/AssociativeArray.java deleted file mode 100644 index e7488489..00000000 --- a/code/collectiontopics/AssociativeArray.java +++ /dev/null @@ -1,64 +0,0 @@ -// collectiontopics/AssociativeArray.java -// (c)2020 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. -// Associates keys with values - -public class AssociativeArray { - private Object[][] pairs; - private int index; - public AssociativeArray(int length) { - pairs = new Object[length][2]; - } - public void put(K key, V value) { - if(index >= pairs.length) - throw new ArrayIndexOutOfBoundsException(); - pairs[index++] = new Object[]{ key, value }; - } - @SuppressWarnings("unchecked") - public V get(K key) { - for(int i = 0; i < index; i++) - if(key.equals(pairs[i][0])) - return (V)pairs[i][1]; - return null; // Did not find key - } - @Override - public String toString() { - StringBuilder result = new StringBuilder(); - for(int i = 0; i < index; i++) { - result.append(pairs[i][0].toString()); - result.append(" : "); - result.append(pairs[i][1].toString()); - if(i < index - 1) - result.append("\n"); - } - return result.toString(); - } - public static void main(String[] args) { - AssociativeArray map = - new AssociativeArray<>(6); - map.put("sky", "blue"); - map.put("grass", "green"); - map.put("ocean", "dancing"); - map.put("tree", "tall"); - map.put("earth", "brown"); - map.put("sun", "warm"); - try { - map.put("extra", "object"); // Past the end - } catch(ArrayIndexOutOfBoundsException e) { - System.out.println("Too many objects!"); - } - System.out.println(map); - System.out.println(map.get("ocean")); - } -} -/* Output: -Too many objects! -sky : blue -grass : green -ocean : dancing -tree : tall -earth : brown -sun : warm -dancing -*/ diff --git a/code/collectiontopics/Bits.java b/code/collectiontopics/Bits.java deleted file mode 100644 index 16afb361..00000000 --- a/code/collectiontopics/Bits.java +++ /dev/null @@ -1,79 +0,0 @@ -// collectiontopics/Bits.java -// (c)2020 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. -// Demonstration of BitSet -import java.util.*; - -public class Bits { - public static void printBitSet(BitSet b) { - System.out.println("bits: " + b); - StringBuilder bbits = new StringBuilder(); - for(int j = 0; j < b.size() ; j++) - bbits.append(b.get(j) ? "1" : "0"); - System.out.println("bit pattern: " + bbits); - } - public static void main(String[] args) { - Random rand = new Random(47); - // Take the LSB of nextInt(): - byte bt = (byte)rand.nextInt(); - BitSet bb = new BitSet(); - for(int i = 7; i >= 0; i--) - if(((1 << i) & bt) != 0) - bb.set(i); - else - bb.clear(i); - System.out.println("byte value: " + bt); - printBitSet(bb); - - short st = (short)rand.nextInt(); - BitSet bs = new BitSet(); - for(int i = 15; i >= 0; i--) - if(((1 << i) & st) != 0) - bs.set(i); - else - bs.clear(i); - System.out.println("short value: " + st); - printBitSet(bs); - - int it = rand.nextInt(); - BitSet bi = new BitSet(); - for(int i = 31; i >= 0; i--) - if(((1 << i) & it) != 0) - bi.set(i); - else - bi.clear(i); - System.out.println("int value: " + it); - printBitSet(bi); - - // Test bitsets >= 64 bits: - BitSet b127 = new BitSet(); - b127.set(127); - System.out.println("set bit 127: " + b127); - BitSet b255 = new BitSet(65); - b255.set(255); - System.out.println("set bit 255: " + b255); - BitSet b1023 = new BitSet(512); - b1023.set(1023); - b1023.set(1024); - System.out.println("set bit 1023: " + b1023); - } -} -/* Output: -byte value: -107 -bits: {0, 2, 4, 7} -bit pattern: 101010010000000000000000000000000000000000 -0000000000000000000000 -short value: 1302 -bits: {1, 2, 4, 8, 10} -bit pattern: 011010001010000000000000000000000000000000 -0000000000000000000000 -int value: -2014573909 -bits: {0, 1, 3, 5, 7, 9, 11, 18, 19, 21, 22, 23, 24, -25, 26, 31} -bit pattern: 110101010101000000110111111000010000000000 -0000000000000000000000 -set bit 127: {127} -set bit 255: {255} -set bit 1023: {1023, 1024} -*/ diff --git a/code/collectiontopics/CanonicalMapping.java b/code/collectiontopics/CanonicalMapping.java deleted file mode 100644 index c02f9132..00000000 --- a/code/collectiontopics/CanonicalMapping.java +++ /dev/null @@ -1,56 +0,0 @@ -// collectiontopics/CanonicalMapping.java -// (c)2020 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. -// Demonstrates WeakHashMap -import java.util.*; - -class Element { - private String ident; - Element(String id) { ident = id; } - @Override - public String toString() { return ident; } - @Override - public int hashCode() { - return Objects.hashCode(ident); - } - @Override - public boolean equals(Object r) { - return r instanceof Element && - Objects.equals(ident, ((Element)r).ident); - } - @SuppressWarnings("deprecation") - @Override - protected void finalize() { - System.out.println("Finalizing " + - getClass().getSimpleName() + " " + ident); - } -} - -class Key extends Element { - Key(String id) { super(id); } -} - -class Value extends Element { - Value(String id) { super(id); } -} - -public class CanonicalMapping { - public static void main(String[] args) { - int size = 1000; - // Or, choose size via the command line: - if(args.length > 0) - size = Integer.valueOf(args[0]); - Key[] keys = new Key[size]; - WeakHashMap map = - new WeakHashMap<>(); - for(int i = 0; i < size; i++) { - Key k = new Key(Integer.toString(i)); - Value v = new Value(Integer.toString(i)); - if(i % 3 == 0) - keys[i] = k; // Save as "real" references - map.put(k, v); - } - System.gc(); - } -} diff --git a/code/collectiontopics/CollectionMethods.java b/code/collectiontopics/CollectionMethods.java deleted file mode 100644 index e32e5982..00000000 --- a/code/collectiontopics/CollectionMethods.java +++ /dev/null @@ -1,135 +0,0 @@ -// collectiontopics/CollectionMethods.java -// (c)2020 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. -// Things you can do with all Collections -import java.util.*; -import static onjava.HTMLColors.*; - -public class CollectionMethods { - public static void main(String[] args) { - Collection c = - new ArrayList<>(LIST.subList(0, 4)); - c.add("ten"); - c.add("eleven"); - show(c); - border(); - // Make an array from the List: - Object[] array = c.toArray(); - // Make a String array from the List: - String[] str = c.toArray(new String[0]); - // Find max and min elements; this means - // different things depending on the way - // the Comparable interface is implemented: - System.out.println( - "Collections.max(c) = " + Collections.max(c)); - System.out.println( - "Collections.min(c) = " + Collections.min(c)); - border(); - // Add a Collection to another Collection - Collection c2 = - new ArrayList<>(LIST.subList(10, 14)); - c.addAll(c2); - show(c); - border(); - c.remove(LIST.get(0)); - show(c); - border(); - // Remove all components that are - // in the argument collection: - c.removeAll(c2); - show(c); - border(); - c.addAll(c2); - show(c); - border(); - // Is an element in this Collection? - String val = LIST.get(3); - System.out.println( - "c.contains(" + val + ") = " + c.contains(val)); - // Is a Collection in this Collection? - System.out.println( - "c.containsAll(c2) = " + c.containsAll(c2)); - Collection c3 = - ((List)c).subList(3, 5); - // Keep all the elements that are in both - // c2 and c3 (an intersection of sets): - c2.retainAll(c3); - show(c2); - // Throw away all the elements - // in c2 that also appear in c3: - c2.removeAll(c3); - System.out.println( - "c2.isEmpty() = " + c2.isEmpty()); - border(); - // Functional operation: - c = new ArrayList<>(LIST); - c.removeIf(s -> !s.startsWith("P")); - c.removeIf(s -> s.startsWith("Pale")); - // Stream operation: - c.stream().forEach(System.out::println); - c.clear(); // Remove all elements - System.out.println("after c.clear():" + c); - } -} -/* Output: -AliceBlue -AntiqueWhite -Aquamarine -Azure -ten -eleven -****************************** -Collections.max(c) = ten -Collections.min(c) = AliceBlue -****************************** -AliceBlue -AntiqueWhite -Aquamarine -Azure -ten -eleven -Brown -BurlyWood -CadetBlue -Chartreuse -****************************** -AntiqueWhite -Aquamarine -Azure -ten -eleven -Brown -BurlyWood -CadetBlue -Chartreuse -****************************** -AntiqueWhite -Aquamarine -Azure -ten -eleven -****************************** -AntiqueWhite -Aquamarine -Azure -ten -eleven -Brown -BurlyWood -CadetBlue -Chartreuse -****************************** -c.contains(Azure) = true -c.containsAll(c2) = true -c2.isEmpty() = true -****************************** -PapayaWhip -PeachPuff -Peru -Pink -Plum -PowderBlue -Purple -after c.clear():[] -*/ diff --git a/code/collectiontopics/Enumerations.java b/code/collectiontopics/Enumerations.java deleted file mode 100644 index 22b83e52..00000000 --- a/code/collectiontopics/Enumerations.java +++ /dev/null @@ -1,24 +0,0 @@ -// collectiontopics/Enumerations.java -// (c)2020 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. -// Java 1.0/1.1 Vector and Enumeration -import java.util.*; -import onjava.*; - -public class Enumerations { - public static void main(String[] args) { - Vector v = - new Vector<>(Countries.names(10)); - Enumeration e = v.elements(); - while(e.hasMoreElements()) - System.out.print(e.nextElement() + ", "); - // Produce an Enumeration from a Collection: - e = Collections.enumeration(new ArrayList<>()); - } -} -/* Output: -ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, -BURUNDI, CAMEROON, CAPE VERDE, CENTRAL AFRICAN -REPUBLIC, CHAD, -*/ diff --git a/code/collectiontopics/FailFast.java b/code/collectiontopics/FailFast.java deleted file mode 100644 index 0b0ce253..00000000 --- a/code/collectiontopics/FailFast.java +++ /dev/null @@ -1,22 +0,0 @@ -// collectiontopics/FailFast.java -// (c)2020 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. -// Demonstrates the "fail-fast" behavior -import java.util.*; - -public class FailFast { - public static void main(String[] args) { - Collection c = new ArrayList<>(); - Iterator it = c.iterator(); - c.add("An object"); - try { - String s = it.next(); - } catch(ConcurrentModificationException e) { - System.out.println(e); - } - } -} -/* Output: -java.util.ConcurrentModificationException -*/ diff --git a/code/collectiontopics/FillMapTest.java b/code/collectiontopics/FillMapTest.java deleted file mode 100644 index 5cfd612b..00000000 --- a/code/collectiontopics/FillMapTest.java +++ /dev/null @@ -1,32 +0,0 @@ -// collectiontopics/FillMapTest.java -// (c)2020 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. -import java.util.*; -import java.util.function.*; -import java.util.stream.*; -import onjava.*; - -public class FillMapTest { - public static void main(String[] args) { - Map mcs = FillMap.basic( - new Rand.String(4), new Count.Integer(), 7); - System.out.println(mcs); - HashMap hashm = - FillMap.create(new Rand.String(4), - new Count.Integer(), HashMap::new, 7); - System.out.println(hashm); - LinkedHashMap linkm = - FillMap.create(new Rand.String(4), - new Count.Integer(), LinkedHashMap::new, 7); - System.out.println(linkm); - } -} -/* Output: -{npcc=1, ztdv=6, gvgm=3, btpe=0, einn=4, eelo=5, -uxsz=2} -{npcc=1, ztdv=6, gvgm=3, btpe=0, einn=4, eelo=5, -uxsz=2} -{btpe=0, npcc=1, uxsz=2, gvgm=3, einn=4, eelo=5, -ztdv=6} -*/ diff --git a/code/collectiontopics/FillingLists.java b/code/collectiontopics/FillingLists.java deleted file mode 100644 index 32bdb8ef..00000000 --- a/code/collectiontopics/FillingLists.java +++ /dev/null @@ -1,35 +0,0 @@ -// collectiontopics/FillingLists.java -// (c)2020 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. -// Collections.fill() & Collections.nCopies() -import java.util.*; - -class StringAddress { - private String s; - StringAddress(String s) { this.s = s; } - @Override - public String toString() { - return super.toString() + " " + s; - } -} - -public class FillingLists { - public static void main(String[] args) { - List list = new ArrayList<>( - Collections.nCopies(4, - new StringAddress("Hello"))); - System.out.println(list); - Collections.fill(list, - new StringAddress("World!")); - System.out.println(list); - } -} -/* Output: -[StringAddress@15db9742 Hello, StringAddress@15db9742 -Hello, StringAddress@15db9742 Hello, -StringAddress@15db9742 Hello] -[StringAddress@6d06d69c World!, StringAddress@6d06d69c -World!, StringAddress@6d06d69c World!, -StringAddress@6d06d69c World!] -*/ diff --git a/code/collectiontopics/FunctionalMap.java b/code/collectiontopics/FunctionalMap.java deleted file mode 100644 index 404a1a64..00000000 --- a/code/collectiontopics/FunctionalMap.java +++ /dev/null @@ -1,38 +0,0 @@ -// collectiontopics/FunctionalMap.java -// (c)2020 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. -// Functional operations on a Map -import java.util.*; -import java.util.stream.*; -import java.util.concurrent.*; -import static onjava.HTMLColors.*; - -public class FunctionalMap { - public static void main(String[] args) { - MAP.entrySet().stream() - .map(Map.Entry::getValue) - .filter(v -> v.startsWith("Dark")) - .map(v -> v.replaceFirst("Dark", "Hot")) - .forEach(System.out::println); - } -} -/* Output: -HotBlue -HotCyan -HotGoldenRod -HotGray -HotGreen -HotKhaki -HotMagenta -HotOliveGreen -HotOrange -HotOrchid -HotRed -HotSalmon -HotSeaGreen -HotSlateBlue -HotSlateGray -HotTurquoise -HotViolet -*/ diff --git a/code/collectiontopics/HTMLColorTest.java b/code/collectiontopics/HTMLColorTest.java deleted file mode 100644 index 99037ced..00000000 --- a/code/collectiontopics/HTMLColorTest.java +++ /dev/null @@ -1,103 +0,0 @@ -// collectiontopics/HTMLColorTest.java -// (c)2020 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. -import static onjava.HTMLColors.*; - -public class HTMLColorTest { - static final int DISPLAY_SIZE = 20; - public static void main(String[] args) { - show(MAP, DISPLAY_SIZE); - border(); - showInv(INVMAP, DISPLAY_SIZE); - border(); - show(LIST, DISPLAY_SIZE); - border(); - showrgb(RGBLIST, DISPLAY_SIZE); - } -} -/* Output: -0xF0F8FF: AliceBlue -0xFAEBD7: AntiqueWhite -0x7FFFD4: Aquamarine -0xF0FFFF: Azure -0xF5F5DC: Beige -0xFFE4C4: Bisque -0x000000: Black -0xFFEBCD: BlanchedAlmond -0x0000FF: Blue -0x8A2BE2: BlueViolet -0xA52A2A: Brown -0xDEB887: BurlyWood -0x5F9EA0: CadetBlue -0x7FFF00: Chartreuse -0xD2691E: Chocolate -0xFF7F50: Coral -0x6495ED: CornflowerBlue -0xFFF8DC: Cornsilk -0xDC143C: Crimson -0x00FFFF: Cyan -****************************** -AliceBlue 0xF0F8FF -AntiqueWhite 0xFAEBD7 -Aquamarine 0x7FFFD4 -Azure 0xF0FFFF -Beige 0xF5F5DC -Bisque 0xFFE4C4 -Black 0x000000 -BlanchedAlmond 0xFFEBCD -Blue 0x0000FF -BlueViolet 0x8A2BE2 -Brown 0xA52A2A -BurlyWood 0xDEB887 -CadetBlue 0x5F9EA0 -Chartreuse 0x7FFF00 -Chocolate 0xD2691E -Coral 0xFF7F50 -CornflowerBlue 0x6495ED -Cornsilk 0xFFF8DC -Crimson 0xDC143C -Cyan 0x00FFFF -****************************** -AliceBlue -AntiqueWhite -Aquamarine -Azure -Beige -Bisque -Black -BlanchedAlmond -Blue -BlueViolet -Brown -BurlyWood -CadetBlue -Chartreuse -Chocolate -Coral -CornflowerBlue -Cornsilk -Crimson -Cyan -****************************** -0xF0F8FF -0xFAEBD7 -0x7FFFD4 -0xF0FFFF -0xF5F5DC -0xFFE4C4 -0x000000 -0xFFEBCD -0x0000FF -0x8A2BE2 -0xA52A2A -0xDEB887 -0x5F9EA0 -0x7FFF00 -0xD2691E -0xFF7F50 -0x6495ED -0xFFF8DC -0xDC143C -0x00FFFF -*/ diff --git a/code/collectiontopics/LinkedHashMapDemo.java b/code/collectiontopics/LinkedHashMapDemo.java deleted file mode 100644 index d0b93393..00000000 --- a/code/collectiontopics/LinkedHashMapDemo.java +++ /dev/null @@ -1,31 +0,0 @@ -// collectiontopics/LinkedHashMapDemo.java -// (c)2020 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 LinkedHashMap -import java.util.*; -import onjava.*; - -public class LinkedHashMapDemo { - public static void main(String[] args) { - LinkedHashMap linkedMap = - new LinkedHashMap<>(new CountMap(9)); - System.out.println(linkedMap); - // Least-recently-used order: - linkedMap = - new LinkedHashMap<>(16, 0.75f, true); - linkedMap.putAll(new CountMap(9)); - System.out.println(linkedMap); - for(int i = 0; i < 6; i++) - linkedMap.get(i); - System.out.println(linkedMap); - linkedMap.get(0); - System.out.println(linkedMap); - } -} -/* Output: -{0=A0, 1=B0, 2=C0, 3=D0, 4=E0, 5=F0, 6=G0, 7=H0, 8=I0} -{0=A0, 1=B0, 2=C0, 3=D0, 4=E0, 5=F0, 6=G0, 7=H0, 8=I0} -{6=G0, 7=H0, 8=I0, 0=A0, 1=B0, 2=C0, 3=D0, 4=E0, 5=F0} -{6=G0, 7=H0, 8=I0, 1=B0, 2=C0, 3=D0, 4=E0, 5=F0, 0=A0} -*/ diff --git a/code/collectiontopics/ListOps.java b/code/collectiontopics/ListOps.java deleted file mode 100644 index 824ffba9..00000000 --- a/code/collectiontopics/ListOps.java +++ /dev/null @@ -1,167 +0,0 @@ -// collectiontopics/ListOps.java -// (c)2020 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. -// Things you can do with Lists -import java.util.*; -import onjava.HTMLColors; - -public class ListOps { - // Create a short list for testing: - static final List LIST = - HTMLColors.LIST.subList(0, 10); - private static boolean b; - private static String s; - private static int i; - private static Iterator it; - private static ListIterator lit; - public static void basicTest(List a) { - a.add(1, "x"); // Add at location 1 - a.add("x"); // Add at end - // Add a collection: - a.addAll(LIST); - // Add a collection starting at location 3: - a.addAll(3, LIST); - b = a.contains("1"); // Is it in there? - // Is the entire collection in there? - b = a.containsAll(LIST); - // Lists allow random access, which is cheap - // for ArrayList, expensive for LinkedList: - s = a.get(1); // Get (typed) object at location 1 - i = a.indexOf("1"); // Tell index of object - b = a.isEmpty(); // Any elements inside? - it = a.iterator(); // Ordinary Iterator - lit = a.listIterator(); // ListIterator - lit = a.listIterator(3); // Start at location 3 - i = a.lastIndexOf("1"); // Last match - a.remove(1); // Remove location 1 - a.remove("3"); // Remove this object - a.set(1, "y"); // Set location 1 to "y" - // Keep everything that's in the argument - // (the intersection of the two sets): - a.retainAll(LIST); - // Remove everything that's in the argument: - a.removeAll(LIST); - i = a.size(); // How big is it? - a.clear(); // Remove all elements - } - public static void iterMotion(List a) { - ListIterator it = a.listIterator(); - b = it.hasNext(); - b = it.hasPrevious(); - s = it.next(); - i = it.nextIndex(); - s = it.previous(); - i = it.previousIndex(); - } - public static void iterManipulation(List a) { - ListIterator it = a.listIterator(); - it.add("47"); - // Must move to an element after add(): - it.next(); - // Remove the element after the new one: - it.remove(); - // Must move to an element after remove(): - it.next(); - // Change the element after the deleted one: - it.set("47"); - } - public static void testVisual(List a) { - System.out.println(a); - List b = LIST; - System.out.println("b = " + b); - a.addAll(b); - a.addAll(b); - System.out.println(a); - // Insert, remove, and replace elements - // using a ListIterator: - ListIterator x = - a.listIterator(a.size()/2); - x.add("one"); - System.out.println(a); - System.out.println(x.next()); - x.remove(); - System.out.println(x.next()); - x.set("47"); - System.out.println(a); - // Traverse the list backwards: - x = a.listIterator(a.size()); - while(x.hasPrevious()) - System.out.print(x.previous() + " "); - System.out.println(); - System.out.println("testVisual finished"); - } - // There are some things that only LinkedLists can do: - public static void testLinkedList() { - LinkedList ll = new LinkedList<>(); - ll.addAll(LIST); - System.out.println(ll); - // Treat it like a stack, pushing: - ll.addFirst("one"); - ll.addFirst("two"); - System.out.println(ll); - // Like "peeking" at the top of a stack: - System.out.println(ll.getFirst()); - // Like popping a stack: - System.out.println(ll.removeFirst()); - System.out.println(ll.removeFirst()); - // Treat it like a queue, pulling elements - // off the tail end: - System.out.println(ll.removeLast()); - System.out.println(ll); - } - public static void main(String[] args) { - // Make and fill a new list each time: - basicTest(new LinkedList<>(LIST)); - basicTest(new ArrayList<>(LIST)); - iterMotion(new LinkedList<>(LIST)); - iterMotion(new ArrayList<>(LIST)); - iterManipulation(new LinkedList<>(LIST)); - iterManipulation(new ArrayList<>(LIST)); - testVisual(new LinkedList<>(LIST)); - testLinkedList(); - } -} -/* Output: -[AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, -Bisque, Black, BlanchedAlmond, Blue, BlueViolet] -b = [AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, -Bisque, Black, BlanchedAlmond, Blue, BlueViolet] -[AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, -Bisque, Black, BlanchedAlmond, Blue, BlueViolet, -AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, -Bisque, Black, BlanchedAlmond, Blue, BlueViolet, -AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, -Bisque, Black, BlanchedAlmond, Blue, BlueViolet] -[AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, -Bisque, Black, BlanchedAlmond, Blue, BlueViolet, -AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, one, -Bisque, Black, BlanchedAlmond, Blue, BlueViolet, -AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, -Bisque, Black, BlanchedAlmond, Blue, BlueViolet] -Bisque -Black -[AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, -Bisque, Black, BlanchedAlmond, Blue, BlueViolet, -AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, one, -47, BlanchedAlmond, Blue, BlueViolet, AliceBlue, -AntiqueWhite, Aquamarine, Azure, Beige, Bisque, Black, -BlanchedAlmond, Blue, BlueViolet] -BlueViolet Blue BlanchedAlmond Black Bisque Beige Azure -Aquamarine AntiqueWhite AliceBlue BlueViolet Blue -BlanchedAlmond 47 one Beige Azure Aquamarine -AntiqueWhite AliceBlue BlueViolet Blue BlanchedAlmond -Black Bisque Beige Azure Aquamarine AntiqueWhite -AliceBlue -testVisual finished -[AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, -Bisque, Black, BlanchedAlmond, Blue, BlueViolet] -[two, one, AliceBlue, AntiqueWhite, Aquamarine, Azure, -Beige, Bisque, Black, BlanchedAlmond, Blue, BlueViolet] -two -two -one -BlueViolet -[AliceBlue, AntiqueWhite, Aquamarine, Azure, Beige, -Bisque, Black, BlanchedAlmond, Blue] -*/ diff --git a/code/collectiontopics/ListSortSearch.java b/code/collectiontopics/ListSortSearch.java deleted file mode 100644 index 4d1fbcf8..00000000 --- a/code/collectiontopics/ListSortSearch.java +++ /dev/null @@ -1,57 +0,0 @@ -// collectiontopics/ListSortSearch.java -// (c)2020 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. -// Sorting/searching Lists with Collections utilities -import java.util.*; - -public class ListSortSearch { - public static void main(String[] args) { - List list = - new ArrayList<>(Utilities.list); - list.addAll(Utilities.list); - System.out.println(list); - Collections.shuffle(list, new Random(47)); - System.out.println("Shuffled: " + list); - // Use ListIterator to trim off last elements: - ListIterator it = list.listIterator(10); - while(it.hasNext()) { - it.next(); - it.remove(); - } - System.out.println("Trimmed: " + list); - Collections.sort(list); - System.out.println("Sorted: " + list); - String key = list.get(7); - int index = Collections.binarySearch(list, key); - System.out.println( - "Location of " + key + " is " + index + - ", list.get(" + index + ") = " + - list.get(index)); - Collections.sort(list, - String.CASE_INSENSITIVE_ORDER); - System.out.println( - "Case-insensitive sorted: " + list); - key = list.get(7); - index = Collections.binarySearch(list, key, - String.CASE_INSENSITIVE_ORDER); - System.out.println( - "Location of " + key + " is " + index + - ", list.get(" + index + ") = " + - list.get(index)); - } -} -/* Output: -[one, Two, three, Four, five, six, one, one, Two, -three, Four, five, six, one] -Shuffled: [Four, five, one, one, Two, six, six, three, -three, five, Four, Two, one, one] -Trimmed: [Four, five, one, one, Two, six, six, three, -three, five] -Sorted: [Four, Two, five, five, one, one, six, six, -three, three] -Location of six is 7, list.get(7) = six -Case-insensitive sorted: [five, five, Four, one, one, -six, six, three, three, Two] -Location of three is 7, list.get(7) = three -*/ diff --git a/code/collectiontopics/MapOps.java b/code/collectiontopics/MapOps.java deleted file mode 100644 index b214fa2d..00000000 --- a/code/collectiontopics/MapOps.java +++ /dev/null @@ -1,76 +0,0 @@ -// collectiontopics/MapOps.java -// (c)2020 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. -// Things you can do with Maps -import java.util.concurrent.*; -import java.util.*; -import onjava.*; - -public class MapOps { - public static - void printKeys(Map map) { - System.out.print("Size = " + map.size() + ", "); - System.out.print("Keys: "); - // Produce a Set of the keys: - System.out.println(map.keySet()); - } - public static - void test(Map map) { - System.out.println( - map.getClass().getSimpleName()); - map.putAll(new CountMap(25)); - // Map has 'Set' behavior for keys: - map.putAll(new CountMap(25)); - printKeys(map); - // Producing a Collection of the values: - System.out.print("Values: "); - System.out.println(map.values()); - System.out.println(map); - System.out.println("map.containsKey(11): " + - map.containsKey(11)); - System.out.println( - "map.get(11): " + map.get(11)); - System.out.println("map.containsValue(\"F0\"): " - + map.containsValue("F0")); - Integer key = map.keySet().iterator().next(); - System.out.println("First key in map: " + key); - map.remove(key); - printKeys(map); - map.clear(); - System.out.println( - "map.isEmpty(): " + map.isEmpty()); - map.putAll(new CountMap(25)); - // Operations on the Set change the Map: - map.keySet().removeAll(map.keySet()); - System.out.println( - "map.isEmpty(): " + map.isEmpty()); - } - public static void main(String[] args) { - test(new HashMap<>()); - test(new TreeMap<>()); - test(new LinkedHashMap<>()); - test(new IdentityHashMap<>()); - test(new ConcurrentHashMap<>()); - test(new WeakHashMap<>()); - } -} -/* Output: (First 11 Lines) -HashMap -Size = 25, Keys: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] -Values: [A0, B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, -L0, M0, N0, O0, P0, Q0, R0, S0, T0, U0, V0, W0, X0, Y0] -{0=A0, 1=B0, 2=C0, 3=D0, 4=E0, 5=F0, 6=G0, 7=H0, 8=I0, -9=J0, 10=K0, 11=L0, 12=M0, 13=N0, 14=O0, 15=P0, 16=Q0, -17=R0, 18=S0, 19=T0, 20=U0, 21=V0, 22=W0, 23=X0, 24=Y0} -map.containsKey(11): true -map.get(11): L0 -map.containsValue("F0"): true -First key in map: 0 -Size = 24, Keys: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] -map.isEmpty(): true -map.isEmpty(): true - ... -*/ diff --git a/code/collectiontopics/NavMap.java b/code/collectiontopics/NavMap.java deleted file mode 100644 index 076ae841..00000000 --- a/code/collectiontopics/NavMap.java +++ /dev/null @@ -1,96 +0,0 @@ -// collectiontopics/NavMap.java -// (c)2020 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. -// NavigableMap produces pieces of a Map -import java.util.*; -import java.util.concurrent.*; -import static onjava.HTMLColors.*; - -public class NavMap { - public static final - NavigableMap COLORS = - new ConcurrentSkipListMap<>(MAP); - public static void main(String[] args) { - show(COLORS.firstEntry()); - border(); - show(COLORS.lastEntry()); - border(); - NavigableMap toLime = - COLORS.headMap(rgb("Lime"), true); - show(toLime); - border(); - show(COLORS.ceilingEntry(rgb("DeepSkyBlue") - 1)); - border(); - show(COLORS.floorEntry(rgb("DeepSkyBlue") - 1)); - border(); - show(toLime.descendingMap()); - border(); - show(COLORS.tailMap(rgb("MistyRose"), true)); - border(); - show(COLORS.subMap( - rgb("Orchid"), true, - rgb("DarkSalmon"), false)); - } -} -/* Output: -0x000000: Black -****************************** -0xFFFFFF: White -****************************** -0x000000: Black -0x000080: Navy -0x00008B: DarkBlue -0x0000CD: MediumBlue -0x0000FF: Blue -0x006400: DarkGreen -0x008000: Green -0x008080: Teal -0x008B8B: DarkCyan -0x00BFFF: DeepSkyBlue -0x00CED1: DarkTurquoise -0x00FA9A: MediumSpringGreen -0x00FF00: Lime -****************************** -0x00BFFF: DeepSkyBlue -****************************** -0x008B8B: DarkCyan -****************************** -0x00FF00: Lime -0x00FA9A: MediumSpringGreen -0x00CED1: DarkTurquoise -0x00BFFF: DeepSkyBlue -0x008B8B: DarkCyan -0x008080: Teal -0x008000: Green -0x006400: DarkGreen -0x0000FF: Blue -0x0000CD: MediumBlue -0x00008B: DarkBlue -0x000080: Navy -0x000000: Black -****************************** -0xFFE4E1: MistyRose -0xFFEBCD: BlanchedAlmond -0xFFEFD5: PapayaWhip -0xFFF0F5: LavenderBlush -0xFFF5EE: SeaShell -0xFFF8DC: Cornsilk -0xFFFACD: LemonChiffon -0xFFFAF0: FloralWhite -0xFFFAFA: Snow -0xFFFF00: Yellow -0xFFFFE0: LightYellow -0xFFFFF0: Ivory -0xFFFFFF: White -****************************** -0xDA70D6: Orchid -0xDAA520: GoldenRod -0xDB7093: PaleVioletRed -0xDC143C: Crimson -0xDCDCDC: Gainsboro -0xDDA0DD: Plum -0xDEB887: BurlyWood -0xE0FFFF: LightCyan -0xE6E6FA: Lavender -*/ diff --git a/code/collectiontopics/QueueBehavior.java b/code/collectiontopics/QueueBehavior.java deleted file mode 100644 index 136fbaf8..00000000 --- a/code/collectiontopics/QueueBehavior.java +++ /dev/null @@ -1,50 +0,0 @@ -// collectiontopics/QueueBehavior.java -// (c)2020 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 basic behavior -import java.util.*; -import java.util.stream.*; -import java.util.concurrent.*; - -public class QueueBehavior { - 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(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: -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/code/collectiontopics/ReadOnly.java b/code/collectiontopics/ReadOnly.java deleted file mode 100644 index 93c336c4..00000000 --- a/code/collectiontopics/ReadOnly.java +++ /dev/null @@ -1,56 +0,0 @@ -// collectiontopics/ReadOnly.java -// (c)2020 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. -// Using the Collections.unmodifiable methods -import java.util.*; -import onjava.*; - -public class ReadOnly { - static Collection data = - new ArrayList<>(Countries.names(6)); - public static void main(String[] args) { - Collection c = - Collections.unmodifiableCollection( - new ArrayList<>(data)); - System.out.println(c); // Reading is OK - //- c.add("one"); // Can't change it - - List a = Collections.unmodifiableList( - new ArrayList<>(data)); - ListIterator lit = a.listIterator(); - System.out.println(lit.next()); // Reading is OK - //- lit.add("one"); // Can't change it - - Set s = Collections.unmodifiableSet( - new HashSet<>(data)); - System.out.println(s); // Reading is OK - //- s.add("one"); // Can't change it - - // For a SortedSet: - Set ss = - Collections.unmodifiableSortedSet( - new TreeSet<>(data)); - - Map m = - Collections.unmodifiableMap( - new HashMap<>(Countries.capitals(6))); - System.out.println(m); // Reading is OK - //- m.put("Ralph", "Howdy!"); - - // For a SortedMap: - Map sm = - Collections.unmodifiableSortedMap( - new TreeMap<>(Countries.capitals(6))); - } -} -/* Output: -[ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, -BURUNDI] -ALGERIA -[BENIN, BOTSWANA, ANGOLA, BURKINA FASO, ALGERIA, -BURUNDI] -{BENIN=Porto-Novo, BOTSWANA=Gaberone, ANGOLA=Luanda, -BURKINA FASO=Ouagadougou, ALGERIA=Algiers, -BURUNDI=Bujumbura} -*/ diff --git a/code/collectiontopics/References.java b/code/collectiontopics/References.java deleted file mode 100644 index 5fcca940..00000000 --- a/code/collectiontopics/References.java +++ /dev/null @@ -1,92 +0,0 @@ -// collectiontopics/References.java -// (c)2020 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. -// Demonstrates Reference objects -import java.lang.ref.*; -import java.util.*; - -class VeryBig { - private static final int SIZE = 10000; - private long[] la = new long[SIZE]; - private String ident; - VeryBig(String id) { ident = id; } - @Override - public String toString() { return ident; } - @SuppressWarnings("deprecation") - @Override - protected void finalize() { - System.out.println("Finalizing " + ident); - } -} - -public class References { - private static ReferenceQueue rq = - new ReferenceQueue<>(); - public static void checkQueue() { - Reference inq = rq.poll(); - if(inq != null) - System.out.println("In queue: " + inq.get()); - } - public static void main(String[] args) { - int size = 10; - // Or, choose size via the command line: - if(args.length > 0) - size = Integer.valueOf(args[0]); - LinkedList> sa = - new LinkedList<>(); - for(int i = 0; i < size; i++) { - sa.add(new SoftReference<>( - new VeryBig("Soft " + i), rq)); - System.out.println( - "Just created: " + sa.getLast()); - checkQueue(); - } - LinkedList> wa = - new LinkedList<>(); - for(int i = 0; i < size; i++) { - wa.add(new WeakReference<>( - new VeryBig("Weak " + i), rq)); - System.out.println( - "Just created: " + wa.getLast()); - checkQueue(); - } - SoftReference s = - new SoftReference<>(new VeryBig("Soft")); - WeakReference w = - new WeakReference<>(new VeryBig("Weak")); - System.gc(); - LinkedList> pa = - new LinkedList<>(); - for(int i = 0; i < size; i++) { - pa.add(new PhantomReference<>( - new VeryBig("Phantom " + i), rq)); - System.out.println( - "Just created: " + pa.getLast()); - checkQueue(); - } - } -} -/* Output: (First and Last 10 Lines) -Just created: java.lang.ref.SoftReference@15db9742 -Just created: java.lang.ref.SoftReference@6d06d69c -Just created: java.lang.ref.SoftReference@7852e922 -Just created: java.lang.ref.SoftReference@4e25154f -Just created: java.lang.ref.SoftReference@70dea4e -Just created: java.lang.ref.SoftReference@5c647e05 -Just created: java.lang.ref.SoftReference@33909752 -Just created: java.lang.ref.SoftReference@55f96302 -Just created: java.lang.ref.SoftReference@3d4eac69 -Just created: java.lang.ref.SoftReference@42a57993 -...________...________...________...________... -Just created: java.lang.ref.PhantomReference@45ee12a7 -In queue: null -Just created: java.lang.ref.PhantomReference@330bedb4 -In queue: null -Just created: java.lang.ref.PhantomReference@2503dbd3 -In queue: null -Just created: java.lang.ref.PhantomReference@4b67cf4d -In queue: null -Just created: java.lang.ref.PhantomReference@7ea987ac -In queue: null -*/ diff --git a/code/collectiontopics/SetOrder.java b/code/collectiontopics/SetOrder.java deleted file mode 100644 index 1c25be23..00000000 --- a/code/collectiontopics/SetOrder.java +++ /dev/null @@ -1,92 +0,0 @@ -// collectiontopics/SetOrder.java -// (c)2020 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. -import java.util.*; -import onjava.HTMLColors; - -public class SetOrder { - static String[] sets = { - "java.util.HashSet", - "java.util.TreeSet", - "java.util.concurrent.ConcurrentSkipListSet", - "java.util.LinkedHashSet", - "java.util.concurrent.CopyOnWriteArraySet", - }; - static final List RLIST = - new ArrayList<>(HTMLColors.LIST); - static { - Collections.reverse(RLIST); - } - public static void - main(String[] args) throws Exception { - for(String type: sets) { - System.out.format("[-> %s <-]%n", - type.substring(type.lastIndexOf('.') + 1)); - @SuppressWarnings({"unchecked", "deprecation"}) - Set set = (Set) - Class.forName(type).newInstance(); - set.addAll(RLIST); - set.stream() - .limit(10) - .forEach(System.out::println); - } - } -} -/* Output: -[-> HashSet <-] -MediumOrchid -PaleGoldenRod -Sienna -LightSlateGray -DarkSeaGreen -Black -Gainsboro -Orange -LightCoral -DodgerBlue -[-> TreeSet <-] -AliceBlue -AntiqueWhite -Aquamarine -Azure -Beige -Bisque -Black -BlanchedAlmond -Blue -BlueViolet -[-> ConcurrentSkipListSet <-] -AliceBlue -AntiqueWhite -Aquamarine -Azure -Beige -Bisque -Black -BlanchedAlmond -Blue -BlueViolet -[-> LinkedHashSet <-] -YellowGreen -Yellow -WhiteSmoke -White -Wheat -Violet -Turquoise -Tomato -Thistle -Teal -[-> CopyOnWriteArraySet <-] -YellowGreen -Yellow -WhiteSmoke -White -Wheat -Violet -Turquoise -Tomato -Thistle -Teal -*/ diff --git a/code/collectiontopics/SimpleDeques.java b/code/collectiontopics/SimpleDeques.java deleted file mode 100644 index fbb4a5ff..00000000 --- a/code/collectiontopics/SimpleDeques.java +++ /dev/null @@ -1,70 +0,0 @@ -// collectiontopics/SimpleDeques.java -// (c)2020 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. -// Very basic test of Deques -import java.util.*; -import java.util.concurrent.*; -import java.util.function.*; - -class CountString implements Supplier { - private int n = 0; - CountString() {} - CountString(int start) { n = start; } - @Override - public String get() { - return Integer.toString(n++); - } -} - -public class SimpleDeques { - static void test(Deque deque) { - CountString s1 = new CountString(), - s2 = new CountString(20); - for(int n = 0; n < 8; n++) { - deque.offerFirst(s1.get()); - deque.offerLast(s2.get()); // Same as offer() - } - System.out.println(deque); - String result = ""; - while(deque.size() > 0) { - System.out.print(deque.peekFirst() + " "); - result += deque.pollFirst() + " "; - System.out.print(deque.peekLast() + " "); - result += deque.pollLast() + " "; - } - System.out.println("\n" + result); - } - public static void main(String[] args) { - int count = 10; - System.out.println("LinkedList"); - test(new LinkedList<>()); - System.out.println("ArrayDeque"); - test(new ArrayDeque<>()); - System.out.println("LinkedBlockingDeque"); - test(new LinkedBlockingDeque<>(count)); - System.out.println("ConcurrentLinkedDeque"); - test(new ConcurrentLinkedDeque<>()); - } -} -/* Output: -LinkedList -[7, 6, 5, 4, 3, 2, 1, 0, 20, 21, 22, 23, 24, 25, 26, -27] -7 27 6 26 5 25 4 24 3 23 2 22 1 21 0 20 -7 27 6 26 5 25 4 24 3 23 2 22 1 21 0 20 -ArrayDeque -[7, 6, 5, 4, 3, 2, 1, 0, 20, 21, 22, 23, 24, 25, 26, -27] -7 27 6 26 5 25 4 24 3 23 2 22 1 21 0 20 -7 27 6 26 5 25 4 24 3 23 2 22 1 21 0 20 -LinkedBlockingDeque -[4, 3, 2, 1, 0, 20, 21, 22, 23, 24] -4 24 3 23 2 22 1 21 0 20 -4 24 3 23 2 22 1 21 0 20 -ConcurrentLinkedDeque -[7, 6, 5, 4, 3, 2, 1, 0, 20, 21, 22, 23, 24, 25, 26, -27] -7 27 6 26 5 25 4 24 3 23 2 22 1 21 0 20 -7 27 6 26 5 25 4 24 3 23 2 22 1 21 0 20 -*/ diff --git a/code/collectiontopics/SortedMapDemo.java b/code/collectiontopics/SortedMapDemo.java deleted file mode 100644 index 4d57d34a..00000000 --- a/code/collectiontopics/SortedMapDemo.java +++ /dev/null @@ -1,42 +0,0 @@ -// collectiontopics/SortedMapDemo.java -// (c)2020 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 TreeMap -import java.util.*; -import onjava.*; - -public class SortedMapDemo { - public static void main(String[] args) { - TreeMap sortedMap = - new TreeMap<>(new CountMap(10)); - System.out.println(sortedMap); - Integer low = sortedMap.firstKey(); - Integer high = sortedMap.lastKey(); - System.out.println(low); - System.out.println(high); - Iterator it = - sortedMap.keySet().iterator(); - for(int i = 0; i <= 6; i++) { - if(i == 3) low = it.next(); - if(i == 6) high = it.next(); - else it.next(); - } - System.out.println(low); - System.out.println(high); - System.out.println(sortedMap.subMap(low, high)); - System.out.println(sortedMap.headMap(high)); - System.out.println(sortedMap.tailMap(low)); - } -} -/* Output: -{0=A0, 1=B0, 2=C0, 3=D0, 4=E0, 5=F0, 6=G0, 7=H0, 8=I0, -9=J0} -0 -9 -3 -7 -{3=D0, 4=E0, 5=F0, 6=G0} -{0=A0, 1=B0, 2=C0, 3=D0, 4=E0, 5=F0, 6=G0} -{3=D0, 4=E0, 5=F0, 6=G0, 7=H0, 8=I0, 9=J0} -*/ diff --git a/code/collectiontopics/SortedSetDemo.java b/code/collectiontopics/SortedSetDemo.java deleted file mode 100644 index 6ed81fb1..00000000 --- a/code/collectiontopics/SortedSetDemo.java +++ /dev/null @@ -1,42 +0,0 @@ -// collectiontopics/SortedSetDemo.java -// (c)2020 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. -import java.util.*; -import static java.util.stream.Collectors.*; - -public class SortedSetDemo { - public static void main(String[] args) { - 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(); - System.out.println(low); - System.out.println(high); - Iterator it = sortedSet.iterator(); - for(int i = 0; i <= 6; i++) { - if(i == 3) low = it.next(); - if(i == 6) high = it.next(); - else it.next(); - } - System.out.println(low); - System.out.println(high); - System.out.println(sortedSet.subSet(low, high)); - System.out.println(sortedSet.headSet(high)); - System.out.println(sortedSet.tailSet(low)); - } -} -/* Output: -[eight, five, four, one, seven, six, three, two] -eight -two -one -two -[one, seven, six, three] -[eight, five, four, one, seven, six, three] -[one, seven, six, three, two] -*/ diff --git a/code/collectiontopics/Stacks.java b/code/collectiontopics/Stacks.java deleted file mode 100644 index 79a684cb..00000000 --- a/code/collectiontopics/Stacks.java +++ /dev/null @@ -1,61 +0,0 @@ -// collectiontopics/Stacks.java -// (c)2020 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. -// Demonstration of Stack Class -import java.util.*; - -enum Month { JANUARY, FEBRUARY, MARCH, APRIL, - MAY, JUNE, JULY, AUGUST, SEPTEMBER, - OCTOBER, NOVEMBER } - -public class Stacks { - public static void main(String[] args) { - Stack stack = new Stack<>(); - for(Month m : Month.values()) - stack.push(m.toString()); - System.out.println("stack = " + stack); - // Treating a stack as a Vector: - stack.addElement("The last line"); - System.out.println( - "element 5 = " + stack.elementAt(5)); - System.out.println("popping elements:"); - while(!stack.empty()) - System.out.print(stack.pop() + " "); - - // Using a LinkedList as a Stack: - LinkedList lstack = new LinkedList<>(); - for(Month m : Month.values()) - lstack.addFirst(m.toString()); - System.out.println("lstack = " + lstack); - while(!lstack.isEmpty()) - System.out.print(lstack.removeFirst() + " "); - - // Using the Stack class from - // the Collections Chapter: - onjava.Stack stack2 = - new onjava.Stack<>(); - for(Month m : Month.values()) - stack2.push(m.toString()); - System.out.println("stack2 = " + stack2); - while(!stack2.isEmpty()) - System.out.print(stack2.pop() + " "); - - } -} -/* Output: -stack = [JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, -JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER] -element 5 = JUNE -popping elements: -The last line NOVEMBER OCTOBER SEPTEMBER AUGUST JULY -JUNE MAY APRIL MARCH FEBRUARY JANUARY lstack = -[NOVEMBER, OCTOBER, SEPTEMBER, AUGUST, JULY, JUNE, MAY, -APRIL, MARCH, FEBRUARY, JANUARY] -NOVEMBER OCTOBER SEPTEMBER AUGUST JULY JUNE MAY APRIL -MARCH FEBRUARY JANUARY stack2 = [NOVEMBER, OCTOBER, -SEPTEMBER, AUGUST, JULY, JUNE, MAY, APRIL, MARCH, -FEBRUARY, JANUARY] -NOVEMBER OCTOBER SEPTEMBER AUGUST JULY JUNE MAY APRIL -MARCH FEBRUARY JANUARY -*/ diff --git a/code/collectiontopics/StreamFillMaps.java b/code/collectiontopics/StreamFillMaps.java deleted file mode 100644 index 816a74b3..00000000 --- a/code/collectiontopics/StreamFillMaps.java +++ /dev/null @@ -1,55 +0,0 @@ -// collectiontopics/StreamFillMaps.java -// (c)2020 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. -import java.util.*; -import java.util.function.*; -import java.util.stream.*; -import onjava.*; - -class Letters -implements Supplier> { - private int number = 1; - private char letter = 'A'; - @Override - public Pair get() { - return new Pair<>(number++, "" + letter++); - } -} - -public class StreamFillMaps { - public static void main(String[] args) { - Map m = - Stream.generate(new Letters()) - .limit(11) - .collect(Collectors - .toMap(Pair::key, Pair::value)); - System.out.println(m); - - // Two separate Suppliers: - Rand.String rs = new Rand.String(3); - Count.Character cc = new Count.Character(); - Map mcs = Stream.generate( - () -> Pair.make(cc.get(), rs.get())) - .limit(8) - .collect(Collectors - .toMap(Pair::key, Pair::value)); - System.out.println(mcs); - - // A key Supplier and a single value: - Map mcs2 = Stream.generate( - () -> Pair.make(cc.get(), "Val")) - .limit(8) - .collect(Collectors - .toMap(Pair::key, Pair::value)); - System.out.println(mcs2); - } -} -/* Output: -{1=A, 2=B, 3=C, 4=D, 5=E, 6=F, 7=G, 8=H, 9=I, 10=J, -11=K} -{b=btp, c=enp, d=ccu, e=xsz, f=gvg, g=mei, h=nne, -i=elo} -{p=Val, q=Val, j=Val, k=Val, l=Val, m=Val, n=Val, -o=Val} -*/ diff --git a/code/collectiontopics/SuppliersCollectionTest.java b/code/collectiontopics/SuppliersCollectionTest.java deleted file mode 100644 index b30f1490..00000000 --- a/code/collectiontopics/SuppliersCollectionTest.java +++ /dev/null @@ -1,67 +0,0 @@ -// collectiontopics/SuppliersCollectionTest.java -// (c)2020 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. -import java.util.*; -import java.util.function.*; -import java.util.stream.*; -import onjava.*; - -class Government implements Supplier { - static String[] foundation = ( - "strange women lying in ponds " + - "distributing swords is no basis " + - "for a system of government").split(" "); - private int index; - @Override - public String get() { - return foundation[index++]; - } -} - -public class SuppliersCollectionTest { - public static void main(String[] args) { - // Suppliers class from the Generics chapter: - Set set = Suppliers.create( - LinkedHashSet::new, new Government(), 15); - System.out.println(set); - List list = Suppliers.create( - LinkedList::new, new Government(), 15); - System.out.println(list); - list = new ArrayList<>(); - Suppliers.fill(list, new Government(), 15); - System.out.println(list); - - // Or we can use Streams: - set = Arrays.stream(Government.foundation) - .collect(Collectors.toSet()); - System.out.println(set); - list = Arrays.stream(Government.foundation) - .collect(Collectors.toList()); - System.out.println(list); - list = Arrays.stream(Government.foundation) - .collect(Collectors - .toCollection(LinkedList::new)); - System.out.println(list); - set = Arrays.stream(Government.foundation) - .collect(Collectors - .toCollection(LinkedHashSet::new)); - System.out.println(set); - } -} -/* Output: -[strange, women, lying, in, ponds, distributing, -swords, is, no, basis, for, a, system, of, government] -[strange, women, lying, in, ponds, distributing, -swords, is, no, basis, for, a, system, of, government] -[strange, women, lying, in, ponds, distributing, -swords, is, no, basis, for, a, system, of, government] -[ponds, no, a, in, swords, for, is, basis, strange, -system, government, distributing, of, women, lying] -[strange, women, lying, in, ponds, distributing, -swords, is, no, basis, for, a, system, of, government] -[strange, women, lying, in, ponds, distributing, -swords, is, no, basis, for, a, system, of, government] -[strange, women, lying, in, ponds, distributing, -swords, is, no, basis, for, a, system, of, government] -*/ diff --git a/code/collectiontopics/Synchronization.java b/code/collectiontopics/Synchronization.java deleted file mode 100644 index c7d3b732..00000000 --- a/code/collectiontopics/Synchronization.java +++ /dev/null @@ -1,24 +0,0 @@ -// collectiontopics/Synchronization.java -// (c)2020 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. -// Using the Collections.synchronized methods -import java.util.*; - -public class Synchronization { - public static void main(String[] args) { - Collection c = - Collections.synchronizedCollection( - new ArrayList<>()); - List list = Collections - .synchronizedList(new ArrayList<>()); - Set s = Collections - .synchronizedSet(new HashSet<>()); - Set ss = Collections - .synchronizedSortedSet(new TreeSet<>()); - Map m = Collections - .synchronizedMap(new HashMap<>()); - Map sm = Collections - .synchronizedSortedMap(new TreeMap<>()); - } -} diff --git a/code/collectiontopics/ToDoList.java b/code/collectiontopics/ToDoList.java deleted file mode 100644 index b288e8e1..00000000 --- a/code/collectiontopics/ToDoList.java +++ /dev/null @@ -1,56 +0,0 @@ -// collectiontopics/ToDoList.java -// (c)2020 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. -// A more complex use of PriorityQueue -import java.util.*; - -class ToDoItem implements Comparable { - private char primary; - private int secondary; - private String item; - 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; - else if(secondary == arg.secondary) - return 0; - return -1; - } - @Override - public String toString() { - return Character.toString(primary) + - secondary + ": " + item; - } -} - -class ToDoList { - public static void main(String[] args) { - 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()); - } -} -/* Output: -A1: Water lawn -A2: Feed dog -B1: Feed cat -B7: Feed bird -C3: Mow lawn -C4: Empty trash -*/ diff --git a/code/collectiontopics/TypesForSets.java b/code/collectiontopics/TypesForSets.java deleted file mode 100644 index 9950b003..00000000 --- a/code/collectiontopics/TypesForSets.java +++ /dev/null @@ -1,93 +0,0 @@ -// collectiontopics/TypesForSets.java -// (c)2020 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. -// Methods necessary to put your own type in a Set -import java.util.*; -import java.util.function.*; -import java.util.Objects; - -class SetType { - protected int i; - SetType(int n) { i = n; } - @Override - public boolean equals(Object o) { - return o instanceof SetType && - Objects.equals(i, ((SetType)o).i); - } - @Override - public String toString() { - return Integer.toString(i); - } -} - -class HashType extends SetType { - HashType(int n) { super(n); } - @Override - public int hashCode() { - return Objects.hashCode(i); - } -} - -class TreeType extends SetType -implements Comparable { - TreeType(int n) { super(n); } - @Override - public int compareTo(TreeType arg) { - return Integer.compare(arg.i, i); - // Equivalent to: - // return arg.i < i ? -1 : (arg.i == i ? 0 : 1); - } -} - -public class TypesForSets { - static void - fill(Set set, Function type) { - 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) { - fill(set, type); - fill(set, type); // Try to add duplicates - fill(set, type); - System.out.println(set); - } - public static void main(String[] args) { - test(new HashSet<>(), HashType::new); - test(new LinkedHashSet<>(), HashType::new); - test(new TreeSet<>(), TreeType::new); - // Things that don't work: - test(new HashSet<>(), SetType::new); - test(new HashSet<>(), TreeType::new); - test(new LinkedHashSet<>(), SetType::new); - test(new LinkedHashSet<>(), TreeType::new); - try { - test(new TreeSet<>(), SetType::new); - } catch(Exception e) { - System.out.println(e.getMessage()); - } - try { - test(new TreeSet<>(), HashType::new); - } catch(Exception e) { - System.out.println(e.getMessage()); - } - } -} -/* Output: -[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/code/collectiontopics/Unsupported.java b/code/collectiontopics/Unsupported.java deleted file mode 100644 index a66b1cfd..00000000 --- a/code/collectiontopics/Unsupported.java +++ /dev/null @@ -1,60 +0,0 @@ -// collectiontopics/Unsupported.java -// (c)2020 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. -// Unsupported operations in Java collections -import java.util.*; - -public class Unsupported { - static void - check(String description, Runnable tst) { - try { - tst.run(); - } catch(Exception e) { - System.out.println(description + "(): " + e); - } - } - static void test(String msg, List list) { - System.out.println("--- " + msg + " ---"); - Collection c = list; - Collection subList = list.subList(1,8); - // Copy of the sublist: - Collection c2 = new ArrayList<>(subList); - check("retainAll", () -> c.retainAll(c2)); - check("removeAll", () -> c.removeAll(c2)); - check("clear", () -> c.clear()); - check("add", () -> c.add("X")); - check("addAll", () -> c.addAll(c2)); - check("remove", () -> c.remove("C")); - // The List.set() method modifies the value but - // doesn't change the size of the data structure: - check("List.set", () -> list.set(0, "X")); - } - public static void main(String[] args) { - List list = Arrays.asList( - "A B C D E F G H I J K L".split(" ")); - test("Modifiable Copy", new ArrayList<>(list)); - test("Arrays.asList()", list); - test("unmodifiableList()", - Collections.unmodifiableList( - new ArrayList<>(list))); - } -} -/* Output: ---- Modifiable Copy --- ---- Arrays.asList() --- -retainAll(): java.lang.UnsupportedOperationException -removeAll(): java.lang.UnsupportedOperationException -clear(): java.lang.UnsupportedOperationException -add(): java.lang.UnsupportedOperationException -addAll(): java.lang.UnsupportedOperationException -remove(): java.lang.UnsupportedOperationException ---- unmodifiableList() --- -retainAll(): java.lang.UnsupportedOperationException -removeAll(): java.lang.UnsupportedOperationException -clear(): java.lang.UnsupportedOperationException -add(): java.lang.UnsupportedOperationException -addAll(): java.lang.UnsupportedOperationException -remove(): java.lang.UnsupportedOperationException -List.set(): java.lang.UnsupportedOperationException -*/ diff --git a/code/collectiontopics/Utilities.java b/code/collectiontopics/Utilities.java deleted file mode 100644 index a2acc427..00000000 --- a/code/collectiontopics/Utilities.java +++ /dev/null @@ -1,88 +0,0 @@ -// collectiontopics/Utilities.java -// (c)2020 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. -// Simple demonstrations of the Collections utilities -import java.util.*; - -public class Utilities { - static List list = Arrays.asList( - "one Two three Four five six one".split(" ")); - public static void main(String[] args) { - System.out.println(list); - System.out.println("'list' disjoint (Four)?: " + - Collections.disjoint(list, - Collections.singletonList("Four"))); - System.out.println( - "max: " + Collections.max(list)); - System.out.println( - "min: " + Collections.min(list)); - System.out.println( - "max w/ comparator: " + Collections.max(list, - String.CASE_INSENSITIVE_ORDER)); - System.out.println( - "min w/ comparator: " + Collections.min(list, - String.CASE_INSENSITIVE_ORDER)); - List sublist = - Arrays.asList("Four five six".split(" ")); - System.out.println("indexOfSubList: " + - Collections.indexOfSubList(list, sublist)); - System.out.println("lastIndexOfSubList: " + - Collections.lastIndexOfSubList(list, sublist)); - Collections.replaceAll(list, "one", "Yo"); - System.out.println("replaceAll: " + list); - Collections.reverse(list); - System.out.println("reverse: " + list); - Collections.rotate(list, 3); - System.out.println("rotate: " + list); - List source = - Arrays.asList("in the matrix".split(" ")); - Collections.copy(list, source); - System.out.println("copy: " + list); - Collections.swap(list, 0, list.size() - 1); - System.out.println("swap: " + list); - Collections.shuffle(list, new Random(47)); - System.out.println("shuffled: " + list); - Collections.fill(list, "pop"); - System.out.println("fill: " + list); - System.out.println("frequency of 'pop': " + - Collections.frequency(list, "pop")); - List dups = - Collections.nCopies(3, "snap"); - System.out.println("dups: " + dups); - System.out.println("'list' disjoint 'dups'?: " + - Collections.disjoint(list, dups)); - // Getting an old-style Enumeration: - Enumeration e = - Collections.enumeration(dups); - Vector v = new Vector<>(); - while(e.hasMoreElements()) - v.addElement(e.nextElement()); - // Converting an old-style Vector - // to a List via an Enumeration: - ArrayList arrayList = - Collections.list(v.elements()); - System.out.println("arrayList: " + arrayList); - } -} -/* Output: -[one, Two, three, Four, five, six, one] -'list' disjoint (Four)?: false -max: three -min: Four -max w/ comparator: Two -min w/ comparator: five -indexOfSubList: 3 -lastIndexOfSubList: 3 -replaceAll: [Yo, Two, three, Four, five, six, Yo] -reverse: [Yo, six, five, Four, three, Two, Yo] -rotate: [three, Two, Yo, Yo, six, five, Four] -copy: [in, the, matrix, Yo, six, five, Four] -swap: [Four, the, matrix, Yo, six, five, in] -shuffled: [six, matrix, the, Four, Yo, five, in] -fill: [pop, pop, pop, pop, pop, pop, pop] -frequency of 'pop': 7 -dups: [snap, snap, snap] -'list' disjoint 'dups'?: true -arrayList: [snap, snap, snap] -*/ diff --git a/code/com/mindviewinc/simple/List.java b/code/com/mindviewinc/simple/List.java deleted file mode 100644 index 84b30315..00000000 --- a/code/com/mindviewinc/simple/List.java +++ /dev/null @@ -1,12 +0,0 @@ -// com/mindviewinc/simple/List.java -// (c)2020 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. -// Creating a package -package com.mindviewinc.simple; - -public class List { - public List() { - System.out.println("com.mindviewinc.simple.List"); - } -} diff --git a/code/com/mindviewinc/simple/Vector.java b/code/com/mindviewinc/simple/Vector.java deleted file mode 100644 index 19824cce..00000000 --- a/code/com/mindviewinc/simple/Vector.java +++ /dev/null @@ -1,12 +0,0 @@ -// com/mindviewinc/simple/Vector.java -// (c)2020 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. -// Creating a package -package com.mindviewinc.simple; - -public class Vector { - public Vector() { - System.out.println("com.mindviewinc.simple.Vector"); - } -} diff --git a/code/compression/GZIPcompress.java b/code/compression/GZIPcompress.java deleted file mode 100644 index c9022e78..00000000 --- a/code/compression/GZIPcompress.java +++ /dev/null @@ -1,45 +0,0 @@ -// compression/GZIPcompress.java -// (c)2020 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. -// {java GZIPcompress GZIPcompress.java} -// {VisuallyInspectOutput} -import java.util.zip.*; -import java.io.*; - -public class GZIPcompress { - public static void main(String[] args) { - if(args.length == 0) { - System.out.println( - "Usage: \nGZIPcompress file\n" + - "\tUses GZIP compression to compress " + - "the file to test.gz"); - System.exit(1); - } - try( - InputStream in = new BufferedInputStream( - new FileInputStream(args[0])); - BufferedOutputStream out = - new BufferedOutputStream( - new GZIPOutputStream( - new FileOutputStream("test.gz"))) - ) { - System.out.println("Writing file"); - int c; - while((c = in.read()) != -1) - out.write(c); - } catch(IOException e) { - throw new RuntimeException(e); - } - System.out.println("Reading file"); - try( - BufferedReader in2 = new BufferedReader( - new InputStreamReader(new GZIPInputStream( - new FileInputStream("test.gz")))) - ) { - in2.lines().forEach(System.out::println); - } catch(IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/code/compression/ZipCompress.java b/code/compression/ZipCompress.java deleted file mode 100644 index f9ce7670..00000000 --- a/code/compression/ZipCompress.java +++ /dev/null @@ -1,83 +0,0 @@ -// compression/ZipCompress.java -// (c)2020 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. -// Uses Zip compression to compress any -// number of files given on the command line -// {java ZipCompress ZipCompress.java} -// {VisuallyInspectOutput} -import java.util.zip.*; -import java.io.*; -import java.util.*; - -public class ZipCompress { - public static void main(String[] args) { - try( - FileOutputStream f = - new FileOutputStream("test.zip"); - CheckedOutputStream csum = - new CheckedOutputStream(f, new Adler32()); - ZipOutputStream zos = new ZipOutputStream(csum); - BufferedOutputStream out = - new BufferedOutputStream(zos) - ) { - zos.setComment("A test of Java Zipping"); - // No corresponding getComment(), though. - for(String arg : args) { - System.out.println("Writing file " + arg); - try( - InputStream in = new BufferedInputStream( - new FileInputStream(arg)) - ) { - zos.putNextEntry(new ZipEntry(arg)); - int c; - while((c = in.read()) != -1) - out.write(c); - } - out.flush(); - } - // Checksum valid only after the file is closed! - System.out.println( - "Checksum: " + csum.getChecksum().getValue()); - } catch(IOException e) { - throw new RuntimeException(e); - } - // Now extract the files: - System.out.println("Reading file"); - try( - FileInputStream fi = - new FileInputStream("test.zip"); - CheckedInputStream csumi = - new CheckedInputStream(fi, new Adler32()); - ZipInputStream in2 = new ZipInputStream(csumi); - BufferedInputStream bis = - new BufferedInputStream(in2) - ) { - ZipEntry ze; - while((ze = in2.getNextEntry()) != null) { - System.out.println("Reading file " + ze); - int x; - while((x = bis.read()) != -1) - System.out.write(x); - } - if(args.length == 1) - System.out.println( - "Checksum: "+csumi.getChecksum().getValue()); - } catch(IOException e) { - throw new RuntimeException(e); - } - // Alternative way to open and read Zip files: - try( - ZipFile zf = new ZipFile("test.zip") - ) { - Enumeration e = zf.entries(); - while(e.hasMoreElements()) { - ZipEntry ze2 = (ZipEntry)e.nextElement(); - System.out.println("File: " + ze2); - // ... and extract the data as before - } - } catch(IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/code/concurrent/Baked.java b/code/concurrent/Baked.java deleted file mode 100644 index d616d94b..00000000 --- a/code/concurrent/Baked.java +++ /dev/null @@ -1,31 +0,0 @@ -// concurrent/Baked.java -// (c)2020 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. -import java.util.concurrent.*; -import java.util.stream.*; -import onjava.Nap; - -public class Baked { - static class Pan {} - static Pan pan(Batter b) { - new Nap(0.1); - return new Pan(); - } - static Baked heat(Pan p) { - new Nap(0.1); - return new Baked(); - } - static CompletableFuture - bake(CompletableFuture cfb) { - return cfb - .thenApplyAsync(Baked::pan) - .thenApplyAsync(Baked::heat); - } - public static - Stream> batch() { - CompletableFuture batter = Batter.mix(); - return Stream.of(bake(batter), bake(batter), - bake(batter), bake(batter)); - } -} diff --git a/code/concurrent/Batter.java b/code/concurrent/Batter.java deleted file mode 100644 index 9fe14c4f..00000000 --- a/code/concurrent/Batter.java +++ /dev/null @@ -1,34 +0,0 @@ -// concurrent/Batter.java -// (c)2020 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. -import java.util.concurrent.*; -import onjava.Nap; - -public class Batter { - static class Eggs {} - static class Milk {} - static class Sugar {} - static class Flour {} - static T prepare(T ingredient) { - new Nap(0.1); - return ingredient; - } - static CompletableFuture prep(T ingredient) { - return CompletableFuture - .completedFuture(ingredient) - .thenApplyAsync(Batter::prepare); - } - public static CompletableFuture mix() { - CompletableFuture eggs = prep(new Eggs()); - CompletableFuture milk = prep(new Milk()); - CompletableFuture sugar = prep(new Sugar()); - CompletableFuture flour = prep(new Flour()); - CompletableFuture - .allOf(eggs, milk, sugar, flour) - .join(); - new Nap(0.1); // Mixing time - return - CompletableFuture.completedFuture(new Batter()); - } -} diff --git a/code/concurrent/Breakable.java b/code/concurrent/Breakable.java deleted file mode 100644 index facd7095..00000000 --- a/code/concurrent/Breakable.java +++ /dev/null @@ -1,29 +0,0 @@ -// concurrent/Breakable.java -// (c)2020 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. -import java.util.concurrent.*; - -public class Breakable { - String id; - private int failcount; - public Breakable(String id, int failcount) { - this.id = id; - this.failcount = failcount; - } - @Override - public String toString() { - return "Breakable_" + id + - " [" + failcount + "]"; - } - public static Breakable work(Breakable b) { - if(--b.failcount == 0) { - System.out.println( - "Throwing Exception for " + b.id + ""); - throw new RuntimeException( - "Breakable_" + b.id + " failed"); - } - System.out.println(b); - return b; - } -} diff --git a/code/concurrent/CachedThreadPool.java b/code/concurrent/CachedThreadPool.java deleted file mode 100644 index e0b825a2..00000000 --- a/code/concurrent/CachedThreadPool.java +++ /dev/null @@ -1,29 +0,0 @@ -// concurrent/CachedThreadPool.java -// (c)2020 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. -import java.util.concurrent.*; -import java.util.stream.*; - -public class CachedThreadPool { - public static void main(String[] args) { - ExecutorService exec = - Executors.newCachedThreadPool(); - IntStream.range(0, 10) - .mapToObj(NapTask::new) - .forEach(exec::execute); - exec.shutdown(); - } -} -/* Output: -NapTask[7] pool-1-thread-8 -NapTask[4] pool-1-thread-5 -NapTask[1] pool-1-thread-2 -NapTask[3] pool-1-thread-4 -NapTask[0] pool-1-thread-1 -NapTask[8] pool-1-thread-9 -NapTask[2] pool-1-thread-3 -NapTask[9] pool-1-thread-10 -NapTask[6] pool-1-thread-7 -NapTask[5] pool-1-thread-6 -*/ diff --git a/code/concurrent/CachedThreadPool2.java b/code/concurrent/CachedThreadPool2.java deleted file mode 100644 index 9d763656..00000000 --- a/code/concurrent/CachedThreadPool2.java +++ /dev/null @@ -1,29 +0,0 @@ -// concurrent/CachedThreadPool2.java -// (c)2020 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. -import java.util.concurrent.*; -import java.util.stream.*; - -public class CachedThreadPool2 { - public static void main(String[] args) { - ExecutorService exec = - Executors.newCachedThreadPool(); - IntStream.range(0, 10) - .mapToObj(InterferingTask::new) - .forEach(exec::execute); - exec.shutdown(); - } -} -/* Output: -0 pool-1-thread-1 200 -1 pool-1-thread-2 200 -4 pool-1-thread-5 300 -5 pool-1-thread-6 400 -8 pool-1-thread-9 500 -9 pool-1-thread-10 600 -2 pool-1-thread-3 700 -7 pool-1-thread-8 800 -3 pool-1-thread-4 900 -6 pool-1-thread-7 1000 -*/ diff --git a/code/concurrent/CachedThreadPool3.java b/code/concurrent/CachedThreadPool3.java deleted file mode 100644 index 4b6e6d2e..00000000 --- a/code/concurrent/CachedThreadPool3.java +++ /dev/null @@ -1,47 +0,0 @@ -// concurrent/CachedThreadPool3.java -// (c)2020 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. -import java.util.*; -import java.util.concurrent.*; -import java.util.stream.*; - -public class CachedThreadPool3 { - public static Integer - extractResult(Future f) { - try { - return f.get(); - } catch(Exception e) { - throw new RuntimeException(e); - } - } - public static void main(String[] args) - throws InterruptedException { - ExecutorService exec = - Executors.newCachedThreadPool(); - List tasks = - IntStream.range(0, 10) - .mapToObj(CountingTask::new) - .collect(Collectors.toList()); - List> futures = - exec.invokeAll(tasks); - Integer sum = futures.stream() - .map(CachedThreadPool3::extractResult) - .reduce(0, Integer::sum); - System.out.println("sum = " + sum); - exec.shutdown(); - } -} -/* Output: -1 pool-1-thread-2 100 -0 pool-1-thread-1 100 -4 pool-1-thread-5 100 -5 pool-1-thread-6 100 -8 pool-1-thread-9 100 -9 pool-1-thread-10 100 -2 pool-1-thread-3 100 -3 pool-1-thread-4 100 -6 pool-1-thread-7 100 -7 pool-1-thread-8 100 -sum = 1000 -*/ diff --git a/code/concurrent/CatchCompletableExceptions.java b/code/concurrent/CatchCompletableExceptions.java deleted file mode 100644 index 67451ed4..00000000 --- a/code/concurrent/CatchCompletableExceptions.java +++ /dev/null @@ -1,81 +0,0 @@ -// concurrent/CatchCompletableExceptions.java -// (c)2020 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. -import java.util.concurrent.*; - -public class CatchCompletableExceptions { - static void handleException(int failcount) { - // Call the Function only if there's an - // exception, must produce same type as came in: - CompletableExceptions - .test("exceptionally", failcount) - .exceptionally((ex) -> { // Function - if(ex == null) - System.out.println("I don't get it yet"); - return new Breakable(ex.getMessage(), 0); - }) - .thenAccept(str -> - System.out.println("result: " + str)); - - // Create a new result (recover): - CompletableExceptions - .test("handle", failcount) - .handle((result, fail) -> { // BiFunction - if(fail != null) - return "Failure recovery object"; - else - return result + " is good"; - }) - .thenAccept(str -> - System.out.println("result: " + str)); - - // Do something but pass the same result through: - CompletableExceptions - .test("whenComplete", failcount) - .whenComplete((result, fail) -> { // BiConsumer - if(fail != null) - System.out.println("It failed"); - else - System.out.println(result + " OK"); - }) - .thenAccept(r -> - System.out.println("result: " + r)); - } - public static void main(String[] args) { - System.out.println("**** Failure Mode ****"); - handleException(2); - System.out.println("**** Success Mode ****"); - handleException(0); - } -} -/* Output: -**** Failure Mode **** -Breakable_exceptionally [1] -Throwing Exception for exceptionally -result: Breakable_java.lang.RuntimeException: -Breakable_exceptionally failed [0] -Breakable_handle [1] -Throwing Exception for handle -result: Failure recovery object -Breakable_whenComplete [1] -Throwing Exception for whenComplete -It failed -**** Success Mode **** -Breakable_exceptionally [-1] -Breakable_exceptionally [-2] -Breakable_exceptionally [-3] -Breakable_exceptionally [-4] -result: Breakable_exceptionally [-4] -Breakable_handle [-1] -Breakable_handle [-2] -Breakable_handle [-3] -Breakable_handle [-4] -result: Breakable_handle [-4] is good -Breakable_whenComplete [-1] -Breakable_whenComplete [-2] -Breakable_whenComplete [-3] -Breakable_whenComplete [-4] -Breakable_whenComplete [-4] OK -result: Breakable_whenComplete [-4] -*/ diff --git a/code/concurrent/CollectionIntoStream.java b/code/concurrent/CollectionIntoStream.java deleted file mode 100644 index 2dc51a7e..00000000 --- a/code/concurrent/CollectionIntoStream.java +++ /dev/null @@ -1,36 +0,0 @@ -// concurrent/CollectionIntoStream.java -// (c)2020 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. -import onjava.*; -import java.util.*; -import java.util.stream.*; - -public class CollectionIntoStream { - public static void main(String[] args) { - List strings = - Stream.generate(new Rand.String(5)) - .limit(10) - .collect(Collectors.toList()); - strings.forEach(System.out::println); - // Convert to a Stream for many more options: - String result = strings.stream() - .map(String::toUpperCase) - .map(s -> s.substring(2)) - .reduce(":", (s1, s2) -> s1 + s2); - System.out.println(result); - } -} -/* Output: -btpen -pccux -szgvg -meinn -eeloz -tdvew -cippc -ygpoa -lkljl -bynxt -:PENCUXGVGINNLOZVEWPPCPOALJLNXT -*/ diff --git a/code/concurrent/CompletableApply.java b/code/concurrent/CompletableApply.java deleted file mode 100644 index 2f5bd9b4..00000000 --- a/code/concurrent/CompletableApply.java +++ /dev/null @@ -1,27 +0,0 @@ -// concurrent/CompletableApply.java -// (c)2020 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. -import java.util.concurrent.*; - -public class CompletableApply { - public static void main(String[] args) { - CompletableFuture cf = - CompletableFuture.completedFuture( - new Machina(0)); - CompletableFuture cf2 = - cf.thenApply(Machina::work); - CompletableFuture cf3 = - cf2.thenApply(Machina::work); - CompletableFuture cf4 = - cf3.thenApply(Machina::work); - CompletableFuture cf5 = - cf4.thenApply(Machina::work); - } -} -/* Output: -Machina0: ONE -Machina0: TWO -Machina0: THREE -Machina0: complete -*/ diff --git a/code/concurrent/CompletableApplyAsync.java b/code/concurrent/CompletableApplyAsync.java deleted file mode 100644 index fa7c9271..00000000 --- a/code/concurrent/CompletableApplyAsync.java +++ /dev/null @@ -1,31 +0,0 @@ -// concurrent/CompletableApplyAsync.java -// (c)2020 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. -import java.util.concurrent.*; -import onjava.*; - -public class CompletableApplyAsync { - public static void main(String[] args) { - Timer timer = new Timer(); - CompletableFuture cf = - CompletableFuture.completedFuture( - new Machina(0)) - .thenApplyAsync(Machina::work) - .thenApplyAsync(Machina::work) - .thenApplyAsync(Machina::work) - .thenApplyAsync(Machina::work); - System.out.println(timer.duration()); - System.out.println(cf.join()); - System.out.println(timer.duration()); - } -} -/* Output: -116 -Machina0: ONE -Machina0: TWO -Machina0: THREE -Machina0: complete -Machina0: complete -552 -*/ diff --git a/code/concurrent/CompletableApplyChained.java b/code/concurrent/CompletableApplyChained.java deleted file mode 100644 index aa6828d5..00000000 --- a/code/concurrent/CompletableApplyChained.java +++ /dev/null @@ -1,27 +0,0 @@ -// concurrent/CompletableApplyChained.java -// (c)2020 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. -import java.util.concurrent.*; -import onjava.Timer; - -public class CompletableApplyChained { - public static void main(String[] args) { - Timer timer = new Timer(); - CompletableFuture cf = - CompletableFuture.completedFuture( - new Machina(0)) - .thenApply(Machina::work) - .thenApply(Machina::work) - .thenApply(Machina::work) - .thenApply(Machina::work); - System.out.println(timer.duration()); - } -} -/* Output: -Machina0: ONE -Machina0: TWO -Machina0: THREE -Machina0: complete -514 -*/ diff --git a/code/concurrent/CompletableExceptions.java b/code/concurrent/CompletableExceptions.java deleted file mode 100644 index 624815d5..00000000 --- a/code/concurrent/CompletableExceptions.java +++ /dev/null @@ -1,75 +0,0 @@ -// concurrent/CompletableExceptions.java -// (c)2020 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. -import java.util.concurrent.*; - -public class CompletableExceptions { - static CompletableFuture - test(String id, int failcount) { - return - CompletableFuture.completedFuture( - new Breakable(id, failcount)) - .thenApply(Breakable::work) - .thenApply(Breakable::work) - .thenApply(Breakable::work) - .thenApply(Breakable::work); - } - public static void main(String[] args) { - // Exceptions don't appear ... - test("A", 1); - test("B", 2); - test("C", 3); - test("D", 4); - test("E", 5); - // ... until you try to fetch the value: - try { - test("F", 2).get(); // or join() - } catch(Exception e) { - System.out.println(e.getMessage()); - } - // Test for exceptions: - System.out.println( - test("G", 2).isCompletedExceptionally()); - // Counts as "done": - System.out.println(test("H", 2).isDone()); - // Force an exception: - CompletableFuture cfi = - new CompletableFuture<>(); - System.out.println("done? " + cfi.isDone()); - cfi.completeExceptionally( - new RuntimeException("forced")); - try { - cfi.get(); - } catch(Exception e) { - System.out.println(e.getMessage()); - } - } -} -/* Output: -Throwing Exception for A -Breakable_B [1] -Throwing Exception for B -Breakable_C [2] -Breakable_C [1] -Throwing Exception for C -Breakable_D [3] -Breakable_D [2] -Breakable_D [1] -Throwing Exception for D -Breakable_E [4] -Breakable_E [3] -Breakable_E [2] -Breakable_E [1] -Breakable_F [1] -Throwing Exception for F -java.lang.RuntimeException: Breakable_F failed -Breakable_G [1] -Throwing Exception for G -true -Breakable_H [1] -Throwing Exception for H -true -done? false -java.lang.RuntimeException: forced -*/ diff --git a/code/concurrent/CompletableOperations.java b/code/concurrent/CompletableOperations.java deleted file mode 100644 index d03e8422..00000000 --- a/code/concurrent/CompletableOperations.java +++ /dev/null @@ -1,74 +0,0 @@ -// concurrent/CompletableOperations.java -// (c)2020 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. -import java.util.concurrent.*; -import static onjava.CompletableUtilities.*; - -public class CompletableOperations { - static CompletableFuture cfi(int i) { - return - CompletableFuture.completedFuture( - Integer.valueOf(i)); - } - public static void main(String[] args) { - showr(cfi(1)); // Basic test - voidr(cfi(2).runAsync(() -> - System.out.println("runAsync"))); - voidr(cfi(3).thenRunAsync(() -> - System.out.println("thenRunAsync"))); - voidr(CompletableFuture.runAsync(() -> - System.out.println("runAsync is static"))); - showr(CompletableFuture.supplyAsync(() -> 99)); - voidr(cfi(4).thenAcceptAsync(i -> - System.out.println("thenAcceptAsync: " + i))); - showr(cfi(5).thenApplyAsync(i -> i + 42)); - showr(cfi(6).thenComposeAsync(i -> cfi(i + 99))); - CompletableFuture c = cfi(7); - c.obtrudeValue(111); - showr(c); - showr(cfi(8).toCompletableFuture()); - c = new CompletableFuture<>(); - c.complete(9); - showr(c); - c = new CompletableFuture<>(); - c.cancel(true); - System.out.println("cancelled: " + - c.isCancelled()); - System.out.println("completed exceptionally: " + - c.isCompletedExceptionally()); - System.out.println("done: " + c.isDone()); - System.out.println(c); - c = new CompletableFuture<>(); - System.out.println(c.getNow(777)); - c = new CompletableFuture<>(); - c.thenApplyAsync(i -> i + 42) - .thenApplyAsync(i -> i * 12); - System.out.println("dependents: " + - c.getNumberOfDependents()); - c.thenApplyAsync(i -> i / 2); - System.out.println("dependents: " + - c.getNumberOfDependents()); - } -} -/* Output: -1 -runAsync -thenRunAsync -runAsync is static -99 -thenAcceptAsync: 4 -47 -105 -111 -8 -9 -cancelled: true -completed exceptionally: true -done: true -java.util.concurrent.CompletableFuture@6d311334[Complet -ed exceptionally] -777 -dependents: 1 -dependents: 2 -*/ diff --git a/code/concurrent/CompletablePizza.java b/code/concurrent/CompletablePizza.java deleted file mode 100644 index 97b68545..00000000 --- a/code/concurrent/CompletablePizza.java +++ /dev/null @@ -1,87 +0,0 @@ -// concurrent/CompletablePizza.java -// (c)2020 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. -import java.util.*; -import java.util.concurrent.*; -import java.util.stream.*; -import onjava.Timer; - -public class CompletablePizza { - static final int QUANTITY = 5; - public static CompletableFuture - makeCF(Pizza za) { - return CompletableFuture - .completedFuture(za) - .thenApplyAsync(Pizza::roll) - .thenApplyAsync(Pizza::sauce) - .thenApplyAsync(Pizza::cheese) - .thenApplyAsync(Pizza::toppings) - .thenApplyAsync(Pizza::bake) - .thenApplyAsync(Pizza::slice) - .thenApplyAsync(Pizza::box); - } - public static void - show(CompletableFuture cf) { - try { - System.out.println(cf.get()); - } catch(Exception e) { - throw new RuntimeException(e); - } - } - public static void main(String[] args) { - Timer timer = new Timer(); - List> pizzas = - IntStream.range(0, QUANTITY) - .mapToObj(Pizza::new) - .map(CompletablePizza::makeCF) - .collect(Collectors.toList()); - System.out.println(timer.duration()); - pizzas.forEach(CompletablePizza::show); - System.out.println(timer.duration()); - } -} -/* Output: -169 -Pizza 0: ROLLED -Pizza 1: ROLLED -Pizza 2: ROLLED -Pizza 4: ROLLED -Pizza 3: ROLLED -Pizza 1: SAUCED -Pizza 0: SAUCED -Pizza 2: SAUCED -Pizza 4: SAUCED -Pizza 3: SAUCED -Pizza 0: CHEESED -Pizza 4: CHEESED -Pizza 1: CHEESED -Pizza 2: CHEESED -Pizza 3: CHEESED -Pizza 0: TOPPED -Pizza 4: TOPPED -Pizza 1: TOPPED -Pizza 2: TOPPED -Pizza 3: TOPPED -Pizza 0: BAKED -Pizza 4: BAKED -Pizza 1: BAKED -Pizza 3: BAKED -Pizza 2: BAKED -Pizza 0: SLICED -Pizza 4: SLICED -Pizza 1: SLICED -Pizza 3: SLICED -Pizza 2: SLICED -Pizza 4: BOXED -Pizza 0: BOXED -Pizza0: complete -Pizza 1: BOXED -Pizza1: complete -Pizza 3: BOXED -Pizza 2: BOXED -Pizza2: complete -Pizza3: complete -Pizza4: complete -1797 -*/ diff --git a/code/concurrent/CompletableUtilities.java b/code/concurrent/CompletableUtilities.java deleted file mode 100644 index 8f3a0e51..00000000 --- a/code/concurrent/CompletableUtilities.java +++ /dev/null @@ -1,27 +0,0 @@ -// concurrent/CompletableUtilities.java -// (c)2020 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 onjava; -import java.util.concurrent.*; - -public class CompletableUtilities { - // Get and show value stored in a CF: - public static void showr(CompletableFuture c) { - try { - System.out.println(c.get()); - } catch(InterruptedException - | ExecutionException e) { - throw new RuntimeException(e); - } - } - // For CF operations that have no value: - public static void voidr(CompletableFuture c) { - try { - c.get(); // Returns void - } catch(InterruptedException - | ExecutionException e) { - throw new RuntimeException(e); - } - } -} diff --git a/code/concurrent/CompletedMachina.java b/code/concurrent/CompletedMachina.java deleted file mode 100644 index 06a78710..00000000 --- a/code/concurrent/CompletedMachina.java +++ /dev/null @@ -1,19 +0,0 @@ -// concurrent/CompletedMachina.java -// (c)2020 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. -import java.util.concurrent.*; - -public class CompletedMachina { - public static void main(String[] args) { - CompletableFuture cf = - CompletableFuture.completedFuture( - new Machina(0)); - try { - Machina m = cf.get(); // Doesn't block - } catch(InterruptedException | - ExecutionException e) { - throw new RuntimeException(e); - } - } -} diff --git a/code/concurrent/CountingStream.java b/code/concurrent/CountingStream.java deleted file mode 100644 index 4cebb24e..00000000 --- a/code/concurrent/CountingStream.java +++ /dev/null @@ -1,32 +0,0 @@ -// concurrent/CountingStream.java -// (c)2020 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. -// {VisuallyInspectOutput} -import java.util.*; -import java.util.concurrent.*; -import java.util.stream.*; - -public class CountingStream { - public static void main(String[] args) { - System.out.println( - IntStream.range(0, 10) - .parallel() - .mapToObj(CountingTask::new) - .map(ct -> ct.call()) - .reduce(0, Integer::sum)); - } -} -/* Output: -1 ForkJoinPool.commonPool-worker-3 100 -8 ForkJoinPool.commonPool-worker-2 100 -0 ForkJoinPool.commonPool-worker-6 100 -2 ForkJoinPool.commonPool-worker-1 100 -4 ForkJoinPool.commonPool-worker-5 100 -9 ForkJoinPool.commonPool-worker-7 100 -6 main 100 -7 ForkJoinPool.commonPool-worker-4 100 -5 ForkJoinPool.commonPool-worker-2 100 -3 ForkJoinPool.commonPool-worker-3 100 -1000 -*/ diff --git a/code/concurrent/CountingTask.java b/code/concurrent/CountingTask.java deleted file mode 100644 index b1fb7b89..00000000 --- a/code/concurrent/CountingTask.java +++ /dev/null @@ -1,19 +0,0 @@ -// concurrent/CountingTask.java -// (c)2020 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. -import java.util.concurrent.*; - -public class CountingTask implements Callable { - final int id; - public CountingTask(int id) { this.id = id; } - @Override - public Integer call() { - Integer val = 0; - for(int i = 0; i < 100; i++) - val++; - System.out.println(id + " " + - Thread.currentThread().getName() + " " + val); - return val; - } -} diff --git a/code/concurrent/DiningPhilosophers.java b/code/concurrent/DiningPhilosophers.java deleted file mode 100644 index 5c2b2f1b..00000000 --- a/code/concurrent/DiningPhilosophers.java +++ /dev/null @@ -1,33 +0,0 @@ -// concurrent/DiningPhilosophers.java -// (c)2020 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. -// Hidden deadlock -// {ExcludeFromGradle} Gradle has trouble -import java.util.*; -import java.util.concurrent.*; -import onjava.Nap; - -public class DiningPhilosophers { - private StickHolder[] sticks; - private Philosopher[] philosophers; - public DiningPhilosophers(int n) { - sticks = new StickHolder[n]; - Arrays.setAll(sticks, i -> new StickHolder()); - philosophers = new Philosopher[n]; - Arrays.setAll(philosophers, i -> - new Philosopher(i, - sticks[i], sticks[(i + 1) % n])); // [1] - // Fix by reversing stick order for this one: - // philosophers[1] = // [2] - // new Philosopher(0, sticks[0], sticks[1]); - Arrays.stream(philosophers) - .forEach(CompletableFuture::runAsync); // [3] - } - public static void main(String[] args) { - // Returns right away: - new DiningPhilosophers(5); // [4] - // Keeps main() from exiting: - new Nap(3, "Shutdown"); - } -} diff --git a/code/concurrent/DualCompletableOperations.java b/code/concurrent/DualCompletableOperations.java deleted file mode 100644 index 42052312..00000000 --- a/code/concurrent/DualCompletableOperations.java +++ /dev/null @@ -1,115 +0,0 @@ -// concurrent/DualCompletableOperations.java -// (c)2020 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. -import java.util.concurrent.*; -import static onjava.CompletableUtilities.*; - -public class DualCompletableOperations { - static CompletableFuture cfA, cfB; - static void init() { - cfA = Workable.make("A", 0.15); - cfB = Workable.make("B", 0.10); // Always wins - } - static void join() { - cfA.join(); - cfB.join(); - System.out.println("*****************"); - } - public static void main(String[] args) { - init(); - voidr(cfA.runAfterEitherAsync(cfB, () -> - System.out.println("runAfterEither"))); - join(); - - init(); - voidr(cfA.runAfterBothAsync(cfB, () -> - System.out.println("runAfterBoth"))); - join(); - - init(); - showr(cfA.applyToEitherAsync(cfB, w -> { - System.out.println("applyToEither: " + w); - return w; - })); - join(); - - init(); - voidr(cfA.acceptEitherAsync(cfB, w -> { - System.out.println("acceptEither: " + w); - })); - join(); - - init(); - voidr(cfA.thenAcceptBothAsync(cfB, (w1, w2) -> { - System.out.println("thenAcceptBoth: " - + w1 + ", " + w2); - })); - join(); - - init(); - showr(cfA.thenCombineAsync(cfB, (w1, w2) -> { - System.out.println("thenCombine: " - + w1 + ", " + w2); - return w1; - })); - join(); - - init(); - CompletableFuture - cfC = Workable.make("C", 0.08), - cfD = Workable.make("D", 0.09); - CompletableFuture.anyOf(cfA, cfB, cfC, cfD) - .thenRunAsync(() -> - System.out.println("anyOf")); - join(); - - init(); - cfC = Workable.make("C", 0.08); - cfD = Workable.make("D", 0.09); - CompletableFuture.allOf(cfA, cfB, cfC, cfD) - .thenRunAsync(() -> - System.out.println("allOf")); - join(); - } -} -/* Output: -Workable[BW] -runAfterEither -Workable[AW] -***************** -Workable[BW] -Workable[AW] -runAfterBoth -***************** -Workable[BW] -applyToEither: Workable[BW] -Workable[BW] -Workable[AW] -***************** -Workable[BW] -acceptEither: Workable[BW] -Workable[AW] -***************** -Workable[BW] -Workable[AW] -thenAcceptBoth: Workable[AW], Workable[BW] -***************** -Workable[BW] -Workable[AW] -thenCombine: Workable[AW], Workable[BW] -Workable[AW] -***************** -Workable[CW] -anyOf -Workable[DW] -Workable[BW] -Workable[AW] -***************** -Workable[CW] -Workable[DW] -Workable[BW] -Workable[AW] -***************** -allOf -*/ diff --git a/code/concurrent/FrostedCake.java b/code/concurrent/FrostedCake.java deleted file mode 100644 index 1be8b661..00000000 --- a/code/concurrent/FrostedCake.java +++ /dev/null @@ -1,32 +0,0 @@ -// concurrent/FrostedCake.java -// (c)2020 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. -import java.util.concurrent.*; -import java.util.stream.*; -import onjava.Nap; - -final class Frosting { - private Frosting() {} - static CompletableFuture make() { - new Nap(0.1); - return CompletableFuture - .completedFuture(new Frosting()); - } -} - -public class FrostedCake { - public FrostedCake(Baked baked, Frosting frosting) { - new Nap(0.1); - } - @Override - public String toString() { return "FrostedCake"; } - public static void main(String[] args) { - Baked.batch().forEach(baked -> baked - .thenCombineAsync(Frosting.make(), - (cake, frosting) -> - new FrostedCake(cake, frosting)) - .thenAcceptAsync(System.out::println) - .join()); - } -} diff --git a/code/concurrent/Futures.java b/code/concurrent/Futures.java deleted file mode 100644 index 888e7f0d..00000000 --- a/code/concurrent/Futures.java +++ /dev/null @@ -1,23 +0,0 @@ -// concurrent/Futures.java -// (c)2020 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. -import java.util.*; -import java.util.concurrent.*; -import java.util.stream.*; - -public class Futures { - public static void main(String[] args) - throws InterruptedException, ExecutionException { - ExecutorService exec = - Executors.newSingleThreadExecutor(); - Future f = - exec.submit(new CountingTask(99)); - System.out.println(f.get()); // [1] - exec.shutdown(); - } -} -/* Output: -99 pool-1-thread-1 100 -100 -*/ diff --git a/code/concurrent/GuardedIDField.java b/code/concurrent/GuardedIDField.java deleted file mode 100644 index e570a5d3..00000000 --- a/code/concurrent/GuardedIDField.java +++ /dev/null @@ -1,18 +0,0 @@ -// concurrent/GuardedIDField.java -// (c)2020 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. -import java.util.concurrent.atomic.*; - -public class GuardedIDField implements HasID { - private static AtomicInteger counter = - new AtomicInteger(); - private int id = counter.getAndIncrement(); - public int getID() { return id; } - public static void main(String[] args) { - IDChecker.test(GuardedIDField::new); - } -} -/* Output: -0 -*/ diff --git a/code/concurrent/HasID.java b/code/concurrent/HasID.java deleted file mode 100644 index e5e13438..00000000 --- a/code/concurrent/HasID.java +++ /dev/null @@ -1,8 +0,0 @@ -// concurrent/HasID.java -// (c)2020 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. - -public interface HasID { - int getID(); -} diff --git a/code/concurrent/IDChecker.java b/code/concurrent/IDChecker.java deleted file mode 100644 index 845c9e6a..00000000 --- a/code/concurrent/IDChecker.java +++ /dev/null @@ -1,41 +0,0 @@ -// concurrent/IDChecker.java -// (c)2020 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. -import java.util.*; -import java.util.function.*; -import java.util.stream.*; -import java.util.concurrent.*; -import com.google.common.collect.Sets; - -public class IDChecker { - public static final int SIZE = 100_000; - static class MakeObjects - implements Supplier> { - private Supplier gen; - MakeObjects(Supplier gen) { - this.gen = gen; - } - @Override - public List get() { - return - Stream.generate(gen) - .limit(SIZE) - .map(HasID::getID) - .collect(Collectors.toList()); - } - } - public static void test(Supplier gen) { - CompletableFuture> - groupA = CompletableFuture - .supplyAsync(new MakeObjects(gen)), - groupB = CompletableFuture - .supplyAsync(new MakeObjects(gen)); - groupA.thenAcceptBoth(groupB, (a, b) -> { - System.out.println( - Sets.intersection( - Sets.newHashSet(a), - Sets.newHashSet(b)).size()); - }).join(); - } -} diff --git a/code/concurrent/InterferingTask.java b/code/concurrent/InterferingTask.java deleted file mode 100644 index da08f653..00000000 --- a/code/concurrent/InterferingTask.java +++ /dev/null @@ -1,17 +0,0 @@ -// concurrent/InterferingTask.java -// (c)2020 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. - -public class InterferingTask implements Runnable { - final int id; - private static Integer val = 0; - public InterferingTask(int id) { this.id = id; } - @Override - public void run() { - for(int i = 0; i < 100; i++) - val++; - System.out.println(id + " " + - Thread.currentThread().getName() + " " + val); - } -} diff --git a/code/concurrent/LambdasAndMethodReferences.java b/code/concurrent/LambdasAndMethodReferences.java deleted file mode 100644 index 10552499..00000000 --- a/code/concurrent/LambdasAndMethodReferences.java +++ /dev/null @@ -1,40 +0,0 @@ -// concurrent/LambdasAndMethodReferences.java -// (c)2020 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. -import java.util.concurrent.*; - -class NotRunnable { - public void go() { - System.out.println("NotRunnable"); - } -} - -class NotCallable { - public Integer get() { - System.out.println("NotCallable"); - return 1; - } -} - -public class LambdasAndMethodReferences { - public static void main(String[] args) - throws InterruptedException { - ExecutorService exec = - Executors.newCachedThreadPool(); - exec.submit(() -> System.out.println("Lambda1")); - exec.submit(new NotRunnable()::go); - exec.submit(() -> { - System.out.println("Lambda2"); - return 1; - }); - exec.submit(new NotCallable()::get); - exec.shutdown(); - } -} -/* Output: -Lambda1 -NotCallable -NotRunnable -Lambda2 -*/ diff --git a/code/concurrent/Machina.java b/code/concurrent/Machina.java deleted file mode 100644 index e70cd2b4..00000000 --- a/code/concurrent/Machina.java +++ /dev/null @@ -1,31 +0,0 @@ -// concurrent/Machina.java -// (c)2020 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. -import onjava.Nap; - -public class Machina { - public enum State { - START, ONE, TWO, THREE, END; - State step() { - if(equals(END)) return END; - return values()[ordinal() + 1]; - } - } - private State state = State.START; - private final int id; - public Machina(int id) { this.id = id; } - public static Machina work(Machina m) { - if(!m.state.equals(State.END)){ - new Nap(0.1); - m.state = m.state.step(); - } - System.out.println(m); - return m; - } - @Override - public String toString() { - return "Machina" + id + ": " + - (state.equals(State.END)? "complete" : state); - } -} diff --git a/code/concurrent/MoreTasksAfterShutdown.java b/code/concurrent/MoreTasksAfterShutdown.java deleted file mode 100644 index 28b96af8..00000000 --- a/code/concurrent/MoreTasksAfterShutdown.java +++ /dev/null @@ -1,27 +0,0 @@ -// concurrent/MoreTasksAfterShutdown.java -// (c)2020 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. -import java.util.concurrent.*; - -public class MoreTasksAfterShutdown { - public static void main(String[] args) { - ExecutorService exec = - Executors.newSingleThreadExecutor(); - exec.execute(new NapTask(1)); - exec.shutdown(); - try { - exec.execute(new NapTask(99)); - } catch(RejectedExecutionException e) { - System.out.println(e); - } - } -} -/* Output: -java.util.concurrent.RejectedExecutionException: Task -NapTask[99] rejected from java.util.concurrent.ThreadPo -olExecutor@4e25154f[Shutting down, pool size = 1, -active threads = 1, queued tasks = 0, completed tasks = -0] -NapTask[1] pool-1-thread-1 -*/ diff --git a/code/concurrent/NapTask.java b/code/concurrent/NapTask.java deleted file mode 100644 index 92df6b60..00000000 --- a/code/concurrent/NapTask.java +++ /dev/null @@ -1,20 +0,0 @@ -// concurrent/NapTask.java -// (c)2020 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. -import onjava.Nap; - -public class NapTask implements Runnable { - final int id; - public NapTask(int id) { this.id = id; } - @Override - public void run() { - new Nap(0.1); // Seconds - System.out.println(this + " " + - Thread.currentThread().getName()); - } - @Override - public String toString() { - return "NapTask[" + id + "]"; - } -} diff --git a/code/concurrent/OnePizza.java b/code/concurrent/OnePizza.java deleted file mode 100644 index f4f27249..00000000 --- a/code/concurrent/OnePizza.java +++ /dev/null @@ -1,26 +0,0 @@ -// concurrent/OnePizza.java -// (c)2020 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. -import onjava.Timer; - -public class OnePizza { - public static void main(String[] args) { - Pizza za = new Pizza(0); - System.out.println( - Timer.duration(() -> { - while(!za.complete()) - za.next(); - })); - } -} -/* Output: -Pizza 0: ROLLED -Pizza 0: SAUCED -Pizza 0: CHEESED -Pizza 0: TOPPED -Pizza 0: BAKED -Pizza 0: SLICED -Pizza 0: BOXED -1622 -*/ diff --git a/code/concurrent/ParallelPrime.java b/code/concurrent/ParallelPrime.java deleted file mode 100644 index 97c02575..00000000 --- a/code/concurrent/ParallelPrime.java +++ /dev/null @@ -1,35 +0,0 @@ -// concurrent/ParallelPrime.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import static java.util.stream.LongStream.*; -import java.io.*; -import java.nio.file.*; -import onjava.Timer; - -public class ParallelPrime { - static final int COUNT = 100_000; - public static boolean isPrime(long n) { - return rangeClosed(2, (long)Math.sqrt(n)) - .noneMatch(i -> n % i == 0); - } - public static void main(String[] args) - throws IOException { - Timer timer = new Timer(); - List primes = - iterate(2, i -> i + 1) - .parallel() // [1] - .filter(ParallelPrime::isPrime) - .limit(COUNT) - .mapToObj(Long::toString) - .collect(Collectors.toList()); - System.out.println(timer.duration()); - Files.write(Paths.get("primes.txt"), primes, - StandardOpenOption.CREATE); - } -} -/* Output: -1224 -*/ diff --git a/code/concurrent/ParallelStreamPuzzle.java b/code/concurrent/ParallelStreamPuzzle.java deleted file mode 100644 index f57dec24..00000000 --- a/code/concurrent/ParallelStreamPuzzle.java +++ /dev/null @@ -1,28 +0,0 @@ -// concurrent/ParallelStreamPuzzle.java -// (c)2020 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. -import java.util.*; -import java.util.function.*; -import java.util.stream.*; - -public class ParallelStreamPuzzle { - static class IntGenerator - implements Supplier { - private int current = 0; - public Integer get() { - return current++; - } - } - public static void main(String[] args) { - List x = - Stream.generate(new IntGenerator()) - .limit(10) - .parallel() // [1] - .collect(Collectors.toList()); - System.out.println(x); - } -} -/* Output: -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -*/ diff --git a/code/concurrent/ParallelStreamPuzzle2.java b/code/concurrent/ParallelStreamPuzzle2.java deleted file mode 100644 index 2fc11d48..00000000 --- a/code/concurrent/ParallelStreamPuzzle2.java +++ /dev/null @@ -1,38 +0,0 @@ -// concurrent/ParallelStreamPuzzle2.java -// (c)2020 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. -import java.util.*; -import java.util.function.*; -import java.util.stream.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.nio.file.*; - -public class ParallelStreamPuzzle2 { - public static final Deque trace = - new ConcurrentLinkedDeque<>(); - static class - IntGenerator implements Supplier { - private AtomicInteger current = - new AtomicInteger(); - public Integer get() { - trace.add(current.get() + ": " + - Thread.currentThread().getName()); - return current.getAndIncrement(); - } - } - public static void - main(String[] args) throws Exception { - List x = - Stream.generate(new IntGenerator()) - .limit(10) - .parallel() - .collect(Collectors.toList()); - System.out.println(x); - Files.write(Paths.get("PSP2.txt"), trace); - } -} -/* Output: -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -*/ diff --git a/code/concurrent/ParallelStreamPuzzle3.java b/code/concurrent/ParallelStreamPuzzle3.java deleted file mode 100644 index 757bddd5..00000000 --- a/code/concurrent/ParallelStreamPuzzle3.java +++ /dev/null @@ -1,33 +0,0 @@ -// concurrent/ParallelStreamPuzzle3.java -// (c)2020 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. -// {VisuallyInspectOutput} -import java.util.*; -import java.util.stream.*; - -public class ParallelStreamPuzzle3 { - public static void main(String[] args) { - List x = IntStream.range(0, 30) - .peek(e -> System.out.println(e + ": " + - Thread.currentThread().getName())) - .limit(10) - .parallel() - .boxed() - .collect(Collectors.toList()); - System.out.println(x); - } -} -/* Output: -8: main -6: ForkJoinPool.commonPool-worker-5 -3: ForkJoinPool.commonPool-worker-7 -5: ForkJoinPool.commonPool-worker-5 -1: ForkJoinPool.commonPool-worker-3 -2: ForkJoinPool.commonPool-worker-6 -4: ForkJoinPool.commonPool-worker-1 -0: ForkJoinPool.commonPool-worker-4 -7: ForkJoinPool.commonPool-worker-1 -9: ForkJoinPool.commonPool-worker-2 -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -*/ diff --git a/code/concurrent/Philosopher.java b/code/concurrent/Philosopher.java deleted file mode 100644 index 48facb38..00000000 --- a/code/concurrent/Philosopher.java +++ /dev/null @@ -1,30 +0,0 @@ -// concurrent/Philosopher.java -// (c)2020 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. - -public class Philosopher implements Runnable { - private final int seat; - private final StickHolder left, right; - public Philosopher(int seat, - StickHolder left, StickHolder right) { - this.seat = seat; - this.left = left; - this.right = right; - } - @Override - public String toString() { - return "P" + seat; - } - @Override - public void run() { - while(true) { - // System.out.println("Thinking"); // [1] - right.pickUp(); - left.pickUp(); - System.out.println(this + " eating"); - right.putDown(); - left.putDown(); - } - } -} diff --git a/code/concurrent/Pizza.java b/code/concurrent/Pizza.java deleted file mode 100644 index 8cd5ff30..00000000 --- a/code/concurrent/Pizza.java +++ /dev/null @@ -1,49 +0,0 @@ -// concurrent/Pizza.java -// (c)2020 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. -import java.util.function.*; -import onjava.Nap; - -public class Pizza { - public enum Step { - DOUGH(4), ROLLED(1), SAUCED(1), CHEESED(2), - TOPPED(5), BAKED(2), SLICED(1), BOXED(0); - int effort; // Needed to get to the next step - Step(int effort) { this.effort = effort; } - Step forward() { - if(equals(BOXED)) return BOXED; - new Nap(effort * 0.1); - return values()[ordinal() + 1]; - } - } - private Step step = Step.DOUGH; - private final int id; - public Pizza(int id) { this.id = id; } - public Pizza next() { - step = step.forward(); - System.out.println("Pizza " + id + ": " + step); - return this; - } - public Pizza next(Step previousStep) { - if(!step.equals(previousStep)) - throw new IllegalStateException("Expected " + - previousStep + " but found " + step); - return next(); - } - public Pizza roll() { return next(Step.DOUGH); } - public Pizza sauce() { return next(Step.ROLLED); } - public Pizza cheese() { return next(Step.SAUCED); } - public Pizza toppings() { return next(Step.CHEESED); } - public Pizza bake() { return next(Step.TOPPED); } - public Pizza slice() { return next(Step.BAKED); } - public Pizza box() { return next(Step.SLICED); } - public boolean complete() { - return step.equals(Step.BOXED); - } - @Override - public String toString() { - return "Pizza" + id + ": " + - (step.equals(Step.BOXED)? "complete" : step); - } -} diff --git a/code/concurrent/PizzaParallelSteps.java b/code/concurrent/PizzaParallelSteps.java deleted file mode 100644 index 605e9985..00000000 --- a/code/concurrent/PizzaParallelSteps.java +++ /dev/null @@ -1,69 +0,0 @@ -// concurrent/PizzaParallelSteps.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import onjava.Timer; - -public class PizzaParallelSteps { - static final int QUANTITY = 5; - public static void main(String[] args) { - Timer timer = new Timer(); - IntStream.range(0, QUANTITY) - .mapToObj(Pizza::new) - .parallel() - .map(Pizza::roll) - .map(Pizza::sauce) - .map(Pizza::cheese) - .map(Pizza::toppings) - .map(Pizza::bake) - .map(Pizza::slice) - .map(Pizza::box) - .forEach(za -> System.out.println(za)); - System.out.println(timer.duration()); - } -} -/* Output: -Pizza 2: ROLLED -Pizza 0: ROLLED -Pizza 1: ROLLED -Pizza 4: ROLLED -Pizza 3: ROLLED -Pizza 1: SAUCED -Pizza 0: SAUCED -Pizza 2: SAUCED -Pizza 3: SAUCED -Pizza 4: SAUCED -Pizza 1: CHEESED -Pizza 0: CHEESED -Pizza 2: CHEESED -Pizza 3: CHEESED -Pizza 4: CHEESED -Pizza 0: TOPPED -Pizza 2: TOPPED -Pizza 1: TOPPED -Pizza 3: TOPPED -Pizza 4: TOPPED -Pizza 1: BAKED -Pizza 2: BAKED -Pizza 0: BAKED -Pizza 4: BAKED -Pizza 3: BAKED -Pizza 0: SLICED -Pizza 2: SLICED -Pizza 1: SLICED -Pizza 3: SLICED -Pizza 4: SLICED -Pizza 1: BOXED -Pizza1: complete -Pizza 2: BOXED -Pizza 0: BOXED -Pizza2: complete -Pizza0: complete -Pizza 3: BOXED -Pizza 4: BOXED -Pizza4: complete -Pizza3: complete -1738 -*/ diff --git a/code/concurrent/PizzaStreams.java b/code/concurrent/PizzaStreams.java deleted file mode 100644 index 16be983a..00000000 --- a/code/concurrent/PizzaStreams.java +++ /dev/null @@ -1,60 +0,0 @@ -// concurrent/PizzaStreams.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import onjava.Timer; - -public class PizzaStreams { - static final int QUANTITY = 5; - public static void main(String[] args) { - Timer timer = new Timer(); - IntStream.range(0, QUANTITY) - .mapToObj(Pizza::new) - .parallel() // [1] - .forEach(za -> { - while(!za.complete()) - za.next(); - }); - System.out.println(timer.duration()); - } -} -/* Output: -Pizza 2: ROLLED -Pizza 0: ROLLED -Pizza 1: ROLLED -Pizza 4: ROLLED -Pizza 3: ROLLED -Pizza 2: SAUCED -Pizza 1: SAUCED -Pizza 0: SAUCED -Pizza 4: SAUCED -Pizza 3: SAUCED -Pizza 2: CHEESED -Pizza 1: CHEESED -Pizza 0: CHEESED -Pizza 4: CHEESED -Pizza 3: CHEESED -Pizza 2: TOPPED -Pizza 1: TOPPED -Pizza 0: TOPPED -Pizza 4: TOPPED -Pizza 3: TOPPED -Pizza 2: BAKED -Pizza 1: BAKED -Pizza 0: BAKED -Pizza 4: BAKED -Pizza 3: BAKED -Pizza 2: SLICED -Pizza 1: SLICED -Pizza 0: SLICED -Pizza 4: SLICED -Pizza 3: SLICED -Pizza 2: BOXED -Pizza 1: BOXED -Pizza 0: BOXED -Pizza 4: BOXED -Pizza 3: BOXED -1739 -*/ diff --git a/code/concurrent/QuittableTask.java b/code/concurrent/QuittableTask.java deleted file mode 100644 index 3cf2a62e..00000000 --- a/code/concurrent/QuittableTask.java +++ /dev/null @@ -1,20 +0,0 @@ -// concurrent/QuittableTask.java -// (c)2020 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. -import java.util.concurrent.atomic.AtomicBoolean; -import onjava.Nap; - -public class QuittableTask implements Runnable { - final int id; - public QuittableTask(int id) { this.id = id; } - private AtomicBoolean running = - new AtomicBoolean(true); - public void quit() { running.set(false); } - @Override - public void run() { - while(running.get()) // [1] - new Nap(0.1); - System.out.print(id + " "); // [2] - } -} diff --git a/code/concurrent/QuittingCompletable.java b/code/concurrent/QuittingCompletable.java deleted file mode 100644 index e41e3899..00000000 --- a/code/concurrent/QuittingCompletable.java +++ /dev/null @@ -1,35 +0,0 @@ -// concurrent/QuittingCompletable.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import java.util.concurrent.*; -import onjava.Nap; - -public class QuittingCompletable { - public static void main(String[] args) { - List tasks = - IntStream.range(1, QuittingTasks.COUNT) - .mapToObj(QuittableTask::new) - .collect(Collectors.toList()); - List> cfutures = - tasks.stream() - .map(CompletableFuture::runAsync) - .collect(Collectors.toList()); - new Nap(1); - tasks.forEach(QuittableTask::quit); - cfutures.forEach(CompletableFuture::join); - } -} -/* Output: -7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 -26 27 28 29 30 31 32 33 34 6 35 4 38 39 40 41 42 43 44 -45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 -63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 -81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 -99 100 101 102 103 104 105 106 107 108 109 110 111 112 -1 113 114 116 117 118 119 120 121 122 123 124 125 126 -127 128 129 130 131 132 133 134 135 136 137 138 139 140 -141 142 143 144 145 146 147 148 149 5 115 37 36 2 3 -*/ diff --git a/code/concurrent/QuittingTasks.java b/code/concurrent/QuittingTasks.java deleted file mode 100644 index 326e24ce..00000000 --- a/code/concurrent/QuittingTasks.java +++ /dev/null @@ -1,35 +0,0 @@ -// concurrent/QuittingTasks.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import java.util.concurrent.*; -import onjava.Nap; - -public class QuittingTasks { - public static final int COUNT = 150; - public static void main(String[] args) { - ExecutorService es = - Executors.newCachedThreadPool(); - List tasks = - IntStream.range(1, COUNT) - .mapToObj(QuittableTask::new) - .peek(qt -> es.execute(qt)) - .collect(Collectors.toList()); - new Nap(1); - tasks.forEach(QuittableTask::quit); - es.shutdown(); - } -} -/* Output: -24 27 31 8 11 7 19 12 16 4 23 3 28 32 15 20 63 60 68 67 -64 39 47 52 51 55 40 43 48 59 44 56 36 35 71 72 83 103 -96 92 88 99 100 87 91 79 75 84 76 115 108 112 104 107 -111 95 80 147 120 127 119 123 144 143 116 132 124 128 -136 131 135 139 148 140 2 126 6 5 1 18 129 17 14 13 21 -22 9 10 30 33 58 37 125 26 34 133 145 78 137 141 138 62 -74 142 86 65 73 146 70 42 149 121 110 134 105 82 117 -106 113 122 45 114 118 38 50 29 90 101 89 57 53 94 41 -61 66 130 69 77 81 85 93 25 102 54 109 98 49 46 97 -*/ diff --git a/code/concurrent/SharedConstructorArgument.java b/code/concurrent/SharedConstructorArgument.java deleted file mode 100644 index 4b09cc26..00000000 --- a/code/concurrent/SharedConstructorArgument.java +++ /dev/null @@ -1,44 +0,0 @@ -// concurrent/SharedConstructorArgument.java -// (c)2020 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. -import java.util.concurrent.atomic.*; - -interface SharedArg { - int get(); -} - -class Unsafe implements SharedArg { - private int i = 0; - public int get() { return i++; } -} - -class Safe implements SharedArg { - private static AtomicInteger counter = - new AtomicInteger(); - public int get() { - return counter.getAndIncrement(); - } -} - -class SharedUser implements HasID { - private final int id; - SharedUser(SharedArg sa) { - id = sa.get(); - } - @Override - public int getID() { return id; } -} - -public class SharedConstructorArgument { - public static void main(String[] args) { - Unsafe unsafe = new Unsafe(); - IDChecker.test(() -> new SharedUser(unsafe)); - Safe safe = new Safe(); - IDChecker.test(() -> new SharedUser(safe)); - } -} -/* Output: -24838 -0 -*/ diff --git a/code/concurrent/SingleThreadExecutor.java b/code/concurrent/SingleThreadExecutor.java deleted file mode 100644 index ef89e3a5..00000000 --- a/code/concurrent/SingleThreadExecutor.java +++ /dev/null @@ -1,49 +0,0 @@ -// concurrent/SingleThreadExecutor.java -// (c)2020 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. -import java.util.concurrent.*; -import java.util.stream.*; -import onjava.*; - -public class SingleThreadExecutor { - public static void main(String[] args) { - ExecutorService exec = - Executors.newSingleThreadExecutor(); - IntStream.range(0, 10) - .mapToObj(NapTask::new) - .forEach(exec::execute); - System.out.println("All tasks submitted"); - exec.shutdown(); - while(!exec.isTerminated()) { - System.out.println( - Thread.currentThread().getName() + - " awaiting termination"); - new Nap(0.1); - } - } -} -/* Output: -All tasks submitted -main awaiting termination -main awaiting termination -NapTask[0] pool-1-thread-1 -main awaiting termination -NapTask[1] pool-1-thread-1 -main awaiting termination -NapTask[2] pool-1-thread-1 -main awaiting termination -NapTask[3] pool-1-thread-1 -main awaiting termination -NapTask[4] pool-1-thread-1 -main awaiting termination -NapTask[5] pool-1-thread-1 -main awaiting termination -NapTask[6] pool-1-thread-1 -main awaiting termination -NapTask[7] pool-1-thread-1 -main awaiting termination -NapTask[8] pool-1-thread-1 -main awaiting termination -NapTask[9] pool-1-thread-1 -*/ diff --git a/code/concurrent/SingleThreadExecutor2.java b/code/concurrent/SingleThreadExecutor2.java deleted file mode 100644 index 08467df5..00000000 --- a/code/concurrent/SingleThreadExecutor2.java +++ /dev/null @@ -1,30 +0,0 @@ -// concurrent/SingleThreadExecutor2.java -// (c)2020 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. -import java.util.concurrent.*; -import java.util.stream.*; - -public class SingleThreadExecutor2 { - public static void main(String[] args) - throws InterruptedException { - ExecutorService exec = - Executors.newSingleThreadExecutor(); - IntStream.range(0, 10) - .mapToObj(NapTask::new) - .forEach(exec::execute); - exec.shutdown(); - } -} -/* Output: -NapTask[0] pool-1-thread-1 -NapTask[1] pool-1-thread-1 -NapTask[2] pool-1-thread-1 -NapTask[3] pool-1-thread-1 -NapTask[4] pool-1-thread-1 -NapTask[5] pool-1-thread-1 -NapTask[6] pool-1-thread-1 -NapTask[7] pool-1-thread-1 -NapTask[8] pool-1-thread-1 -NapTask[9] pool-1-thread-1 -*/ diff --git a/code/concurrent/SingleThreadExecutor3.java b/code/concurrent/SingleThreadExecutor3.java deleted file mode 100644 index 58149423..00000000 --- a/code/concurrent/SingleThreadExecutor3.java +++ /dev/null @@ -1,30 +0,0 @@ -// concurrent/SingleThreadExecutor3.java -// (c)2020 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. -import java.util.concurrent.*; -import java.util.stream.*; - -public class SingleThreadExecutor3 { - public static void main(String[] args) - throws InterruptedException { - ExecutorService exec = - Executors.newSingleThreadExecutor(); - IntStream.range(0, 10) - .mapToObj(InterferingTask::new) - .forEach(exec::execute); - exec.shutdown(); - } -} -/* Output: -0 pool-1-thread-1 100 -1 pool-1-thread-1 200 -2 pool-1-thread-1 300 -3 pool-1-thread-1 400 -4 pool-1-thread-1 500 -5 pool-1-thread-1 600 -6 pool-1-thread-1 700 -7 pool-1-thread-1 800 -8 pool-1-thread-1 900 -9 pool-1-thread-1 1000 -*/ diff --git a/code/concurrent/StaticIDField.java b/code/concurrent/StaticIDField.java deleted file mode 100644 index 22623faa..00000000 --- a/code/concurrent/StaticIDField.java +++ /dev/null @@ -1,10 +0,0 @@ -// concurrent/StaticIDField.java -// (c)2020 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. - -public class StaticIDField implements HasID { - private static int counter = 0; - private int id = counter++; - public int getID() { return id; } -} diff --git a/code/concurrent/StickHolder.java b/code/concurrent/StickHolder.java deleted file mode 100644 index 719a1c63..00000000 --- a/code/concurrent/StickHolder.java +++ /dev/null @@ -1,27 +0,0 @@ -// concurrent/StickHolder.java -// (c)2020 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. -import java.util.concurrent.*; - -public class StickHolder { - private static class Chopstick {} - private Chopstick stick = new Chopstick(); - private BlockingQueue holder = - new ArrayBlockingQueue<>(1); - public StickHolder() { putDown(); } - public void pickUp() { - try { - holder.take(); // Blocks if unavailable - } catch(InterruptedException e) { - throw new RuntimeException(e); - } - } - public void putDown() { - try { - holder.put(stick); - } catch(InterruptedException e) { - throw new RuntimeException(e); - } - } -} diff --git a/code/concurrent/StreamExceptions.java b/code/concurrent/StreamExceptions.java deleted file mode 100644 index 493daee1..00000000 --- a/code/concurrent/StreamExceptions.java +++ /dev/null @@ -1,40 +0,0 @@ -// concurrent/StreamExceptions.java -// (c)2020 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. -import java.util.concurrent.*; -import java.util.stream.*; - -public class StreamExceptions { - static Stream - test(String id, int failcount) { - return - Stream.of(new Breakable(id, failcount)) - .map(Breakable::work) - .map(Breakable::work) - .map(Breakable::work) - .map(Breakable::work); - } - public static void main(String[] args) { - // No operations are even applied ... - test("A", 1); - test("B", 2); - Stream c = test("C", 3); - test("D", 4); - test("E", 5); - // ... until there's a terminal operation: - System.out.println("Entering try"); - try { - c.forEach(System.out::println); // [1] - } catch(Exception e) { - System.out.println(e.getMessage()); - } - } -} -/* Output: -Entering try -Breakable_C [2] -Breakable_C [1] -Throwing Exception for C -Breakable_C failed -*/ diff --git a/code/concurrent/Summing.java b/code/concurrent/Summing.java deleted file mode 100644 index 321dcb57..00000000 --- a/code/concurrent/Summing.java +++ /dev/null @@ -1,47 +0,0 @@ -// concurrent/Summing.java -// (c)2020 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. -import java.util.stream.*; -import java.util.function.*; -import onjava.Timer; - -public class Summing { - static void timeTest(String id, long checkValue, - LongSupplier operation) { - System.out.print(id + ": "); - Timer timer = new Timer(); - long result = operation.getAsLong(); - if(result == checkValue) - System.out.println(timer.duration() + "ms"); - else - System.out.format("result: %d%ncheckValue: %d%n", - result, checkValue); - } - public static final int SZ = 100_000_000; - // This even works: - // public static final int SZ = 1_000_000_000; - public static final long CHECK = - (long)SZ * ((long)SZ + 1)/2; // Gauss's formula - public static void main(String[] args) { - System.out.println(CHECK); - timeTest("Sum Stream", CHECK, () -> - LongStream.rangeClosed(0, SZ).sum()); - timeTest("Sum Stream Parallel", CHECK, () -> - LongStream.rangeClosed(0, SZ).parallel().sum()); - timeTest("Sum Iterated", CHECK, () -> - LongStream.iterate(0, i -> i + 1) - .limit(SZ+1).sum()); - // Slower & runs out of memory above 1_000_000: - // timeTest("Sum Iterated Parallel", CHECK, () -> - // LongStream.iterate(0, i -> i + 1) - // .parallel() - // .limit(SZ+1).sum()); - } -} -/* Output: -5000000050000000 -Sum Stream: 167ms -Sum Stream Parallel: 46ms -Sum Iterated: 284ms -*/ diff --git a/code/concurrent/Summing2.java b/code/concurrent/Summing2.java deleted file mode 100644 index c046721f..00000000 --- a/code/concurrent/Summing2.java +++ /dev/null @@ -1,44 +0,0 @@ -// concurrent/Summing2.java -// (c)2020 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. -// {ExcludeFromTravisCI} -import java.util.*; - -public class Summing2 { - static long basicSum(long[] ia) { - long sum = 0; - int size = ia.length; - for(int i = 0; i < size; i++) - sum += ia[i]; - return sum; - } - // Approximate largest value of SZ before - // running out of memory on my machine: - public static final int SZ = 20_000_000; - public static final long CHECK = - (long)SZ * ((long)SZ + 1)/2; - public static void main(String[] args) { - System.out.println(CHECK); - long[] la = new long[SZ+1]; - Arrays.parallelSetAll(la, i -> i); - Summing.timeTest("Array Stream Sum", CHECK, () -> - Arrays.stream(la).sum()); - Summing.timeTest("Parallel", CHECK, () -> - Arrays.stream(la).parallel().sum()); - Summing.timeTest("Basic Sum", CHECK, () -> - basicSum(la)); - // Destructive summation: - Summing.timeTest("parallelPrefix", CHECK, () -> { - Arrays.parallelPrefix(la, Long::sum); - return la[la.length - 1]; - }); - } -} -/* Output: -200000010000000 -Array Stream Sum: 104ms -Parallel: 81ms -Basic Sum: 106ms -parallelPrefix: 265ms -*/ diff --git a/code/concurrent/Summing3.java b/code/concurrent/Summing3.java deleted file mode 100644 index 252e96f7..00000000 --- a/code/concurrent/Summing3.java +++ /dev/null @@ -1,42 +0,0 @@ -// concurrent/Summing3.java -// (c)2020 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. -// {ExcludeFromTravisCI} -import java.util.*; - -public class Summing3 { - static long basicSum(Long[] ia) { - long sum = 0; - int size = ia.length; - for(int i = 0; i < size; i++) - sum += ia[i]; - return sum; - } - // Approximate largest value of SZ before - // running out of memory on my machine: - public static final int SZ = 10_000_000; - public static final long CHECK = - (long)SZ * ((long)SZ + 1)/2; - public static void main(String[] args) { - System.out.println(CHECK); - Long[] aL = new Long[SZ+1]; - Arrays.parallelSetAll(aL, i -> (long)i); - Summing.timeTest("Long Array Stream Reduce", - CHECK, () -> - Arrays.stream(aL).reduce(0L, Long::sum)); - Summing.timeTest("Long Basic Sum", CHECK, () -> - basicSum(aL)); - // Destructive summation: - Summing.timeTest("Long parallelPrefix",CHECK, ()-> { - Arrays.parallelPrefix(aL, Long::sum); - return aL[aL.length - 1]; - }); - } -} -/* Output: -50000005000000 -Long Array Stream Reduce: 1038ms -Long Basic Sum: 21ms -Long parallelPrefix: 3616ms -*/ diff --git a/code/concurrent/Summing4.java b/code/concurrent/Summing4.java deleted file mode 100644 index bb4fe2ea..00000000 --- a/code/concurrent/Summing4.java +++ /dev/null @@ -1,23 +0,0 @@ -// concurrent/Summing4.java -// (c)2020 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. -// {ExcludeFromTravisCI} -import java.util.*; - -public class Summing4 { - public static void main(String[] args) { - System.out.println(Summing3.CHECK); - Long[] aL = new Long[Summing3.SZ+1]; - Arrays.parallelSetAll(aL, i -> (long)i); - Summing.timeTest("Long Parallel", - Summing3.CHECK, () -> - Arrays.stream(aL) - .parallel() - .reduce(0L,Long::sum)); - } -} -/* Output: -50000005000000 -Long Parallel: 1014ms -*/ diff --git a/code/concurrent/SynchronizedConstructor.java b/code/concurrent/SynchronizedConstructor.java deleted file mode 100644 index 95aa6a54..00000000 --- a/code/concurrent/SynchronizedConstructor.java +++ /dev/null @@ -1,29 +0,0 @@ -// concurrent/SynchronizedConstructor.java -// (c)2020 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. -import java.util.concurrent.atomic.*; - -class SyncConstructor implements HasID { - private final int id; - private static Object - constructorLock = new Object(); - SyncConstructor(SharedArg sa) { - synchronized(constructorLock) { - id = sa.get(); - } - } - @Override - public int getID() { return id; } -} - -public class SynchronizedConstructor { - public static void main(String[] args) { - Unsafe unsafe = new Unsafe(); - IDChecker.test(() -> - new SyncConstructor(unsafe)); - } -} -/* Output: -0 -*/ diff --git a/code/concurrent/SynchronizedFactory.java b/code/concurrent/SynchronizedFactory.java deleted file mode 100644 index 669d4d76..00000000 --- a/code/concurrent/SynchronizedFactory.java +++ /dev/null @@ -1,29 +0,0 @@ -// concurrent/SynchronizedFactory.java -// (c)2020 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. -import java.util.concurrent.atomic.*; - -final class SyncFactory implements HasID { - private final int id; - private SyncFactory(SharedArg sa) { - id = sa.get(); - } - @Override - public int getID() { return id; } - public static synchronized - SyncFactory factory(SharedArg sa) { - return new SyncFactory(sa); - } -} - -public class SynchronizedFactory { - public static void main(String[] args) { - Unsafe unsafe = new Unsafe(); - IDChecker.test(() -> - SyncFactory.factory(unsafe)); - } -} -/* Output: -0 -*/ diff --git a/code/concurrent/TestStaticIDField.java b/code/concurrent/TestStaticIDField.java deleted file mode 100644 index 5df298b7..00000000 --- a/code/concurrent/TestStaticIDField.java +++ /dev/null @@ -1,13 +0,0 @@ -// concurrent/TestStaticIDField.java -// (c)2020 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. - -public class TestStaticIDField { - public static void main(String[] args) { - IDChecker.test(StaticIDField::new); - } -} -/* Output: -13287 -*/ diff --git a/code/concurrent/ThrowsChecked.java b/code/concurrent/ThrowsChecked.java deleted file mode 100644 index 59177b35..00000000 --- a/code/concurrent/ThrowsChecked.java +++ /dev/null @@ -1,42 +0,0 @@ -// concurrent/ThrowsChecked.java -// (c)2020 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. -import java.util.stream.*; -import java.util.concurrent.*; - -public class ThrowsChecked { - class Checked extends Exception {} - static ThrowsChecked nochecked(ThrowsChecked tc) { - return tc; - } - static ThrowsChecked - withchecked(ThrowsChecked tc) throws Checked { - return tc; - } - static void testStream() { - Stream.of(new ThrowsChecked()) - .map(ThrowsChecked::nochecked) - // .map(ThrowsChecked::withchecked); // [1] - .map(tc -> { - try { - return withchecked(tc); - } catch(Checked e) { - throw new RuntimeException(e); - } - }); - } - static void testCompletableFuture() { - CompletableFuture - .completedFuture(new ThrowsChecked()) - .thenApply(ThrowsChecked::nochecked) - // .thenApply(ThrowsChecked::withchecked); // [2] - .thenApply(tc -> { - try { - return withchecked(tc); - } catch(Checked e) { - throw new RuntimeException(e); - } - }); - } -} diff --git a/code/concurrent/Workable.java b/code/concurrent/Workable.java deleted file mode 100644 index fcdbbbf8..00000000 --- a/code/concurrent/Workable.java +++ /dev/null @@ -1,32 +0,0 @@ -// concurrent/Workable.java -// (c)2020 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. -import java.util.concurrent.*; -import onjava.Nap; - -public class Workable { - String id; - final double duration; - public Workable(String id, double duration) { - this.id = id; - this.duration = duration; - } - @Override - public String toString() { - return "Workable[" + id + "]"; - } - public static Workable work(Workable tt) { - new Nap(tt.duration); // Seconds - tt.id = tt.id + "W"; - System.out.println(tt); - return tt; - } - public static CompletableFuture - make(String id, double duration) { - return - CompletableFuture.completedFuture( - new Workable(id, duration)) - .thenApplyAsync(Workable::work); - } -} diff --git a/code/control/BreakAndContinue.java b/code/control/BreakAndContinue.java deleted file mode 100644 index 1faaaa03..00000000 --- a/code/control/BreakAndContinue.java +++ /dev/null @@ -1,38 +0,0 @@ -// control/BreakAndContinue.java -// (c)2020 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. -// Break and continue keywords -import static onjava.Range.*; - -public class BreakAndContinue { - public static void main(String[] args) { - for(int i = 0; i < 100; i++) { // [1] - if(i == 74) break; // Out of for loop - if(i % 9 != 0) continue; // Next iteration - System.out.print(i + " "); - } - System.out.println(); - // Using for-in: - for(int i : range(100)) { // [2] - if(i == 74) break; // Out of for loop - if(i % 9 != 0) continue; // Next iteration - System.out.print(i + " "); - } - System.out.println(); - int i = 0; - // An "infinite loop": - while(true) { // [3] - i++; - int j = i * 27; - if(j == 1269) break; // Out of loop - if(i % 10 != 0) continue; // Top of loop - System.out.print(i + " "); - } - } -} -/* Output: -0 9 18 27 36 45 54 63 72 -0 9 18 27 36 45 54 63 72 -10 20 30 40 -*/ diff --git a/code/control/CommaOperator.java b/code/control/CommaOperator.java deleted file mode 100644 index eae2df82..00000000 --- a/code/control/CommaOperator.java +++ /dev/null @@ -1,18 +0,0 @@ -// control/CommaOperator.java -// (c)2020 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. - -public class CommaOperator { - public static void main(String[] args) { - for(int i = 1, j = i + 10; i < 5; i++, j = i * 2) { - System.out.println("i = " + i + " j = " + j); - } - } -} -/* Output: -i = 1 j = 11 -i = 2 j = 4 -i = 3 j = 6 -i = 4 j = 8 -*/ diff --git a/code/control/ForInFloat.java b/code/control/ForInFloat.java deleted file mode 100644 index cee845b5..00000000 --- a/code/control/ForInFloat.java +++ /dev/null @@ -1,28 +0,0 @@ -// control/ForInFloat.java -// (c)2020 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. -import java.util.*; - -public class ForInFloat { - public static void main(String[] args) { - Random rand = new Random(47); - float[] f = new float[10]; - for(int i = 0; i < 10; i++) - f[i] = rand.nextFloat(); - for(float x : f) - System.out.println(x); - } -} -/* Output: -0.72711575 -0.39982635 -0.5309454 -0.0534122 -0.16020656 -0.57799757 -0.18847865 -0.4170137 -0.51660204 -0.73734957 -*/ diff --git a/code/control/ForInInt.java b/code/control/ForInInt.java deleted file mode 100644 index f6b283a3..00000000 --- a/code/control/ForInInt.java +++ /dev/null @@ -1,28 +0,0 @@ -// control/ForInInt.java -// (c)2020 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. -import static onjava.Range.*; - -public class ForInInt { - public static void main(String[] args) { - for(int i : range(10)) // 0..9 - System.out.print(i + " "); - System.out.println(); - for(int i : range(5, 10)) // 5..9 - System.out.print(i + " "); - System.out.println(); - for(int i : range(5, 20, 3)) // 5..20 step 3 - System.out.print(i + " "); - System.out.println(); - for(int i : range(20, 5, -3)) // Count down - System.out.print(i + " "); - System.out.println(); - } -} -/* Output: -0 1 2 3 4 5 6 7 8 9 -5 6 7 8 9 -5 8 11 14 17 -20 17 14 11 8 -*/ diff --git a/code/control/ForInString.java b/code/control/ForInString.java deleted file mode 100644 index 73e16538..00000000 --- a/code/control/ForInString.java +++ /dev/null @@ -1,14 +0,0 @@ -// control/ForInString.java -// (c)2020 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. - -public class ForInString { - public static void main(String[] args) { - for(char c : "An African Swallow".toCharArray()) - System.out.print(c + " "); - } -} -/* Output: -A n A f r i c a n S w a l l o w -*/ diff --git a/code/control/IfElse.java b/code/control/IfElse.java deleted file mode 100644 index f40a07b7..00000000 --- a/code/control/IfElse.java +++ /dev/null @@ -1,29 +0,0 @@ -// control/IfElse.java -// (c)2020 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. - -public class IfElse { - static int result = 0; - static void test(int testval, int target) { - if(testval > target) - result = +1; - else if(testval < target) // [1] - result = -1; - else - result = 0; // Match - } - public static void main(String[] args) { - test(10, 5); - System.out.println(result); - test(5, 10); - System.out.println(result); - test(5, 5); - System.out.println(result); - } -} -/* Output: -1 --1 -0 -*/ diff --git a/code/control/LabeledFor.java b/code/control/LabeledFor.java deleted file mode 100644 index 2df79bad..00000000 --- a/code/control/LabeledFor.java +++ /dev/null @@ -1,65 +0,0 @@ -// control/LabeledFor.java -// (c)2020 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. -// For loops with "labeled break"/"labeled continue." - -public class LabeledFor { - public static void main(String[] args) { - int i = 0; - outer: // Can't have statements here - for(; true ;) { // infinite loop - inner: // Can't have statements here - for(; i < 10; i++) { - System.out.println("i = " + i); - if(i == 2) { - System.out.println("continue"); - continue; - } - if(i == 3) { - System.out.println("break"); - i++; // Otherwise i never - // gets incremented. - break; - } - if(i == 7) { - System.out.println("continue outer"); - i++; // Otherwise i never - // gets incremented. - continue outer; - } - if(i == 8) { - System.out.println("break outer"); - break outer; - } - for(int k = 0; k < 5; k++) { - if(k == 3) { - System.out.println("continue inner"); - continue inner; - } - } - } - } - // Can't break or continue to labels here - } -} -/* Output: -i = 0 -continue inner -i = 1 -continue inner -i = 2 -continue -i = 3 -break -i = 4 -continue inner -i = 5 -continue inner -i = 6 -continue inner -i = 7 -continue outer -i = 8 -break outer -*/ diff --git a/code/control/LabeledWhile.java b/code/control/LabeledWhile.java deleted file mode 100644 index 961f5ff3..00000000 --- a/code/control/LabeledWhile.java +++ /dev/null @@ -1,51 +0,0 @@ -// control/LabeledWhile.java -// (c)2020 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. -// "While" with "labeled break" and "labeled continue." - -public class LabeledWhile { - public static void main(String[] args) { - int i = 0; - outer: - while(true) { - System.out.println("Outer while loop"); - while(true) { - i++; - System.out.println("i = " + i); - if(i == 1) { - System.out.println("continue"); - continue; - } - if(i == 3) { - System.out.println("continue outer"); - continue outer; - } - if(i == 5) { - System.out.println("break"); - break; - } - if(i == 7) { - System.out.println("break outer"); - break outer; - } - } - } - } -} -/* Output: -Outer while loop -i = 1 -continue -i = 2 -i = 3 -continue outer -Outer while loop -i = 4 -i = 5 -break -Outer while loop -i = 6 -i = 7 -break outer -*/ diff --git a/code/control/ListCharacters.java b/code/control/ListCharacters.java deleted file mode 100644 index 43efce9f..00000000 --- a/code/control/ListCharacters.java +++ /dev/null @@ -1,27 +0,0 @@ -// control/ListCharacters.java -// (c)2020 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. -// List all the lowercase ASCII letters - -public class ListCharacters { - public static void main(String[] args) { - for(char c = 0; c < 128; c++) - if(Character.isLowerCase(c)) - System.out.println("value: " + (int)c + - " character: " + c); - } -} -/* Output: (First 10 Lines) -value: 97 character: a -value: 98 character: b -value: 99 character: c -value: 100 character: d -value: 101 character: e -value: 102 character: f -value: 103 character: g -value: 104 character: h -value: 105 character: i -value: 106 character: j - ... -*/ diff --git a/code/control/RandomBounds.java b/code/control/RandomBounds.java deleted file mode 100644 index 6befc6f4..00000000 --- a/code/control/RandomBounds.java +++ /dev/null @@ -1,30 +0,0 @@ -// control/RandomBounds.java -// (c)2020 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. -// Does Math.random() produce 0.0 and 1.0? -// {java RandomBounds lower} -import onjava.*; - -public class RandomBounds { - public static void main(String[] args) { - new TimedAbort(3); - switch(args.length == 0 ? "" : args[0]) { - case "lower": - while(Math.random() != 0.0) - ; // Keep trying - System.out.println("Produced 0.0!"); - break; - case "upper": - while(Math.random() != 1.0) - ; // Keep trying - System.out.println("Produced 1.0!"); - break; - default: - System.out.println("Usage:"); - System.out.println("\tRandomBounds lower"); - System.out.println("\tRandomBounds upper"); - System.exit(1); - } - } -} diff --git a/code/control/StringSwitch.java b/code/control/StringSwitch.java deleted file mode 100644 index 638cc427..00000000 --- a/code/control/StringSwitch.java +++ /dev/null @@ -1,44 +0,0 @@ -// control/StringSwitch.java -// (c)2020 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. - -public class StringSwitch { - public static void main(String[] args) { - String color = "red"; - // Old way: using if-then - if("red".equals(color)) { - System.out.println("RED"); - } else if("green".equals(color)) { - System.out.println("GREEN"); - } else if("blue".equals(color)) { - System.out.println("BLUE"); - } else if("yellow".equals(color)) { - System.out.println("YELLOW"); - } else { - System.out.println("Unknown"); - } - // New way: Strings in switch - switch(color) { - case "red": - System.out.println("RED"); - break; - case "green": - System.out.println("GREEN"); - break; - case "blue": - System.out.println("BLUE"); - break; - case "yellow": - System.out.println("YELLOW"); - break; - default: - System.out.println("Unknown"); - break; - } - } -} -/* Output: -RED -RED -*/ diff --git a/code/control/TestWithReturn.java b/code/control/TestWithReturn.java deleted file mode 100644 index efe05c90..00000000 --- a/code/control/TestWithReturn.java +++ /dev/null @@ -1,24 +0,0 @@ -// control/TestWithReturn.java -// (c)2020 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. - -public class TestWithReturn { - static int test(int testval, int target) { - if(testval > target) - return +1; - if(testval < target) - return -1; - return 0; // Match - } - public static void main(String[] args) { - System.out.println(test(10, 5)); - System.out.println(test(5, 10)); - System.out.println(test(5, 5)); - } -} -/* Output: -1 --1 -0 -*/ diff --git a/code/control/TrueFalse.java b/code/control/TrueFalse.java deleted file mode 100644 index e87dade4..00000000 --- a/code/control/TrueFalse.java +++ /dev/null @@ -1,15 +0,0 @@ -// control/TrueFalse.java -// (c)2020 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. - -public class TrueFalse { - public static void main(String[] args) { - System.out.println(1 == 1); - System.out.println(1 == 2); - } -} -/* Output: -true -false -*/ diff --git a/code/control/VowelsAndConsonants.java b/code/control/VowelsAndConsonants.java deleted file mode 100644 index d3a192d0..00000000 --- a/code/control/VowelsAndConsonants.java +++ /dev/null @@ -1,44 +0,0 @@ -// control/VowelsAndConsonants.java -// (c)2020 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. -// Demonstrates the switch statement -import java.util.*; - -public class VowelsAndConsonants { - public static void main(String[] args) { - Random rand = new Random(47); - for(int i = 0; i < 100; i++) { - int c = rand.nextInt(26) + 'a'; - System.out.print((char)c + ", " + c + ": "); - switch(c) { - case 'a': - case 'e': - case 'i': - case 'o': - case 'u': System.out.println("vowel"); - break; - case 'y': - case 'w': System.out.println("Sometimes vowel"); - break; - default: System.out.println("consonant"); - } - } - } -} -/* Output: (First 13 Lines) -y, 121: Sometimes vowel -n, 110: consonant -z, 122: consonant -b, 98: consonant -r, 114: consonant -n, 110: consonant -y, 121: Sometimes vowel -g, 103: consonant -c, 99: consonant -f, 102: consonant -o, 111: vowel -w, 119: Sometimes vowel -z, 122: consonant - ... -*/ diff --git a/code/control/WhileTest.java b/code/control/WhileTest.java deleted file mode 100644 index 075068cf..00000000 --- a/code/control/WhileTest.java +++ /dev/null @@ -1,31 +0,0 @@ -// control/WhileTest.java -// (c)2020 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. -// Demonstrates the while loop - -public class WhileTest { - static boolean condition() { - boolean result = Math.random() < 0.99; - System.out.print(result + ", "); - return result; - } - public static void main(String[] args) { - while(condition()) - System.out.println("Inside 'while'"); - System.out.println("Exited 'while'"); - } -} -/* Output: (First and Last 5 Lines) -true, Inside 'while' -true, Inside 'while' -true, Inside 'while' -true, Inside 'while' -true, Inside 'while' -...________...________...________...________... -true, Inside 'while' -true, Inside 'while' -true, Inside 'while' -true, Inside 'while' -false, Exited 'while' -*/ diff --git a/code/enums/AlarmPoints.java b/code/enums/AlarmPoints.java deleted file mode 100644 index a8731137..00000000 --- a/code/enums/AlarmPoints.java +++ /dev/null @@ -1,9 +0,0 @@ -// enums/AlarmPoints.java -// (c)2020 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 enums; -public enum AlarmPoints { - STAIR1, STAIR2, LOBBY, OFFICE1, OFFICE2, OFFICE3, - OFFICE4, BATHROOM, UTILITY, KITCHEN -} diff --git a/code/enums/BigEnumSet.java b/code/enums/BigEnumSet.java deleted file mode 100644 index 52ac3445..00000000 --- a/code/enums/BigEnumSet.java +++ /dev/null @@ -1,29 +0,0 @@ -// enums/BigEnumSet.java -// (c)2020 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. -import java.util.*; - -public class BigEnumSet { - enum Big { A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, - A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, - A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, - A30, A31, A32, A33, A34, A35, A36, A37, A38, A39, - A40, A41, A42, A43, A44, A45, A46, A47, A48, A49, - A50, A51, A52, A53, A54, A55, A56, A57, A58, A59, - A60, A61, A62, A63, A64, A65, A66, A67, A68, A69, - A70, A71, A72, A73, A74, A75 } - public static void main(String[] args) { - EnumSet bigEnumSet = EnumSet.allOf(Big.class); - System.out.println(bigEnumSet); - } -} -/* Output: -[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, -A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, -A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, -A35, A36, A37, A38, A39, A40, A41, A42, A43, A44, A45, -A46, A47, A48, A49, A50, A51, A52, A53, A54, A55, A56, -A57, A58, A59, A60, A61, A62, A63, A64, A65, A66, A67, -A68, A69, A70, A71, A72, A73, A74, A75] -*/ diff --git a/code/enums/Burrito2.java b/code/enums/Burrito2.java deleted file mode 100644 index 8b92ab0d..00000000 --- a/code/enums/Burrito2.java +++ /dev/null @@ -1,28 +0,0 @@ -// enums/Burrito2.java -// (c)2020 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. -// {java enums.Burrito2} -package enums; -import static enums.SpicinessEnum.*; - -public class Burrito2 { - SpicinessEnum degree; - public Burrito2(SpicinessEnum degree) { - this.degree = degree; - } - @Override - public String toString() { - return "Burrito is "+ degree; - } - public static void main(String[] args) { - System.out.println(new Burrito2(NOT)); - System.out.println(new Burrito2(MEDIUM)); - System.out.println(new Burrito2(HOT)); - } -} -/* Output: -Burrito is NOT -Burrito is MEDIUM -Burrito is HOT -*/ diff --git a/code/enums/CarWash.java b/code/enums/CarWash.java deleted file mode 100644 index 95800e8f..00000000 --- a/code/enums/CarWash.java +++ /dev/null @@ -1,88 +0,0 @@ -// enums/CarWash.java -// (c)2020 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. -import java.util.*; - -public class CarWash { - public enum Cycle { - UNDERBODY { - @Override - void action() { - System.out.println("Spraying the underbody"); - } - }, - WHEELWASH { - @Override - void action() { - System.out.println("Washing the wheels"); - } - }, - PREWASH { - @Override - void action() { - System.out.println("Loosening the dirt"); - } - }, - BASIC { - @Override - void action() { - System.out.println("The basic wash"); - } - }, - HOTWAX { - @Override - void action() { - System.out.println("Applying hot wax"); - } - }, - RINSE { - @Override - void action() { - System.out.println("Rinsing"); - } - }, - BLOWDRY { - @Override - void action() { - System.out.println("Blowing dry"); - } - }; - abstract void action(); - } - EnumSet cycles = - EnumSet.of(Cycle.BASIC, Cycle.RINSE); - public void add(Cycle cycle) { - cycles.add(cycle); - } - public void washCar() { - for(Cycle c : cycles) - c.action(); - } - @Override - public String toString() { - return cycles.toString(); - } - public static void main(String[] args) { - CarWash wash = new CarWash(); - System.out.println(wash); - wash.washCar(); - // Order of addition is unimportant: - wash.add(Cycle.BLOWDRY); - wash.add(Cycle.BLOWDRY); // Duplicates ignored - wash.add(Cycle.RINSE); - wash.add(Cycle.HOTWAX); - System.out.println(wash); - wash.washCar(); - } -} -/* Output: -[BASIC, RINSE] -The basic wash -Rinsing -[BASIC, HOTWAX, RINSE, BLOWDRY] -The basic wash -Applying hot wax -Rinsing -Blowing dry -*/ diff --git a/code/enums/Competitor.java b/code/enums/Competitor.java deleted file mode 100644 index 09bf7141..00000000 --- a/code/enums/Competitor.java +++ /dev/null @@ -1,10 +0,0 @@ -// enums/Competitor.java -// (c)2020 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. -// Switching one enum on another -package enums; - -public interface Competitor> { - Outcome compete(T competitor); -} diff --git a/code/enums/ConstantSpecificMethod.java b/code/enums/ConstantSpecificMethod.java deleted file mode 100644 index 913aa291..00000000 --- a/code/enums/ConstantSpecificMethod.java +++ /dev/null @@ -1,41 +0,0 @@ -// enums/ConstantSpecificMethod.java -// (c)2020 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. -import java.util.*; -import java.text.*; - -public enum ConstantSpecificMethod { - DATE_TIME { - @Override - String getInfo() { - return - DateFormat.getDateInstance() - .format(new Date()); - } - }, - CLASSPATH { - @Override - String getInfo() { - return System.getenv("CLASSPATH"); - } - }, - VERSION { - @Override - String getInfo() { - return System.getProperty("java.version"); - } - }; - abstract String getInfo(); - public static void main(String[] args) { - for(ConstantSpecificMethod csm : values()) - System.out.println(csm.getInfo()); - } -} -/* Output: -May 9, 2017 -C:\Users\Bruce\Documents\GitHub\on- -java\ExtractedExamples\\gradle\wrapper\gradle- -wrapper.jar -1.8.0_112 -*/ diff --git a/code/enums/EnumClass.java b/code/enums/EnumClass.java deleted file mode 100644 index 061f8abf..00000000 --- a/code/enums/EnumClass.java +++ /dev/null @@ -1,51 +0,0 @@ -// enums/EnumClass.java -// (c)2020 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. -// Capabilities of the Enum class - -enum Shrubbery { GROUND, CRAWLING, HANGING } - -public class EnumClass { - public static void main(String[] args) { - for(Shrubbery s : Shrubbery.values()) { - System.out.println( - s + " ordinal: " + s.ordinal()); - System.out.print( - s.compareTo(Shrubbery.CRAWLING) + " "); - System.out.print( - s.equals(Shrubbery.CRAWLING) + " "); - System.out.println(s == Shrubbery.CRAWLING); - System.out.println(s.getDeclaringClass()); - System.out.println(s.name()); - System.out.println("********************"); - } - // Produce an enum value from a String name: - for(String s : - "HANGING CRAWLING GROUND".split(" ")) { - Shrubbery shrub = - Enum.valueOf(Shrubbery.class, s); - System.out.println(shrub); - } - } -} -/* Output: -GROUND ordinal: 0 --1 false false -class Shrubbery -GROUND -******************** -CRAWLING ordinal: 1 -0 true true -class Shrubbery -CRAWLING -******************** -HANGING ordinal: 2 -1 false false -class Shrubbery -HANGING -******************** -HANGING -CRAWLING -GROUND -*/ diff --git a/code/enums/EnumMaps.java b/code/enums/EnumMaps.java deleted file mode 100644 index f75c5cd4..00000000 --- a/code/enums/EnumMaps.java +++ /dev/null @@ -1,37 +0,0 @@ -// enums/EnumMaps.java -// (c)2020 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. -// Basics of EnumMaps -// {java enums.EnumMaps} -package enums; -import java.util.*; -import static enums.AlarmPoints.*; - -interface Command { void action(); } - -public class EnumMaps { - public static void main(String[] args) { - EnumMap em = - new EnumMap<>(AlarmPoints.class); - em.put(KITCHEN, - () -> System.out.println("Kitchen fire!")); - em.put(BATHROOM, - () -> System.out.println("Bathroom alert!")); - for(Map.Entry e: - em.entrySet()) { - System.out.print(e.getKey() + ": "); - e.getValue().action(); - } - try { // If there's no value for a particular key: - em.get(UTILITY).action(); - } catch(Exception e) { - System.out.println("Expected: " + e); - } - } -} -/* Output: -BATHROOM: Bathroom alert! -KITCHEN: Kitchen fire! -Expected: java.lang.NullPointerException -*/ diff --git a/code/enums/EnumSets.java b/code/enums/EnumSets.java deleted file mode 100644 index 0e749cad..00000000 --- a/code/enums/EnumSets.java +++ /dev/null @@ -1,39 +0,0 @@ -// enums/EnumSets.java -// (c)2020 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. -// Operations on EnumSets -// {java enums.EnumSets} -package enums; -import java.util.*; -import static enums.AlarmPoints.*; - -public class EnumSets { - public static void main(String[] args) { - EnumSet points = - EnumSet.noneOf(AlarmPoints.class); // Empty - points.add(BATHROOM); - System.out.println(points); - points.addAll( - EnumSet.of(STAIR1, STAIR2, KITCHEN)); - System.out.println(points); - points = EnumSet.allOf(AlarmPoints.class); - points.removeAll( - EnumSet.of(STAIR1, STAIR2, KITCHEN)); - System.out.println(points); - points.removeAll( - EnumSet.range(OFFICE1, OFFICE4)); - System.out.println(points); - points = EnumSet.complementOf(points); - System.out.println(points); - } -} -/* Output: -[BATHROOM] -[STAIR1, STAIR2, BATHROOM, KITCHEN] -[LOBBY, OFFICE1, OFFICE2, OFFICE3, OFFICE4, BATHROOM, -UTILITY] -[LOBBY, BATHROOM, UTILITY] -[STAIR1, STAIR2, OFFICE1, OFFICE2, OFFICE3, OFFICE4, -KITCHEN] -*/ diff --git a/code/enums/Input.java b/code/enums/Input.java deleted file mode 100644 index 3dc0ec44..00000000 --- a/code/enums/Input.java +++ /dev/null @@ -1,33 +0,0 @@ -// enums/Input.java -// (c)2020 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. -import java.util.*; - -public enum Input { - NICKEL(5), DIME(10), QUARTER(25), DOLLAR(100), - TOOTHPASTE(200), CHIPS(75), SODA(100), SOAP(50), - ABORT_TRANSACTION { - @Override - public int amount() { // Disallow - throw new RuntimeException("ABORT.amount()"); - } - }, - STOP { // This must be the last instance. - @Override - public int amount() { // Disallow - throw new - RuntimeException("SHUT_DOWN.amount()"); - } - }; - int value; // In cents - Input(int value) { this.value = value; } - Input() {} - int amount() { return value; }; // In cents - static Random rand = new Random(47); - public static Input randomSelection() { - // Don't include STOP: - return - values()[rand.nextInt(values().length - 1)]; - } -} diff --git a/code/enums/NonEnum.java b/code/enums/NonEnum.java deleted file mode 100644 index 34440730..00000000 --- a/code/enums/NonEnum.java +++ /dev/null @@ -1,19 +0,0 @@ -// enums/NonEnum.java -// (c)2020 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. - -public class NonEnum { - public static void main(String[] args) { - Class intClass = Integer.class; - try { - for(Object en : intClass.getEnumConstants()) - System.out.println(en); - } catch(Exception e) { - System.out.println("Expected: " + e); - } - } -} -/* Output: -Expected: java.lang.NullPointerException -*/ diff --git a/code/enums/NotClasses.java b/code/enums/NotClasses.java deleted file mode 100644 index 681e807d..00000000 --- a/code/enums/NotClasses.java +++ /dev/null @@ -1,50 +0,0 @@ -// enums/NotClasses.java -// (c)2020 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. -// {ExcludeFromGradle} -// javap -c LikeClasses - -enum LikeClasses { - WINKEN { - @Override - void behavior() { - System.out.println("Behavior1"); - } - }, - BLINKEN { - @Override - void behavior() { - System.out.println("Behavior2"); - } - }, - NOD { - @Override - void behavior() { - System.out.println("Behavior3"); - } - }; - abstract void behavior(); -} - -public class NotClasses { - // void f1(LikeClasses.WINKEN instance) {} // Nope -} -/* Output: (First 12 Lines) -Compiled from "NotClasses.java" -abstract class LikeClasses extends -java.lang.Enum { - public static final LikeClasses WINKEN; - - public static final LikeClasses BLINKEN; - - public static final LikeClasses NOD; - - public static LikeClasses[] values(); - Code: - 0: getstatic #2 // Field -$VALUES:[LLikeClasses; - 3: invokevirtual #3 // Method -"[LLikeClasses;".clone:()Ljava/lang/Object; - ... -*/ diff --git a/code/enums/Outcome.java b/code/enums/Outcome.java deleted file mode 100644 index 0e2a25d6..00000000 --- a/code/enums/Outcome.java +++ /dev/null @@ -1,6 +0,0 @@ -// enums/Outcome.java -// (c)2020 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 enums; -public enum Outcome { WIN, LOSE, DRAW } diff --git a/code/enums/OverrideConstantSpecific.java b/code/enums/OverrideConstantSpecific.java deleted file mode 100644 index 28e3343b..00000000 --- a/code/enums/OverrideConstantSpecific.java +++ /dev/null @@ -1,28 +0,0 @@ -// enums/OverrideConstantSpecific.java -// (c)2020 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. - -public enum OverrideConstantSpecific { - NUT, BOLT, - WASHER { - @Override - void f() { - System.out.println("Overridden method"); - } - }; - void f() { - System.out.println("default behavior"); - } - public static void main(String[] args) { - for(OverrideConstantSpecific ocs : values()) { - System.out.print(ocs + ": "); - ocs.f(); - } - } -} -/* Output: -NUT: default behavior -BOLT: default behavior -WASHER: Overridden method -*/ diff --git a/code/enums/OzWitch.java b/code/enums/OzWitch.java deleted file mode 100644 index c9eedb4f..00000000 --- a/code/enums/OzWitch.java +++ /dev/null @@ -1,32 +0,0 @@ -// enums/OzWitch.java -// (c)2020 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. -// The witches in the land of Oz - -public enum OzWitch { - // Instances must be defined first, before methods: - WEST("Miss Gulch, aka the Wicked Witch of the West"), - NORTH("Glinda, the Good Witch of the North"), - EAST("Wicked Witch of the East, wearer of the Ruby " + - "Slippers, crushed by Dorothy's house"), - SOUTH("Good by inference, but missing"); - private String description; - // Constructor must be package or private access: - private OzWitch(String description) { - this.description = description; - } - public String getDescription() { return description; } - public static void main(String[] args) { - for(OzWitch witch : OzWitch.values()) - System.out.println( - witch + ": " + witch.getDescription()); - } -} -/* Output: -WEST: Miss Gulch, aka the Wicked Witch of the West -NORTH: Glinda, the Good Witch of the North -EAST: Wicked Witch of the East, wearer of the Ruby -Slippers, crushed by Dorothy's house -SOUTH: Good by inference, but missing -*/ diff --git a/code/enums/PostOffice.java b/code/enums/PostOffice.java deleted file mode 100644 index 05634820..00000000 --- a/code/enums/PostOffice.java +++ /dev/null @@ -1,197 +0,0 @@ -// enums/PostOffice.java -// (c)2020 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. -// Modeling a post office -import java.util.*; -import onjava.*; - -class Mail { - // The NO's reduce probability of random selection: - enum GeneralDelivery {YES,NO1,NO2,NO3,NO4,NO5} - enum Scannability {UNSCANNABLE,YES1,YES2,YES3,YES4} - enum Readability {ILLEGIBLE,YES1,YES2,YES3,YES4} - enum Address {INCORRECT,OK1,OK2,OK3,OK4,OK5,OK6} - enum ReturnAddress {MISSING,OK1,OK2,OK3,OK4,OK5} - GeneralDelivery generalDelivery; - Scannability scannability; - Readability readability; - Address address; - ReturnAddress returnAddress; - static long counter = 0; - long id = counter++; - @Override - public String toString() { return "Mail " + id; } - public String details() { - return toString() + - ", General Delivery: " + generalDelivery + - ", Address Scanability: " + scannability + - ", Address Readability: " + readability + - ", Address Address: " + address + - ", Return address: " + returnAddress; - } - // Generate test Mail: - public static Mail randomMail() { - Mail m = new Mail(); - m.generalDelivery = - Enums.random(GeneralDelivery.class); - m.scannability = - Enums.random(Scannability.class); - m.readability = - Enums.random(Readability.class); - m.address = Enums.random(Address.class); - m.returnAddress = - Enums.random(ReturnAddress.class); - return m; - } - public static - Iterable generator(final int count) { - return new Iterable() { - int n = count; - @Override - public Iterator iterator() { - return new Iterator() { - @Override - public boolean hasNext() { - return n-- > 0; - } - @Override - public Mail next() { - return randomMail(); - } - @Override - public void remove() { // Not implemented - throw new UnsupportedOperationException(); - } - }; - } - }; - } -} - -public class PostOffice { - enum MailHandler { - GENERAL_DELIVERY { - @Override - boolean handle(Mail m) { - switch(m.generalDelivery) { - case YES: - System.out.println( - "Using general delivery for " + m); - return true; - default: return false; - } - } - }, - MACHINE_SCAN { - @Override - boolean handle(Mail m) { - switch(m.scannability) { - case UNSCANNABLE: return false; - default: - switch(m.address) { - case INCORRECT: return false; - default: - System.out.println( - "Delivering "+ m + " automatically"); - return true; - } - } - } - }, - VISUAL_INSPECTION { - @Override - boolean handle(Mail m) { - switch(m.readability) { - case ILLEGIBLE: return false; - default: - switch(m.address) { - case INCORRECT: return false; - default: - System.out.println( - "Delivering " + m + " normally"); - return true; - } - } - } - }, - RETURN_TO_SENDER { - @Override - boolean handle(Mail m) { - switch(m.returnAddress) { - case MISSING: return false; - default: - System.out.println( - "Returning " + m + " to sender"); - return true; - } - } - }; - abstract boolean handle(Mail m); - } - static void handle(Mail m) { - for(MailHandler handler : MailHandler.values()) - if(handler.handle(m)) - return; - System.out.println(m + " is a dead letter"); - } - public static void main(String[] args) { - for(Mail mail : Mail.generator(10)) { - System.out.println(mail.details()); - handle(mail); - System.out.println("*****"); - } - } -} -/* Output: -Mail 0, General Delivery: NO2, Address Scanability: -UNSCANNABLE, Address Readability: YES3, Address -Address: OK1, Return address: OK1 -Delivering Mail 0 normally -***** -Mail 1, General Delivery: NO5, Address Scanability: -YES3, Address Readability: ILLEGIBLE, Address Address: -OK5, Return address: OK1 -Delivering Mail 1 automatically -***** -Mail 2, General Delivery: YES, Address Scanability: -YES3, Address Readability: YES1, Address Address: OK1, -Return address: OK5 -Using general delivery for Mail 2 -***** -Mail 3, General Delivery: NO4, Address Scanability: -YES3, Address Readability: YES1, Address Address: -INCORRECT, Return address: OK4 -Returning Mail 3 to sender -***** -Mail 4, General Delivery: NO4, Address Scanability: -UNSCANNABLE, Address Readability: YES1, Address -Address: INCORRECT, Return address: OK2 -Returning Mail 4 to sender -***** -Mail 5, General Delivery: NO3, Address Scanability: -YES1, Address Readability: ILLEGIBLE, Address Address: -OK4, Return address: OK2 -Delivering Mail 5 automatically -***** -Mail 6, General Delivery: YES, Address Scanability: -YES4, Address Readability: ILLEGIBLE, Address Address: -OK4, Return address: OK4 -Using general delivery for Mail 6 -***** -Mail 7, General Delivery: YES, Address Scanability: -YES3, Address Readability: YES4, Address Address: OK2, -Return address: MISSING -Using general delivery for Mail 7 -***** -Mail 8, General Delivery: NO3, Address Scanability: -YES1, Address Readability: YES3, Address Address: -INCORRECT, Return address: MISSING -Mail 8 is a dead letter -***** -Mail 9, General Delivery: NO1, Address Scanability: -UNSCANNABLE, Address Readability: YES2, Address -Address: OK1, Return address: OK4 -Delivering Mail 9 normally -***** -*/ diff --git a/code/enums/RandomTest.java b/code/enums/RandomTest.java deleted file mode 100644 index 92f2e481..00000000 --- a/code/enums/RandomTest.java +++ /dev/null @@ -1,21 +0,0 @@ -// enums/RandomTest.java -// (c)2020 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. -import onjava.*; - -enum Activity { SITTING, LYING, STANDING, HOPPING, - RUNNING, DODGING, JUMPING, FALLING, FLYING } - -public class RandomTest { - public static void main(String[] args) { - for(int i = 0; i < 20; i++) - System.out.print( - Enums.random(Activity.class) + " "); - } -} -/* Output: -STANDING FLYING RUNNING STANDING RUNNING STANDING LYING -DODGING SITTING RUNNING HOPPING HOPPING HOPPING RUNNING -STANDING LYING FALLING RUNNING FLYING LYING -*/ diff --git a/code/enums/Reflection.java b/code/enums/Reflection.java deleted file mode 100644 index 822a134e..00000000 --- a/code/enums/Reflection.java +++ /dev/null @@ -1,71 +0,0 @@ -// enums/Reflection.java -// (c)2020 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. -// Analyzing enums using reflection -import java.lang.reflect.*; -import java.util.*; -import onjava.*; - -enum Explore { HERE, THERE } - -public class Reflection { - public static - Set analyze(Class enumClass) { - System.out.println( - "_____ Analyzing " + enumClass + " _____"); - System.out.println("Interfaces:"); - for(Type t : enumClass.getGenericInterfaces()) - System.out.println(t); - System.out.println( - "Base: " + enumClass.getSuperclass()); - System.out.println("Methods: "); - Set methods = new TreeSet<>(); - for(Method m : enumClass.getMethods()) - methods.add(m.getName()); - System.out.println(methods); - return methods; - } - public static void main(String[] args) { - Set exploreMethods = - analyze(Explore.class); - Set enumMethods = analyze(Enum.class); - System.out.println( - "Explore.containsAll(Enum)? " + - exploreMethods.containsAll(enumMethods)); - System.out.print("Explore.removeAll(Enum): "); - exploreMethods.removeAll(enumMethods); - System.out.println(exploreMethods); - // Decompile the code for the enum: - OSExecute.command( - "javap -cp build/classes/java/main Explore"); - } -} -/* Output: -_____ Analyzing class Explore _____ -Interfaces: -Base: class java.lang.Enum -Methods: -[compareTo, equals, getClass, getDeclaringClass, -hashCode, name, notify, notifyAll, ordinal, toString, -valueOf, values, wait] -_____ Analyzing class java.lang.Enum _____ -Interfaces: -java.lang.Comparable -interface java.io.Serializable -Base: class java.lang.Object -Methods: -[compareTo, equals, getClass, getDeclaringClass, -hashCode, name, notify, notifyAll, ordinal, toString, -valueOf, wait] -Explore.containsAll(Enum)? true -Explore.removeAll(Enum): [values] -Compiled from "Reflection.java" -final class Explore extends java.lang.Enum { - public static final Explore HERE; - public static final Explore THERE; - public static Explore[] values(); - public static Explore valueOf(java.lang.String); - static {}; -} -*/ diff --git a/code/enums/RoShamBo.java b/code/enums/RoShamBo.java deleted file mode 100644 index 76b3d76f..00000000 --- a/code/enums/RoShamBo.java +++ /dev/null @@ -1,21 +0,0 @@ -// enums/RoShamBo.java -// (c)2020 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. -// Common tools for RoShamBo examples -package enums; -import onjava.*; - -public class RoShamBo { - public static > - void match(T a, T b) { - System.out.println( - a + " vs. " + b + ": " + a.compete(b)); - } - public static & Competitor> - void play(Class rsbClass, int size) { - for(int i = 0; i < size; i++) - match( - Enums.random(rsbClass),Enums.random(rsbClass)); - } -} diff --git a/code/enums/RoShamBo1.java b/code/enums/RoShamBo1.java deleted file mode 100644 index abf52c9c..00000000 --- a/code/enums/RoShamBo1.java +++ /dev/null @@ -1,104 +0,0 @@ -// enums/RoShamBo1.java -// (c)2020 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. -// Demonstration of multiple dispatching -// {java enums.RoShamBo1} -package enums; -import java.util.*; -import static enums.Outcome.*; - -interface Item { - Outcome compete(Item it); - Outcome eval(Paper p); - Outcome eval(Scissors s); - Outcome eval(Rock r); -} - -class Paper implements Item { - @Override - public Outcome compete(Item it) { - return it.eval(this); - } - @Override - public Outcome eval(Paper p) { return DRAW; } - @Override - public Outcome eval(Scissors s) { return WIN; } - @Override - public Outcome eval(Rock r) { return LOSE; } - @Override - public String toString() { return "Paper"; } -} - -class Scissors implements Item { - @Override - public Outcome compete(Item it) { - return it.eval(this); - } - @Override - public Outcome eval(Paper p) { return LOSE; } - @Override - public Outcome eval(Scissors s) { return DRAW; } - @Override - public Outcome eval(Rock r) { return WIN; } - @Override - public String toString() { return "Scissors"; } -} - -class Rock implements Item { - @Override - public Outcome compete(Item it) { - return it.eval(this); - } - @Override - public Outcome eval(Paper p) { return WIN; } - @Override - public Outcome eval(Scissors s) { return LOSE; } - @Override - public Outcome eval(Rock r) { return DRAW; } - @Override - public String toString() { return "Rock"; } -} - -public class RoShamBo1 { - static final int SIZE = 20; - private static Random rand = new Random(47); - public static Item newItem() { - switch(rand.nextInt(3)) { - default: - case 0: return new Scissors(); - case 1: return new Paper(); - case 2: return new Rock(); - } - } - public static void match(Item a, Item b) { - System.out.println( - a + " vs. " + b + ": " + a.compete(b)); - } - public static void main(String[] args) { - for(int i = 0; i < SIZE; i++) - match(newItem(), newItem()); - } -} -/* Output: -Rock vs. Rock: DRAW -Paper vs. Rock: WIN -Paper vs. Rock: WIN -Paper vs. Rock: WIN -Scissors vs. Paper: WIN -Scissors vs. Scissors: DRAW -Scissors vs. Paper: WIN -Rock vs. Paper: LOSE -Paper vs. Paper: DRAW -Rock vs. Paper: LOSE -Paper vs. Scissors: LOSE -Paper vs. Scissors: LOSE -Rock vs. Scissors: WIN -Rock vs. Paper: LOSE -Paper vs. Rock: WIN -Scissors vs. Paper: WIN -Paper vs. Scissors: LOSE -Paper vs. Scissors: LOSE -Paper vs. Scissors: LOSE -Paper vs. Scissors: LOSE -*/ diff --git a/code/enums/RoShamBo2.java b/code/enums/RoShamBo2.java deleted file mode 100644 index ec8ab25b..00000000 --- a/code/enums/RoShamBo2.java +++ /dev/null @@ -1,55 +0,0 @@ -// enums/RoShamBo2.java -// (c)2020 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. -// Switching one enum on another -// {java enums.RoShamBo2} -package enums; -import static enums.Outcome.*; - -public enum RoShamBo2 implements Competitor { - PAPER(DRAW, LOSE, WIN), - SCISSORS(WIN, DRAW, LOSE), - ROCK(LOSE, WIN, DRAW); - private Outcome vPAPER, vSCISSORS, vROCK; - RoShamBo2(Outcome paper, - Outcome scissors, Outcome rock) { - this.vPAPER = paper; - this.vSCISSORS = scissors; - this.vROCK = rock; - } - @Override - public Outcome compete(RoShamBo2 it) { - switch(it) { - default: - case PAPER: return vPAPER; - case SCISSORS: return vSCISSORS; - case ROCK: return vROCK; - } - } - public static void main(String[] args) { - RoShamBo.play(RoShamBo2.class, 20); - } -} -/* Output: -ROCK vs. ROCK: DRAW -SCISSORS vs. ROCK: LOSE -SCISSORS vs. ROCK: LOSE -SCISSORS vs. ROCK: LOSE -PAPER vs. SCISSORS: LOSE -PAPER vs. PAPER: DRAW -PAPER vs. SCISSORS: LOSE -ROCK vs. SCISSORS: WIN -SCISSORS vs. SCISSORS: DRAW -ROCK vs. SCISSORS: WIN -SCISSORS vs. PAPER: WIN -SCISSORS vs. PAPER: WIN -ROCK vs. PAPER: LOSE -ROCK vs. SCISSORS: WIN -SCISSORS vs. ROCK: LOSE -PAPER vs. SCISSORS: LOSE -SCISSORS vs. PAPER: WIN -SCISSORS vs. PAPER: WIN -SCISSORS vs. PAPER: WIN -SCISSORS vs. PAPER: WIN -*/ diff --git a/code/enums/RoShamBo3.java b/code/enums/RoShamBo3.java deleted file mode 100644 index ffcd2cf1..00000000 --- a/code/enums/RoShamBo3.java +++ /dev/null @@ -1,71 +0,0 @@ -// enums/RoShamBo3.java -// (c)2020 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. -// Using constant-specific methods -// {java enums.RoShamBo3} -package enums; -import static enums.Outcome.*; - -public enum RoShamBo3 implements Competitor { - PAPER { - @Override - public Outcome compete(RoShamBo3 it) { - switch(it) { - default: // To placate the compiler - case PAPER: return DRAW; - case SCISSORS: return LOSE; - case ROCK: return WIN; - } - } - }, - SCISSORS { - @Override - public Outcome compete(RoShamBo3 it) { - switch(it) { - default: - case PAPER: return WIN; - case SCISSORS: return DRAW; - case ROCK: return LOSE; - } - } - }, - ROCK { - @Override - public Outcome compete(RoShamBo3 it) { - switch(it) { - default: - case PAPER: return LOSE; - case SCISSORS: return WIN; - case ROCK: return DRAW; - } - } - }; - @Override - public abstract Outcome compete(RoShamBo3 it); - public static void main(String[] args) { - RoShamBo.play(RoShamBo3.class, 20); - } -} -/* Output: -ROCK vs. ROCK: DRAW -SCISSORS vs. ROCK: LOSE -SCISSORS vs. ROCK: LOSE -SCISSORS vs. ROCK: LOSE -PAPER vs. SCISSORS: LOSE -PAPER vs. PAPER: DRAW -PAPER vs. SCISSORS: LOSE -ROCK vs. SCISSORS: WIN -SCISSORS vs. SCISSORS: DRAW -ROCK vs. SCISSORS: WIN -SCISSORS vs. PAPER: WIN -SCISSORS vs. PAPER: WIN -ROCK vs. PAPER: LOSE -ROCK vs. SCISSORS: WIN -SCISSORS vs. ROCK: LOSE -PAPER vs. SCISSORS: LOSE -SCISSORS vs. PAPER: WIN -SCISSORS vs. PAPER: WIN -SCISSORS vs. PAPER: WIN -SCISSORS vs. PAPER: WIN -*/ diff --git a/code/enums/RoShamBo4.java b/code/enums/RoShamBo4.java deleted file mode 100644 index f0b473ae..00000000 --- a/code/enums/RoShamBo4.java +++ /dev/null @@ -1,57 +0,0 @@ -// enums/RoShamBo4.java -// (c)2020 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. -// {java enums.RoShamBo4} -package enums; - -public enum RoShamBo4 implements Competitor { - ROCK { - @Override - public Outcome compete(RoShamBo4 opponent) { - return compete(SCISSORS, opponent); - } - }, - SCISSORS { - @Override - public Outcome compete(RoShamBo4 opponent) { - return compete(PAPER, opponent); - } - }, - PAPER { - @Override - public Outcome compete(RoShamBo4 opponent) { - return compete(ROCK, opponent); - } - }; - Outcome compete(RoShamBo4 loser, RoShamBo4 opponent) { - return ((opponent == this) ? Outcome.DRAW - : ((opponent == loser) ? Outcome.WIN - : Outcome.LOSE)); - } - public static void main(String[] args) { - RoShamBo.play(RoShamBo4.class, 20); - } -} -/* Output: -PAPER vs. PAPER: DRAW -SCISSORS vs. PAPER: WIN -SCISSORS vs. PAPER: WIN -SCISSORS vs. PAPER: WIN -ROCK vs. SCISSORS: WIN -ROCK vs. ROCK: DRAW -ROCK vs. SCISSORS: WIN -PAPER vs. SCISSORS: LOSE -SCISSORS vs. SCISSORS: DRAW -PAPER vs. SCISSORS: LOSE -SCISSORS vs. ROCK: LOSE -SCISSORS vs. ROCK: LOSE -PAPER vs. ROCK: WIN -PAPER vs. SCISSORS: LOSE -SCISSORS vs. PAPER: WIN -ROCK vs. SCISSORS: WIN -SCISSORS vs. ROCK: LOSE -SCISSORS vs. ROCK: LOSE -SCISSORS vs. ROCK: LOSE -SCISSORS vs. ROCK: LOSE -*/ diff --git a/code/enums/RoShamBo5.java b/code/enums/RoShamBo5.java deleted file mode 100644 index 69885c01..00000000 --- a/code/enums/RoShamBo5.java +++ /dev/null @@ -1,59 +0,0 @@ -// enums/RoShamBo5.java -// (c)2020 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. -// Multiple dispatching using an EnumMap of EnumMaps -// {java enums.RoShamBo5} -package enums; -import java.util.*; -import static enums.Outcome.*; - -enum RoShamBo5 implements Competitor { - PAPER, SCISSORS, ROCK; - static EnumMap> - table = new EnumMap<>(RoShamBo5.class); - static { - for(RoShamBo5 it : RoShamBo5.values()) - table.put(it, new EnumMap<>(RoShamBo5.class)); - initRow(PAPER, DRAW, LOSE, WIN); - initRow(SCISSORS, WIN, DRAW, LOSE); - initRow(ROCK, LOSE, WIN, DRAW); - } - static void initRow(RoShamBo5 it, - Outcome vPAPER, Outcome vSCISSORS, Outcome vROCK) { - EnumMap row = - RoShamBo5.table.get(it); - row.put(RoShamBo5.PAPER, vPAPER); - row.put(RoShamBo5.SCISSORS, vSCISSORS); - row.put(RoShamBo5.ROCK, vROCK); - } - @Override - public Outcome compete(RoShamBo5 it) { - return table.get(this).get(it); - } - public static void main(String[] args) { - RoShamBo.play(RoShamBo5.class, 20); - } -} -/* Output: -ROCK vs. ROCK: DRAW -SCISSORS vs. ROCK: LOSE -SCISSORS vs. ROCK: LOSE -SCISSORS vs. ROCK: LOSE -PAPER vs. SCISSORS: LOSE -PAPER vs. PAPER: DRAW -PAPER vs. SCISSORS: LOSE -ROCK vs. SCISSORS: WIN -SCISSORS vs. SCISSORS: DRAW -ROCK vs. SCISSORS: WIN -SCISSORS vs. PAPER: WIN -SCISSORS vs. PAPER: WIN -ROCK vs. PAPER: LOSE -ROCK vs. SCISSORS: WIN -SCISSORS vs. ROCK: LOSE -PAPER vs. SCISSORS: LOSE -SCISSORS vs. PAPER: WIN -SCISSORS vs. PAPER: WIN -SCISSORS vs. PAPER: WIN -SCISSORS vs. PAPER: WIN -*/ diff --git a/code/enums/RoShamBo6.java b/code/enums/RoShamBo6.java deleted file mode 100644 index 164911d5..00000000 --- a/code/enums/RoShamBo6.java +++ /dev/null @@ -1,46 +0,0 @@ -// enums/RoShamBo6.java -// (c)2020 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. -// Enums using "tables" instead of multiple dispatch -// {java enums.RoShamBo6} -package enums; -import static enums.Outcome.*; - -enum RoShamBo6 implements Competitor { - PAPER, SCISSORS, ROCK; - private static Outcome[][] table = { - { DRAW, LOSE, WIN }, // PAPER - { WIN, DRAW, LOSE }, // SCISSORS - { LOSE, WIN, DRAW }, // ROCK - }; - @Override - public Outcome compete(RoShamBo6 other) { - return table[this.ordinal()][other.ordinal()]; - } - public static void main(String[] args) { - RoShamBo.play(RoShamBo6.class, 20); - } -} -/* Output: -ROCK vs. ROCK: DRAW -SCISSORS vs. ROCK: LOSE -SCISSORS vs. ROCK: LOSE -SCISSORS vs. ROCK: LOSE -PAPER vs. SCISSORS: LOSE -PAPER vs. PAPER: DRAW -PAPER vs. SCISSORS: LOSE -ROCK vs. SCISSORS: WIN -SCISSORS vs. SCISSORS: DRAW -ROCK vs. SCISSORS: WIN -SCISSORS vs. PAPER: WIN -SCISSORS vs. PAPER: WIN -ROCK vs. PAPER: LOSE -ROCK vs. SCISSORS: WIN -SCISSORS vs. ROCK: LOSE -PAPER vs. SCISSORS: LOSE -SCISSORS vs. PAPER: WIN -SCISSORS vs. PAPER: WIN -SCISSORS vs. PAPER: WIN -SCISSORS vs. PAPER: WIN -*/ diff --git a/code/enums/SecurityCategory.java b/code/enums/SecurityCategory.java deleted file mode 100644 index 884cb56a..00000000 --- a/code/enums/SecurityCategory.java +++ /dev/null @@ -1,46 +0,0 @@ -// enums/SecurityCategory.java -// (c)2020 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. -// More succinct subcategorization of enums -import onjava.*; - -enum SecurityCategory { - STOCK(Security.Stock.class), - BOND(Security.Bond.class); - Security[] values; - SecurityCategory(Class kind) { - values = kind.getEnumConstants(); - } - interface Security { - enum Stock implements Security { - SHORT, LONG, MARGIN - } - enum Bond implements Security { - MUNICIPAL, JUNK - } - } - public Security randomSelection() { - return Enums.random(values); - } - public static void main(String[] args) { - for(int i = 0; i < 10; i++) { - SecurityCategory category = - Enums.random(SecurityCategory.class); - System.out.println(category + ": " + - category.randomSelection()); - } - } -} -/* Output: -BOND: MUNICIPAL -BOND: MUNICIPAL -STOCK: MARGIN -STOCK: MARGIN -BOND: JUNK -STOCK: SHORT -STOCK: LONG -STOCK: LONG -BOND: MUNICIPAL -BOND: JUNK -*/ diff --git a/code/enums/SpaceShip.java b/code/enums/SpaceShip.java deleted file mode 100644 index 3623389e..00000000 --- a/code/enums/SpaceShip.java +++ /dev/null @@ -1,28 +0,0 @@ -// enums/SpaceShip.java -// (c)2020 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. -import java.util.stream.*; - -public enum SpaceShip { - SCOUT, CARGO, TRANSPORT, - CRUISER, BATTLESHIP, MOTHERSHIP; - @Override - public String toString() { - String id = name(); - String lower = id.substring(1).toLowerCase(); - return id.charAt(0) + lower; - } - public static void main(String[] args) { - Stream.of(values()) - .forEach(System.out::println); - } -} -/* Output: -Scout -Cargo -Transport -Cruiser -Battleship -Mothership -*/ diff --git a/code/enums/SpicinessEnum.java b/code/enums/SpicinessEnum.java deleted file mode 100644 index eef6f89a..00000000 --- a/code/enums/SpicinessEnum.java +++ /dev/null @@ -1,9 +0,0 @@ -// enums/SpicinessEnum.java -// (c)2020 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 enums; - -public enum SpicinessEnum { - NOT, MILD, MEDIUM, HOT, FLAMING -} diff --git a/code/enums/TrafficLight.java b/code/enums/TrafficLight.java deleted file mode 100644 index b018e02c..00000000 --- a/code/enums/TrafficLight.java +++ /dev/null @@ -1,44 +0,0 @@ -// enums/TrafficLight.java -// (c)2020 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. -// Enums in switch statements - -// Define an enum type: -enum Signal { GREEN, YELLOW, RED, } - -public class TrafficLight { - Signal color = Signal.RED; - public void change() { - switch(color) { - // Note you don't have to say Signal.RED - // in the case statement: - case RED: color = Signal.GREEN; - break; - case GREEN: color = Signal.YELLOW; - break; - case YELLOW: color = Signal.RED; - break; - } - } - @Override - public String toString() { - return "The traffic light is " + color; - } - public static void main(String[] args) { - TrafficLight t = new TrafficLight(); - for(int i = 0; i < 7; i++) { - System.out.println(t); - t.change(); - } - } -} -/* Output: -The traffic light is RED -The traffic light is GREEN -The traffic light is YELLOW -The traffic light is RED -The traffic light is GREEN -The traffic light is YELLOW -The traffic light is RED -*/ diff --git a/code/enums/UpcastEnum.java b/code/enums/UpcastEnum.java deleted file mode 100644 index a5df2a86..00000000 --- a/code/enums/UpcastEnum.java +++ /dev/null @@ -1,21 +0,0 @@ -// enums/UpcastEnum.java -// (c)2020 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. -// No values() method if you upcast an enum - -enum Search { HITHER, YON } - -public class UpcastEnum { - public static void main(String[] args) { - Search[] vals = Search.values(); - Enum e = Search.HITHER; // Upcast - // e.values(); // No values() in Enum - for(Enum en : e.getClass().getEnumConstants()) - System.out.println(en); - } -} -/* Output: -HITHER -YON -*/ diff --git a/code/enums/VendingMachine.java b/code/enums/VendingMachine.java deleted file mode 100644 index bc7d7c19..00000000 --- a/code/enums/VendingMachine.java +++ /dev/null @@ -1,183 +0,0 @@ -// enums/VendingMachine.java -// (c)2020 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. -// {java VendingMachine VendingMachineInput.txt} -import java.util.*; -import java.io.IOException; -import java.util.function.*; -import java.nio.file.*; -import java.util.stream.*; - -enum Category { - MONEY(Input.NICKEL, Input.DIME, - Input.QUARTER, Input.DOLLAR), - ITEM_SELECTION(Input.TOOTHPASTE, Input.CHIPS, - Input.SODA, Input.SOAP), - QUIT_TRANSACTION(Input.ABORT_TRANSACTION), - SHUT_DOWN(Input.STOP); - private Input[] values; - Category(Input... types) { values = types; } - private static EnumMap categories = - new EnumMap<>(Input.class); - static { - for(Category c : Category.class.getEnumConstants()) - for(Input type : c.values) - categories.put(type, c); - } - public static Category categorize(Input input) { - return categories.get(input); - } -} - -public class VendingMachine { - private static State state = State.RESTING; - private static int amount = 0; - private static Input selection = null; - enum StateDuration { TRANSIENT } // Tagging enum - enum State { - RESTING { - @Override - void next(Input input) { - switch(Category.categorize(input)) { - case MONEY: - amount += input.amount(); - state = ADDING_MONEY; - break; - case SHUT_DOWN: - state = TERMINAL; - default: - } - } - }, - ADDING_MONEY { - @Override - void next(Input input) { - switch(Category.categorize(input)) { - case MONEY: - amount += input.amount(); - break; - case ITEM_SELECTION: - selection = input; - if(amount < selection.amount()) - System.out.println( - "Insufficient money for " + selection); - else state = DISPENSING; - break; - case QUIT_TRANSACTION: - state = GIVING_CHANGE; - break; - case SHUT_DOWN: - state = TERMINAL; - default: - } - } - }, - DISPENSING(StateDuration.TRANSIENT) { - @Override - void next() { - System.out.println("here is your " + selection); - amount -= selection.amount(); - state = GIVING_CHANGE; - } - }, - GIVING_CHANGE(StateDuration.TRANSIENT) { - @Override - void next() { - if(amount > 0) { - System.out.println("Your change: " + amount); - amount = 0; - } - state = RESTING; - } - }, - TERMINAL {@Override - void output() { System.out.println("Halted"); } }; - private boolean isTransient = false; - State() {} - State(StateDuration trans) { isTransient = true; } - void next(Input input) { - throw new RuntimeException("Only call " + - "next(Input input) for non-transient states"); - } - void next() { - throw new RuntimeException( - "Only call next() for " + - "StateDuration.TRANSIENT states"); - } - void output() { System.out.println(amount); } - } - static void run(Supplier gen) { - while(state != State.TERMINAL) { - state.next(gen.get()); - while(state.isTransient) - state.next(); - state.output(); - } - } - public static void main(String[] args) { - Supplier gen = new RandomInputSupplier(); - if(args.length == 1) - gen = new FileInputSupplier(args[0]); - run(gen); - } -} - -// For a basic sanity check: -class RandomInputSupplier implements Supplier { - @Override - public Input get() { - return Input.randomSelection(); - } -} - -// Create Inputs from a file of ';'-separated strings: -class FileInputSupplier implements Supplier { - private Iterator input; - FileInputSupplier(String fileName) { - try { - input = Files.lines(Paths.get(fileName)) - .skip(1) // Skip the comment line - .flatMap(s -> Arrays.stream(s.split(";"))) - .map(String::trim) - .collect(Collectors.toList()) - .iterator(); - } catch(IOException e) { - throw new RuntimeException(e); - } - } - @Override - public Input get() { - if(!input.hasNext()) - return null; - return Enum.valueOf( - Input.class, input.next().trim()); - } -} -/* Output: -25 -50 -75 -here is your CHIPS -0 -100 -200 -here is your TOOTHPASTE -0 -25 -35 -Your change: 35 -0 -25 -35 -Insufficient money for SODA -35 -60 -70 -75 -Insufficient money for SODA -75 -Your change: 75 -0 -Halted -*/ diff --git a/code/enums/VendingMachineInput.txt b/code/enums/VendingMachineInput.txt deleted file mode 100644 index b39554f0..00000000 --- a/code/enums/VendingMachineInput.txt +++ /dev/null @@ -1,8 +0,0 @@ -// enums/VendingMachineInput.txt -QUARTER; QUARTER; QUARTER; CHIPS; -DOLLAR; DOLLAR; TOOTHPASTE; -QUARTER; DIME; ABORT_TRANSACTION; -QUARTER; DIME; SODA; -QUARTER; DIME; NICKEL; SODA; -ABORT_TRANSACTION; -STOP; diff --git a/code/enums/cartoons/EnumImplementation.java b/code/enums/cartoons/EnumImplementation.java deleted file mode 100644 index 58902e3f..00000000 --- a/code/enums/cartoons/EnumImplementation.java +++ /dev/null @@ -1,37 +0,0 @@ -// enums/cartoons/EnumImplementation.java -// (c)2020 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. -// An enum can implement an interface -// {java enums.cartoons.EnumImplementation} -package enums.cartoons; -import java.util.*; -import java.util.function.*; - -enum CartoonCharacter -implements Supplier { - SLAPPY, SPANKY, PUNCHY, - SILLY, BOUNCY, NUTTY, BOB; - private Random rand = - new Random(47); - @Override - public CartoonCharacter get() { - return values()[rand.nextInt(values().length)]; - } -} - -public class EnumImplementation { - public static void printNext(Supplier rg) { - System.out.print(rg.get() + ", "); - } - public static void main(String[] args) { - // Choose any instance: - CartoonCharacter cc = CartoonCharacter.BOB; - for(int i = 0; i < 10; i++) - printNext(cc); - } -} -/* Output: -BOB, PUNCHY, BOB, SPANKY, NUTTY, PUNCHY, SLAPPY, NUTTY, -NUTTY, SLAPPY, -*/ diff --git a/code/enums/menu/Course.java b/code/enums/menu/Course.java deleted file mode 100644 index 96481f1e..00000000 --- a/code/enums/menu/Course.java +++ /dev/null @@ -1,20 +0,0 @@ -// enums/menu/Course.java -// (c)2020 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 enums.menu; -import onjava.*; - -public enum Course { - APPETIZER(Food.Appetizer.class), - MAINCOURSE(Food.MainCourse.class), - DESSERT(Food.Dessert.class), - COFFEE(Food.Coffee.class); - private Food[] values; - private Course(Class kind) { - values = kind.getEnumConstants(); - } - public Food randomSelection() { - return Enums.random(values); - } -} diff --git a/code/enums/menu/Food.java b/code/enums/menu/Food.java deleted file mode 100644 index 4b97f69e..00000000 --- a/code/enums/menu/Food.java +++ /dev/null @@ -1,24 +0,0 @@ -// enums/menu/Food.java -// (c)2020 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. -// Subcategorization of enums within interfaces -package enums.menu; - -public interface Food { - enum Appetizer implements Food { - SALAD, SOUP, SPRING_ROLLS; - } - enum MainCourse implements Food { - LASAGNE, BURRITO, PAD_THAI, - LENTILS, HUMMOUS, VINDALOO; - } - enum Dessert implements Food { - TIRAMISU, GELATO, BLACK_FOREST_CAKE, - FRUIT, CREME_CARAMEL; - } - enum Coffee implements Food { - BLACK_COFFEE, DECAF_COFFEE, ESPRESSO, - LATTE, CAPPUCCINO, TEA, HERB_TEA; - } -} diff --git a/code/enums/menu/Meal.java b/code/enums/menu/Meal.java deleted file mode 100644 index 64bc496d..00000000 --- a/code/enums/menu/Meal.java +++ /dev/null @@ -1,45 +0,0 @@ -// enums/menu/Meal.java -// (c)2020 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. -// {java enums.menu.Meal} -package enums.menu; - -public class Meal { - public static void main(String[] args) { - for(int i = 0; i < 5; i++) { - for(Course course : Course.values()) { - Food food = course.randomSelection(); - System.out.println(food); - } - System.out.println("***"); - } - } -} -/* Output: -SPRING_ROLLS -VINDALOO -FRUIT -DECAF_COFFEE -*** -SOUP -VINDALOO -FRUIT -TEA -*** -SALAD -BURRITO -FRUIT -TEA -*** -SALAD -BURRITO -CREME_CARAMEL -LATTE -*** -SOUP -BURRITO -TIRAMISU -ESPRESSO -*** -*/ diff --git a/code/enums/menu/Meal2.java b/code/enums/menu/Meal2.java deleted file mode 100644 index df1b90a5..00000000 --- a/code/enums/menu/Meal2.java +++ /dev/null @@ -1,74 +0,0 @@ -// enums/menu/Meal2.java -// (c)2020 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. -// {java enums.menu.Meal2} -package enums.menu; -import onjava.*; - -public enum Meal2 { - APPETIZER(Food.Appetizer.class), - MAINCOURSE(Food.MainCourse.class), - DESSERT(Food.Dessert.class), - COFFEE(Food.Coffee.class); - private Food[] values; - private Meal2(Class kind) { - values = kind.getEnumConstants(); - } - public interface Food { - enum Appetizer implements Food { - SALAD, SOUP, SPRING_ROLLS; - } - enum MainCourse implements Food { - LASAGNE, BURRITO, PAD_THAI, - LENTILS, HUMMOUS, VINDALOO; - } - enum Dessert implements Food { - TIRAMISU, GELATO, BLACK_FOREST_CAKE, - FRUIT, CREME_CARAMEL; - } - enum Coffee implements Food { - BLACK_COFFEE, DECAF_COFFEE, ESPRESSO, - LATTE, CAPPUCCINO, TEA, HERB_TEA; - } - } - public Food randomSelection() { - return Enums.random(values); - } - public static void main(String[] args) { - for(int i = 0; i < 5; i++) { - for(Meal2 meal : Meal2.values()) { - Food food = meal.randomSelection(); - System.out.println(food); - } - System.out.println("***"); - } - } -} -/* Output: -SPRING_ROLLS -VINDALOO -FRUIT -DECAF_COFFEE -*** -SOUP -VINDALOO -FRUIT -TEA -*** -SALAD -BURRITO -FRUIT -TEA -*** -SALAD -BURRITO -CREME_CARAMEL -LATTE -*** -SOUP -BURRITO -TIRAMISU -ESPRESSO -*** -*/ diff --git a/code/enums/menu/TypeOfFood.java b/code/enums/menu/TypeOfFood.java deleted file mode 100644 index 5e59e78b..00000000 --- a/code/enums/menu/TypeOfFood.java +++ /dev/null @@ -1,16 +0,0 @@ -// enums/menu/TypeOfFood.java -// (c)2020 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. -// {java enums.menu.TypeOfFood} -package enums.menu; -import static enums.menu.Food.*; - -public class TypeOfFood { - public static void main(String[] args) { - Food food = Appetizer.SALAD; - food = MainCourse.LASAGNE; - food = Dessert.GELATO; - food = Coffee.CAPPUCCINO; - } -} diff --git a/code/equalshashcode/ComposedEquality.java b/code/equalshashcode/ComposedEquality.java deleted file mode 100644 index c224231c..00000000 --- a/code/equalshashcode/ComposedEquality.java +++ /dev/null @@ -1,66 +0,0 @@ -// equalshashcode/ComposedEquality.java -// (c)2020 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. -import java.util.*; - -class Part { - String ss; - double dd; - Part(String ss, double dd) { - this.ss = ss; - this.dd = dd; - } - @Override - public boolean equals(Object rval) { - return rval instanceof Part && - Objects.equals(ss, ((Part)rval).ss) && - Objects.equals(dd, ((Part)rval).dd); - } -} - -public class ComposedEquality extends SuccinctEquality { - Part part; - public ComposedEquality(int i, String s, double d) { - super(i, s, d); - part = new Part(s, d); - System.out.println("made 'ComposedEquality'"); - } - @Override - public boolean equals(Object rval) { - return rval instanceof ComposedEquality && - super.equals(rval) && - Objects.equals(part, - ((ComposedEquality)rval).part); - } - public static void main(String[] args) { - Equality.testAll( (i, s, d) -> - new ComposedEquality(i, s, d)); - } -} -/* Output: -made 'Equality' -made 'SuccinctEquality' -made 'ComposedEquality' -made 'Equality' -made 'SuccinctEquality' -made 'ComposedEquality' -made 'Equality' -made 'SuccinctEquality' -made 'ComposedEquality' --- Testing null -- -null instanceof Equality: false -Expected false, got false --- Testing same object -- -same object instanceof Equality: true -Expected true, got true --- Testing different type -- -different type instanceof Equality: false -Expected false, got false --- Testing same values -- -same values instanceof Equality: true -Expected true, got true --- Testing different values -- -different values instanceof Equality: true -Expected false, got false -*/ diff --git a/code/equalshashcode/CountedString.java b/code/equalshashcode/CountedString.java deleted file mode 100644 index 5a6ec5fa..00000000 --- a/code/equalshashcode/CountedString.java +++ /dev/null @@ -1,72 +0,0 @@ -// equalshashcode/CountedString.java -// (c)2020 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. -// Creating a good hashCode() -import java.util.*; - -public class CountedString { - private static List created = - new ArrayList<>(); - private String s; - private int id = 0; - public CountedString(String str) { - s = str; - created.add(s); - // id is the total number of instances - // of this String used by CountedString: - for(String s2 : created) - if(s2.equals(s)) - id++; - } - @Override - public String toString() { - return "String: " + s + " id: " + id + - " hashCode(): " + hashCode(); - } - @Override - public int hashCode() { - // The very simple approach: - // return s.hashCode() * id; - // Using Joshua Bloch's recipe: - int result = 17; - result = 37 * result + s.hashCode(); - result = 37 * result + id; - return result; - } - @Override - public boolean equals(Object o) { - return o instanceof CountedString && - Objects.equals(s, ((CountedString)o).s) && - Objects.equals(id, ((CountedString)o).id); - } - public static void main(String[] args) { - Map map = new HashMap<>(); - CountedString[] cs = new CountedString[5]; - for(int i = 0; i < cs.length; i++) { - cs[i] = new CountedString("hi"); - map.put(cs[i], i); // Autobox int to Integer - } - System.out.println(map); - for(CountedString cstring : cs) { - System.out.println("Looking up " + cstring); - System.out.println(map.get(cstring)); - } - } -} -/* Output: -{String: hi id: 4 hashCode(): 146450=3, String: hi id: -5 hashCode(): 146451=4, String: hi id: 2 hashCode(): -146448=1, String: hi id: 3 hashCode(): 146449=2, -String: hi id: 1 hashCode(): 146447=0} -Looking up String: hi id: 1 hashCode(): 146447 -0 -Looking up String: hi id: 2 hashCode(): 146448 -1 -Looking up String: hi id: 3 hashCode(): 146449 -2 -Looking up String: hi id: 4 hashCode(): 146450 -3 -Looking up String: hi id: 5 hashCode(): 146451 -4 -*/ diff --git a/code/equalshashcode/DefaultComparison.java b/code/equalshashcode/DefaultComparison.java deleted file mode 100644 index d855de36..00000000 --- a/code/equalshashcode/DefaultComparison.java +++ /dev/null @@ -1,24 +0,0 @@ -// equalshashcode/DefaultComparison.java -// (c)2020 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. - -class DefaultComparison { - private int i, j, k; - DefaultComparison(int i, int j, int k) { - this.i = i; - this.j = j; - this.k = k; - } - public static void main(String[] args) { - DefaultComparison - a = new DefaultComparison(1, 2, 3), - b = new DefaultComparison(1, 2, 3); - System.out.println(a == a); - System.out.println(a == b); - } -} -/* Output: -true -false -*/ diff --git a/code/equalshashcode/Equality.java b/code/equalshashcode/Equality.java deleted file mode 100644 index 6ab13e5e..00000000 --- a/code/equalshashcode/Equality.java +++ /dev/null @@ -1,77 +0,0 @@ -// equalshashcode/Equality.java -// (c)2020 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. -import java.util.*; - -public class Equality { - protected int i; - protected String s; - protected double d; - public Equality(int i, String s, double d) { - this.i = i; - this.s = s; - this.d = d; - System.out.println("made 'Equality'"); - } - @Override - public boolean equals(Object rval) { - if(rval == null) - return false; - if(rval == this) - return true; - if(!(rval instanceof Equality)) - return false; - Equality other = (Equality)rval; - if(!Objects.equals(i, other.i)) - return false; - if(!Objects.equals(s, other.s)) - return false; - if(!Objects.equals(d, other.d)) - return false; - return true; - } - public void - test(String descr, String expected, Object rval) { - System.out.format("-- Testing %s --%n" + - "%s instanceof Equality: %s%n" + - "Expected %s, got %s%n", - descr, descr, rval instanceof Equality, - expected, equals(rval)); - } - public static void testAll(EqualityFactory eqf) { - Equality - e = eqf.make(1, "Monty", 3.14), - eq = eqf.make(1, "Monty", 3.14), - neq = eqf.make(99, "Bob", 1.618); - e.test("null", "false", null); - e.test("same object", "true", e); - e.test("different type", - "false", Integer.valueOf(99)); - e.test("same values", "true", eq); - e.test("different values", "false", neq); - } - public static void main(String[] args) { - testAll( (i, s, d) -> new Equality(i, s, d)); - } -} -/* Output: -made 'Equality' -made 'Equality' -made 'Equality' --- Testing null -- -null instanceof Equality: false -Expected false, got false --- Testing same object -- -same object instanceof Equality: true -Expected true, got true --- Testing different type -- -different type instanceof Equality: false -Expected false, got false --- Testing same values -- -same values instanceof Equality: true -Expected true, got true --- Testing different values -- -different values instanceof Equality: true -Expected false, got false -*/ diff --git a/code/equalshashcode/EqualityFactory.java b/code/equalshashcode/EqualityFactory.java deleted file mode 100644 index 378b56b0..00000000 --- a/code/equalshashcode/EqualityFactory.java +++ /dev/null @@ -1,9 +0,0 @@ -// equalshashcode/EqualityFactory.java -// (c)2020 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. -import java.util.*; - -interface EqualityFactory { - Equality make(int i, String s, double d); -} diff --git a/code/equalshashcode/Groundhog.java b/code/equalshashcode/Groundhog.java deleted file mode 100644 index 55c77563..00000000 --- a/code/equalshashcode/Groundhog.java +++ /dev/null @@ -1,14 +0,0 @@ -// equalshashcode/Groundhog.java -// (c)2020 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. -// Looks plausible, but doesn't work as a HashMap key - -public class Groundhog { - protected int number; - public Groundhog(int n) { number = n; } - @Override - public String toString() { - return "Groundhog #" + number; - } -} diff --git a/code/equalshashcode/Groundhog2.java b/code/equalshashcode/Groundhog2.java deleted file mode 100644 index 5348d1e5..00000000 --- a/code/equalshashcode/Groundhog2.java +++ /dev/null @@ -1,19 +0,0 @@ -// equalshashcode/Groundhog2.java -// (c)2020 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. -// A class that's used as a key in a HashMap -// must override hashCode() and equals() -import java.util.*; - -public class Groundhog2 extends Groundhog { - public Groundhog2(int n) { super(n); } - @Override - public int hashCode() { return number; } - @Override - public boolean equals(Object o) { - return o instanceof Groundhog2 && - Objects.equals( - number, ((Groundhog2)o).number); - } -} diff --git a/code/equalshashcode/IndividualTest.java b/code/equalshashcode/IndividualTest.java deleted file mode 100644 index d8f50974..00000000 --- a/code/equalshashcode/IndividualTest.java +++ /dev/null @@ -1,31 +0,0 @@ -// equalshashcode/IndividualTest.java -// (c)2020 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. -import collections.MapOfList; -import typeinfo.pets.*; -import java.util.*; - -public class IndividualTest { - public static void main(String[] args) { - Set pets = new TreeSet<>(); - for(List lp : - MapOfList.petPeople.values()) - for(Pet p : lp) - pets.add(p); - pets.forEach(System.out::println); - } -} -/* Output: -Cat Elsie May -Cat Pinkola -Cat Shackleton -Cat Stanford -Cymric Molly -Dog Margrett -Mutt Spot -Pug Louie aka Louis Snorkelstein Dupree -Rat Fizzy -Rat Freckly -Rat Fuzzy -*/ diff --git a/code/equalshashcode/MapEntry.java b/code/equalshashcode/MapEntry.java deleted file mode 100644 index c6e28bf4..00000000 --- a/code/equalshashcode/MapEntry.java +++ /dev/null @@ -1,42 +0,0 @@ -// equalshashcode/MapEntry.java -// (c)2020 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. -// A simple Map.Entry for sample Map implementations -import java.util.*; - -public class MapEntry implements Map.Entry { - private K key; - private V value; - public MapEntry(K key, V value) { - this.key = key; - this.value = value; - } - @Override - public K getKey() { return key; } - @Override - public V getValue() { return value; } - @Override - public V setValue(V v) { - V result = value; - value = v; - return result; - } - @Override - public int hashCode() { - return Objects.hash(key, value); - } - @SuppressWarnings("unchecked") - @Override - public boolean equals(Object rval) { - return rval instanceof MapEntry && - Objects.equals(key, - ((MapEntry)rval).getKey()) && - Objects.equals(value, - ((MapEntry)rval).getValue()); - } - @Override - public String toString() { - return key + "=" + value; - } -} diff --git a/code/equalshashcode/Prediction.java b/code/equalshashcode/Prediction.java deleted file mode 100644 index c8ff9777..00000000 --- a/code/equalshashcode/Prediction.java +++ /dev/null @@ -1,15 +0,0 @@ -// equalshashcode/Prediction.java -// (c)2020 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. -// Predicting the weather -import java.util.*; - -public class Prediction { - private static Random rand = new Random(47); - @Override - public String toString() { - return rand.nextBoolean() ? - "Six more weeks of Winter!" : "Early Spring!"; - } -} diff --git a/code/equalshashcode/SimpleHashMap.java b/code/equalshashcode/SimpleHashMap.java deleted file mode 100644 index f82022a1..00000000 --- a/code/equalshashcode/SimpleHashMap.java +++ /dev/null @@ -1,90 +0,0 @@ -// equalshashcode/SimpleHashMap.java -// (c)2020 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. -// A demonstration hashed Map -import java.util.*; -import onjava.*; - -public -class SimpleHashMap extends AbstractMap { - // Choose a prime number for the hash table - // size, to achieve a uniform distribution: - static final int SIZE = 997; - // You can't have a physical array of generics, - // but you can upcast to one: - @SuppressWarnings("unchecked") - LinkedList>[] buckets = - new LinkedList[SIZE]; - @Override - public V put(K key, V value) { - V oldValue = null; - int index = Math.abs(key.hashCode()) % SIZE; - if(buckets[index] == null) - buckets[index] = new LinkedList<>(); - LinkedList> bucket = buckets[index]; - MapEntry pair = new MapEntry<>(key, value); - boolean found = false; - ListIterator> it = - bucket.listIterator(); - while(it.hasNext()) { - MapEntry iPair = it.next(); - if(iPair.getKey().equals(key)) { - oldValue = iPair.getValue(); - it.set(pair); // Replace old with new - found = true; - break; - } - } - if(!found) - buckets[index].add(pair); - return oldValue; - } - @Override - public V get(Object key) { - int index = Math.abs(key.hashCode()) % SIZE; - if(buckets[index] == null) return null; - for(MapEntry iPair : buckets[index]) - if(iPair.getKey().equals(key)) - return iPair.getValue(); - return null; - } - @Override - public Set> entrySet() { - Set> set= new HashSet<>(); - for(LinkedList> bucket : buckets) { - if(bucket == null) continue; - for(MapEntry mpair : bucket) - set.add(mpair); - } - return set; - } - public static void main(String[] args) { - SimpleHashMap m = - new SimpleHashMap<>(); - m.putAll(Countries.capitals(8)); - m.forEach((k, v) -> - System.out.println(k + "=" + v)); - System.out.println(m.get("BENIN")); - m.entrySet().forEach(System.out::println); - } -} -/* Output: -CAMEROON=Yaounde -ANGOLA=Luanda -BURKINA FASO=Ouagadougou -BURUNDI=Bujumbura -ALGERIA=Algiers -BENIN=Porto-Novo -CAPE VERDE=Praia -BOTSWANA=Gaberone -Porto-Novo -CAMEROON=Yaounde -ANGOLA=Luanda -BURKINA FASO=Ouagadougou -BURUNDI=Bujumbura -ALGERIA=Algiers -BENIN=Porto-Novo -CAPE VERDE=Praia -BOTSWANA=Gaberone -*/ diff --git a/code/equalshashcode/SlowMap.java b/code/equalshashcode/SlowMap.java deleted file mode 100644 index 63f17092..00000000 --- a/code/equalshashcode/SlowMap.java +++ /dev/null @@ -1,64 +0,0 @@ -// equalshashcode/SlowMap.java -// (c)2020 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. -// A Map implemented with ArrayLists -import java.util.*; -import onjava.*; - -public class SlowMap extends AbstractMap { - private List keys = new ArrayList<>(); - private List values = new ArrayList<>(); - @Override - public V put(K key, V value) { - V oldValue = get(key); // The old value or null - if(!keys.contains(key)) { - keys.add(key); - values.add(value); - } else - values.set(keys.indexOf(key), value); - return oldValue; - } - @Override - public V get(Object key) { // key: type Object, not K - if(!keys.contains(key)) - return null; - return values.get(keys.indexOf(key)); - } - @Override - public Set> entrySet() { - Set> set= new HashSet<>(); - Iterator ki = keys.iterator(); - Iterator vi = values.iterator(); - while(ki.hasNext()) - set.add(new MapEntry<>(ki.next(), vi.next())); - return set; - } - public static void main(String[] args) { - SlowMap m= new SlowMap<>(); - m.putAll(Countries.capitals(8)); - m.forEach((k, v) -> - System.out.println(k + "=" + v)); - System.out.println(m.get("BENIN")); - m.entrySet().forEach(System.out::println); - } -} -/* Output: -CAMEROON=Yaounde -ANGOLA=Luanda -BURKINA FASO=Ouagadougou -BURUNDI=Bujumbura -ALGERIA=Algiers -BENIN=Porto-Novo -CAPE VERDE=Praia -BOTSWANA=Gaberone -Porto-Novo -CAMEROON=Yaounde -ANGOLA=Luanda -BURKINA FASO=Ouagadougou -BURUNDI=Bujumbura -ALGERIA=Algiers -BENIN=Porto-Novo -CAPE VERDE=Praia -BOTSWANA=Gaberone -*/ diff --git a/code/equalshashcode/SpringDetector.java b/code/equalshashcode/SpringDetector.java deleted file mode 100644 index 9b41bd3e..00000000 --- a/code/equalshashcode/SpringDetector.java +++ /dev/null @@ -1,62 +0,0 @@ -// equalshashcode/SpringDetector.java -// (c)2020 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 will the weather be? -import java.util.*; -import java.util.stream.*; -import java.util.function.*; -import java.lang.reflect.*; - -public class SpringDetector { - public static - void detectSpring(Class type) { - try { - Constructor ghog = - type.getConstructor(int.class); - Map map = - IntStream.range(0, 10) - .mapToObj(i -> { - try { - return ghog.newInstance(i); - } catch(Exception e) { - throw new RuntimeException(e); - } - }) - .collect(Collectors.toMap( - Function.identity(), - gh -> new Prediction())); - map.forEach((k, v) -> - System.out.println(k + ": " + v)); - Groundhog gh = ghog.newInstance(3); - System.out.println( - "Looking up prediction for " + gh); - if(map.containsKey(gh)) - System.out.println(map.get(gh)); - else - System.out.println("Key not found: " + gh); - } catch(NoSuchMethodException | - IllegalAccessException | - InvocationTargetException | - InstantiationException e) { - throw new RuntimeException(e); - } - } - public static void main(String[] args) { - detectSpring(Groundhog.class); - } -} -/* Output: -Groundhog #3: Six more weeks of Winter! -Groundhog #0: Early Spring! -Groundhog #8: Six more weeks of Winter! -Groundhog #6: Early Spring! -Groundhog #4: Early Spring! -Groundhog #2: Six more weeks of Winter! -Groundhog #1: Early Spring! -Groundhog #9: Early Spring! -Groundhog #5: Six more weeks of Winter! -Groundhog #7: Six more weeks of Winter! -Looking up prediction for Groundhog #3 -Key not found: Groundhog #3 -*/ diff --git a/code/equalshashcode/SpringDetector2.java b/code/equalshashcode/SpringDetector2.java deleted file mode 100644 index 1e136e47..00000000 --- a/code/equalshashcode/SpringDetector2.java +++ /dev/null @@ -1,25 +0,0 @@ -// equalshashcode/SpringDetector2.java -// (c)2020 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. -// A working key - -public class SpringDetector2 { - public static void main(String[] args) { - SpringDetector.detectSpring(Groundhog2.class); - } -} -/* Output: -Groundhog #0: Six more weeks of Winter! -Groundhog #1: Early Spring! -Groundhog #2: Six more weeks of Winter! -Groundhog #3: Early Spring! -Groundhog #4: Early Spring! -Groundhog #5: Six more weeks of Winter! -Groundhog #6: Early Spring! -Groundhog #7: Early Spring! -Groundhog #8: Six more weeks of Winter! -Groundhog #9: Six more weeks of Winter! -Looking up prediction for Groundhog #3 -Early Spring! -*/ diff --git a/code/equalshashcode/StringHashCode.java b/code/equalshashcode/StringHashCode.java deleted file mode 100644 index 222fa612..00000000 --- a/code/equalshashcode/StringHashCode.java +++ /dev/null @@ -1,16 +0,0 @@ -// equalshashcode/StringHashCode.java -// (c)2020 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. - -public class StringHashCode { - public static void main(String[] args) { - String[] hellos = "Hello Hello".split(" "); - System.out.println(hellos[0].hashCode()); - System.out.println(hellos[1].hashCode()); - } -} -/* Output: -69609650 -69609650 -*/ diff --git a/code/equalshashcode/SubtypeEquality.java b/code/equalshashcode/SubtypeEquality.java deleted file mode 100644 index 90320c88..00000000 --- a/code/equalshashcode/SubtypeEquality.java +++ /dev/null @@ -1,60 +0,0 @@ -// equalshashcode/SubtypeEquality.java -// (c)2020 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. -import java.util.*; - -enum Size { SMALL, MEDIUM, LARGE } - -class Animal { - private static int counter = 0; - private final int id = counter++; - private final String name; - private final Size size; - Animal(String name, Size size) { - this.name = name; - this.size = size; - } - @Override - public boolean equals(Object rval) { - return rval instanceof Animal && - // Objects.equals(id, ((Animal)rval).id) && // [1] - Objects.equals(name, ((Animal)rval).name) && - Objects.equals(size, ((Animal)rval).size); - } - @Override - public int hashCode() { - return Objects.hash(name, size); - // return Objects.hash(name, size, id); // [2] - } - @Override - public String toString() { - return String.format("%s[%d]: %s %s %x", - getClass().getSimpleName(), id, - name, size, hashCode()); - } -} - -class Dog extends Animal { - Dog(String name, Size size) { - super(name, size); - } -} - -class Pig extends Animal { - Pig(String name, Size size) { - super(name, size); - } -} - -public class SubtypeEquality { - public static void main(String[] args) { - Set pets = new HashSet<>(); - pets.add(new Dog("Ralph", Size.MEDIUM)); - pets.add(new Pig("Ralph", Size.MEDIUM)); - pets.forEach(System.out::println); - } -} -/* Output: -Dog[0]: Ralph MEDIUM a752aeee -*/ diff --git a/code/equalshashcode/SubtypeEquality2.java b/code/equalshashcode/SubtypeEquality2.java deleted file mode 100644 index c0ac5057..00000000 --- a/code/equalshashcode/SubtypeEquality2.java +++ /dev/null @@ -1,40 +0,0 @@ -// equalshashcode/SubtypeEquality2.java -// (c)2020 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. -import java.util.*; - -class Dog2 extends Animal { - Dog2(String name, Size size) { - super(name, size); - } - @Override - public boolean equals(Object rval) { - return rval instanceof Dog2 && - super.equals(rval); - } -} - -class Pig2 extends Animal { - Pig2(String name, Size size) { - super(name, size); - } - @Override - public boolean equals(Object rval) { - return rval instanceof Pig2 && - super.equals(rval); - } -} - -public class SubtypeEquality2 { - public static void main(String[] args) { - Set pets = new HashSet<>(); - pets.add(new Dog2("Ralph", Size.MEDIUM)); - pets.add(new Pig2("Ralph", Size.MEDIUM)); - pets.forEach(System.out::println); - } -} -/* Output: -Dog2[0]: Ralph MEDIUM a752aeee -Pig2[1]: Ralph MEDIUM a752aeee -*/ diff --git a/code/equalshashcode/SuccinctEquality.java b/code/equalshashcode/SuccinctEquality.java deleted file mode 100644 index 55a0d8de..00000000 --- a/code/equalshashcode/SuccinctEquality.java +++ /dev/null @@ -1,46 +0,0 @@ -// equalshashcode/SuccinctEquality.java -// (c)2020 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. -import java.util.*; - -public class SuccinctEquality extends Equality { - public SuccinctEquality(int i, String s, double d) { - super(i, s, d); - System.out.println("made 'SuccinctEquality'"); - } - @Override - public boolean equals(Object rval) { - return rval instanceof SuccinctEquality && - Objects.equals(i, ((SuccinctEquality)rval).i) && - Objects.equals(s, ((SuccinctEquality)rval).s) && - Objects.equals(d, ((SuccinctEquality)rval).d); - } - public static void main(String[] args) { - Equality.testAll( (i, s, d) -> - new SuccinctEquality(i, s, d)); - } -} -/* Output: -made 'Equality' -made 'SuccinctEquality' -made 'Equality' -made 'SuccinctEquality' -made 'Equality' -made 'SuccinctEquality' --- Testing null -- -null instanceof Equality: false -Expected false, got false --- Testing same object -- -same object instanceof Equality: true -Expected true, got true --- Testing different type -- -different type instanceof Equality: false -Expected false, got false --- Testing same values -- -same values instanceof Equality: true -Expected true, got true --- Testing different values -- -different values instanceof Equality: true -Expected false, got false -*/ diff --git a/code/exceptions/AlwaysFinally.java b/code/exceptions/AlwaysFinally.java deleted file mode 100644 index bb2270f7..00000000 --- a/code/exceptions/AlwaysFinally.java +++ /dev/null @@ -1,33 +0,0 @@ -// exceptions/AlwaysFinally.java -// (c)2020 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. -// Finally is always executed - -class FourException extends Exception {} - -public class AlwaysFinally { - public static void main(String[] args) { - System.out.println("Entering first try block"); - try { - System.out.println("Entering second try block"); - try { - throw new FourException(); - } finally { - System.out.println("finally in 2nd try block"); - } - } catch(FourException e) { - System.out.println( - "Caught FourException in 1st try block"); - } finally { - System.out.println("finally in 1st try block"); - } - } -} -/* Output: -Entering first try block -Entering second try block -finally in 2nd try block -Caught FourException in 1st try block -finally in 1st try block -*/ diff --git a/code/exceptions/AutoCloseableDetails.java b/code/exceptions/AutoCloseableDetails.java deleted file mode 100644 index 24a22e9d..00000000 --- a/code/exceptions/AutoCloseableDetails.java +++ /dev/null @@ -1,33 +0,0 @@ -// exceptions/AutoCloseableDetails.java -// (c)2020 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. - -class Reporter implements AutoCloseable { - String name = getClass().getSimpleName(); - Reporter() { - System.out.println("Creating " + name); - } - public void close() { - System.out.println("Closing " + name); - } -} - -class First extends Reporter {} -class Second extends Reporter {} - -public class AutoCloseableDetails { - public static void main(String[] args) { - try( - First f = new First(); - Second s = new Second() - ) { - } - } -} -/* Output: -Creating First -Creating Second -Closing Second -Closing First -*/ diff --git a/code/exceptions/BodyException.java b/code/exceptions/BodyException.java deleted file mode 100644 index 3e907f8a..00000000 --- a/code/exceptions/BodyException.java +++ /dev/null @@ -1,32 +0,0 @@ -// exceptions/BodyException.java -// (c)2020 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. - -class Third extends Reporter {} - -public class BodyException { - public static void main(String[] args) { - try( - First f = new First(); - Second s2 = new Second() - ) { - System.out.println("In body"); - Third t = new Third(); - new SecondExcept(); - System.out.println("End of body"); - } catch(CE e) { - System.out.println("Caught: " + e); - } - } -} -/* Output: -Creating First -Creating Second -In body -Creating Third -Creating SecondExcept -Closing Second -Closing First -Caught: CE -*/ diff --git a/code/exceptions/Cleanup.java b/code/exceptions/Cleanup.java deleted file mode 100644 index 3d072304..00000000 --- a/code/exceptions/Cleanup.java +++ /dev/null @@ -1,30 +0,0 @@ -// exceptions/Cleanup.java -// (c)2020 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. -// Guaranteeing proper cleanup of a resource - -public class Cleanup { - public static void main(String[] args) { - try { - InputFile in = new InputFile("Cleanup.java"); - try { - String s; - int i = 1; - while((s = in.getLine()) != null) - ; // Perform line-by-line processing here... - } catch(Exception e) { - System.out.println("Caught Exception in main"); - e.printStackTrace(System.out); - } finally { - in.dispose(); - } - } catch(Exception e) { - System.out.println( - "InputFile construction failed"); - } - } -} -/* Output: -dispose() successful -*/ diff --git a/code/exceptions/CleanupIdiom.java b/code/exceptions/CleanupIdiom.java deleted file mode 100644 index e8dd62c4..00000000 --- a/code/exceptions/CleanupIdiom.java +++ /dev/null @@ -1,72 +0,0 @@ -// exceptions/CleanupIdiom.java -// (c)2020 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. -// Disposable objects must be followed by a try-finally - -class NeedsCleanup { // Construction can't fail - private static long counter = 1; - private final long id = counter++; - public void dispose() { - System.out.println( - "NeedsCleanup " + id + " disposed"); - } -} - -class ConstructionException extends Exception {} - -class NeedsCleanup2 extends NeedsCleanup { - // Construction can fail: - NeedsCleanup2() throws ConstructionException {} -} - -public class CleanupIdiom { - public static void main(String[] args) { - // [1]: - NeedsCleanup nc1 = new NeedsCleanup(); - try { - // ... - } finally { - nc1.dispose(); - } - - // [2]: - // If construction cannot fail, - // you can group objects: - NeedsCleanup nc2 = new NeedsCleanup(); - NeedsCleanup nc3 = new NeedsCleanup(); - try { - // ... - } finally { - nc3.dispose(); // Reverse order of construction - nc2.dispose(); - } - - // [3]: - // If construction can fail you must guard each one: - try { - NeedsCleanup2 nc4 = new NeedsCleanup2(); - try { - NeedsCleanup2 nc5 = new NeedsCleanup2(); - try { - // ... - } finally { - nc5.dispose(); - } - } catch(ConstructionException e) { // nc5 const. - System.out.println(e); - } finally { - nc4.dispose(); - } - } catch(ConstructionException e) { // nc4 const. - System.out.println(e); - } - } -} -/* Output: -NeedsCleanup 1 disposed -NeedsCleanup 3 disposed -NeedsCleanup 2 disposed -NeedsCleanup 5 disposed -NeedsCleanup 4 disposed -*/ diff --git a/code/exceptions/CloseExceptions.java b/code/exceptions/CloseExceptions.java deleted file mode 100644 index 4309a888..00000000 --- a/code/exceptions/CloseExceptions.java +++ /dev/null @@ -1,48 +0,0 @@ -// exceptions/CloseExceptions.java -// (c)2020 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. - -class CloseException extends Exception {} - -class Reporter2 implements AutoCloseable { - String name = getClass().getSimpleName(); - Reporter2() { - System.out.println("Creating " + name); - } - public void close() throws CloseException { - System.out.println("Closing " + name); - } -} - -class Closer extends Reporter2 { - @Override - public void close() throws CloseException { - super.close(); - throw new CloseException(); - } -} - -public class CloseExceptions { - public static void main(String[] args) { - try( - First f = new First(); - Closer c = new Closer(); - Second s = new Second() - ) { - System.out.println("In body"); - } catch(CloseException e) { - System.out.println("Caught: " + e); - } - } -} -/* Output: -Creating First -Creating Closer -Creating Second -In body -Closing Second -Closing Closer -Closing First -Caught: CloseException -*/ diff --git a/code/exceptions/ConstructorException.java b/code/exceptions/ConstructorException.java deleted file mode 100644 index 54eaaba3..00000000 --- a/code/exceptions/ConstructorException.java +++ /dev/null @@ -1,33 +0,0 @@ -// exceptions/ConstructorException.java -// (c)2020 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. - -class CE extends Exception {} - -class SecondExcept extends Reporter { - SecondExcept() throws CE { - super(); - throw new CE(); - } -} - -public class ConstructorException { - public static void main(String[] args) { - try( - First f = new First(); - SecondExcept s = new SecondExcept(); - Second s2 = new Second() - ) { - System.out.println("In body"); - } catch(CE e) { - System.out.println("Caught: " + e); - } - } -} -/* Output: -Creating First -Creating SecondExcept -Closing First -Caught: CE -*/ diff --git a/code/exceptions/DynamicFields.java b/code/exceptions/DynamicFields.java deleted file mode 100644 index da3b9617..00000000 --- a/code/exceptions/DynamicFields.java +++ /dev/null @@ -1,130 +0,0 @@ -// exceptions/DynamicFields.java -// (c)2020 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. -// A Class that dynamically adds fields to itself to -// demonstrate exception chaining - -class DynamicFieldsException extends Exception {} - -public class DynamicFields { - private Object[][] fields; - public DynamicFields(int initialSize) { - fields = new Object[initialSize][2]; - for(int i = 0; i < initialSize; i++) - fields[i] = new Object[] { null, null }; - } - @Override - public String toString() { - StringBuilder result = new StringBuilder(); - for(Object[] obj : fields) { - result.append(obj[0]); - result.append(": "); - result.append(obj[1]); - result.append("\n"); - } - return result.toString(); - } - private int hasField(String id) { - for(int i = 0; i < fields.length; i++) - if(id.equals(fields[i][0])) - return i; - return -1; - } - private int getFieldNumber(String id) - throws NoSuchFieldException { - int fieldNum = hasField(id); - if(fieldNum == -1) - throw new NoSuchFieldException(); - return fieldNum; - } - private int makeField(String id) { - for(int i = 0; i < fields.length; i++) - if(fields[i][0] == null) { - fields[i][0] = id; - return i; - } - // No empty fields. Add one: - Object[][] tmp = new Object[fields.length + 1][2]; - for(int i = 0; i < fields.length; i++) - tmp[i] = fields[i]; - for(int i = fields.length; i < tmp.length; i++) - tmp[i] = new Object[] { null, null }; - fields = tmp; - // Recursive call with expanded fields: - return makeField(id); - } - public Object - getField(String id) throws NoSuchFieldException { - return fields[getFieldNumber(id)][1]; - } - public Object setField(String id, Object value) - throws DynamicFieldsException { - if(value == null) { - // Most exceptions don't have a "cause" - // constructor. In these cases you must use - // initCause(), available in all - // Throwable subclasses. - DynamicFieldsException dfe = - new DynamicFieldsException(); - dfe.initCause(new NullPointerException()); - throw dfe; - } - int fieldNumber = hasField(id); - if(fieldNumber == -1) - fieldNumber = makeField(id); - Object result = null; - try { - result = getField(id); // Get old value - } catch(NoSuchFieldException e) { - // Use constructor that takes "cause": - throw new RuntimeException(e); - } - fields[fieldNumber][1] = value; - return result; - } - public static void main(String[] args) { - DynamicFields df = new DynamicFields(3); - System.out.println(df); - try { - df.setField("d", "A value for d"); - df.setField("number", 47); - df.setField("number2", 48); - System.out.println(df); - df.setField("d", "A new value for d"); - df.setField("number3", 11); - System.out.println("df: " + df); - System.out.println("df.getField(\"d\") : " - + df.getField("d")); - Object field = - df.setField("d", null); // Exception - } catch(NoSuchFieldException | - DynamicFieldsException e) { - e.printStackTrace(System.out); - } - } -} -/* Output: -null: null -null: null -null: null - -d: A value for d -number: 47 -number2: 48 - -df: d: A new value for d -number: 47 -number2: 48 -number3: 11 - -df.getField("d") : A new value for d -DynamicFieldsException - at -DynamicFields.setField(DynamicFields.java:65) - at DynamicFields.main(DynamicFields.java:97) -Caused by: java.lang.NullPointerException - at -DynamicFields.setField(DynamicFields.java:67) - ... 1 more -*/ diff --git a/code/exceptions/ExceptionMethods.java b/code/exceptions/ExceptionMethods.java deleted file mode 100644 index bd6e8259..00000000 --- a/code/exceptions/ExceptionMethods.java +++ /dev/null @@ -1,32 +0,0 @@ -// exceptions/ExceptionMethods.java -// (c)2020 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. -// Demonstrating the Exception Methods - -public class ExceptionMethods { - public static void main(String[] args) { - try { - throw new Exception("My Exception"); - } catch(Exception e) { - System.out.println("Caught Exception"); - System.out.println( - "getMessage():" + e.getMessage()); - System.out.println("getLocalizedMessage():" + - e.getLocalizedMessage()); - System.out.println("toString():" + e); - System.out.println("printStackTrace():"); - e.printStackTrace(System.out); - } - } -} -/* Output: -Caught Exception -getMessage():My Exception -getLocalizedMessage():My Exception -toString():java.lang.Exception: My Exception -printStackTrace(): -java.lang.Exception: My Exception - at -ExceptionMethods.main(ExceptionMethods.java:7) -*/ diff --git a/code/exceptions/ExceptionSilencer.java b/code/exceptions/ExceptionSilencer.java deleted file mode 100644 index e418e9de..00000000 --- a/code/exceptions/ExceptionSilencer.java +++ /dev/null @@ -1,16 +0,0 @@ -// exceptions/ExceptionSilencer.java -// (c)2020 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. - -public class ExceptionSilencer { - public static void main(String[] args) { - try { - throw new RuntimeException(); - } finally { - // Using 'return' inside the finally block - // will silence any thrown exception. - return; - } - } -} diff --git a/code/exceptions/ExtraFeatures.java b/code/exceptions/ExtraFeatures.java deleted file mode 100644 index 8aa922af..00000000 --- a/code/exceptions/ExtraFeatures.java +++ /dev/null @@ -1,72 +0,0 @@ -// exceptions/ExtraFeatures.java -// (c)2020 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. -// Further embellishment of exception classes - -class MyException2 extends Exception { - private int x; - MyException2() {} - MyException2(String msg) { super(msg); } - MyException2(String msg, int x) { - super(msg); - this.x = x; - } - public int val() { return x; } - @Override - public String getMessage() { - return "Detail Message: "+ x - + " "+ super.getMessage(); - } -} - -public class ExtraFeatures { - public static void f() throws MyException2 { - System.out.println( - "Throwing MyException2 from f()"); - throw new MyException2(); - } - public static void g() throws MyException2 { - System.out.println( - "Throwing MyException2 from g()"); - throw new MyException2("Originated in g()"); - } - public static void h() throws MyException2 { - System.out.println( - "Throwing MyException2 from h()"); - throw new MyException2("Originated in h()", 47); - } - public static void main(String[] args) { - try { - f(); - } catch(MyException2 e) { - e.printStackTrace(System.out); - } - try { - g(); - } catch(MyException2 e) { - e.printStackTrace(System.out); - } - try { - h(); - } catch(MyException2 e) { - e.printStackTrace(System.out); - System.out.println("e.val() = " + e.val()); - } - } -} -/* Output: -Throwing MyException2 from f() -MyException2: Detail Message: 0 null - at ExtraFeatures.f(ExtraFeatures.java:24) - at ExtraFeatures.main(ExtraFeatures.java:38) -Throwing MyException2 from g() -MyException2: Detail Message: 0 Originated in g() - at ExtraFeatures.g(ExtraFeatures.java:29) - at ExtraFeatures.main(ExtraFeatures.java:43) -Throwing MyException2 from h() -MyException2: Detail Message: 47 Originated in h() - at ExtraFeatures.h(ExtraFeatures.java:34) - at ExtraFeatures.main(ExtraFeatures.java:48) -e.val() = 47 -*/ diff --git a/code/exceptions/FinallyWorks.java b/code/exceptions/FinallyWorks.java deleted file mode 100644 index fc4fec0a..00000000 --- a/code/exceptions/FinallyWorks.java +++ /dev/null @@ -1,32 +0,0 @@ -// exceptions/FinallyWorks.java -// (c)2020 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. -// The finally clause is always executed - -class ThreeException extends Exception {} - -public class FinallyWorks { - static int count = 0; - public static void main(String[] args) { - while(true) { - try { - // Post-increment is zero first time: - if(count++ == 0) - throw new ThreeException(); - System.out.println("No exception"); - } catch(ThreeException e) { - System.out.println("ThreeException"); - } finally { - System.out.println("In finally clause"); - if(count == 2) break; // out of "while" - } - } - } -} -/* Output: -ThreeException -In finally clause -No exception -In finally clause -*/ diff --git a/code/exceptions/FullConstructors.java b/code/exceptions/FullConstructors.java deleted file mode 100644 index f5b4c9ff..00000000 --- a/code/exceptions/FullConstructors.java +++ /dev/null @@ -1,44 +0,0 @@ -// exceptions/FullConstructors.java -// (c)2020 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. - -class MyException extends Exception { - MyException() {} - MyException(String msg) { super(msg); } -} - -public class FullConstructors { - public static void f() throws MyException { - System.out.println("Throwing MyException from f()"); - throw new MyException(); - } - public static void g() throws MyException { - System.out.println("Throwing MyException from g()"); - throw new MyException("Originated in g()"); - } - public static void main(String[] args) { - try { - f(); - } catch(MyException e) { - e.printStackTrace(System.out); - } - try { - g(); - } catch(MyException e) { - e.printStackTrace(System.out); - } - } -} -/* Output: -Throwing MyException from f() -MyException - at FullConstructors.f(FullConstructors.java:11) - at -FullConstructors.main(FullConstructors.java:19) -Throwing MyException from g() -MyException: Originated in g() - at FullConstructors.g(FullConstructors.java:15) - at -FullConstructors.main(FullConstructors.java:24) -*/ diff --git a/code/exceptions/Human.java b/code/exceptions/Human.java deleted file mode 100644 index 7ee7dcaa..00000000 --- a/code/exceptions/Human.java +++ /dev/null @@ -1,31 +0,0 @@ -// exceptions/Human.java -// (c)2020 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. -// Catching exception hierarchies - -class Annoyance extends Exception {} -class Sneeze extends Annoyance {} - -public class Human { - public static void main(String[] args) { - // Catch the exact type: - try { - throw new Sneeze(); - } catch(Sneeze s) { - System.out.println("Caught Sneeze"); - } catch(Annoyance a) { - System.out.println("Caught Annoyance"); - } - // Catch the base type: - try { - throw new Sneeze(); - } catch(Annoyance a) { - System.out.println("Caught Annoyance"); - } - } -} -/* Output: -Caught Sneeze -Caught Annoyance -*/ diff --git a/code/exceptions/InheritingExceptions.java b/code/exceptions/InheritingExceptions.java deleted file mode 100644 index abb80c3b..00000000 --- a/code/exceptions/InheritingExceptions.java +++ /dev/null @@ -1,28 +0,0 @@ -// exceptions/InheritingExceptions.java -// (c)2020 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. -// Creating your own exceptions - -class SimpleException extends Exception {} - -public class InheritingExceptions { - public void f() throws SimpleException { - System.out.println( - "Throw SimpleException from f()"); - throw new SimpleException(); - } - public static void main(String[] args) { - InheritingExceptions sed = - new InheritingExceptions(); - try { - sed.f(); - } catch(SimpleException e) { - System.out.println("Caught it!"); - } - } -} -/* Output: -Throw SimpleException from f() -Caught it! -*/ diff --git a/code/exceptions/InputFile.java b/code/exceptions/InputFile.java deleted file mode 100644 index 5c269851..00000000 --- a/code/exceptions/InputFile.java +++ /dev/null @@ -1,47 +0,0 @@ -// exceptions/InputFile.java -// (c)2020 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. -// Paying attention to exceptions in constructors -import java.io.*; - -public class InputFile { - private BufferedReader in; - public InputFile(String fname) throws Exception { - try { - in = new BufferedReader(new FileReader(fname)); - // Other code that might throw exceptions - } catch(FileNotFoundException e) { - System.out.println("Could not open " + fname); - // Wasn't open, so don't close it - throw e; - } catch(Exception e) { - // All other exceptions must close it - try { - in.close(); - } catch(IOException e2) { - System.out.println("in.close() unsuccessful"); - } - throw e; // Rethrow - } finally { - // Don't close it here!!! - } - } - public String getLine() { - String s; - try { - s = in.readLine(); - } catch(IOException e) { - throw new RuntimeException("readLine() failed"); - } - return s; - } - public void dispose() { - try { - in.close(); - System.out.println("dispose() successful"); - } catch(IOException e2) { - throw new RuntimeException("in.close() failed"); - } - } -} diff --git a/code/exceptions/InputFile2.java b/code/exceptions/InputFile2.java deleted file mode 100644 index 74a68c3f..00000000 --- a/code/exceptions/InputFile2.java +++ /dev/null @@ -1,28 +0,0 @@ -// exceptions/InputFile2.java -// (c)2020 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. -import java.io.*; -import java.nio.file.*; -import java.util.stream.*; - -public class InputFile2 { - private String fname; - public InputFile2(String fname) { - this.fname = fname; - } - public - Stream getLines() throws IOException { - return Files.lines(Paths.get(fname)); - } - public static void - main(String[] args) throws IOException { - new InputFile2("InputFile2.java").getLines() - .skip(15) - .limit(1) - .forEach(System.out::println); - } -} -/* Output: - main(String[] args) throws IOException { -*/ diff --git a/code/exceptions/LoggingExceptions.java b/code/exceptions/LoggingExceptions.java deleted file mode 100644 index 0120ee17..00000000 --- a/code/exceptions/LoggingExceptions.java +++ /dev/null @@ -1,48 +0,0 @@ -// exceptions/LoggingExceptions.java -// (c)2020 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. -// An exception that reports through a Logger -// {ErrorOutputExpected} -import java.util.logging.*; -import java.io.*; - -class LoggingException extends Exception { - private static Logger logger = - Logger.getLogger("LoggingException"); - LoggingException() { - StringWriter trace = new StringWriter(); - printStackTrace(new PrintWriter(trace)); - logger.severe(trace.toString()); - } -} - -public class LoggingExceptions { - public static void main(String[] args) { - try { - throw new LoggingException(); - } catch(LoggingException e) { - System.err.println("Caught " + e); - } - try { - throw new LoggingException(); - } catch(LoggingException e) { - System.err.println("Caught " + e); - } - } -} -/* Output: -___[ Error Output ]___ -May 09, 2017 6:07:17 AM LoggingException -SEVERE: LoggingException - at -LoggingExceptions.main(LoggingExceptions.java:20) - -Caught LoggingException -May 09, 2017 6:07:17 AM LoggingException -SEVERE: LoggingException - at -LoggingExceptions.main(LoggingExceptions.java:25) - -Caught LoggingException -*/ diff --git a/code/exceptions/LoggingExceptions2.java b/code/exceptions/LoggingExceptions2.java deleted file mode 100644 index 21a92137..00000000 --- a/code/exceptions/LoggingExceptions2.java +++ /dev/null @@ -1,32 +0,0 @@ -// exceptions/LoggingExceptions2.java -// (c)2020 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. -// Logging caught exceptions -// {ErrorOutputExpected} -import java.util.logging.*; -import java.io.*; - -public class LoggingExceptions2 { - private static Logger logger = - Logger.getLogger("LoggingExceptions2"); - static void logException(Exception e) { - StringWriter trace = new StringWriter(); - e.printStackTrace(new PrintWriter(trace)); - logger.severe(trace.toString()); - } - public static void main(String[] args) { - try { - throw new NullPointerException(); - } catch(NullPointerException e) { - logException(e); - } - } -} -/* Output: -___[ Error Output ]___ -May 09, 2017 6:07:17 AM LoggingExceptions2 logException -SEVERE: java.lang.NullPointerException - at -LoggingExceptions2.main(LoggingExceptions2.java:17) -*/ diff --git a/code/exceptions/LostMessage.java b/code/exceptions/LostMessage.java deleted file mode 100644 index 1446d903..00000000 --- a/code/exceptions/LostMessage.java +++ /dev/null @@ -1,44 +0,0 @@ -// exceptions/LostMessage.java -// (c)2020 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. -// How an exception can be lost - -class VeryImportantException extends Exception { - @Override - public String toString() { - return "A very important exception!"; - } -} - -class HoHumException extends Exception { - @Override - public String toString() { - return "A trivial exception"; - } -} - -public class LostMessage { - void f() throws VeryImportantException { - throw new VeryImportantException(); - } - void dispose() throws HoHumException { - throw new HoHumException(); - } - public static void main(String[] args) { - try { - LostMessage lm = new LostMessage(); - try { - lm.f(); - } finally { - lm.dispose(); - } - } catch(VeryImportantException | - HoHumException e) { - System.out.println(e); - } - } -} -/* Output: -A trivial exception -*/ diff --git a/code/exceptions/MainException.java b/code/exceptions/MainException.java deleted file mode 100644 index 7a7e2638..00000000 --- a/code/exceptions/MainException.java +++ /dev/null @@ -1,17 +0,0 @@ -// exceptions/MainException.java -// (c)2020 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. -import java.util.*; -import java.nio.file.*; - -public class MainException { - // Pass exceptions to the console: - public static void - main(String[] args) throws Exception { - // Open the file: - List lines = Files.readAllLines( - Paths.get("MainException.java")); - // Use the file ... - } -} diff --git a/code/exceptions/MessyExceptions.java b/code/exceptions/MessyExceptions.java deleted file mode 100644 index e8f7fc9d..00000000 --- a/code/exceptions/MessyExceptions.java +++ /dev/null @@ -1,27 +0,0 @@ -// exceptions/MessyExceptions.java -// (c)2020 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. -import java.io.*; - -public class MessyExceptions { - public static void main(String[] args) { - InputStream in = null; - try { - in = new FileInputStream( - new File("MessyExceptions.java")); - int contents = in.read(); - // Process contents - } catch(IOException e) { - // Handle the error - } finally { - if(in != null) { - try { - in.close(); - } catch(IOException e) { - // Handle the close() error - } - } - } - } -} diff --git a/code/exceptions/MultiCatch.java b/code/exceptions/MultiCatch.java deleted file mode 100644 index f97bde13..00000000 --- a/code/exceptions/MultiCatch.java +++ /dev/null @@ -1,16 +0,0 @@ -// exceptions/MultiCatch.java -// (c)2020 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. - -public class MultiCatch { - void x() throws Except1, Except2, Except3, Except4 {} - void process() {} - void f() { - try { - x(); - } catch(Except1 | Except2 | Except3 | Except4 e) { - process(); - } - } -} diff --git a/code/exceptions/MultiCatch2.java b/code/exceptions/MultiCatch2.java deleted file mode 100644 index 4629e93f..00000000 --- a/code/exceptions/MultiCatch2.java +++ /dev/null @@ -1,19 +0,0 @@ -// exceptions/MultiCatch2.java -// (c)2020 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. - -public class MultiCatch2 { - void x() throws Except1, Except2, Except3, Except4 {} - void process1() {} - void process2() {} - void f() { - try { - x(); - } catch(Except1 | Except2 e) { - process1(); - } catch(Except3 | Except4 e) { - process2(); - } - } -} diff --git a/code/exceptions/MultipleReturns.java b/code/exceptions/MultipleReturns.java deleted file mode 100644 index 3f667b33..00000000 --- a/code/exceptions/MultipleReturns.java +++ /dev/null @@ -1,47 +0,0 @@ -// exceptions/MultipleReturns.java -// (c)2020 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. - -public class MultipleReturns { - public static void f(int i) { - System.out.println( - "Initialization that requires cleanup"); - try { - System.out.println("Point 1"); - if(i == 1) return; - System.out.println("Point 2"); - if(i == 2) return; - System.out.println("Point 3"); - if(i == 3) return; - System.out.println("End"); - return; - } finally { - System.out.println("Performing cleanup"); - } - } - public static void main(String[] args) { - for(int i = 1; i <= 4; i++) - f(i); - } -} -/* Output: -Initialization that requires cleanup -Point 1 -Performing cleanup -Initialization that requires cleanup -Point 1 -Point 2 -Performing cleanup -Initialization that requires cleanup -Point 1 -Point 2 -Point 3 -Performing cleanup -Initialization that requires cleanup -Point 1 -Point 2 -Point 3 -End -Performing cleanup -*/ diff --git a/code/exceptions/NeverCaught.java b/code/exceptions/NeverCaught.java deleted file mode 100644 index c8bb0a2f..00000000 --- a/code/exceptions/NeverCaught.java +++ /dev/null @@ -1,26 +0,0 @@ -// exceptions/NeverCaught.java -// (c)2020 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. -// Ignoring RuntimeExceptions -// {ThrowsException} - -public class NeverCaught { - static void f() { - throw new RuntimeException("From f()"); - } - static void g() { - f(); - } - public static void main(String[] args) { - g(); - } -} -/* Output: -___[ Error Output ]___ -Exception in thread "main" java.lang.RuntimeException: -From f() - at NeverCaught.f(NeverCaught.java:7) - at NeverCaught.g(NeverCaught.java:10) - at NeverCaught.main(NeverCaught.java:13) -*/ diff --git a/code/exceptions/OnOffException1.java b/code/exceptions/OnOffException1.java deleted file mode 100644 index 3333d815..00000000 --- a/code/exceptions/OnOffException1.java +++ /dev/null @@ -1,5 +0,0 @@ -// exceptions/OnOffException1.java -// (c)2020 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. -public class OnOffException1 extends Exception {} diff --git a/code/exceptions/OnOffException2.java b/code/exceptions/OnOffException2.java deleted file mode 100644 index 0bb5e164..00000000 --- a/code/exceptions/OnOffException2.java +++ /dev/null @@ -1,5 +0,0 @@ -// exceptions/OnOffException2.java -// (c)2020 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. -public class OnOffException2 extends Exception {} diff --git a/code/exceptions/OnOffSwitch.java b/code/exceptions/OnOffSwitch.java deleted file mode 100644 index fe05fa35..00000000 --- a/code/exceptions/OnOffSwitch.java +++ /dev/null @@ -1,29 +0,0 @@ -// exceptions/OnOffSwitch.java -// (c)2020 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. -// Why use finally? - -public class OnOffSwitch { - private static Switch sw = new Switch(); - public static void f() - throws OnOffException1, OnOffException2 {} - public static void main(String[] args) { - try { - sw.on(); - // Code that can throw exceptions... - f(); - sw.off(); - } catch(OnOffException1 e) { - System.out.println("OnOffException1"); - sw.off(); - } catch(OnOffException2 e) { - System.out.println("OnOffException2"); - sw.off(); - } - } -} -/* Output: -on -off -*/ diff --git a/code/exceptions/PreciseRethrow.java b/code/exceptions/PreciseRethrow.java deleted file mode 100644 index f8849a3d..00000000 --- a/code/exceptions/PreciseRethrow.java +++ /dev/null @@ -1,17 +0,0 @@ -// exceptions/PreciseRethrow.java -// (c)2020 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. - -class BaseException extends Exception {} -class DerivedException extends BaseException {} - -public class PreciseRethrow { - void catcher() throws DerivedException { - try { - throw new DerivedException(); - } catch(BaseException e) { - throw e; - } - } -} diff --git a/code/exceptions/RethrowNew.java b/code/exceptions/RethrowNew.java deleted file mode 100644 index daa4ad41..00000000 --- a/code/exceptions/RethrowNew.java +++ /dev/null @@ -1,47 +0,0 @@ -// exceptions/RethrowNew.java -// (c)2020 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. -// Rethrow a different object from the one you caught - -class OneException extends Exception { - OneException(String s) { super(s); } -} - -class TwoException extends Exception { - TwoException(String s) { super(s); } -} - -public class RethrowNew { - public static void f() throws OneException { - System.out.println( - "originating the exception in f()"); - throw new OneException("thrown from f()"); - } - public static void main(String[] args) { - try { - try { - f(); - } catch(OneException e) { - System.out.println( - "Caught in inner try, e.printStackTrace()"); - e.printStackTrace(System.out); - throw new TwoException("from inner try"); - } - } catch(TwoException e) { - System.out.println( - "Caught in outer try, e.printStackTrace()"); - e.printStackTrace(System.out); - } - } -} -/* Output: -originating the exception in f() -Caught in inner try, e.printStackTrace() -OneException: thrown from f() - at RethrowNew.f(RethrowNew.java:16) - at RethrowNew.main(RethrowNew.java:21) -Caught in outer try, e.printStackTrace() -TwoException: from inner try - at RethrowNew.main(RethrowNew.java:26) -*/ diff --git a/code/exceptions/Rethrowing.java b/code/exceptions/Rethrowing.java deleted file mode 100644 index 5bf1a635..00000000 --- a/code/exceptions/Rethrowing.java +++ /dev/null @@ -1,70 +0,0 @@ -// exceptions/Rethrowing.java -// (c)2020 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. -// Demonstrating fillInStackTrace() - -public class Rethrowing { - public static void f() throws Exception { - System.out.println( - "originating the exception in f()"); - throw new Exception("thrown from f()"); - } - public static void g() throws Exception { - try { - f(); - } catch(Exception e) { - System.out.println( - "Inside g(), e.printStackTrace()"); - e.printStackTrace(System.out); - throw e; - } - } - public static void h() throws Exception { - try { - f(); - } catch(Exception e) { - System.out.println( - "Inside h(), e.printStackTrace()"); - e.printStackTrace(System.out); - throw (Exception)e.fillInStackTrace(); - } - } - public static void main(String[] args) { - try { - g(); - } catch(Exception e) { - System.out.println("main: printStackTrace()"); - e.printStackTrace(System.out); - } - try { - h(); - } catch(Exception e) { - System.out.println("main: printStackTrace()"); - e.printStackTrace(System.out); - } - } -} -/* Output: -originating the exception in f() -Inside g(), e.printStackTrace() -java.lang.Exception: thrown from f() - at Rethrowing.f(Rethrowing.java:8) - at Rethrowing.g(Rethrowing.java:12) - at Rethrowing.main(Rethrowing.java:32) -main: printStackTrace() -java.lang.Exception: thrown from f() - at Rethrowing.f(Rethrowing.java:8) - at Rethrowing.g(Rethrowing.java:12) - at Rethrowing.main(Rethrowing.java:32) -originating the exception in f() -Inside h(), e.printStackTrace() -java.lang.Exception: thrown from f() - at Rethrowing.f(Rethrowing.java:8) - at Rethrowing.h(Rethrowing.java:22) - at Rethrowing.main(Rethrowing.java:38) -main: printStackTrace() -java.lang.Exception: thrown from f() - at Rethrowing.h(Rethrowing.java:27) - at Rethrowing.main(Rethrowing.java:38) -*/ diff --git a/code/exceptions/SameHandler.java b/code/exceptions/SameHandler.java deleted file mode 100644 index 8c680567..00000000 --- a/code/exceptions/SameHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -// exceptions/SameHandler.java -// (c)2020 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. - -class EBase1 extends Exception {} -class Except1 extends EBase1 {} -class EBase2 extends Exception {} -class Except2 extends EBase2 {} -class EBase3 extends Exception {} -class Except3 extends EBase3 {} -class EBase4 extends Exception {} -class Except4 extends EBase4 {} - -public class SameHandler { - void x() throws Except1, Except2, Except3, Except4 {} - void process() {} - void f() { - try { - x(); - } catch(Except1 e) { - process(); - } catch(Except2 e) { - process(); - } catch(Except3 e) { - process(); - } catch(Except4 e) { - process(); - } - } -} diff --git a/code/exceptions/StormyInning.java b/code/exceptions/StormyInning.java deleted file mode 100644 index 644c10ba..00000000 --- a/code/exceptions/StormyInning.java +++ /dev/null @@ -1,83 +0,0 @@ -// exceptions/StormyInning.java -// (c)2020 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. -// Overridden methods can throw only the exceptions -// specified in their base-class versions, or exceptions -// derived from the base-class exceptions - -class BaseballException extends Exception {} -class Foul extends BaseballException {} -class Strike extends BaseballException {} - -abstract class Inning { - Inning() throws BaseballException {} - public void event() throws BaseballException { - // Doesn't actually have to throw anything - } - public abstract void atBat() throws Strike, Foul; - public void walk() {} // Throws no checked exceptions -} - -class StormException extends Exception {} -class RainedOut extends StormException {} -class PopFoul extends Foul {} - -interface Storm { - void event() throws RainedOut; - void rainHard() throws RainedOut; -} - -public -class StormyInning extends Inning implements Storm { - // OK to add new exceptions for constructors, but you - // must deal with the base constructor exceptions: - public StormyInning() - throws RainedOut, BaseballException {} - public StormyInning(String s) - throws BaseballException {} - // Regular methods must conform to base class: - //- void walk() throws PopFoul {} //Compile error - // Interface CANNOT add exceptions to existing - // methods from the base class: - //- public void event() throws RainedOut {} - // If the method doesn't already exist in the - // base class, the exception is OK: - @Override - public void rainHard() throws RainedOut {} - // You can choose to not throw any exceptions, - // even if the base version does: - @Override - public void event() {} - // Overridden methods can throw inherited exceptions: - @Override - public void atBat() throws PopFoul {} - public static void main(String[] args) { - try { - StormyInning si = new StormyInning(); - si.atBat(); - } catch(PopFoul e) { - System.out.println("Pop foul"); - } catch(RainedOut e) { - System.out.println("Rained out"); - } catch(BaseballException e) { - System.out.println("Generic baseball exception"); - } - // Strike not thrown in derived version. - try { - // What happens if you upcast? - Inning i = new StormyInning(); - i.atBat(); - // You must catch the exceptions from the - // base-class version of the method: - } catch(Strike e) { - System.out.println("Strike"); - } catch(Foul e) { - System.out.println("Foul"); - } catch(RainedOut e) { - System.out.println("Rained out"); - } catch(BaseballException e) { - System.out.println("Generic baseball exception"); - } - } -} diff --git a/code/exceptions/StreamsAreAutoCloseable.java b/code/exceptions/StreamsAreAutoCloseable.java deleted file mode 100644 index c55bf417..00000000 --- a/code/exceptions/StreamsAreAutoCloseable.java +++ /dev/null @@ -1,24 +0,0 @@ -// exceptions/StreamsAreAutoCloseable.java -// (c)2020 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. -import java.io.*; -import java.nio.file.*; -import java.util.stream.*; - -public class StreamsAreAutoCloseable { - public static void - main(String[] args) throws IOException{ - try( - Stream in = Files.lines( - Paths.get("StreamsAreAutoCloseable.java")); - PrintWriter outfile = new PrintWriter( - "Results.txt"); // [1] - ) { - in.skip(5) - .limit(1) - .map(String::toLowerCase) - .forEachOrdered(outfile::println); - } // [2] - } -} diff --git a/code/exceptions/Switch.java b/code/exceptions/Switch.java deleted file mode 100644 index 7d491d00..00000000 --- a/code/exceptions/Switch.java +++ /dev/null @@ -1,21 +0,0 @@ -// exceptions/Switch.java -// (c)2020 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. - -public class Switch { - private boolean state = false; - public boolean read() { return state; } - public void on() { - state = true; - System.out.println(this); - } - public void off() { - state = false; - System.out.println(this); - } - @Override - public String toString() { - return state ? "on" : "off"; - } -} diff --git a/code/exceptions/TryAnything.java b/code/exceptions/TryAnything.java deleted file mode 100644 index 9eeee07b..00000000 --- a/code/exceptions/TryAnything.java +++ /dev/null @@ -1,16 +0,0 @@ -// exceptions/TryAnything.java -// (c)2020 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. -// {WillNotCompile} - -class Anything {} - -public class TryAnything { - public static void main(String[] args) { - try( - Anything a = new Anything() - ) { - } - } -} diff --git a/code/exceptions/TryWithResources.java b/code/exceptions/TryWithResources.java deleted file mode 100644 index cdc83a5c..00000000 --- a/code/exceptions/TryWithResources.java +++ /dev/null @@ -1,19 +0,0 @@ -// exceptions/TryWithResources.java -// (c)2020 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. -import java.io.*; - -public class TryWithResources { - public static void main(String[] args) { - try( - InputStream in = new FileInputStream( - new File("TryWithResources.java")) - ) { - int contents = in.read(); - // Process contents - } catch(IOException e) { - // Handle the error - } - } -} diff --git a/code/exceptions/TurnOffChecking.java b/code/exceptions/TurnOffChecking.java deleted file mode 100644 index 898431b6..00000000 --- a/code/exceptions/TurnOffChecking.java +++ /dev/null @@ -1,64 +0,0 @@ -// exceptions/TurnOffChecking.java -// (c)2020 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. -// "Turning off" Checked exceptions -import java.io.*; - -class WrapCheckedException { - void throwRuntimeException(int type) { - try { - switch(type) { - case 0: throw new FileNotFoundException(); - case 1: throw new IOException(); - case 2: throw new - RuntimeException("Where am I?"); - default: return; - } - } catch(IOException | RuntimeException e) { - // Adapt to unchecked: - throw new RuntimeException(e); - } - } -} - -class SomeOtherException extends Exception {} - -public class TurnOffChecking { - public static void main(String[] args) { - WrapCheckedException wce = - new WrapCheckedException(); - // You can call throwRuntimeException() without - // a try block, and let RuntimeExceptions - // leave the method: - wce.throwRuntimeException(3); - // Or you can choose to catch exceptions: - for(int i = 0; i < 4; i++) - try { - if(i < 3) - wce.throwRuntimeException(i); - else - throw new SomeOtherException(); - } catch(SomeOtherException e) { - System.out.println( - "SomeOtherException: " + e); - } catch(RuntimeException re) { - try { - throw re.getCause(); - } catch(FileNotFoundException e) { - System.out.println( - "FileNotFoundException: " + e); - } catch(IOException e) { - System.out.println("IOException: " + e); - } catch(Throwable e) { - System.out.println("Throwable: " + e); - } - } - } -} -/* Output: -FileNotFoundException: java.io.FileNotFoundException -IOException: java.io.IOException -Throwable: java.lang.RuntimeException: Where am I? -SomeOtherException: SomeOtherException -*/ diff --git a/code/exceptions/WhoCalled.java b/code/exceptions/WhoCalled.java deleted file mode 100644 index 4c4e0104..00000000 --- a/code/exceptions/WhoCalled.java +++ /dev/null @@ -1,39 +0,0 @@ -// exceptions/WhoCalled.java -// (c)2020 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. -// Programmatic access to stack trace information - -public class WhoCalled { - static void f() { - // Generate an exception to fill in the stack trace - try { - throw new Exception(); - } catch(Exception e) { - for(StackTraceElement ste : e.getStackTrace()) - System.out.println(ste.getMethodName()); - } - } - static void g() { f(); } - static void h() { g(); } - public static void main(String[] args) { - f(); - System.out.println("*******"); - g(); - System.out.println("*******"); - h(); - } -} -/* Output: -f -main -******* -f -g -main -******* -f -g -h -main -*/ diff --git a/code/exceptions/WithFinally.java b/code/exceptions/WithFinally.java deleted file mode 100644 index 9d3efc3a..00000000 --- a/code/exceptions/WithFinally.java +++ /dev/null @@ -1,26 +0,0 @@ -// exceptions/WithFinally.java -// (c)2020 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. -// Finally Guarantees cleanup - -public class WithFinally { - static Switch sw = new Switch(); - public static void main(String[] args) { - try { - sw.on(); - // Code that can throw exceptions... - OnOffSwitch.f(); - } catch(OnOffException1 e) { - System.out.println("OnOffException1"); - } catch(OnOffException2 e) { - System.out.println("OnOffException2"); - } finally { - sw.off(); - } - } -} -/* Output: -on -off -*/ diff --git a/code/files/AddAndSubtractPaths.java b/code/files/AddAndSubtractPaths.java deleted file mode 100644 index f3984d19..00000000 --- a/code/files/AddAndSubtractPaths.java +++ /dev/null @@ -1,87 +0,0 @@ -// files/AddAndSubtractPaths.java -// (c)2020 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. -import java.nio.file.*; -import java.io.IOException; - -public class AddAndSubtractPaths { - static Path base = Paths.get("..", "..", "..") - .toAbsolutePath() - .normalize(); - static void show(int id, Path result) { - if(result.isAbsolute()) - System.out.println("(" + id + ")r " + - base.relativize(result)); - else - System.out.println("(" + id + ") " + result); - try { - System.out.println("RealPath: " - + result.toRealPath()); - } catch(IOException e) { - System.out.println(e); - } - } - public static void main(String[] args) { - System.out.println(System.getProperty("os.name")); - System.out.println(base); - Path p = Paths.get("AddAndSubtractPaths.java") - .toAbsolutePath(); - show(1, p); - Path convoluted = p.getParent().getParent() - .resolve("strings") - .resolve("..") - .resolve(p.getParent().getFileName()); - show(2, convoluted); - show(3, convoluted.normalize()); - - Path p2 = Paths.get("..", ".."); - show(4, p2); - show(5, p2.normalize()); - show(6, p2.toAbsolutePath().normalize()); - - Path p3 = Paths.get(".").toAbsolutePath(); - Path p4 = p3.resolve(p2); - show(7, p4); - show(8, p4.normalize()); - - Path p5 = Paths.get("").toAbsolutePath(); - show(9, p5); - show(10, p5.resolveSibling("strings")); - show(11, Paths.get("nonexistent")); - } -} -/* Output: -Windows 10 -C:\Users\Bruce\Documents\GitHub -(1)r on- -java\ExtractedExamples\files\AddAndSubtractPaths.java -RealPath: C:\Users\Bruce\Documents\GitHub\on- -java\ExtractedExamples\files\AddAndSubtractPaths.java -(2)r on-java\ExtractedExamples\strings\..\files -RealPath: C:\Users\Bruce\Documents\GitHub\on- -java\ExtractedExamples\files -(3)r on-java\ExtractedExamples\files -RealPath: C:\Users\Bruce\Documents\GitHub\on- -java\ExtractedExamples\files -(4) ..\.. -RealPath: C:\Users\Bruce\Documents\GitHub\on-java -(5) ..\.. -RealPath: C:\Users\Bruce\Documents\GitHub\on-java -(6)r on-java -RealPath: C:\Users\Bruce\Documents\GitHub\on-java -(7)r on-java\ExtractedExamples\files\.\..\.. -RealPath: C:\Users\Bruce\Documents\GitHub\on-java -(8)r on-java -RealPath: C:\Users\Bruce\Documents\GitHub\on-java -(9)r on-java\ExtractedExamples\files -RealPath: C:\Users\Bruce\Documents\GitHub\on- -java\ExtractedExamples\files -(10)r on-java\ExtractedExamples\strings -RealPath: C:\Users\Bruce\Documents\GitHub\on- -java\ExtractedExamples\strings -(11) nonexistent -java.nio.file.NoSuchFileException: -C:\Users\Bruce\Documents\GitHub\on- -java\ExtractedExamples\files\nonexistent -*/ diff --git a/code/files/Directories.java b/code/files/Directories.java deleted file mode 100644 index 10ad9bee..00000000 --- a/code/files/Directories.java +++ /dev/null @@ -1,94 +0,0 @@ -// files/Directories.java -// (c)2020 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. -import java.util.*; -import java.nio.file.*; -import onjava.RmDir; - -public class Directories { - static Path test = Paths.get("test"); - static String sep = - FileSystems.getDefault().getSeparator(); - static List parts = - Arrays.asList("foo", "bar", "baz", "bag"); - static Path makeVariant() { - Collections.rotate(parts, 1); - return Paths.get("test", String.join(sep, parts)); - } - static void refreshTestDir() throws Exception { - if(Files.exists(test)) - RmDir.rmdir(test); - if(!Files.exists(test)) - Files.createDirectory(test); - } - public static void - main(String[] args) throws Exception { - refreshTestDir(); - Files.createFile(test.resolve("Hello.txt")); - Path variant = makeVariant(); - // Throws exception (too many levels): - try { - Files.createDirectory(variant); - } catch(Exception e) { - System.out.println("Nope, that doesn't work."); - } - populateTestDir(); - Path tempdir = - Files.createTempDirectory(test, "DIR_"); - Files.createTempFile(tempdir, "pre", ".non"); - Files.newDirectoryStream(test) - .forEach(System.out::println); - System.out.println("*********"); - Files.walk(test).forEach(System.out::println); - } - static void populateTestDir() throws Exception { - for(int i = 0; i < parts.size(); i++) { - Path variant = makeVariant(); - if(!Files.exists(variant)) { - Files.createDirectories(variant); - Files.copy(Paths.get("Directories.java"), - variant.resolve("File.txt")); - Files.createTempFile(variant, null, null); - } - } - } -} -/* Output: -Nope, that doesn't work. -test\bag -test\bar -test\baz -test\DIR_5142667942049986036 -test\foo -test\Hello.txt -********* -test -test\bag -test\bag\foo -test\bag\foo\bar -test\bag\foo\bar\baz -test\bag\foo\bar\baz\8279660869874696036.tmp -test\bag\foo\bar\baz\File.txt -test\bar -test\bar\baz -test\bar\baz\bag -test\bar\baz\bag\foo -test\bar\baz\bag\foo\1274043134240426261.tmp -test\bar\baz\bag\foo\File.txt -test\baz -test\baz\bag -test\baz\bag\foo -test\baz\bag\foo\bar -test\baz\bag\foo\bar\6130572530014544105.tmp -test\baz\bag\foo\bar\File.txt -test\DIR_5142667942049986036 -test\DIR_5142667942049986036\pre7704286843227113253.non -test\foo -test\foo\bar -test\foo\bar\baz -test\foo\bar\baz\bag -test\foo\bar\baz\bag\5412864507741775436.tmp -test\foo\bar\baz\bag\File.txt -test\Hello.txt -*/ diff --git a/code/files/FileSystemDemo.java b/code/files/FileSystemDemo.java deleted file mode 100644 index 3d9024ca..00000000 --- a/code/files/FileSystemDemo.java +++ /dev/null @@ -1,41 +0,0 @@ -// files/FileSystemDemo.java -// (c)2020 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. -import java.nio.file.*; - -public class FileSystemDemo { - static void show(String id, Object o) { - System.out.println(id + ": " + o); - } - public static void main(String[] args) { - System.out.println(System.getProperty("os.name")); - FileSystem fsys = FileSystems.getDefault(); - for(FileStore fs : fsys.getFileStores()) - show("File Store", fs); - for(Path rd : fsys.getRootDirectories()) - show("Root Directory", rd); - show("Separator", fsys.getSeparator()); - show("UserPrincipalLookupService", - fsys.getUserPrincipalLookupService()); - show("isOpen", fsys.isOpen()); - show("isReadOnly", fsys.isReadOnly()); - show("FileSystemProvider", fsys.provider()); - show("File Attribute Views", - fsys.supportedFileAttributeViews()); - } -} -/* Output: -Windows 10 -File Store: SSD (C:) -Root Directory: C:\ -Root Directory: D:\ -Separator: \ -UserPrincipalLookupService: -sun.nio.fs.WindowsFileSystem$LookupService$1@15db9742 -isOpen: true -isReadOnly: false -FileSystemProvider: -sun.nio.fs.WindowsFileSystemProvider@6d06d69c -File Attribute Views: [owner, dos, acl, basic, user] -*/ diff --git a/code/files/Find.java b/code/files/Find.java deleted file mode 100644 index ac97ebdc..00000000 --- a/code/files/Find.java +++ /dev/null @@ -1,60 +0,0 @@ -// files/Find.java -// (c)2020 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. -// {ExcludeFromGradle} -import java.nio.file.*; - -public class Find { - public static void - main(String[] args) throws Exception { - Path test = Paths.get("test"); - Directories.refreshTestDir(); - Directories.populateTestDir(); - // Creating a *directory*, not a file: - Files.createDirectory(test.resolve("dir.tmp")); - - PathMatcher matcher = FileSystems.getDefault() - .getPathMatcher("glob:**/*.{tmp,txt}"); - Files.walk(test) - .filter(matcher::matches) - .forEach(System.out::println); - System.out.println("***************"); - - PathMatcher matcher2 = FileSystems.getDefault() - .getPathMatcher("glob:*.tmp"); - Files.walk(test) - .map(Path::getFileName) - .filter(matcher2::matches) - .forEach(System.out::println); - System.out.println("***************"); - - Files.walk(test) // Only look for files - .filter(Files::isRegularFile) - .map(Path::getFileName) - .filter(matcher2::matches) - .forEach(System.out::println); - } -} -/* Output: -test\bag\foo\bar\baz\5208762845883213974.tmp -test\bag\foo\bar\baz\File.txt -test\bar\baz\bag\foo\7918367201207778677.tmp -test\bar\baz\bag\foo\File.txt -test\baz\bag\foo\bar\8016595521026696632.tmp -test\baz\bag\foo\bar\File.txt -test\dir.tmp -test\foo\bar\baz\bag\5832319279813617280.tmp -test\foo\bar\baz\bag\File.txt -*************** -5208762845883213974.tmp -7918367201207778677.tmp -8016595521026696632.tmp -dir.tmp -5832319279813617280.tmp -*************** -5208762845883213974.tmp -7918367201207778677.tmp -8016595521026696632.tmp -5832319279813617280.tmp -*/ diff --git a/code/files/ListOfLines.java b/code/files/ListOfLines.java deleted file mode 100644 index 6f9ef467..00000000 --- a/code/files/ListOfLines.java +++ /dev/null @@ -1,26 +0,0 @@ -// files/ListOfLines.java -// (c)2020 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. -import java.util.*; -import java.nio.file.*; - -public class ListOfLines { - public static void - main(String[] args) throws Exception { - Files.readAllLines( - Paths.get("../streams/Cheese.dat")) - .stream() - .filter(line -> !line.startsWith("//")) - .map(line -> - line.substring(0, line.length()/2)) - .forEach(System.out::println); - } -} -/* Output: -Not much of a cheese -Finest in the -And what leads you -Well, it's -It's certainly uncon -*/ diff --git a/code/files/PartsOfPaths.java b/code/files/PartsOfPaths.java deleted file mode 100644 index 1170fc68..00000000 --- a/code/files/PartsOfPaths.java +++ /dev/null @@ -1,45 +0,0 @@ -// files/PartsOfPaths.java -// (c)2020 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. -import java.nio.file.*; - -public class PartsOfPaths { - public static void main(String[] args) { - System.out.println(System.getProperty("os.name")); - Path p = - Paths.get("PartsOfPaths.java").toAbsolutePath(); - for(int i = 0; i < p.getNameCount(); i++) - System.out.println(p.getName(i)); - System.out.println("ends with '.java': " + - p.endsWith(".java")); - for(Path pp : p) { - System.out.print(pp + ": "); - System.out.print(p.startsWith(pp) + " : "); - System.out.println(p.endsWith(pp)); - } - System.out.println("Starts with " + p.getRoot() + - " " + p.startsWith(p.getRoot())); - } -} -/* Output: -Windows 10 -Users -Bruce -Documents -GitHub -on-java -ExtractedExamples -files -PartsOfPaths.java -ends with '.java': false -Users: false : false -Bruce: false : false -Documents: false : false -GitHub: false : false -on-java: false : false -ExtractedExamples: false : false -files: false : false -PartsOfPaths.java: false : true -Starts with C:\ true -*/ diff --git a/code/files/PathAnalysis.java b/code/files/PathAnalysis.java deleted file mode 100644 index 117119cd..00000000 --- a/code/files/PathAnalysis.java +++ /dev/null @@ -1,56 +0,0 @@ -// files/PathAnalysis.java -// (c)2020 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. -import java.nio.file.*; -import java.io.IOException; - -public class PathAnalysis { - static void say(String id, Object result) { - System.out.print(id + ": "); - System.out.println(result); - } - public static void - main(String[] args) throws IOException { - System.out.println(System.getProperty("os.name")); - Path p = - Paths.get("PathAnalysis.java").toAbsolutePath(); - say("Exists", Files.exists(p)); - say("Directory", Files.isDirectory(p)); - say("Executable", Files.isExecutable(p)); - say("Readable", Files.isReadable(p)); - say("RegularFile", Files.isRegularFile(p)); - say("Writable", Files.isWritable(p)); - say("notExists", Files.notExists(p)); - say("Hidden", Files.isHidden(p)); - say("size", Files.size(p)); - say("FileStore", Files.getFileStore(p)); - say("LastModified: ", Files.getLastModifiedTime(p)); - say("Owner", Files.getOwner(p)); - say("ContentType", Files.probeContentType(p)); - say("SymbolicLink", Files.isSymbolicLink(p)); - if(Files.isSymbolicLink(p)) - say("SymbolicLink", Files.readSymbolicLink(p)); - if(FileSystems.getDefault() - .supportedFileAttributeViews().contains("posix")) - say("PosixFilePermissions", - Files.getPosixFilePermissions(p)); - } -} -/* Output: -Windows 10 -Exists: true -Directory: false -Executable: true -Readable: true -RegularFile: true -Writable: true -notExists: false -Hidden: false -size: 1631 -FileStore: SSD (C:) -LastModified: : 2017-05-09T12:07:00.428366Z -Owner: MINDVIEWTOSHIBA\Bruce (User) -ContentType: null -SymbolicLink: false -*/ diff --git a/code/files/PathInfo.java b/code/files/PathInfo.java deleted file mode 100644 index 96af9d93..00000000 --- a/code/files/PathInfo.java +++ /dev/null @@ -1,102 +0,0 @@ -// files/PathInfo.java -// (c)2020 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. -import java.nio.file.*; -import java.net.URI; -import java.io.File; -import java.io.IOException; - -public class PathInfo { - static void show(String id, Object p) { - System.out.println(id + ": " + p); - } - static void info(Path p) { - show("toString", p); - show("Exists", Files.exists(p)); - show("RegularFile", Files.isRegularFile(p)); - show("Directory", Files.isDirectory(p)); - show("Absolute", p.isAbsolute()); - show("FileName", p.getFileName()); - show("Parent", p.getParent()); - show("Root", p.getRoot()); - System.out.println("******************"); - } - public static void main(String[] args) { - System.out.println(System.getProperty("os.name")); - info(Paths.get( - "C:", "path", "to", "nowhere", "NoFile.txt")); - Path p = Paths.get("PathInfo.java"); - info(p); - Path ap = p.toAbsolutePath(); - info(ap); - info(ap.getParent()); - try { - info(p.toRealPath()); - } catch(IOException e) { - System.out.println(e); - } - URI u = p.toUri(); - System.out.println("URI: " + u); - Path puri = Paths.get(u); - System.out.println(Files.exists(puri)); - File f = ap.toFile(); // Don't be fooled - } -} -/* Output: -Windows 10 -toString: C:\path\to\nowhere\NoFile.txt -Exists: false -RegularFile: false -Directory: false -Absolute: true -FileName: NoFile.txt -Parent: C:\path\to\nowhere -Root: C:\ -****************** -toString: PathInfo.java -Exists: true -RegularFile: true -Directory: false -Absolute: false -FileName: PathInfo.java -Parent: null -Root: null -****************** -toString: C:\Users\Bruce\Documents\GitHub\on- -java\ExtractedExamples\files\PathInfo.java -Exists: true -RegularFile: true -Directory: false -Absolute: true -FileName: PathInfo.java -Parent: C:\Users\Bruce\Documents\GitHub\on- -java\ExtractedExamples\files -Root: C:\ -****************** -toString: C:\Users\Bruce\Documents\GitHub\on- -java\ExtractedExamples\files -Exists: true -RegularFile: false -Directory: true -Absolute: true -FileName: files -Parent: C:\Users\Bruce\Documents\GitHub\on- -java\ExtractedExamples -Root: C:\ -****************** -toString: C:\Users\Bruce\Documents\GitHub\on- -java\ExtractedExamples\files\PathInfo.java -Exists: true -RegularFile: true -Directory: false -Absolute: true -FileName: PathInfo.java -Parent: C:\Users\Bruce\Documents\GitHub\on- -java\ExtractedExamples\files -Root: C:\ -****************** -URI: file:///C:/Users/Bruce/Documents/GitHub/on- -java/ExtractedExamples/files/PathInfo.java -true -*/ diff --git a/code/files/PathWatcher.java b/code/files/PathWatcher.java deleted file mode 100644 index 162641d7..00000000 --- a/code/files/PathWatcher.java +++ /dev/null @@ -1,61 +0,0 @@ -// files/PathWatcher.java -// (c)2020 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. -// {ExcludeFromGradle} -import java.io.IOException; -import java.nio.file.*; -import static java.nio.file.StandardWatchEventKinds.*; -import java.util.concurrent.*; - -public class PathWatcher { - static Path test = Paths.get("test"); - static void delTxtFiles() { - try { - Files.walk(test) - .filter(f -> - f.toString().endsWith(".txt")) - .forEach(f -> { - try { - System.out.println("deleting " + f); - Files.delete(f); - } catch(IOException e) { - throw new RuntimeException(e); - } - }); - } catch(IOException e) { - throw new RuntimeException(e); - } - } - public static void - main(String[] args) throws Exception { - Directories.refreshTestDir(); - Directories.populateTestDir(); - Files.createFile(test.resolve("Hello.txt")); - WatchService watcher = - FileSystems.getDefault().newWatchService(); - test.register(watcher, ENTRY_DELETE); - Executors.newSingleThreadScheduledExecutor() - .schedule( - PathWatcher::delTxtFiles, - 250, TimeUnit.MILLISECONDS); - WatchKey key = watcher.take(); - for(WatchEvent evt : key.pollEvents()) { - System.out.println( - "evt.context(): " + evt.context() + - "\nevt.count(): " + evt.count() + - "\nevt.kind(): " + evt.kind()); - System.exit(0); - } - } -} -/* Output: -deleting test\bag\foo\bar\baz\File.txt -deleting test\bar\baz\bag\foo\File.txt -deleting test\baz\bag\foo\bar\File.txt -deleting test\foo\bar\baz\bag\File.txt -deleting test\Hello.txt -evt.context(): Hello.txt -evt.count(): 1 -evt.kind(): ENTRY_DELETE -*/ diff --git a/code/files/ReadLineStream.java b/code/files/ReadLineStream.java deleted file mode 100644 index 64b0f562..00000000 --- a/code/files/ReadLineStream.java +++ /dev/null @@ -1,18 +0,0 @@ -// files/ReadLineStream.java -// (c)2020 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. -import java.nio.file.*; - -public class ReadLineStream { - public static void - main(String[] args) throws Exception { - Files.lines(Paths.get("PathInfo.java")) - .skip(13) - .findFirst() - .ifPresent(System.out::println); - } -} -/* Output: - show("RegularFile", Files.isRegularFile(p)); -*/ diff --git a/code/files/StreamInAndOut.java b/code/files/StreamInAndOut.java deleted file mode 100644 index ec17c700..00000000 --- a/code/files/StreamInAndOut.java +++ /dev/null @@ -1,24 +0,0 @@ -// files/StreamInAndOut.java -// (c)2020 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. -import java.io.*; -import java.nio.file.*; -import java.util.stream.*; - -public class StreamInAndOut { - public static void main(String[] args) { - try( - Stream input = - Files.lines(Paths.get("StreamInAndOut.java")); - PrintWriter output = - new PrintWriter("StreamInAndOut.txt") - ) { - input - .map(String::toUpperCase) - .forEachOrdered(output::println); - } catch(Exception e) { - throw new RuntimeException(e); - } - } -} diff --git a/code/files/TreeWatcher.java b/code/files/TreeWatcher.java deleted file mode 100644 index f0660888..00000000 --- a/code/files/TreeWatcher.java +++ /dev/null @@ -1,51 +0,0 @@ -// files/TreeWatcher.java -// (c)2020 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. -// {ExcludeFromGradle} -import java.io.IOException; -import java.nio.file.*; -import static java.nio.file.StandardWatchEventKinds.*; -import java.util.concurrent.*; - -public class TreeWatcher { - static void watchDir(Path dir) { - try { - WatchService watcher = - FileSystems.getDefault().newWatchService(); - dir.register(watcher, ENTRY_DELETE); - Executors.newSingleThreadExecutor().submit(() -> { - try { - WatchKey key = watcher.take(); - for(WatchEvent evt : key.pollEvents()) { - System.out.println( - "evt.context(): " + evt.context() + - "\nevt.count(): " + evt.count() + - "\nevt.kind(): " + evt.kind()); - System.exit(0); - } - } catch(InterruptedException e) { - return; - } - }); - } catch(IOException e) { - throw new RuntimeException(e); - } - } - public static void - main(String[] args) throws Exception { - Directories.refreshTestDir(); - Directories.populateTestDir(); - Files.walk(Paths.get("test")) - .filter(Files::isDirectory) - .forEach(TreeWatcher::watchDir); - PathWatcher.delTxtFiles(); - } -} -/* Output: -deleting test\bag\foo\bar\baz\File.txt -deleting test\bar\baz\bag\foo\File.txt -evt.context(): File.txt -evt.count(): 1 -evt.kind(): ENTRY_DELETE -*/ diff --git a/code/files/Writing.java b/code/files/Writing.java deleted file mode 100644 index 68a04fbc..00000000 --- a/code/files/Writing.java +++ /dev/null @@ -1,31 +0,0 @@ -// files/Writing.java -// (c)2020 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. -import java.util.*; -import java.nio.file.*; - -public class Writing { - static Random rand = new Random(47); - static final int SIZE = 1000; - public static void - main(String[] args) throws Exception { - // Write bytes to a file: - byte[] bytes = new byte[SIZE]; - rand.nextBytes(bytes); - Files.write(Paths.get("bytes.dat"), bytes); - System.out.println("bytes.dat: " + - Files.size(Paths.get("bytes.dat"))); - - // Write an iterable to a file: - List lines = Files.readAllLines( - Paths.get("../streams/Cheese.dat")); - Files.write(Paths.get("Cheese.txt"), lines); - System.out.println("Cheese.txt: " + - Files.size(Paths.get("Cheese.txt"))); - } -} -/* Output: -bytes.dat: 1000 -Cheese.txt: 199 -*/ diff --git a/code/functional/AnonymousClosure.java b/code/functional/AnonymousClosure.java deleted file mode 100644 index 497a1a52..00000000 --- a/code/functional/AnonymousClosure.java +++ /dev/null @@ -1,17 +0,0 @@ -// functional/AnonymousClosure.java -// (c)2020 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. -import java.util.function.*; - -public class AnonymousClosure { - IntSupplier makeFun(int x) { - int i = 0; - // Same rules apply: - // i++; // Not "effectively final" - // x++; // Ditto - return new IntSupplier() { - public int getAsInt() { return x + i; } - }; - } -} diff --git a/code/functional/BiConsumerPermutations.java b/code/functional/BiConsumerPermutations.java deleted file mode 100644 index 75b7c32d..00000000 --- a/code/functional/BiConsumerPermutations.java +++ /dev/null @@ -1,24 +0,0 @@ -// functional/BiConsumerPermutations.java -// (c)2020 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. -import java.util.function.*; - -public class BiConsumerPermutations { - static BiConsumer bicid = (i, d) -> - System.out.format("%d, %f%n", i, d); - static BiConsumer bicdi = (d, i) -> - System.out.format("%d, %f%n", i, d); - static BiConsumer bicil = (i, l) -> - System.out.format("%d, %d%n", i, l); - public static void main(String[] args) { - bicid.accept(47, 11.34); - bicdi.accept(22.45, 92); - bicil.accept(1, 11L); - } -} -/* Output: -47, 11.340000 -92, 22.450000 -1, 11 -*/ diff --git a/code/functional/ClassFunctionals.java b/code/functional/ClassFunctionals.java deleted file mode 100644 index e5101df4..00000000 --- a/code/functional/ClassFunctionals.java +++ /dev/null @@ -1,45 +0,0 @@ -// functional/ClassFunctionals.java -// (c)2020 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. -import java.util.*; -import java.util.function.*; - -class AA {} -class BB {} -class CC {} - -public class ClassFunctionals { - static AA f1() { return new AA(); } - static int f2(AA aa1, AA aa2) { return 1; } - static void f3(AA aa) {} - static void f4(AA aa, BB bb) {} - static CC f5(AA aa) { return new CC(); } - static CC f6(AA aa, BB bb) { return new CC(); } - static boolean f7(AA aa) { return true; } - static boolean f8(AA aa, BB bb) { return true; } - static AA f9(AA aa) { return new AA(); } - static AA f10(AA aa1, AA aa2) { return new AA(); } - public static void main(String[] args) { - Supplier s = ClassFunctionals::f1; - s.get(); - Comparator c = ClassFunctionals::f2; - c.compare(new AA(), new AA()); - Consumer cons = ClassFunctionals::f3; - cons.accept(new AA()); - BiConsumer bicons = ClassFunctionals::f4; - bicons.accept(new AA(), new BB()); - Function f = ClassFunctionals::f5; - CC cc = f.apply(new AA()); - BiFunction bif = ClassFunctionals::f6; - cc = bif.apply(new AA(), new BB()); - Predicate p = ClassFunctionals::f7; - boolean result = p.test(new AA()); - BiPredicate bip = ClassFunctionals::f8; - result = bip.test(new AA(), new BB()); - UnaryOperator uo = ClassFunctionals::f9; - AA aa = uo.apply(new AA()); - BinaryOperator bo = ClassFunctionals::f10; - aa = bo.apply(new AA(), new AA()); - } -} diff --git a/code/functional/Closure1.java b/code/functional/Closure1.java deleted file mode 100644 index 2f504f42..00000000 --- a/code/functional/Closure1.java +++ /dev/null @@ -1,12 +0,0 @@ -// functional/Closure1.java -// (c)2020 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. -import java.util.function.*; - -public class Closure1 { - int i; - IntSupplier makeFun(int x) { - return () -> x + i++; - } -} diff --git a/code/functional/Closure2.java b/code/functional/Closure2.java deleted file mode 100644 index 825cf423..00000000 --- a/code/functional/Closure2.java +++ /dev/null @@ -1,12 +0,0 @@ -// functional/Closure2.java -// (c)2020 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. -import java.util.function.*; - -public class Closure2 { - IntSupplier makeFun(int x) { - int i = 0; - return () -> x + i; - } -} diff --git a/code/functional/Closure3.java b/code/functional/Closure3.java deleted file mode 100644 index 811179fb..00000000 --- a/code/functional/Closure3.java +++ /dev/null @@ -1,14 +0,0 @@ -// functional/Closure3.java -// (c)2020 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. -// {WillNotCompile} -import java.util.function.*; - -public class Closure3 { - IntSupplier makeFun(int x) { - int i = 0; - // Neither x++ nor i++ will work: - return () -> x++ + i++; - } -} diff --git a/code/functional/Closure4.java b/code/functional/Closure4.java deleted file mode 100644 index 148aaf64..00000000 --- a/code/functional/Closure4.java +++ /dev/null @@ -1,12 +0,0 @@ -// functional/Closure4.java -// (c)2020 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. -import java.util.function.*; - -public class Closure4 { - IntSupplier makeFun(final int x) { - final int i = 0; - return () -> x + i; - } -} diff --git a/code/functional/Closure5.java b/code/functional/Closure5.java deleted file mode 100644 index fb9aad77..00000000 --- a/code/functional/Closure5.java +++ /dev/null @@ -1,15 +0,0 @@ -// functional/Closure5.java -// (c)2020 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. -// {WillNotCompile} -import java.util.function.*; - -public class Closure5 { - IntSupplier makeFun(int x) { - int i = 0; - i++; - x++; - return () -> x + i; - } -} diff --git a/code/functional/Closure6.java b/code/functional/Closure6.java deleted file mode 100644 index 178f9b4a..00000000 --- a/code/functional/Closure6.java +++ /dev/null @@ -1,16 +0,0 @@ -// functional/Closure6.java -// (c)2020 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. -import java.util.function.*; - -public class Closure6 { - IntSupplier makeFun(int x) { - int i = 0; - i++; - x++; - final int iFinal = i; - final int xFinal = x; - return () -> xFinal + iFinal; - } -} diff --git a/code/functional/Closure7.java b/code/functional/Closure7.java deleted file mode 100644 index 9facdc06..00000000 --- a/code/functional/Closure7.java +++ /dev/null @@ -1,14 +0,0 @@ -// functional/Closure7.java -// (c)2020 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. -// {WillNotCompile} -import java.util.function.*; - -public class Closure7 { - IntSupplier makeFun(int x) { - Integer i = 0; - i = i + 1; - return () -> x + i; - } -} diff --git a/code/functional/Closure8.java b/code/functional/Closure8.java deleted file mode 100644 index 7ec059b2..00000000 --- a/code/functional/Closure8.java +++ /dev/null @@ -1,32 +0,0 @@ -// functional/Closure8.java -// (c)2020 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. -import java.util.*; -import java.util.function.*; - -public class Closure8 { - Supplier> makeFun() { - final List ai = new ArrayList<>(); - ai.add(1); - return () -> ai; - } - public static void main(String[] args) { - Closure8 c7 = new Closure8(); - List - l1 = c7.makeFun().get(), - l2 = c7.makeFun().get(); - System.out.println(l1); - System.out.println(l2); - l1.add(42); - l2.add(96); - System.out.println(l1); - System.out.println(l2); - } -} -/* Output: -[1] -[1] -[1, 42] -[1, 96] -*/ diff --git a/code/functional/Closure9.java b/code/functional/Closure9.java deleted file mode 100644 index 4eddb47a..00000000 --- a/code/functional/Closure9.java +++ /dev/null @@ -1,15 +0,0 @@ -// functional/Closure9.java -// (c)2020 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. -// {WillNotCompile} -import java.util.*; -import java.util.function.*; - -public class Closure9 { - Supplier> makeFun() { - List ai = new ArrayList<>(); - ai = new ArrayList<>(); // Reassignment - return () -> ai; - } -} diff --git a/code/functional/ConsumeFunction.java b/code/functional/ConsumeFunction.java deleted file mode 100644 index ea84a24a..00000000 --- a/code/functional/ConsumeFunction.java +++ /dev/null @@ -1,17 +0,0 @@ -// functional/ConsumeFunction.java -// (c)2020 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. -import java.util.function.*; - -class One {} -class Two {} - -public class ConsumeFunction { - static Two consume(Function onetwo) { - return onetwo.apply(new One()); - } - public static void main(String[] args) { - Two two = consume(one -> new Two()); - } -} diff --git a/code/functional/CtorReference.java b/code/functional/CtorReference.java deleted file mode 100644 index 4c22bdf1..00000000 --- a/code/functional/CtorReference.java +++ /dev/null @@ -1,36 +0,0 @@ -// functional/CtorReference.java -// (c)2020 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. - -class Dog { - String name; - int age = -1; // For "unknown" - Dog() { name = "stray"; } - Dog(String nm) { name = nm; } - Dog(String nm, int yrs) { name = nm; age = yrs; } -} - -interface MakeNoArgs { - Dog make(); -} - -interface Make1Arg { - Dog make(String nm); -} - -interface Make2Args { - Dog make(String nm, int age); -} - -public class CtorReference { - public static void main(String[] args) { - MakeNoArgs mna = Dog::new; // [1] - Make1Arg m1a = Dog::new; // [2] - Make2Args m2a = Dog::new; // [3] - - Dog dn = mna.make(); - Dog d1 = m1a.make("Comet"); - Dog d2 = m2a.make("Ralph", 4); - } -} diff --git a/code/functional/CurriedIntAdd.java b/code/functional/CurriedIntAdd.java deleted file mode 100644 index e89ac8e2..00000000 --- a/code/functional/CurriedIntAdd.java +++ /dev/null @@ -1,17 +0,0 @@ -// functional/CurriedIntAdd.java -// (c)2020 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. -import java.util.function.*; - -public class CurriedIntAdd { - public static void main(String[] args) { - IntFunction - curriedIntAdd = a -> b -> a + b; - IntUnaryOperator add4 = curriedIntAdd.apply(4); - System.out.println(add4.applyAsInt(5)); - } -} -/* Output: -9 -*/ diff --git a/code/functional/Curry3Args.java b/code/functional/Curry3Args.java deleted file mode 100644 index 0fd376bc..00000000 --- a/code/functional/Curry3Args.java +++ /dev/null @@ -1,23 +0,0 @@ -// functional/Curry3Args.java -// (c)2020 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. -import java.util.function.*; - -public class Curry3Args { - public static void main(String[] args) { - Function>> sum = - a -> b -> c -> a + b + c; - Function> hi = - sum.apply("Hi "); - Function ho = - hi.apply("Ho "); - System.out.println(ho.apply("Hup")); - } -} -/* Output: -Hi Ho Hup -*/ diff --git a/code/functional/CurryingAndPartials.java b/code/functional/CurryingAndPartials.java deleted file mode 100644 index 0addb811..00000000 --- a/code/functional/CurryingAndPartials.java +++ /dev/null @@ -1,35 +0,0 @@ -// functional/CurryingAndPartials.java -// (c)2020 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. -import java.util.function.*; - -public class CurryingAndPartials { - // Uncurried: - static String uncurried(String a, String b) { - return a + b; - } - public static void main(String[] args) { - // Curried function: - Function> sum = - a -> b -> a + b; // [1] - - System.out.println(uncurried("Hi ", "Ho")); - - Function - hi = sum.apply("Hi "); // [2] - System.out.println(hi.apply("Ho")); - - // Partial application: - Function sumHi = - sum.apply("Hup "); - System.out.println(sumHi.apply("Ho")); - System.out.println(sumHi.apply("Hey")); - } -} -/* Output: -Hi Ho -Hi Ho -Hup Ho -Hup Hey -*/ diff --git a/code/functional/FunctionComposition.java b/code/functional/FunctionComposition.java deleted file mode 100644 index a183039d..00000000 --- a/code/functional/FunctionComposition.java +++ /dev/null @@ -1,24 +0,0 @@ -// functional/FunctionComposition.java -// (c)2020 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. -import java.util.function.*; - -public class FunctionComposition { - static Function - f1 = s -> { - System.out.println(s); - return s.replace('A', '_'); - }, - f2 = s -> s.substring(3), - f3 = s -> s.toLowerCase(), - f4 = f1.compose(f2).andThen(f3); - public static void main(String[] args) { - System.out.println( - f4.apply("GO AFTER ALL AMBULANCES")); - } -} -/* Output: -AFTER ALL AMBULANCES -_fter _ll _mbul_nces -*/ diff --git a/code/functional/FunctionVariants.java b/code/functional/FunctionVariants.java deleted file mode 100644 index a6205462..00000000 --- a/code/functional/FunctionVariants.java +++ /dev/null @@ -1,65 +0,0 @@ -// functional/FunctionVariants.java -// (c)2020 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. -import java.util.function.*; - -class Foo {} - -class Bar { - Foo f; - Bar(Foo f) { this.f = f; } -} - -class IBaz { - int i; - IBaz(int i) { - this.i = i; - } -} - -class LBaz { - long l; - LBaz(long l) { - this.l = l; - } -} - -class DBaz { - double d; - DBaz(double d) { - this.d = d; - } -} - -public class FunctionVariants { - static Function f1 = f -> new Bar(f); - static IntFunction f2 = i -> new IBaz(i); - static LongFunction f3 = l -> new LBaz(l); - static DoubleFunction f4 = d -> new DBaz(d); - static ToIntFunction f5 = ib -> ib.i; - static ToLongFunction f6 = lb -> lb.l; - static ToDoubleFunction f7 = db -> db.d; - static IntToLongFunction f8 = i -> i; - static IntToDoubleFunction f9 = i -> i; - static LongToIntFunction f10 = l -> (int)l; - static LongToDoubleFunction f11 = l -> l; - static DoubleToIntFunction f12 = d -> (int)d; - static DoubleToLongFunction f13 = d -> (long)d; - - public static void main(String[] args) { - Bar b = f1.apply(new Foo()); - IBaz ib = f2.apply(11); - LBaz lb = f3.apply(11); - DBaz db = f4.apply(11); - int i = f5.applyAsInt(ib); - long l = f6.applyAsLong(lb); - double d = f7.applyAsDouble(db); - l = f8.applyAsLong(12); - d = f9.applyAsDouble(12); - i = f10.applyAsInt(12); - d = f11.applyAsDouble(12); - i = f12.applyAsInt(13.0); - l = f13.applyAsLong(13.0); - } -} diff --git a/code/functional/FunctionWithWrapped.java b/code/functional/FunctionWithWrapped.java deleted file mode 100644 index b654da65..00000000 --- a/code/functional/FunctionWithWrapped.java +++ /dev/null @@ -1,12 +0,0 @@ -// functional/FunctionWithWrapped.java -// (c)2020 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. -import java.util.function.*; - -public class FunctionWithWrapped { - public static void main(String[] args) { - Function fid = i -> (double)i; - IntToDoubleFunction fid2 = i -> i; - } -} diff --git a/code/functional/FunctionalAnnotation.java b/code/functional/FunctionalAnnotation.java deleted file mode 100644 index 84cec649..00000000 --- a/code/functional/FunctionalAnnotation.java +++ /dev/null @@ -1,40 +0,0 @@ -// functional/FunctionalAnnotation.java -// (c)2020 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. - -@FunctionalInterface -interface Functional { - String goodbye(String arg); -} - -interface FunctionalNoAnn { - String goodbye(String arg); -} - -/* -@FunctionalInterface -interface NotFunctional { - String goodbye(String arg); - String hello(String arg); -} -Produces error message: -NotFunctional is not a functional interface -multiple non-overriding abstract methods -found in interface NotFunctional -*/ - -public class FunctionalAnnotation { - public String goodbye(String arg) { - return "Goodbye, " + arg; - } - public static void main(String[] args) { - FunctionalAnnotation fa = - new FunctionalAnnotation(); - Functional f = fa::goodbye; - FunctionalNoAnn fna = fa::goodbye; - // Functional fac = fa; // Incompatible - Functional fl = a -> "Goodbye, " + a; - FunctionalNoAnn fnal = a -> "Goodbye, " + a; - } -} diff --git a/code/functional/IntCall.java b/code/functional/IntCall.java deleted file mode 100644 index a8256a00..00000000 --- a/code/functional/IntCall.java +++ /dev/null @@ -1,8 +0,0 @@ -// functional/IntCall.java -// (c)2020 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. - -interface IntCall { - int call(int arg); -} diff --git a/code/functional/LambdaExpressions.java b/code/functional/LambdaExpressions.java deleted file mode 100644 index fe7e3acb..00000000 --- a/code/functional/LambdaExpressions.java +++ /dev/null @@ -1,48 +0,0 @@ -// functional/LambdaExpressions.java -// (c)2020 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. - -interface Description { - String brief(); -} - -interface Body { - String detailed(String head); -} - -interface Multi { - String twoArg(String head, Double d); -} - -public class LambdaExpressions { - - static Body bod = h -> h + " No Parens!"; // [1] - - static Body bod2 = (h) -> h + " More details"; // [2] - - static Description desc = () -> "Short info"; // [3] - - static Multi mult = (h, n) -> h + n; // [4] - - static Description moreLines = () -> { // [5] - System.out.println("moreLines()"); - return "from moreLines()"; - }; - - public static void main(String[] args) { - System.out.println(bod.detailed("Oh!")); - System.out.println(bod2.detailed("Hi!")); - System.out.println(desc.brief()); - System.out.println(mult.twoArg("Pi! ", 3.14159)); - System.out.println(moreLines.brief()); - } -} -/* Output: -Oh! No Parens! -Hi! More details -Short info -Pi! 3.14159 -moreLines() -from moreLines() -*/ diff --git a/code/functional/MethodConversion.java b/code/functional/MethodConversion.java deleted file mode 100644 index 008ecfc0..00000000 --- a/code/functional/MethodConversion.java +++ /dev/null @@ -1,31 +0,0 @@ -// functional/MethodConversion.java -// (c)2020 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. -import java.util.function.*; - -class In1 {} -class In2 {} - -public class MethodConversion { - static void accept(In1 i1, In2 i2) { - System.out.println("accept()"); - } - static void someOtherName(In1 i1, In2 i2) { - System.out.println("someOtherName()"); - } - public static void main(String[] args) { - BiConsumer bic; - - bic = MethodConversion::accept; - bic.accept(new In1(), new In2()); - - bic = MethodConversion::someOtherName; - // bic.someOtherName(new In1(), new In2()); // Nope - bic.accept(new In1(), new In2()); - } -} -/* Output: -accept() -someOtherName() -*/ diff --git a/code/functional/MethodReferences.java b/code/functional/MethodReferences.java deleted file mode 100644 index 63bc365d..00000000 --- a/code/functional/MethodReferences.java +++ /dev/null @@ -1,53 +0,0 @@ -// functional/MethodReferences.java -// (c)2020 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. -import java.util.*; - -interface Callable { // [1] - void call(String s); -} - -class Describe { - void show(String msg) { // [2] - System.out.println(msg); - } -} - -public class MethodReferences { - static void hello(String name) { // [3] - System.out.println("Hello, " + name); - } - static class Description { - String about; - Description(String desc) { about = desc; } - void help(String msg) { // [4] - System.out.println(about + " " + msg); - } - } - static class Helper { - static void assist(String msg) { // [5] - System.out.println(msg); - } - } - public static void main(String[] args) { - Describe d = new Describe(); - Callable c = d::show; // [6] - c.call("call()"); // [7] - - c = MethodReferences::hello; // [8] - c.call("Bob"); - - c = new Description("valuable")::help; // [9] - c.call("information"); - - c = Helper::assist; // [10] - c.call("Help!"); - } -} -/* Output: -call() -Hello, Bob -valuable information -Help! -*/ diff --git a/code/functional/MultiUnbound.java b/code/functional/MultiUnbound.java deleted file mode 100644 index 4209fb04..00000000 --- a/code/functional/MultiUnbound.java +++ /dev/null @@ -1,36 +0,0 @@ -// functional/MultiUnbound.java -// (c)2020 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. -// Unbound methods with multiple arguments - -class This { - void two(int i, double d) {} - void three(int i, double d, String s) {} - void four(int i, double d, String s, char c) {} -} - -interface TwoArgs { - void call2(This athis, int i, double d); -} - -interface ThreeArgs { - void call3(This athis, int i, double d, String s); -} - -interface FourArgs { - void call4( - This athis, int i, double d, String s, char c); -} - -public class MultiUnbound { - public static void main(String[] args) { - TwoArgs twoargs = This::two; - ThreeArgs threeargs = This::three; - FourArgs fourargs = This::four; - This athis = new This(); - twoargs.call2(athis, 11, 3.14); - threeargs.call3(athis, 11, 3.14, "Three"); - fourargs.call4(athis, 11, 3.14, "Four", 'Z'); - } -} diff --git a/code/functional/PredicateComposition.java b/code/functional/PredicateComposition.java deleted file mode 100644 index f95bbcbd..00000000 --- a/code/functional/PredicateComposition.java +++ /dev/null @@ -1,23 +0,0 @@ -// functional/PredicateComposition.java -// (c)2020 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. -import java.util.function.*; -import java.util.stream.*; - -public class PredicateComposition { - static Predicate - p1 = s -> s.contains("bar"), - p2 = s -> s.length() < 5, - p3 = s -> s.contains("foo"), - p4 = p1.negate().and(p2).or(p3); - public static void main(String[] args) { - Stream.of("bar", "foobar", "foobaz", "fongopuckey") - .filter(p4) - .forEach(System.out::println); - } -} -/* Output: -foobar -foobaz -*/ diff --git a/code/functional/ProduceFunction.java b/code/functional/ProduceFunction.java deleted file mode 100644 index 03471601..00000000 --- a/code/functional/ProduceFunction.java +++ /dev/null @@ -1,21 +0,0 @@ -// functional/ProduceFunction.java -// (c)2020 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. -import java.util.function.*; - -interface -FuncSS extends Function {} // [1] - -public class ProduceFunction { - static FuncSS produce() { - return s -> s.toLowerCase(); // [2] - } - public static void main(String[] args) { - FuncSS f = produce(); - System.out.println(f.apply("YELLING")); - } -} -/* Output: -yelling -*/ diff --git a/code/functional/RecursiveFactorial.java b/code/functional/RecursiveFactorial.java deleted file mode 100644 index 2d610441..00000000 --- a/code/functional/RecursiveFactorial.java +++ /dev/null @@ -1,26 +0,0 @@ -// functional/RecursiveFactorial.java -// (c)2020 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. - -public class RecursiveFactorial { - static IntCall fact; - public static void main(String[] args) { - fact = n -> n == 0 ? 1 : n * fact.call(n - 1); - for(int i = 0; i <= 10; i++) - System.out.println(fact.call(i)); - } -} -/* Output: -1 -1 -2 -6 -24 -120 -720 -5040 -40320 -362880 -3628800 -*/ diff --git a/code/functional/RecursiveFibonacci.java b/code/functional/RecursiveFibonacci.java deleted file mode 100644 index 9be43dc6..00000000 --- a/code/functional/RecursiveFibonacci.java +++ /dev/null @@ -1,32 +0,0 @@ -// functional/RecursiveFibonacci.java -// (c)2020 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. - -public class RecursiveFibonacci { - IntCall fib; - RecursiveFibonacci() { - fib = n -> n == 0 ? 0 : - n == 1 ? 1 : - fib.call(n - 1) + fib.call(n - 2); - } - int fibonacci(int n) { return fib.call(n); } - public static void main(String[] args) { - RecursiveFibonacci rf = new RecursiveFibonacci(); - for(int i = 0; i <= 10; i++) - System.out.println(rf.fibonacci(i)); - } -} -/* Output: -0 -1 -1 -2 -3 -5 -8 -13 -21 -34 -55 -*/ diff --git a/code/functional/RunnableMethodReference.java b/code/functional/RunnableMethodReference.java deleted file mode 100644 index 5fb8cd00..00000000 --- a/code/functional/RunnableMethodReference.java +++ /dev/null @@ -1,33 +0,0 @@ -// functional/RunnableMethodReference.java -// (c)2020 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. -// Method references with interface Runnable - -class Go { - static void go() { - System.out.println("Go::go()"); - } -} - -public class RunnableMethodReference { - public static void main(String[] args) { - - new Thread(new Runnable() { - public void run() { - System.out.println("Anonymous"); - } - }).start(); - - new Thread( - () -> System.out.println("lambda") - ).start(); - - new Thread(Go::go).start(); - } -} -/* Output: -Anonymous -lambda -Go::go() -*/ diff --git a/code/functional/SharedStorage.java b/code/functional/SharedStorage.java deleted file mode 100644 index c2a41f66..00000000 --- a/code/functional/SharedStorage.java +++ /dev/null @@ -1,22 +0,0 @@ -// functional/SharedStorage.java -// (c)2020 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. -import java.util.function.*; - -public class SharedStorage { - public static void main(String[] args) { - Closure1 c1 = new Closure1(); - IntSupplier f1 = c1.makeFun(0); - IntSupplier f2 = c1.makeFun(0); - IntSupplier f3 = c1.makeFun(0); - System.out.println(f1.getAsInt()); - System.out.println(f2.getAsInt()); - System.out.println(f3.getAsInt()); - } -} -/* Output: -0 -1 -2 -*/ diff --git a/code/functional/Strategize.java b/code/functional/Strategize.java deleted file mode 100644 index e46c9143..00000000 --- a/code/functional/Strategize.java +++ /dev/null @@ -1,58 +0,0 @@ -// functional/Strategize.java -// (c)2020 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. - -interface Strategy { - String approach(String msg); -} - -class Soft implements Strategy { - public String approach(String msg) { - return msg.toLowerCase() + "?"; - } -} - -class Unrelated { - static String twice(String msg) { - return msg + " " + msg; - } -} - -public class Strategize { - Strategy strategy; - String msg; - Strategize(String msg) { - strategy = new Soft(); // [1] - this.msg = msg; - } - void communicate() { - System.out.println(strategy.approach(msg)); - } - void changeStrategy(Strategy strategy) { - this.strategy = strategy; - } - public static void main(String[] args) { - Strategy[] strategies = { - new Strategy() { // [2] - public String approach(String msg) { - return msg.toUpperCase() + "!"; - } - }, - msg -> msg.substring(0, 5), // [3] - Unrelated::twice // [4] - }; - Strategize s = new Strategize("Hello there"); - s.communicate(); - for(Strategy newStrategy : strategies) { - s.changeStrategy(newStrategy); // [5] - s.communicate(); // [6] - } - } -} -/* Output: -hello there? -HELLO THERE! -Hello -Hello there Hello there -*/ diff --git a/code/functional/TransformFunction.java b/code/functional/TransformFunction.java deleted file mode 100644 index 1a046eb1..00000000 --- a/code/functional/TransformFunction.java +++ /dev/null @@ -1,35 +0,0 @@ -// functional/TransformFunction.java -// (c)2020 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. -import java.util.function.*; - -class I { - @Override - public String toString() { return "I"; } -} - -class O { - @Override - public String toString() { return "O"; } -} - -public class TransformFunction { - static Function transform(Function in) { - return in.andThen(o -> { - System.out.println(o); - return o; - }); - } - public static void main(String[] args) { - Function f2 = transform(i -> { - System.out.println(i); - return new O(); - }); - O o = f2.apply(new I()); - } -} -/* Output: -I -O -*/ diff --git a/code/functional/TriFunction.java b/code/functional/TriFunction.java deleted file mode 100644 index 76049621..00000000 --- a/code/functional/TriFunction.java +++ /dev/null @@ -1,9 +0,0 @@ -// functional/TriFunction.java -// (c)2020 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. - -@FunctionalInterface -public interface TriFunction { - R apply(T t, U u, V v); -} diff --git a/code/functional/TriFunctionTest.java b/code/functional/TriFunctionTest.java deleted file mode 100644 index fccf8b9a..00000000 --- a/code/functional/TriFunctionTest.java +++ /dev/null @@ -1,13 +0,0 @@ -// functional/TriFunctionTest.java -// (c)2020 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. - -public class TriFunctionTest { - static int f(int i, long l, double d) { return 99; } - public static void main(String[] args) { - TriFunction tf = - TriFunctionTest::f; - tf = (i, l, d) -> 12; - } -} diff --git a/code/functional/UnboundMethodReference.java b/code/functional/UnboundMethodReference.java deleted file mode 100644 index da2c7872..00000000 --- a/code/functional/UnboundMethodReference.java +++ /dev/null @@ -1,31 +0,0 @@ -// functional/UnboundMethodReference.java -// (c)2020 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. -// Method reference without an object - -class X { - String f() { return "X::f()"; } -} - -interface MakeString { - String make(); -} - -interface TransformX { - String transform(X x); -} - -public class UnboundMethodReference { - public static void main(String[] args) { - // MakeString ms = X::f; // [1] - TransformX sp = X::f; - X x = new X(); - System.out.println(sp.transform(x)); // [2] - System.out.println(x.f()); // Same effect - } -} -/* Output: -X::f() -X::f() -*/ diff --git a/code/generics/Amphibian.java b/code/generics/Amphibian.java deleted file mode 100644 index 5e76d8b1..00000000 --- a/code/generics/Amphibian.java +++ /dev/null @@ -1,5 +0,0 @@ -// generics/Amphibian.java -// (c)2020 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. -public class Amphibian {} diff --git a/code/generics/Apply.java b/code/generics/Apply.java deleted file mode 100644 index c9378611..00000000 --- a/code/generics/Apply.java +++ /dev/null @@ -1,21 +0,0 @@ -// generics/Apply.java -// (c)2020 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. -import java.lang.reflect.*; -import java.util.*; - -public class Apply { - public static > - void apply(S seq, Method f, Object... args) { - try { - for(T t: seq) - f.invoke(t, args); - } catch(IllegalAccessException | - IllegalArgumentException | - InvocationTargetException e) { - // Failures are programmer errors - throw new RuntimeException(e); - } - } -} diff --git a/code/generics/ApplyFunctional.java b/code/generics/ApplyFunctional.java deleted file mode 100644 index 4cce156e..00000000 --- a/code/generics/ApplyFunctional.java +++ /dev/null @@ -1,49 +0,0 @@ -// generics/ApplyFunctional.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import java.util.function.*; -import onjava.*; - -public class ApplyFunctional { - public static void main(String[] args) { - Stream.of( - Stream.generate(Shape::new).limit(2), - Stream.generate(Square::new).limit(2)) - .flatMap(c -> c) // flatten into one stream - .peek(Shape::rotate) - .forEach(s -> s.resize(7)); - - new FilledList<>(Shape::new, 2) - .forEach(Shape::rotate); - new FilledList<>(Square::new, 2) - .forEach(Shape::rotate); - - SimpleQueue shapeQ = Suppliers.fill( - new SimpleQueue<>(), SimpleQueue::add, - Shape::new, 2); - Suppliers.fill(shapeQ, SimpleQueue::add, - Square::new, 2); - shapeQ.forEach(Shape::rotate); - } -} -/* Output: -Shape 0 rotate -Shape 0 resize 7 -Shape 1 rotate -Shape 1 resize 7 -Square 2 rotate -Square 2 resize 7 -Square 3 rotate -Square 3 resize 7 -Shape 4 rotate -Shape 5 rotate -Square 6 rotate -Square 7 rotate -Shape 8 rotate -Shape 9 rotate -Square 10 rotate -Square 11 rotate -*/ diff --git a/code/generics/ApplyTest.java b/code/generics/ApplyTest.java deleted file mode 100644 index 62ef4eec..00000000 --- a/code/generics/ApplyTest.java +++ /dev/null @@ -1,65 +0,0 @@ -// generics/ApplyTest.java -// (c)2020 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. -import java.util.*; -import java.util.function.*; -import onjava.*; - -public class ApplyTest { - public static - void main(String[] args) throws Exception { - List shapes = - Suppliers.create(ArrayList::new, Shape::new, 3); - Apply.apply(shapes, - Shape.class.getMethod("rotate")); - Apply.apply(shapes, - Shape.class.getMethod("resize", int.class), 7); - - List squares = - Suppliers.create(ArrayList::new, Square::new, 3); - Apply.apply(squares, - Shape.class.getMethod("rotate")); - Apply.apply(squares, - Shape.class.getMethod("resize", int.class), 7); - - Apply.apply(new FilledList<>(Shape::new, 3), - Shape.class.getMethod("rotate")); - Apply.apply(new FilledList<>(Square::new, 3), - Shape.class.getMethod("rotate")); - - SimpleQueue shapeQ = Suppliers.fill( - new SimpleQueue<>(), SimpleQueue::add, - Shape::new, 3); - Suppliers.fill(shapeQ, SimpleQueue::add, - Square::new, 3); - Apply.apply(shapeQ, - Shape.class.getMethod("rotate")); - } -} -/* Output: -Shape 0 rotate -Shape 1 rotate -Shape 2 rotate -Shape 0 resize 7 -Shape 1 resize 7 -Shape 2 resize 7 -Square 3 rotate -Square 4 rotate -Square 5 rotate -Square 3 resize 7 -Square 4 resize 7 -Square 5 resize 7 -Shape 6 rotate -Shape 7 rotate -Shape 8 rotate -Square 9 rotate -Square 10 rotate -Square 11 rotate -Shape 12 rotate -Shape 13 rotate -Shape 14 rotate -Square 15 rotate -Square 16 rotate -Square 17 rotate -*/ diff --git a/code/generics/ArrayMaker.java b/code/generics/ArrayMaker.java deleted file mode 100644 index f1bb6b9a..00000000 --- a/code/generics/ArrayMaker.java +++ /dev/null @@ -1,24 +0,0 @@ -// generics/ArrayMaker.java -// (c)2020 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. -import java.lang.reflect.*; -import java.util.*; - -public class ArrayMaker { - private Class kind; - public ArrayMaker(Class kind) { this.kind = kind; } - @SuppressWarnings("unchecked") - T[] create(int size) { - return (T[])Array.newInstance(kind, size); - } - public static void main(String[] args) { - ArrayMaker stringMaker = - new ArrayMaker<>(String.class); - String[] stringArray = stringMaker.create(9); - System.out.println(Arrays.toString(stringArray)); - } -} -/* Output: -[null, null, null, null, null, null, null, null, null] -*/ diff --git a/code/generics/ArrayOfGeneric.java b/code/generics/ArrayOfGeneric.java deleted file mode 100644 index 67e6cb97..00000000 --- a/code/generics/ArrayOfGeneric.java +++ /dev/null @@ -1,28 +0,0 @@ -// generics/ArrayOfGeneric.java -// (c)2020 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. - -public class ArrayOfGeneric { - static final int SIZE = 100; - static Generic[] gia; - @SuppressWarnings("unchecked") - public static void main(String[] args) { - try { - gia = (Generic[])new Object[SIZE]; - } catch(ClassCastException e) { - System.out.println(e.getMessage()); - } - // Runtime type is the raw (erased) type: - gia = (Generic[])new Generic[SIZE]; - System.out.println(gia.getClass().getSimpleName()); - gia[0] = new Generic<>(); - //- gia[1] = new Object(); // Compile-time error - // Discovers type mismatch at compile time: - //- gia[2] = new Generic(); - } -} -/* Output: -[Ljava.lang.Object; cannot be cast to [LGeneric; -Generic[] -*/ diff --git a/code/generics/ArrayOfGenericReference.java b/code/generics/ArrayOfGenericReference.java deleted file mode 100644 index 1cb2f345..00000000 --- a/code/generics/ArrayOfGenericReference.java +++ /dev/null @@ -1,10 +0,0 @@ -// generics/ArrayOfGenericReference.java -// (c)2020 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. - -class Generic {} - -public class ArrayOfGenericReference { - static Generic[] gia; -} diff --git a/code/generics/BankTeller.java b/code/generics/BankTeller.java deleted file mode 100644 index 68301996..00000000 --- a/code/generics/BankTeller.java +++ /dev/null @@ -1,71 +0,0 @@ -// generics/BankTeller.java -// (c)2020 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. -// A very simple bank teller simulation -import java.util.*; -import onjava.*; - -class Customer { - private static long counter = 1; - private final long id = counter++; - @Override - public String toString() { - return "Customer " + id; - } -} - -class Teller { - private static long counter = 1; - private final long id = counter++; - @Override - public String toString() { - return "Teller " + id; - } -} - -class Bank { - private List tellers = - new ArrayList<>(); - public void put(BankTeller bt) { - tellers.add(bt); - } -} - -public class BankTeller { - public static void serve(Teller t, Customer c) { - System.out.println(t + " serves " + c); - } - public static void main(String[] args) { - // Demonstrate create(): - RandomList tellers = - Suppliers.create( - RandomList::new, Teller::new, 4); - // Demonstrate fill(): - List customers = Suppliers.fill( - new ArrayList<>(), Customer::new, 12); - customers.forEach(c -> - serve(tellers.select(), c)); - // Demonstrate assisted latent typing: - Bank bank = Suppliers.fill( - new Bank(), Bank::put, BankTeller::new, 3); - // Can also use second version of fill(): - List customers2 = Suppliers.fill( - new ArrayList<>(), - List::add, Customer::new, 12); - } -} -/* Output: -Teller 3 serves Customer 1 -Teller 2 serves Customer 2 -Teller 3 serves Customer 3 -Teller 1 serves Customer 4 -Teller 1 serves Customer 5 -Teller 3 serves Customer 6 -Teller 1 serves Customer 7 -Teller 2 serves Customer 8 -Teller 3 serves Customer 9 -Teller 3 serves Customer 10 -Teller 2 serves Customer 11 -Teller 4 serves Customer 12 -*/ diff --git a/code/generics/BasicBounds.java b/code/generics/BasicBounds.java deleted file mode 100644 index 434d0fd8..00000000 --- a/code/generics/BasicBounds.java +++ /dev/null @@ -1,63 +0,0 @@ -// generics/BasicBounds.java -// (c)2020 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. - -interface HasColor { java.awt.Color getColor(); } - -class WithColor { - T item; - WithColor(T item) { this.item = item; } - T getItem() { return item; } - // The bound allows you to call a method: - java.awt.Color color() { return item.getColor(); } -} - -class Coord { public int x, y, z; } - -// This fails. Class must be first, then interfaces: -// class WithColorCoord { - -// Multiple bounds: -class WithColorCoord { - T item; - WithColorCoord(T item) { this.item = item; } - T getItem() { return item; } - java.awt.Color color() { return item.getColor(); } - int getX() { return item.x; } - int getY() { return item.y; } - int getZ() { return item.z; } -} - -interface Weight { int weight(); } - -// As with inheritance, you can have only one -// concrete class but multiple interfaces: -class Solid { - T item; - Solid(T item) { this.item = item; } - T getItem() { return item; } - java.awt.Color color() { return item.getColor(); } - int getX() { return item.x; } - int getY() { return item.y; } - int getZ() { return item.z; } - int weight() { return item.weight(); } -} - -class Bounded -extends Coord implements HasColor, Weight { - @Override - public java.awt.Color getColor() { return null; } - @Override - public int weight() { return 0; } -} - -public class BasicBounds { - public static void main(String[] args) { - Solid solid = - new Solid<>(new Bounded()); - solid.color(); - solid.getY(); - solid.weight(); - } -} diff --git a/code/generics/BasicHolder.java b/code/generics/BasicHolder.java deleted file mode 100644 index 2b8b8a9b..00000000 --- a/code/generics/BasicHolder.java +++ /dev/null @@ -1,14 +0,0 @@ -// generics/BasicHolder.java -// (c)2020 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. - -public class BasicHolder { - T element; - void set(T arg) { element = arg; } - T get() { return element; } - void f() { - System.out.println( - element.getClass().getSimpleName()); - } -} diff --git a/code/generics/BasicSupplierDemo.java b/code/generics/BasicSupplierDemo.java deleted file mode 100644 index 1ce95ca1..00000000 --- a/code/generics/BasicSupplierDemo.java +++ /dev/null @@ -1,22 +0,0 @@ -// generics/BasicSupplierDemo.java -// (c)2020 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. -import onjava.*; -import java.util.stream.*; - -public class BasicSupplierDemo { - public static void main(String[] args) { - Stream.generate( - BasicSupplier.create(CountedObject.class)) - .limit(5) - .forEach(System.out::println); - } -} -/* Output: -CountedObject 0 -CountedObject 1 -CountedObject 2 -CountedObject 3 -CountedObject 4 -*/ diff --git a/code/generics/ByteSet.java b/code/generics/ByteSet.java deleted file mode 100644 index 19b27091..00000000 --- a/code/generics/ByteSet.java +++ /dev/null @@ -1,14 +0,0 @@ -// generics/ByteSet.java -// (c)2020 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. -import java.util.*; - -public class ByteSet { - Byte[] possibles = { 1,2,3,4,5,6,7,8,9 }; - Set mySet = - new HashSet<>(Arrays.asList(possibles)); - // But you can't do this: - // Set mySet2 = new HashSet<>( - // Arrays.asList(1,2,3,4,5,6,7,8,9)); -} diff --git a/code/generics/CRGWithBasicHolder.java b/code/generics/CRGWithBasicHolder.java deleted file mode 100644 index eb85868a..00000000 --- a/code/generics/CRGWithBasicHolder.java +++ /dev/null @@ -1,20 +0,0 @@ -// generics/CRGWithBasicHolder.java -// (c)2020 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. - -class Subtype extends BasicHolder {} - -public class CRGWithBasicHolder { - public static void main(String[] args) { - Subtype - st1 = new Subtype(), - st2 = new Subtype(); - st1.set(st2); - Subtype st3 = st1.get(); - st1.f(); - } -} -/* Output: -Subtype -*/ diff --git a/code/generics/CaptureConversion.java b/code/generics/CaptureConversion.java deleted file mode 100644 index 16348468..00000000 --- a/code/generics/CaptureConversion.java +++ /dev/null @@ -1,62 +0,0 @@ -// generics/CaptureConversion.java -// (c)2020 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. - -public class CaptureConversion { - static void f1(Holder holder) { - T t = holder.get(); - System.out.println(t.getClass().getSimpleName()); - } - static void f2(Holder holder) { - f1(holder); // Call with captured type - } - @SuppressWarnings("unchecked") - public static void main(String[] args) { - Holder raw = new Holder<>(1); - - f1(raw); - // warning: [unchecked] unchecked method invocation: - // method f1 in class CaptureConversion - // is applied to given types - // f1(raw); - // ^ - // required: Holder - // found: Holder - // where T is a type-variable: - // T extends Object declared in - // method f1(Holder) - // warning: [unchecked] unchecked conversion - // f1(raw); - // ^ - // required: Holder - // found: Holder - // where T is a type-variable: - // T extends Object declared in - // method f1(Holder) - // 2 warnings - - f2(raw); // No warnings - Holder rawBasic = new Holder(); - - rawBasic.set(new Object()); - // warning: [unchecked] unchecked call to set(T) - // as a member of the raw type Holder - // rawBasic.set(new Object()); - // ^ - // where T is a type-variable: - // T extends Object declared in class Holder - // 1 warning - - f2(rawBasic); // No warnings - // Upcast to Holder, still figures it out: - Holder wildcarded = new Holder<>(1.0); - f2(wildcarded); - } -} -/* Output: -Integer -Integer -Object -Double -*/ diff --git a/code/generics/CheckedList.java b/code/generics/CheckedList.java deleted file mode 100644 index 6e330cf6..00000000 --- a/code/generics/CheckedList.java +++ /dev/null @@ -1,35 +0,0 @@ -// generics/CheckedList.java -// (c)2020 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. -// Using Collection.checkedList() -import typeinfo.pets.*; -import java.util.*; - -public class CheckedList { - @SuppressWarnings("unchecked") - static void oldStyleMethod(List probablyDogs) { - probablyDogs.add(new Cat()); - } - public static void main(String[] args) { - List dogs1 = new ArrayList<>(); - oldStyleMethod(dogs1); // Quietly accepts a Cat - List dogs2 = Collections.checkedList( - new ArrayList<>(), Dog.class); - try { - oldStyleMethod(dogs2); // Throws an exception - } catch(Exception e) { - System.out.println("Expected: " + e); - } - // Derived types work fine: - List pets = Collections.checkedList( - new ArrayList<>(), Pet.class); - pets.add(new Dog()); - pets.add(new Cat()); - } -} -/* Output: -Expected: java.lang.ClassCastException: Attempt to -insert class typeinfo.pets.Cat element into collection -with element type class typeinfo.pets.Dog -*/ diff --git a/code/generics/ClassCasting.java b/code/generics/ClassCasting.java deleted file mode 100644 index c6da592a..00000000 --- a/code/generics/ClassCasting.java +++ /dev/null @@ -1,18 +0,0 @@ -// generics/ClassCasting.java -// (c)2020 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. -import java.io.*; -import java.util.*; - -public class ClassCasting { - @SuppressWarnings("unchecked") - public void f(String[] args) throws Exception { - ObjectInputStream in = new ObjectInputStream( - new FileInputStream(args[0])); - // Won't Compile: -// List lw1 = -// List<>.class.cast(in.readObject()); - List lw2 = List.class.cast(in.readObject()); - } -} diff --git a/code/generics/ClassTypeCapture.java b/code/generics/ClassTypeCapture.java deleted file mode 100644 index ab193dfe..00000000 --- a/code/generics/ClassTypeCapture.java +++ /dev/null @@ -1,33 +0,0 @@ -// generics/ClassTypeCapture.java -// (c)2020 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. - -class Building {} -class House extends Building {} - -public class ClassTypeCapture { - Class kind; - public ClassTypeCapture(Class kind) { - this.kind = kind; - } - public boolean f(Object arg) { - return kind.isInstance(arg); - } - public static void main(String[] args) { - ClassTypeCapture ctt1 = - new ClassTypeCapture<>(Building.class); - System.out.println(ctt1.f(new Building())); - System.out.println(ctt1.f(new House())); - ClassTypeCapture ctt2 = - new ClassTypeCapture<>(House.class); - System.out.println(ctt2.f(new Building())); - System.out.println(ctt2.f(new House())); - } -} -/* Output: -true -true -false -true -*/ diff --git a/code/generics/ComparablePet.java b/code/generics/ComparablePet.java deleted file mode 100644 index 3646e66a..00000000 --- a/code/generics/ComparablePet.java +++ /dev/null @@ -1,12 +0,0 @@ -// generics/ComparablePet.java -// (c)2020 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. - -public class ComparablePet -implements Comparable { - @Override - public int compareTo(ComparablePet arg) { - return 0; - } -} diff --git a/code/generics/CompilerIntelligence.java b/code/generics/CompilerIntelligence.java deleted file mode 100644 index 6e4cd0e8..00000000 --- a/code/generics/CompilerIntelligence.java +++ /dev/null @@ -1,15 +0,0 @@ -// generics/CompilerIntelligence.java -// (c)2020 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. -import java.util.*; - -public class CompilerIntelligence { - public static void main(String[] args) { - List flist = - Arrays.asList(new Apple()); - Apple a = (Apple)flist.get(0); // No warning - flist.contains(new Apple()); // Argument is 'Object' - flist.indexOf(new Apple()); // Argument is 'Object' - } -} diff --git a/code/generics/CountedObject.java b/code/generics/CountedObject.java deleted file mode 100644 index ab4caecd..00000000 --- a/code/generics/CountedObject.java +++ /dev/null @@ -1,14 +0,0 @@ -// generics/CountedObject.java -// (c)2020 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. - -public class CountedObject { - private static long counter = 0; - private final long id = counter++; - public long id() { return id; } - @Override - public String toString() { - return "CountedObject " + id; - } -} diff --git a/code/generics/CovariantArrays.java b/code/generics/CovariantArrays.java deleted file mode 100644 index e202ca07..00000000 --- a/code/generics/CovariantArrays.java +++ /dev/null @@ -1,30 +0,0 @@ -// generics/CovariantArrays.java -// (c)2020 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. - -class Fruit {} -class Apple extends Fruit {} -class Jonathan extends Apple {} -class Orange extends Fruit {} - -public class CovariantArrays { - public static void main(String[] args) { - Fruit[] fruit = new Apple[10]; - fruit[0] = new Apple(); // OK - fruit[1] = new Jonathan(); // OK - // Runtime type is Apple[], not Fruit[] or Orange[]: - try { - // Compiler allows you to add Fruit: - fruit[0] = new Fruit(); // ArrayStoreException - } catch(Exception e) { System.out.println(e); } - try { - // Compiler allows you to add Oranges: - fruit[0] = new Orange(); // ArrayStoreException - } catch(Exception e) { System.out.println(e); } - } -} -/* Output: -java.lang.ArrayStoreException: Fruit -java.lang.ArrayStoreException: Orange -*/ diff --git a/code/generics/CovariantReturnTypes.java b/code/generics/CovariantReturnTypes.java deleted file mode 100644 index 04178ad4..00000000 --- a/code/generics/CovariantReturnTypes.java +++ /dev/null @@ -1,23 +0,0 @@ -// generics/CovariantReturnTypes.java -// (c)2020 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. - -class Base {} -class Derived extends Base {} - -interface OrdinaryGetter { - Base get(); -} - -interface DerivedGetter extends OrdinaryGetter { - // Overridden method return type can vary: - @Override - Derived get(); -} - -public class CovariantReturnTypes { - void test(DerivedGetter d) { - Derived d2 = d.get(); - } -} diff --git a/code/generics/CreatorGeneric.java b/code/generics/CreatorGeneric.java deleted file mode 100644 index 7fd90df4..00000000 --- a/code/generics/CreatorGeneric.java +++ /dev/null @@ -1,31 +0,0 @@ -// generics/CreatorGeneric.java -// (c)2020 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. - -abstract class GenericWithCreate { - final T element; - GenericWithCreate() { element = create(); } - abstract T create(); -} - -class X {} - -class XCreator extends GenericWithCreate { - @Override - X create() { return new X(); } - void f() { - System.out.println( - element.getClass().getSimpleName()); - } -} - -public class CreatorGeneric { - public static void main(String[] args) { - XCreator xc = new XCreator(); - xc.f(); - } -} -/* Output: -X -*/ diff --git a/code/generics/CuriouslyRecurringGeneric.java b/code/generics/CuriouslyRecurringGeneric.java deleted file mode 100644 index ee1f3a61..00000000 --- a/code/generics/CuriouslyRecurringGeneric.java +++ /dev/null @@ -1,9 +0,0 @@ -// generics/CuriouslyRecurringGeneric.java -// (c)2020 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. - -class GenericType {} - -public class CuriouslyRecurringGeneric - extends GenericType {} diff --git a/code/generics/Diamond.java b/code/generics/Diamond.java deleted file mode 100644 index 32c3ff1a..00000000 --- a/code/generics/Diamond.java +++ /dev/null @@ -1,13 +0,0 @@ -// generics/Diamond.java -// (c)2020 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. - -class Bob {} - -public class Diamond { - public static void main(String[] args) { - GenericHolder h3 = new GenericHolder<>(); - h3.set(new Bob()); - } -} diff --git a/code/generics/DogsAndRobotMethodReferences.java b/code/generics/DogsAndRobotMethodReferences.java deleted file mode 100644 index 7c3fa357..00000000 --- a/code/generics/DogsAndRobotMethodReferences.java +++ /dev/null @@ -1,45 +0,0 @@ -// generics/DogsAndRobotMethodReferences.java -// (c)2020 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. -// "Assisted Latent Typing" -import typeinfo.pets.*; -import java.util.function.*; - -class PerformingDogA extends Dog { - public void speak() { System.out.println("Woof!"); } - public void sit() { System.out.println("Sitting"); } - public void reproduce() {} -} - -class RobotA { - public void speak() { System.out.println("Click!"); } - public void sit() { System.out.println("Clank!"); } - public void oilChange() {} -} - -class CommunicateA { - public static

void perform(P performer, - Consumer

action1, Consumer

action2) { - action1.accept(performer); - action2.accept(performer); - } -} - -public class DogsAndRobotMethodReferences { - public static void main(String[] args) { - CommunicateA.perform(new PerformingDogA(), - PerformingDogA::speak, PerformingDogA::sit); - CommunicateA.perform(new RobotA(), - RobotA::speak, RobotA::sit); - CommunicateA.perform(new Mime(), - Mime::walkAgainstTheWind, - Mime::pushInvisibleWalls); - } -} -/* Output: -Woof! -Sitting -Click! -Clank! -*/ diff --git a/code/generics/DogsAndRobots.cpp b/code/generics/DogsAndRobots.cpp deleted file mode 100644 index 81ced5d9..00000000 --- a/code/generics/DogsAndRobots.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// generics/DogsAndRobots.cpp -// (c)2020 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. -#include -using namespace std; - -class Dog { -public: - void speak() { cout << "Arf!" << endl; } - void sit() { cout << "Sitting" << endl; } - void reproduce() {} -}; - -class Robot { -public: - void speak() { cout << "Click!" << endl; } - void sit() { cout << "Clank!" << endl; } - void oilChange() {} -}; - -template void perform(T anything) { - anything.speak(); - anything.sit(); -} - -int main() { - Dog d; - Robot r; - perform(d); - perform(r); -} -/* Output: -Arf! -Sitting -Click! -Clank! -*/ diff --git a/code/generics/DogsAndRobots.java b/code/generics/DogsAndRobots.java deleted file mode 100644 index b6151122..00000000 --- a/code/generics/DogsAndRobots.java +++ /dev/null @@ -1,41 +0,0 @@ -// generics/DogsAndRobots.java -// (c)2020 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. -// No (direct) latent typing in Java -import typeinfo.pets.*; - -class PerformingDog extends Dog implements Performs { - @Override - public void speak() { System.out.println("Woof!"); } - @Override - public void sit() { System.out.println("Sitting"); } - public void reproduce() {} -} - -class Robot implements Performs { - public void speak() { System.out.println("Click!"); } - public void sit() { System.out.println("Clank!"); } - public void oilChange() {} -} - -class Communicate { - public static - void perform(T performer) { - performer.speak(); - performer.sit(); - } -} - -public class DogsAndRobots { - public static void main(String[] args) { - Communicate.perform(new PerformingDog()); - Communicate.perform(new Robot()); - } -} -/* Output: -Woof! -Sitting -Click! -Clank! -*/ diff --git a/code/generics/DogsAndRobots.py b/code/generics/DogsAndRobots.py deleted file mode 100644 index c9ca6fef..00000000 --- a/code/generics/DogsAndRobots.py +++ /dev/null @@ -1,36 +0,0 @@ -# generics/DogsAndRobots.py -# (c)2020 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. - -class Dog: - def speak(self): - print("Arf!") - def sit(self): - print("Sitting") - def reproduce(self): - pass - -class Robot: - def speak(self): - print("Click!") - def sit(self): - print("Clank!") - def oilChange(self): - pass - -def perform(anything): - anything.speak() - anything.sit() - -a = Dog() -b = Robot() -perform(a) -perform(b) - -output = """ -Arf! -Sitting -Click! -Clank! -""" diff --git a/code/generics/DynamicProxyMixin.java b/code/generics/DynamicProxyMixin.java deleted file mode 100644 index 38431e31..00000000 --- a/code/generics/DynamicProxyMixin.java +++ /dev/null @@ -1,66 +0,0 @@ -// generics/DynamicProxyMixin.java -// (c)2020 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. -import java.lang.reflect.*; -import java.util.*; -import onjava.*; -import static onjava.Tuple.*; - -class MixinProxy implements InvocationHandler { - Map delegatesByMethod; - @SuppressWarnings("unchecked") - MixinProxy(Tuple2>... pairs) { - delegatesByMethod = new HashMap<>(); - for(Tuple2> pair : pairs) { - for(Method method : pair.a2.getMethods()) { - String methodName = method.getName(); - // The first interface in the map - // implements the method. - if(!delegatesByMethod.containsKey(methodName)) - delegatesByMethod.put(methodName, pair.a1); - } - } - } - @Override - public Object invoke(Object proxy, Method method, - Object[] args) throws Throwable { - String methodName = method.getName(); - Object delegate = delegatesByMethod.get(methodName); - return method.invoke(delegate, args); - } - @SuppressWarnings("unchecked") - public static Object newInstance(Tuple2... pairs) { - Class[] interfaces = new Class[pairs.length]; - for(int i = 0; i < pairs.length; i++) { - interfaces[i] = (Class)pairs[i].a2; - } - ClassLoader cl = - pairs[0].a1.getClass().getClassLoader(); - return Proxy.newProxyInstance( - cl, interfaces, new MixinProxy(pairs)); - } -} - -public class DynamicProxyMixin { - public static void main(String[] args) { - @SuppressWarnings("unchecked") - Object mixin = MixinProxy.newInstance( - tuple(new BasicImp(), Basic.class), - tuple(new TimeStampedImp(), TimeStamped.class), - tuple(new SerialNumberedImp(), - SerialNumbered.class)); - Basic b = (Basic)mixin; - TimeStamped t = (TimeStamped)mixin; - SerialNumbered s = (SerialNumbered)mixin; - b.set("Hello"); - System.out.println(b.get()); - System.out.println(t.getStamp()); - System.out.println(s.getSerialNumber()); - } -} -/* Output: -Hello -1494331653339 -1 -*/ diff --git a/code/generics/EpicBattle.java b/code/generics/EpicBattle.java deleted file mode 100644 index 908a3343..00000000 --- a/code/generics/EpicBattle.java +++ /dev/null @@ -1,74 +0,0 @@ -// generics/EpicBattle.java -// (c)2020 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. -// Bounds in Java generics -import java.util.*; - -interface SuperPower {} - -interface XRayVision extends SuperPower { - void seeThroughWalls(); -} - -interface SuperHearing extends SuperPower { - void hearSubtleNoises(); -} - -interface SuperSmell extends SuperPower { - void trackBySmell(); -} - -class SuperHero { - POWER power; - SuperHero(POWER power) { this.power = power; } - POWER getPower() { return power; } -} - -class SuperSleuth -extends SuperHero { - SuperSleuth(POWER power) { super(power); } - void see() { power.seeThroughWalls(); } -} - -class -CanineHero -extends SuperHero { - CanineHero(POWER power) { super(power); } - void hear() { power.hearSubtleNoises(); } - void smell() { power.trackBySmell(); } -} - -class SuperHearSmell -implements SuperHearing, SuperSmell { - @Override - public void hearSubtleNoises() {} - @Override - public void trackBySmell() {} -} - -class DogPerson extends CanineHero { - DogPerson() { super(new SuperHearSmell()); } -} - -public class EpicBattle { - // Bounds in generic methods: - static - void useSuperHearing(SuperHero hero) { - hero.getPower().hearSubtleNoises(); - } - static - void superFind(SuperHero hero) { - hero.getPower().hearSubtleNoises(); - hero.getPower().trackBySmell(); - } - public static void main(String[] args) { - DogPerson dogPerson = new DogPerson(); - useSuperHearing(dogPerson); - superFind(dogPerson); - // You can do this: - List audioPeople; - // But you can't do this: - // List dogPs; - } -} diff --git a/code/generics/Erased.java b/code/generics/Erased.java deleted file mode 100644 index 911839c3..00000000 --- a/code/generics/Erased.java +++ /dev/null @@ -1,24 +0,0 @@ -// generics/Erased.java -// (c)2020 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. -// {WillNotCompile} - -public class Erased { - private final int SIZE = 100; - public void f(Object arg) { - - // error: illegal generic type for instanceof - if(arg instanceof T) {} - - // error: unexpected type - T var = new T(); - - // error: generic array creation - T[] array = new T[SIZE]; - - // warning: [unchecked] unchecked cast - T[] array = (T[])new Object[SIZE]; - - } -} diff --git a/code/generics/ErasedTypeEquivalence.java b/code/generics/ErasedTypeEquivalence.java deleted file mode 100644 index 6034b304..00000000 --- a/code/generics/ErasedTypeEquivalence.java +++ /dev/null @@ -1,16 +0,0 @@ -// generics/ErasedTypeEquivalence.java -// (c)2020 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. -import java.util.*; - -public class ErasedTypeEquivalence { - public static void main(String[] args) { - Class c1 = new ArrayList().getClass(); - Class c2 = new ArrayList().getClass(); - System.out.println(c1 == c2); - } -} -/* Output: -true -*/ diff --git a/code/generics/ErasureAndInheritance.java b/code/generics/ErasureAndInheritance.java deleted file mode 100644 index 44a07b62..00000000 --- a/code/generics/ErasureAndInheritance.java +++ /dev/null @@ -1,28 +0,0 @@ -// generics/ErasureAndInheritance.java -// (c)2020 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. - -class GenericBase { - private T element; - public void set(T arg) { element = arg; } - public T get() { return element; } -} - -class Derived1 extends GenericBase {} - -class Derived2 extends GenericBase {} // No warning - -// class Derived3 extends GenericBase {} -// Strange error: -// unexpected type -// required: class or interface without bounds - -public class ErasureAndInheritance { - @SuppressWarnings("unchecked") - public static void main(String[] args) { - Derived2 d2 = new Derived2(); - Object obj = d2.get(); - d2.set(obj); // Warning here! - } -} diff --git a/code/generics/FactoryConstraint.java b/code/generics/FactoryConstraint.java deleted file mode 100644 index f0651073..00000000 --- a/code/generics/FactoryConstraint.java +++ /dev/null @@ -1,62 +0,0 @@ -// generics/FactoryConstraint.java -// (c)2020 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. -import java.util.*; -import java.util.function.*; -import onjava.*; - -class IntegerFactory implements Supplier { - private int i = 0; - @Override - public Integer get() { - return ++i; - } -} - -class Widget { - private int id; - Widget(int n) { id = n; } - @Override - public String toString() { - return "Widget " + id; - } - public static - class Factory implements Supplier { - private int i = 0; - @Override - public Widget get() { return new Widget(++i); } - } -} - -class Fudge { - private static int count = 1; - private int n = count++; - @Override - public String toString() { return "Fudge " + n; } -} - -class Foo2 { - private List x = new ArrayList<>(); - Foo2(Supplier factory) { - Suppliers.fill(x, factory, 5); - } - @Override - public String toString() { return x.toString(); } -} - -public class FactoryConstraint { - public static void main(String[] args) { - System.out.println( - new Foo2<>(new IntegerFactory())); - System.out.println( - new Foo2<>(new Widget.Factory())); - System.out.println( - new Foo2<>(Fudge::new)); - } -} -/* Output: -[1, 2, 3, 4, 5] -[Widget 1, Widget 2, Widget 3, Widget 4, Widget 5] -[Fudge 1, Fudge 2, Fudge 3, Fudge 4, Fudge 5] -*/ diff --git a/code/generics/Fibonacci.java b/code/generics/Fibonacci.java deleted file mode 100644 index 11540061..00000000 --- a/code/generics/Fibonacci.java +++ /dev/null @@ -1,27 +0,0 @@ -// generics/Fibonacci.java -// (c)2020 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. -// Generate a Fibonacci sequence -import java.util.function.*; -import java.util.stream.*; - -public class Fibonacci implements Supplier { - private int count = 0; - @Override - public Integer get() { return fib(count++); } - private int fib(int n) { - if(n < 2) return 1; - return fib(n-2) + fib(n-1); - } - public static void main(String[] args) { - Stream.generate(new Fibonacci()) - .limit(18) - .map(n -> n + " ") - .forEach(System.out::print); - } -} -/* Output: -1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 -2584 -*/ diff --git a/code/generics/FilledList.java b/code/generics/FilledList.java deleted file mode 100644 index e24423ce..00000000 --- a/code/generics/FilledList.java +++ /dev/null @@ -1,28 +0,0 @@ -// generics/FilledList.java -// (c)2020 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. -import java.util.*; -import java.util.function.*; -import onjava.*; - -public class FilledList extends ArrayList { - FilledList(Supplier gen, int size) { - Suppliers.fill(this, gen, size); - } - public FilledList(T t, int size) { - for(int i = 0; i < size; i++) - this.add(t); - } - public static void main(String[] args) { - List list = new FilledList<>("Hello", 4); - System.out.println(list); - // Supplier version: - List ilist = new FilledList<>(() -> 47, 4); - System.out.println(ilist); - } -} -/* Output: -[Hello, Hello, Hello, Hello] -[47, 47, 47, 47] -*/ diff --git a/code/generics/GenericArray.java b/code/generics/GenericArray.java deleted file mode 100644 index f0ffba3d..00000000 --- a/code/generics/GenericArray.java +++ /dev/null @@ -1,32 +0,0 @@ -// generics/GenericArray.java -// (c)2020 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. - -public class GenericArray { - private T[] array; - @SuppressWarnings("unchecked") - public GenericArray(int sz) { - array = (T[])new Object[sz]; - } - public void put(int index, T item) { - array[index] = item; - } - public T get(int index) { return array[index]; } - // Method that exposes the underlying representation: - public T[] rep() { return array; } - public static void main(String[] args) { - GenericArray gai = new GenericArray<>(10); - try { - Integer[] ia = gai.rep(); - } catch(ClassCastException e) { - System.out.println(e.getMessage()); - } - // This is OK: - Object[] oa = gai.rep(); - } -} -/* Output: -[Ljava.lang.Object; cannot be cast to -[Ljava.lang.Integer; -*/ diff --git a/code/generics/GenericArray2.java b/code/generics/GenericArray2.java deleted file mode 100644 index 7ef4179e..00000000 --- a/code/generics/GenericArray2.java +++ /dev/null @@ -1,39 +0,0 @@ -// generics/GenericArray2.java -// (c)2020 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. - -public class GenericArray2 { - private Object[] array; - public GenericArray2(int sz) { - array = new Object[sz]; - } - public void put(int index, T item) { - array[index] = item; - } - @SuppressWarnings("unchecked") - public T get(int index) { return (T)array[index]; } - @SuppressWarnings("unchecked") - public T[] rep() { - return (T[])array; // Unchecked cast - } - public static void main(String[] args) { - GenericArray2 gai = - new GenericArray2<>(10); - for(int i = 0; i < 10; i ++) - gai.put(i, i); - for(int i = 0; i < 10; i ++) - System.out.print(gai.get(i) + " "); - System.out.println(); - try { - Integer[] ia = gai.rep(); - } catch(Exception e) { - System.out.println(e); - } - } -} -/* Output: -0 1 2 3 4 5 6 7 8 9 -java.lang.ClassCastException: [Ljava.lang.Object; -cannot be cast to [Ljava.lang.Integer; -*/ diff --git a/code/generics/GenericArrayWithTypeToken.java b/code/generics/GenericArrayWithTypeToken.java deleted file mode 100644 index 6ea36a76..00000000 --- a/code/generics/GenericArrayWithTypeToken.java +++ /dev/null @@ -1,27 +0,0 @@ -// generics/GenericArrayWithTypeToken.java -// (c)2020 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. -import java.lang.reflect.*; - -public class GenericArrayWithTypeToken { - private T[] array; - @SuppressWarnings("unchecked") - public - GenericArrayWithTypeToken(Class type, int sz) { - array = (T[])Array.newInstance(type, sz); - } - public void put(int index, T item) { - array[index] = item; - } - public T get(int index) { return array[index]; } - // Expose the underlying representation: - public T[] rep() { return array; } - public static void main(String[] args) { - GenericArrayWithTypeToken gai = - new GenericArrayWithTypeToken<>( - Integer.class, 10); - // This now works: - Integer[] ia = gai.rep(); - } -} diff --git a/code/generics/GenericCast.java b/code/generics/GenericCast.java deleted file mode 100644 index c3f82dac..00000000 --- a/code/generics/GenericCast.java +++ /dev/null @@ -1,47 +0,0 @@ -// generics/GenericCast.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; - -class FixedSizeStack { - private final int size; - private Object[] storage; - private int index = 0; - FixedSizeStack(int size) { - this.size = size; - storage = new Object[size]; - } - public void push(T item) { - if(index < size) - storage[index++] = item; - } - @SuppressWarnings("unchecked") - public T pop() { - return index == 0 ? null : (T)storage[--index]; - } - @SuppressWarnings("unchecked") - Stream stream() { - return (Stream)Arrays.stream(storage); - } -} - -public class GenericCast { - static String[] letters = - "ABCDEFGHIJKLMNOPQRS".split(""); - public static void main(String[] args) { - FixedSizeStack strings = - new FixedSizeStack<>(letters.length); - Arrays.stream("ABCDEFGHIJKLMNOPQRS".split("")) - .forEach(strings::push); - System.out.println(strings.pop()); - strings.stream() - .map(s -> s + " ") - .forEach(System.out::print); - } -} -/* Output: -S -A B C D E F G H I J K L M N O P Q R S -*/ diff --git a/code/generics/GenericHolder.java b/code/generics/GenericHolder.java deleted file mode 100644 index 6d998a1c..00000000 --- a/code/generics/GenericHolder.java +++ /dev/null @@ -1,19 +0,0 @@ -// generics/GenericHolder.java -// (c)2020 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. - -public class GenericHolder { - private T a; - public GenericHolder() {} - public void set(T a) { this.a = a; } - public T get() { return a; } - public static void main(String[] args) { - GenericHolder h3 = - new GenericHolder(); - h3.set(new Automobile()); // type checked - Automobile a = h3.get(); // No cast needed - //- h3.set("Not an Automobile"); // Error - //- h3.set(1); // Error - } -} diff --git a/code/generics/GenericHolder2.java b/code/generics/GenericHolder2.java deleted file mode 100644 index 9747f49b..00000000 --- a/code/generics/GenericHolder2.java +++ /dev/null @@ -1,16 +0,0 @@ -// generics/GenericHolder2.java -// (c)2020 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. - -public class GenericHolder2 { - private T obj; - public void set(T obj) { this.obj = obj; } - public T get() { return obj; } - public static void main(String[] args) { - GenericHolder2 holder = - new GenericHolder2<>(); - holder.set("Item"); - String s = holder.get(); - } -} diff --git a/code/generics/GenericMethods.java b/code/generics/GenericMethods.java deleted file mode 100644 index 66f40e72..00000000 --- a/code/generics/GenericMethods.java +++ /dev/null @@ -1,27 +0,0 @@ -// generics/GenericMethods.java -// (c)2020 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. - -public class GenericMethods { - public void f(T x) { - System.out.println(x.getClass().getName()); - } - public static void main(String[] args) { - GenericMethods gm = new GenericMethods(); - gm.f(""); - gm.f(1); - gm.f(1.0); - gm.f(1.0F); - gm.f('c'); - gm.f(gm); - } -} -/* Output: -java.lang.String -java.lang.Integer -java.lang.Double -java.lang.Float -java.lang.Character -GenericMethods -*/ diff --git a/code/generics/GenericReading.java b/code/generics/GenericReading.java deleted file mode 100644 index 5709c7a9..00000000 --- a/code/generics/GenericReading.java +++ /dev/null @@ -1,46 +0,0 @@ -// generics/GenericReading.java -// (c)2020 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. -import java.util.*; - -public class GenericReading { - static List apples = - Arrays.asList(new Apple()); - static List fruit = Arrays.asList(new Fruit()); - static T readExact(List list) { - return list.get(0); - } - // A static method adapts to each call: - static void f1() { - Apple a = readExact(apples); - Fruit f = readExact(fruit); - f = readExact(apples); - } - // A class type is established - // when the class is instantiated: - static class Reader { - T readExact(List list) { return list.get(0); } - } - static void f2() { - Reader fruitReader = new Reader<>(); - Fruit f = fruitReader.readExact(fruit); - //- Fruit a = fruitReader.readExact(apples); - // error: incompatible types: List - // cannot be converted to List - } - static class CovariantReader { - T readCovariant(List list) { - return list.get(0); - } - } - static void f3() { - CovariantReader fruitReader = - new CovariantReader<>(); - Fruit f = fruitReader.readCovariant(fruit); - Fruit a = fruitReader.readCovariant(apples); - } - public static void main(String[] args) { - f1(); f2(); f3(); - } -} diff --git a/code/generics/GenericVarargs.java b/code/generics/GenericVarargs.java deleted file mode 100644 index 3a6e348c..00000000 --- a/code/generics/GenericVarargs.java +++ /dev/null @@ -1,30 +0,0 @@ -// generics/GenericVarargs.java -// (c)2020 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. -import java.util.*; - -public class GenericVarargs { - @SafeVarargs - public static List makeList(T... args) { - List result = new ArrayList<>(); - for(T item : args) - result.add(item); - return result; - } - public static void main(String[] args) { - List ls = makeList("A"); - System.out.println(ls); - ls = makeList("A", "B", "C"); - System.out.println(ls); - ls = makeList( - "ABCDEFFHIJKLMNOPQRSTUVWXYZ".split("")); - System.out.println(ls); - } -} -/* Output: -[A] -[A, B, C] -[A, B, C, D, E, F, F, H, I, J, K, L, M, N, O, P, Q, R, -S, T, U, V, W, X, Y, Z] -*/ diff --git a/code/generics/GenericsAndCovariance.java b/code/generics/GenericsAndCovariance.java deleted file mode 100644 index f16b837b..00000000 --- a/code/generics/GenericsAndCovariance.java +++ /dev/null @@ -1,19 +0,0 @@ -// generics/GenericsAndCovariance.java -// (c)2020 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. -import java.util.*; - -public class GenericsAndCovariance { - public static void main(String[] args) { - // Wildcards allow covariance: - List flist = new ArrayList<>(); - // Compile Error: can't add any type of object: - // flist.add(new Apple()); - // flist.add(new Fruit()); - // flist.add(new Object()); - flist.add(null); // Legal but uninteresting - // We know it returns at least Fruit: - Fruit f = flist.get(0); - } -} diff --git a/code/generics/GenericsAndReturnTypes.java b/code/generics/GenericsAndReturnTypes.java deleted file mode 100644 index de661864..00000000 --- a/code/generics/GenericsAndReturnTypes.java +++ /dev/null @@ -1,17 +0,0 @@ -// generics/GenericsAndReturnTypes.java -// (c)2020 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. - -interface GenericGetter> { - T get(); -} - -interface Getter extends GenericGetter {} - -public class GenericsAndReturnTypes { - void test(Getter g) { - Getter result = g.get(); - GenericGetter gg = g.get(); // Also the base type - } -} diff --git a/code/generics/HasF.java b/code/generics/HasF.java deleted file mode 100644 index f967386e..00000000 --- a/code/generics/HasF.java +++ /dev/null @@ -1,10 +0,0 @@ -// generics/HasF.java -// (c)2020 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. - -public class HasF { - public void f() { - System.out.println("HasF.f()"); - } -} diff --git a/code/generics/HijackedInterface.java b/code/generics/HijackedInterface.java deleted file mode 100644 index 868e1d46..00000000 --- a/code/generics/HijackedInterface.java +++ /dev/null @@ -1,16 +0,0 @@ -// generics/HijackedInterface.java -// (c)2020 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. -// {WillNotCompile} - -class Cat - extends ComparablePet implements Comparable{ - // error: Comparable cannot be inherited with - // different arguments: and - // class Cat - // ^ - // 1 error - - public int compareTo(Cat arg) { return 0; } -} diff --git a/code/generics/Holder.java b/code/generics/Holder.java deleted file mode 100644 index e4301dc6..00000000 --- a/code/generics/Holder.java +++ /dev/null @@ -1,42 +0,0 @@ -// generics/Holder.java -// (c)2020 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. -import java.util.Objects; - -public class Holder { - private T value; - public Holder() {} - public Holder(T val) { value = val; } - public void set(T val) { value = val; } - public T get() { return value; } - @Override - public boolean equals(Object o) { - return o instanceof Holder && - Objects.equals(value, ((Holder)o).value); - } - @Override - public int hashCode() { - return Objects.hashCode(value); - } - public static void main(String[] args) { - Holder apple = new Holder<>(new Apple()); - Apple d = apple.get(); - apple.set(d); - // Holder Fruit = apple; // Cannot upcast - Holder fruit = apple; // OK - Fruit p = fruit.get(); - d = (Apple)fruit.get(); // Returns 'Object' - try { - Orange c = (Orange)fruit.get(); // No warning - } catch(Exception e) { System.out.println(e); } - // fruit.set(new Apple()); // Cannot call set() - // fruit.set(new Fruit()); // Cannot call set() - System.out.println(fruit.equals(d)); // OK - } -} -/* Output: -java.lang.ClassCastException: Apple cannot be cast to -Orange -false -*/ diff --git a/code/generics/Holder1.java b/code/generics/Holder1.java deleted file mode 100644 index 0c222cb5..00000000 --- a/code/generics/Holder1.java +++ /dev/null @@ -1,12 +0,0 @@ -// generics/Holder1.java -// (c)2020 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. - -class Automobile {} - -public class Holder1 { - private Automobile a; - public Holder1(Automobile a) { this.a = a; } - Automobile get() { return a; } -} diff --git a/code/generics/InheritBounds.java b/code/generics/InheritBounds.java deleted file mode 100644 index fddd2543..00000000 --- a/code/generics/InheritBounds.java +++ /dev/null @@ -1,40 +0,0 @@ -// generics/InheritBounds.java -// (c)2020 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. - -class HoldItem { - T item; - HoldItem(T item) { this.item = item; } - T getItem() { return item; } -} - -class WithColor2 -extends HoldItem { - WithColor2(T item) { super(item); } - java.awt.Color color() { return item.getColor(); } -} - -class WithColorCoord2 -extends WithColor2 { - WithColorCoord2(T item) { super(item); } - int getX() { return item.x; } - int getY() { return item.y; } - int getZ() { return item.z; } -} - -class Solid2 -extends WithColorCoord2 { - Solid2(T item) { super(item); } - int weight() { return item.weight(); } -} - -public class InheritBounds { - public static void main(String[] args) { - Solid2 solid2 = - new Solid2<>(new Bounded()); - solid2.color(); - solid2.getY(); - solid2.weight(); - } -} diff --git a/code/generics/InstantiateGenericType.cpp b/code/generics/InstantiateGenericType.cpp deleted file mode 100644 index 1799d05b..00000000 --- a/code/generics/InstantiateGenericType.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// generics/InstantiateGenericType.cpp -// (c)2020 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. -// C++, not Java! - -template class Foo { - T x; // Create a field of type T - T* y; // Pointer to T -public: - // Initialize the pointer: - Foo() { y = new T(); } -}; - -class Bar {}; - -int main() { - Foo fb; - Foo fi; // ... and it works with primitives -} diff --git a/code/generics/InstantiateGenericType.java b/code/generics/InstantiateGenericType.java deleted file mode 100644 index 9424c9a1..00000000 --- a/code/generics/InstantiateGenericType.java +++ /dev/null @@ -1,46 +0,0 @@ -// generics/InstantiateGenericType.java -// (c)2020 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. -import java.util.function.*; -import java.lang.reflect.InvocationTargetException; - -class ClassAsFactory implements Supplier { - Class kind; - ClassAsFactory(Class kind) { - this.kind = kind; - } - @SuppressWarnings("deprecation") - @Override - public T get() { - try { - return kind.newInstance(); - } catch(Exception e) { - throw new RuntimeException(e); - } - } -} - -class Employee { - @Override - public String toString() { return "Employee"; } -} - -public class InstantiateGenericType { - public static void main(String[] args) { - ClassAsFactory fe = - new ClassAsFactory<>(Employee.class); - System.out.println(fe.get()); - ClassAsFactory fi = - new ClassAsFactory<>(Integer.class); - try { - System.out.println(fi.get()); - } catch(Exception e) { - System.out.println(e.getMessage()); - } - } -} -/* Output: -Employee -java.lang.InstantiationException: java.lang.Integer -*/ diff --git a/code/generics/IterableFibonacci.java b/code/generics/IterableFibonacci.java deleted file mode 100644 index b5ccf285..00000000 --- a/code/generics/IterableFibonacci.java +++ /dev/null @@ -1,36 +0,0 @@ -// generics/IterableFibonacci.java -// (c)2020 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. -// Adapt the Fibonacci class to make it Iterable -import java.util.*; - -public class IterableFibonacci -extends Fibonacci implements Iterable { - private int n; - public IterableFibonacci(int count) { n = count; } - @Override - public Iterator iterator() { - return new Iterator() { - @Override - public boolean hasNext() { return n > 0; } - @Override - public Integer next() { - n--; - return IterableFibonacci.this.get(); - } - @Override - public void remove() { // Not implemented - throw new UnsupportedOperationException(); - } - }; - } - public static void main(String[] args) { - for(int i : new IterableFibonacci(18)) - System.out.print(i + " "); - } -} -/* Output: -1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 -2584 -*/ diff --git a/code/generics/LatentReflection.java b/code/generics/LatentReflection.java deleted file mode 100644 index 0e9511a3..00000000 --- a/code/generics/LatentReflection.java +++ /dev/null @@ -1,65 +0,0 @@ -// generics/LatentReflection.java -// (c)2020 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. -// Using reflection for latent typing -import java.lang.reflect.*; - -// Does not implement Performs: -class Mime { - public void walkAgainstTheWind() {} - public void sit() { - System.out.println("Pretending to sit"); - } - public void pushInvisibleWalls() {} - @Override - public String toString() { return "Mime"; } -} - -// Does not implement Performs: -class SmartDog { - public void speak() { System.out.println("Woof!"); } - public void sit() { System.out.println("Sitting"); } - public void reproduce() {} -} - -class CommunicateReflectively { - public static void perform(Object speaker) { - Class spkr = speaker.getClass(); - try { - try { - Method speak = spkr.getMethod("speak"); - speak.invoke(speaker); - } catch(NoSuchMethodException e) { - System.out.println(speaker + " cannot speak"); - } - try { - Method sit = spkr.getMethod("sit"); - sit.invoke(speaker); - } catch(NoSuchMethodException e) { - System.out.println(speaker + " cannot sit"); - } - } catch(SecurityException | - IllegalAccessException | - IllegalArgumentException | - InvocationTargetException e) { - throw new RuntimeException(speaker.toString(), e); - } - } -} - -public class LatentReflection { - public static void main(String[] args) { - CommunicateReflectively.perform(new SmartDog()); - CommunicateReflectively.perform(new Robot()); - CommunicateReflectively.perform(new Mime()); - } -} -/* Output: -Woof! -Sitting -Click! -Clank! -Mime cannot speak -Pretending to sit -*/ diff --git a/code/generics/LinkedStack.java b/code/generics/LinkedStack.java deleted file mode 100644 index 5142bcc7..00000000 --- a/code/generics/LinkedStack.java +++ /dev/null @@ -1,43 +0,0 @@ -// generics/LinkedStack.java -// (c)2020 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. -// A stack implemented with an internal linked structure - -public class LinkedStack { - private static class Node { - U item; - Node next; - Node() { item = null; next = null; } - Node(U item, Node next) { - this.item = item; - this.next = next; - } - boolean end() { - return item == null && next == null; - } - } - private Node top = new Node<>(); // End sentinel - public void push(T item) { - top = new Node<>(item, top); - } - public T pop() { - T result = top.item; - if(!top.end()) - top = top.next; - return result; - } - public static void main(String[] args) { - LinkedStack lss = new LinkedStack<>(); - for(String s : "Phasers on stun!".split(" ")) - lss.push(s); - String s; - while((s = lss.pop()) != null) - System.out.println(s); - } -} -/* Output: -stun! -on -Phasers -*/ diff --git a/code/generics/ListMaker.java b/code/generics/ListMaker.java deleted file mode 100644 index 582cbaea..00000000 --- a/code/generics/ListMaker.java +++ /dev/null @@ -1,13 +0,0 @@ -// generics/ListMaker.java -// (c)2020 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. -import java.util.*; - -public class ListMaker { - List create() { return new ArrayList<>(); } - public static void main(String[] args) { - ListMaker stringMaker = new ListMaker<>(); - List stringList = stringMaker.create(); - } -} diff --git a/code/generics/ListOfGenerics.java b/code/generics/ListOfGenerics.java deleted file mode 100644 index 10a48031..00000000 --- a/code/generics/ListOfGenerics.java +++ /dev/null @@ -1,11 +0,0 @@ -// generics/ListOfGenerics.java -// (c)2020 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. -import java.util.*; - -public class ListOfGenerics { - private List array = new ArrayList<>(); - public void add(T item) { array.add(item); } - public T get(int index) { return array.get(index); } -} diff --git a/code/generics/ListOfInt.java b/code/generics/ListOfInt.java deleted file mode 100644 index f8ac8e11..00000000 --- a/code/generics/ListOfInt.java +++ /dev/null @@ -1,20 +0,0 @@ -// generics/ListOfInt.java -// (c)2020 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. -// Autoboxing compensates for the inability -// to use primitives in generics -import java.util.*; -import java.util.stream.*; - -public class ListOfInt { - public static void main(String[] args) { - List li = IntStream.range(38, 48) - .boxed() // Converts ints to Integers - .collect(Collectors.toList()); - System.out.println(li); - } -} -/* Output: -[38, 39, 40, 41, 42, 43, 44, 45, 46, 47] -*/ diff --git a/code/generics/LostInformation.java b/code/generics/LostInformation.java deleted file mode 100644 index e27430d2..00000000 --- a/code/generics/LostInformation.java +++ /dev/null @@ -1,33 +0,0 @@ -// generics/LostInformation.java -// (c)2020 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. -import java.util.*; - -class Frob {} -class Fnorkle {} -class Quark {} -class Particle {} - -public class LostInformation { - public static void main(String[] args) { - List list = new ArrayList<>(); - Map map = new HashMap<>(); - Quark quark = new Quark<>(); - Particle p = new Particle<>(); - System.out.println(Arrays.toString( - list.getClass().getTypeParameters())); - System.out.println(Arrays.toString( - map.getClass().getTypeParameters())); - System.out.println(Arrays.toString( - quark.getClass().getTypeParameters())); - System.out.println(Arrays.toString( - p.getClass().getTypeParameters())); - } -} -/* Output: -[E] -[K, V] -[Q] -[POSITION, MOMENTUM] -*/ diff --git a/code/generics/Manipulation.java b/code/generics/Manipulation.java deleted file mode 100644 index f365cf19..00000000 --- a/code/generics/Manipulation.java +++ /dev/null @@ -1,21 +0,0 @@ -// generics/Manipulation.java -// (c)2020 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. -// {WillNotCompile} - -class Manipulator { - private T obj; - Manipulator(T x) { obj = x; } - // Error: cannot find symbol: method f(): - public void manipulate() { obj.f(); } -} - -public class Manipulation { - public static void main(String[] args) { - HasF hf = new HasF(); - Manipulator manipulator = - new Manipulator<>(hf); - manipulator.manipulate(); - } -} diff --git a/code/generics/Manipulator2.java b/code/generics/Manipulator2.java deleted file mode 100644 index 7c7c648b..00000000 --- a/code/generics/Manipulator2.java +++ /dev/null @@ -1,10 +0,0 @@ -// generics/Manipulator2.java -// (c)2020 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. - -class Manipulator2 { - private T obj; - Manipulator2(T x) { obj = x; } - public void manipulate() { obj.f(); } -} diff --git a/code/generics/Manipulator3.java b/code/generics/Manipulator3.java deleted file mode 100644 index 2201d474..00000000 --- a/code/generics/Manipulator3.java +++ /dev/null @@ -1,10 +0,0 @@ -// generics/Manipulator3.java -// (c)2020 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. - -class Manipulator3 { - private HasF obj; - Manipulator3(HasF x) { obj = x; } - public void manipulate() { obj.f(); } -} diff --git a/code/generics/Mixins.cpp b/code/generics/Mixins.cpp deleted file mode 100644 index 89949d46..00000000 --- a/code/generics/Mixins.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// generics/Mixins.cpp -// (c)2020 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. -#include -#include -#include -using namespace std; - -template class TimeStamped : public T { - long timeStamp; -public: - TimeStamped() { timeStamp = time(0); } - long getStamp() { return timeStamp; } -}; - -template class SerialNumbered : public T { - long serialNumber; - static long counter; -public: - SerialNumbered() { serialNumber = counter++; } - long getSerialNumber() { return serialNumber; } -}; - -// Define and initialize the static storage: -template long SerialNumbered::counter = 1; - -class Basic { - string value; -public: - void set(string val) { value = val; } - string get() { return value; } -}; - -int main() { - TimeStamped> mixin1, mixin2; - mixin1.set("test string 1"); - mixin2.set("test string 2"); - cout << mixin1.get() << " " << mixin1.getStamp() << - " " << mixin1.getSerialNumber() << endl; - cout << mixin2.get() << " " << mixin2.getStamp() << - " " << mixin2.getSerialNumber() << endl; -} -/* Output: -test string 1 1452987605 1 -test string 2 1452987605 2 -*/ diff --git a/code/generics/Mixins.java b/code/generics/Mixins.java deleted file mode 100644 index af58b81e..00000000 --- a/code/generics/Mixins.java +++ /dev/null @@ -1,71 +0,0 @@ -// generics/Mixins.java -// (c)2020 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. -import java.util.*; - -interface TimeStamped { long getStamp(); } - -class TimeStampedImp implements TimeStamped { - private final long timeStamp; - TimeStampedImp() { - timeStamp = new Date().getTime(); - } - @Override - public long getStamp() { return timeStamp; } -} - -interface SerialNumbered { long getSerialNumber(); } - -class SerialNumberedImp implements SerialNumbered { - private static long counter = 1; - private final long serialNumber = counter++; - @Override - public long getSerialNumber() { return serialNumber; } -} - -interface Basic { - void set(String val); - String get(); -} - -class BasicImp implements Basic { - private String value; - @Override - public void set(String val) { value = val; } - @Override - public String get() { return value; } -} - -class Mixin extends BasicImp -implements TimeStamped, SerialNumbered { - private TimeStamped timeStamp = new TimeStampedImp(); - private SerialNumbered serialNumber = - new SerialNumberedImp(); - @Override - public long getStamp() { - return timeStamp.getStamp(); - } - @Override - public long getSerialNumber() { - return serialNumber.getSerialNumber(); - } -} - -public class Mixins { - public static void main(String[] args) { - Mixin mixin1 = new Mixin(), mixin2 = new Mixin(); - mixin1.set("test string 1"); - mixin2.set("test string 2"); - System.out.println(mixin1.get() + " " + - mixin1.getStamp() + " " + - mixin1.getSerialNumber()); - System.out.println(mixin2.get() + " " + - mixin2.getStamp() + " " + - mixin2.getSerialNumber()); - } -} -/* Output: -test string 1 1494331663026 1 -test string 2 1494331663027 2 -*/ diff --git a/code/generics/MultipleInterfaceVariants.java b/code/generics/MultipleInterfaceVariants.java deleted file mode 100644 index 70a535a2..00000000 --- a/code/generics/MultipleInterfaceVariants.java +++ /dev/null @@ -1,13 +0,0 @@ -// generics/MultipleInterfaceVariants.java -// (c)2020 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. -// {WillNotCompile} -package generics; - -interface Payable {} - -class Employee implements Payable {} - -class Hourly extends Employee -implements Payable {} diff --git a/code/generics/NeedCasting.java b/code/generics/NeedCasting.java deleted file mode 100644 index 8801f5d8..00000000 --- a/code/generics/NeedCasting.java +++ /dev/null @@ -1,15 +0,0 @@ -// generics/NeedCasting.java -// (c)2020 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. -import java.io.*; -import java.util.*; - -public class NeedCasting { - @SuppressWarnings("unchecked") - public void f(String[] args) throws Exception { - ObjectInputStream in = new ObjectInputStream( - new FileInputStream(args[0])); - List shapes = (List)in.readObject(); - } -} diff --git a/code/generics/NonCovariantGenerics.java b/code/generics/NonCovariantGenerics.java deleted file mode 100644 index c219a0d3..00000000 --- a/code/generics/NonCovariantGenerics.java +++ /dev/null @@ -1,11 +0,0 @@ -// generics/NonCovariantGenerics.java -// (c)2020 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. -// {WillNotCompile} -import java.util.*; - -public class NonCovariantGenerics { - // Compile Error: incompatible types: - List flist = new ArrayList(); -} diff --git a/code/generics/NotSelfBounded.java b/code/generics/NotSelfBounded.java deleted file mode 100644 index 76aa593c..00000000 --- a/code/generics/NotSelfBounded.java +++ /dev/null @@ -1,24 +0,0 @@ -// generics/NotSelfBounded.java -// (c)2020 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. - -public class NotSelfBounded { - T element; - NotSelfBounded set(T arg) { - element = arg; - return this; - } - T get() { return element; } -} - -class A2 extends NotSelfBounded {} -class B2 extends NotSelfBounded {} - -class C2 extends NotSelfBounded { - C2 setAndGet(C2 arg) { set(arg); return get(); } -} - -class D2 {} -// Now this is OK: -class E2 extends NotSelfBounded {} diff --git a/code/generics/ObjectHolder.java b/code/generics/ObjectHolder.java deleted file mode 100644 index f1dafd30..00000000 --- a/code/generics/ObjectHolder.java +++ /dev/null @@ -1,20 +0,0 @@ -// generics/ObjectHolder.java -// (c)2020 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. - -public class ObjectHolder { - private Object a; - public ObjectHolder(Object a) { this.a = a; } - public void set(Object a) { this.a = a; } - public Object get() { return a; } - public static void main(String[] args) { - ObjectHolder h2 = - new ObjectHolder(new Automobile()); - Automobile a = (Automobile)h2.get(); - h2.set("Not an Automobile"); - String s = (String)h2.get(); - h2.set(1); // Autoboxes to Integer - Integer x = (Integer)h2.get(); - } -} diff --git a/code/generics/OrdinaryArguments.java b/code/generics/OrdinaryArguments.java deleted file mode 100644 index 6e50550d..00000000 --- a/code/generics/OrdinaryArguments.java +++ /dev/null @@ -1,31 +0,0 @@ -// generics/OrdinaryArguments.java -// (c)2020 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. - -class OrdinarySetter { - void set(Base base) { - System.out.println("OrdinarySetter.set(Base)"); - } -} - -class DerivedSetter extends OrdinarySetter { - void set(Derived derived) { - System.out.println("DerivedSetter.set(Derived)"); - } -} - -public class OrdinaryArguments { - public static void main(String[] args) { - Base base = new Base(); - Derived derived = new Derived(); - DerivedSetter ds = new DerivedSetter(); - ds.set(derived); - // Compiles--overloaded, not overridden!: - ds.set(base); - } -} -/* Output: -DerivedSetter.set(Derived) -OrdinarySetter.set(Base) -*/ diff --git a/code/generics/Performs.java b/code/generics/Performs.java deleted file mode 100644 index ace09523..00000000 --- a/code/generics/Performs.java +++ /dev/null @@ -1,9 +0,0 @@ -// generics/Performs.java -// (c)2020 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. - -public interface Performs { - void speak(); - void sit(); -} diff --git a/code/generics/PlainGenericInheritance.java b/code/generics/PlainGenericInheritance.java deleted file mode 100644 index 93eb61c6..00000000 --- a/code/generics/PlainGenericInheritance.java +++ /dev/null @@ -1,30 +0,0 @@ -// generics/PlainGenericInheritance.java -// (c)2020 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. - -class GenericSetter { // Not self-bounded - void set(T arg) { - System.out.println("GenericSetter.set(Base)"); - } -} - -class DerivedGS extends GenericSetter { - void set(Derived derived) { - System.out.println("DerivedGS.set(Derived)"); - } -} - -public class PlainGenericInheritance { - public static void main(String[] args) { - Base base = new Base(); - Derived derived = new Derived(); - DerivedGS dgs = new DerivedGS(); - dgs.set(derived); - dgs.set(base); // Overloaded, not overridden! - } -} -/* Output: -DerivedGS.set(Derived) -GenericSetter.set(Base) -*/ diff --git a/code/generics/PrimitiveGenericTest.java b/code/generics/PrimitiveGenericTest.java deleted file mode 100644 index 79356437..00000000 --- a/code/generics/PrimitiveGenericTest.java +++ /dev/null @@ -1,42 +0,0 @@ -// generics/PrimitiveGenericTest.java -// (c)2020 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. -import onjava.*; -import java.util.*; -import java.util.function.*; - -// Fill an array using a generator: -interface FillArray { - static T[] fill(T[] a, Supplier gen) { - Arrays.setAll(a, n -> gen.get()); - return a; - } - static int[] fill(int[] a, IntSupplier gen) { - Arrays.setAll(a, n -> gen.getAsInt()); - return a; - } - static long[] fill(long[] a, LongSupplier gen) { - Arrays.setAll(a, n -> gen.getAsLong()); - return a; - } - static double[] fill(double[] a, DoubleSupplier gen) { - Arrays.setAll(a, n -> gen.getAsDouble()); - return a; - } -} - -public class PrimitiveGenericTest { - public static void main(String[] args) { - String[] strings = FillArray.fill( - new String[5], new Rand.String(9)); - System.out.println(Arrays.toString(strings)); - int[] integers = FillArray.fill( - new int[9], new Rand.Pint()); - System.out.println(Arrays.toString(integers)); - } -} -/* Output: -[btpenpccu, xszgvgmei, nneeloztd, vewcippcy, gpoalkljl] -[635, 8737, 3941, 4720, 6177, 8479, 6656, 3768, 4948] -*/ diff --git a/code/generics/RandomList.java b/code/generics/RandomList.java deleted file mode 100644 index d4f198bc..00000000 --- a/code/generics/RandomList.java +++ /dev/null @@ -1,26 +0,0 @@ -// generics/RandomList.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; - -public class RandomList extends ArrayList { - private Random rand = new Random(47); - public T select() { - return get(rand.nextInt(size())); - } - public static void main(String[] args) { - RandomList rs = new RandomList<>(); - Arrays.stream( - ("The quick brown fox jumped over " + - "the lazy brown dog").split(" ")) - .forEach(rs::add); - IntStream.range(0, 11).forEach(i -> - System.out.print(rs.select() + " ")); - } -} -/* Output: -brown over fox quick quick dog brown The brown lazy -brown -*/ diff --git a/code/generics/RestrictedComparablePets.java b/code/generics/RestrictedComparablePets.java deleted file mode 100644 index 16146d7b..00000000 --- a/code/generics/RestrictedComparablePets.java +++ /dev/null @@ -1,19 +0,0 @@ -// generics/RestrictedComparablePets.java -// (c)2020 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. - -class Hamster extends ComparablePet -implements Comparable { - public int compareTo(ComparablePet arg) { - return 0; - } -} - -// Or just: - -class Gecko extends ComparablePet { - public int compareTo(ComparablePet arg) { - return 0; - } -} diff --git a/code/generics/ReturnGenericType.java b/code/generics/ReturnGenericType.java deleted file mode 100644 index bf46ae15..00000000 --- a/code/generics/ReturnGenericType.java +++ /dev/null @@ -1,10 +0,0 @@ -// generics/ReturnGenericType.java -// (c)2020 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. - -class ReturnGenericType { - private T obj; - ReturnGenericType(T x) { obj = x; } - public T get() { return obj; } -} diff --git a/code/generics/SelfBounding.java b/code/generics/SelfBounding.java deleted file mode 100644 index c8ecf0ff..00000000 --- a/code/generics/SelfBounding.java +++ /dev/null @@ -1,40 +0,0 @@ -// generics/SelfBounding.java -// (c)2020 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. - -class SelfBounded> { - T element; - SelfBounded set(T arg) { - element = arg; - return this; - } - T get() { return element; } -} - -class A extends SelfBounded {} -class B extends SelfBounded {} // Also OK - -class C extends SelfBounded { - C setAndGet(C arg) { set(arg); return get(); } -} - -class D {} -// Can't do this: -// class E extends SelfBounded {} -// Compile error: -// Type parameter D is not within its bound - -// Alas, you can do this, so you cannot force the idiom: -class F extends SelfBounded {} - -public class SelfBounding { - public static void main(String[] args) { - A a = new A(); - a.set(new A()); - a = a.set(new A()).get(); - a = a.get(); - C c = new C(); - c = c.setAndGet(new C()); - } -} diff --git a/code/generics/SelfBoundingAndCovariantArguments.java b/code/generics/SelfBoundingAndCovariantArguments.java deleted file mode 100644 index 34262b0e..00000000 --- a/code/generics/SelfBoundingAndCovariantArguments.java +++ /dev/null @@ -1,31 +0,0 @@ -// generics/SelfBoundingAndCovariantArguments.java -// (c)2020 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. - -interface -SelfBoundSetter> { - void set(T arg); -} - -interface Setter extends SelfBoundSetter {} - -public class SelfBoundingAndCovariantArguments { - void - testA(Setter s1, Setter s2, SelfBoundSetter sbs) { - s1.set(s2); - //- s1.set(sbs); - // error: method set in interface SelfBoundSetter - // cannot be applied to given types; - // s1.set(sbs); - // ^ - // required: Setter - // found: SelfBoundSetter - // reason: argument mismatch; - // SelfBoundSetter cannot be converted to Setter - // where T is a type-variable: - // T extends SelfBoundSetter declared in - // interface SelfBoundSetter - // 1 error - } -} diff --git a/code/generics/SelfBoundingMethods.java b/code/generics/SelfBoundingMethods.java deleted file mode 100644 index e6cb7949..00000000 --- a/code/generics/SelfBoundingMethods.java +++ /dev/null @@ -1,13 +0,0 @@ -// generics/SelfBoundingMethods.java -// (c)2020 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. - -public class SelfBoundingMethods { - static > T f(T arg) { - return arg.set(arg).get(); - } - public static void main(String[] args) { - A a = f(new A()); - } -} diff --git a/code/generics/Shape.java b/code/generics/Shape.java deleted file mode 100644 index dd2458c2..00000000 --- a/code/generics/Shape.java +++ /dev/null @@ -1,19 +0,0 @@ -// generics/Shape.java -// (c)2020 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. - -public class Shape { - private static long counter = 0; - private final long id = counter++; - @Override - public String toString() { - return getClass().getSimpleName() + " " + id; - } - public void rotate() { - System.out.println(this + " rotate"); - } - public void resize(int newSize) { - System.out.println(this + " resize " + newSize); - } -} diff --git a/code/generics/SimpleDogsAndRobots.java b/code/generics/SimpleDogsAndRobots.java deleted file mode 100644 index b9cee77b..00000000 --- a/code/generics/SimpleDogsAndRobots.java +++ /dev/null @@ -1,25 +0,0 @@ -// generics/SimpleDogsAndRobots.java -// (c)2020 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. -// Removing the generic; code still works - -class CommunicateSimply { - static void perform(Performs performer) { - performer.speak(); - performer.sit(); - } -} - -public class SimpleDogsAndRobots { - public static void main(String[] args) { - CommunicateSimply.perform(new PerformingDog()); - CommunicateSimply.perform(new Robot()); - } -} -/* Output: -Woof! -Sitting -Click! -Clank! -*/ diff --git a/code/generics/SimpleHolder.java b/code/generics/SimpleHolder.java deleted file mode 100644 index a73af0ab..00000000 --- a/code/generics/SimpleHolder.java +++ /dev/null @@ -1,15 +0,0 @@ -// generics/SimpleHolder.java -// (c)2020 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. - -public class SimpleHolder { - private Object obj; - public void set(Object obj) { this.obj = obj; } - public Object get() { return obj; } - public static void main(String[] args) { - SimpleHolder holder = new SimpleHolder(); - holder.set("Item"); - String s = (String)holder.get(); - } -} diff --git a/code/generics/SimpleQueue.java b/code/generics/SimpleQueue.java deleted file mode 100644 index 76fb4f3e..00000000 --- a/code/generics/SimpleQueue.java +++ /dev/null @@ -1,16 +0,0 @@ -// generics/SimpleQueue.java -// (c)2020 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. -// A different kind of Iterable collection -import java.util.*; - -public class SimpleQueue implements Iterable { - private LinkedList storage = new LinkedList<>(); - public void add(T t) { storage.offer(t); } - public T get() { return storage.poll(); } - @Override - public Iterator iterator() { - return storage.iterator(); - } -} diff --git a/code/generics/Square.java b/code/generics/Square.java deleted file mode 100644 index e3bcad93..00000000 --- a/code/generics/Square.java +++ /dev/null @@ -1,5 +0,0 @@ -// generics/Square.java -// (c)2020 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. -public class Square extends Shape {} diff --git a/code/generics/Store.java b/code/generics/Store.java deleted file mode 100644 index c165926a..00000000 --- a/code/generics/Store.java +++ /dev/null @@ -1,90 +0,0 @@ -// generics/Store.java -// (c)2020 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. -// Building a complex model using generic collections -import java.util.*; -import java.util.function.*; -import onjava.*; - -class Product { - private final int id; - private String description; - private double price; - Product(int idNumber, String descr, double price) { - id = idNumber; - description = descr; - this.price = price; - System.out.println(toString()); - } - @Override - public String toString() { - return id + ": " + description + - ", price: $" + price; - } - public void priceChange(double change) { - price += change; - } - public static Supplier generator = - new Supplier() { - private Random rand = new Random(47); - @Override - public Product get() { - return new Product(rand.nextInt(1000), "Test", - Math.round( - rand.nextDouble() * 1000.0) + 0.99); - } - }; -} - -class Shelf extends ArrayList { - Shelf(int nProducts) { - Suppliers.fill(this, Product.generator, nProducts); - } -} - -class Aisle extends ArrayList { - Aisle(int nShelves, int nProducts) { - for(int i = 0; i < nShelves; i++) - add(new Shelf(nProducts)); - } -} - -class CheckoutStand {} -class Office {} - -public class Store extends ArrayList { - private ArrayList checkouts = - new ArrayList<>(); - private Office office = new Office(); - public Store( - int nAisles, int nShelves, int nProducts) { - for(int i = 0; i < nAisles; i++) - add(new Aisle(nShelves, nProducts)); - } - @Override - public String toString() { - StringBuilder result = new StringBuilder(); - for(Aisle a : this) - for(Shelf s : a) - for(Product p : s) { - result.append(p); - result.append("\n"); - } - return result.toString(); - } - public static void main(String[] args) { - System.out.println(new Store(5, 4, 3)); - } -} -/* Output: (First 8 Lines) -258: Test, price: $400.99 -861: Test, price: $160.99 -868: Test, price: $417.99 -207: Test, price: $268.99 -551: Test, price: $114.99 -278: Test, price: $804.99 -520: Test, price: $554.99 -140: Test, price: $530.99 - ... -*/ diff --git a/code/generics/SuperTypeWildcards.java b/code/generics/SuperTypeWildcards.java deleted file mode 100644 index f8672a4f..00000000 --- a/code/generics/SuperTypeWildcards.java +++ /dev/null @@ -1,13 +0,0 @@ -// generics/SuperTypeWildcards.java -// (c)2020 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. -import java.util.*; - -public class SuperTypeWildcards { - static void writeTo(List apples) { - apples.add(new Apple()); - apples.add(new Jonathan()); - // apples.add(new Fruit()); // Error - } -} diff --git a/code/generics/Templates.cpp b/code/generics/Templates.cpp deleted file mode 100644 index ab2a3b64..00000000 --- a/code/generics/Templates.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// generics/Templates.cpp -// (c)2020 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. -#include -using namespace std; - -template class Manipulator { - T obj; -public: - Manipulator(T x) { obj = x; } - void manipulate() { obj.f(); } -}; - -class HasF { -public: - void f() { cout << "HasF::f()" << endl; } -}; - -int main() { - HasF hf; - Manipulator manipulator(hf); - manipulator.manipulate(); -} -/* Output: -HasF::f() -*/ diff --git a/code/generics/ThrowGenericException.java b/code/generics/ThrowGenericException.java deleted file mode 100644 index 994c7f88..00000000 --- a/code/generics/ThrowGenericException.java +++ /dev/null @@ -1,82 +0,0 @@ -// generics/ThrowGenericException.java -// (c)2020 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. -import java.util.*; - -interface Processor { - void process(List resultCollector) throws E; -} - -class ProcessRunner -extends ArrayList> { - List processAll() throws E { - List resultCollector = new ArrayList<>(); - for(Processor processor : this) - processor.process(resultCollector); - return resultCollector; - } -} - -class Failure1 extends Exception {} - -class Processor1 -implements Processor { - static int count = 3; - @Override - public void process(List resultCollector) - throws Failure1 { - if(count-- > 1) - resultCollector.add("Hep!"); - else - resultCollector.add("Ho!"); - if(count < 0) - throw new Failure1(); - } -} - -class Failure2 extends Exception {} - -class Processor2 -implements Processor { - static int count = 2; - @Override - public void process(List resultCollector) - throws Failure2 { - if(count-- == 0) - resultCollector.add(47); - else { - resultCollector.add(11); - } - if(count < 0) - throw new Failure2(); - } -} - -public class ThrowGenericException { - public static void main(String[] args) { - ProcessRunner runner = - new ProcessRunner<>(); - for(int i = 0; i < 3; i++) - runner.add(new Processor1()); - try { - System.out.println(runner.processAll()); - } catch(Failure1 e) { - System.out.println(e); - } - - ProcessRunner runner2 = - new ProcessRunner<>(); - for(int i = 0; i < 3; i++) - runner2.add(new Processor2()); - try { - System.out.println(runner2.processAll()); - } catch(Failure2 e) { - System.out.println(e); - } - } -} -/* Output: -[Hep!, Hep!, Ho!] -Failure2 -*/ diff --git a/code/generics/TupleList.java b/code/generics/TupleList.java deleted file mode 100644 index fe93330b..00000000 --- a/code/generics/TupleList.java +++ /dev/null @@ -1,23 +0,0 @@ -// generics/TupleList.java -// (c)2020 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. -// Combining generic types to make complex generic types -import java.util.*; -import onjava.*; -import java.util.stream.*; - -public class TupleList -extends ArrayList> { - public static void main(String[] args) { - TupleList tl = - new TupleList<>(); - tl.add(TupleTest2.h()); - tl.add(TupleTest2.h()); - tl.forEach(System.out::println); - } -} -/* Output: -(Vehicle@7cca494b, Amphibian@7ba4f24f, hi, 47) -(Vehicle@3b9a45b3, Amphibian@7699a589, hi, 47) -*/ diff --git a/code/generics/TupleTest.java b/code/generics/TupleTest.java deleted file mode 100644 index e207da40..00000000 --- a/code/generics/TupleTest.java +++ /dev/null @@ -1,42 +0,0 @@ -// generics/TupleTest.java -// (c)2020 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. -import onjava.*; - -public class TupleTest { - static Tuple2 f() { - // Autoboxing converts the int to Integer: - return new Tuple2<>("hi", 47); - } - static Tuple3 g() { - return new Tuple3<>(new Amphibian(), "hi", 47); - } - static - Tuple4 h() { - return - new Tuple4<>( - new Vehicle(), new Amphibian(), "hi", 47); - } - static - Tuple5 k() { - return new - Tuple5<>( - new Vehicle(), new Amphibian(), "hi", 47, 11.1); - } - public static void main(String[] args) { - Tuple2 ttsi = f(); - System.out.println(ttsi); - // ttsi.a1 = "there"; // Compile error: final - System.out.println(g()); - System.out.println(h()); - System.out.println(k()); - } -} -/* Output: -(hi, 47) -(Amphibian@1540e19d, hi, 47) -(Vehicle@7f31245a, Amphibian@6d6f6e28, hi, 47) -(Vehicle@330bedb4, Amphibian@2503dbd3, hi, 47, 11.1) -*/ diff --git a/code/generics/TupleTest2.java b/code/generics/TupleTest2.java deleted file mode 100644 index 3a0c8d14..00000000 --- a/code/generics/TupleTest2.java +++ /dev/null @@ -1,42 +0,0 @@ -// generics/TupleTest2.java -// (c)2020 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. -import onjava.*; -import static onjava.Tuple.*; - -public class TupleTest2 { - static Tuple2 f() { - return tuple("hi", 47); - } - static Tuple2 f2() { return tuple("hi", 47); } - static Tuple3 g() { - return tuple(new Amphibian(), "hi", 47); - } - static - Tuple4 h() { - return tuple( - new Vehicle(), new Amphibian(), "hi", 47); - } - static - Tuple5 k() { - return tuple(new Vehicle(), new Amphibian(), - "hi", 47, 11.1); - } - public static void main(String[] args) { - Tuple2 ttsi = f(); - System.out.println(ttsi); - System.out.println(f2()); - System.out.println(g()); - System.out.println(h()); - System.out.println(k()); - } -} -/* Output: -(hi, 47) -(hi, 47) -(Amphibian@14ae5a5, hi, 47) -(Vehicle@135fbaa4, Amphibian@45ee12a7, hi, 47) -(Vehicle@4b67cf4d, Amphibian@7ea987ac, hi, 47, 11.1) -*/ diff --git a/code/generics/UnboundedWildcards1.java b/code/generics/UnboundedWildcards1.java deleted file mode 100644 index 6b163a4c..00000000 --- a/code/generics/UnboundedWildcards1.java +++ /dev/null @@ -1,58 +0,0 @@ -// generics/UnboundedWildcards1.java -// (c)2020 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. -import java.util.*; - -public class UnboundedWildcards1 { - static List list1; - static List list2; - static List list3; - static void assign1(List list) { - list1 = list; - list2 = list; - //- list3 = list; - // warning: [unchecked] unchecked conversion - // list3 = list; - // ^ - // required: List - // found: List - } - static void assign2(List list) { - list1 = list; - list2 = list; - list3 = list; - } - static void assign3(List list) { - list1 = list; - list2 = list; - list3 = list; - } - public static void main(String[] args) { - assign1(new ArrayList()); - assign2(new ArrayList()); - //- assign3(new ArrayList()); - // warning: [unchecked] unchecked method invocation: - // method assign3 in class UnboundedWildcards1 - // is applied to given types - // assign3(new ArrayList()); - // ^ - // required: List - // found: ArrayList - // warning: [unchecked] unchecked conversion - // assign3(new ArrayList()); - // ^ - // required: List - // found: ArrayList - // 2 warnings - assign1(new ArrayList<>()); - assign2(new ArrayList<>()); - assign3(new ArrayList<>()); - // Both forms are acceptable as List: - List wildList = new ArrayList(); - wildList = new ArrayList<>(); - assign1(wildList); - assign2(wildList); - assign3(wildList); - } -} diff --git a/code/generics/UnboundedWildcards2.java b/code/generics/UnboundedWildcards2.java deleted file mode 100644 index ee80d555..00000000 --- a/code/generics/UnboundedWildcards2.java +++ /dev/null @@ -1,35 +0,0 @@ -// generics/UnboundedWildcards2.java -// (c)2020 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. -import java.util.*; - -public class UnboundedWildcards2 { - static Map map1; - static Map map2; - static Map map3; - static void assign1(Map map) { map1 = map; } - static void assign2(Map map) { map2 = map; } - static void assign3(Map map) { map3 = map; } - public static void main(String[] args) { - assign1(new HashMap()); - assign2(new HashMap()); - //- assign3(new HashMap()); - // warning: [unchecked] unchecked method invocation: - // method assign3 in class UnboundedWildcards2 - // is applied to given types - // assign3(new HashMap()); - // ^ - // required: Map - // found: HashMap - // warning: [unchecked] unchecked conversion - // assign3(new HashMap()); - // ^ - // required: Map - // found: HashMap - // 2 warnings - assign1(new HashMap<>()); - assign2(new HashMap<>()); - assign3(new HashMap<>()); - } -} diff --git a/code/generics/Unconstrained.java b/code/generics/Unconstrained.java deleted file mode 100644 index f683d53f..00000000 --- a/code/generics/Unconstrained.java +++ /dev/null @@ -1,20 +0,0 @@ -// generics/Unconstrained.java -// (c)2020 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. - -class Other {} -class BasicOther extends BasicHolder {} - -public class Unconstrained { - public static void main(String[] args) { - BasicOther b = new BasicOther(); - BasicOther b2 = new BasicOther(); - b.set(new Other()); - Other other = b.get(); - b.f(); - } -} -/* Output: -Other -*/ diff --git a/code/generics/UseList.java b/code/generics/UseList.java deleted file mode 100644 index 924d3b56..00000000 --- a/code/generics/UseList.java +++ /dev/null @@ -1,11 +0,0 @@ -// generics/UseList.java -// (c)2020 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. -// {WillNotCompile} -import java.util.*; - -public class UseList { - void f(List v) {} - void f(List v) {} -} diff --git a/code/generics/UseList2.java b/code/generics/UseList2.java deleted file mode 100644 index 83d3b5d3..00000000 --- a/code/generics/UseList2.java +++ /dev/null @@ -1,10 +0,0 @@ -// generics/UseList2.java -// (c)2020 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. -import java.util.*; - -public class UseList2 { - void f1(List v) {} - void f2(List v) {} -} diff --git a/code/generics/Vehicle.java b/code/generics/Vehicle.java deleted file mode 100644 index 301a84e4..00000000 --- a/code/generics/Vehicle.java +++ /dev/null @@ -1,5 +0,0 @@ -// generics/Vehicle.java -// (c)2020 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. -public class Vehicle {} diff --git a/code/generics/WatercolorSets.java b/code/generics/WatercolorSets.java deleted file mode 100644 index 7956778d..00000000 --- a/code/generics/WatercolorSets.java +++ /dev/null @@ -1,54 +0,0 @@ -// generics/WatercolorSets.java -// (c)2020 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. -import generics.watercolors.*; -import java.util.*; -import static onjava.Sets.*; -import static generics.watercolors.Watercolors.*; - -public class WatercolorSets { - public static void main(String[] args) { - Set set1 = - EnumSet.range(BRILLIANT_RED, VIRIDIAN_HUE); - Set set2 = - EnumSet.range(CERULEAN_BLUE_HUE, BURNT_UMBER); - System.out.println("set1: " + set1); - System.out.println("set2: " + set2); - System.out.println( - "union(set1, set2): " + union(set1, set2)); - Set subset = intersection(set1, set2); - System.out.println( - "intersection(set1, set2): " + subset); - System.out.println("difference(set1, subset): " + - difference(set1, subset)); - System.out.println("difference(set2, subset): " + - difference(set2, subset)); - System.out.println("complement(set1, set2): " + - complement(set1, set2)); - } -} -/* Output: -set1: [BRILLIANT_RED, CRIMSON, MAGENTA, ROSE_MADDER, -VIOLET, CERULEAN_BLUE_HUE, PHTHALO_BLUE, ULTRAMARINE, -COBALT_BLUE_HUE, PERMANENT_GREEN, VIRIDIAN_HUE] -set2: [CERULEAN_BLUE_HUE, PHTHALO_BLUE, ULTRAMARINE, -COBALT_BLUE_HUE, PERMANENT_GREEN, VIRIDIAN_HUE, -SAP_GREEN, YELLOW_OCHRE, BURNT_SIENNA, RAW_UMBER, -BURNT_UMBER] -union(set1, set2): [BURNT_SIENNA, BRILLIANT_RED, -YELLOW_OCHRE, MAGENTA, SAP_GREEN, CERULEAN_BLUE_HUE, -ULTRAMARINE, VIRIDIAN_HUE, VIOLET, RAW_UMBER, -ROSE_MADDER, PERMANENT_GREEN, BURNT_UMBER, -PHTHALO_BLUE, CRIMSON, COBALT_BLUE_HUE] -intersection(set1, set2): [PERMANENT_GREEN, -CERULEAN_BLUE_HUE, ULTRAMARINE, VIRIDIAN_HUE, -PHTHALO_BLUE, COBALT_BLUE_HUE] -difference(set1, subset): [BRILLIANT_RED, MAGENTA, -VIOLET, CRIMSON, ROSE_MADDER] -difference(set2, subset): [BURNT_SIENNA, YELLOW_OCHRE, -BURNT_UMBER, SAP_GREEN, RAW_UMBER] -complement(set1, set2): [BURNT_SIENNA, BRILLIANT_RED, -YELLOW_OCHRE, MAGENTA, SAP_GREEN, VIOLET, RAW_UMBER, -ROSE_MADDER, BURNT_UMBER, CRIMSON] -*/ diff --git a/code/generics/Wildcards.java b/code/generics/Wildcards.java deleted file mode 100644 index 65348ecb..00000000 --- a/code/generics/Wildcards.java +++ /dev/null @@ -1,285 +0,0 @@ -// generics/Wildcards.java -// (c)2020 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. -// Exploring the meaning of wildcards - -public class Wildcards { - // Raw argument: - static void rawArgs(Holder holder, Object arg) { - //- holder.set(arg); - // warning: [unchecked] unchecked call to set(T) - // as a member of the raw type Holder - // holder.set(arg); - // ^ - // where T is a type-variable: - // T extends Object declared in class Holder - // 1 warning - - // Can't do this; don't have any 'T': - // T t = holder.get(); - - // OK, but type information is lost: - Object obj = holder.get(); - } - // Like rawArgs(), but errors instead of warnings: - static void - unboundedArg(Holder holder, Object arg) { - //- holder.set(arg); - // error: method set in class Holder - // cannot be applied to given types; - // holder.set(arg); - // ^ - // required: CAP#1 - // found: Object - // reason: argument mismatch; - // Object cannot be converted to CAP#1 - // where T is a type-variable: - // T extends Object declared in class Holder - // where CAP#1 is a fresh type-variable: - // CAP#1 extends Object from capture of ? - // 1 error - - // Can't do this; don't have any 'T': - // T t = holder.get(); - - // OK, but type information is lost: - Object obj = holder.get(); - } - static T exact1(Holder holder) { - return holder.get(); - } - static T exact2(Holder holder, T arg) { - holder.set(arg); - return holder.get(); - } - static - T wildSubtype(Holder holder, T arg) { - //- holder.set(arg); - // error: method set in class Holder - // cannot be applied to given types; - // holder.set(arg); - // ^ - // required: CAP#1 - // found: T#1 - // reason: argument mismatch; - // T#1 cannot be converted to CAP#1 - // where T#1,T#2 are type-variables: - // T#1 extends Object declared in method - // wildSubtype(Holder,T#1) - // T#2 extends Object declared in class Holder - // where CAP#1 is a fresh type-variable: - // CAP#1 extends T#1 from - // capture of ? extends T#1 - // 1 error - - return holder.get(); - } - static - void wildSupertype(Holder holder, T arg) { - holder.set(arg); - //- T t = holder.get(); - // error: incompatible types: - // CAP#1 cannot be converted to T - // T t = holder.get(); - // ^ - // where T is a type-variable: - // T extends Object declared in method - // wildSupertype(Holder,T) - // where CAP#1 is a fresh type-variable: - // CAP#1 extends Object super: - // T from capture of ? super T - // 1 error - - // OK, but type information is lost: - Object obj = holder.get(); - } - public static void main(String[] args) { - Holder raw = new Holder<>(); - // Or: - raw = new Holder(); - Holder qualified = new Holder<>(); - Holder unbounded = new Holder<>(); - Holder bounded = new Holder<>(); - Long lng = 1L; - - rawArgs(raw, lng); - rawArgs(qualified, lng); - rawArgs(unbounded, lng); - rawArgs(bounded, lng); - - unboundedArg(raw, lng); - unboundedArg(qualified, lng); - unboundedArg(unbounded, lng); - unboundedArg(bounded, lng); - - //- Object r1 = exact1(raw); - // warning: [unchecked] unchecked method invocation: - // method exact1 in class Wildcards is applied - // to given types - // Object r1 = exact1(raw); - // ^ - // required: Holder - // found: Holder - // where T is a type-variable: - // T extends Object declared in - // method exact1(Holder) - // warning: [unchecked] unchecked conversion - // Object r1 = exact1(raw); - // ^ - // required: Holder - // found: Holder - // where T is a type-variable: - // T extends Object declared in - // method exact1(Holder) - // 2 warnings - - Long r2 = exact1(qualified); - Object r3 = exact1(unbounded); // Must return Object - Long r4 = exact1(bounded); - - //- Long r5 = exact2(raw, lng); - // warning: [unchecked] unchecked method invocation: - // method exact2 in class Wildcards is - // applied to given types - // Long r5 = exact2(raw, lng); - // ^ - // required: Holder,T - // found: Holder,Long - // where T is a type-variable: - // T extends Object declared in - // method exact2(Holder,T) - // warning: [unchecked] unchecked conversion - // Long r5 = exact2(raw, lng); - // ^ - // required: Holder - // found: Holder - // where T is a type-variable: - // T extends Object declared in - // method exact2(Holder,T) - // 2 warnings - - Long r6 = exact2(qualified, lng); - - //- Long r7 = exact2(unbounded, lng); - // error: method exact2 in class Wildcards - // cannot be applied to given types; - // Long r7 = exact2(unbounded, lng); - // ^ - // required: Holder,T - // found: Holder,Long - // reason: inference variable T has - // incompatible bounds - // equality constraints: CAP#1 - // lower bounds: Long - // where T is a type-variable: - // T extends Object declared in - // method exact2(Holder,T) - // where CAP#1 is a fresh type-variable: - // CAP#1 extends Object from capture of ? - // 1 error - - //- Long r8 = exact2(bounded, lng); - // error: method exact2 in class Wildcards - // cannot be applied to given types; - // Long r8 = exact2(bounded, lng); - // ^ - // required: Holder,T - // found: Holder,Long - // reason: inference variable T - // has incompatible bounds - // equality constraints: CAP#1 - // lower bounds: Long - // where T is a type-variable: - // T extends Object declared in - // method exact2(Holder,T) - // where CAP#1 is a fresh type-variable: - // CAP#1 extends Long from - // capture of ? extends Long - // 1 error - - //- Long r9 = wildSubtype(raw, lng); - // warning: [unchecked] unchecked method invocation: - // method wildSubtype in class Wildcards - // is applied to given types - // Long r9 = wildSubtype(raw, lng); - // ^ - // required: Holder,T - // found: Holder,Long - // where T is a type-variable: - // T extends Object declared in - // method wildSubtype(Holder,T) - // warning: [unchecked] unchecked conversion - // Long r9 = wildSubtype(raw, lng); - // ^ - // required: Holder - // found: Holder - // where T is a type-variable: - // T extends Object declared in - // method wildSubtype(Holder,T) - // 2 warnings - - Long r10 = wildSubtype(qualified, lng); - // OK, but can only return Object: - Object r11 = wildSubtype(unbounded, lng); - Long r12 = wildSubtype(bounded, lng); - - //- wildSupertype(raw, lng); - // warning: [unchecked] unchecked method invocation: - // method wildSupertype in class Wildcards - // is applied to given types - // wildSupertype(raw, lng); - // ^ - // required: Holder,T - // found: Holder,Long - // where T is a type-variable: - // T extends Object declared in - // method wildSupertype(Holder,T) - // warning: [unchecked] unchecked conversion - // wildSupertype(raw, lng); - // ^ - // required: Holder - // found: Holder - // where T is a type-variable: - // T extends Object declared in - // method wildSupertype(Holder,T) - // 2 warnings - - wildSupertype(qualified, lng); - - //- wildSupertype(unbounded, lng); - // error: method wildSupertype in class Wildcards - // cannot be applied to given types; - // wildSupertype(unbounded, lng); - // ^ - // required: Holder,T - // found: Holder,Long - // reason: cannot infer type-variable(s) T - // (argument mismatch; Holder - // cannot be converted to Holder) - // where T is a type-variable: - // T extends Object declared in - // method wildSupertype(Holder,T) - // where CAP#1 is a fresh type-variable: - // CAP#1 extends Object from capture of ? - // 1 error - - //- wildSupertype(bounded, lng); - // error: method wildSupertype in class Wildcards - // cannot be applied to given types; - // wildSupertype(bounded, lng); - // ^ - // required: Holder,T - // found: Holder,Long - // reason: cannot infer type-variable(s) T - // (argument mismatch; Holder - // cannot be converted to Holder) - // where T is a type-variable: - // T extends Object declared in - // method wildSupertype(Holder,T) - // where CAP#1 is a fresh type-variable: - // CAP#1 extends Long from capture of - // ? extends Long - // 1 error - } -} diff --git a/code/generics/coffee/Americano.java b/code/generics/coffee/Americano.java deleted file mode 100644 index 96cd4a1f..00000000 --- a/code/generics/coffee/Americano.java +++ /dev/null @@ -1,6 +0,0 @@ -// generics/coffee/Americano.java -// (c)2020 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 generics.coffee; -public class Americano extends Coffee {} diff --git a/code/generics/coffee/Breve.java b/code/generics/coffee/Breve.java deleted file mode 100644 index 329c406b..00000000 --- a/code/generics/coffee/Breve.java +++ /dev/null @@ -1,6 +0,0 @@ -// generics/coffee/Breve.java -// (c)2020 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 generics.coffee; -public class Breve extends Coffee {} diff --git a/code/generics/coffee/Cappuccino.java b/code/generics/coffee/Cappuccino.java deleted file mode 100644 index 3ce89b50..00000000 --- a/code/generics/coffee/Cappuccino.java +++ /dev/null @@ -1,6 +0,0 @@ -// generics/coffee/Cappuccino.java -// (c)2020 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 generics.coffee; -public class Cappuccino extends Coffee {} diff --git a/code/generics/coffee/Coffee.java b/code/generics/coffee/Coffee.java deleted file mode 100644 index c90d88c1..00000000 --- a/code/generics/coffee/Coffee.java +++ /dev/null @@ -1,14 +0,0 @@ -// generics/coffee/Coffee.java -// (c)2020 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 generics.coffee; - -public class Coffee { - private static long counter = 0; - private final long id = counter++; - @Override - public String toString() { - return getClass().getSimpleName() + " " + id; - } -} diff --git a/code/generics/coffee/CoffeeSupplier.java b/code/generics/coffee/CoffeeSupplier.java deleted file mode 100644 index fe5dced8..00000000 --- a/code/generics/coffee/CoffeeSupplier.java +++ /dev/null @@ -1,72 +0,0 @@ -// generics/coffee/CoffeeSupplier.java -// (c)2020 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. -// {java generics.coffee.CoffeeSupplier} -package generics.coffee; -import java.util.*; -import java.util.function.*; -import java.util.stream.*; -import java.lang.reflect.InvocationTargetException; - -public class CoffeeSupplier -implements Supplier, Iterable { - private Class[] types = { Latte.class, Mocha.class, - Cappuccino.class, Americano.class, Breve.class, }; - private static Random rand = new Random(47); - public CoffeeSupplier() {} - // For iteration: - private int size = 0; - public CoffeeSupplier(int sz) { size = sz; } - @Override - public Coffee get() { - try { - return (Coffee) - types[rand.nextInt(types.length)] - .getConstructor().newInstance(); - // Report programmer errors at run time: - } catch(InstantiationException | - NoSuchMethodException | - InvocationTargetException | - IllegalAccessException e) { - throw new RuntimeException(e); - } - } - class CoffeeIterator implements Iterator { - int count = size; - @Override - public boolean hasNext() { return count > 0; } - @Override - public Coffee next() { - count--; - return CoffeeSupplier.this.get(); - } - @Override - public void remove() { // Not implemented - throw new UnsupportedOperationException(); - } - } - @Override - public Iterator iterator() { - return new CoffeeIterator(); - } - public static void main(String[] args) { - Stream.generate(new CoffeeSupplier()) - .limit(5) - .forEach(System.out::println); - for(Coffee c : new CoffeeSupplier(5)) - System.out.println(c); - } -} -/* Output: -Americano 0 -Latte 1 -Americano 2 -Mocha 3 -Mocha 4 -Breve 5 -Americano 6 -Latte 7 -Cappuccino 8 -Cappuccino 9 -*/ diff --git a/code/generics/coffee/Latte.java b/code/generics/coffee/Latte.java deleted file mode 100644 index d735cc87..00000000 --- a/code/generics/coffee/Latte.java +++ /dev/null @@ -1,6 +0,0 @@ -// generics/coffee/Latte.java -// (c)2020 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 generics.coffee; -public class Latte extends Coffee {} diff --git a/code/generics/coffee/Mocha.java b/code/generics/coffee/Mocha.java deleted file mode 100644 index cc567be1..00000000 --- a/code/generics/coffee/Mocha.java +++ /dev/null @@ -1,6 +0,0 @@ -// generics/coffee/Mocha.java -// (c)2020 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 generics.coffee; -public class Mocha extends Coffee {} diff --git a/code/generics/decorator/Decoration.java b/code/generics/decorator/Decoration.java deleted file mode 100644 index 96611a75..00000000 --- a/code/generics/decorator/Decoration.java +++ /dev/null @@ -1,51 +0,0 @@ -// generics/decorator/Decoration.java -// (c)2020 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. -// {java generics.decorator.Decoration} -package generics.decorator; -import java.util.*; - -class Basic { - private String value; - public void set(String val) { value = val; } - public String get() { return value; } -} - -class Decorator extends Basic { - protected Basic basic; - Decorator(Basic basic) { this.basic = basic; } - @Override - public void set(String val) { basic.set(val); } - @Override - public String get() { return basic.get(); } -} - -class TimeStamped extends Decorator { - private final long timeStamp; - TimeStamped(Basic basic) { - super(basic); - timeStamp = new Date().getTime(); - } - public long getStamp() { return timeStamp; } -} - -class SerialNumbered extends Decorator { - private static long counter = 1; - private final long serialNumber = counter++; - SerialNumbered(Basic basic) { super(basic); } - public long getSerialNumber() { return serialNumber; } -} - -public class Decoration { - public static void main(String[] args) { - TimeStamped t = new TimeStamped(new Basic()); - TimeStamped t2 = new TimeStamped( - new SerialNumbered(new Basic())); - //- t2.getSerialNumber(); // Not available - SerialNumbered s = new SerialNumbered(new Basic()); - SerialNumbered s2 = new SerialNumbered( - new TimeStamped(new Basic())); - //- s2.getStamp(); // Not available - } -} diff --git a/code/generics/dogsandrobots.go b/code/generics/dogsandrobots.go deleted file mode 100644 index f65b9c18..00000000 --- a/code/generics/dogsandrobots.go +++ /dev/null @@ -1,32 +0,0 @@ -// generics/dogsandrobots.go -// (c)2020 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 main -import "fmt" - -type Dog struct {} -func (this Dog) speak() { fmt.Printf("Arf!\n")} -func (this Dog) sit() { fmt.Printf("Sitting\n")} -func (this Dog) reproduce() {} - -type Robot struct {} -func (this Robot) speak() { fmt.Printf("Click!\n") } -func (this Robot) sit() { fmt.Printf("Clank!\n") } -func (this Robot) oilChange() {} - -func perform(speaker interface { speak(); sit() }) { - speaker.speak(); - speaker.sit(); -} - -func main() { - perform(Dog{}) - perform(Robot{}) -} -/* Output: -Arf! -Sitting -Click! -Clank! -*/ diff --git a/code/generics/watercolors/Watercolors.java b/code/generics/watercolors/Watercolors.java deleted file mode 100644 index 0625e532..00000000 --- a/code/generics/watercolors/Watercolors.java +++ /dev/null @@ -1,15 +0,0 @@ -// generics/watercolors/Watercolors.java -// (c)2020 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 generics.watercolors; - -public enum Watercolors { - ZINC, LEMON_YELLOW, MEDIUM_YELLOW, DEEP_YELLOW, - ORANGE, BRILLIANT_RED, CRIMSON, MAGENTA, - ROSE_MADDER, VIOLET, CERULEAN_BLUE_HUE, - PHTHALO_BLUE, ULTRAMARINE, COBALT_BLUE_HUE, - PERMANENT_GREEN, VIRIDIAN_HUE, SAP_GREEN, - YELLOW_OCHRE, BURNT_SIENNA, RAW_UMBER, - BURNT_UMBER, PAYNES_GRAY, IVORY_BLACK -} diff --git a/code/gradle.properties b/code/gradle.properties deleted file mode 100644 index f97ebb7d..00000000 --- a/code/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -org.gradle.parallel=true diff --git a/code/gradle/checkstyle.gradle b/code/gradle/checkstyle.gradle deleted file mode 100644 index 0f0e6086..00000000 --- a/code/gradle/checkstyle.gradle +++ /dev/null @@ -1,14 +0,0 @@ -apply plugin: 'checkstyle' - -checkstyle { - ignoreFailures = true - configFile = new File(rootProject.projectDir, 'checkstyle.xml') - sourceSets = [sourceSets.main] -} - -tasks.withType(Checkstyle) { - reports { - xml.enabled = false - html.enabled = true - } -} diff --git a/code/gradle/findbugs.gradle b/code/gradle/findbugs.gradle deleted file mode 100644 index ac628cb2..00000000 --- a/code/gradle/findbugs.gradle +++ /dev/null @@ -1,15 +0,0 @@ -/* -apply plugin: 'findbugs' - -findbugs { - ignoreFailures = true - sourceSets = [sourceSets.main] -} - -tasks.withType(FindBugs) { - reports { - xml.enabled = false - html.enabled = true - } -} -*/ diff --git a/code/gradle/java.gradle b/code/gradle/java.gradle deleted file mode 100644 index eadc4ef9..00000000 --- a/code/gradle/java.gradle +++ /dev/null @@ -1,39 +0,0 @@ -apply plugin: 'java' - -sourceCompatibility = '1.8' -targetCompatibility = '1.8' - -compileJava { - options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" -} - -sourceSets { - main { - java { - srcDir projectDir - exclude "tests/**" - } - resources { - srcDir projectDir - include '*.xml' - } - } - - test { - java { - srcDir file("tests") - } - } -} - -repositories { - jcenter() -} - -dependencies { - // Logging: - compile 'org.slf4j:slf4j-api:1.7.21' - compile 'ch.qos.logback:logback-classic:1.1.7' - // You can also use the JDK's built-in logging as the back end: - // compile group: 'org.slf4j:slf4j-jdk14:1.7.21' -} \ No newline at end of file diff --git a/code/gradle/jmh.gradle b/code/gradle/jmh.gradle deleted file mode 100644 index ce61db4b..00000000 --- a/code/gradle/jmh.gradle +++ /dev/null @@ -1,17 +0,0 @@ -apply plugin: 'me.champeau.gradle.jmh' - -sourceSets { - jmh { - java { - srcDir projectDir - } - } -} - -jmh { - jmhVersion = '1.17.4' - duplicateClassesStrategy = 'warn' - failOnError = true - // See https://github.com/melix/jmh-gradle-plugin - // for other options -} diff --git a/code/gradle/junit-jupiter.gradle b/code/gradle/junit-jupiter.gradle deleted file mode 100644 index 98a77843..00000000 --- a/code/gradle/junit-jupiter.gradle +++ /dev/null @@ -1,72 +0,0 @@ -import org.apache.tools.ant.util.TeeOutputStream - -dependencies { - testImplementation(platform('org.junit:junit-bom:5.7.0')) - testImplementation('org.junit.jupiter:junit-jupiter') -} - -test { - useJUnitPlatform() - testLogging { - events "passed", "skipped", "failed" - } -} - -/* NEW: (REQUIRES CODE REWRITES IN BOOK AND TEST CODE) --> http://junit.org/junit5/docs/current/user-guide/ - -ext { - junitJupiterVersion = '5.0.0-M3' -} - -dependencies { - testCompile "org.junit.jupiter:junit-jupiter-api:${junitJupiterVersion}" - testRuntime "org.junit.jupiter:junit-jupiter-engine:${junitJupiterVersion}" -} - - -junitPlatform { - platformVersion '1.0.0-M3' - - filters { - packages { - exclude 'collectiontopics.jmh' - } - includeClassNamePattern '.*' - } -} -*/ - -/* Store test output in $projectName/tests - JUnit 5's junitPlatformTest runs as a "javaExec" rather than a "test", - so we can't hook into the before/after test behavior. -*/ -tasks.findByPath(":$name:test").configure { - File testDir = file("tests") - if(testDir.exists()) { - File outFile = new File(testDir, 'report.txt') - - Writer taskOutput - - doFirst { - taskOutput = project.file(outFile).newWriter() - } - - testLogging.showStandardStreams = true - - onOutput { descriptor, event -> - taskOutput.append(event.message) - } - - doLast { - // WARNING: if the task fails, this won't be executed and the file remains open. - // The memory cache version doesn't have this problem. - taskOutput.close() - - if(outFile.size() == 0) - outFile.delete() - else if(outFile.text.contains("0 tests found")) - outFile.delete() - } - } -} diff --git a/code/gradle/subprojects.gradle b/code/gradle/subprojects.gradle deleted file mode 100644 index e9d857d8..00000000 --- a/code/gradle/subprojects.gradle +++ /dev/null @@ -1,67 +0,0 @@ -project(':validating') { - jmh { - include = 'validating.jmh.*' - } -} - -project(':equalshashcode') { - dependencies { - compile project(':typeinfo') - compile project(':collections') - } -} - -project(':lowlevel') { - dependencies { - compile project(':enums') - } -} - -project(':strings') { - dependencies { - compile project(':generics') - } -} - -project(':serialization') { - configurations.all { - resolutionStrategy { - force 'xml-apis:xml-apis:1.0.b2' - } - } - dependencies { - compile 'com.io7m.xom:xom:1.2.10' - } -} - -project(':interfaces') { - dependencies { - compile project(':polymorphism') - } -} - -project(':hiding') { - dependencies { - compile project(':com') - } -} - -project(':generics') { - dependencies { - compile project(':typeinfo') - } -} - -project(':collections') { - dependencies { - compile project(':typeinfo') - } -} - -configure(subprojects - project(':onjava')) { - dependencies { - compile project(':onjava') - compile 'com.google.guava:guava:21.0' - compileOnly "org.openjdk.jmh:jmh-core:${jmh.jmhVersion}" - } -} diff --git a/code/gradle/wrapper/gradle-wrapper.jar b/code/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index e708b1c023ec8b20f512888fe07c5bd3ff77bb8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59203 zcma&O1CT9Y(k9%tZQHhO+qUh#ZQHhO+qmuS+qP|E@9xZO?0h@l{(r>DQ>P;GjjD{w zH}lENr;dU&FbEU?00aa80D$0M0RRB{U*7-#kbjS|qAG&4l5%47zyJ#WrfA#1$1Ctx zf&Z_d{GW=lf^w2#qRJ|CvSJUi(^E3iv~=^Z(zH}F)3Z%V3`@+rNB7gTVU{Bb~90p|f+0(v;nz01EG7yDMX9@S~__vVgv%rS$+?IH+oZ03D5zYrv|^ zC1J)SruYHmCki$jLBlTaE5&dFG9-kq3!^i>^UQL`%gn6)jz54$WDmeYdsBE9;PqZ_ zoGd=P4+|(-u4U1dbAVQrFWoNgNd;0nrghPFbQrJctO>nwDdI`Q^i0XJDUYm|T|RWc zZ3^Qgo_Qk$%Fvjj-G}1NB#ZJqIkh;kX%V{THPqOyiq)d)0+(r9o(qKlSp*hmK#iIY zA^)Vr$-Hz<#SF=0@tL@;dCQsm`V9s1vYNq}K1B)!XSK?=I1)tX+bUV52$YQu*0%fnWEukW>mxkz+%3-S!oguE8u#MGzST8_Dy^#U?fA@S#K$S@9msUiX!gd_ow>08w5)nX{-KxqMOo7d?k2&?Vf z&diGDtZr(0cwPe9z9FAUSD9KC)7(n^lMWuayCfxzy8EZsns%OEblHFSzP=cL6}?J| z0U$H!4S_TVjj<`6dy^2j`V`)mC;cB%* z8{>_%E1^FH!*{>4a7*C1v>~1*@TMcLK{7nEQ!_igZC}ikJ$*<$yHy>7)oy79A~#xE zWavoJOIOC$5b6*q*F_qN1>2#MY)AXVyr$6x4b=$x^*aqF*L?vmj>Mgv+|ITnw_BoW zO?jwHvNy^prH{9$rrik1#fhyU^MpFqF2fYEt(;4`Q&XWOGDH8k6M=%@fics4ajI;st# zCU^r1CK&|jzUhRMv;+W~6N;u<;#DI6cCw-otsc@IsN3MoSD^O`eNflIoR~l4*&-%RBYk@gb^|-JXs&~KuSEmMxB}xSb z@K76cXD=Y|=I&SNC2E+>Zg?R6E%DGCH5J1nU!A|@eX9oS(WPaMm==k2s_ueCqdZw| z&hqHp)47`c{BgwgvY2{xz%OIkY1xDwkw!<0veB#yF4ZKJyabhyyVS`gZepcFIk%e2 zTcrmt2@-8`7i-@5Nz>oQWFuMC_KlroCl(PLSodswHqJ3fn<;gxg9=}~3x_L3P`9Sn zChIf}8vCHvTriz~T2~FamRi?rh?>3bX1j}%bLH+uFX+p&+^aXbOK7clZxdU~6Uxgy z8R=obwO4dL%pmVo*Ktf=lH6hnlz_5k3cG;m8lgaPp~?eD!Yn2kf)tU6PF{kLyn|oI@eQ`F z3IF7~Blqg8-uwUuWZScRKn%c2_}dXB6Dx_&xR*n9M9LXasJhtZdr$vBY!rP{c@=)& z#!?L$2UrkvClwQO>U*fSMs67oSj2mxiJ$t;E|>q%Kh_GzzWWO&3;ufU%2z%ucBU8H z3WIwr$n)cfCXR&>tyB7BcSInK>=ByZA%;cVEJhcg<#6N{aZC4>K41XF>ZgjG`z_u& zGY?;Ad?-sgiOnI`oppF1o1Gurqbi*;#x2>+SSV6|1^G@ooVy@fg?wyf@0Y!UZ4!}nGuLeC^l)6pwkh|oRY`s1Pm$>zZ3u-83T|9 zGaKJIV3_x+u1>cRibsaJpJqhcm%?0-L;2 zitBrdRxNmb0OO2J%Y&Ym(6*`_P3&&5Bw157{o7LFguvxC$4&zTy#U=W*l&(Q2MNO} zfaUwYm{XtILD$3864IA_nn34oVa_g^FRuHL5wdUd)+W-p-iWCKe8m_cMHk+=? zeKX)M?Dt(|{r5t7IenkAXo%&EXIb-i^w+0CX0D=xApC=|Xy(`xy+QG^UyFe z+#J6h_&T5i#sV)hj3D4WN%z;2+jJcZxcI3*CHXGmOF3^)JD5j&wfX)e?-|V0GPuA+ zQFot%aEqGNJJHn$!_}#PaAvQ^{3-Ye7b}rWwrUmX53(|~i0v{}G_sI9uDch_brX&6 zWl5Ndj-AYg(W9CGfQf<6!YmY>Ey)+uYd_JNXH=>|`OH-CDCmcH(0%iD_aLlNHKH z7bcW-^5+QV$jK?R*)wZ>r9t}loM@XN&M-Pw=F#xn(;u3!(3SXXY^@=aoj70;_=QE9 zGghsG3ekq#N||u{4We_25U=y#T*S{4I{++Ku)> zQ!DZW;pVcn>b;&g2;YE#+V`v*Bl&Y-i@X6D*OpNA{G@JAXho&aOk(_j^weW{#3X5Y z%$q_wpb07EYPdmyH(1^09i$ca{O<}7) zRWncXdSPgBE%BM#by!E>tdnc$8RwUJg1*x($6$}ae$e9Knj8gvVZe#bLi!<+&BkFj zg@nOpDneyc+hU9P-;jmOSMN|*H#>^Ez#?;%C3hg_65leSUm;iz)UkW)jX#p)e&S&M z1|a?wDzV5NVnlhRBCd_;F87wp>6c<&nkgvC+!@KGiIqWY4l}=&1w7|r6{oBN8xyzh zG$b#2=RJp_iq6)#t5%yLkKx(0@D=C3w+oiXtSuaQ%I1WIb-eiE$d~!)b@|4XLy!CZ z9p=t=%3ad@Ep+<9003D2KZ5VyP~_n$=;~r&YUg5UZ0KVD&tR1DHy9x)qWtKJp#Kq# zP*8p#W(8JJ_*h_3W}FlvRam?<4Z+-H77^$Lvi+#vmhL9J zJ<1SV45xi;SrO2f=-OB(7#iNA5)x1uNC-yNxUw|!00vcW2PufRm>e~toH;M0Q85MQLWd?3O{i8H+5VkR@l9Dg-ma ze2fZ%>G(u5(k9EHj2L6!;(KZ8%8|*-1V|B#EagbF(rc+5iL_5;Eu)L4Z-V;0HfK4d z*{utLse_rvHZeQ>V5H=f78M3Ntg1BPxFCVD{HbNA6?9*^YIq;B-DJd{Ca2L#)qWP? zvX^NhFmX?CTWw&Ns}lgs;r3i+Bq@y}Ul+U%pzOS0Fcv9~aB(0!>GT0)NO?p=25LjN z2bh>6RhgqD7bQj#k-KOm@JLgMa6>%-ok1WpOe)FS^XOU{c?d5shG(lIn3GiVBxmg`u%-j=)^v&pX1JecJics3&jvPI)mDut52? z3jEA)DM%}BYbxxKrizVYwq?(P&19EXlwD9^-6J+4!}9{ywR9Gk42jjAURAF&EO|~N z)?s>$Da@ikI4|^z0e{r`J8zIs>SpM~Vn^{3fArRu;?+43>lD+^XtUcY1HidJwnR6+ z!;oG2=B6Z_=M%*{z-RaHc(n|1RTKQdNjjV!Pn9lFt^4w|AeN06*j}ZyhqZ^!-=cyGP_ShV1rGxkx8t zB;8`h!S{LD%ot``700d0@Grql(DTt4Awgmi+Yr0@#jbe=2#UkK%rv=OLqF)9D7D1j z!~McAwMYkeaL$~kI~90)5vBhBzWYc3Cj1WI0RS`z000R8-@ET0dA~*r(gSiCJmQMN&4%1D zyVNf0?}sBH8zNbBLn>~(W{d3%@kL_eQ6jEcR{l>C|JK z(R-fA!z|TTRG40|zv}7E@PqCAXP3n`;%|SCQ|ZS%ym$I{`}t3KPL&^l5`3>yah4*6 zifO#{VNz3)?ZL$be;NEaAk9b#{tV?V7 zP|wf5YA*1;s<)9A4~l3BHzG&HH`1xNr#%){4xZ!jq%o=7nN*wMuXlFV{HaiQLJ`5G zBhDi#D(m`Q1pLh@Tq+L;OwuC52RdW7b8}~60WCOK5iYMUad9}7aWBuILb({5=z~YF zt?*Jr5NG+WadM{mDL>GyiByCuR)hd zA=HM?J6l1Xv0Dl+LW@w$OTcEoOda^nFCw*Sy^I@$sSuneMl{4ys)|RY#9&NxW4S)9 zq|%83IpslTLoz~&vTo!Ga@?rj_kw{|k{nv+w&Ku?fyk4Ki4I?);M|5Axm)t+BaE)D zm(`AQ#k^DWrjbuXoJf2{Aj^KT zFb1zMSqxq|vceV+Mf-)$oPflsO$@*A0n0Z!R{&(xh8s}=;t(lIy zv$S8x>m;vQNHuRzoaOo?eiWFe{0;$s`Bc+Osz~}Van${u;g(su`3lJ^TEfo~nERfP z)?aFzpDgnLYiERsKPu|0tq4l2wT)Atr6Qb%m-AUn6HnCue*yWICp7TjW$@sO zm5rm4aTcPQ(rfi7a`xP7cKCFrJD}*&_~xgLyr^-bmsL}y;A5P|al8J3WUoBSjqu%v zxC;mK!g(7r6RRJ852Z~feoC&sD3(6}^5-uLK8o)9{8L_%%rItZK9C){UxB|;G>JbP zsRRtS4-3B*5c+K2kvmgZK8472%l>3cntWUOVHxB|{Ay~aOg5RN;{PJgeVD*H%ac+y!h#wi%o2bF2Ca8IyMyH{>4#{E_8u^@+l-+n=V}Sq?$O z{091@v%Bd*3pk0^2UtiF9Z+(a@wy6 zUdw8J*ze$K#=$48IBi1U%;hmhO>lu!uU;+RS}p&6@rQila7WftH->*A4=5W|Fmtze z)7E}jh@cbmr9iup^i%*(uF%LG&!+Fyl@LFA-}Ca#bxRfDJAiR2dt6644TaYw1Ma79 zt8&DYj31j^5WPNf5P&{)J?WlCe@<3u^78wnd(Ja4^a>{^Tw}W>|Cjt^If|7l^l)^Q zbz|7~CF(k_9~n|h;ysZ+jHzkXf(*O*@5m zLzUmbHp=x!Q|!9NVXyipZ3)^GuIG$k;D)EK!a5=8MFLI_lpf`HPKl=-Ww%z8H_0$j ztJ||IfFG1lE9nmQ0+jPQy zCBdKkjArH@K7jVcMNz);Q(Q^R{d5G?-kk;Uu_IXSyWB)~KGIizZL(^&qF;|1PI7!E zTP`%l)gpX|OFn&)M%txpQ2F!hdA~hX1Cm5)IrdljqzRg!f{mN%G~H1&oqe`5eJCIF zHdD7O;AX-{XEV(a`gBFJ9ews#CVS2y!&>Cm_dm3C8*n3MA*e67(WC?uP@8TXuMroq z{#w$%z@CBIkRM7?}Xib+>hRjy?%G!fiw8! z8(gB+8J~KOU}yO7UGm&1g_MDJ$IXS!`+*b*QW2x)9>K~Y*E&bYMnjl6h!{17_8d!%&9D`a7r&LKZjC<&XOvTRaKJ1 zUY@hl5^R&kZl3lU3njk`3dPzxj$2foOL26r(9zsVF3n_F#v)s5vv3@dgs|lP#eylq62{<-vczqP!RpVBTgI>@O6&sU>W|do17+#OzQ7o5A$ICH z?GqwqnK^n2%LR;$^oZM;)+>$X3s2n}2jZ7CdWIW0lnGK-b#EG01)P@aU`pg}th&J-TrU`tIpb5t((0eu|!u zQz+3ZiOQ^?RxxK4;zs=l8q!-n7X{@jSwK(iqNFiRColuEOg}!7cyZi`iBX4g1pNBj zAPzL?P^Ljhn;1$r8?bc=#n|Ed7wB&oHcw()&*k#SS#h}jO?ZB246EGItsz*;^&tzp zu^YJ0=lwsi`eP_pU8}6JA7MS;9pfD;DsSsLo~ogzMNP70@@;Fm8f0^;>$Z>~}GWRw!W5J3tNX*^2+1f3hz{~rIzJo z6W%J(H!g-eI_J1>0juX$X4Cl6i+3wbc~k146UIX&G22}WE>0ga#WLsn9tY(&29zBvH1$`iWtTe zG2jYl@P!P)eb<5DsR72BdI7-zP&cZNI{7q3e@?N8IKc4DE#UVr->|-ryuJXk^u^>4 z$3wE~=q390;XuOQP~TNoDR?#|NSPJ%sTMInA6*rJ%go|=YjGe!B>z6u$IhgQSwoV* zjy3F2#I>uK{42{&IqP59)Y(1*Z>>#W8rCf4_eVsH)`v!P#^;BgzKDR`ARGEZzkNX+ zJUQu=*-ol=Xqqt5=`=pA@BIn@6a9G8C{c&`i^(i+BxQO9?YZ3iu%$$da&Kb?2kCCo zo7t$UpSFWqmydXf@l3bVJ=%K?SSw)|?srhJ-1ZdFu*5QhL$~-IQS!K1s@XzAtv6*Y zl8@(5BlWYLt1yAWy?rMD&bwze8bC3-GfNH=p zynNFCdxyX?K&G(ZZ)afguQ2|r;XoV^=^(;Cku#qYn4Lus`UeKt6rAlFo_rU`|Rq z&G?~iWMBio<78of-2X(ZYHx~=U0Vz4btyXkctMKdc9UM!vYr~B-(>)(Hc|D zMzkN4!PBg%tZoh+=Gba!0++d193gbMk2&krfDgcbx0jI92cq?FFESVg0D$>F+bil} zY~$)|>1HZsX=5sAZ2WgPB5P=8X#TI+NQ(M~GqyVB53c6IdX=k>Wu@A0Svf5#?uHaF zsYn|koIi3$(%GZ2+G+7Fv^lHTb#5b8sAHSTnL^qWZLM<(1|9|QFw9pnRU{svj}_Al zL)b9>fN{QiA($8peNEJyy`(a{&uh-T4_kdZFIVsKKVM(?05}76EEz?#W za^fiZOAd14IJ4zLX-n7Lq0qlQ^lW8Cvz4UKkV9~P}>sq0?xD3vg+$4vLm~C(+ zM{-3Z#qnZ09bJ>}j?6ry^h+@PfaD7*jZxBEY4)UG&daWb??6)TP+|3#Z&?GL?1i+280CFsE|vIXQbm| zM}Pk!U`U5NsNbyKzkrul-DzwB{X?n3E6?TUHr{M&+R*2%yOiXdW-_2Yd6?38M9Vy^ z*lE%gA{wwoSR~vN0=no}tP2Ul5Gk5M(Xq`$nw#ndFk`tcpd5A=Idue`XZ!FS>Q zG^0w#>P4pPG+*NC9gLP4x2m=cKP}YuS!l^?sHSFftZy{4CoQrb_ z^20(NnG`wAhMI=eq)SsIE~&Gp9Ne0nD4%Xiu|0Fj1UFk?6avDqjdXz{O1nKao*46y zT8~iA%Exu=G#{x=KD;_C&M+Zx4+n`sHT>^>=-1YM;H<72k>$py1?F3#T1*ef9mLZw z5naLQr?n7K;2l+{_uIw*_1nsTn~I|kkCgrn;|G~##hM;9l7Jy$yJfmk+&}W@JeKcF zx@@Woiz8qdi|D%aH3XTx5*wDlbs?dC1_nrFpm^QbG@wM=i2?Zg;$VK!c^Dp8<}BTI zyRhAq@#%2pGV49*Y5_mV4+OICP|%I(dQ7x=6Ob}>EjnB_-_18*xrY?b%-yEDT(wrO z9RY2QT0`_OpGfMObKHV;QLVnrK%mc?$WAdIT`kJQT^n%GuzE7|9@k3ci5fYOh(287 zuIbg!GB3xLg$YN=n)^pHGB0jH+_iIiC=nUcD;G6LuJsjn2VI1cyZx=a?ShCsF==QK z;q~*m&}L<-cb+mDDXzvvrRsybcgQ;Vg21P(uLv5I+eGc7o7tc6`;OA9{soHFOz zT~2?>Ts}gprIX$wRBb4yE>ot<8+*Bv`qbSDv*VtRi|cyWS>)Fjs>fkNOH-+PX&4(~ z&)T8Zam2L6puQl?;5zg9h<}k4#|yH9czHw;1jw-pwBM*O2hUR6yvHATrI%^mvs9q_ z&ccT0>f#eDG<^WG^q@oVqlJrhxH)dcq2cty@l3~|5#UDdExyXUmLQ}f4#;6fI{f^t zDCsgIJ~0`af%YR%Ma5VQq-p21k`vaBu6WE?66+5=XUd%Ay%D$irN>5LhluRWt7 zov-=f>QbMk*G##&DTQyou$s7UqjjW@k6=!I@!k+S{pP8R(2=e@io;N8E`EOB;OGoI zw6Q+{X1_I{OO0HPpBz!X!@`5YQ2)t{+!?M_iH25X(d~-Zx~cXnS9z>u?+If|iNJbx zyFU2d1!ITX64D|lE0Z{dLRqL1Ajj=CCMfC4lD3&mYR_R_VZ>_7_~|<^o*%_&jevU+ zQ4|qzci=0}Jydw|LXLCrOl1_P6Xf@c0$ieK2^7@A9UbF{@V_0p%lqW|L?5k>bVM8|p5v&2g;~r>B8uo<4N+`B zH{J)h;SYiIVx@#jI&p-v3dwL5QNV1oxPr8J%ooezTnLW>i*3Isb49%5i!&ac_dEXv zvXmVUck^QHmyrF8>CGXijC_R-y(Qr{3Zt~EmW)-nC!tiH`wlw5D*W7Pip;T?&j%kX z6DkZX4&}iw>hE(boLyjOoupf6JpvBG8}jIh!!VhnD0>}KSMMo{1#uU6kiFcA04~|7 zVO8eI&x1`g4CZ<2cYUI(n#wz2MtVFHx47yE5eL~8bot~>EHbevSt}LLMQX?odD{Ux zJMnam{d)W4da{l7&y-JrgiU~qY3$~}_F#G7|MxT)e;G{U`In&?`j<5D->}cb{}{T(4DF0BOk-=1195KB-E*o@c?`>y#4=dMtYtSY=&L{!TAjFVcq0y@AH`vH! z$41+u!Ld&}F^COPgL(EE{0X7LY&%D7-(?!kjFF7=qw<;`V{nwWBq<)1QiGJgUc^Vz ztMUlq1bZqKn17|6x6iAHbWc~l1HcmAxr%$Puv!znW)!JiukwIrqQ00|H$Z)OmGG@= zv%A8*4cq}(?qn4rN6o`$Y))(MyXr8R<2S^J+v(wmFmtac!%VOfN?&(8Nr!T@kV`N; z*Q33V3t`^rN&aBiHet)18wy{*wi1=W!B%B-Q6}SCrUl$~Hl{@!95ydml@FK8P=u4s z4e*7gV2s=YxEvskw2Ju!2%{8h01rx-3`NCPc(O zH&J0VH5etNB2KY6k4R@2Wvl^Ck$MoR3=)|SEclT2ccJ!RI9Nuter7u9@;sWf-%um;GfI!=eEIQ2l2p_YWUd{|6EG ze{yO6;lMc>;2tPrsNdi@&1K6(1;|$xe8vLgiouj%QD%gYk`4p{Ktv9|j+!OF-P?@p z;}SV|oIK)iwlBs+`ROXkhd&NK zzo__r!B>tOXpBJMDcv!Mq54P+n4(@dijL^EpO1wdg~q+!DT3lB<>9AANSe!T1XgC=J^)IP0XEZ()_vpu!!3HQyJhwh?r`Ae%Yr~b% zO*NY9t9#qWa@GCPYOF9aron7thfWT`eujS4`t2uG6)~JRTI;f(ZuoRQwjZjp5Pg34 z)rp$)Kr?R+KdJ;IO;pM{$6|2y=k_siqvp%)2||cHTe|b5Ht8&A{wazGNca zX$Ol?H)E_R@SDi~4{d-|8nGFhZPW;Cts1;08TwUvLLv&_2$O6Vt=M)X;g%HUr$&06 zISZb(6)Q3%?;3r~*3~USIg=HcJhFtHhIV(siOwV&QkQe#J%H9&E21!C*d@ln3E@J* zVqRO^<)V^ky-R|%{(9`l-(JXq9J)1r$`uQ8a}$vr9E^nNiI*thK8=&UZ0dsFN_eSl z(q~lnD?EymWLsNa3|1{CRPW60>DSkY9YQ;$4o3W7Ms&@&lv9eH!tk~N&dhqX&>K@} zi1g~GqglxkZ5pEFkllJ)Ta1I^c&Bt6#r(QLQ02yHTaJB~- zCcE=5tmi`UA>@P=1LBfBiqk)HB4t8D?02;9eXj~kVPwv?m{5&!&TFYhu>3=_ zsGmYZ^mo*-j69-42y&Jj0cBLLEulNRZ9vXE)8~mt9C#;tZs;=#M=1*hebkS;7(aGf zcs7zH(I8Eui9UU4L--))yy`&d&$In&VA2?DAEss4LAPCLd>-$i?lpXvn!gu^JJ$(DoUlc6wE98VLZ*z`QGQov5l4Fm_h?V-;mHLYDVOwKz7>e4+%AzeO>P6v}ndPW| zM>m#6Tnp7K?0mbK=>gV}=@k*0Mr_PVAgGMu$j+pWxzq4MAa&jpCDU&-5eH27Iz>m^ zax1?*HhG%pJ((tkR(V(O(L%7v7L%!_X->IjS3H5kuXQT2!ow(;%FDE>16&3r){!ex zhf==oJ!}YU89C9@mfDq!P3S4yx$aGB?rbtVH?sHpg?J5C->!_FHM%Hl3#D4eplxzQ zRA+<@LD%LKSkTk2NyWCg7u=$%F#;SIL44~S_OGR}JqX}X+=bc@swpiClB`Zbz|f!4 z7Ysah7OkR8liXfI`}IIwtEoL}(URrGe;IM8%{>b1SsqXh)~w}P>yiFRaE>}rEnNkT z!HXZUtxUp1NmFm)Dm@-{FI^aRQqpSkz}ZSyKR%Y}YHNzBk)ZIp} zMtS=aMvkgWKm9&oTcU0?S|L~CDqA+sHpOxwnswF-fEG)cXCzUR?ps@tZa$=O)=L+5 zf%m58cq8g_o}3?Bhh+c!w4(7AjxwQ3>WnVi<{{38g7yFboo>q|+7qs<$8CPXUFAN< zG&}BHbbyQ5n|qqSr?U~GY{@GJ{(Jny{bMaOG{|IkUj7tj^9pa9|FB_<+KHLxSxR;@ zHpS$4V)PP+tx}22fWx(Ku9y+}Ap;VZqD0AZW4gCDTPCG=zgJmF{|x;(rvdM|2|9a}cex6xrMkERnkE;}jvU-kmzd%_J50$M`lIPCKf+^*zL=@LW`1SaEc%=m zQ+lT06Gw+wVwvQ9fZ~#qd430v2HndFsBa9WjD0P}K(rZYdAt^5WQIvb%D^Q|pkVE^ zte$&#~zmULFACGfS#g=2OLOnIf2Of-k!(BIHjs77nr!5Q1*I9 z1%?=~#Oss!rV~?-6Gm~BWJiA4mJ5TY&iPm_$)H1_rTltuU1F3I(qTQ^U$S>%$l z)Wx1}R?ij0idp@8w-p!Oz{&*W;v*IA;JFHA9%nUvVDy7Q8woheC#|8QuDZb-L_5@R zOqHwrh|mVL9b=+$nJxM`3eE{O$sCt$UK^2@L$R(r^-_+z?lOo+me-VW=Zw z-Bn>$4ovfWd%SPY`ab-u9{INc*k2h+yH%toDHIyqQ zO68=u`N}RIIs7lsn1D){)~%>ByF<>i@qFb<-axvu(Z+6t7v<^z&gm9McRB~BIaDn$ z#xSGT!rzgad8o>~kyj#h1?7g96tOcCJniQ+*#=b7wPio>|6a1Z?_(TS{)KrPe}(8j z!#&A=k(&Pj^F;r)CI=Z{LVu>uj!_W1q4b`N1}E(i%;BWjbEcnD=mv$FL$l?zS6bW!{$7j1GR5ocn94P2u{ z70tAAcpqtQo<@cXw~@i-@6B23;317|l~S>CB?hR5qJ%J3EFgyBdJd^fHZu7AzHF(BQ!tyAz^L0`X z23S4Fe{2X$W0$zu9gm%rg~A>ijaE#GlYlrF9$ds^QtaszE#4M(OLVP2O-;XdT(XIC zatwzF*)1c+t~c{L=fMG8Z=k5lv>U0;C{caN1NItnuSMp)6G3mbahu>E#sj&oy94KC zpH}8oEw{G@N3pvHhp{^-YaZeH;K+T_1AUv;IKD<=mv^&Ueegrb!yf`4VlRl$M?wsl zZyFol(2|_QM`e_2lYSABpKR{{NlxlDSYQNkS;J66aT#MSiTx~;tUmvs-b*CrR4w=f z8+0;*th6kfZ3|5!Icx3RV11sp=?`0Jy3Fs0N4GZQMN=8HmT6%x9@{Dza)k}UwL6JT zHRDh;%!XwXr6yuuy`4;Xsn0zlR$k%r%9abS1;_v?`HX_hI|+EibVnlyE@3aL5vhQq zlIG?tN^w@0(v9M*&L+{_+RQZw=o|&BRPGB>e5=ys7H`nc8nx)|-g;s7mRc7hg{GJC zAe^vCIJhajmm7C6g! zL&!WAQ~5d_5)00?w_*|*H>3$loHrvFbitw#WvLB!JASO?#5Ig5$Ys10n>e4|3d;tS zELJ0|R4n3Az(Fl3-r^QiV_C;)lQ1_CW{5bKS15U|E9?ZgLec@%kXr84>5jV2a5v=w z?pB1GPdxD$IQL4)G||B_lI+A=08MUFFR4MxfGOu07vfIm+j=z9tp~5i_6jb`tR>qV z$#`=BQ*jpCjm$F0+F)L%xRlnS%#&gro6PiRfu^l!EVan|r3y}AHJQOORGx4~ z&<)3=K-tx518DZyp%|!EqpU!+X3Et7n2AaC5(AtrkW>_57i}$eqs$rupubg0a1+WO zGHZKLN2L0D;ab%{_S1Plm|hx8R?O14*w*f&2&bB050n!R2by zw!@XOQx$SqZ5I<(Qu$V6g>o#A!JVwErWv#(Pjx=KeS0@hxr4?13zj#oWwPS(7Ro|v z>Mp@Kmxo79q|}!5qtX2-O@U&&@6s~!I&)1WQIl?lTnh6UdKT_1R640S4~f=_xoN3- zI+O)$R@RjV$F=>Ti7BlnG1-cFKCC(t|Qjm{SalS~V-tX#+2ekRhwmN zZr`8{QF6y~Z!D|{=1*2D-JUa<(1Z=;!Ei!KiRNH?o{p5o3crFF=_pX9O-YyJchr$~ zRC`+G+8kx~fD2k*ZIiiIGR<8r&M@3H?%JVOfE>)})7ScOd&?OjgAGT@WVNSCZ8N(p zuQG~76GE3%(%h1*vUXg$vH{ua0b`sQ4f0*y=u~lgyb^!#CcPJa2mkSEHGLsnO^kb$ zru5_l#nu=Y{rSMWiYx?nO{8I!gH+?wEj~UM?IrG}E|bRIBUM>UlY<`T1EHpRr36vv zBi&dG8oxS|J$!zoaq{+JpJy+O^W(nt*|#g32bd&K^w-t>!Vu9N!k9eA8r!Xc{utY> zg9aZ(D2E0gL#W0MdjwES-7~Wa8iubPrd?8-$C4BP?*wok&O8+ykOx{P=Izx+G~hM8 z*9?BYz!T8~dzcZr#ux8kS7u7r@A#DogBH8km8Ry4slyie^n|GrTbO|cLhpqgMdsjX zJ_LdmM#I&4LqqsOUIXK8gW;V0B(7^$y#h3h>J0k^WJfAMeYek%Y-Dcb_+0zPJez!GM zAmJ1u;*rK=FNM0Nf}Y!!P9c4)HIkMnq^b;JFd!S3?_Qi2G#LIQ)TF|iHl~WKK6JmK zbv7rPE6VkYr_%_BT}CK8h=?%pk@3cz(UrZ{@h40%XgThP*-Oeo`T0eq9 zA8BnWZKzCy5e&&_GEsU4*;_k}(8l_&al5K-V*BFM=O~;MgRkYsOs%9eOY6s6AtE*<7GQAR2ulC3RAJrG_P1iQK5Z~&B z&f8X<>yJV6)oDGIlS$Y*D^Rj(cszTy5c81a5IwBr`BtnC6_e`ArI8CaTX_%rx7;cn zR-0?J_LFg*?(#n~G8cXut(1nVF0Oka$A$1FGcERU<^ggx;p@CZc?3UB41RY+wLS`LWFNSs~YP zuw1@DNN3lTd|jDL7gjBsd9}wIw}4xT2+8dBQzI00m<@?c2L%>}QLfK5%r!a-iII`p zX@`VEUH)uj^$;7jVUYdADQ2k*!1O3WdfgF?OMtUXNpQ1}QINamBTKDuv19^{$`8A1 zeq%q*O0mi@(%sZU>Xdb0Ru96CFqk9-L3pzLVsMQ`Xpa~N6CR{9Rm2)A|CI21L(%GW zh&)Y$BNHa=FD+=mBw3{qTgw)j0b!Eahs!rZnpu)z!!E$*eXE~##yaXz`KE5(nQM`s zD!$vW9XH)iMxu9R>r$VlLk9oIR%HxpUiW=BK@4U)|1WNQ=mz9a z^!KkO=>GaJ!GBXm{KJj^;kh-MkUlEQ%lza`-G&}C5y1>La1sR6hT=d*NeCnuK%_LV zOXt$}iP6(YJKc9j-Fxq~*ItVUqljQ8?oaysB-EYtFQp9oxZ|5m0^Hq(qV!S+hq#g( z?|i*H2MIr^Kxgz+3vIljQ*Feejy6S4v~jKEPTF~Qhq!(ms5>NGtRgO5vfPPc4Z^AM zTj!`5xEreIN)vaNxa|q6qWdg>+T`Ol0Uz)ckXBXEGvPNEL3R8hB3=C5`@=SYgAju1 z!)UBr{2~=~xa{b8>x2@C7weRAEuatC)3pkRhT#pMPTpSbA|tan%U7NGMvzmF?c!V8 z=pEWxbdXbTAGtWTyI?Fml%lEr-^AE}w#l(<7OIw;ctw}imYax&vR4UYNJZK6P7ZOd zP87XfhnUHxCUHhM@b*NbTi#(-8|wcv%3BGNs#zRCVV(W?1Qj6^PPQa<{yaBwZ`+<`w|;rqUY_C z&AeyKwwf*q#OW-F()lir=T^<^wjK65Lif$puuU5+tk$;e_EJ;Lu+pH>=-8=PDhkBg z8cWt%@$Sc#C6F$Vd+0507;{OOyT7Hs%nKS88q-W!$f~9*WGBpHGgNp}=C*7!RiZ5s zn1L_DbKF@B8kwhDiLKRB@lsXVVLK|ph=w%_`#owlf@s@V(pa`GY$8h%;-#h@TsO|Y8V=n@*!Rog7<7Cid%apR|x zOjhHCyfbIt%+*PCveTEcuiDi%Wx;O;+K=W?OFUV%)%~6;gl?<0%)?snDDqIvkHF{ zyI02)+lI9ov42^hL>ZRrh*HhjF9B$A@=H94iaBESBF=eC_KT$8A@uB^6$~o?3Wm5t1OIaqF^~><2?4e3c&)@wKn9bD? zoeCs;H>b8DL^F&>Xw-xjZEUFFTv>JD^O#1E#)CMBaG4DX9bD(Wtc8Rzq}9soQ8`jf zeSnHOL}<+WVSKp4kkq&?SbETjq6yr@4%SAqOG=9E(3YeLG9dtV+8vmzq+6PFPk{L; z(&d++iu=^F%b+ea$i2UeTC{R*0Isk;vFK!no<;L+(`y`3&H-~VTdKROkdyowo1iqR zbVW(3`+(PQ2>TKY>N!jGmGo7oeoB8O|P_!Ic@ zZ^;3dnuXo;WJ?S+)%P>{Hcg!Jz#2SI(s&dY4QAy_vRlmOh)QHvs_7c&zkJCmJGVvV zX;Mtb>QE+xp`KyciG$Cn*0?AK%-a|=o!+7x&&yzHQOS>8=B*R=niSnta^Pxp1`=md z#;$pS$4WCT?mbiCYU?FcHGZ#)kHVJTTBt^%XE(Q};aaO=Zik0UgLcc0I(tUpt(>|& zcxB_|fxCF7>&~5eJ=Dpn&5Aj{A^cV^^}(7w#p;HG&Q)EaN~~EqrE1qKrMAc&WXIE;>@<&)5;gD2?={Xf@Mvn@OJKw=8Mgn z!JUFMwD+s==JpjhroT&d{$kQAy%+d`a*XxDEVxy3`NHzmITrE`o!;5ClXNPb4t*8P zzAivdr{j_v!=9!^?T3y?gzmqDWX6mkzhIzJ-3S{T5bcCFMr&RPDryMcdwbBuZbsgN zGrp@^i?rcfN7v0NKGzDPGE#4yszxu=I_`MI%Z|10nFjU-UjQXXA?k8Pk|OE<(?ae) zE%vG#eZAlj*E7_3dx#Zz4kMLj>H^;}33UAankJiDy5ZvEhrjr`!9eMD8COp}U*hP+ zF}KIYx@pkccIgyxFm#LNw~G&`;o&5)2`5aogs`1~7cMZQ7zj!%L4E`2yzlQN6REX20&O<9 zKV6fyr)TScJPPzNTC2gL+0x#=u>(({{D7j)c-%tvqls3#Y?Z1m zV5WUE)zdJ{$p>yX;^P!UcXP?UD~YM;IRa#Rs5~l+*$&nO(;Ers`G=0D!twR(0GF@c zHl9E5DQI}Oz74n zfKP>&$q0($T4y$6w(p=ERAFh+>n%iaeRA%!T%<^+pg?M)@ucY<&59$x9M#n+V&>}=nO9wCV{O~lg&v#+jcUj(tQ z`0u1YH)-`U$15a{pBkGyPL0THv1P|4e@pf@3IBZS4dVJPo#H>pWq%Lr0YS-SeWash z8R7=jb28KPMI|_lo#GEO|5B?N_e``H*23{~a!AmUJ+fb4HX-%QI@lSEUxKlGV7z7Q zSKw@-TR>@1RL%w{x}dW#k1NgW+q4yt2Xf1J62Bx*O^WG8OJ|FqI4&@d3_o8Id@*)4 zYrk=>@!wv~mh7YWv*bZhxqSmFh2Xq)o=m;%n$I?GSz49l1$xRpPu_^N(vZ>*>Z<04 z2+rP70oM=NDysd!@fQdM2OcyT?3T^Eb@lIC-UG=Bw{BjQ&P`KCv$AcJ;?`vdZ4){d z&gkoUK{$!$$K`3*O-jyM1~p-7T*qb)Ys>Myt^;#1&a%O@x8A+E>! zY8=eD`ZG)LVagDLBeHg>=atOG?Kr%h4B%E6m@J^C+U|y)XX@f z8oyJDW|9g=<#f<{JRr{y#~euMnv)`7j=%cHWLc}ngjq~7k**6%4u>Px&W%4D94(r* z+akunK}O0DC2A%Xo9jyF;DobX?!1I(7%}@7F>i%&nk*LMO)bMGg2N+1iqtg+r(70q zF5{Msgsm5GS7DT`kBsjMvOrkx&|EU!{{~gL4d2MWrAT=KBQ-^zQCUq{5PD1orxlIL zq;CvlWx#f1NWvh`hg011I%?T_s!e38l*lWVt|~z-PO4~~1g)SrJ|>*tXh=QfXT)%( z+ex+inPvD&O4Ur;JGz>$sUOnWdpSLcm1X%aQDw4{dB!cnj`^muI$CJ2%p&-kULVCE z>$eMR36kN$wCPR+OFDM3-U(VOrp9k3)lI&YVFqd;Kpz~K)@Fa&FRw}L(SoD z9B4a+hQzZT-BnVltst&=kq6Y(f^S4hIGNKYBgMxGJ^;2yrO}P3;r)(-I-CZ)26Y6? z&rzHI_1GCvGkgy-t1E;r^3Le30|%$ebDRu2+gdLG)r=A~Qz`}~&L@aGJ{}vVs_GE* zVUjFnzHiXfKQbpv&bR&}l2bzIjAooB)=-XNcYmrGmBh(&iu@o!^hn0^#}m2yZZUK8 zufVm7Gq0y`Mj;9b>`c?&PZkU0j4>IL=UL&-Lp3j&47B5pAW4JceG{!XCA)kT<%2nqCxj<)uy6XR_uws~>_MEKPOpAQ!H zkn>FKh)<9DwwS*|Y(q?$^N!6(51O0 z^JM~Ax{AI1Oj$fs-S5d4T7Z_i1?{%0SsIuQ&r8#(JA=2iLcTN+?>wOL532%&dMYkT z*T5xepC+V6zxhS@vNbMoi|i)=rpli@R9~P!39tWbSSb904ekv7D#quKbgFEMTb48P zuq(VJ+&L8aWU(_FCD$3^uD!YM%O^K(dvy~Wm2hUuh6bD|#(I39Xt>N1Y{ZqXL`Fg6 zKQ?T2htHN!(Bx;tV2bfTtIj7e)liN-29s1kew>v(D^@)#v;}C4-G=7x#;-dM4yRWm zyY`cS21ulzMK{PoaQ6xChEZ}o_#}X-o}<&0)$1#3we?+QeLt;aVCjeA)hn!}UaKt< zat1fHEx13y-rXNMvpUUmCVzocPmN~-Y4(YJvQ#db)4|%B!rBsgAe+*yor~}FrNH08 z3V!97S}D7d$zbSD{$z;@IYMxM6aHdypIuS*pr_U6;#Y!_?0i|&yU*@16l z*dcMqDQgfNBf}?quiu4e>H)yTVfsp#f+Du0@=Kc41QockXkCkvu>FBd6Q+@FL!(Yx z2`YuX#eMEiLEDhp+9uFqME_E^faV&~9qjBHJkIp~%$x^bN=N)K@kvSVEMdDuzA0sn z88CBG?`RX1@#hQNd`o^V{37)!w|nA)QfiYBE^m=yQKv-fQF+UCMcuEe1d4BH7$?>b zJl-r9@0^Ie=)guO1vOd=i$_4sz>y3x^R7n4ED!5oXL3@5**h(xr%Hv)_gILarO46q+MaDOF%ChaymKoI6JU5Pg;7#2n9-18|S1;AK+ zgsn6;k6-%!QD>D?cFy}8F;r@z8H9xN1jsOBw2vQONVqBVEbkiNUqgw~*!^##ht>w0 zUOykwH=$LwX2j&nLy=@{hr)2O&-wm-NyjW7n~Zs9UlH;P7iP3 zI}S(r0YFVYacnKH(+{*)Tbw)@;6>%=&Th=+Z6NHo_tR|JCI8TJiXv2N7ei7M^Q+RM z?9o`meH$5Yi;@9XaNR#jIK^&{N|DYNNbtdb)XW1Lv2k{E>;?F`#Pq|&_;gm~&~Zc9 zf+6ZE%{x4|{YdtE?a^gKyzr}dA>OxQv+pq|@IXL%WS0CiX!V zm$fCePA%lU{%pTKD7|5NJHeXg=I0jL@$tOF@K*MI$)f?om)D63K*M|r`gb9edD1~Y zc|w7N)Y%do7=0{RC|AziW7#am$)9jciRJ?IWl9PE{G3U+$%FcyKs_0Cgq`=K3@ttV z9g;M!3z~f_?P%y3-ph%vBMeS@p7P&Ea8M@97+%XEj*(1E6vHj==d zjsoviB>j^$_^OI_DEPvFkVo(BGRo%cJeD){6Uckei=~1}>sp299|IRjhXe)%?uP0I zF5+>?0#Ye}T^Y$u_rc4=lPcq4K^D(TZG-w30-YiEM=dcK+4#o*>lJ8&JLi+3UcpZk z!^?95S^C0ja^jwP`|{<+3cBVog$(mRdQmadS+Vh~z zS@|P}=|z3P6uS+&@QsMp0no9Od&27O&14zHXGAOEy zh~OKpymK5C%;LLb467@KgIiVwYbYd6wFxI{0-~MOGfTq$nBTB!{SrWmL9Hs}C&l&l#m?s*{tA?BHS4mVKHAVMqm63H<|c5n0~k)-kbg zXidai&9ZUy0~WFYYKT;oe~rytRk?)r8bptITsWj(@HLI;@=v5|XUnSls7$uaxFRL+ zRVMGuL3w}NbV1`^=Pw*0?>bm8+xfeY(1PikW*PB>>Tq(FR`91N0c2&>lL2sZo5=VD zQY{>7dh_TX98L2)n{2OV=T10~*YzX27i2Q7W86M4$?gZIXZaBq#sA*{PH8){|GUi;oM>e?ua7eF4WFuFYZSG| zze?srg|5Ti8Og{O zeFxuw9!U+zhyk?@w zjsA6(oKD=Ka;A>Ca)oPORxK+kxH#O@zhC!!XS4@=swnuMk>t+JmLmFiE^1aX3f<)D@`%K0FGK^gg1a1j>zi z2KhV>sjU7AX3F$SEqrXSC}fRx64GDoc%!u2Yag68Lw@w9v;xOONf@o)Lc|Uh3<21ctTYu-mFZuHk*+R{GjXHIGq3p)tFtQp%TYqD=j1&y)>@zxoxUJ!G@ zgI0XKmP6MNzw>nRxK$-Gbzs}dyfFzt>#5;f6oR27ql!%+{tr+(`(>%51|k`ML} zY4eE)Lxq|JMas(;JibNQds1bUB&r}ydMQXBY4x(^&fY_&LlQC)3hylc$~8&~|06-D z#T+%66rYbHX%^KuqJED_wuGB+=h`nWA!>1n0)3wZrBG3%`b^Ozv6__dNa@%V14|!D zQ?o$z5u0^8`giv%qE!BzZ!3j;BlDlJDk)h@9{nSQeEk!z9RGW) z${RSF3phEM*ce*>Xdp}585vj$|40=&S{S-GTiE?Op*vY&Lvr9}BO$XWy80IF+6@%n z5*2ueT_g@ofP#u5pxb7n*fv^Xtt7&?SRc{*2Ka-*!BuOpf}neHGCiHy$@Ka1^Dint z;DkmIL$-e)rj4o2WQV%Gy;Xg(_Bh#qeOsTM2f@KEe~4kJ8kNLQ+;(!j^bgJMcNhvklP5Z6I+9Fq@c&D~8Fb-4rmDT!MB5QC{Dsb;BharP*O;SF4& zc$wj-7Oep7#$WZN!1nznc@Vb<_Dn%ga-O#J(l=OGB`dy=Sy&$(5-n3zzu%d7E#^8`T@}V+5B;PP8J14#4cCPw-SQTdGa2gWL0*zKM z#DfSXs_iWOMt)0*+Y>Lkd=LlyoHjublNLefhKBv@JoC>P7N1_#> zv=mLWe96%EY;!ZGSQDbZWb#;tzqAGgx~uk+-$+2_8U`!ypbwXl z^2E-FkM1?lY@yt8=J3%QK+xaZ6ok=-y%=KXCD^0r!5vUneW>95PzCkOPO*t}p$;-> ze5j-BLT_;)cZQzR2CEsm@rU7GZfFtdp*a|g4wDr%8?2QkIGasRfDWT-Dvy*U{?IHT z*}wGnzdlSptl#ZF^sf)KT|BJs&kLG91^A6ls{CzFprZ6-Y!V0Xysh%9p%iMd7HLsS zN+^Un$tDV)T@i!v?3o0Fsx2qI(AX_$dDkBzQ@fRM%n zRXk6hb9Py#JXUs+7)w@eo;g%QQ95Yq!K_d=z{0dGS+pToEI6=Bo8+{k$7&Z zo4>PH(`ce8E-Ps&uv`NQ;U$%t;w~|@E3WVOCi~R4oj5wP?%<*1C%}Jq%a^q~T7u>K zML5AKfQDv6>PuT`{SrKHRAF+^&edg6+5R_#H?Lz3iGoWo#PCEd0DS;)2U({{X#zU^ zw_xv{4x7|t!S)>44J;KfA|DC?;uQ($l+5Vp7oeqf7{GBF9356nx|&B~gs+@N^gSdd zvb*>&W)|u#F{Z_b`f#GVtQ`pYv3#||N{xj1NgB<#=Odt6{eB%#9RLt5v zIi|0u70`#ai}9fJjKv7dE!9ZrOIX!3{$z_K5FBd-Kp-&e4(J$LD-)NMTp^_pB`RT; zftVVlK2g@+1Ahv2$D){@Y#cL#dUj9*&%#6 zd2m9{1NYp>)6=oAvqdCn5#cx{AJ%S8skUgMglu2*IAtd+z1>B&`MuEAS(D(<6X#Lj z?f4CFx$)M&$=7*>9v1ER4b6!SIz-m0e{o0BfkySREchp?WdVPpQCh!q$t>?rL!&Jg zd#heM;&~A}VEm8Dvy&P|J*eAV&w!&Nx6HFV&B8jJFVTmgLaswn!cx$&%JbTsloz!3 zMEz1d`k==`Ueub_JAy_&`!ogbwx27^ZXgFNAbx=g_I~5nO^r)}&myw~+yY*cJl4$I znNJ32M&K=0(2Dj_>@39`3=FX!v3nZHno_@q^!y}%(yw0PqOo=);6Y@&ylVe>nMOZ~ zd>j#QQSBn3oaWd;qy$&5(5H$Ayi)0haAYO6TH>FR?rhqHmNOO+(})NB zLI@B@v0)eq!ug`>G<@htRlp3n!EpU|n+G+AvXFrWSUsLMBfL*ZB`CRsIVHNTR&b?K zxBgsN0BjfB>UVcJ|x%=-zb%OV7lmZc& zxiupadZVF7)6QuhoY;;FK2b*qL0J-Rn-8!X4ZY$-ZSUXV5DFd7`T41c(#lAeLMoeT z4%g655v@7AqT!i@)Edt5JMbN(=Q-6{=L4iG8RA%}w;&pKmtWvI4?G9pVRp|RTw`g0 zD5c12B&A2&P6Ng~8WM2eIW=wxd?r7A*N+&!Be7PX3s|7~z=APxm=A?5 zt>xB4WG|*Td@VX{Rs)PV0|yK`oI3^xn(4c_j&vgxk_Y3o(-`_5o`V zRTghg6%l@(qodXN;dB#+OKJEEvhfcnc#BeO2|E(5df-!fKDZ!%9!^BJ_4)9P+9Dq5 zK1=(v?KmIp34r?z{NEWnLB3Px{XYwy-akun4F7xTRr2^zeYW{gcK9)>aJDdU5;w5@ zak=<+-PLH-|04pelTb%ULpuuuJC7DgyT@D|p{!V!0v3KpDnRjANN12q6SUR3mb9<- z>2r~IApQGhstZ!3*?5V z8#)hJ0TdZg0M-BK#nGFP>$i=qk82DO z7h;Ft!D5E15OgW)&%lej*?^1~2=*Z5$2VX>V{x8SC+{i10BbtUk9@I#Vi&hX)q

Q!LwySI{Bnv%Sm)yh{^sSVJ8&h_D-BJ_YZe5eCaAWU9b$O2c z$T|{vWVRtOL!xC0DTc(Qbe`ItNtt5hr<)VijD0{U;T#bUEp381_y`%ZIav?kuYG{iyYdEBPW=*xNSc;Rlt6~F4M`5G+VtOjc z*0qGzCb@gME5udTjJA-9O<&TWd~}ysBd(eVT1-H82-doyH9RST)|+Pb{o*;$j9Tjs zhU!IlsPsj8=(x3bAKJTopW3^6AKROHR^7wZ185wJGVhA~hEc|LP;k7NEz-@4p5o}F z`AD6naG3(n=NF9HTH81=F+Q|JOz$7wm9I<+#BSmB@o_cLt2GkW9|?7mM;r!JZp89l zbo!Hp8=n!XH1{GwaDU+k)pGp`C|cXkCU5%vcH)+v@0eK>%7gWxmuMu9YLlChA|_D@ zi#5zovN_!a-0?~pUV-Rj*1P)KwdU-LguR>YM&*Nen+ln8Q$?WFCJg%DY%K}2!!1FE zDv-A%Cbwo^p(lzac&_TZ-l#9kq`mhLcY3h9ZTUVCM(Ad&=EriQY5{jJv<5K&g|*Lk zgV%ILnf1%8V2B0E&;Sp4sYbYOvvMebLwYwzkRQ#F8GpTQq#uv=J`uaSJ34OWITeSGo6+-8Xw znCk*n{kdDEi)Hi&u^)~cs@iyCkFWB2SWZU|Uc%^43ZIZQ-vWNExCCtDWjqHs;;tWf$v{}0{p0Rvxkq``)*>+Akq%|Na zA`@~-Vfe|+(AIlqru+7Ceh4nsVmO9p9jc8}HX^W&ViBDXT+uXbT#R#idPn&L>+#b6 zflC-4C5-X;kUnR~L>PSLh*gvL68}RBsu#2l`s_9KjUWRhiqF`j)`y`2`YU(>3bdBj z?>iyjEhe-~$^I5!nn%B6Wh+I`FvLNvauve~eX<+Ipl&04 zT}};W&1a3%W?dJ2=N#0t?e+aK+%t}5q%jSLvp3jZ%?&F}nOOWr>+{GFIa%wO_2`et z=JzoRR~}iKuuR+azPI8;Gf9)z3kyA4EIOSl!sRR$DlW}0>&?GbgPojmjmnln;cTqCt=ADbE zZ8GAnoM+S1(5$i8^O4t`ue;vO4i}z0wz-QEIVe5_u03;}-!G1NyY8;h^}y;tzY}i5 zqQr#Ur3Fy8sSa$Q0ys+f`!`+>9WbvU_I`Sj;$4{S>O3?#inLHCrtLy~!s#WXV=oVP zeE93*Nc`PBi4q@%Ao$x4lw9vLHM!6mn3-b_cebF|n-2vt-zYVF_&sDE--J-P;2WHo z+@n2areE0o$LjvjlV2X7ZU@j+`{*8zq`JR3gKF#EW|#+{nMyo-a>nFFTg&vhyT=b} zDa8+v0(Dgx0yRL@ZXOYIlVSZ0|MFizy0VPW8;AfA5|pe!#j zX}Py^8fl5SyS4g1WSKKtnyP+_PoOwMMwu`(i@Z)diJp~U54*-miOchy7Z35eL>^M z4p<-aIxH4VUZgS783@H%M7P9hX>t{|RU7$n4T(brCG#h9e9p! z+o`i;EGGq3&pF;~5V~eBD}lC)>if$w%Vf}AFxGqO88|ApfHf&Bvu+xdG)@vuF}Yvk z)o;~k-%+0K0g+L`Wala!$=ZV|z$e%>f0%XoLib%)!R^RoS+{!#X?h-6uu zF&&KxORdZU&EwQFITIRLo(7TA3W}y6X{?Y%y2j0It!ekU#<)$qghZtpcS>L3uh`Uj z7GY;6f$9qKynP#oS3$$a{p^{D+0oJQ71`1?OAn_m8)UGZmj3l*ZI)`V-a>MKGGFG< z&^jg#Ok%(hhm>hSrZ5;Qga4u(?^i>GiW_j9%_7M>j(^|Om$#{k+^*ULnEgzW_1gCICtAD^WpC`A z{9&DXkG#01Xo)U$OC(L5Y$DQ|Q4C6CjUKk1UkPj$nXH##J{c8e#K|&{mA*;b$r0E4 zUNo0jthwA(c&N1l=PEe8Rw_8cEl|-eya9z&H3#n`B$t#+aJ03RFMzrV@gowbe8v(c zIFM60^0&lCFO10NU4w@|61xiZ4CVXeaKjd;d?sv52XM*lS8XiVjgWpRB;&U_C0g+`6B5V&w|O6B*_q zsATxL!M}+$He)1eOWECce#eS@2n^xhlB4<_Nn?yCVEQWDs(r`|@2GqLe<#(|&P0U? z$7V5IgpWf09uIf_RazRwC?qEqRaHyL?iiS05UiGesJy%^>-C{{ypTBI&B0-iUYhk> zIk<5xpsuV@g|z(AZD+C-;A!fTG=df1=<%nxy(a(IS+U{ME4ZbDEBtcD_3V=icT6*_ z)>|J?>&6%nvHhZERBtjK+s4xnut*@>GAmA5m*OTp$!^CHTr}vM4n(X1Q*;{e-Rd2BCF-u@1ZGm z!S8hJ6L=Gl4T_SDa7Xx|-{4mxveJg=ctf`BJ*fy!yF6Dz&?w(Q_6B}WQVtNI!BVBC zKfX<>7vd6C96}XAQmF-Jd?1Q4eTfRB3q7hCh0f!(JkdWT5<{iAE#dKy*Jxq&3a1@~ z8C||Dn2mFNyrUV|<-)C^_y7@8c2Fz+2jrae9deBDu;U}tJ{^xAdxCD248(k;dCJ%o z`y3sADe>U%suxwwv~8A1+R$VB=Q?%U?4joI$um;aH+eCrBqpn- z%79D_7rb;R-;-9RTrwi9dPlg8&@tfWhhZ(Vx&1PQ+6(huX`;M9x~LrW~~#3{j0Bh2kDU$}@!fFQej4VGkJv?M4rU^x!RU zEwhu$!CA_iDjFjrJa`aocySDX16?~;+wgav;}Zut6Mg%C4>}8FL?8)Kgwc(Qlj{@#2Pt0?G`$h7P#M+qoXtlV@d}%c&OzO+QYKK`kyXaK{U(O^2DyIXCZlNQjt0^8~8JzNGrIxhj}}M z&~QZlbx%t;MJ(Vux;2tgNKGlAqphLq%pd}JG9uoVHUo?|hN{pLQ6Em%r*+7t^<);X zm~6=qChlNAVXNN*Sow->*4;}T;l;D1I-5T{Bif@4_}=>l`tK;qqDdt5zvisCKhMAH z#r}`)7VW?LZqfdmXQ%zo5bJ00{Xb9^YKrk0Nf|oIW*K@(=`o2Vndz}ZDyk{!u}PVx zzd--+_WC*U{~DH3{?GI64IB+@On&@9X>EUAo&L+G{L^dozaI4C3G#2wr~hseW@K&g zKWs{uHu-9Je!3;4pE>eBltKUXb^*hG8I&413)$J&{D4N%7PcloU6bn%jPxJyQL?g* z9g+YFFEDiE`8rW^laCNzQmi7CTnPfwyg3VDHRAl>h=In6jeaVOP@!-CP60j3+#vpL zEYmh_oP0{-gTe7Or`L6x)6w?77QVi~jD8lWN@3RHcm80iV%M1A!+Y6iHM)05iC64tb$X2lV_%Txk@0l^hZqi^%Z?#- zE;LE0uFx)R08_S-#(wC=dS&}vj6P4>5ZWjhthP=*Hht&TdLtKDR;rXEX4*z0h74FA zMCINqrh3Vq;s%3MC1YL`{WjIAPkVL#3rj^9Pj9Ss7>7duy!9H0vYF%>1jh)EPqvlr6h%R%CxDsk| z!BACz7E%j?bm=pH6Eaw{+suniuY7C9Ut~1cWfOX9KW9=H><&kQlinPV3h9R>3nJvK z4L9(DRM=x;R&d#a@oFY7mB|m8h4692U5eYfcw|QKwqRsshN(q^v$4$)HgPpAJDJ`I zkqjq(8Cd!K!+wCd=d@w%~e$=gdUgD&wj$LQ1r>-E=O@c ze+Z$x{>6(JA-fNVr)X;*)40Eym1TtUZI1Pwwx1hUi+G1Jlk~vCYeXMNYtr)1?qwyg zsX_e*$h?380O00ou?0R@7-Fc59o$UvyVs4cUbujHUA>sH!}L54>`e` zHUx#Q+Hn&Og#YVOuo*niy*GU3rH;%f``nk#NN5-xrZ34NeH$l`4@t);4(+0|Z#I>Y z)~Kzs#exIAaf--65L0UHT_SvV8O2WYeD>Mq^Y6L!Xu8%vnpofG@w!}R7M28?i1*T&zp3X4^OMCY6(Dg<-! zXmcGQrRgHXGYre7GfTJ)rhl|rs%abKT_Nt24_Q``XH{88NVPW+`x4ZdrMuO0iZ0g` z%p}y};~T5gbb9SeL8BSc`SO#ixC$@QhXxZ=B}L`tP}&k?1oSPS=4%{UOHe0<_XWln zwbl5cn(j-qK`)vGHY5B5C|QZd5)W7c@{bNVXqJ!!n$^ufc?N9C-BF2QK1(kv++h!>$QbAjq)_b$$PcJdV+F7hz0Hu@ zqj+}m0qn{t^tD3DfBb~0B36|Q`bs*xs|$i^G4uNUEBl4g;op-;Wl~iThgga?+dL7s zUP(8lMO?g{GcYpDS{NM!UA8Hco?#}eNEioRBHy4`mq!Pd-9@-97|k$hpEX>xoX+dY zDr$wfm^P&}Wu{!%?)U_(%Mn79$(ywvu*kJ9r4u|MyYLI_67U7%6Gd_vb##Nerf@>& z8W11z$$~xEZt$dPG}+*IZky+os5Ju2eRi;1=rUEeIn>t-AzC_IGM-IXWK3^6QNU+2pe=MBn4I*R@A%-iLDCOHTE-O^wo$sL_h{dcPl=^muAQb`_BRm};=cy{qSkui;`WSsj9%c^+bIDQ z0`_?KX0<-=o!t{u(Ln)v>%VGL z0pC=GB7*AQ?N7N{ut*a%MH-tdtNmNC+Yf$|KS)BW(gQJ*z$d{+{j?(e&hgTy^2|AR9vx1Xre2fagGv0YXWqtNkg*v%40v?BJBt|f9wX5 z{QTlCM}b-0{mV?IG>TW_BdviUKhtosrBqdfq&Frdz>cF~yK{P@(w{Vr7z2qKFwLhc zQuogKO@~YwyS9%+d-zD7mJG~@?EFJLSn!a&mhE5$_4xBl&6QHMzL?CdzEnC~C3$X@ zvY!{_GR06ep5;<#cKCSJ%srxX=+pn?ywDwtJ2{TV;0DKBO2t++B(tIO4)Wh`rD13P z4fE$#%zkd=UzOB74gi=-*CuID&Z3zI^-`4U^S?dHxK8fP*;fE|a(KYMgMUo`THIS1f!*6dOI2 zFjC3O=-AL`6=9pp;`CYPTdVX z8(*?V&%QoipuH0>WKlL8A*zTKckD!paN@~hh zmXzm~qZhMGVdQGd=AG8&20HW0RGV8X{$9LldFZYm zE?}`Q3i?xJRz43S?VFMmqRyvWaS#(~Lempg9nTM$EFDP(Gzx#$r)W&lpFKqcAoJh-AxEw$-bjW>`_+gEi z2w`99#UbFZGiQjS8kj~@PGqpsPX`T{YOj`CaEqTFag;$jY z8_{Wzz>HXx&G*Dx<5skhpETxIdhKH?DtY@b9l8$l?UkM#J-Snmts7bd7xayKTFJ(u zyAT&@6cAYcs{PBfpqZa%sxhJ5nSZBPji?Zlf&}#L?t)vC4X5VLp%~fz2Sx<*oN<7` z?ge=k<=X7r<~F7Tvp9#HB{!mA!QWBOf%EiSJ6KIF8QZNjg&x~-%e*tflL(ji_S^sO ztmib1rp09uon}RcsFi#k)oLs@$?vs(i>5k3YN%$T(5Or(TZ5JW9mA6mIMD08=749$ z!d+l*iu{Il7^Yu}H;lgw=En1sJpCKPSqTCHy4(f&NPelr31^*l%KHq^QE>z>Ks_bH zjbD?({~8Din7IvZeJ>8Ey=e;I?thpzD=zE5UHeO|neioJwG;IyLk?xOz(yO&0DTU~ z^#)xcs|s>Flgmp;SmYJ4g(|HMu3v7#;c*Aa8iF#UZo7CvDq4>8#qLJ|YdZ!AsH%^_7N1IQjCro

K7UpUK$>l@ zw`1S}(D?mUXu_C{wupRS-jiX~w=Uqqhf|Vb3Cm9L=T+w91Cu^ z*&Ty%sN?x*h~mJc4g~k{xD4ZmF%FXZNC;oVDwLZ_WvrnzY|{v8hc1nmx4^}Z;yriXsAf+Lp+OFLbR!&Ox?xABwl zu8w&|5pCxmu#$?Cv2_-Vghl2LZ6m7}VLEfR5o2Ou$x02uA-%QB2$c(c1rH3R9hesc zfpn#oqpbKuVsdfV#cv@5pV4^f_!WS+F>SV6N0JQ9E!T90EX((_{bSSFv9ld%I0&}9 zH&Jd4MEX1e0iqDtq~h?DBrxQX1iI0lIs<|kB$Yrh&cpeK0-^K%=FBsCBT46@h#yi!AyDq1V(#V}^;{{V*@T4WJ&U-NTq43w=|K>z8%pr_nC>%C(Wa_l78Ufib$r8Od)IIN=u>417 z`Hl{9A$mI5A(;+-Q&$F&h-@;NR>Z<2U;Y21>>Z;s@0V@SbkMQQj%_;~+qTuQ?c|AV zcWm3XZQHhP&R%QWarS%mJ!9R^&!_)*s(v+VR@I#QrAT}`17Y+l<`b-nvmDNW`De%y zrwTZ9EJrj1AFA>B`1jYDow}~*dfPs}IZMO3=a{Fy#IOILc8F0;JS4x(k-NSpbN@qM z`@aE_e}5{!$v3+qVs7u?sOV(y@1Os*Fgu`fCW9=G@F_#VQ%xf$hj0~wnnP0$hFI+@ zkQj~v#V>xn)u??YutKsX>pxKCl^p!C-o?+9;!Nug^ z{rP!|+KsP5%uF;ZCa5F;O^9TGac=M|=V z_H(PfkV1rz4jl?gJ(ArXMyWT4y(86d3`$iI4^l9`vLdZkzpznSd5Ikfrs8qcSy&>z zTIZgWZGXw0n9ibQxYWE@gI0(3#KA-dAdPcsL_|hg2@~C!VZDM}5;v_Nykfq!*@*Zf zE_wVgx82GMDryKO{U{D>vSzSc%B~|cjDQrt5BN=Ugpsf8H8f1lR4SGo#hCuXPL;QQ z#~b?C4MoepT3X`qdW2dNn& zo8)K}%Lpu>0tQei+{>*VGErz|qjbK#9 zvtd8rcHplw%YyQCKR{kyo6fgg!)6tHUYT(L>B7er5)41iG`j$qe*kSh$fY!PehLcD zWeKZHn<492B34*JUQh=CY1R~jT9Jt=k=jCU2=SL&&y5QI2uAG2?L8qd2U(^AW#{(x zThSy=C#>k+QMo^7caQcpU?Qn}j-`s?1vXuzG#j8(A+RUAY})F@=r&F(8nI&HspAy4 z4>(M>hI9c7?DCW8rw6|23?qQMSq?*Vx?v30U%luBo)B-k2mkL)Ljk5xUha3pK>EEj z@(;tH|M@xkuN?gsz;*bygizwYR!6=(Xgcg^>WlGtRYCozY<rFX2E>kaZo)O<^J7a`MX8Pf`gBd4vrtD|qKn&B)C&wp0O-x*@-|m*0egT=-t@%dD zgP2D+#WPptnc;_ugD6%zN}Z+X4=c61XNLb7L1gWd8;NHrBXwJ7s0ce#lWnnFUMTR& z1_R9Fin4!d17d4jpKcfh?MKRxxQk$@)*hradH2$3)nyXep5Z;B z?yX+-Bd=TqO2!11?MDtG0n(*T^!CIiF@ZQymqq1wPM_X$Iu9-P=^}v7npvvPBu!d$ z7K?@CsA8H38+zjA@{;{kG)#AHME>Ix<711_iQ@WWMObXyVO)a&^qE1GqpP47Q|_AG zP`(AD&r!V^MXQ^e+*n5~Lp9!B+#y3#f8J^5!iC@3Y@P`;FoUH{G*pj*q7MVV)29+j z>BC`a|1@U_v%%o9VH_HsSnM`jZ-&CDvbiqDg)tQEnV>b%Ptm)T|1?TrpIl)Y$LnG_ zzKi5j2Fx^K^PG1=*?GhK;$(UCF-tM~^=Z*+Wp{FSuy7iHt9#4n(sUuHK??@v+6*|10Csdnyg9hAsC5_OrSL;jVkLlf zHXIPukLqbhs~-*oa^gqgvtpgTk_7GypwH><53riYYL*M=Q@F-yEPLqQ&1Sc zZB%w}T~RO|#jFjMWcKMZccxm-SL)s_ig?OC?y_~gLFj{n8D$J_Kw%{r0oB8?@dWzn zB528d-wUBQzrrSSLq?fR!K%59Zv9J4yCQhhDGwhptpA5O5U?Hjqt>8nOD zi{)0CI|&Gu%zunGI*XFZh(ix)q${jT8wnnzbBMPYVJc4HX*9d^mz|21$=R$J$(y7V zo0dxdbX3N#=F$zjstTf*t8vL)2*{XH!+<2IJ1VVFa67|{?LP&P41h$2i2;?N~RA30LV`BsUcj zfO9#Pg1$t}7zpv#&)8`mis3~o+P(DxOMgz-V*(?wWaxi?R=NhtW}<#^Z?(BhSwyar zG|A#Q7wh4OfK<|DAcl9THc-W4*>J4nTevsD%dkj`U~wSUCh15?_N@uMdF^Kw+{agk zJ`im^wDqj`Ev)W3k3stasP`88-M0ZBs7;B6{-tSm3>I@_e-QfT?7|n0D~0RRqDb^G zyHb=is;IwuQ&ITzL4KsP@Z`b$d%B0Wuhioo1CWttW8yhsER1ZUZzA{F*K=wmi-sb#Ju+j z-l@In^IKnb{bQG}Ps>+Vu_W#grNKNGto+yjA)?>0?~X`4I3T@5G1)RqGUZuP^NJCq&^HykuYtMDD8qq+l8RcZNJsvN(10{ zQ1$XcGt}QH-U^WU!-wRR1d--{B$%vY{JLWIV%P4-KQuxxDeJaF#{eu&&r!3Qu{w}0f--8^H|KwE>)ORrcR+2Qf zb})DRcH>k0zWK8@{RX}NYvTF;E~phK{+F;MkIP$)T$93Ba2R2TvKc>`D??#mv9wg$ zd~|-`Qx5LwwsZ2hb*Rt4S9dsF%Cny5<1fscy~)d;0m2r$f=83<->c~!GNyb!U)PA; zq^!`@@)UaG)Ew(9V?5ZBq#c%dCWZrplmuM`o~TyHjAIMh0*#1{B>K4po-dx$Tk-Cq z=WZDkP5x2W&Os`N8KiYHRH#UY*n|nvd(U>yO=MFI-2BEp?x@=N<~CbLJBf6P)}vLS?xJXYJ2^<3KJUdrwKnJnTp{ zjIi|R=L7rn9b*D#Xxr4*R<3T5AuOS+#U8hNlfo&^9JO{VbH!v9^JbK=TCGR-5EWR@ zN8T-_I|&@A}(hKeL4_*eb!1G8p~&_Im8|wc>Cdir+gg90n1dw?QaXcx6Op_W1r=axRw>4;rM*UOpT#Eb9xU1IiWo@h?|5uP zka>-XW0Ikp@dIe;MN8B01a7+5V@h3WN{J=HJ*pe0uwQ3S&MyWFni47X32Q7SyCTNQ z+sR!_9IZa5!>f&V$`q!%H8ci!a|RMx5}5MA_kr+bhtQy{-^)(hCVa@I!^TV4RBi zAFa!Nsi3y37I5EK;0cqu|9MRj<^r&h1lF}u0KpKQD^5Y+LvFEwM zLU@@v4_Na#Axy6tn3P%sD^5P#<7F;sd$f4a7LBMk zGU^RZHBcxSA%kCx*eH&wgA?Qwazm8>9SCSz_!;MqY-QX<1@p$*T8lc?@`ikEqJ>#w zcG``^CoFMAhdEXT9qt47g0IZkaU)4R7wkGs^Ax}usqJ5HfDYAV$!=6?>J6+Ha1I<5 z|6=9soU4>E))tW$<#>F ziZ$6>KJf0bPfbx_)7-}tMINlc=}|H+$uX)mhC6-Hz+XZxsKd^b?RFB6et}O#+>Wmw9Ec9) z{q}XFWp{3@qmyK*Jvzpyqv57LIR;hPXKsrh{G?&dRjF%Zt5&m20Ll?OyfUYC3WRn{cgQ?^V~UAv+5 z&_m#&nIwffgX1*Z2#5^Kl4DbE#NrD&Hi4|7SPqZ}(>_+JMz=s|k77aEL}<=0Zfb)a z%F(*L3zCA<=xO)2U3B|pcTqDbBoFp>QyAEU(jMu8(jLA61-H!ucI804+B!$E^cQQa z)_ERrW3g!B9iLb3nn3dlkvD7KsY?sRvls3QC0qPi>o<)GHx%4Xb$5a3GBTJ(k@`e@ z$RUa^%S15^1oLEmA=sayrP5;9qtf!Z1*?e$ORVPsXpL{jL<6E)0sj&swP3}NPmR%FM?O>SQgN5XfHE< zo(4#Cv11(%Nnw_{_Ro}r6=gKd{k?NebJ~<~Kv0r(r0qe4n3LFx$5%x(BKvrz$m?LG zjLIc;hbj0FMdb9aH9Lpsof#yG$(0sG2%RL;d(n>;#jb!R_+dad+K;Ccw!|RY?uS(a zj~?=&M!4C(5LnlH6k%aYvz@7?xRa^2gml%vn&eKl$R_lJ+e|xsNfXzr#xuh(>`}9g zLHSyiFwK^-p!;p$yt7$F|3*IfO3Mlu9e>Dpx8O`37?fA`cj`C0B-m9uRhJjs^mRp# zWB;Aj6|G^1V6`jg7#7V9UFvnB4((nIwG?k%c7h`?0tS8J3Bn0t#pb#SA}N-|45$-j z$R>%7cc2ebAClXc(&0UtHX<>pd)akR3Kx_cK+n<}FhzmTx!8e9^u2e4%x{>T6pQ`6 zO182bh$-W5A3^wos0SV_TgPmF4WUP-+D25KjbC{y_6W_9I2_vNKwU(^qSdn&>^=*t z&uvp*@c8#2*paD!ZMCi3;K{Na;I4Q35zw$YrW5U@Kk~)&rw;G?d7Q&c9|x<Hg|CNMsxovmfth*|E*GHezPTWa^Hd^F4!B3sF;)? z(NaPyAhocu1jUe(!5Cy|dh|W2=!@fNmuNOzxi^tE_jAtzNJ0JR-avc_H|ve#KO}#S z#a(8secu|^Tx553d4r@3#6^MHbH)vmiBpn0X^29xEv!Vuh1n(Sr5I0V&`jA2;WS|Y zbf0e}X|)wA-Pf5gBZ>r4YX3Mav1kKY(ulAJ0Q*jB)YhviHK)w!TJsi3^dMa$L@^{` z_De`fF4;M87vM3Ph9SzCoCi$#Fsd38u!^0#*sPful^p5oI(xGU?yeYjn;Hq1!wzFk zG&2w}W3`AX4bxoVm03y>ts{KaDf!}b&7$(P4KAMP=vK5?1In^-YYNtx1f#}+2QK@h zeSeAI@E6Z8a?)>sZ`fbq9_snl6LCu6g>o)rO;ijp3|$vig+4t} zylEo7$SEW<_U+qgVcaVhk+4k+C9THI5V10qV*dOV6pPtAI$)QN{!JRBKh-D zk2^{j@bZ}yqW?<#VVuI_27*cI-V~sJiqQv&m07+10XF+#ZnIJdr8t`9s_EE;T2V;B z4UnQUH9EdX%zwh-5&wflY#ve!IWt0UE-My3?L#^Bh%kcgP1q{&26eXLn zTkjJ*w+(|_>Pq0v8{%nX$QZbf)tbJaLY$03;MO=Ic-uqYUmUCuXD>J>o6BCRF=xa% z3R4SK9#t1!K4I_d>tZgE>&+kZ?Q}1qo4&h%U$GfY058s%*=!kac{0Z+4Hwm!)pFLR zJ+5*OpgWUrm0FPI2ib4NPJ+Sk07j(`diti^i#kh&f}i>P4~|d?RFb#!JN)~D@)beox}bw?4VCf^y*`2{4`-@%SFTry2h z>9VBc9#JxEs1+0i2^LR@B1J`B9Ac=#FW=(?2;5;#U$0E0UNag_!jY$&2diQk_n)bT zl5Me_SUvqUjwCqmVcyb`igygB_4YUB*m$h5oeKv3uIF0sk}~es!{D>4r%PC*F~FN3owq5e0|YeUTSG#Vq%&Gk7uwW z0lDo#_wvflqHeRm*}l?}o;EILszBt|EW*zNPmq#?4A+&i0xx^?9obLyY4xx=Y9&^G;xYXYPxG)DOpPg!i_Ccl#3L}6xAAZzNhPK1XaC_~ z!A|mlo?Be*8Nn=a+FhgpOj@G7yYs(Qk(8&|h@_>w8Y^r&5nCqe0V60rRz?b5%J;GYeBqSAjo|K692GxD4` zRZyM2FdI+-jK2}WAZTZ()w_)V{n5tEb@>+JYluDozCb$fA4H)$bzg(Ux{*hXurjO^ zwAxc+UXu=&JV*E59}h3kzQPG4M)X8E*}#_&}w*KEgtX)cU{vm9b$atHa;s>| z+L6&cn8xUL*OSjx4YGjf6{Eq+Q3{!ZyhrL&^6Vz@jGbI%cAM9GkmFlamTbcQGvOlL zmJ?(FI)c86=JEs|*;?h~o)88>12nXlpMR4@yh%qdwFNpct;vMlc=;{FSo*apJ;p}! zAX~t;3tb~VuP|ZW;z$=IHf->F@Ml)&-&Bnb{iQyE#;GZ@C$PzEf6~q}4D>9jic@mTO5x76ulDz@+XAcm35!VSu zT*Gs>;f0b2TNpjU_BjHZ&S6Sqk6V1370+!eppV2H+FY!q*n=GHQ!9Rn6MjY!Jc77A zG7Y!lFp8?TIHN!LXO?gCnsYM-gQxsm=Ek**VmZu7vnuufD7K~GIxfxbsQ@qv2T zPa`tvHB$fFCyZl>3oYg?_wW)C>^_iDOc^B7klnTOoytQH18WkOk)L2BSD0r%xgRSW zQS9elF^?O=_@|58zKLK;(f77l-Zzu}4{fXed2saq!5k#UZAoDBqYQS{sn@j@Vtp|$ zG%gnZ$U|9@u#w1@11Sjl8ze^Co=)7yS(}=;68a3~g;NDe_X^}yJj;~s8xq9ahQ5_r zxAlTMnep*)w1e(TG%tWsjo3RR;yVGPEO4V{Zp?=a_0R#=V^ioQu4YL=BO4r0$$XTX zZfnw#_$V}sDAIDrezGQ+h?q24St0QNug_?{s-pI(^jg`#JRxM1YBV;a@@JQvH8*>> zIJvku74E0NlXkYe_624>znU0J@L<-c=G#F3k4A_)*;ky!C(^uZfj%WB3-*{*B$?9+ zDm$WFp=0(xnt6`vDQV3Jl5f&R(Mp};;q8d3I%Kn>Kx=^;uSVCw0L=gw53%Bp==8Sw zxtx=cs!^-_+i{2OK`Q;913+AXc_&Z5$@z3<)So0CU3;JAv=H?@Zpi~riQ{z-zLtVL z!oF<}@IgJp)Iyz1zVJ42!SPHSkjYNS4%ulVVIXdRuiZ@5Mx8LJS}J#qD^Zi_xQ@>DKDr-_e#>5h3dtje*NcwH_h;i{Sx7}dkdpuW z(yUCjckQsagv*QGMSi9u1`Z|V^}Wjf7B@q%j2DQXyd0nOyqg%m{CK_lAoKlJ7#8M} z%IvR?Vh$6aDWK2W!=i?*<77q&B8O&3?zP(Cs@kapc)&p7En?J;t-TX9abGT#H?TW? ztO5(lPKRuC7fs}zwcUKbRh=7E8wzTsa#Z{a`WR}?UZ%!HohN}d&xJ=JQhpO1PI#>X zHkb>pW04pU%Bj_mf~U}1F1=wxdBZu1790>3Dm44bQ#F=T4V3&HlOLsGH)+AK$cHk6 zia$=$kog?)07HCL*PI6}DRhpM^*%I*kHM<#1Se+AQ!!xyhcy6j7`iDX7Z-2i73_n# zas*?7LkxS-XSqv;YBa zW_n*32D(HTYQ0$feV_Fru1ZxW0g&iwqixPX3=9t4o)o|kOo79V$?$uh?#8Q8e>4e)V6;_(x&ViUVxma+i25qea;d-oK7ouuDsB^ab{ zu1qjQ%`n56VtxBE#0qAzb7lph`Eb-}TYpXB!H-}3Ykqyp`otprp7{VEuW*^IR2n$Fb99*nAtqT&oOFIf z@w*6>YvOGw@Ja?Pp1=whZqydzx@9X4n^2!n83C5{C?G@|E?&$?p*g68)kNvUTJ)I6 z1Q|(#UuP6pj78GUxq11m-GSszc+)X{C2eo-?8ud9sB=3(D47v?`JAa{V(IF zPZQ_0AY*9M97>Jf<o%#O_%Wq}8>YM=q0|tGY+hlXcpE=Z4Od z`NT7Hu2hnvRoqOw@g1f=bv`+nba{GwA$Ak0INlqI1k<9!x_!sL()h?hEWoWrdU3w` zZ%%)VR+Bc@_v!C#koM1p-3v_^L6)_Ktj4HE>aUh%2XZE@JFMOn)J~c`_7VWNb9c-N z2b|SZMR4Z@E7j&q&9(6H3yjEu6HV7{2!1t0lgizD;mZ9$r(r7W5G$ky@w(T_dFnOD z*p#+z$@pKE+>o@%eT(2-p_C}wbQ5s(%Sn_{$HDN@MB+Ev?t@3dPy`%TZ!z}AThZSu zN<1i$siJhXFdjV zP*y|V<`V8t=h#XTRUR~5`c`Z9^-`*BZf?WAehGdg)E2Je)hqFa!k{V(u+(hTf^Yq& zoruUh2(^3pe)2{bvt4&4Y9CY3js)PUHtd4rVG57}uFJL)D(JfSIo^{P=7liFXG zq5yqgof0V8paQcP!gy+;^pp-DA5pj=gbMN0eW=-eY+N8~y+G>t+x}oa!5r>tW$xhI zPQSv=pi;~653Gvf6~*JcQ%t1xOrH2l3Zy@8AoJ+wz@daW@m7?%LXkr!bw9GY@ns3e zSfuWF_gkWnesv?s3I`@}NgE2xwgs&rj?kH-FEy82=O8`+szN ziHch`vvS`zNfap14!&#i9H@wF7}yIPm=UB%(o(}F{wsZ(wA0nJ2aD^@B41>>o-_U6 zUqD~vdo48S8~FTb^+%#zcbQiiYoDKYcj&$#^;Smmb+Ljp(L=1Kt_J!;0s%1|JK}Wi z;={~oL!foo5n8=}rs6MmUW~R&;SIJO3TL4Ky?kh+b2rT9B1Jl4>#Uh-Bec z`Hsp<==#UEW6pGPhNk8H!!DUQR~#F9jEMI6T*OWfN^Ze&X(4nV$wa8QUJ>oTkruH# zm~O<`J7Wxseo@FqaZMl#Y(mrFW9AHM9Kb|XBMqaZ2a)DvJgYipkDD_VUF_PKd~dT7 z#02}bBfPn9a!X!O#83=lbJSK#E}K&yx-HI#T6ua)6o0{|={*HFusCkHzs|Fn&|C3H zBck1cmfcWVUN&i>X$YU^Sn6k2H;r3zuXbJFz)r5~3$d$tUj(l1?o={MM){kjgqXRO zc5R*#{;V7AQh|G|)jLM@wGAK&rm2~@{Pewv#06pHbKn#wL0P6F1!^qw9g&cW3Z=9} zj)POhOlwsh@eF=>z?#sIs*C-Nl(yU!#DaiaxhEs#iJqQ8w%(?+6lU02MYSeDkr!B- zPjMv+on6OLXgGnAtl(ao>|X2Y8*Hb}GRW5}-IzXnoo-d0!m4Vy$GS!XOLy>3_+UGs z2D|YcQx@M#M|}TDOetGi{9lGo9m-=0-^+nKE^*?$^uHkxZh}I{#UTQd;X!L+W@jm( zDg@N4+lUqI92o_rNk{3P>1gxAL=&O;x)ZT=q1mk0kLlE$WeWuY_$0`0jY-Kkt zP*|m3AF}Ubd=`<>(Xg0har*_@x2YH}bn0Wk*OZz3*e5;Zc;2uBdnl8?&XjupbkOeNZsNh6pvsq_ydmJI+*z**{I{0K)-;p1~k8cpJXL$^t!-`E}=*4G^-E8>H!LjTPxSx zcF+cS`ommfKMhNSbas^@YbTpH1*RFrBuATUR zt{oFWSk^$xU&kbFQ;MCX22RAN5F6eq9UfR$ut`Jw--p2YX)A*J69m^!oYfj2y7NYcH6&r+0~_sH^c^nzeN1AU4Ga7=FlR{S|Mm~MpzY0$Z+p2W(a={b-pR9EO1Rs zB%KY|@wLcAA@)KXi!d2_BxrkhDn`DT1=Dec}V!okd{$+wK z4E{n8R*xKyci1(CnNdhf$Dp2(Jpof0-0%-38X=Dd9PQgT+w%Lshx9+loPS~MOm%ZT zt%2B2iL_KU_ita%N>xjB!#71_3=3c}o zgeW~^U_ZTJQ2!PqXulQd=3b=XOQhwATK$y(9$#1jOQ4}4?~l#&nek)H(04f(Sr=s| zWv7Lu1=%WGk4FSw^;;!8&YPM)pQDCY9DhU`hMty1@sq1=Tj7bFsOOBZOFlpR`W>-J$-(kezWJj;`?x-v>ev{*8V z8p|KXJPV$HyQr1A(9LVrM47u-XpcrIyO`yWvx1pVYc&?154aneRpLqgx)EMvRaa#|9?Wwqs2+W8n5~79G z(}iCiLk;?enn}ew`HzhG+tu+Ru@T+K5juvZN)wY;x6HjvqD!&!)$$;1VAh~7fg0K| zEha#aN=Yv|3^~YFH}cc38ovVb%L|g@9W6fo(JtT6$fa?zf@Ct88e}m?i)b*Jgc{fl zExfdvw-BYDmH6>(4QMt#p0;FUIQqkhD}aH?a7)_%JtA~soqj{ppP_82yi9kaxuK>~ ze_)Zt>1?q=ZH*kF{1iq9sr*tVuy=u>Zev}!gEZx@O6-fjyu9X00gpIl-fS_pzjpqJ z1yqBmf9NF!jaF<+YxgH6oXBdK)sH(>VZ)1siyA$P<#KDt;8NT*l_0{xit~5j1P)FN zI8hhYKhQ)i z37^aP13B~u65?sg+_@2Kr^iWHN=U;EDSZ@2W2!5ALhGNWXnFBY%7W?1 z=HI9JzQ-pLKZDYTv<0-lt|6c-RwhxZ)mU2Os{bsX_i^@*fKUj8*aDO5pks=qn3Dv6 zwggpKLuyRCTVPwmw1r}B#AS}?X7b837UlXwp~E2|PJw2SGVueL7){Y&z!jL!XN=0i zU^Eig`S2`{+gU$68aRdWx?BZ{sU_f=8sn~>s~M?GU~`fH5kCc; z8ICp+INM3(3{#k32RZdv6b9MQYdZXNuk7ed8;G?S2nT+NZBG=Tar^KFl2SvhW$bGW#kdWL-I)s_IqVnCDDM9fm8g;P;8 z7t4yZn3^*NQfx7SwmkzP$=fwdC}bafQSEF@pd&P8@H#`swGy_rz;Z?Ty5mkS%>m#% zp_!m9e<()sfKiY(nF<1zBz&&`ZlJf6QLvLhl`_``%RW&{+O>Xhp;lwSsyRqGf=RWd zpftiR`={2(siiPAS|p}@q=NhVc0ELprt%=fMXO3B)4ryC2LT(o=sLM7hJC!}T1@)E zA3^J$3&1*M6Xq>03FX`R&w*NkrZE?FwU+Muut;>qNhj@bX17ZJxnOlPSZ=Zeiz~T_ zOu#yc3t6ONHB;?|r4w+pI)~KGN;HOGC)txxiUN8#mexj+W(cz%9a4sx|IRG=}ia zuEBuba3AHsV2feqw-3MvuL`I+2|`Ud4~7ZkN=JZ;L20|Oxna5vx1qbIh#k2O4$RQF zo`tL()zxaqibg^GbB+BS5#U{@K;WWQj~GcB1zb}zJkPwH|5hZ9iH2308!>_;%msji zJHSL~s)YHBR=Koa1mLEOHos*`gp=s8KA-C zu0aE+W!#iJ*0xqKm3A`fUGy#O+X+5W36myS>Uh2!R*s$aCU^`K&KKLCCDkejX2p=5 z%o7-fl03x`gaSNyr?3_JLv?2RLS3F*8ub>Jd@^Cc17)v8vYEK4aqo?OS@W9mt%ITJ z9=S2%R8M){CugT@k~~0x`}Vl!svYqX=E)c_oU6o}#Hb^%G1l3BudxA{F*tbjG;W_>=xV73pKY53v%>I)@D36I_@&p$h|Aw zonQS`07z_F#@T-%@-Tb|)7;;anoD_WH>9ewFy(ZcEOM$#Y)8>qi7rCnsH9GO-_7zF zu*C87{Df1P4TEOsnzZ@H%&lvV(3V@;Q!%+OYRp`g05PjY^gL$^$-t0Y>H*CDDs?FZly*oZ&dxvsxaUWF!{em4{A>n@vpXg$dwvt@_rgmHF z-MER`ABa8R-t_H*kv>}CzOpz;!>p^^9ztHMsHL|SRnS<-y5Z*r(_}c4=fXF`l^-i}>e7v!qs_jv zqvWhX^F=2sDNWA9c@P0?lUlr6ecrTKM%pNQ^?*Lq?p-0~?_j50xV%^(+H>sMul#Tw zeciF*1=?a7cI(}352%>LO96pD+?9!fNyl^9v3^v&Y4L)mNGK0FN43&Xf8jUlxW1Bw zyiu2;qW-aGNhs=zbuoxnxiwZ3{PFZM#Kw)9H@(hgX23h(`Wm~m4&TvoZoYp{plb^> z_#?vXcxd>r7K+1HKJvhed>gtK`TAbJUazUWQY6T~t2af%#<+Veyr%7-#*A#@&*;@g58{i|E%6yC_InGXCOd{L0;$)z#?n7M`re zh!kO{6=>7I?*}czyF7_frt#)s1CFJ_XE&VrDA?Dp3XbvF{qsEJgb&OLSNz_5g?HpK z9)8rsr4JN!Af3G9!#Qn(6zaUDqLN(g2g8*M)Djap?WMK9NKlkC)E2|-g|#-rp%!Gz zAHd%`iq|81efi93m3yTBw3g0j#;Yb2X{mhRAI?&KDmbGqou(2xiRNb^sV}%%Wu0?< z?($L>(#BO*)^)rSgyNRni$i`R4v;GhlCZ8$@e^ROX(p=2_v6Y!%^As zu022)fHdv_-~Yu_H6WVPLpHQx!W%^6j)cBhS`O3QBW#x(eX54d&I22op(N59b*&$v zFiSRY6rOc^(dgSV1>a7-5C;(5S5MvKcM2Jm-LD9TGqDpP097%52V+0>Xqq!! zq4e3vj53SE6i8J`XcQB|MZPP8j;PAOnpGnllH6#Ku~vS42xP*Nz@~y%db7Xi8s09P z1)e%8ys6&M8D=Dt6&t`iKG_4X=!kgRQoh%Z`dc&mlOUqXk-k`jKv9@(a^2-Upw>?< zt5*^DV~6Zedbec4NVl($2T{&b)zA@b#dUyd>`2JC0=xa_fIm8{5um zr-!ApXZhC8@=vC2WyxO|!@0Km)h8ep*`^he92$@YwP>VcdoS5OC^s38e#7RPsg4j+ zbVGG}WRSET&ZfrcR(x~k8n1rTP%CnfUNKUonD$P?FtNFF#cn!wEIab-;jU=B1dHK@ z(;(yAQJ`O$sMn>h;pf^8{JISW%d+@v6@CnXh9n5TXGC}?FI9i-D0OMaIg&mAg=0Kn zNJ7oz5*ReJukD55fUsMuaP+H4tDN&V9zfqF@ zr=#ecUk9wu{0;!+gl;3Bw=Vn^)z$ahVhhw)io!na&9}LmWurLb0zubxK=UEnU*{5P z+SP}&*(iBKSO4{alBHaY^)5Q=mZ+2OwIooJ7*Q5XJ+2|q`9#f?6myq!&oz?klihLq z4C)$XP!BNS0G_Z1&TM>?Jk{S~{F3n83ioli=IO6f%wkvCl(RFFw~j0tb{GvXTx>*sB0McY0s&SNvj4+^h`9nJ_wM>F!Uc>X}9PifQekn0sKI2SAJP!a4h z5cyGTuCj3ZBM^&{dRelIlT^9zcfaAuL5Y~bl!ppSf`wZbK$z#6U~rdclk``e+!qhe z6Qspo*%<)eu6?C;Bp<^VuW6JI|Ncvyn+LlSl;Mp22Bl7ARQ0Xc24%29(ZrdsIPw&-=yHQ7_Vle|5h>AST0 zUGX2Zk34vp?U~IHT|;$U86T+UUHl_NE4m|}>E~6q``7hccCaT^#y+?wD##Q%HwPd8 zV3x4L4|qqu`B$4(LXqDJngNy-{&@aFBvVsywt@X^}iH7P%>bR?ciC$I^U-4Foa`YKI^qDyGK7k%E%c_P=yzAi`YnxGA%DeNd++j3*h^ z=rn>oBd0|~lZ<6YvmkKY*ZJlJ;Im0tqgWu&E92eqt;+NYdxx`eS(4Hw_Jb5|yVvBg z*tbdY^!AN;luEyN4VRhS@-_DC{({ziH{&Z}iGElSV~qvT>L-8G%+yEL zX#MFOhj{InyKG=mvW-<1B@c-}x$vA(nU?>S>0*eN#!SLzQ)Ex7fvQ)S4D<8|I#N$3 zT5Ei`Z?cxBODHX8(Xp73v`IsAYC@9b;t}z0wxVuQSY1J^GRwDPN@qbM-ZF48T$GZ< z8WU+;Pqo?{ghI-KZ-i*ydXu`Ep0Xw^McH_KE9J0S7G;x8Fe`DVG?j3Pv=0YzJ}yZR z%2=oqHiUjvuk0~Ca>Kol4CFi0_xQT~;_F?=u+!kIDl-9g`#ZNZ9HCy17Ga1v^Jv9# z{T4Kb1-AzUxq*MutfOWWZgD*HnFfyYg0&e9f(5tZ>krPF6{VikNeHoc{linPPt#Si z&*g>(c54V8rT_AX!J&bNm-!umPvOR}vDai#`CX___J#=zeB*{4<&2WpaDncZsOkp* zsg<%@@rbrMkR_ux9?LsQxzoBa1s%$BBn6vk#{&&zUwcfzeCBJUwFYSF$08qDsB;gWQN*g!p8pxjofWbqNSZOEKOaTx@+* zwdt5*Q47@EOZ~EZL9s?1o?A%9TJT=Ob_13yyugvPg*e&ZU(r6^k4=2+D-@n=Hv5vu zSXG|hM(>h9^zn=eQ=$6`JO&70&2|%V5Lsx>)(%#;pcOfu>*nk_3HB_BNaH$`jM<^S zcSftDU1?nL;jy)+sfonQN}(}gUW?d_ikr*3=^{G)=tjBtEPe>TO|0ddVB zTklrSHiW+!#26frPXQQ(YN8DG$PZo?(po(QUCCf_OJC`pw*uey00%gmH!`WJkrKXj2!#6?`T25mTu9OJp2L8z3! z=arrL$ZqxuE{%yV)14Kd>k}j7pxZ6#$Dz8$@WV5p8kTqN<-7W)Q7Gt2{KoOPK_tZ| zf2WG~O5@{qPI+W<4f_;reuFVdO^5`ADC1!JQE|N`s3cq@(0WB!n0uh@*c{=LAd;~} zyGK@hbF-Oo+!nN)@i*O(`@FA#u?o=~e{`4O#5}z&=UkU*50fOrzi11D^&FOqe>wii z?*k+2|EcUs;Gx{!@KBT~>PAwLrIDT7Th=Utu?~?np@t^gFs?zgX=D${RwOY^WGh-+ z+#4$066ISh8eYW#FXWp~S`<*%O^ZuItL1Tyqt8#tZ zY120E;^VG`!lZn&3sPd$RkdHpU#|w+bYV)pJC|SH9g%|5IkxVTQcBA4CL0}$&}ef@ zW^Vtj%M;;_1xxP9x#ex17&4N*{ksO*_4O}xYu(p*JkL#yr}@7b)t5X?%CY<+s5_MJ zuiqt+N_;A(_)%lumoyRFixWa-M7qK_9s6<1X?JDa9fP!+_6u~~M$5L=ipB=7(j#f< zZ34J%=bs549%~_mA(|={uZNs_0?o7;-LBP(ZRnkd{-^|2|=4vUTmtByHL8 zEph`(LSEzQj68a+`d$V<45J7cyv^#|^|%fD#si1Nx!4NW*`l*{->HEWNh6-|g>-=r zXmQ|-i}Ku$ndUeHQ^&ieT!Lf}vf6GaqW9$DJ2NWrqwPY%%4nip$@vK$nRp*_C-v<| zuKz~ZyN&<%!NS26&x?jhy+@awJipMQ-8(X4#Ae5??U<1QMt1l9R=w9fAnEF}NYu$2 z>6}Vkc zIb*A?G*z8^IvibmBKn_u^5&T_1oey0gZS2~obf(#xk=erZGTEdQnt3DMGM+0oPwss zj5zXD;(oWhB_T@~Ig#9@v)AKtXu3>Inmgf@A|-lD-1U>cNyl3h?ADD9)GG4}zUGPk zZzaXe!~Kf?<~@$G?Uql3t8jy9{2!doq4=J}j9ktTxss{p6!9UdjyDERlA*xZ!=Q)KDs5O)phz>Vq3BNGoM(H|=1*Q4$^2fTZw z(%nq1P|5Rt81}SYJpEEzMPl5VJsV5&4e)ZWKDyoZ>1EwpkHx-AQVQc8%JMz;{H~p{=FXV>jIxvm4X*qv52e?Y-f%DJ zxEA165GikEASQ^fH6K#d!Tpu2HP{sFs%E=e$gYd$aj$+xue6N+Wc(rAz~wUsk2`(b z8Kvmyz%bKQxpP}~baG-rwYcYCvkHOi zlkR<=>ZBTU*8RF_d#Bl@zZsRIhx<%~Z@Z=ik z>adw3!DK(8R|q$vy{FTxw%#xliD~6qXmY^7_9kthVPTF~Xy1CfBqbU~?1QmxmU=+k z(ggxvEuA;0e&+ci-zQR{-f7aO{O(Pz_OsEjLh_K>MbvoZ4nxtk5u{g@nPv)cgW_R} z9}EA4K4@z0?7ue}Z(o~R(X&FjejUI2g~08PH1E4w>9o{)S(?1>Z0XMvTb|;&EuyOE zGvWNpYX)Nv<8|a^;1>bh#&znEcl-r!T#pn= z4$?Yudha6F%4b>*8@=BdtXXY4N+`U4Dmx$}>HeVJk-QdTG@t!tVT#0(LeV0gvqyyw z2sEp^9eY0N`u10Tm4n8No&A=)IeEC|gnmEXoNSzu!1<4R<%-9kY_8~5Ej?zRegMn78wuMs#;i&eUA0Zk_RXQ3b&TT} z;SCI=7-FUB@*&;8|n>(_g^HGf3@QODE3LpmX~ELnymQm{Sx9xrKS zK29p~?v@R$0=v6Dr5aW>-!{+h@?Q58|Kz8{{W`%J+lDAdb&M5VHrX_mDY;1-JLnf)ezmPau$)1;=`-FU=-r-83tX=C`S#}GZufju zQ>sXNT0Ny=k@nc%cFnvA_i4SC)?_ORXHq8B4D%el1uPX`c~uG#S1M7C+*MMqLw78E zhY2dI8@+N^qrMI1+;TUda(vGqGSRyU{Fnm`aqrr7bz42c5xsOO-~oZpkzorD1g}Y<6rk&3>PsSGy}W?MtqFky@A(X# zIuNZK0cK?^=;PUAu>j0#HtjbHCV*6?jzA&OoE$*Jlga*}LF`SF?WLhv1O|zqC<>*> zYB;#lsYKx0&kH@BFpW8n*yDcc6?;_zaJs<-jPSkCsSX-!aV=P5kUgF@Nu<{a%#K*F z134Q{9|YX7X(v$62_cY3^G%t~rD>Q0z@)1|zs)vjJ6Jq9;7#Ki`w+eS**En?7;n&7 zu==V3T&eFboN3ZiMx3D8qYc;VjFUk_H-WWCau(VFXSQf~viH0L$gwD$UfFHqNcgN`x}M+YQ6RnN<+@t>JUp#)9YOkqst-Ga?{FsDpEeX0(5v{0J~SEbWiL zXC2}M4?UH@u&|;%0y`eb33ldo4~z-x8zY!oVmV=c+f$m?RfDC35mdQ2E>Pze7KWP- z>!Bh<&57I+O_^s}9Tg^k)h7{xx@0a0IA~GAOt2yy!X%Q$1rt~LbTB6@Du!_0%HV>N zlf)QI1&gvERKwso23mJ!Ou6ZS#zCS5W`gxE5T>C#E|{i<1D35C222I33?Njaz`On7 zi<+VWFP6D{e-{yiN#M|Jgk<44u1TiMI78S5W`Sdb5f+{zu34s{CfWN7a3Cf^@L%!& zN$?|!!9j2c)j$~+R6n#891w-z8(!oBpL2K=+%a$r2|~8-(vQj5_XT`<0Ksf;oP+tz z9CObS!0m)Tgg`K#xBM8B(|Z)Wb&DYL{WTYv`;A=q6~Nnx2+!lTIXtj8J7dZE!P_{z z#f8w6F}^!?^KE#+ZDv+xd5O&3EmomZzsv?>E-~ygGum45fk!SBN&|eo1rKw^?aZJ4 E2O(~oYXATM diff --git a/code/gradle/wrapper/gradle-wrapper.properties b/code/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 6c9a2247..00000000 --- a/code/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/code/gradlew b/code/gradlew deleted file mode 100644 index 4f906e0c..00000000 --- a/code/gradlew +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -exec "$JAVACMD" "$@" diff --git a/code/gradlew.bat b/code/gradlew.bat deleted file mode 100644 index 107acd32..00000000 --- a/code/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/code/hiding/Cake.java b/code/hiding/Cake.java deleted file mode 100644 index d20e2cbf..00000000 --- a/code/hiding/Cake.java +++ /dev/null @@ -1,15 +0,0 @@ -// hiding/Cake.java -// (c)2020 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. -// Accesses a class in a separate compilation unit - -class Cake { - public static void main(String[] args) { - Pie x = new Pie(); - x.f(); - } -} -/* Output: -Pie.f() -*/ diff --git a/code/hiding/ChocolateChip.java b/code/hiding/ChocolateChip.java deleted file mode 100644 index 1467fff4..00000000 --- a/code/hiding/ChocolateChip.java +++ /dev/null @@ -1,23 +0,0 @@ -// hiding/ChocolateChip.java -// (c)2020 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. -// Can't use package-access member from another package -import hiding.dessert.*; - -public class ChocolateChip extends Cookie { - public ChocolateChip() { - System.out.println("ChocolateChip constructor"); - } - public void chomp() { - //- bite(); // Can't access bite - } - public static void main(String[] args) { - ChocolateChip x = new ChocolateChip(); - x.chomp(); - } -} -/* Output: -Cookie constructor -ChocolateChip constructor -*/ diff --git a/code/hiding/ChocolateChip2.java b/code/hiding/ChocolateChip2.java deleted file mode 100644 index 03c9d1ab..00000000 --- a/code/hiding/ChocolateChip2.java +++ /dev/null @@ -1,21 +0,0 @@ -// hiding/ChocolateChip2.java -// (c)2020 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. -import hiding.cookie2.*; - -public class ChocolateChip2 extends Cookie { - public ChocolateChip2() { - System.out.println("ChocolateChip2 constructor"); - } - public void chomp() { bite(); } // Protected method - public static void main(String[] args) { - ChocolateChip2 x = new ChocolateChip2(); - x.chomp(); - } -} -/* Output: -Cookie constructor -ChocolateChip2 constructor -bite -*/ diff --git a/code/hiding/CreatePackageAccessObject.java b/code/hiding/CreatePackageAccessObject.java deleted file mode 100644 index 8442b51f..00000000 --- a/code/hiding/CreatePackageAccessObject.java +++ /dev/null @@ -1,12 +0,0 @@ -// hiding/CreatePackageAccessObject.java -// (c)2020 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. -// {WillNotCompile} -import hiding.packageaccess.*; - -public class CreatePackageAccessObject { - public static void main(String[] args) { - new PublicConstructor(); - } -} diff --git a/code/hiding/Dinner.java b/code/hiding/Dinner.java deleted file mode 100644 index 7a7b97d5..00000000 --- a/code/hiding/Dinner.java +++ /dev/null @@ -1,16 +0,0 @@ -// hiding/Dinner.java -// (c)2020 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. -// Uses the library -import hiding.dessert.*; - -public class Dinner { - public static void main(String[] args) { - Cookie x = new Cookie(); - //- x.bite(); // Can't access - } -} -/* Output: -Cookie constructor -*/ diff --git a/code/hiding/FullQualification.java b/code/hiding/FullQualification.java deleted file mode 100644 index 2fadb28c..00000000 --- a/code/hiding/FullQualification.java +++ /dev/null @@ -1,11 +0,0 @@ -// hiding/FullQualification.java -// (c)2020 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. - -public class FullQualification { - public static void main(String[] args) { - java.util.ArrayList list = - new java.util.ArrayList(); - } -} diff --git a/code/hiding/IceCream.java b/code/hiding/IceCream.java deleted file mode 100644 index d91619a2..00000000 --- a/code/hiding/IceCream.java +++ /dev/null @@ -1,19 +0,0 @@ -// hiding/IceCream.java -// (c)2020 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. -// Demonstrates "private" keyword - -class Sundae { - private Sundae() {} - static Sundae makeASundae() { - return new Sundae(); - } -} - -public class IceCream { - public static void main(String[] args) { - //- Sundae x = new Sundae(); - Sundae x = Sundae.makeASundae(); - } -} diff --git a/code/hiding/ImportedMyClass.java b/code/hiding/ImportedMyClass.java deleted file mode 100644 index a644f5d8..00000000 --- a/code/hiding/ImportedMyClass.java +++ /dev/null @@ -1,11 +0,0 @@ -// hiding/ImportedMyClass.java -// (c)2020 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. -import hiding.mypackage.*; - -public class ImportedMyClass { - public static void main(String[] args) { - MyClass m = new MyClass(); - } -} diff --git a/code/hiding/LibTest.java b/code/hiding/LibTest.java deleted file mode 100644 index c439352a..00000000 --- a/code/hiding/LibTest.java +++ /dev/null @@ -1,17 +0,0 @@ -// hiding/LibTest.java -// (c)2020 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. -// Uses the library -import com.mindviewinc.simple.*; - -public class LibTest { - public static void main(String[] args) { - Vector v = new Vector(); - List l = new List(); - } -} -/* Output: -com.mindviewinc.simple.Vector -com.mindviewinc.simple.List -*/ diff --git a/code/hiding/Lunch.java b/code/hiding/Lunch.java deleted file mode 100644 index eca4baf0..00000000 --- a/code/hiding/Lunch.java +++ /dev/null @@ -1,36 +0,0 @@ -// hiding/Lunch.java -// (c)2020 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. -// Demonstrates class access specifiers. Make a class -// effectively private with private constructors: - -class Soup1 { - private Soup1() {} - public static Soup1 makeSoup() { // [1] - return new Soup1(); - } -} - -class Soup2 { - private Soup2() {} - private static Soup2 ps1 = new Soup2(); // [2] - public static Soup2 access() { - return ps1; - } - public void f() {} -} - -// Only one public class allowed per file: -public class Lunch { - void testPrivate() { - // Can't do this! Private constructor: - //- Soup1 soup = new Soup1(); - } - void testStatic() { - Soup1 soup = Soup1.makeSoup(); - } - void testSingleton() { - Soup2.access().f(); - } -} diff --git a/code/hiding/OrganizedByAccess.java b/code/hiding/OrganizedByAccess.java deleted file mode 100644 index 46af158f..00000000 --- a/code/hiding/OrganizedByAccess.java +++ /dev/null @@ -1,15 +0,0 @@ -// hiding/OrganizedByAccess.java -// (c)2020 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. - -public class OrganizedByAccess { - public void pub1() { /* ... */ } - public void pub2() { /* ... */ } - public void pub3() { /* ... */ } - private void priv1() { /* ... */ } - private void priv2() { /* ... */ } - private void priv3() { /* ... */ } - private int i; - // ... -} diff --git a/code/hiding/Pie.java b/code/hiding/Pie.java deleted file mode 100644 index 1470fbc3..00000000 --- a/code/hiding/Pie.java +++ /dev/null @@ -1,9 +0,0 @@ -// hiding/Pie.java -// (c)2020 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. -// The other class - -class Pie { - void f() { System.out.println("Pie.f()"); } -} diff --git a/code/hiding/QualifiedMyClass.java b/code/hiding/QualifiedMyClass.java deleted file mode 100644 index 58a097cc..00000000 --- a/code/hiding/QualifiedMyClass.java +++ /dev/null @@ -1,11 +0,0 @@ -// hiding/QualifiedMyClass.java -// (c)2020 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. - -public class QualifiedMyClass { - public static void main(String[] args) { - hiding.mypackage.MyClass m = - new hiding.mypackage.MyClass(); - } -} diff --git a/code/hiding/SingleImport.java b/code/hiding/SingleImport.java deleted file mode 100644 index 5168ebe8..00000000 --- a/code/hiding/SingleImport.java +++ /dev/null @@ -1,11 +0,0 @@ -// hiding/SingleImport.java -// (c)2020 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. -import java.util.ArrayList; - -public class SingleImport { - public static void main(String[] args) { - ArrayList list = new ArrayList(); - } -} diff --git a/code/hiding/cookie2/Cookie.java b/code/hiding/cookie2/Cookie.java deleted file mode 100644 index aff5bb17..00000000 --- a/code/hiding/cookie2/Cookie.java +++ /dev/null @@ -1,14 +0,0 @@ -// hiding/cookie2/Cookie.java -// (c)2020 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 hiding.cookie2; - -public class Cookie { - public Cookie() { - System.out.println("Cookie constructor"); - } - protected void bite() { - System.out.println("bite"); - } -} diff --git a/code/hiding/dessert/Cookie.java b/code/hiding/dessert/Cookie.java deleted file mode 100644 index 803e504c..00000000 --- a/code/hiding/dessert/Cookie.java +++ /dev/null @@ -1,13 +0,0 @@ -// hiding/dessert/Cookie.java -// (c)2020 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. -// Creates a library -package hiding.dessert; - -public class Cookie { - public Cookie() { - System.out.println("Cookie constructor"); - } - void bite() { System.out.println("bite"); } -} diff --git a/code/hiding/mypackage/MyClass.java b/code/hiding/mypackage/MyClass.java deleted file mode 100644 index 5245d479..00000000 --- a/code/hiding/mypackage/MyClass.java +++ /dev/null @@ -1,9 +0,0 @@ -// hiding/mypackage/MyClass.java -// (c)2020 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 hiding.mypackage; - -public class MyClass { - // ... -} diff --git a/code/hiding/packageaccess/PublicConstructor.java b/code/hiding/packageaccess/PublicConstructor.java deleted file mode 100644 index 533c28a0..00000000 --- a/code/hiding/packageaccess/PublicConstructor.java +++ /dev/null @@ -1,9 +0,0 @@ -// hiding/packageaccess/PublicConstructor.java -// (c)2020 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 hiding.packageaccess; - -class PublicConstructor { - public PublicConstructor() {} -} diff --git a/code/housekeeping/Apricot.java b/code/housekeeping/Apricot.java deleted file mode 100644 index dae8f33d..00000000 --- a/code/housekeeping/Apricot.java +++ /dev/null @@ -1,8 +0,0 @@ -// housekeeping/Apricot.java -// (c)2020 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. -public class Apricot { - void pick() { /* ... */ } - void pit() { pick(); /* ... */ } -} diff --git a/code/housekeeping/ArrayClassObj.java b/code/housekeeping/ArrayClassObj.java deleted file mode 100644 index 44e31b59..00000000 --- a/code/housekeeping/ArrayClassObj.java +++ /dev/null @@ -1,22 +0,0 @@ -// housekeeping/ArrayClassObj.java -// (c)2020 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. -// Creating an array of nonprimitive objects -import java.util.*; - -public class ArrayClassObj { - public static void main(String[] args) { - Random rand = new Random(47); - Integer[] a = new Integer[rand.nextInt(20)]; - System.out.println("length of a = " + a.length); - for(int i = 0; i < a.length; i++) - a[i] = rand.nextInt(500); // Autoboxing - System.out.println(Arrays.toString(a)); - } -} -/* Output: -length of a = 18 -[55, 193, 361, 461, 429, 368, 200, 22, 207, 288, 128, -51, 89, 309, 278, 498, 361, 20] -*/ diff --git a/code/housekeeping/ArrayInit.java b/code/housekeeping/ArrayInit.java deleted file mode 100644 index 4186bd24..00000000 --- a/code/housekeeping/ArrayInit.java +++ /dev/null @@ -1,25 +0,0 @@ -// housekeeping/ArrayInit.java -// (c)2020 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. -// Array initialization -import java.util.*; - -public class ArrayInit { - public static void main(String[] args) { - Integer[] a = { - 1, 2, - 3, // Autoboxing - }; - Integer[] b = new Integer[]{ - 1, 2, - 3, // Autoboxing - }; - System.out.println(Arrays.toString(a)); - System.out.println(Arrays.toString(b)); - } -} -/* Output: -[1, 2, 3] -[1, 2, 3] -*/ diff --git a/code/housekeeping/ArrayNew.java b/code/housekeeping/ArrayNew.java deleted file mode 100644 index 022cec16..00000000 --- a/code/housekeeping/ArrayNew.java +++ /dev/null @@ -1,20 +0,0 @@ -// housekeeping/ArrayNew.java -// (c)2020 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. -// Creating arrays with new -import java.util.*; - -public class ArrayNew { - public static void main(String[] args) { - int[] a; - Random rand = new Random(47); - a = new int[rand.nextInt(20)]; - System.out.println("length of a = " + a.length); - System.out.println(Arrays.toString(a)); - } -} -/* Output: -length of a = 18 -[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] -*/ diff --git a/code/housekeeping/ArraysOfPrimitives.java b/code/housekeeping/ArraysOfPrimitives.java deleted file mode 100644 index 165afe89..00000000 --- a/code/housekeeping/ArraysOfPrimitives.java +++ /dev/null @@ -1,23 +0,0 @@ -// housekeeping/ArraysOfPrimitives.java -// (c)2020 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. - -public class ArraysOfPrimitives { - public static void main(String[] args) { - int[] a1 = { 1, 2, 3, 4, 5 }; - int[] a2; - a2 = a1; - for(int i = 0; i < a2.length; i++) - a2[i] += 1; - for(int i = 0; i < a1.length; i++) - System.out.println("a1[" + i + "] = " + a1[i]); - } -} -/* Output: -a1[0] = 2 -a1[1] = 3 -a1[2] = 4 -a1[3] = 5 -a1[4] = 6 -*/ diff --git a/code/housekeeping/AutoboxingVarargs.java b/code/housekeeping/AutoboxingVarargs.java deleted file mode 100644 index c670fa67..00000000 --- a/code/housekeeping/AutoboxingVarargs.java +++ /dev/null @@ -1,22 +0,0 @@ -// housekeeping/AutoboxingVarargs.java -// (c)2020 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. - -public class AutoboxingVarargs { - public static void f(Integer... args) { - for(Integer i : args) - System.out.print(i + " "); - System.out.println(); - } - public static void main(String[] args) { - f(1, 2); - f(4, 5, 6, 7, 8, 9); - f(10, 11, 12); - } -} -/* Output: -1 2 -4 5 6 7 8 9 -10 11 12 -*/ diff --git a/code/housekeeping/BananaPeel.java b/code/housekeeping/BananaPeel.java deleted file mode 100644 index b3e01b27..00000000 --- a/code/housekeeping/BananaPeel.java +++ /dev/null @@ -1,15 +0,0 @@ -// housekeeping/BananaPeel.java -// (c)2020 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. - -class Banana { void peel(int i) { /* ... */ } } - -public class BananaPeel { - public static void main(String[] args) { - Banana a = new Banana(), - b = new Banana(); - a.peel(1); - b.peel(2); - } -} diff --git a/code/housekeeping/Burrito.java b/code/housekeeping/Burrito.java deleted file mode 100644 index e3fd028b..00000000 --- a/code/housekeeping/Burrito.java +++ /dev/null @@ -1,39 +0,0 @@ -// housekeeping/Burrito.java -// (c)2020 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. - -public class Burrito { - Spiciness degree; - public Burrito(Spiciness degree) { - this.degree = degree; - } - public void describe() { - System.out.print("This burrito is "); - switch(degree) { - case NOT: System.out.println( - "not spicy at all."); - break; - case MILD: - case MEDIUM: System.out.println("a little hot."); - break; - case HOT: - case FLAMING: - default: System.out.println("maybe too hot."); - } - } - public static void main(String[] args) { - Burrito - plain = new Burrito(Spiciness.NOT), - greenChile = new Burrito(Spiciness.MEDIUM), - jalapeno = new Burrito(Spiciness.HOT); - plain.describe(); - greenChile.describe(); - jalapeno.describe(); - } -} -/* Output: -This burrito is not spicy at all. -This burrito is a little hot. -This burrito is maybe too hot. -*/ diff --git a/code/housekeeping/Counter.java b/code/housekeeping/Counter.java deleted file mode 100644 index d0a58ecc..00000000 --- a/code/housekeeping/Counter.java +++ /dev/null @@ -1,9 +0,0 @@ -// housekeeping/Counter.java -// (c)2020 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. -public class Counter { - int i; - Counter() { i = 7; } - // ... -} diff --git a/code/housekeeping/DefaultConstructor.java b/code/housekeeping/DefaultConstructor.java deleted file mode 100644 index 22e3787d..00000000 --- a/code/housekeeping/DefaultConstructor.java +++ /dev/null @@ -1,12 +0,0 @@ -// housekeeping/DefaultConstructor.java -// (c)2020 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. - -class Bird {} - -public class DefaultConstructor { - public static void main(String[] args) { - Bird b = new Bird(); // Default! - } -} diff --git a/code/housekeeping/Demotion.java b/code/housekeeping/Demotion.java deleted file mode 100644 index ad2c4e86..00000000 --- a/code/housekeeping/Demotion.java +++ /dev/null @@ -1,43 +0,0 @@ -// housekeeping/Demotion.java -// (c)2020 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. -// Demotion of primitives - -public class Demotion { - void f1(double x) { - System.out.println("f1(double)"); - } - void f2(float x) { System.out.println("f2(float)"); } - void f3(long x) { System.out.println("f3(long)"); } - void f4(int x) { System.out.println("f4(int)"); } - void f5(short x) { System.out.println("f5(short)"); } - void f6(byte x) { System.out.println("f6(byte)"); } - void f7(char x) { System.out.println("f7(char)"); } - - void testDouble() { - double x = 0; - System.out.println("double argument:"); - f1(x); - f2((float)x); - f3((long)x); - f4((int)x); - f5((short)x); - f6((byte)x); - f7((char)x); - } - public static void main(String[] args) { - Demotion p = new Demotion(); - p.testDouble(); - } -} -/* Output: -double argument: -f1(double) -f2(float) -f3(long) -f4(int) -f5(short) -f6(byte) -f7(char) -*/ diff --git a/code/housekeeping/DynamicArray.java b/code/housekeeping/DynamicArray.java deleted file mode 100644 index 726ec034..00000000 --- a/code/housekeeping/DynamicArray.java +++ /dev/null @@ -1,21 +0,0 @@ -// housekeeping/DynamicArray.java -// (c)2020 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. -// Array initialization - -public class DynamicArray { - public static void main(String[] args) { - Other.main(new String[]{ "fiddle", "de", "dum" }); - } -} - -class Other { - public static void main(String[] args) { - for(String s : args) - System.out.print(s + " "); - } -} -/* Output: -fiddle de dum -*/ diff --git a/code/housekeeping/EnumOrder.java b/code/housekeeping/EnumOrder.java deleted file mode 100644 index a3c96284..00000000 --- a/code/housekeeping/EnumOrder.java +++ /dev/null @@ -1,19 +0,0 @@ -// housekeeping/EnumOrder.java -// (c)2020 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. - -public class EnumOrder { - public static void main(String[] args) { - for(Spiciness s : Spiciness.values()) - System.out.println( - s + ", ordinal " + s.ordinal()); - } -} -/* Output: -NOT, ordinal 0 -MILD, ordinal 1 -MEDIUM, ordinal 2 -HOT, ordinal 3 -FLAMING, ordinal 4 -*/ diff --git a/code/housekeeping/ExplicitStatic.java b/code/housekeeping/ExplicitStatic.java deleted file mode 100644 index 7d9cb31a..00000000 --- a/code/housekeeping/ExplicitStatic.java +++ /dev/null @@ -1,41 +0,0 @@ -// housekeeping/ExplicitStatic.java -// (c)2020 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. -// Explicit static initialization with "static" clause - -class Cup { - Cup(int marker) { - System.out.println("Cup(" + marker + ")"); - } - void f(int marker) { - System.out.println("f(" + marker + ")"); - } -} - -class Cups { - static Cup cup1; - static Cup cup2; - static { - cup1 = new Cup(1); - cup2 = new Cup(2); - } - Cups() { - System.out.println("Cups()"); - } -} - -public class ExplicitStatic { - public static void main(String[] args) { - System.out.println("Inside main()"); - Cups.cup1.f(99); // [1] - } - // static Cups cups1 = new Cups(); // [2] - // static Cups cups2 = new Cups(); // [2] -} -/* Output: -Inside main() -Cup(1) -Cup(2) -f(99) -*/ diff --git a/code/housekeeping/Flower.java b/code/housekeeping/Flower.java deleted file mode 100644 index a62d7cbe..00000000 --- a/code/housekeeping/Flower.java +++ /dev/null @@ -1,46 +0,0 @@ -// housekeeping/Flower.java -// (c)2020 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. -// Calling constructors with "this" - -public class Flower { - int petalCount = 0; - String s = "initial value"; - Flower(int petals) { - petalCount = petals; - System.out.println( - "Constructor w/ int arg only, petalCount= " - + petalCount); - } - Flower(String ss) { - System.out.println( - "Constructor w/ String arg only, s = " + ss); - s = ss; - } - Flower(String s, int petals) { - this(petals); - //- this(s); // Can't call two! - this.s = s; // Another use of "this" - System.out.println("String & int args"); - } - Flower() { - this("hi", 47); - System.out.println("no-arg constructor"); - } - void printPetalCount() { - //- this(11); // Not inside non-constructor! - System.out.println( - "petalCount = " + petalCount + " s = "+ s); - } - public static void main(String[] args) { - Flower x = new Flower(); - x.printPetalCount(); - } -} -/* Output: -Constructor w/ int arg only, petalCount= 47 -String & int args -no-arg constructor -petalCount = 47 s = hi -*/ diff --git a/code/housekeeping/InitialValues.java b/code/housekeeping/InitialValues.java deleted file mode 100644 index dced4dd2..00000000 --- a/code/housekeeping/InitialValues.java +++ /dev/null @@ -1,44 +0,0 @@ -// housekeeping/InitialValues.java -// (c)2020 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. -// Shows default initial values - -public class InitialValues { - boolean t; - char c; - byte b; - short s; - int i; - long l; - float f; - double d; - InitialValues reference; - void printInitialValues() { - System.out.println("Data type Initial value"); - System.out.println("boolean " + t); - System.out.println("char [" + c + "]"); - System.out.println("byte " + b); - System.out.println("short " + s); - System.out.println("int " + i); - System.out.println("long " + l); - System.out.println("float " + f); - System.out.println("double " + d); - System.out.println("reference " + reference); - } - public static void main(String[] args) { - new InitialValues().printInitialValues(); - } -} -/* Output: -Data type Initial value -boolean false -char [NUL] -byte 0 -short 0 -int 0 -long 0 -float 0.0 -double 0.0 -reference null -*/ diff --git a/code/housekeeping/InitialValues2.java b/code/housekeeping/InitialValues2.java deleted file mode 100644 index 1cb50974..00000000 --- a/code/housekeeping/InitialValues2.java +++ /dev/null @@ -1,16 +0,0 @@ -// housekeeping/InitialValues2.java -// (c)2020 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. -// Providing explicit initial values - -public class InitialValues2 { - boolean bool = true; - char ch = 'x'; - byte b = 47; - short s = 0xff; - int i = 999; - long lng = 1; - float f = 3.14f; - double d = 3.14159; -} diff --git a/code/housekeeping/Leaf.java b/code/housekeeping/Leaf.java deleted file mode 100644 index f9c560b2..00000000 --- a/code/housekeeping/Leaf.java +++ /dev/null @@ -1,23 +0,0 @@ -// housekeeping/Leaf.java -// (c)2020 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. -// Simple use of the "this" keyword - -public class Leaf { - int i = 0; - Leaf increment() { - i++; - return this; - } - void print() { - System.out.println("i = " + i); - } - public static void main(String[] args) { - Leaf x = new Leaf(); - x.increment().increment().increment().print(); - } -} -/* Output: -i = 3 -*/ diff --git a/code/housekeeping/Measurement.java b/code/housekeeping/Measurement.java deleted file mode 100644 index 8a920779..00000000 --- a/code/housekeeping/Measurement.java +++ /dev/null @@ -1,10 +0,0 @@ -// housekeeping/Measurement.java -// (c)2020 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. -class Depth {} - -public class Measurement { - Depth d = new Depth(); - // ... -} diff --git a/code/housekeeping/MethodInit.java b/code/housekeeping/MethodInit.java deleted file mode 100644 index 84e15fce..00000000 --- a/code/housekeeping/MethodInit.java +++ /dev/null @@ -1,8 +0,0 @@ -// housekeeping/MethodInit.java -// (c)2020 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. -public class MethodInit { - int i = f(); - int f() { return 11; } -} diff --git a/code/housekeeping/MethodInit2.java b/code/housekeeping/MethodInit2.java deleted file mode 100644 index 24750fb2..00000000 --- a/code/housekeeping/MethodInit2.java +++ /dev/null @@ -1,10 +0,0 @@ -// housekeeping/MethodInit2.java -// (c)2020 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. -public class MethodInit2 { - int i = f(); - int j = g(i); - int f() { return 11; } - int g(int n) { return n * 10; } -} diff --git a/code/housekeeping/MethodInit3.java b/code/housekeeping/MethodInit3.java deleted file mode 100644 index 2a6524ab..00000000 --- a/code/housekeeping/MethodInit3.java +++ /dev/null @@ -1,10 +0,0 @@ -// housekeeping/MethodInit3.java -// (c)2020 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. -public class MethodInit3 { - //- int j = g(i); // Illegal forward reference - int i = f(); - int f() { return 11; } - int g(int n) { return n * 10; } -} diff --git a/code/housekeeping/Mugs.java b/code/housekeeping/Mugs.java deleted file mode 100644 index e4ebba69..00000000 --- a/code/housekeeping/Mugs.java +++ /dev/null @@ -1,47 +0,0 @@ -// housekeeping/Mugs.java -// (c)2020 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. -// Instance initialization - -class Mug { - Mug(int marker) { - System.out.println("Mug(" + marker + ")"); - } -} - -public class Mugs { - Mug mug1; - Mug mug2; - { // [1] - mug1 = new Mug(1); - mug2 = new Mug(2); - System.out.println("mug1 & mug2 initialized"); - } - Mugs() { - System.out.println("Mugs()"); - } - Mugs(int i) { - System.out.println("Mugs(int)"); - } - public static void main(String[] args) { - System.out.println("Inside main()"); - new Mugs(); - System.out.println("new Mugs() completed"); - new Mugs(1); - System.out.println("new Mugs(1) completed"); - } -} -/* Output: -Inside main() -Mug(1) -Mug(2) -mug1 & mug2 initialized -Mugs() -new Mugs() completed -Mug(1) -Mug(2) -mug1 & mug2 initialized -Mugs(int) -new Mugs(1) completed -*/ diff --git a/code/housekeeping/NewVarArgs.java b/code/housekeeping/NewVarArgs.java deleted file mode 100644 index 291dd134..00000000 --- a/code/housekeeping/NewVarArgs.java +++ /dev/null @@ -1,30 +0,0 @@ -// housekeeping/NewVarArgs.java -// (c)2020 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. -// Using array syntax to create variable argument lists - -public class NewVarArgs { - static void printArray(Object... args) { - for(Object obj : args) - System.out.print(obj + " "); - System.out.println(); - } - public static void main(String[] args) { - // Can take individual elements: - printArray(47, (float) 3.14, 11.11); - printArray(47, 3.14F, 11.11); - printArray("one", "two", "three"); - printArray(new A(), new A(), new A()); - // Or an array: - printArray((Object[])new Integer[]{ 1, 2, 3, 4 }); - printArray(); // Empty list is OK - } -} -/* Output: -47 3.14 11.11 -47 3.14 11.11 -one two three -A@15db9742 A@6d06d69c A@7852e922 -1 2 3 4 -*/ diff --git a/code/housekeeping/NoSynthesis.java b/code/housekeeping/NoSynthesis.java deleted file mode 100644 index 217c2023..00000000 --- a/code/housekeeping/NoSynthesis.java +++ /dev/null @@ -1,17 +0,0 @@ -// housekeeping/NoSynthesis.java -// (c)2020 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. - -class Bird2 { - Bird2(int i) {} - Bird2(double d) {} -} - -public class NoSynthesis { - public static void main(String[] args) { - //- Bird2 b = new Bird2(); // No default - Bird2 b2 = new Bird2(1); - Bird2 b3 = new Bird2(1.0); - } -} diff --git a/code/housekeeping/OptionalTrailingArguments.java b/code/housekeeping/OptionalTrailingArguments.java deleted file mode 100644 index d7ee9fbb..00000000 --- a/code/housekeeping/OptionalTrailingArguments.java +++ /dev/null @@ -1,23 +0,0 @@ -// housekeeping/OptionalTrailingArguments.java -// (c)2020 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. - -public class OptionalTrailingArguments { - static void f(int required, String... trailing) { - System.out.print("required: " + required + " "); - for(String s : trailing) - System.out.print(s + " "); - System.out.println(); - } - public static void main(String[] args) { - f(1, "one"); - f(2, "two", "three"); - f(0); - } -} -/* Output: -required: 1 one -required: 2 two three -required: 0 -*/ diff --git a/code/housekeeping/OrderOfInitialization.java b/code/housekeeping/OrderOfInitialization.java deleted file mode 100644 index c715ed7c..00000000 --- a/code/housekeeping/OrderOfInitialization.java +++ /dev/null @@ -1,40 +0,0 @@ -// housekeeping/OrderOfInitialization.java -// (c)2020 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. -// Demonstrates initialization order - -// When the constructor is called to create a -// Window object, you'll see a message: -class Window { - Window(int marker) { - System.out.println("Window(" + marker + ")"); - } -} - -class House { - Window w1 = new Window(1); // Before constructor - House() { - // Show that we're in the constructor: - System.out.println("House()"); - w3 = new Window(33); // Reinitialize w3 - } - Window w2 = new Window(2); // After constructor - void f() { System.out.println("f()"); } - Window w3 = new Window(3); // At end -} - -public class OrderOfInitialization { - public static void main(String[] args) { - House h = new House(); - h.f(); // Shows that construction is done - } -} -/* Output: -Window(1) -Window(2) -Window(3) -House() -Window(33) -f() -*/ diff --git a/code/housekeeping/Overloading.java b/code/housekeeping/Overloading.java deleted file mode 100644 index 99d21bf8..00000000 --- a/code/housekeeping/Overloading.java +++ /dev/null @@ -1,56 +0,0 @@ -// housekeeping/Overloading.java -// (c)2020 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. -// Both constructor and ordinary method overloading - -class Tree { - int height; - Tree() { - System.out.println("Planting a seedling"); - height = 0; - } - Tree(int initialHeight) { - height = initialHeight; - System.out.println("Creating new Tree that is " + - height + " feet tall"); - } - void info() { - System.out.println( - "Tree is " + height + " feet tall"); - } - void info(String s) { - System.out.println( - s + ": Tree is " + height + " feet tall"); - } -} - -public class Overloading { - public static void main(String[] args) { - for(int i = 0; i < 5; i++) { - Tree t = new Tree(i); - t.info(); - t.info("overloaded method"); - } - // Overloaded constructor: - new Tree(); - } -} -/* Output: -Creating new Tree that is 0 feet tall -Tree is 0 feet tall -overloaded method: Tree is 0 feet tall -Creating new Tree that is 1 feet tall -Tree is 1 feet tall -overloaded method: Tree is 1 feet tall -Creating new Tree that is 2 feet tall -Tree is 2 feet tall -overloaded method: Tree is 2 feet tall -Creating new Tree that is 3 feet tall -Tree is 3 feet tall -overloaded method: Tree is 3 feet tall -Creating new Tree that is 4 feet tall -Tree is 4 feet tall -overloaded method: Tree is 4 feet tall -Planting a seedling -*/ diff --git a/code/housekeeping/OverloadingOrder.java b/code/housekeeping/OverloadingOrder.java deleted file mode 100644 index 42f6466e..00000000 --- a/code/housekeeping/OverloadingOrder.java +++ /dev/null @@ -1,22 +0,0 @@ -// housekeeping/OverloadingOrder.java -// (c)2020 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. -// Overloading based on the order of the arguments - -public class OverloadingOrder { - static void f(String s, int i) { - System.out.println("String: " + s + ", int: " + i); - } - static void f(int i, String s) { - System.out.println("int: " + i + ", String: " + s); - } - public static void main(String[] args) { - f("String first", 11); - f(99, "Int first"); - } -} -/* Output: -String: String first, int: 11 -int: 99, String: Int first -*/ diff --git a/code/housekeeping/OverloadingVarargs.java b/code/housekeeping/OverloadingVarargs.java deleted file mode 100644 index c13b7406..00000000 --- a/code/housekeeping/OverloadingVarargs.java +++ /dev/null @@ -1,37 +0,0 @@ -// housekeeping/OverloadingVarargs.java -// (c)2020 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. - -public class OverloadingVarargs { - static void f(Character... args) { - System.out.print("first"); - for(Character c : args) - System.out.print(" " + c); - System.out.println(); - } - static void f(Integer... args) { - System.out.print("second"); - for(Integer i : args) - System.out.print(" " + i); - System.out.println(); - } - static void f(Long... args) { - System.out.println("third"); - } - public static void main(String[] args) { - f('a', 'b', 'c'); - f(1); - f(2, 1); - f(0); - f(0L); - //- f(); // Won't compile -- ambiguous - } -} -/* Output: -first a b c -second 1 -second 2 1 -second 0 -third -*/ diff --git a/code/housekeeping/OverloadingVarargs2.java b/code/housekeeping/OverloadingVarargs2.java deleted file mode 100644 index c3a09845..00000000 --- a/code/housekeeping/OverloadingVarargs2.java +++ /dev/null @@ -1,18 +0,0 @@ -// housekeeping/OverloadingVarargs2.java -// (c)2020 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. -// {WillNotCompile} - -public class OverloadingVarargs2 { - static void f(float i, Character... args) { - System.out.println("first"); - } - static void f(Character... args) { - System.out.print("second"); - } - public static void main(String[] args) { - f(1, 'a'); - f('a', 'b'); - } -} diff --git a/code/housekeeping/OverloadingVarargs3.java b/code/housekeeping/OverloadingVarargs3.java deleted file mode 100644 index 23e757ec..00000000 --- a/code/housekeeping/OverloadingVarargs3.java +++ /dev/null @@ -1,21 +0,0 @@ -// housekeeping/OverloadingVarargs3.java -// (c)2020 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. - -public class OverloadingVarargs3 { - static void f(float i, Character... args) { - System.out.println("first"); - } - static void f(char c, Character... args) { - System.out.println("second"); - } - public static void main(String[] args) { - f(1, 'a'); - f('a', 'b'); - } -} -/* Output: -first -second -*/ diff --git a/code/housekeeping/PassingThis.java b/code/housekeeping/PassingThis.java deleted file mode 100644 index ce725eab..00000000 --- a/code/housekeeping/PassingThis.java +++ /dev/null @@ -1,31 +0,0 @@ -// housekeeping/PassingThis.java -// (c)2020 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. - -class Person { - public void eat(Apple apple) { - Apple peeled = apple.getPeeled(); - System.out.println("Yummy"); - } -} - -class Peeler { - static Apple peel(Apple apple) { - // ... remove peel - return apple; // Peeled - } -} - -class Apple { - Apple getPeeled() { return Peeler.peel(this); } -} - -public class PassingThis { - public static void main(String[] args) { - new Person().eat(new Apple()); - } -} -/* Output: -Yummy -*/ diff --git a/code/housekeeping/PrimitiveOverloading.java b/code/housekeeping/PrimitiveOverloading.java deleted file mode 100644 index 1d8c1e2c..00000000 --- a/code/housekeeping/PrimitiveOverloading.java +++ /dev/null @@ -1,120 +0,0 @@ -// housekeeping/PrimitiveOverloading.java -// (c)2020 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. -// Promotion of primitives and overloading - -public class PrimitiveOverloading { - void f1(char x) { System.out.print("f1(char) "); } - void f1(byte x) { System.out.print("f1(byte) "); } - void f1(short x) { System.out.print("f1(short) "); } - void f1(int x) { System.out.print("f1(int) "); } - void f1(long x) { System.out.print("f1(long) "); } - void f1(float x) { System.out.print("f1(float) "); } - void f1(double x) { System.out.print("f1(double) "); } - - void f2(byte x) { System.out.print("f2(byte) "); } - void f2(short x) { System.out.print("f2(short) "); } - void f2(int x) { System.out.print("f2(int) "); } - void f2(long x) { System.out.print("f2(long) "); } - void f2(float x) { System.out.print("f2(float) "); } - void f2(double x) { System.out.print("f2(double) "); } - - void f3(short x) { System.out.print("f3(short) "); } - void f3(int x) { System.out.print("f3(int) "); } - void f3(long x) { System.out.print("f3(long) "); } - void f3(float x) { System.out.print("f3(float) "); } - void f3(double x) { System.out.print("f3(double) "); } - - void f4(int x) { System.out.print("f4(int) "); } - void f4(long x) { System.out.print("f4(long) "); } - void f4(float x) { System.out.print("f4(float) "); } - void f4(double x) { System.out.print("f4(double) "); } - - void f5(long x) { System.out.print("f5(long) "); } - void f5(float x) { System.out.print("f5(float) "); } - void f5(double x) { System.out.print("f5(double) "); } - - void f6(float x) { System.out.print("f6(float) "); } - void f6(double x) { System.out.print("f6(double) "); } - - void f7(double x) { System.out.print("f7(double) "); } - - void testConstVal() { - System.out.print("5: "); - f1(5);f2(5);f3(5);f4(5);f5(5);f6(5);f7(5); - System.out.println(); - } - void testChar() { - char x = 'x'; - System.out.print("char: "); - f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); - System.out.println(); - } - void testByte() { - byte x = 0; - System.out.print("byte: "); - f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); - System.out.println(); - } - void testShort() { - short x = 0; - System.out.print("short: "); - f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); - System.out.println(); - } - void testInt() { - int x = 0; - System.out.print("int: "); - f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); - System.out.println(); - } - void testLong() { - long x = 0; - System.out.print("long: "); - f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); - System.out.println(); - } - void testFloat() { - float x = 0; - System.out.print("float: "); - f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); - System.out.println(); - } - void testDouble() { - double x = 0; - System.out.print("double: "); - f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); - System.out.println(); - } - public static void main(String[] args) { - PrimitiveOverloading p = - new PrimitiveOverloading(); - p.testConstVal(); - p.testChar(); - p.testByte(); - p.testShort(); - p.testInt(); - p.testLong(); - p.testFloat(); - p.testDouble(); - } -} -/* Output: -5: f1(int) f2(int) f3(int) f4(int) f5(long) f6(float) -f7(double) -char: f1(char) f2(int) f3(int) f4(int) f5(long) -f6(float) f7(double) -byte: f1(byte) f2(byte) f3(short) f4(int) f5(long) -f6(float) f7(double) -short: f1(short) f2(short) f3(short) f4(int) f5(long) -f6(float) f7(double) -int: f1(int) f2(int) f3(int) f4(int) f5(long) f6(float) -f7(double) -long: f1(long) f2(long) f3(long) f4(long) f5(long) -f6(float) f7(double) -float: f1(float) f2(float) f3(float) f4(float) -f5(float) f6(float) f7(double) -double: f1(double) f2(double) f3(double) f4(double) -f5(double) f6(double) f7(double) -*/ diff --git a/code/housekeeping/SimpleConstructor.java b/code/housekeeping/SimpleConstructor.java deleted file mode 100644 index c6917c33..00000000 --- a/code/housekeeping/SimpleConstructor.java +++ /dev/null @@ -1,21 +0,0 @@ -// housekeeping/SimpleConstructor.java -// (c)2020 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. -// Demonstration of a simple constructor - -class Rock { - Rock() { // This is the constructor - System.out.print("Rock "); - } -} - -public class SimpleConstructor { - public static void main(String[] args) { - for(int i = 0; i < 10; i++) - new Rock(); - } -} -/* Output: -Rock Rock Rock Rock Rock Rock Rock Rock Rock Rock -*/ diff --git a/code/housekeeping/SimpleConstructor2.java b/code/housekeeping/SimpleConstructor2.java deleted file mode 100644 index 4a191af7..00000000 --- a/code/housekeeping/SimpleConstructor2.java +++ /dev/null @@ -1,21 +0,0 @@ -// housekeeping/SimpleConstructor2.java -// (c)2020 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. -// Constructors can have arguments - -class Rock2 { - Rock2(int i) { - System.out.print("Rock " + i + " "); - } -} - -public class SimpleConstructor2 { - public static void main(String[] args) { - for(int i = 0; i < 8; i++) - new Rock2(i); - } -} -/* Output: -Rock 0 Rock 1 Rock 2 Rock 3 Rock 4 Rock 5 Rock 6 Rock 7 -*/ diff --git a/code/housekeeping/SimpleEnumUse.java b/code/housekeeping/SimpleEnumUse.java deleted file mode 100644 index cc0de33b..00000000 --- a/code/housekeeping/SimpleEnumUse.java +++ /dev/null @@ -1,14 +0,0 @@ -// housekeeping/SimpleEnumUse.java -// (c)2020 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. - -public class SimpleEnumUse { - public static void main(String[] args) { - Spiciness howHot = Spiciness.MEDIUM; - System.out.println(howHot); - } -} -/* Output: -MEDIUM -*/ diff --git a/code/housekeeping/Spiciness.java b/code/housekeeping/Spiciness.java deleted file mode 100644 index a134a822..00000000 --- a/code/housekeeping/Spiciness.java +++ /dev/null @@ -1,8 +0,0 @@ -// housekeeping/Spiciness.java -// (c)2020 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. - -public enum Spiciness { - NOT, MILD, MEDIUM, HOT, FLAMING -} diff --git a/code/housekeeping/Spoon.java b/code/housekeeping/Spoon.java deleted file mode 100644 index fd344815..00000000 --- a/code/housekeeping/Spoon.java +++ /dev/null @@ -1,10 +0,0 @@ -// housekeeping/Spoon.java -// (c)2020 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. -public class Spoon { - static int i; - static { - i = 47; - } -} diff --git a/code/housekeeping/StaticInitialization.java b/code/housekeeping/StaticInitialization.java deleted file mode 100644 index 0cfe99ae..00000000 --- a/code/housekeeping/StaticInitialization.java +++ /dev/null @@ -1,73 +0,0 @@ -// housekeeping/StaticInitialization.java -// (c)2020 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. -// Specifying initial values in a class definition - -class Bowl { - Bowl(int marker) { - System.out.println("Bowl(" + marker + ")"); - } - void f1(int marker) { - System.out.println("f1(" + marker + ")"); - } -} - -class Table { - static Bowl bowl1 = new Bowl(1); - Table() { - System.out.println("Table()"); - bowl2.f1(1); - } - void f2(int marker) { - System.out.println("f2(" + marker + ")"); - } - static Bowl bowl2 = new Bowl(2); -} - -class Cupboard { - Bowl bowl3 = new Bowl(3); - static Bowl bowl4 = new Bowl(4); - Cupboard() { - System.out.println("Cupboard()"); - bowl4.f1(2); - } - void f3(int marker) { - System.out.println("f3(" + marker + ")"); - } - static Bowl bowl5 = new Bowl(5); -} - -public class StaticInitialization { - public static void main(String[] args) { - System.out.println("main creating new Cupboard()"); - new Cupboard(); - System.out.println("main creating new Cupboard()"); - new Cupboard(); - table.f2(1); - cupboard.f3(1); - } - static Table table = new Table(); - static Cupboard cupboard = new Cupboard(); -} -/* Output: -Bowl(1) -Bowl(2) -Table() -f1(1) -Bowl(4) -Bowl(5) -Bowl(3) -Cupboard() -f1(2) -main creating new Cupboard() -Bowl(3) -Cupboard() -f1(2) -main creating new Cupboard() -Bowl(3) -Cupboard() -f1(2) -f2(1) -f3(1) -*/ diff --git a/code/housekeeping/TerminationCondition.java b/code/housekeeping/TerminationCondition.java deleted file mode 100644 index dc8d347b..00000000 --- a/code/housekeeping/TerminationCondition.java +++ /dev/null @@ -1,41 +0,0 @@ -// housekeeping/TerminationCondition.java -// (c)2020 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. -// Using finalize() to detect an object that -// hasn't been properly cleaned up -import onjava.*; - -class Book { - boolean checkedOut = false; - Book(boolean checkOut) { - checkedOut = checkOut; - } - void checkIn() { - checkedOut = false; - } - @SuppressWarnings("deprecation") - @Override - public void finalize() { - if(checkedOut) - System.out.println("Error: checked out"); - // Normally, you'll also do this: - // super.finalize(); // Call the base-class version - } -} - -public class TerminationCondition { - public static void main(String[] args) { - Book novel = new Book(true); - // Proper cleanup: - novel.checkIn(); - // Drop the reference, forget to clean up: - new Book(true); - // Force garbage collection & finalization: - System.gc(); - new Nap(1); // One second delay - } -} -/* Output: -Error: checked out -*/ diff --git a/code/housekeeping/VarArgs.java b/code/housekeeping/VarArgs.java deleted file mode 100644 index 73a94c39..00000000 --- a/code/housekeeping/VarArgs.java +++ /dev/null @@ -1,26 +0,0 @@ -// housekeeping/VarArgs.java -// (c)2020 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. -// Using array syntax to create variable argument lists - -class A {} - -public class VarArgs { - static void printArray(Object[] args) { - for(Object obj : args) - System.out.print(obj + " "); - System.out.println(); - } - public static void main(String[] args) { - printArray(new Object[]{ - 47, (float) 3.14, 11.11}); - printArray(new Object[]{"one", "two", "three" }); - printArray(new Object[]{new A(), new A(), new A()}); - } -} -/* Output: -47 3.14 11.11 -one two three -A@15db9742 A@6d06d69c A@7852e922 -*/ diff --git a/code/housekeeping/VarargType.java b/code/housekeeping/VarargType.java deleted file mode 100644 index 5b25b053..00000000 --- a/code/housekeeping/VarargType.java +++ /dev/null @@ -1,30 +0,0 @@ -// housekeeping/VarargType.java -// (c)2020 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. - -public class VarargType { - static void f(Character... args) { - System.out.print(args.getClass()); - System.out.println(" length " + args.length); - } - static void g(int... args) { - System.out.print(args.getClass()); - System.out.println(" length " + args.length); - } - public static void main(String[] args) { - f('a'); - f(); - g(1); - g(); - System.out.println("int[]: " + - new int[0].getClass()); - } -} -/* Output: -class [Ljava.lang.Character; length 1 -class [Ljava.lang.Character; length 0 -class [I length 1 -class [I length 0 -int[]: class [I -*/ diff --git a/code/innerclasses/AnonymousConstructor.java b/code/innerclasses/AnonymousConstructor.java deleted file mode 100644 index d8e08e7c..00000000 --- a/code/innerclasses/AnonymousConstructor.java +++ /dev/null @@ -1,34 +0,0 @@ -// innerclasses/AnonymousConstructor.java -// (c)2020 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. -// Creating a constructor for an anonymous inner class - -abstract class Base { - Base(int i) { - System.out.println("Base constructor, i = " + i); - } - public abstract void f(); -} - -public class AnonymousConstructor { - public static Base getBase(int i) { - return new Base(i) { - { System.out.println( - "Inside instance initializer"); } - @Override - public void f() { - System.out.println("In anonymous f()"); - } - }; - } - public static void main(String[] args) { - Base base = getBase(47); - base.f(); - } -} -/* Output: -Base constructor, i = 47 -Inside instance initializer -In anonymous f() -*/ diff --git a/code/innerclasses/BigEgg.java b/code/innerclasses/BigEgg.java deleted file mode 100644 index 7b2c3624..00000000 --- a/code/innerclasses/BigEgg.java +++ /dev/null @@ -1,33 +0,0 @@ -// innerclasses/BigEgg.java -// (c)2020 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. -// An inner class cannot be overridden like a method - -class Egg { - private Yolk y; - protected class Yolk { - public Yolk() { - System.out.println("Egg.Yolk()"); - } - } - Egg() { - System.out.println("New Egg()"); - y = new Yolk(); - } -} - -public class BigEgg extends Egg { - public class Yolk { - public Yolk() { - System.out.println("BigEgg.Yolk()"); - } - } - public static void main(String[] args) { - new BigEgg(); - } -} -/* Output: -New Egg() -Egg.Yolk() -*/ diff --git a/code/innerclasses/BigEgg2.java b/code/innerclasses/BigEgg2.java deleted file mode 100644 index 1631008d..00000000 --- a/code/innerclasses/BigEgg2.java +++ /dev/null @@ -1,44 +0,0 @@ -// innerclasses/BigEgg2.java -// (c)2020 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. -// Proper inheritance of an inner class - -class Egg2 { - protected class Yolk { - public Yolk() { - System.out.println("Egg2.Yolk()"); - } - public void f() { - System.out.println("Egg2.Yolk.f()"); - } - } - private Yolk y = new Yolk(); - Egg2() { System.out.println("New Egg2()"); } - public void insertYolk(Yolk yy) { y = yy; } - public void g() { y.f(); } -} - -public class BigEgg2 extends Egg2 { - public class Yolk extends Egg2.Yolk { - public Yolk() { - System.out.println("BigEgg2.Yolk()"); - } - @Override - public void f() { - System.out.println("BigEgg2.Yolk.f()"); - } - } - public BigEgg2() { insertYolk(new Yolk()); } - public static void main(String[] args) { - Egg2 e2 = new BigEgg2(); - e2.g(); - } -} -/* Output: -Egg2.Yolk() -New Egg2() -Egg2.Yolk() -BigEgg2.Yolk() -BigEgg2.Yolk.f() -*/ diff --git a/code/innerclasses/Callbacks.java b/code/innerclasses/Callbacks.java deleted file mode 100644 index d1659332..00000000 --- a/code/innerclasses/Callbacks.java +++ /dev/null @@ -1,84 +0,0 @@ -// innerclasses/Callbacks.java -// (c)2020 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. -// Using inner classes for callbacks -// {java innerclasses.Callbacks} -package innerclasses; - -interface Incrementable { - void increment(); -} - -// Very simple to just implement the interface: -class Callee1 implements Incrementable { - private int i = 0; - @Override - public void increment() { - i++; - System.out.println(i); - } -} - -class MyIncrement { - public void increment() { - System.out.println("Other operation"); - } - static void f(MyIncrement mi) { mi.increment(); } -} - -// If your class must implement increment() in -// some other way, you must use an inner class: -class Callee2 extends MyIncrement { - private int i = 0; - @Override - public void increment() { - super.increment(); - i++; - System.out.println(i); - } - private class Closure implements Incrementable { - @Override - public void increment() { - // Specify outer-class method, otherwise - // you'll get an infinite recursion: - Callee2.this.increment(); - } - } - Incrementable getCallbackReference() { - return new Closure(); - } -} - -class Caller { - private Incrementable callbackReference; - Caller(Incrementable cbh) { - callbackReference = cbh; - } - void go() { callbackReference.increment(); } -} - -public class Callbacks { - public static void main(String[] args) { - Callee1 c1 = new Callee1(); - Callee2 c2 = new Callee2(); - MyIncrement.f(c2); - Caller caller1 = new Caller(c1); - Caller caller2 = - new Caller(c2.getCallbackReference()); - caller1.go(); - caller1.go(); - caller2.go(); - caller2.go(); - } -} -/* Output: -Other operation -1 -1 -2 -Other operation -2 -Other operation -3 -*/ diff --git a/code/innerclasses/ClassInInterface.java b/code/innerclasses/ClassInInterface.java deleted file mode 100644 index c3cc0589..00000000 --- a/code/innerclasses/ClassInInterface.java +++ /dev/null @@ -1,21 +0,0 @@ -// innerclasses/ClassInInterface.java -// (c)2020 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. -// {java ClassInInterface$Test} - -public interface ClassInInterface { - void howdy(); - class Test implements ClassInInterface { - @Override - public void howdy() { - System.out.println("Howdy!"); - } - public static void main(String[] args) { - new Test().howdy(); - } - } -} -/* Output: -Howdy! -*/ diff --git a/code/innerclasses/Contents.java b/code/innerclasses/Contents.java deleted file mode 100644 index 0cebe1a0..00000000 --- a/code/innerclasses/Contents.java +++ /dev/null @@ -1,7 +0,0 @@ -// innerclasses/Contents.java -// (c)2020 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. -public interface Contents { - int value(); -} diff --git a/code/innerclasses/Destination.java b/code/innerclasses/Destination.java deleted file mode 100644 index bf221526..00000000 --- a/code/innerclasses/Destination.java +++ /dev/null @@ -1,7 +0,0 @@ -// innerclasses/Destination.java -// (c)2020 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. -public interface Destination { - String readLabel(); -} diff --git a/code/innerclasses/DotNew.java b/code/innerclasses/DotNew.java deleted file mode 100644 index 317400e8..00000000 --- a/code/innerclasses/DotNew.java +++ /dev/null @@ -1,13 +0,0 @@ -// innerclasses/DotNew.java -// (c)2020 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. -// Creating an inner class directly using .new syntax - -public class DotNew { - public class Inner {} - public static void main(String[] args) { - DotNew dn = new DotNew(); - DotNew.Inner dni = dn.new Inner(); - } -} diff --git a/code/innerclasses/DotThis.java b/code/innerclasses/DotThis.java deleted file mode 100644 index b87cb1f4..00000000 --- a/code/innerclasses/DotThis.java +++ /dev/null @@ -1,24 +0,0 @@ -// innerclasses/DotThis.java -// (c)2020 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. -// Accessing the outer-class object - -public class DotThis { - void f() { System.out.println("DotThis.f()"); } - public class Inner { - public DotThis outer() { - return DotThis.this; - // A plain "this" would be Inner's "this" - } - } - public Inner inner() { return new Inner(); } - public static void main(String[] args) { - DotThis dt = new DotThis(); - DotThis.Inner dti = dt.inner(); - dti.outer().f(); - } -} -/* Output: -DotThis.f() -*/ diff --git a/code/innerclasses/GreenhouseController.java b/code/innerclasses/GreenhouseController.java deleted file mode 100644 index cf3ec653..00000000 --- a/code/innerclasses/GreenhouseController.java +++ /dev/null @@ -1,54 +0,0 @@ -// innerclasses/GreenhouseController.java -// (c)2020 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. -// Configure and execute the greenhouse system -import innerclasses.controller.*; - -public class GreenhouseController { - public static void main(String[] args) { - GreenhouseControls gc = new GreenhouseControls(); - // Instead of using code, you could parse - // configuration information from a text file: - gc.addEvent(gc.new Bell(900)); - Event[] eventList = { - gc.new ThermostatNight(0), - gc.new LightOn(200), - gc.new LightOff(400), - gc.new WaterOn(600), - gc.new WaterOff(800), - gc.new ThermostatDay(1400) - }; - gc.addEvent(gc.new Restart(2000, eventList)); - gc.addEvent( - new GreenhouseControls.Terminate(5000)); - gc.run(); - } -} -/* Output: -Thermostat on night setting -Light is on -Light is off -Greenhouse water is on -Greenhouse water is off -Bing! -Thermostat on day setting -Bing! -Restarting system -Thermostat on night setting -Light is on -Light is off -Greenhouse water is on -Bing! -Greenhouse water is off -Thermostat on day setting -Bing! -Restarting system -Thermostat on night setting -Light is on -Light is off -Bing! -Greenhouse water is on -Greenhouse water is off -Terminating -*/ diff --git a/code/innerclasses/GreenhouseControls.java b/code/innerclasses/GreenhouseControls.java deleted file mode 100644 index 57458d66..00000000 --- a/code/innerclasses/GreenhouseControls.java +++ /dev/null @@ -1,150 +0,0 @@ -// innerclasses/GreenhouseControls.java -// (c)2020 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. -// This produces a specific application of the -// control system, all in a single class. Inner -// classes allow you to encapsulate different -// functionality for each type of event. -import innerclasses.controller.*; - -public class GreenhouseControls extends Controller { - private boolean light = false; - public class LightOn extends Event { - public LightOn(long delayTime) { - super(delayTime); - } - @Override - public void action() { - // Put hardware control code here to - // physically turn on the light. - light = true; - } - @Override - public String toString() { - return "Light is on"; - } - } - public class LightOff extends Event { - public LightOff(long delayTime) { - super(delayTime); - } - @Override - public void action() { - // Put hardware control code here to - // physically turn off the light. - light = false; - } - @Override - public String toString() { - return "Light is off"; - } - } - private boolean water = false; - public class WaterOn extends Event { - public WaterOn(long delayTime) { - super(delayTime); - } - @Override - public void action() { - // Put hardware control code here. - water = true; - } - @Override - public String toString() { - return "Greenhouse water is on"; - } - } - public class WaterOff extends Event { - public WaterOff(long delayTime) { - super(delayTime); - } - @Override - public void action() { - // Put hardware control code here. - water = false; - } - @Override - public String toString() { - return "Greenhouse water is off"; - } - } - private String thermostat = "Day"; - public class ThermostatNight extends Event { - public ThermostatNight(long delayTime) { - super(delayTime); - } - @Override - public void action() { - // Put hardware control code here. - thermostat = "Night"; - } - @Override - public String toString() { - return "Thermostat on night setting"; - } - } - public class ThermostatDay extends Event { - public ThermostatDay(long delayTime) { - super(delayTime); - } - @Override - public void action() { - // Put hardware control code here. - thermostat = "Day"; - } - @Override - public String toString() { - return "Thermostat on day setting"; - } - } - // An example of an action() that inserts a - // new one of itself into the event list: - public class Bell extends Event { - public Bell(long delayTime) { - super(delayTime); - } - @Override - public void action() { - addEvent(new Bell(delayTime.toMillis())); - } - @Override - public String toString() { - return "Bing!"; - } - } - public class Restart extends Event { - private Event[] eventList; - public - Restart(long delayTime, Event[] eventList) { - super(delayTime); - this.eventList = eventList; - for(Event e : eventList) - addEvent(e); - } - @Override - public void action() { - for(Event e : eventList) { - e.start(); // Rerun each event - addEvent(e); - } - start(); // Rerun this Event - addEvent(this); - } - @Override - public String toString() { - return "Restarting system"; - } - } - public static class Terminate extends Event { - public Terminate(long delayTime) { - super(delayTime); - } - @Override - public void action() { System.exit(0); } - @Override - public String toString() { - return "Terminating"; - } - } -} diff --git a/code/innerclasses/InheritInner.java b/code/innerclasses/InheritInner.java deleted file mode 100644 index ffc86894..00000000 --- a/code/innerclasses/InheritInner.java +++ /dev/null @@ -1,20 +0,0 @@ -// innerclasses/InheritInner.java -// (c)2020 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. -// Inheriting an inner class - -class WithInner { - class Inner {} -} - -public class InheritInner extends WithInner.Inner { - //- InheritInner() {} // Won't compile - InheritInner(WithInner wi) { - wi.super(); - } - public static void main(String[] args) { - WithInner wi = new WithInner(); - InheritInner ii = new InheritInner(wi); - } -} diff --git a/code/innerclasses/LocalInnerClass.java b/code/innerclasses/LocalInnerClass.java deleted file mode 100644 index 01510854..00000000 --- a/code/innerclasses/LocalInnerClass.java +++ /dev/null @@ -1,67 +0,0 @@ -// innerclasses/LocalInnerClass.java -// (c)2020 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. -// Holds a sequence of Objects - -interface Counter { - int next(); -} - -public class LocalInnerClass { - private int count = 0; - Counter getCounter(final String name) { - // A local inner class: - class LocalCounter implements Counter { - LocalCounter() { - // Local inner class can have a constructor - System.out.println("LocalCounter()"); - } - @Override - public int next() { - System.out.print(name); // Access local final - return count++; - } - } - return new LocalCounter(); - } - // Repeat, but with an anonymous inner class: - Counter getCounter2(final String name) { - return new Counter() { - // Anonymous inner class cannot have a named - // constructor, only an instance initializer: - { - System.out.println("Counter()"); - } - @Override - public int next() { - System.out.print(name); // Access local final - return count++; - } - }; - } - public static void main(String[] args) { - LocalInnerClass lic = new LocalInnerClass(); - Counter - c1 = lic.getCounter("Local inner "), - c2 = lic.getCounter2("Anonymous inner "); - for(int i = 0; i < 5; i++) - System.out.println(c1.next()); - for(int i = 0; i < 5; i++) - System.out.println(c2.next()); - } -} -/* Output: -LocalCounter() -Counter() -Local inner 0 -Local inner 1 -Local inner 2 -Local inner 3 -Local inner 4 -Anonymous inner 5 -Anonymous inner 6 -Anonymous inner 7 -Anonymous inner 8 -Anonymous inner 9 -*/ diff --git a/code/innerclasses/MultiImplementation.java b/code/innerclasses/MultiImplementation.java deleted file mode 100644 index 6eb6c494..00000000 --- a/code/innerclasses/MultiImplementation.java +++ /dev/null @@ -1,25 +0,0 @@ -// innerclasses/MultiImplementation.java -// (c)2020 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. -// For concrete or abstract classes, inner classes -// produce "multiple implementation inheritance" -// {java innerclasses.MultiImplementation} -package innerclasses; - -class D {} -abstract class E {} - -class Z extends D { - E makeE() { return new E() {}; } -} - -public class MultiImplementation { - static void takesD(D d) {} - static void takesE(E e) {} - public static void main(String[] args) { - Z z = new Z(); - takesD(z); - takesE(z.makeE()); - } -} diff --git a/code/innerclasses/MultiNestingAccess.java b/code/innerclasses/MultiNestingAccess.java deleted file mode 100644 index bf9e3cb0..00000000 --- a/code/innerclasses/MultiNestingAccess.java +++ /dev/null @@ -1,28 +0,0 @@ -// innerclasses/MultiNestingAccess.java -// (c)2020 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. -// Nested classes can access all members of all -// levels of the classes they are nested within - -class MNA { - private void f() {} - class A { - private void g() {} - public class B { - void h() { - g(); - f(); - } - } - } -} - -public class MultiNestingAccess { - public static void main(String[] args) { - MNA mna = new MNA(); - MNA.A mnaa = mna.new A(); - MNA.A.B mnaab = mnaa.new B(); - mnaab.h(); - } -} diff --git a/code/innerclasses/Parcel1.java b/code/innerclasses/Parcel1.java deleted file mode 100644 index 94464cbc..00000000 --- a/code/innerclasses/Parcel1.java +++ /dev/null @@ -1,33 +0,0 @@ -// innerclasses/Parcel1.java -// (c)2020 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. -// Creating inner classes - -public class Parcel1 { - class Contents { - private int i = 11; - public int value() { return i; } - } - class Destination { - private String label; - Destination(String whereTo) { - label = whereTo; - } - String readLabel() { return label; } - } - // Using inner classes looks just like - // using any other class, within Parcel1: - public void ship(String dest) { - Contents c = new Contents(); - Destination d = new Destination(dest); - System.out.println(d.readLabel()); - } - public static void main(String[] args) { - Parcel1 p = new Parcel1(); - p.ship("Tasmania"); - } -} -/* Output: -Tasmania -*/ diff --git a/code/innerclasses/Parcel10.java b/code/innerclasses/Parcel10.java deleted file mode 100644 index 7150c192..00000000 --- a/code/innerclasses/Parcel10.java +++ /dev/null @@ -1,31 +0,0 @@ -// innerclasses/Parcel10.java -// (c)2020 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. -// Using "instance initialization" to perform -// construction on an anonymous inner class - -public class Parcel10 { - public Destination - destination(final String dest, final float price) { - return new Destination() { - private int cost; - // Instance initialization for each object: - { - cost = Math.round(price); - if(cost > 100) - System.out.println("Over budget!"); - } - private String label = dest; - @Override - public String readLabel() { return label; } - }; - } - public static void main(String[] args) { - Parcel10 p = new Parcel10(); - Destination d = p.destination("Tasmania", 101.395F); - } -} -/* Output: -Over budget! -*/ diff --git a/code/innerclasses/Parcel11.java b/code/innerclasses/Parcel11.java deleted file mode 100644 index 720981f0..00000000 --- a/code/innerclasses/Parcel11.java +++ /dev/null @@ -1,40 +0,0 @@ -// innerclasses/Parcel11.java -// (c)2020 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. -// Nested classes (static inner classes) - -public class Parcel11 { - private static class - ParcelContents implements Contents { - private int i = 11; - @Override - public int value() { return i; } - } - protected static final class ParcelDestination - implements Destination { - private String label; - private ParcelDestination(String whereTo) { - label = whereTo; - } - @Override - public String readLabel() { return label; } - // Nested classes can contain other static elements: - public static void f() {} - static int x = 10; - static class AnotherLevel { - public static void f() {} - static int x = 10; - } - } - public static Destination destination(String s) { - return new ParcelDestination(s); - } - public static Contents contents() { - return new ParcelContents(); - } - public static void main(String[] args) { - Contents c = contents(); - Destination d = destination("Tasmania"); - } -} diff --git a/code/innerclasses/Parcel2.java b/code/innerclasses/Parcel2.java deleted file mode 100644 index 1eca5cba..00000000 --- a/code/innerclasses/Parcel2.java +++ /dev/null @@ -1,41 +0,0 @@ -// innerclasses/Parcel2.java -// (c)2020 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. -// Returning a reference to an inner class - -public class Parcel2 { - class Contents { - private int i = 11; - public int value() { return i; } - } - class Destination { - private String label; - Destination(String whereTo) { - label = whereTo; - } - String readLabel() { return label; } - } - public Destination to(String s) { - return new Destination(s); - } - public Contents contents() { - return new Contents(); - } - public void ship(String dest) { - Contents c = contents(); - Destination d = to(dest); - System.out.println(d.readLabel()); - } - public static void main(String[] args) { - Parcel2 p = new Parcel2(); - p.ship("Tasmania"); - Parcel2 q = new Parcel2(); - // Defining references to inner classes: - Parcel2.Contents c = q.contents(); - Parcel2.Destination d = q.to("Borneo"); - } -} -/* Output: -Tasmania -*/ diff --git a/code/innerclasses/Parcel3.java b/code/innerclasses/Parcel3.java deleted file mode 100644 index 2e0733e0..00000000 --- a/code/innerclasses/Parcel3.java +++ /dev/null @@ -1,25 +0,0 @@ -// innerclasses/Parcel3.java -// (c)2020 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. -// Using .new to create instances of inner classes - -public class Parcel3 { - class Contents { - private int i = 11; - public int value() { return i; } - } - class Destination { - private String label; - Destination(String whereTo) { label = whereTo; } - String readLabel() { return label; } - } - public static void main(String[] args) { - Parcel3 p = new Parcel3(); - // Must use instance of outer class - // to create an instance of the inner class: - Parcel3.Contents c = p.new Contents(); - Parcel3.Destination d = - p.new Destination("Tasmania"); - } -} diff --git a/code/innerclasses/Parcel5.java b/code/innerclasses/Parcel5.java deleted file mode 100644 index 622b3fd0..00000000 --- a/code/innerclasses/Parcel5.java +++ /dev/null @@ -1,23 +0,0 @@ -// innerclasses/Parcel5.java -// (c)2020 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. -// Nesting a class within a method - -public class Parcel5 { - public Destination destination(String s) { - final class PDestination implements Destination { - private String label; - private PDestination(String whereTo) { - label = whereTo; - } - @Override - public String readLabel() { return label; } - } - return new PDestination(s); - } - public static void main(String[] args) { - Parcel5 p = new Parcel5(); - Destination d = p.destination("Tasmania"); - } -} diff --git a/code/innerclasses/Parcel6.java b/code/innerclasses/Parcel6.java deleted file mode 100644 index 7a2c866e..00000000 --- a/code/innerclasses/Parcel6.java +++ /dev/null @@ -1,28 +0,0 @@ -// innerclasses/Parcel6.java -// (c)2020 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. -// Nesting a class within a scope - -public class Parcel6 { - private void internalTracking(boolean b) { - if(b) { - class TrackingSlip { - private String id; - TrackingSlip(String s) { - id = s; - } - String getSlip() { return id; } - } - TrackingSlip ts = new TrackingSlip("slip"); - String s = ts.getSlip(); - } - // Can't use it here! Out of scope: - //- TrackingSlip ts = new TrackingSlip("x"); - } - public void track() { internalTracking(true); } - public static void main(String[] args) { - Parcel6 p = new Parcel6(); - p.track(); - } -} diff --git a/code/innerclasses/Parcel7.java b/code/innerclasses/Parcel7.java deleted file mode 100644 index 3a4aefbb..00000000 --- a/code/innerclasses/Parcel7.java +++ /dev/null @@ -1,19 +0,0 @@ -// innerclasses/Parcel7.java -// (c)2020 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. -// Returning an instance of an anonymous inner class - -public class Parcel7 { - public Contents contents() { - return new Contents() { // Insert class definition - private int i = 11; - @Override - public int value() { return i; } - }; // Semicolon required - } - public static void main(String[] args) { - Parcel7 p = new Parcel7(); - Contents c = p.contents(); - } -} diff --git a/code/innerclasses/Parcel7b.java b/code/innerclasses/Parcel7b.java deleted file mode 100644 index bee95727..00000000 --- a/code/innerclasses/Parcel7b.java +++ /dev/null @@ -1,20 +0,0 @@ -// innerclasses/Parcel7b.java -// (c)2020 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. -// Expanded version of Parcel7.java - -public class Parcel7b { - class MyContents implements Contents { - private int i = 11; - @Override - public int value() { return i; } - } - public Contents contents() { - return new MyContents(); - } - public static void main(String[] args) { - Parcel7b p = new Parcel7b(); - Contents c = p.contents(); - } -} diff --git a/code/innerclasses/Parcel8.java b/code/innerclasses/Parcel8.java deleted file mode 100644 index 1e615ac5..00000000 --- a/code/innerclasses/Parcel8.java +++ /dev/null @@ -1,21 +0,0 @@ -// innerclasses/Parcel8.java -// (c)2020 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. -// Calling the base-class constructor - -public class Parcel8 { - public Wrapping wrapping(int x) { - // Base constructor call: - return new Wrapping(x) { // [1] - @Override - public int value() { - return super.value() * 47; - } - }; // [2] - } - public static void main(String[] args) { - Parcel8 p = new Parcel8(); - Wrapping w = p.wrapping(10); - } -} diff --git a/code/innerclasses/Parcel9.java b/code/innerclasses/Parcel9.java deleted file mode 100644 index 775390f1..00000000 --- a/code/innerclasses/Parcel9.java +++ /dev/null @@ -1,20 +0,0 @@ -// innerclasses/Parcel9.java -// (c)2020 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. - -public class Parcel9 { - // Argument must be final or "effectively final" - // to use within the anonymous inner class: - public Destination destination(final String dest) { - return new Destination() { - private String label = dest; - @Override - public String readLabel() { return label; } - }; - } - public static void main(String[] args) { - Parcel9 p = new Parcel9(); - Destination d = p.destination("Tasmania"); - } -} diff --git a/code/innerclasses/Sequence.java b/code/innerclasses/Sequence.java deleted file mode 100644 index b5a870b9..00000000 --- a/code/innerclasses/Sequence.java +++ /dev/null @@ -1,48 +0,0 @@ -// innerclasses/Sequence.java -// (c)2020 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. -// Holds a sequence of Objects - -interface Selector { - boolean end(); - Object current(); - void next(); -} - -public class Sequence { - private Object[] items; - private int next = 0; - public Sequence(int size) { - items = new Object[size]; - } - public void add(Object x) { - if(next < items.length) - items[next++] = x; - } - private class SequenceSelector implements Selector { - private int i = 0; - @Override - public boolean end() { return i == items.length; } - @Override - public Object current() { return items[i]; } - @Override - public void next() { if(i < items.length) i++; } - } - public Selector selector() { - return new SequenceSelector(); - } - public static void main(String[] args) { - Sequence sequence = new Sequence(10); - for(int i = 0; i < 10; i++) - sequence.add(Integer.toString(i)); - Selector selector = sequence.selector(); - while(!selector.end()) { - System.out.print(selector.current() + " "); - selector.next(); - } - } -} -/* Output: -0 1 2 3 4 5 6 7 8 9 -*/ diff --git a/code/innerclasses/TestBed.java b/code/innerclasses/TestBed.java deleted file mode 100644 index d4bc16dd..00000000 --- a/code/innerclasses/TestBed.java +++ /dev/null @@ -1,19 +0,0 @@ -// innerclasses/TestBed.java -// (c)2020 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. -// Putting test code in a nested class -// {java TestBed$Tester} - -public class TestBed { - public void f() { System.out.println("f()"); } - public static class Tester { - public static void main(String[] args) { - TestBed t = new TestBed(); - t.f(); - } - } -} -/* Output: -f() -*/ diff --git a/code/innerclasses/TestParcel.java b/code/innerclasses/TestParcel.java deleted file mode 100644 index f1ec5d47..00000000 --- a/code/innerclasses/TestParcel.java +++ /dev/null @@ -1,37 +0,0 @@ -// innerclasses/TestParcel.java -// (c)2020 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. - -class Parcel4 { - private class PContents implements Contents { - private int i = 11; - @Override - public int value() { return i; } - } - protected final class - PDestination implements Destination { - private String label; - private PDestination(String whereTo) { - label = whereTo; - } - @Override - public String readLabel() { return label; } - } - public Destination destination(String s) { - return new PDestination(s); - } - public Contents contents() { - return new PContents(); - } -} - -public class TestParcel { - public static void main(String[] args) { - Parcel4 p = new Parcel4(); - Contents c = p.contents(); - Destination d = p.destination("Tasmania"); - // Illegal -- can't access private class: - //- Parcel4.PContents pc = p.new PContents(); - } -} diff --git a/code/innerclasses/Wrapping.java b/code/innerclasses/Wrapping.java deleted file mode 100644 index 651c0748..00000000 --- a/code/innerclasses/Wrapping.java +++ /dev/null @@ -1,9 +0,0 @@ -// innerclasses/Wrapping.java -// (c)2020 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. -public class Wrapping { - private int i; - public Wrapping(int x) { i = x; } - public int value() { return i; } -} diff --git a/code/innerclasses/controller/Controller.java b/code/innerclasses/controller/Controller.java deleted file mode 100644 index 9a3625b3..00000000 --- a/code/innerclasses/controller/Controller.java +++ /dev/null @@ -1,24 +0,0 @@ -// innerclasses/controller/Controller.java -// (c)2020 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. -// The reusable framework for control systems -package innerclasses.controller; -import java.util.*; - -public class Controller { - // A class from java.util to hold Event objects: - private List eventList = new ArrayList<>(); - public void addEvent(Event c) { eventList.add(c); } - public void run() { - while(eventList.size() > 0) - // Make a copy so you're not modifying the list - // while you're selecting the elements in it: - for(Event e : new ArrayList<>(eventList)) - if(e.ready()) { - System.out.println(e); - e.action(); - eventList.remove(e); - } - } -} diff --git a/code/innerclasses/controller/Event.java b/code/innerclasses/controller/Event.java deleted file mode 100644 index 5523168f..00000000 --- a/code/innerclasses/controller/Event.java +++ /dev/null @@ -1,23 +0,0 @@ -// innerclasses/controller/Event.java -// (c)2020 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. -// The common methods for any control event -package innerclasses.controller; -import java.time.*; // Java 8 time classes - -public abstract class Event { - private Instant eventTime; - protected final Duration delayTime; - public Event(long millisecondDelay) { - delayTime = Duration.ofMillis(millisecondDelay); - start(); - } - public void start() { // Allows restarting - eventTime = Instant.now().plus(delayTime); - } - public boolean ready() { - return Instant.now().isAfter(eventTime); - } - public abstract void action(); -} diff --git a/code/innerclasses/mui/MultiInterfaces.java b/code/innerclasses/mui/MultiInterfaces.java deleted file mode 100644 index 127a6c80..00000000 --- a/code/innerclasses/mui/MultiInterfaces.java +++ /dev/null @@ -1,32 +0,0 @@ -// innerclasses/mui/MultiInterfaces.java -// (c)2020 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. -// Two ways a class can implement multiple interfaces -// {java innerclasses.mui.MultiInterfaces} -package innerclasses.mui; - -interface A {} -interface B {} - -class X implements A, B {} - -class Y implements A { - B makeB() { - // Anonymous inner class: - return new B() {}; - } -} - -public class MultiInterfaces { - static void takesA(A a) {} - static void takesB(B b) {} - public static void main(String[] args) { - X x = new X(); - Y y = new Y(); - takesA(x); - takesA(y); - takesB(x); - takesB(y.makeB()); - } -} diff --git a/code/interfaces/AbstractAccess.java b/code/interfaces/AbstractAccess.java deleted file mode 100644 index c2e43da3..00000000 --- a/code/interfaces/AbstractAccess.java +++ /dev/null @@ -1,15 +0,0 @@ -// interfaces/AbstractAccess.java -// (c)2020 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. - -abstract class AbstractAccess { - private void m1() {} - // private abstract void m1a(); // illegal - protected void m2() {} - protected abstract void m2a(); - void m3() {} - abstract void m3a(); - public void m4() {} - public abstract void m4a(); -} diff --git a/code/interfaces/AbstractWithoutAbstracts.java b/code/interfaces/AbstractWithoutAbstracts.java deleted file mode 100644 index 2e6b700c..00000000 --- a/code/interfaces/AbstractWithoutAbstracts.java +++ /dev/null @@ -1,14 +0,0 @@ -// interfaces/AbstractWithoutAbstracts.java -// (c)2020 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. - -abstract class Basic3 { - int f() { return 111; } - // No abstract methods -} - -public class AbstractWithoutAbstracts { - // Basic3 b3 = new Basic3(); - // error: Basic3 is abstract; cannot be instantiated -} diff --git a/code/interfaces/AdaptedRandomDoubles.java b/code/interfaces/AdaptedRandomDoubles.java deleted file mode 100644 index 6c786655..00000000 --- a/code/interfaces/AdaptedRandomDoubles.java +++ /dev/null @@ -1,35 +0,0 @@ -// interfaces/AdaptedRandomDoubles.java -// (c)2020 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. -// Creating an adapter with inheritance -import java.nio.*; -import java.util.*; - -public class AdaptedRandomDoubles -implements RandomDoubles, Readable { - private int count; - public AdaptedRandomDoubles(int count) { - this.count = count; - } - @Override - public int read(CharBuffer cb) { - if(count-- == 0) - return -1; - String result = Double.toString(next()) + " "; - cb.append(result); - return result.length(); - } - public static void main(String[] args) { - Scanner s = - new Scanner(new AdaptedRandomDoubles(7)); - while(s.hasNextDouble()) - System.out.print(s.nextDouble() + " "); - } -} -/* Output: -0.7271157860730044 0.5309454508634242 -0.16020656493302599 0.18847866977771732 -0.5166020801268457 0.2678662084200585 -0.2613610344283964 -*/ diff --git a/code/interfaces/Adventure.java b/code/interfaces/Adventure.java deleted file mode 100644 index 1a7135d1..00000000 --- a/code/interfaces/Adventure.java +++ /dev/null @@ -1,41 +0,0 @@ -// interfaces/Adventure.java -// (c)2020 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. -// Multiple interfaces - -interface CanFight { - void fight(); -} - -interface CanSwim { - void swim(); -} - -interface CanFly { - void fly(); -} - -class ActionCharacter { - public void fight() {} -} - -class Hero extends ActionCharacter - implements CanFight, CanSwim, CanFly { - public void swim() {} - public void fly() {} -} - -public class Adventure { - public static void t(CanFight x) { x.fight(); } - public static void u(CanSwim x) { x.swim(); } - public static void v(CanFly x) { x.fly(); } - public static void w(ActionCharacter x) { x.fight(); } - public static void main(String[] args) { - Hero h = new Hero(); - t(h); // Treat it as a CanFight - u(h); // Treat it as a CanSwim - v(h); // Treat it as a CanFly - w(h); // Treat it as an ActionCharacter - } -} diff --git a/code/interfaces/AnImplementation.java b/code/interfaces/AnImplementation.java deleted file mode 100644 index 3ff13a30..00000000 --- a/code/interfaces/AnImplementation.java +++ /dev/null @@ -1,22 +0,0 @@ -// interfaces/AnImplementation.java -// (c)2020 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. - -public class AnImplementation implements AnInterface { - public void firstMethod() { - System.out.println("firstMethod"); - } - public void secondMethod() { - System.out.println("secondMethod"); - } - public static void main(String[] args) { - AnInterface i = new AnImplementation(); - i.firstMethod(); - i.secondMethod(); - } -} -/* Output: -firstMethod -secondMethod -*/ diff --git a/code/interfaces/AnInterface.java b/code/interfaces/AnInterface.java deleted file mode 100644 index 30f82b3a..00000000 --- a/code/interfaces/AnInterface.java +++ /dev/null @@ -1,9 +0,0 @@ -// interfaces/AnInterface.java -// (c)2020 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. - -interface AnInterface { - void firstMethod(); - void secondMethod(); -} diff --git a/code/interfaces/Applicator.java b/code/interfaces/Applicator.java deleted file mode 100644 index a6aa172f..00000000 --- a/code/interfaces/Applicator.java +++ /dev/null @@ -1,58 +0,0 @@ -// interfaces/Applicator.java -// (c)2020 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. -import java.util.*; - -class Processor { - public String name() { - return getClass().getSimpleName(); - } - public Object process(Object input) { - return input; - } -} - -class Upcase extends Processor { - @Override // Covariant return: - public String process(Object input) { - return ((String)input).toUpperCase(); - } -} - -class Downcase extends Processor { - @Override - public String process(Object input) { - return ((String)input).toLowerCase(); - } -} - -class Splitter extends Processor { - @Override - public String process(Object input) { - // split() divides a String into pieces: - return Arrays.toString(((String)input).split(" ")); - } -} - -public class Applicator { - public static void apply(Processor p, Object s) { - System.out.println("Using Processor " + p.name()); - System.out.println(p.process(s)); - } - public static void main(String[] args) { - String s = - "We are such stuff as dreams are made on"; - apply(new Upcase(), s); - apply(new Downcase(), s); - apply(new Splitter(), s); - } -} -/* Output: -Using Processor Upcase -WE ARE SUCH STUFF AS DREAMS ARE MADE ON -Using Processor Downcase -we are such stuff as dreams are made on -Using Processor Splitter -[We, are, such, stuff, as, dreams, are, made, on] -*/ diff --git a/code/interfaces/AttemptToUseBasic.java b/code/interfaces/AttemptToUseBasic.java deleted file mode 100644 index 0d265527..00000000 --- a/code/interfaces/AttemptToUseBasic.java +++ /dev/null @@ -1,10 +0,0 @@ -// interfaces/AttemptToUseBasic.java -// (c)2020 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. -// {WillNotCompile} - -public class AttemptToUseBasic { - Basic b = new Basic(); - // error: Basic is abstract; cannot be instantiated -} diff --git a/code/interfaces/Basic.java b/code/interfaces/Basic.java deleted file mode 100644 index 19c1c75b..00000000 --- a/code/interfaces/Basic.java +++ /dev/null @@ -1,8 +0,0 @@ -// interfaces/Basic.java -// (c)2020 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. - -abstract class Basic { - abstract void unimplemented(); -} diff --git a/code/interfaces/Basic2.java b/code/interfaces/Basic2.java deleted file mode 100644 index 4c8f0c93..00000000 --- a/code/interfaces/Basic2.java +++ /dev/null @@ -1,10 +0,0 @@ -// interfaces/Basic2.java -// (c)2020 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. - -abstract class Basic2 extends Basic { - int f() { return 111; } - abstract void g(); - // unimplemented() still not implemented -} diff --git a/code/interfaces/Factories.java b/code/interfaces/Factories.java deleted file mode 100644 index 87e28251..00000000 --- a/code/interfaces/Factories.java +++ /dev/null @@ -1,67 +0,0 @@ -// interfaces/Factories.java -// (c)2020 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. - -interface Service { - void method1(); - void method2(); -} - -interface ServiceFactory { - Service getService(); -} - -class Service1 implements Service { - Service1() {} // Package access - public void method1() { - System.out.println("Service1 method1"); - } - public void method2() { - System.out.println("Service1 method2"); - } -} - -class Service1Factory implements ServiceFactory { - @Override - public Service getService() { - return new Service1(); - } -} - -class Service2 implements Service { - Service2() {} // Package access - public void method1() { - System.out.println("Service2 method1"); - } - public void method2() { - System.out.println("Service2 method2"); - } -} - -class Service2Factory implements ServiceFactory { - @Override - public Service getService() { - return new Service2(); - } -} - -public class Factories { - public static void - serviceConsumer(ServiceFactory fact) { - Service s = fact.getService(); - s.method1(); - s.method2(); - } - public static void main(String[] args) { - serviceConsumer(new Service1Factory()); - // Services are completely interchangeable: - serviceConsumer(new Service2Factory()); - } -} -/* Output: -Service1 method1 -Service1 method2 -Service2 method1 -Service2 method2 -*/ diff --git a/code/interfaces/Games.java b/code/interfaces/Games.java deleted file mode 100644 index 867efe0c..00000000 --- a/code/interfaces/Games.java +++ /dev/null @@ -1,59 +0,0 @@ -// interfaces/Games.java -// (c)2020 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. -// A Game framework using Factory Methods - -interface Game { boolean move(); } -interface GameFactory { Game getGame(); } - -class Checkers implements Game { - private int moves = 0; - private static final int MOVES = 3; - @Override - public boolean move() { - System.out.println("Checkers move " + moves); - return ++moves != MOVES; - } -} - -class CheckersFactory implements GameFactory { - @Override - public Game getGame() { return new Checkers(); } -} - -class Chess implements Game { - private int moves = 0; - private static final int MOVES = 4; - @Override - public boolean move() { - System.out.println("Chess move " + moves); - return ++moves != MOVES; - } -} - -class ChessFactory implements GameFactory { - @Override - public Game getGame() { return new Chess(); } -} - -public class Games { - public static void playGame(GameFactory factory) { - Game s = factory.getGame(); - while(s.move()) - ; - } - public static void main(String[] args) { - playGame(new CheckersFactory()); - playGame(new ChessFactory()); - } -} -/* Output: -Checkers move 0 -Checkers move 1 -Checkers move 2 -Chess move 0 -Chess move 1 -Chess move 2 -Chess move 3 -*/ diff --git a/code/interfaces/HorrorShow.java b/code/interfaces/HorrorShow.java deleted file mode 100644 index b1c687da..00000000 --- a/code/interfaces/HorrorShow.java +++ /dev/null @@ -1,57 +0,0 @@ -// interfaces/HorrorShow.java -// (c)2020 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. -// Extending an interface with inheritance - -interface Monster { - void menace(); -} - -interface DangerousMonster extends Monster { - void destroy(); -} - -interface Lethal { - void kill(); -} - -class DragonZilla implements DangerousMonster { - @Override - public void menace() {} - @Override - public void destroy() {} -} - -interface Vampire extends DangerousMonster, Lethal { - void drinkBlood(); -} - -class VeryBadVampire implements Vampire { - @Override - public void menace() {} - @Override - public void destroy() {} - @Override - public void kill() {} - @Override - public void drinkBlood() {} -} - -public class HorrorShow { - static void u(Monster b) { b.menace(); } - static void v(DangerousMonster d) { - d.menace(); - d.destroy(); - } - static void w(Lethal l) { l.kill(); } - public static void main(String[] args) { - DangerousMonster barney = new DragonZilla(); - u(barney); - v(barney); - Vampire vlad = new VeryBadVampire(); - u(vlad); - v(vlad); - w(vlad); - } -} diff --git a/code/interfaces/Implementation2.java b/code/interfaces/Implementation2.java deleted file mode 100644 index 61c6efa0..00000000 --- a/code/interfaces/Implementation2.java +++ /dev/null @@ -1,26 +0,0 @@ -// interfaces/Implementation2.java -// (c)2020 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. - -public class Implementation2 -implements InterfaceWithDefault { - public void firstMethod() { - System.out.println("firstMethod"); - } - public void secondMethod() { - System.out.println("secondMethod"); - } - public static void main(String[] args) { - InterfaceWithDefault i = - new Implementation2(); - i.firstMethod(); - i.secondMethod(); - i.newMethod(); - } -} -/* Output: -firstMethod -secondMethod -newMethod -*/ diff --git a/code/interfaces/ImplementingAnInterface.java b/code/interfaces/ImplementingAnInterface.java deleted file mode 100644 index 6a13ebb6..00000000 --- a/code/interfaces/ImplementingAnInterface.java +++ /dev/null @@ -1,14 +0,0 @@ -// interfaces/ImplementingAnInterface.java -// (c)2020 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. - -interface Concept { // Package access - void idea1(); - void idea2(); -} - -class Implementation implements Concept { - public void idea1() { System.out.println("idea1"); } - public void idea2() { System.out.println("idea2"); } -} diff --git a/code/interfaces/Instantiable.java b/code/interfaces/Instantiable.java deleted file mode 100644 index 427b6ca3..00000000 --- a/code/interfaces/Instantiable.java +++ /dev/null @@ -1,19 +0,0 @@ -// interfaces/Instantiable.java -// (c)2020 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. - -abstract class Uninstantiable { - abstract void f(); - abstract int g(); -} - -public class Instantiable extends Uninstantiable { - @Override - void f() { System.out.println("f()"); } - @Override - int g() { return 22; } - public static void main(String[] args) { - Uninstantiable ui = new Instantiable(); - } -} diff --git a/code/interfaces/InterfaceCollision.java b/code/interfaces/InterfaceCollision.java deleted file mode 100644 index 0f7de1ac..00000000 --- a/code/interfaces/InterfaceCollision.java +++ /dev/null @@ -1,31 +0,0 @@ -// interfaces/InterfaceCollision.java -// (c)2020 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. - -interface I1 { void f(); } -interface I2 { int f(int i); } -interface I3 { int f(); } -class C { public int f() { return 1; } } - -class C2 implements I1, I2 { - @Override - public void f() {} - @Override - public int f(int i) { return 1; } // overloaded -} - -class C3 extends C implements I2 { - @Override - public int f(int i) { return 1; } // overloaded -} - -class C4 extends C implements I3 { - // Identical, no problem: - @Override - public int f() { return 1; } -} - -// Methods differ only by return type: -//- class C5 extends C implements I1 {} -//- interface I4 extends I1, I3 {} diff --git a/code/interfaces/InterfaceWithDefault.java b/code/interfaces/InterfaceWithDefault.java deleted file mode 100644 index a87f02db..00000000 --- a/code/interfaces/InterfaceWithDefault.java +++ /dev/null @@ -1,12 +0,0 @@ -// interfaces/InterfaceWithDefault.java -// (c)2020 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. - -interface InterfaceWithDefault { - void firstMethod(); - void secondMethod(); - default void newMethod() { - System.out.println("newMethod"); - } -} diff --git a/code/interfaces/Jim.java b/code/interfaces/Jim.java deleted file mode 100644 index 515db6e5..00000000 --- a/code/interfaces/Jim.java +++ /dev/null @@ -1,28 +0,0 @@ -// interfaces/Jim.java -// (c)2020 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. -import java.util.*; - -interface Jim1 { - default void jim() { - System.out.println("Jim1::jim"); - } -} - -interface Jim2 { - default void jim() { - System.out.println("Jim2::jim"); - } -} - -public class Jim implements Jim1, Jim2 { - @Override - public void jim() { Jim2.super.jim(); } - public static void main(String[] args) { - new Jim().jim(); - } -} -/* Output: -Jim2::jim -*/ diff --git a/code/interfaces/MICollision.java b/code/interfaces/MICollision.java deleted file mode 100644 index c96e5696..00000000 --- a/code/interfaces/MICollision.java +++ /dev/null @@ -1,60 +0,0 @@ -// interfaces/MICollision.java -// (c)2020 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. -import java.util.*; - -interface Bob1 { - default void bob() { - System.out.println("Bob1::bob"); - } -} - -interface Bob2 { - default void bob() { - System.out.println("Bob2::bob"); - } -} - -// class Bob implements Bob1, Bob2 {} -/* Produces: -error: class Bob inherits unrelated defaults -for bob() from types Bob1 and Bob2 -class Bob implements Bob1, Bob2 {} -^ -1 error -*/ - -interface Sam1 { - default void sam() { - System.out.println("Sam1::sam"); - } -} - -interface Sam2 { - default void sam(int i) { - System.out.println(i * 2); - } -} - -// This works because the argument lists are distinct: -class Sam implements Sam1, Sam2 {} - -interface Max1 { - default void max() { - System.out.println("Max1::max"); - } -} - -interface Max2 { - default int max() { return 47; } -} - -// class Max implements Max1, Max2 {} -/* Produces: -error: types Max2 and Max1 are incompatible; -both define max(), but with unrelated return types -class Max implements Max1, Max2 {} -^ -1 error -*/ diff --git a/code/interfaces/Machine.java b/code/interfaces/Machine.java deleted file mode 100644 index 2b1144ae..00000000 --- a/code/interfaces/Machine.java +++ /dev/null @@ -1,36 +0,0 @@ -// interfaces/Machine.java -// (c)2020 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. -import java.util.*; -import onjava.Operations; - -class Bing implements Operations { - public void execute() { - Operations.show("Bing"); - } -} - -class Crack implements Operations { - public void execute() { - Operations.show("Crack"); - } -} - -class Twist implements Operations { - public void execute() { - Operations.show("Twist"); - } -} - -public class Machine { - public static void main(String[] args) { - Operations.runOps( - new Bing(), new Crack(), new Twist()); - } -} -/* Output: -Bing -Crack -Twist -*/ diff --git a/code/interfaces/Months.java b/code/interfaces/Months.java deleted file mode 100644 index 27317dd5..00000000 --- a/code/interfaces/Months.java +++ /dev/null @@ -1,13 +0,0 @@ -// interfaces/Months.java -// (c)2020 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. -// Using interfaces to create groups of constants - -public interface Months { - int - JANUARY = 1, FEBRUARY = 2, MARCH = 3, - APRIL = 4, MAY = 5, JUNE = 6, JULY = 7, - AUGUST = 8, SEPTEMBER = 9, OCTOBER = 10, - NOVEMBER = 11, DECEMBER = 12; -} diff --git a/code/interfaces/MultipleInheritance.java b/code/interfaces/MultipleInheritance.java deleted file mode 100644 index 6ce9c91e..00000000 --- a/code/interfaces/MultipleInheritance.java +++ /dev/null @@ -1,35 +0,0 @@ -// interfaces/MultipleInheritance.java -// (c)2020 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. -import java.util.*; - -interface One { - default void first() { System.out.println("first"); } -} - -interface Two { - default void second() { - System.out.println("second"); - } -} - -interface Three { - default void third() { System.out.println("third"); } -} - -class MI implements One, Two, Three {} - -public class MultipleInheritance { - public static void main(String[] args) { - MI mi = new MI(); - mi.first(); - mi.second(); - mi.third(); - } -} -/* Output: -first -second -third -*/ diff --git a/code/interfaces/PureInterface.java b/code/interfaces/PureInterface.java deleted file mode 100644 index 37bf9f0b..00000000 --- a/code/interfaces/PureInterface.java +++ /dev/null @@ -1,11 +0,0 @@ -// interfaces/PureInterface.java -// (c)2020 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. -// Interface only looked like this before Java 8 - -public interface PureInterface { - int m1(); - void m2(); - double m3(); -} diff --git a/code/interfaces/RandVals.java b/code/interfaces/RandVals.java deleted file mode 100644 index 0221c851..00000000 --- a/code/interfaces/RandVals.java +++ /dev/null @@ -1,15 +0,0 @@ -// interfaces/RandVals.java -// (c)2020 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. -// Initializing interface fields with -// non-constant initializers -import java.util.*; - -public interface RandVals { - Random RAND = new Random(47); - int RANDOM_INT = RAND.nextInt(10); - long RANDOM_LONG = RAND.nextLong() * 10; - float RANDOM_FLOAT = RAND.nextLong() * 10; - double RANDOM_DOUBLE = RAND.nextDouble() * 10; -} diff --git a/code/interfaces/RandomDoubles.java b/code/interfaces/RandomDoubles.java deleted file mode 100644 index 99154d95..00000000 --- a/code/interfaces/RandomDoubles.java +++ /dev/null @@ -1,21 +0,0 @@ -// interfaces/RandomDoubles.java -// (c)2020 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. -import java.util.*; - -public interface RandomDoubles { - Random RAND = new Random(47); - default double next() { return RAND.nextDouble(); } - static void main(String[] args) { - RandomDoubles rd = new RandomDoubles() {}; - for(int i = 0; i < 7; i ++) - System.out.print(rd.next() + " "); - } -} -/* Output: -0.7271157860730044 0.5309454508634242 -0.16020656493302599 0.18847866977771732 -0.5166020801268457 0.2678662084200585 -0.2613610344283964 -*/ diff --git a/code/interfaces/RandomStrings.java b/code/interfaces/RandomStrings.java deleted file mode 100644 index 82f98230..00000000 --- a/code/interfaces/RandomStrings.java +++ /dev/null @@ -1,50 +0,0 @@ -// interfaces/RandomStrings.java -// (c)2020 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. -// Implementing an interface to conform to a method -import java.nio.*; -import java.util.*; - -public class RandomStrings implements Readable { - private static Random rand = new Random(47); - private static final char[] CAPITALS = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); - private static final char[] LOWERS = - "abcdefghijklmnopqrstuvwxyz".toCharArray(); - private static final char[] VOWELS = - "aeiou".toCharArray(); - private int count; - public RandomStrings(int count) { - this.count = count; - } - @Override - public int read(CharBuffer cb) { - if(count-- == 0) - return -1; // Indicates end of input - cb.append(CAPITALS[rand.nextInt(CAPITALS.length)]); - for(int i = 0; i < 4; i++) { - cb.append(VOWELS[rand.nextInt(VOWELS.length)]); - cb.append(LOWERS[rand.nextInt(LOWERS.length)]); - } - cb.append(" "); - return 10; // Number of characters appended - } - public static void main(String[] args) { - Scanner s = new Scanner(new RandomStrings(10)); - while(s.hasNext()) - System.out.println(s.next()); - } -} -/* Output: -Yazeruyac -Fowenucor -Goeazimom -Raeuuacio -Nuoadesiw -Hageaikux -Ruqicibui -Numasetih -Kuuuuozog -Waqizeyoy -*/ diff --git a/code/interfaces/TestRandVals.java b/code/interfaces/TestRandVals.java deleted file mode 100644 index df3490b2..00000000 --- a/code/interfaces/TestRandVals.java +++ /dev/null @@ -1,19 +0,0 @@ -// interfaces/TestRandVals.java -// (c)2020 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. - -public class TestRandVals { - public static void main(String[] args) { - System.out.println(RandVals.RANDOM_INT); - System.out.println(RandVals.RANDOM_LONG); - System.out.println(RandVals.RANDOM_FLOAT); - System.out.println(RandVals.RANDOM_DOUBLE); - } -} -/* Output: -8 --32032247016559954 --8.5939291E18 -5.779976127815049 -*/ diff --git a/code/interfaces/filters/BandPass.java b/code/interfaces/filters/BandPass.java deleted file mode 100644 index 7d09ed28..00000000 --- a/code/interfaces/filters/BandPass.java +++ /dev/null @@ -1,17 +0,0 @@ -// interfaces/filters/BandPass.java -// (c)2020 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 interfaces.filters; - -public class BandPass extends Filter { - double lowCutoff, highCutoff; - public BandPass(double lowCut, double highCut) { - lowCutoff = lowCut; - highCutoff = highCut; - } - @Override - public Waveform process(Waveform input) { - return input; - } -} diff --git a/code/interfaces/filters/Filter.java b/code/interfaces/filters/Filter.java deleted file mode 100644 index 72e29a9e..00000000 --- a/code/interfaces/filters/Filter.java +++ /dev/null @@ -1,14 +0,0 @@ -// interfaces/filters/Filter.java -// (c)2020 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 interfaces.filters; - -public class Filter { - public String name() { - return getClass().getSimpleName(); - } - public Waveform process(Waveform input) { - return input; - } -} diff --git a/code/interfaces/filters/HighPass.java b/code/interfaces/filters/HighPass.java deleted file mode 100644 index 7bf047df..00000000 --- a/code/interfaces/filters/HighPass.java +++ /dev/null @@ -1,16 +0,0 @@ -// interfaces/filters/HighPass.java -// (c)2020 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 interfaces.filters; - -public class HighPass extends Filter { - double cutoff; - public HighPass(double cutoff) { - this.cutoff = cutoff; - } - @Override - public Waveform process(Waveform input) { - return input; - } -} diff --git a/code/interfaces/filters/LowPass.java b/code/interfaces/filters/LowPass.java deleted file mode 100644 index e9320a82..00000000 --- a/code/interfaces/filters/LowPass.java +++ /dev/null @@ -1,16 +0,0 @@ -// interfaces/filters/LowPass.java -// (c)2020 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 interfaces.filters; - -public class LowPass extends Filter { - double cutoff; - public LowPass(double cutoff) { - this.cutoff = cutoff; - } - @Override - public Waveform process(Waveform input) { - return input; // Dummy processing - } -} diff --git a/code/interfaces/filters/Waveform.java b/code/interfaces/filters/Waveform.java deleted file mode 100644 index 40644677..00000000 --- a/code/interfaces/filters/Waveform.java +++ /dev/null @@ -1,14 +0,0 @@ -// interfaces/filters/Waveform.java -// (c)2020 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 interfaces.filters; - -public class Waveform { - private static long counter; - private final long id = counter++; - @Override - public String toString() { - return "Waveform " + id; - } -} diff --git a/code/interfaces/interfaceprocessor/Applicator.java b/code/interfaces/interfaceprocessor/Applicator.java deleted file mode 100644 index 77d7a9a6..00000000 --- a/code/interfaces/interfaceprocessor/Applicator.java +++ /dev/null @@ -1,12 +0,0 @@ -// interfaces/interfaceprocessor/Applicator.java -// (c)2020 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 interfaces.interfaceprocessor; - -public class Applicator { - public static void apply(Processor p, Object s) { - System.out.println("Using Processor " + p.name()); - System.out.println(p.process(s)); - } -} diff --git a/code/interfaces/interfaceprocessor/FilterProcessor.java b/code/interfaces/interfaceprocessor/FilterProcessor.java deleted file mode 100644 index 33689ed4..00000000 --- a/code/interfaces/interfaceprocessor/FilterProcessor.java +++ /dev/null @@ -1,40 +0,0 @@ -// interfaces/interfaceprocessor/FilterProcessor.java -// (c)2020 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. -// {java interfaces.interfaceprocessor.FilterProcessor} -package interfaces.interfaceprocessor; -import interfaces.filters.*; - -class FilterAdapter implements Processor { - Filter filter; - FilterAdapter(Filter filter) { - this.filter = filter; - } - @Override - public String name() { return filter.name(); } - @Override - public Waveform process(Object input) { - return filter.process((Waveform)input); - } -} - -public class FilterProcessor { - public static void main(String[] args) { - Waveform w = new Waveform(); - Applicator.apply( - new FilterAdapter(new LowPass(1.0)), w); - Applicator.apply( - new FilterAdapter(new HighPass(2.0)), w); - Applicator.apply( - new FilterAdapter(new BandPass(3.0, 4.0)), w); - } -} -/* Output: -Using Processor LowPass -Waveform 0 -Using Processor HighPass -Waveform 0 -Using Processor BandPass -Waveform 0 -*/ diff --git a/code/interfaces/interfaceprocessor/Processor.java b/code/interfaces/interfaceprocessor/Processor.java deleted file mode 100644 index 6315da30..00000000 --- a/code/interfaces/interfaceprocessor/Processor.java +++ /dev/null @@ -1,12 +0,0 @@ -// interfaces/interfaceprocessor/Processor.java -// (c)2020 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 interfaces.interfaceprocessor; - -public interface Processor { - default String name() { - return getClass().getSimpleName(); - } - Object process(Object input); -} diff --git a/code/interfaces/interfaceprocessor/StringProcessor.java b/code/interfaces/interfaceprocessor/StringProcessor.java deleted file mode 100644 index 37cb4946..00000000 --- a/code/interfaces/interfaceprocessor/StringProcessor.java +++ /dev/null @@ -1,50 +0,0 @@ -// interfaces/interfaceprocessor/StringProcessor.java -// (c)2020 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. -// {java interfaces.interfaceprocessor.StringProcessor} -package interfaces.interfaceprocessor; -import java.util.*; - -interface StringProcessor extends Processor { - @Override - String process(Object input); // [1] - String S = // [2] - "If she weighs the same as a duck, " + - "she's made of wood"; - static void main(String[] args) { // [3] - Applicator.apply(new Upcase(), S); - Applicator.apply(new Downcase(), S); - Applicator.apply(new Splitter(), S); - } -} - -class Upcase implements StringProcessor { - @Override // Covariant return: - public String process(Object input) { - return ((String)input).toUpperCase(); - } -} - -class Downcase implements StringProcessor { - @Override - public String process(Object input) { - return ((String)input).toLowerCase(); - } -} - -class Splitter implements StringProcessor { - @Override - public String process(Object input) { - return Arrays.toString(((String)input).split(" ")); - } -} -/* Output: -Using Processor Upcase -IF SHE WEIGHS THE SAME AS A DUCK, SHE'S MADE OF WOOD -Using Processor Downcase -if she weighs the same as a duck, she's made of wood -Using Processor Splitter -[If, she, weighs, the, same, as, a, duck,, she's, made, -of, wood] -*/ diff --git a/code/interfaces/music4/Music4.java b/code/interfaces/music4/Music4.java deleted file mode 100644 index 71034149..00000000 --- a/code/interfaces/music4/Music4.java +++ /dev/null @@ -1,105 +0,0 @@ -// interfaces/music4/Music4.java -// (c)2020 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. -// Abstract classes and methods -// {java interfaces.music4.Music4} -package interfaces.music4; -import polymorphism.music.Note; - -abstract class Instrument { - private int i; // Storage allocated for each - public abstract void play(Note n); - public String what() { return "Instrument"; } - public abstract void adjust(); -} - -class Wind extends Instrument { - @Override - public void play(Note n) { - System.out.println("Wind.play() " + n); - } - @Override - public String what() { return "Wind"; } - @Override - public void adjust() { - System.out.println("Adjusting Wind"); - } -} - -class Percussion extends Instrument { - @Override - public void play(Note n) { - System.out.println("Percussion.play() " + n); - } - @Override - public String what() { return "Percussion"; } - @Override - public void adjust() { - System.out.println("Adjusting Percussion"); - } -} - -class Stringed extends Instrument { - @Override - public void play(Note n) { - System.out.println("Stringed.play() " + n); - } - @Override - public String what() { return "Stringed"; } - @Override - public void adjust() { - System.out.println("Adjusting Stringed"); - } -} - -class Brass extends Wind { - @Override - public void play(Note n) { - System.out.println("Brass.play() " + n); - } - @Override - public void adjust() { - System.out.println("Adjusting Brass"); - } -} - -class Woodwind extends Wind { - @Override - public void play(Note n) { - System.out.println("Woodwind.play() " + n); - } - @Override - public String what() { return "Woodwind"; } -} - -public class Music4 { - // Doesn't care about type, so new types - // added to the system still work right: - static void tune(Instrument i) { - // ... - i.play(Note.MIDDLE_C); - } - static void tuneAll(Instrument[] e) { - for(Instrument i : e) - tune(i); - } - public static void main(String[] args) { - // Upcasting during addition to the array: - Instrument[] orchestra = { - new Wind(), - new Percussion(), - new Stringed(), - new Brass(), - new Woodwind() - }; - tuneAll(orchestra); - } -} -/* Output: -Wind.play() MIDDLE_C -Percussion.play() MIDDLE_C -Stringed.play() MIDDLE_C -Brass.play() MIDDLE_C -Woodwind.play() MIDDLE_C -*/ diff --git a/code/interfaces/music5/Music5.java b/code/interfaces/music5/Music5.java deleted file mode 100644 index 2326bdbc..00000000 --- a/code/interfaces/music5/Music5.java +++ /dev/null @@ -1,74 +0,0 @@ -// interfaces/music5/Music5.java -// (c)2020 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. -// {java interfaces.music5.Music5} -package interfaces.music5; -import polymorphism.music.Note; - -interface Instrument { - // Compile-time constant: - int VALUE = 5; // static & final - default void play(Note n) { // Automatically public - System.out.println(this + ".play() " + n); - } - default void adjust() { - System.out.println("Adjusting " + this); - } -} - -class Wind implements Instrument { - @Override - public String toString() { return "Wind"; } -} - -class Percussion implements Instrument { - @Override - public String toString() { return "Percussion"; } -} - -class Stringed implements Instrument { - @Override - public String toString() { return "Stringed"; } -} - -class Brass extends Wind { - @Override - public String toString() { return "Brass"; } -} - -class Woodwind extends Wind { - @Override - public String toString() { return "Woodwind"; } -} - -public class Music5 { - // Doesn't care about type, so new types - // added to the system still work right: - static void tune(Instrument i) { - // ... - i.play(Note.MIDDLE_C); - } - static void tuneAll(Instrument[] e) { - for(Instrument i : e) - tune(i); - } - public static void main(String[] args) { - // Upcasting during addition to the array: - Instrument[] orchestra = { - new Wind(), - new Percussion(), - new Stringed(), - new Brass(), - new Woodwind() - }; - tuneAll(orchestra); - } -} -/* Output: -Wind.play() MIDDLE_C -Percussion.play() MIDDLE_C -Stringed.play() MIDDLE_C -Brass.play() MIDDLE_C -Woodwind.play() MIDDLE_C -*/ diff --git a/code/interfaces/nesting/NestingInterfaces.java b/code/interfaces/nesting/NestingInterfaces.java deleted file mode 100644 index 99b466bb..00000000 --- a/code/interfaces/nesting/NestingInterfaces.java +++ /dev/null @@ -1,105 +0,0 @@ -// interfaces/nesting/NestingInterfaces.java -// (c)2020 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. -// {java interfaces.nesting.NestingInterfaces} -package interfaces.nesting; - -class A { - interface B { - void f(); - } - public class BImp implements B { - @Override - public void f() {} - } - private class BImp2 implements B { - @Override - public void f() {} - } - public interface C { - void f(); - } - class CImp implements C { - @Override - public void f() {} - } - private class CImp2 implements C { - @Override - public void f() {} - } - private interface D { - void f(); - } - private class DImp implements D { - @Override - public void f() {} - } - public class DImp2 implements D { - @Override - public void f() {} - } - public D getD() { return new DImp2(); } - private D dRef; - public void receiveD(D d) { - dRef = d; - dRef.f(); - } -} - -interface E { - interface G { - void f(); - } - // Redundant "public": - public interface H { - void f(); - } - void g(); - // Cannot be private within an interface: - //- private interface I {} -} - -public class NestingInterfaces { - public class BImp implements A.B { - @Override - public void f() {} - } - class CImp implements A.C { - @Override - public void f() {} - } - // Cannot implement a private interface except - // within that interface's defining class: - //- class DImp implements A.D { - //- public void f() {} - //- } - class EImp implements E { - @Override - public void g() {} - } - class EGImp implements E.G { - @Override - public void f() {} - } - class EImp2 implements E { - @Override - public void g() {} - class EG implements E.G { - @Override - public void f() {} - } - } - public static void main(String[] args) { - A a = new A(); - // Can't access A.D: - //- A.D ad = a.getD(); - // Doesn't return anything but A.D: - //- A.DImp2 di2 = a.getD(); - // Cannot access a member of the interface: - //- a.getD().f(); - // Only another A can do anything with getD(): - A a2 = new A(); - a2.receiveD(a.getD()); - } -} diff --git a/code/iostreams/BasicFileOutput.java b/code/iostreams/BasicFileOutput.java deleted file mode 100644 index 1da5c6fd..00000000 --- a/code/iostreams/BasicFileOutput.java +++ /dev/null @@ -1,26 +0,0 @@ -// iostreams/BasicFileOutput.java -// (c)2020 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. -// {VisuallyInspectOutput} -import java.io.*; - -public class BasicFileOutput { - static String file = "BasicFileOutput.dat"; - public static void main(String[] args) { - try( - BufferedReader in = new BufferedReader( - new StringReader( - BufferedInputFile.read( - "BasicFileOutput.java"))); - PrintWriter out = new PrintWriter( - new BufferedWriter(new FileWriter(file))) - ) { - in.lines().forEach(out::println); - } catch(IOException e) { - throw new RuntimeException(e); - } - // Show the stored file: - System.out.println(BufferedInputFile.read(file)); - } -} diff --git a/code/iostreams/BufferedInputFile.java b/code/iostreams/BufferedInputFile.java deleted file mode 100644 index bfe6396f..00000000 --- a/code/iostreams/BufferedInputFile.java +++ /dev/null @@ -1,23 +0,0 @@ -// iostreams/BufferedInputFile.java -// (c)2020 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. -// {VisuallyInspectOutput} -import java.io.*; -import java.util.stream.*; - -public class BufferedInputFile { - public static String read(String filename) { - try(BufferedReader in = new BufferedReader( - new FileReader(filename))) { - return in.lines() - .collect(Collectors.joining("\n")); - } catch(IOException e) { - throw new RuntimeException(e); - } - } - public static void main(String[] args) { - System.out.print( - read("BufferedInputFile.java")); - } -} diff --git a/code/iostreams/FileOutputShortcut.java b/code/iostreams/FileOutputShortcut.java deleted file mode 100644 index 5a160ec0..00000000 --- a/code/iostreams/FileOutputShortcut.java +++ /dev/null @@ -1,24 +0,0 @@ -// iostreams/FileOutputShortcut.java -// (c)2020 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. -// {VisuallyInspectOutput} -import java.io.*; - -public class FileOutputShortcut { - static String file = "FileOutputShortcut.dat"; - public static void main(String[] args) { - try( - BufferedReader in = new BufferedReader( - new StringReader(BufferedInputFile.read( - "FileOutputShortcut.java"))); - // Here's the shortcut: - PrintWriter out = new PrintWriter(file) - ) { - in.lines().forEach(out::println); - } catch(IOException e) { - throw new RuntimeException(e); - } - System.out.println(BufferedInputFile.read(file)); - } -} diff --git a/code/iostreams/FormattedMemoryInput.java b/code/iostreams/FormattedMemoryInput.java deleted file mode 100644 index 055dd882..00000000 --- a/code/iostreams/FormattedMemoryInput.java +++ /dev/null @@ -1,25 +0,0 @@ -// iostreams/FormattedMemoryInput.java -// (c)2020 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. -// {VisuallyInspectOutput} -import java.io.*; - -public class FormattedMemoryInput { - public static void main(String[] args) { - try( - DataInputStream in = new DataInputStream( - new ByteArrayInputStream( - BufferedInputFile.read( - "FormattedMemoryInput.java") - .getBytes())) - ) { - while(true) - System.out.write((char)in.readByte()); - } catch(EOFException e) { - System.out.println("\nEnd of stream"); - } catch(IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/code/iostreams/MemoryInput.java b/code/iostreams/MemoryInput.java deleted file mode 100644 index 1326965c..00000000 --- a/code/iostreams/MemoryInput.java +++ /dev/null @@ -1,17 +0,0 @@ -// iostreams/MemoryInput.java -// (c)2020 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. -// {VisuallyInspectOutput} -import java.io.*; - -public class MemoryInput { - public static void - main(String[] args) throws IOException { - StringReader in = new StringReader( - BufferedInputFile.read("MemoryInput.java")); - int c; - while((c = in.read()) != -1) - System.out.print((char)c); - } -} diff --git a/code/iostreams/StoringAndRecoveringData.java b/code/iostreams/StoringAndRecoveringData.java deleted file mode 100644 index 761f022e..00000000 --- a/code/iostreams/StoringAndRecoveringData.java +++ /dev/null @@ -1,42 +0,0 @@ -// iostreams/StoringAndRecoveringData.java -// (c)2020 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. -import java.io.*; - -public class StoringAndRecoveringData { - public static void main(String[] args) { - try( - DataOutputStream out = new DataOutputStream( - new BufferedOutputStream( - new FileOutputStream("Data.txt"))) - ) { - out.writeDouble(3.14159); - out.writeUTF("That was pi"); - out.writeDouble(1.41413); - out.writeUTF("Square root of 2"); - } catch(IOException e) { - throw new RuntimeException(e); - } - try( - DataInputStream in = new DataInputStream( - new BufferedInputStream( - new FileInputStream("Data.txt"))) - ) { - System.out.println(in.readDouble()); - // Only readUTF() will recover the - // Java-UTF String properly: - System.out.println(in.readUTF()); - System.out.println(in.readDouble()); - System.out.println(in.readUTF()); - } catch(IOException e) { - throw new RuntimeException(e); - } - } -} -/* Output: -3.14159 -That was pi -1.41413 -Square root of 2 -*/ diff --git a/code/iostreams/TestEOF.java b/code/iostreams/TestEOF.java deleted file mode 100644 index 956cb1a0..00000000 --- a/code/iostreams/TestEOF.java +++ /dev/null @@ -1,22 +0,0 @@ -// iostreams/TestEOF.java -// (c)2020 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. -// Testing for end of file -// {VisuallyInspectOutput} -import java.io.*; - -public class TestEOF { - public static void main(String[] args) { - try( - DataInputStream in = new DataInputStream( - new BufferedInputStream( - new FileInputStream("TestEOF.java"))) - ) { - while(in.available() != 0) - System.out.write(in.readByte()); - } catch(IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/code/iostreams/UsingRandomAccessFile.java b/code/iostreams/UsingRandomAccessFile.java deleted file mode 100644 index dde6d1ee..00000000 --- a/code/iostreams/UsingRandomAccessFile.java +++ /dev/null @@ -1,65 +0,0 @@ -// iostreams/UsingRandomAccessFile.java -// (c)2020 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. -import java.io.*; - -public class UsingRandomAccessFile { - static String file = "rtest.dat"; - public static void display() { - try( - RandomAccessFile rf = - new RandomAccessFile(file, "r") - ) { - for(int i = 0; i < 7; i++) - System.out.println( - "Value " + i + ": " + rf.readDouble()); - System.out.println(rf.readUTF()); - } catch(IOException e) { - throw new RuntimeException(e); - } - } - public static void main(String[] args) { - try( - RandomAccessFile rf = - new RandomAccessFile(file, "rw") - ) { - for(int i = 0; i < 7; i++) - rf.writeDouble(i*1.414); - rf.writeUTF("The end of the file"); - rf.close(); - display(); - } catch(IOException e) { - throw new RuntimeException(e); - } - try( - RandomAccessFile rf = - new RandomAccessFile(file, "rw") - ) { - rf.seek(5*8); - rf.writeDouble(47.0001); - rf.close(); - display(); - } catch(IOException e) { - throw new RuntimeException(e); - } - } -} -/* Output: -Value 0: 0.0 -Value 1: 1.414 -Value 2: 2.828 -Value 3: 4.242 -Value 4: 5.656 -Value 5: 7.069999999999999 -Value 6: 8.484 -The end of the file -Value 0: 0.0 -Value 1: 1.414 -Value 2: 2.828 -Value 3: 4.242 -Value 4: 5.656 -Value 5: 47.0001 -Value 6: 8.484 -The end of the file -*/ diff --git a/code/javadoc/Documentation1.java b/code/javadoc/Documentation1.java deleted file mode 100644 index 7838fbd9..00000000 --- a/code/javadoc/Documentation1.java +++ /dev/null @@ -1,11 +0,0 @@ -// javadoc/Documentation1.java -// (c)2020 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. -/** A class comment */ -public class Documentation1 { - /** A field comment */ - public int i; - /** A method comment */ - public void f() {} -} diff --git a/code/javadoc/Documentation2.java b/code/javadoc/Documentation2.java deleted file mode 100644 index 237755f4..00000000 --- a/code/javadoc/Documentation2.java +++ /dev/null @@ -1,9 +0,0 @@ -// javadoc/Documentation2.java -// (c)2020 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. -/**

- * System.out.println(new Date());
- * 
- */ -public class Documentation2 {} diff --git a/code/javadoc/Documentation3.java b/code/javadoc/Documentation3.java deleted file mode 100644 index a3063c3d..00000000 --- a/code/javadoc/Documentation3.java +++ /dev/null @@ -1,12 +0,0 @@ -// javadoc/Documentation3.java -// (c)2020 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. -/** You can even insert a list: - *
    - *
  1. Item one - *
  2. Item two - *
  3. Item three - *
- */ -public class Documentation3 {} diff --git a/code/javadoc/HelloDateDoc.java b/code/javadoc/HelloDateDoc.java deleted file mode 100644 index 54b505a4..00000000 --- a/code/javadoc/HelloDateDoc.java +++ /dev/null @@ -1,26 +0,0 @@ -// javadoc/HelloDateDoc.java -// (c)2020 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. -import java.util.*; - -/** The first On Java 8 example program. - * Displays a String and today's date. - * @author Bruce Eckel - * @author www.MindviewInc.com - * @version 5.0 - */ -public class HelloDateDoc { - /** Entry point to class & application. - * @param args array of String arguments - * @throws exceptions No exceptions thrown - */ - public static void main(String[] args) { - System.out.println("Hello, it's: "); - System.out.println(new Date()); - } -} -/* Output: -Hello, it's: -Tue May 09 06:07:27 MDT 2017 -*/ diff --git a/code/lowlevel/AtomicEvenProducer.java b/code/lowlevel/AtomicEvenProducer.java deleted file mode 100644 index 8c45b61c..00000000 --- a/code/lowlevel/AtomicEvenProducer.java +++ /dev/null @@ -1,21 +0,0 @@ -// lowlevel/AtomicEvenProducer.java -// (c)2020 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. -// Atomic classes: occasionally useful in regular code -import java.util.concurrent.atomic.*; - -public class AtomicEvenProducer extends IntGenerator { - private AtomicInteger currentEvenValue = - new AtomicInteger(0); - @Override - public int next() { - return currentEvenValue.addAndGet(2); - } - public static void main(String[] args) { - EvenChecker.test(new AtomicEvenProducer()); - } -} -/* Output: -No odd numbers discovered -*/ diff --git a/code/lowlevel/AtomicIntegerTest.java b/code/lowlevel/AtomicIntegerTest.java deleted file mode 100644 index 09db1ca8..00000000 --- a/code/lowlevel/AtomicIntegerTest.java +++ /dev/null @@ -1,20 +0,0 @@ -// lowlevel/AtomicIntegerTest.java -// (c)2020 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. -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.util.*; -import onjava.*; - -public class AtomicIntegerTest extends IntTestable { - private AtomicInteger i = new AtomicInteger(0); - public int getAsInt() { return i.get(); } - public void evenIncrement() { i.addAndGet(2); } - public static void main(String[] args) { - Atomicity.test(new AtomicIntegerTest()); - } -} -/* Output: -No failures found -*/ diff --git a/code/lowlevel/AtomicSerialNumbers.java b/code/lowlevel/AtomicSerialNumbers.java deleted file mode 100644 index 2e30e9c4..00000000 --- a/code/lowlevel/AtomicSerialNumbers.java +++ /dev/null @@ -1,21 +0,0 @@ -// lowlevel/AtomicSerialNumbers.java -// (c)2020 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. -import java.util.concurrent.atomic.*; - -public class -AtomicSerialNumbers extends SerialNumbers { - private AtomicInteger serialNumber = - new AtomicInteger(); - public int nextSerialNumber() { - return serialNumber.getAndIncrement(); - } - public static void main(String[] args) { - SerialNumberChecker.test( - new AtomicSerialNumbers()); - } -} -/* Output: -No duplicates detected -*/ diff --git a/code/lowlevel/Atomicity.java b/code/lowlevel/Atomicity.java deleted file mode 100644 index 632631bf..00000000 --- a/code/lowlevel/Atomicity.java +++ /dev/null @@ -1,20 +0,0 @@ -// lowlevel/Atomicity.java -// (c)2020 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. -import java.util.concurrent.*; -import onjava.TimedAbort; - -public class Atomicity { - public static void test(IntTestable it) { - new TimedAbort(4, "No failures found"); - CompletableFuture.runAsync(it); - while(true) { - int val = it.getAsInt(); - if(val % 2 != 0) { - System.out.println("failed with: " + val); - System.exit(0); - } - } - } -} diff --git a/code/lowlevel/AttemptLocking.java b/code/lowlevel/AttemptLocking.java deleted file mode 100644 index 9dbe2b28..00000000 --- a/code/lowlevel/AttemptLocking.java +++ /dev/null @@ -1,57 +0,0 @@ -// lowlevel/AttemptLocking.java -// (c)2020 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. -// Locks in the concurrent library allow you -// to give up on trying to acquire a lock -import java.util.concurrent.*; -import java.util.concurrent.locks.*; -import onjava.Nap; - -public class AttemptLocking { - private ReentrantLock lock = new ReentrantLock(); - public void untimed() { - boolean captured = lock.tryLock(); - try { - System.out.println("tryLock(): " + captured); - } finally { - if(captured) - lock.unlock(); - } - } - public void timed() { - boolean captured = false; - try { - captured = lock.tryLock(2, TimeUnit.SECONDS); - } catch(InterruptedException e) { - throw new RuntimeException(e); - } - try { - System.out.println( - "tryLock(2, TimeUnit.SECONDS): " + captured); - } finally { - if(captured) - lock.unlock(); - } - } - public static void main(String[] args) { - final AttemptLocking al = new AttemptLocking(); - al.untimed(); // True -- lock is available - al.timed(); // True -- lock is available - // Now create a second task to grab the lock: - CompletableFuture.runAsync( () -> { - al.lock.lock(); - System.out.println("acquired"); - }); - new Nap(0.1); // Give the second task a chance - al.untimed(); // False -- lock grabbed by task - al.timed(); // False -- lock grabbed by task - } -} -/* Output: -tryLock(): true -tryLock(2, TimeUnit.SECONDS): true -acquired -tryLock(): false -tryLock(2, TimeUnit.SECONDS): false -*/ diff --git a/code/lowlevel/CaptureUncaughtException.java b/code/lowlevel/CaptureUncaughtException.java deleted file mode 100644 index 33261667..00000000 --- a/code/lowlevel/CaptureUncaughtException.java +++ /dev/null @@ -1,56 +0,0 @@ -// lowlevel/CaptureUncaughtException.java -// (c)2020 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. -import java.util.concurrent.*; - -class ExceptionThread2 implements Runnable { - @Override - public void run() { - Thread t = Thread.currentThread(); - System.out.println("run() by " + t.getName()); - System.out.println( - "eh = " + t.getUncaughtExceptionHandler()); - throw new RuntimeException(); - } -} - -class MyUncaughtExceptionHandler implements -Thread.UncaughtExceptionHandler { - @Override - public void uncaughtException(Thread t, Throwable e) { - System.out.println("caught " + e); - } -} - -class HandlerThreadFactory implements ThreadFactory { - @Override - public Thread newThread(Runnable r) { - System.out.println(this + " creating new Thread"); - Thread t = new Thread(r); - System.out.println("created " + t); - t.setUncaughtExceptionHandler( - new MyUncaughtExceptionHandler()); - System.out.println( - "eh = " + t.getUncaughtExceptionHandler()); - return t; - } -} - -public class CaptureUncaughtException { - public static void main(String[] args) { - ExecutorService exec = - Executors.newCachedThreadPool( - new HandlerThreadFactory()); - exec.execute(new ExceptionThread2()); - exec.shutdown(); - } -} -/* Output: -HandlerThreadFactory@4e25154f creating new Thread -created Thread[Thread-0,5,main] -eh = MyUncaughtExceptionHandler@70dea4e -run() by Thread-0 -eh = MyUncaughtExceptionHandler@70dea4e -caught java.lang.RuntimeException -*/ diff --git a/code/lowlevel/CircularSet.java b/code/lowlevel/CircularSet.java deleted file mode 100644 index 225eaeca..00000000 --- a/code/lowlevel/CircularSet.java +++ /dev/null @@ -1,29 +0,0 @@ -// lowlevel/CircularSet.java -// (c)2020 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. -// Reuses storage so we don't run out of memory -import java.util.*; - -public class CircularSet { - private int[] array; - private int size; - private int index = 0; - public CircularSet(int size) { - this.size = size; - array = new int[size]; - // Initialize to a value not produced - // by SerialNumbers: - Arrays.fill(array, -1); - } - public synchronized void add(int i) { - array[index] = i; - // Wrap index and write over old elements: - index = ++index % size; - } - public synchronized boolean contains(int val) { - for(int i = 0; i < size; i++) - if(array[i] == val) return true; - return false; - } -} diff --git a/code/lowlevel/DelayQueueDemo.java b/code/lowlevel/DelayQueueDemo.java deleted file mode 100644 index c5575c68..00000000 --- a/code/lowlevel/DelayQueueDemo.java +++ /dev/null @@ -1,99 +0,0 @@ -// lowlevel/DelayQueueDemo.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import java.util.concurrent.*; -import static java.util.concurrent.TimeUnit.*; - -class DelayedTask implements Runnable, Delayed { - private static int counter = 0; - private final int id = counter++; - private final int delta; - private final long trigger; - protected static List sequence = - new ArrayList<>(); - DelayedTask(int delayInMilliseconds) { - delta = delayInMilliseconds; - trigger = System.nanoTime() + - NANOSECONDS.convert(delta, MILLISECONDS); - sequence.add(this); - } - @Override - public long getDelay(TimeUnit unit) { - return unit.convert( - trigger - System.nanoTime(), NANOSECONDS); - } - @Override - public int compareTo(Delayed arg) { - DelayedTask that = (DelayedTask)arg; - if(trigger < that.trigger) return -1; - if(trigger > that.trigger) return 1; - return 0; - } - @Override - public void run() { - System.out.print(this + " "); - } - @Override - public String toString() { - return - String.format("[%d] Task %d", delta, id); - } - public String summary() { - return String.format("(%d:%d)", id, delta); - } - public static class EndTask extends DelayedTask { - EndTask(int delay) { super(delay); } - @Override - public void run() { - sequence.forEach(dt -> - System.out.println(dt.summary())); - } - } -} - -public class DelayQueueDemo { - public static void - main(String[] args) throws Exception { - DelayQueue tasks = - Stream.concat( // Random delays: - new Random(47).ints(20, 0, 4000) - .mapToObj(DelayedTask::new), - // Add the summarizing task: - Stream.of(new DelayedTask.EndTask(4000))) - .collect(Collectors - .toCollection(DelayQueue::new)); - while(tasks.size() > 0) - tasks.take().run(); - } -} -/* Output: -[128] Task 12 [429] Task 6 [551] Task 13 [555] Task 2 -[693] Task 3 [809] Task 15 [961] Task 5 [1258] Task 1 -[1258] Task 20 [1520] Task 19 [1861] Task 4 [1998] Task -17 [2200] Task 8 [2207] Task 10 [2288] Task 11 [2522] -Task 9 [2589] Task 14 [2861] Task 18 [2868] Task 7 -[3278] Task 16 (0:4000) -(1:1258) -(2:555) -(3:693) -(4:1861) -(5:961) -(6:429) -(7:2868) -(8:2200) -(9:2522) -(10:2207) -(11:2288) -(12:128) -(13:551) -(14:2589) -(15:809) -(16:3278) -(17:1998) -(18:2861) -(19:1520) -(20:1258) -*/ diff --git a/code/lowlevel/EvenChecker.java b/code/lowlevel/EvenChecker.java deleted file mode 100644 index 5e27a39e..00000000 --- a/code/lowlevel/EvenChecker.java +++ /dev/null @@ -1,41 +0,0 @@ -// lowlevel/EvenChecker.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import java.util.concurrent.*; -import onjava.TimedAbort; - -public class EvenChecker implements Runnable { - private IntGenerator generator; - private final int id; - public EvenChecker(IntGenerator generator, int id) { - this.generator = generator; - this.id = id; - } - @Override - public void run() { - while(!generator.isCanceled()) { - int val = generator.next(); - if(val % 2 != 0) { - System.out.println(val + " not even!"); - generator.cancel(); // Cancels all EvenCheckers - } - } - } - // Test any IntGenerator: - public static void test(IntGenerator gp, int count) { - List> checkers = - IntStream.range(0, count) - .mapToObj(i -> new EvenChecker(gp, i)) - .map(CompletableFuture::runAsync) - .collect(Collectors.toList()); - checkers.forEach(CompletableFuture::join); - } - // Default value for count: - public static void test(IntGenerator gp) { - new TimedAbort(4, "No odd numbers discovered"); - test(gp, 10); - } -} diff --git a/code/lowlevel/EvenProducer.java b/code/lowlevel/EvenProducer.java deleted file mode 100644 index 30157755..00000000 --- a/code/lowlevel/EvenProducer.java +++ /dev/null @@ -1,26 +0,0 @@ -// lowlevel/EvenProducer.java -// (c)2020 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. -// When threads collide -// {VisuallyInspectOutput} - -public class EvenProducer extends IntGenerator { - private int currentEvenValue = 0; - @Override - public int next() { - ++currentEvenValue; // [1] - ++currentEvenValue; - return currentEvenValue; - } - public static void main(String[] args) { - EvenChecker.test(new EvenProducer()); - } -} -/* Output: -419 not even! -425 not even! -423 not even! -421 not even! -417 not even! -*/ diff --git a/code/lowlevel/ExceptionThread.java b/code/lowlevel/ExceptionThread.java deleted file mode 100644 index 518b9f5f..00000000 --- a/code/lowlevel/ExceptionThread.java +++ /dev/null @@ -1,30 +0,0 @@ -// lowlevel/ExceptionThread.java -// (c)2020 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. -// {ThrowsException} -import java.util.concurrent.*; - -public class ExceptionThread implements Runnable { - @Override - public void run() { - throw new RuntimeException(); - } - public static void main(String[] args) { - ExecutorService es = - Executors.newCachedThreadPool(); - es.execute(new ExceptionThread()); - es.shutdown(); - } -} -/* Output: -___[ Error Output ]___ -Exception in thread "pool-1-thread-1" -java.lang.RuntimeException - at ExceptionThread.run(ExceptionThread.java:8) - at java.util.concurrent.ThreadPoolExecutor.runW -orker(ThreadPoolExecutor.java:1142) - at java.util.concurrent.ThreadPoolExecutor$Work -er.run(ThreadPoolExecutor.java:617) - at java.lang.Thread.run(Thread.java:745) -*/ diff --git a/code/lowlevel/IntGenerator.java b/code/lowlevel/IntGenerator.java deleted file mode 100644 index e1dd0f62..00000000 --- a/code/lowlevel/IntGenerator.java +++ /dev/null @@ -1,15 +0,0 @@ -// lowlevel/IntGenerator.java -// (c)2020 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. -import java.util.concurrent.atomic.AtomicBoolean; - -public abstract class IntGenerator { - private AtomicBoolean canceled = - new AtomicBoolean(); - public abstract int next(); - public void cancel() { canceled.set(true); } - public boolean isCanceled() { - return canceled.get(); - } -} diff --git a/code/lowlevel/IntTestable.java b/code/lowlevel/IntTestable.java deleted file mode 100644 index 1989ff4d..00000000 --- a/code/lowlevel/IntTestable.java +++ /dev/null @@ -1,15 +0,0 @@ -// lowlevel/IntTestable.java -// (c)2020 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. -import java.util.function.*; - -public abstract class -IntTestable implements Runnable, IntSupplier { - abstract void evenIncrement(); - @Override - public void run() { - while(true) - evenIncrement(); - } -} diff --git a/code/lowlevel/MutexEvenProducer.java b/code/lowlevel/MutexEvenProducer.java deleted file mode 100644 index ae82df82..00000000 --- a/code/lowlevel/MutexEvenProducer.java +++ /dev/null @@ -1,30 +0,0 @@ -// lowlevel/MutexEvenProducer.java -// (c)2020 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. -// Preventing thread collisions with mutexes -import java.util.concurrent.locks.*; -import onjava.Nap; - -public class MutexEvenProducer extends IntGenerator { - private int currentEvenValue = 0; - private Lock lock = new ReentrantLock(); - @Override - public int next() { - lock.lock(); - try { - ++currentEvenValue; - new Nap(0.01); // Cause failure faster - ++currentEvenValue; - return currentEvenValue; - } finally { - lock.unlock(); - } - } - public static void main(String[] args) { - EvenChecker.test(new MutexEvenProducer()); - } -} -/* -No odd numbers discovered -*/ diff --git a/code/lowlevel/NaiveExceptionHandling.java b/code/lowlevel/NaiveExceptionHandling.java deleted file mode 100644 index 3681337e..00000000 --- a/code/lowlevel/NaiveExceptionHandling.java +++ /dev/null @@ -1,32 +0,0 @@ -// lowlevel/NaiveExceptionHandling.java -// (c)2020 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. -// {ThrowsException} -import java.util.concurrent.*; - -public class NaiveExceptionHandling { - public static void main(String[] args) { - ExecutorService es = - Executors.newCachedThreadPool(); - try { - es.execute(new ExceptionThread()); - } catch(RuntimeException ue) { - // This statement will NOT execute! - System.out.println("Exception was handled!"); - } finally { - es.shutdown(); - } - } -} -/* Output: -___[ Error Output ]___ -Exception in thread "pool-1-thread-1" -java.lang.RuntimeException - at ExceptionThread.run(ExceptionThread.java:8) - at java.util.concurrent.ThreadPoolExecutor.runW -orker(ThreadPoolExecutor.java:1142) - at java.util.concurrent.ThreadPoolExecutor$Work -er.run(ThreadPoolExecutor.java:617) - at java.lang.Thread.run(Thread.java:745) -*/ diff --git a/code/lowlevel/NotAtomic.java b/code/lowlevel/NotAtomic.java deleted file mode 100644 index c6c6c321..00000000 --- a/code/lowlevel/NotAtomic.java +++ /dev/null @@ -1,49 +0,0 @@ -// lowlevel/NotAtomic.java -// (c)2020 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. -// javap -c NotAtomic -// {ExcludeFromGradle} -// {VisuallyInspectOutput} - -public class NotAtomic { - int i; - void f1() { i++; } - void f2() { i += 3; } -} -/* Output: -Compiled from "NotAtomic.java" -public class NotAtomic { - int i; - - public NotAtomic(); - Code: - 0: aload_0 - 1: invokespecial #1 // Method java/lang/Object."":()V - 4: return - - void f1(); - Code: - 0: aload_0 - 1: dup - 2: getfield #2 // Field -i:I - 5: iconst_1 - 6: iadd - 7: putfield #2 // Field -i:I - 10: return - - void f2(); - Code: - 0: aload_0 - 1: dup - 2: getfield #2 // Field -i:I - 5: iconst_3 - 6: iadd - 7: putfield #2 // Field -i:I - 10: return -} -*/ diff --git a/code/lowlevel/NumberOfProcessors.java b/code/lowlevel/NumberOfProcessors.java deleted file mode 100644 index 44abeb5d..00000000 --- a/code/lowlevel/NumberOfProcessors.java +++ /dev/null @@ -1,14 +0,0 @@ -// lowlevel/NumberOfProcessors.java -// (c)2020 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. - -public class NumberOfProcessors { - public static void main(String[] args) { - System.out.println( - Runtime.getRuntime().availableProcessors()); - } -} -/* Output: -8 -*/ diff --git a/code/lowlevel/PriorityBlockingQueueDemo.java b/code/lowlevel/PriorityBlockingQueueDemo.java deleted file mode 100644 index 099a5349..00000000 --- a/code/lowlevel/PriorityBlockingQueueDemo.java +++ /dev/null @@ -1,139 +0,0 @@ -// lowlevel/PriorityBlockingQueueDemo.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import onjava.Nap; - -class Prioritized implements Comparable { - private static AtomicInteger counter = - new AtomicInteger(); - private final int id = counter.getAndIncrement(); - private final int priority; - private static List sequence = - new CopyOnWriteArrayList<>(); - Prioritized(int priority) { - this.priority = priority; - sequence.add(this); - } - @Override - public int compareTo(Prioritized arg) { - return priority < arg.priority ? 1 : - (priority > arg.priority ? -1 : 0); - } - @Override - public String toString() { - return String.format( - "[%d] Prioritized %d", priority, id); - } - public void displaySequence() { - int count = 0; - for(Prioritized pt : sequence) { - System.out.printf("(%d:%d)", pt.id, pt.priority); - if(++count % 5 == 0) - System.out.println(); - } - } - public static class EndSentinel extends Prioritized { - EndSentinel() { super(-1); } - } -} - -class Producer implements Runnable { - private static AtomicInteger seed = - new AtomicInteger(47); - private SplittableRandom rand = - new SplittableRandom(seed.getAndAdd(10)); - private Queue queue; - Producer(Queue q) { - queue = q; - } - @Override - public void run() { - rand.ints(10, 0, 20) - .mapToObj(Prioritized::new) - .peek(p -> new Nap(rand.nextDouble() / 10)) - .forEach(p -> queue.add(p)); - queue.add(new Prioritized.EndSentinel()); - } -} - -class Consumer implements Runnable { - private PriorityBlockingQueue q; - private SplittableRandom rand = - new SplittableRandom(47); - Consumer(PriorityBlockingQueue q) { - this.q = q; - } - @Override - public void run() { - while(true) { - try { - Prioritized pt = q.take(); - System.out.println(pt); - if(pt instanceof Prioritized.EndSentinel) { - pt.displaySequence(); - break; - } - new Nap(rand.nextDouble() / 10); - } catch(InterruptedException e) { - throw new RuntimeException(e); - } - } - } -} - -public class PriorityBlockingQueueDemo { - public static void main(String[] args) { - PriorityBlockingQueue queue = - new PriorityBlockingQueue<>(); - CompletableFuture.runAsync(new Producer(queue)); - CompletableFuture.runAsync(new Producer(queue)); - CompletableFuture.runAsync(new Producer(queue)); - CompletableFuture.runAsync(new Consumer(queue)) - .join(); - } -} -/* Output: -[15] Prioritized 2 -[17] Prioritized 1 -[17] Prioritized 5 -[16] Prioritized 6 -[14] Prioritized 9 -[12] Prioritized 0 -[11] Prioritized 4 -[11] Prioritized 12 -[13] Prioritized 13 -[12] Prioritized 16 -[14] Prioritized 18 -[15] Prioritized 23 -[18] Prioritized 26 -[16] Prioritized 29 -[12] Prioritized 17 -[11] Prioritized 30 -[11] Prioritized 24 -[10] Prioritized 15 -[10] Prioritized 22 -[8] Prioritized 25 -[8] Prioritized 11 -[8] Prioritized 10 -[6] Prioritized 31 -[3] Prioritized 7 -[2] Prioritized 20 -[1] Prioritized 3 -[0] Prioritized 19 -[0] Prioritized 8 -[0] Prioritized 14 -[0] Prioritized 21 -[-1] Prioritized 28 -(0:12)(2:15)(1:17)(3:1)(4:11) -(5:17)(6:16)(7:3)(8:0)(9:14) -(10:8)(11:8)(12:11)(13:13)(14:0) -(15:10)(16:12)(17:12)(18:14)(19:0) -(20:2)(21:0)(22:10)(23:15)(24:11) -(25:8)(26:18)(27:-1)(28:-1)(29:16) -(30:11)(31:6)(32:-1) -*/ diff --git a/code/lowlevel/ReOrdering.java b/code/lowlevel/ReOrdering.java deleted file mode 100644 index 8209ac40..00000000 --- a/code/lowlevel/ReOrdering.java +++ /dev/null @@ -1,19 +0,0 @@ -// lowlevel/ReOrdering.java -// (c)2020 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. - -public class ReOrdering implements Runnable { - int one, two, three, four, five, six; - volatile int volaTile; - @Override - public void run() { - one = 1; - two = 2; - three = 3; - volaTile = 92; - int x = four; - int y = five; - int z = six; - } -} diff --git a/code/lowlevel/SafeReturn.java b/code/lowlevel/SafeReturn.java deleted file mode 100644 index 751c96be..00000000 --- a/code/lowlevel/SafeReturn.java +++ /dev/null @@ -1,20 +0,0 @@ -// lowlevel/SafeReturn.java -// (c)2020 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. -import java.util.function.*; -import java.util.concurrent.*; - -public class SafeReturn extends IntTestable { - private int i = 0; - public synchronized int getAsInt() { return i; } - public synchronized void evenIncrement() { - i++; i++; - } - public static void main(String[] args) { - Atomicity.test(new SafeReturn()); - } -} -/* Output: -No failures found -*/ diff --git a/code/lowlevel/SerialNumberChecker.java b/code/lowlevel/SerialNumberChecker.java deleted file mode 100644 index 9c2b92ad..00000000 --- a/code/lowlevel/SerialNumberChecker.java +++ /dev/null @@ -1,32 +0,0 @@ -// lowlevel/SerialNumberChecker.java -// (c)2020 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. -// Test SerialNumbers implementations for thread-safety -import java.util.concurrent.*; -import onjava.Nap; - -public class SerialNumberChecker implements Runnable { - private CircularSet serials = new CircularSet(1000); - private SerialNumbers producer; - public SerialNumberChecker(SerialNumbers producer) { - this.producer = producer; - } - @Override - public void run() { - while(true) { - int serial = producer.nextSerialNumber(); - if(serials.contains(serial)) { - System.out.println("Duplicate: " + serial); - System.exit(0); - } - serials.add(serial); - } - } - static void test(SerialNumbers producer) { - for(int i = 0; i < 10; i++) - CompletableFuture.runAsync( - new SerialNumberChecker(producer)); - new Nap(4, "No duplicates detected"); - } -} diff --git a/code/lowlevel/SerialNumberTest.java b/code/lowlevel/SerialNumberTest.java deleted file mode 100644 index cdeddcd9..00000000 --- a/code/lowlevel/SerialNumberTest.java +++ /dev/null @@ -1,13 +0,0 @@ -// lowlevel/SerialNumberTest.java -// (c)2020 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. - -public class SerialNumberTest { - public static void main(String[] args) { - SerialNumberChecker.test(new SerialNumbers()); - } -} -/* Output: -Duplicate: 148044 -*/ diff --git a/code/lowlevel/SerialNumbers.java b/code/lowlevel/SerialNumbers.java deleted file mode 100644 index 3f6101c7..00000000 --- a/code/lowlevel/SerialNumbers.java +++ /dev/null @@ -1,11 +0,0 @@ -// lowlevel/SerialNumbers.java -// (c)2020 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. - -public class SerialNumbers { - private volatile int serialNumber = 0; - public int nextSerialNumber() { - return serialNumber++; // Not thread-safe - } -} diff --git a/code/lowlevel/SettingDefaultHandler.java b/code/lowlevel/SettingDefaultHandler.java deleted file mode 100644 index 56a04642..00000000 --- a/code/lowlevel/SettingDefaultHandler.java +++ /dev/null @@ -1,19 +0,0 @@ -// lowlevel/SettingDefaultHandler.java -// (c)2020 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. -import java.util.concurrent.*; - -public class SettingDefaultHandler { - public static void main(String[] args) { - Thread.setDefaultUncaughtExceptionHandler( - new MyUncaughtExceptionHandler()); - ExecutorService es = - Executors.newCachedThreadPool(); - es.execute(new ExceptionThread()); - es.shutdown(); - } -} -/* Output: -caught java.lang.RuntimeException -*/ diff --git a/code/lowlevel/SwallowedException.java b/code/lowlevel/SwallowedException.java deleted file mode 100644 index 60edd0d6..00000000 --- a/code/lowlevel/SwallowedException.java +++ /dev/null @@ -1,17 +0,0 @@ -// lowlevel/SwallowedException.java -// (c)2020 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. -import java.util.concurrent.*; - -public class SwallowedException { - public static void main(String[] args) - throws InterruptedException { - ExecutorService exec = - Executors.newSingleThreadExecutor(); - exec.submit(() -> { - throw new RuntimeException(); - }); - exec.shutdown(); - } -} diff --git a/code/lowlevel/SyncOnObject.java b/code/lowlevel/SyncOnObject.java deleted file mode 100644 index 846c5573..00000000 --- a/code/lowlevel/SyncOnObject.java +++ /dev/null @@ -1,70 +0,0 @@ -// lowlevel/SyncOnObject.java -// (c)2020 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. -// Synchronizing on another object -import java.util.*; -import java.util.stream.*; -import java.util.concurrent.*; -import onjava.Nap; - -class DualSynch { - ConcurrentLinkedQueue trace = - new ConcurrentLinkedQueue<>(); - public synchronized void f(boolean nap) { - for(int i = 0; i < 5; i++) { - trace.add(String.format("f() " + i)); - if(nap) new Nap(0.01); - } - } - private Object syncObject = new Object(); - public void g(boolean nap) { - synchronized(syncObject) { - for(int i = 0; i < 5; i++) { - trace.add(String.format("g() " + i)); - if(nap) new Nap(0.01); - } - } - } -} - -public class SyncOnObject { - static void test(boolean fNap, boolean gNap) { - DualSynch ds = new DualSynch(); - List> cfs = - Arrays.stream(new Runnable[] { - () -> ds.f(fNap), () -> ds.g(gNap) }) - .map(CompletableFuture::runAsync) - .collect(Collectors.toList()); - cfs.forEach(CompletableFuture::join); - ds.trace.forEach(System.out::println); - } - public static void main(String[] args) { - test(true, false); - System.out.println("****"); - test(false, true); - } -} -/* Output: -f() 0 -g() 0 -g() 1 -g() 2 -g() 3 -g() 4 -f() 1 -f() 2 -f() 3 -f() 4 -**** -f() 0 -g() 0 -f() 1 -f() 2 -f() 3 -f() 4 -g() 1 -g() 2 -g() 3 -g() 4 -*/ diff --git a/code/lowlevel/SynchronizedComparison.java b/code/lowlevel/SynchronizedComparison.java deleted file mode 100644 index 6fbcd1f3..00000000 --- a/code/lowlevel/SynchronizedComparison.java +++ /dev/null @@ -1,89 +0,0 @@ -// lowlevel/SynchronizedComparison.java -// (c)2020 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. -// Synchronizing blocks instead of entire methods -// speeds up access. -import java.util.*; -import java.util.stream.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import onjava.Nap; - -abstract class Guarded { - AtomicLong callCount = new AtomicLong(); - public abstract void method(); - @Override - public String toString() { - return getClass().getSimpleName() + - ": " + callCount.get(); - } -} - -class SynchronizedMethod extends Guarded { - public synchronized void method() { - new Nap(0.01); - callCount.incrementAndGet(); - } -} - -class CriticalSection extends Guarded { - public void method() { - new Nap(0.01); - synchronized(this) { - callCount.incrementAndGet(); - } - } -} - -class Caller implements Runnable { - private Guarded g; - Caller(Guarded g) { this.g = g; } - private AtomicLong successfulCalls = - new AtomicLong(); - private AtomicBoolean stop = - new AtomicBoolean(false); - @Override - public void run() { - new Timer().schedule(new TimerTask() { - public void run() { stop.set(true); } - }, 2500); - while(!stop.get()) { - g.method(); - successfulCalls.getAndIncrement(); - } - System.out.println( - "-> " + successfulCalls.get()); - } -} - -public class SynchronizedComparison { - static void test(Guarded g) { - List> callers = - Stream.of( - new Caller(g), - new Caller(g), - new Caller(g), - new Caller(g)) - .map(CompletableFuture::runAsync) - .collect(Collectors.toList()); - callers.forEach(CompletableFuture::join); - System.out.println(g); - } - public static void main(String[] args) { - test(new CriticalSection()); - test(new SynchronizedMethod()); - } -} -/* Output: --> 243 --> 243 --> 243 --> 243 -CriticalSection: 972 --> 69 --> 61 --> 83 --> 36 -SynchronizedMethod: 249 -*/ diff --git a/code/lowlevel/SynchronizedEvenProducer.java b/code/lowlevel/SynchronizedEvenProducer.java deleted file mode 100644 index 377aeecb..00000000 --- a/code/lowlevel/SynchronizedEvenProducer.java +++ /dev/null @@ -1,24 +0,0 @@ -// lowlevel/SynchronizedEvenProducer.java -// (c)2020 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. -// Simplifying mutexes with the synchronized keyword -import onjava.Nap; - -public class -SynchronizedEvenProducer extends IntGenerator { - private int currentEvenValue = 0; - @Override - public synchronized int next() { - ++currentEvenValue; - new Nap(0.01); // Cause failure faster - ++currentEvenValue; - return currentEvenValue; - } - public static void main(String[] args) { - EvenChecker.test(new SynchronizedEvenProducer()); - } -} -/* Output: -No odd numbers discovered -*/ diff --git a/code/lowlevel/SynchronizedSerialNumbers.java b/code/lowlevel/SynchronizedSerialNumbers.java deleted file mode 100644 index 1739d840..00000000 --- a/code/lowlevel/SynchronizedSerialNumbers.java +++ /dev/null @@ -1,19 +0,0 @@ -// lowlevel/SynchronizedSerialNumbers.java -// (c)2020 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. - -public class -SynchronizedSerialNumbers extends SerialNumbers { - private int serialNumber = 0; - public synchronized int nextSerialNumber() { - return serialNumber++; - } - public static void main(String[] args) { - SerialNumberChecker.test( - new SynchronizedSerialNumbers()); - } -} -/* Output: -No duplicates detected -*/ diff --git a/code/lowlevel/TestAbort.java b/code/lowlevel/TestAbort.java deleted file mode 100644 index a9efe528..00000000 --- a/code/lowlevel/TestAbort.java +++ /dev/null @@ -1,17 +0,0 @@ -// lowlevel/TestAbort.java -// (c)2020 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. -import onjava.*; - -public class TestAbort { - public static void main(String[] args) { - new TimedAbort(1); - System.out.println("Napping for 4"); - new Nap(4); - } -} -/* Output: -Napping for 4 -TimedAbort 1.0 -*/ diff --git a/code/lowlevel/ThreadSize.java b/code/lowlevel/ThreadSize.java deleted file mode 100644 index 0f00023d..00000000 --- a/code/lowlevel/ThreadSize.java +++ /dev/null @@ -1,31 +0,0 @@ -// lowlevel/ThreadSize.java -// (c)2020 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. -// {ExcludeFromGradle} Takes a long time or hangs -import java.util.concurrent.*; -import onjava.Nap; - -public class ThreadSize { - static class Dummy extends Thread { - @Override - public void run() { new Nap(1); } - } - public static void main(String[] args) { - ExecutorService exec = - Executors.newCachedThreadPool(); - int count = 0; - try { - while(true) { - exec.execute(new Dummy()); - count++; - } - } catch(Error e) { - System.out.println( - e.getClass().getSimpleName() + ": " + count); - System.exit(0); - } finally { - exec.shutdown(); - } - } -} diff --git a/code/lowlevel/UnsafeReturn.java b/code/lowlevel/UnsafeReturn.java deleted file mode 100644 index c2481fc0..00000000 --- a/code/lowlevel/UnsafeReturn.java +++ /dev/null @@ -1,20 +0,0 @@ -// lowlevel/UnsafeReturn.java -// (c)2020 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. -import java.util.function.*; -import java.util.concurrent.*; - -public class UnsafeReturn extends IntTestable { - private int i = 0; - public int getAsInt() { return i; } - public synchronized void evenIncrement() { - i++; i++; - } - public static void main(String[] args) { - Atomicity.test(new UnsafeReturn()); - } -} -/* Output: -failed with: 79 -*/ diff --git a/code/lowlevel/WorkStealingPool.java b/code/lowlevel/WorkStealingPool.java deleted file mode 100644 index 984de706..00000000 --- a/code/lowlevel/WorkStealingPool.java +++ /dev/null @@ -1,41 +0,0 @@ -// lowlevel/WorkStealingPool.java -// (c)2020 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. -import java.util.stream.*; -import java.util.concurrent.*; - -class ShowThread implements Runnable { - @Override - public void run() { - System.out.println( - Thread.currentThread().getName()); - } -} - -public class WorkStealingPool { - public static void main(String[] args) - throws InterruptedException { - System.out.println( - Runtime.getRuntime().availableProcessors()); - ExecutorService exec = - Executors.newWorkStealingPool(); - IntStream.range(0, 10) - .mapToObj(n -> new ShowThread()) - .forEach(exec::execute); - exec.awaitTermination(1, TimeUnit.SECONDS); - } -} -/* Output: -8 -ForkJoinPool-1-worker-2 -ForkJoinPool-1-worker-1 -ForkJoinPool-1-worker-2 -ForkJoinPool-1-worker-3 -ForkJoinPool-1-worker-2 -ForkJoinPool-1-worker-1 -ForkJoinPool-1-worker-3 -ForkJoinPool-1-worker-1 -ForkJoinPool-1-worker-4 -ForkJoinPool-1-worker-2 -*/ diff --git a/code/newio/AvailableCharSets.java b/code/newio/AvailableCharSets.java deleted file mode 100644 index eda3b93c..00000000 --- a/code/newio/AvailableCharSets.java +++ /dev/null @@ -1,43 +0,0 @@ -// newio/AvailableCharSets.java -// (c)2020 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. -// Displays Charsets and aliases -import java.nio.charset.*; -import java.util.*; - -public class AvailableCharSets { - public static void main(String[] args) { - SortedMap charSets = - Charset.availableCharsets(); - for(String csName : charSets.keySet()) { - System.out.print(csName); - Iterator aliases = charSets.get(csName) - .aliases().iterator(); - if(aliases.hasNext()) - System.out.print(": "); - while(aliases.hasNext()) { - System.out.print(aliases.next()); - if(aliases.hasNext()) - System.out.print(", "); - } - System.out.println(); - } - } -} -/* Output: (First 7 Lines) -Big5: csBig5 -Big5-HKSCS: big5-hkscs, big5hk, Big5_HKSCS, big5hkscs -CESU-8: CESU8, csCESU-8 -EUC-JP: csEUCPkdFmtjapanese, x-euc-jp, eucjis, -Extended_UNIX_Code_Packed_Format_for_Japanese, euc_jp, -eucjp, x-eucjp -EUC-KR: ksc5601-1987, csEUCKR, ksc5601_1987, ksc5601, -5601, -euc_kr, ksc_5601, ks_c_5601-1987, euckr -GB18030: gb18030-2000 -GB2312: gb2312, euc-cn, x-EUC-CN, euccn, EUC_CN, -gb2312-80, -gb2312-1980 - ... -*/ diff --git a/code/newio/BufferToText.java b/code/newio/BufferToText.java deleted file mode 100644 index 2f38c2c6..00000000 --- a/code/newio/BufferToText.java +++ /dev/null @@ -1,93 +0,0 @@ -// newio/BufferToText.java -// (c)2020 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. -// Converting text to and from ByteBuffers -import java.nio.*; -import java.nio.channels.*; -import java.nio.charset.*; -import java.io.*; - -public class BufferToText { - private static final int BSIZE = 1024; - public static void main(String[] args) { - try( - FileChannel fc = new FileOutputStream( - "data2.txt").getChannel() - ) { - fc.write(ByteBuffer.wrap("Some text".getBytes())); - } catch(IOException e) { - throw new RuntimeException(e); - } - ByteBuffer buff = ByteBuffer.allocate(BSIZE); - try( - FileChannel fc = new FileInputStream( - "data2.txt").getChannel() - ) { - fc.read(buff); - } catch(IOException e) { - throw new RuntimeException(e); - } - buff.flip(); - // Doesn't work: - System.out.println(buff.asCharBuffer()); - // Decode using this system's default Charset: - buff.rewind(); - String encoding = - System.getProperty("file.encoding"); - System.out.println("Decoded using " + - encoding + ": " - + Charset.forName(encoding).decode(buff)); - // Encode with something that prints: - try( - FileChannel fc = new FileOutputStream( - "data2.txt").getChannel() - ) { - fc.write(ByteBuffer.wrap( - "Some text".getBytes("UTF-16BE"))); - } catch(IOException e) { - throw new RuntimeException(e); - } - // Now try reading again: - buff.clear(); - try( - FileChannel fc = new FileInputStream( - "data2.txt").getChannel() - ) { - fc.read(buff); - } catch(IOException e) { - throw new RuntimeException(e); - } - buff.flip(); - System.out.println(buff.asCharBuffer()); - // Use a CharBuffer to write through: - buff = ByteBuffer.allocate(24); - buff.asCharBuffer().put("Some text"); - try( - FileChannel fc = new FileOutputStream( - "data2.txt").getChannel() - ) { - fc.write(buff); - } catch(IOException e) { - throw new RuntimeException(e); - } - // Read and display: - buff.clear(); - try( - FileChannel fc = new FileInputStream( - "data2.txt").getChannel() - ) { - fc.read(buff); - } catch(IOException e) { - throw new RuntimeException(e); - } - buff.flip(); - System.out.println(buff.asCharBuffer()); - } -} -/* Output: -???? -Decoded using windows-1252: Some text -Some text -Some textNULNULNUL -*/ diff --git a/code/newio/ChannelCopy.java b/code/newio/ChannelCopy.java deleted file mode 100644 index 84696131..00000000 --- a/code/newio/ChannelCopy.java +++ /dev/null @@ -1,35 +0,0 @@ -// newio/ChannelCopy.java -// (c)2020 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. -// Copying a file using channels and buffers -// {java ChannelCopy ChannelCopy.java test.txt} -import java.nio.*; -import java.nio.channels.*; -import java.io.*; - -public class ChannelCopy { - private static final int BSIZE = 1024; - public static void main(String[] args) { - if(args.length != 2) { - System.out.println( - "arguments: sourcefile destfile"); - System.exit(1); - } - try( - FileChannel in = new FileInputStream( - args[0]).getChannel(); - FileChannel out = new FileOutputStream( - args[1]).getChannel() - ) { - ByteBuffer buffer = ByteBuffer.allocate(BSIZE); - while(in.read(buffer) != -1) { - buffer.flip(); // Prepare for writing - out.write(buffer); - buffer.clear(); // Prepare for reading - } - } catch(IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/code/newio/Endians.java b/code/newio/Endians.java deleted file mode 100644 index 11d66076..00000000 --- a/code/newio/Endians.java +++ /dev/null @@ -1,28 +0,0 @@ -// newio/Endians.java -// (c)2020 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. -// Endian differences and data storage -import java.nio.*; -import java.util.*; - -public class Endians { - public static void main(String[] args) { - ByteBuffer bb = ByteBuffer.wrap(new byte[12]); - bb.asCharBuffer().put("abcdef"); - System.out.println(Arrays.toString(bb.array())); - bb.rewind(); - bb.order(ByteOrder.BIG_ENDIAN); - bb.asCharBuffer().put("abcdef"); - System.out.println(Arrays.toString(bb.array())); - bb.rewind(); - bb.order(ByteOrder.LITTLE_ENDIAN); - bb.asCharBuffer().put("abcdef"); - System.out.println(Arrays.toString(bb.array())); - } -} -/* Output: -[0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102] -[0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102] -[97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0] -*/ diff --git a/code/newio/FileLocking.java b/code/newio/FileLocking.java deleted file mode 100644 index e8c74d2a..00000000 --- a/code/newio/FileLocking.java +++ /dev/null @@ -1,30 +0,0 @@ -// newio/FileLocking.java -// (c)2020 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. -import java.nio.channels.*; -import java.util.concurrent.*; -import java.io.*; - -public class FileLocking { - public static void main(String[] args) { - try( - FileOutputStream fos = - new FileOutputStream("file.txt"); - FileLock fl = fos.getChannel().tryLock() - ) { - if(fl != null) { - System.out.println("Locked File"); - TimeUnit.MILLISECONDS.sleep(100); - fl.release(); - System.out.println("Released Lock"); - } - } catch(IOException | InterruptedException e) { - throw new RuntimeException(e); - } - } -} -/* Output: -Locked File -Released Lock -*/ diff --git a/code/newio/GetChannel.java b/code/newio/GetChannel.java deleted file mode 100644 index 16caa340..00000000 --- a/code/newio/GetChannel.java +++ /dev/null @@ -1,53 +0,0 @@ -// newio/GetChannel.java -// (c)2020 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. -// Getting channels from streams -import java.nio.*; -import java.nio.channels.*; -import java.io.*; - -public class GetChannel { - private static String name = "data.txt"; - private static final int BSIZE = 1024; - public static void main(String[] args) { - // Write a file: - try( - FileChannel fc = new FileOutputStream(name) - .getChannel() - ) { - fc.write(ByteBuffer - .wrap("Some text ".getBytes())); - } catch(IOException e) { - throw new RuntimeException(e); - } - // Add to the end of the file: - try( - FileChannel fc = new RandomAccessFile( - name, "rw").getChannel() - ) { - fc.position(fc.size()); // Move to the end - fc.write(ByteBuffer - .wrap("Some more".getBytes())); - } catch(IOException e) { - throw new RuntimeException(e); - } - // Read the file: - try( - FileChannel fc = new FileInputStream(name) - .getChannel() - ) { - ByteBuffer buff = ByteBuffer.allocate(BSIZE); - fc.read(buff); - buff.flip(); - while(buff.hasRemaining()) - System.out.write(buff.get()); - } catch(IOException e) { - throw new RuntimeException(e); - } - System.out.flush(); - } -} -/* Output: -Some text Some more -*/ diff --git a/code/newio/GetData.java b/code/newio/GetData.java deleted file mode 100644 index b2518b10..00000000 --- a/code/newio/GetData.java +++ /dev/null @@ -1,56 +0,0 @@ -// newio/GetData.java -// (c)2020 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. -// Getting different representations from a ByteBuffer -import java.nio.*; - -public class GetData { - private static final int BSIZE = 1024; - public static void main(String[] args) { - ByteBuffer bb = ByteBuffer.allocate(BSIZE); - // Allocation automatically zeroes the ByteBuffer: - int i = 0; - while(i++ < bb.limit()) - if(bb.get() != 0) - System.out.println("nonzero"); - System.out.println("i = " + i); - bb.rewind(); - // Store and read a char array: - bb.asCharBuffer().put("Howdy!"); - char c; - while((c = bb.getChar()) != 0) - System.out.print(c + " "); - System.out.println(); - bb.rewind(); - // Store and read a short: - bb.asShortBuffer().put((short)471142); - System.out.println(bb.getShort()); - bb.rewind(); - // Store and read an int: - bb.asIntBuffer().put(99471142); - System.out.println(bb.getInt()); - bb.rewind(); - // Store and read a long: - bb.asLongBuffer().put(99471142); - System.out.println(bb.getLong()); - bb.rewind(); - // Store and read a float: - bb.asFloatBuffer().put(99471142); - System.out.println(bb.getFloat()); - bb.rewind(); - // Store and read a double: - bb.asDoubleBuffer().put(99471142); - System.out.println(bb.getDouble()); - bb.rewind(); - } -} -/* Output: -i = 1025 -H o w d y ! -12390 -99471142 -99471142 -9.9471144E7 -9.9471142E7 -*/ diff --git a/code/newio/IntBufferDemo.java b/code/newio/IntBufferDemo.java deleted file mode 100644 index 31ffaa8f..00000000 --- a/code/newio/IntBufferDemo.java +++ /dev/null @@ -1,35 +0,0 @@ -// newio/IntBufferDemo.java -// (c)2020 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. -// Manipulating ints in a ByteBuffer with an IntBuffer -import java.nio.*; - -public class IntBufferDemo { - private static final int BSIZE = 1024; - public static void main(String[] args) { - ByteBuffer bb = ByteBuffer.allocate(BSIZE); - IntBuffer ib = bb.asIntBuffer(); - // Store an array of int: - ib.put(new int[]{ 11, 42, 47, 99, 143, 811, 1016 }); - // Absolute location read and write: - System.out.println(ib.get(3)); - ib.put(3, 1811); - // Setting a new limit before rewinding the buffer. - ib.flip(); - while(ib.hasRemaining()) { - int i = ib.get(); - System.out.println(i); - } - } -} -/* Output: -99 -11 -42 -47 -1811 -143 -811 -1016 -*/ diff --git a/code/newio/LargeMappedFiles.java b/code/newio/LargeMappedFiles.java deleted file mode 100644 index c4976e45..00000000 --- a/code/newio/LargeMappedFiles.java +++ /dev/null @@ -1,31 +0,0 @@ -// newio/LargeMappedFiles.java -// (c)2020 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. -// Creating a very large file using mapping -import java.nio.*; -import java.nio.channels.*; -import java.io.*; - -public class LargeMappedFiles { - static int length = 0x8000000; // 128 MB - public static void - main(String[] args) throws Exception { - try( - RandomAccessFile tdat = - new RandomAccessFile("test.dat", "rw") - ) { - MappedByteBuffer out = tdat.getChannel().map( - FileChannel.MapMode.READ_WRITE, 0, length); - for(int i = 0; i < length; i++) - out.put((byte)'x'); - System.out.println("Finished writing"); - for(int i = length/2; i < length/2 + 6; i++) - System.out.print((char)out.get(i)); - } - } -} -/* Output: -Finished writing -xxxxxx -*/ diff --git a/code/newio/LockingMappedFiles.java b/code/newio/LockingMappedFiles.java deleted file mode 100644 index 6fe8fee5..00000000 --- a/code/newio/LockingMappedFiles.java +++ /dev/null @@ -1,60 +0,0 @@ -// newio/LockingMappedFiles.java -// (c)2020 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. -// Locking portions of a mapped file -import java.nio.*; -import java.nio.channels.*; -import java.io.*; - -public class LockingMappedFiles { - static final int LENGTH = 0x8FFFFFF; // 128 MB - static FileChannel fc; - public static void - main(String[] args) throws Exception { - fc = new RandomAccessFile("test.dat", "rw") - .getChannel(); - MappedByteBuffer out = fc.map( - FileChannel.MapMode.READ_WRITE, 0, LENGTH); - for(int i = 0; i < LENGTH; i++) - out.put((byte)'x'); - new LockAndModify(out, 0, 0 + LENGTH/3); - new LockAndModify( - out, LENGTH/2, LENGTH/2 + LENGTH/4); - } - private static class LockAndModify extends Thread { - private ByteBuffer buff; - private int start, end; - LockAndModify(ByteBuffer mbb, int start, int end) { - this.start = start; - this.end = end; - mbb.limit(end); - mbb.position(start); - buff = mbb.slice(); - start(); - } - @Override - public void run() { - try { - // Exclusive lock with no overlap: - FileLock fl = fc.lock(start, end, false); - System.out.println( - "Locked: "+ start +" to "+ end); - // Perform modification: - while(buff.position() < buff.limit() - 1) - buff.put((byte)(buff.get() + 1)); - fl.release(); - System.out.println( - "Released: " + start + " to " + end); - } catch(IOException e) { - throw new RuntimeException(e); - } - } - } -} -/* Output: -Locked: 75497471 to 113246206 -Locked: 0 to 50331647 -Released: 75497471 to 113246206 -Released: 0 to 50331647 -*/ diff --git a/code/newio/MappedIO.java b/code/newio/MappedIO.java deleted file mode 100644 index 93b4ddf3..00000000 --- a/code/newio/MappedIO.java +++ /dev/null @@ -1,145 +0,0 @@ -// newio/MappedIO.java -// (c)2020 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. -// {ExcludeFromGradle} Runs too long under WSL2 -import java.util.*; -import java.nio.*; -import java.nio.channels.*; -import java.io.*; - -public class MappedIO { - private static int numOfInts = 4_000_000; - private static int numOfUbuffInts = 100_000; - private abstract static class Tester { - private String name; - Tester(String name) { - this.name = name; - } - public void runTest() { - System.out.print(name + ": "); - long start = System.nanoTime(); - test(); - double duration = System.nanoTime() - start; - System.out.format("%.3f%n", duration/1.0e9); - } - public abstract void test(); - } - private static Tester[] tests = { - new Tester("Stream Write") { - @Override - public void test() { - try( - DataOutputStream dos = - new DataOutputStream( - new BufferedOutputStream( - new FileOutputStream( - new File("temp.tmp")))) - ) { - for(int i = 0; i < numOfInts; i++) - dos.writeInt(i); - } catch(IOException e) { - throw new RuntimeException(e); - } - } - }, - new Tester("Mapped Write") { - @Override - public void test() { - try( - FileChannel fc = - new RandomAccessFile("temp.tmp", "rw") - .getChannel() - ) { - IntBuffer ib = - fc.map(FileChannel.MapMode.READ_WRITE, - 0, fc.size()).asIntBuffer(); - for(int i = 0; i < numOfInts; i++) - ib.put(i); - } catch(IOException e) { - throw new RuntimeException(e); - } - } - }, - new Tester("Stream Read") { - @Override - public void test() { - try( - DataInputStream dis = - new DataInputStream( - new BufferedInputStream( - new FileInputStream("temp.tmp"))) - ) { - for(int i = 0; i < numOfInts; i++) - dis.readInt(); - } catch(IOException e) { - throw new RuntimeException(e); - } - } - }, - new Tester("Mapped Read") { - @Override - public void test() { - try( - FileChannel fc = new FileInputStream( - new File("temp.tmp")).getChannel() - ) { - IntBuffer ib = - fc.map(FileChannel.MapMode.READ_ONLY, - 0, fc.size()).asIntBuffer(); - while(ib.hasRemaining()) - ib.get(); - } catch(IOException e) { - throw new RuntimeException(e); - } - } - }, - new Tester("Stream Read/Write") { - @Override - public void test() { - try( - RandomAccessFile raf = - new RandomAccessFile( - new File("temp.tmp"), "rw") - ) { - raf.writeInt(1); - for(int i = 0; i < numOfUbuffInts; i++) { - raf.seek(raf.length() - 4); - raf.writeInt(raf.readInt()); - } - } catch(IOException e) { - throw new RuntimeException(e); - } - } - }, - new Tester("Mapped Read/Write") { - @Override - public void test() { - try( - FileChannel fc = new RandomAccessFile( - new File("temp.tmp"), "rw").getChannel() - ) { - IntBuffer ib = - fc.map(FileChannel.MapMode.READ_WRITE, - 0, fc.size()).asIntBuffer(); - ib.put(0); - for(int i = 1; i < numOfUbuffInts; i++) - ib.put(ib.get(i - 1)); - } catch(IOException e) { - throw new RuntimeException(e); - } - } - } - }; - public static void main(String[] args) { - Arrays.stream(tests).forEach(Tester::runTest); - } -} -/* Output: -Stream Write: 0.615 -Mapped Write: 0.050 -Stream Read: 0.577 -Mapped Read: 0.015 -Stream Read/Write: 4.069 -Mapped Read/Write: 0.013 -*/ diff --git a/code/newio/TransferTo.java b/code/newio/TransferTo.java deleted file mode 100644 index f3095b71..00000000 --- a/code/newio/TransferTo.java +++ /dev/null @@ -1,30 +0,0 @@ -// newio/TransferTo.java -// (c)2020 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. -// Using transferTo() between channels -// {java TransferTo TransferTo.java TransferTo.txt} -import java.nio.channels.*; -import java.io.*; - -public class TransferTo { - public static void main(String[] args) { - if(args.length != 2) { - System.out.println( - "arguments: sourcefile destfile"); - System.exit(1); - } - try( - FileChannel in = new FileInputStream( - args[0]).getChannel(); - FileChannel out = new FileOutputStream( - args[1]).getChannel() - ) { - in.transferTo(0, in.size(), out); - // Or: - // out.transferFrom(in, 0, in.size()); - } catch(IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/code/newio/UsingBuffers.java b/code/newio/UsingBuffers.java deleted file mode 100644 index 3f3a6bd1..00000000 --- a/code/newio/UsingBuffers.java +++ /dev/null @@ -1,35 +0,0 @@ -// newio/UsingBuffers.java -// (c)2020 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. -import java.nio.*; - -public class UsingBuffers { - private static - void symmetricScramble(CharBuffer buffer) { - while(buffer.hasRemaining()) { - buffer.mark(); - char c1 = buffer.get(); - char c2 = buffer.get(); - buffer.reset(); - buffer.put(c2).put(c1); - } - } - public static void main(String[] args) { - char[] data = "UsingBuffers".toCharArray(); - ByteBuffer bb = - ByteBuffer.allocate(data.length * 2); - CharBuffer cb = bb.asCharBuffer(); - cb.put(data); - System.out.println(cb.rewind()); - symmetricScramble(cb); - System.out.println(cb.rewind()); - symmetricScramble(cb); - System.out.println(cb.rewind()); - } -} -/* Output: -UsingBuffers -sUniBgfuefsr -UsingBuffers -*/ diff --git a/code/newio/ViewBuffers.java b/code/newio/ViewBuffers.java deleted file mode 100644 index d7bb1adf..00000000 --- a/code/newio/ViewBuffers.java +++ /dev/null @@ -1,69 +0,0 @@ -// newio/ViewBuffers.java -// (c)2020 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. -import java.nio.*; - -public class ViewBuffers { - public static void main(String[] args) { - ByteBuffer bb = ByteBuffer.wrap( - new byte[]{ 0, 0, 0, 0, 0, 0, 0, 'a' }); - bb.rewind(); - System.out.print("Byte Buffer "); - while(bb.hasRemaining()) - System.out.print( - bb.position()+ " -> " + bb.get() + ", "); - System.out.println(); - CharBuffer cb = - ((ByteBuffer)bb.rewind()).asCharBuffer(); - System.out.print("Char Buffer "); - while(cb.hasRemaining()) - System.out.print( - cb.position() + " -> " + cb.get() + ", "); - System.out.println(); - FloatBuffer fb = - ((ByteBuffer)bb.rewind()).asFloatBuffer(); - System.out.print("Float Buffer "); - while(fb.hasRemaining()) - System.out.print( - fb.position()+ " -> " + fb.get() + ", "); - System.out.println(); - IntBuffer ib = - ((ByteBuffer)bb.rewind()).asIntBuffer(); - System.out.print("Int Buffer "); - while(ib.hasRemaining()) - System.out.print( - ib.position()+ " -> " + ib.get() + ", "); - System.out.println(); - LongBuffer lb = - ((ByteBuffer)bb.rewind()).asLongBuffer(); - System.out.print("Long Buffer "); - while(lb.hasRemaining()) - System.out.print( - lb.position()+ " -> " + lb.get() + ", "); - System.out.println(); - ShortBuffer sb = - ((ByteBuffer)bb.rewind()).asShortBuffer(); - System.out.print("Short Buffer "); - while(sb.hasRemaining()) - System.out.print( - sb.position()+ " -> " + sb.get() + ", "); - System.out.println(); - DoubleBuffer db = - ((ByteBuffer)bb.rewind()).asDoubleBuffer(); - System.out.print("Double Buffer "); - while(db.hasRemaining()) - System.out.print( - db.position()+ " -> " + db.get() + ", "); - } -} -/* Output: -Byte Buffer 0 -> 0, 1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0, 5 --> 0, 6 -> 0, 7 -> 97, -Char Buffer 0 -> NUL, 1 -> NUL, 2 -> NUL, 3 -> a, -Float Buffer 0 -> 0.0, 1 -> 1.36E-43, -Int Buffer 0 -> 0, 1 -> 97, -Long Buffer 0 -> 97, -Short Buffer 0 -> 0, 1 -> 0, 2 -> 0, 3 -> 97, -Double Buffer 0 -> 4.8E-322, -*/ diff --git a/code/objects/HelloDate.java b/code/objects/HelloDate.java deleted file mode 100644 index 1f613e8e..00000000 --- a/code/objects/HelloDate.java +++ /dev/null @@ -1,12 +0,0 @@ -// objects/HelloDate.java -// (c)2020 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. -import java.util.*; - -public class HelloDate { - public static void main(String[] args) { - System.out.println("Hello, it's: "); - System.out.println(new Date()); - } -} diff --git a/code/objects/ShowProperties.java b/code/objects/ShowProperties.java deleted file mode 100644 index ac2bf41e..00000000 --- a/code/objects/ShowProperties.java +++ /dev/null @@ -1,39 +0,0 @@ -// objects/ShowProperties.java -// (c)2020 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. - -public class ShowProperties { - public static void main(String[] args) { - System.getProperties().list(System.out); - System.out.println(System.getProperty("user.name")); - System.out.println( - System.getProperty("java.library.path")); - } -} -/* Output: (First 20 Lines) --- listing properties -- -java.runtime.name=Java(TM) SE Runtime Environment -sun.boot.library.path=C:\Program -Files\Java\jdk1.8.0_112\jr... -java.vm.version=25.112-b15 -java.vm.vendor=Oracle Corporation -java.vendor.url=http://java.oracle.com/ -path.separator=; -java.vm.name=Java HotSpot(TM) 64-Bit Server VM -file.encoding.pkg=sun.io -user.script= -user.country=US -sun.java.launcher=SUN_STANDARD -sun.os.patch.level= -java.vm.specification.name=Java Virtual Machine -Specification -user.dir=C:\Users\Bruce\Documents\GitHub\on-ja... -java.runtime.version=1.8.0_112-b15 -java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment -java.endorsed.dirs=C:\Program -Files\Java\jdk1.8.0_112\jr... -os.arch=amd64 -java.io.tmpdir=C:\Users\Bruce\AppData\Local\Temp\ - ... -*/ diff --git a/code/onjava/ArrayShow.java b/code/onjava/ArrayShow.java deleted file mode 100644 index 6edd148f..00000000 --- a/code/onjava/ArrayShow.java +++ /dev/null @@ -1,73 +0,0 @@ -// onjava/ArrayShow.java -// (c)2020 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 onjava; -import java.util.*; - -public interface ArrayShow { - static void show(Object[] a) { - System.out.println(Arrays.toString(a)); - } - static void show(boolean[] a) { - System.out.println(Arrays.toString(a)); - } - static void show(byte[] a) { - System.out.println(Arrays.toString(a)); - } - static void show(char[] a) { - System.out.println(Arrays.toString(a)); - } - static void show(short[] a) { - System.out.println(Arrays.toString(a)); - } - static void show(int[] a) { - System.out.println(Arrays.toString(a)); - } - static void show(long[] a) { - System.out.println(Arrays.toString(a)); - } - static void show(float[] a) { - System.out.println(Arrays.toString(a)); - } - static void show(double[] a) { - System.out.println(Arrays.toString(a)); - } - // Start with a description: - static void show(String info, Object[] a) { - System.out.print(info + ": "); - show(a); - } - static void show(String info, boolean[] a) { - System.out.print(info + ": "); - show(a); - } - static void show(String info, byte[] a) { - System.out.print(info + ": "); - show(a); - } - static void show(String info, char[] a) { - System.out.print(info + ": "); - show(a); - } - static void show(String info, short[] a) { - System.out.print(info + ": "); - show(a); - } - static void show(String info, int[] a) { - System.out.print(info + ": "); - show(a); - } - static void show(String info, long[] a) { - System.out.print(info + ": "); - show(a); - } - static void show(String info, float[] a) { - System.out.print(info + ": "); - show(a); - } - static void show(String info, double[] a) { - System.out.print(info + ": "); - show(a); - } -} diff --git a/code/onjava/BasicSupplier.java b/code/onjava/BasicSupplier.java deleted file mode 100644 index d4bf3b3d..00000000 --- a/code/onjava/BasicSupplier.java +++ /dev/null @@ -1,31 +0,0 @@ -// onjava/BasicSupplier.java -// (c)2020 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. -// Supplier from a class with a no-arg constructor -package onjava; -import java.util.function.*; -import java.lang.reflect.InvocationTargetException; - -public class BasicSupplier implements Supplier { - private Class type; - public BasicSupplier(Class type) { - this.type = type; - } - @Override - public T get() { - try { - // Assumes type is a public class: - return type.getConstructor().newInstance(); - } catch(InstantiationException | - NoSuchMethodException | - InvocationTargetException | - IllegalAccessException e) { - throw new RuntimeException(e); - } - } - // Produce a default Supplier from a type token: - public static Supplier create(Class type) { - return new BasicSupplier<>(type); - } -} diff --git a/code/onjava/CollectionMethodDifferences.java b/code/onjava/CollectionMethodDifferences.java deleted file mode 100644 index 375d4e41..00000000 --- a/code/onjava/CollectionMethodDifferences.java +++ /dev/null @@ -1,117 +0,0 @@ -// onjava/CollectionMethodDifferences.java -// (c)2020 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. -// {java onjava.CollectionMethodDifferences} -package onjava; -import java.lang.reflect.*; -import java.util.*; -import java.util.stream.*; - -public class CollectionMethodDifferences { - static Set methodSet(Class type) { - return Arrays.stream(type.getMethods()) - .map(Method::getName) - .collect(Collectors.toCollection(TreeSet::new)); - } - static void interfaces(Class type) { - System.out.print("Interfaces in " + - type.getSimpleName() + ": "); - System.out.println( - Arrays.stream(type.getInterfaces()) - .map(Class::getSimpleName) - .collect(Collectors.toList())); - } - static Set object = methodSet(Object.class); - static { object.add("clone"); } - static void - difference(Class superset, Class subset) { - System.out.print(superset.getSimpleName() + - " extends " + subset.getSimpleName() + - ", adds: "); - Set comp = Sets.difference( - methodSet(superset), methodSet(subset)); - comp.removeAll(object); // Ignore 'Object' methods - System.out.println(comp); - interfaces(superset); - } - public static void main(String[] args) { - System.out.println("Collection: " + - methodSet(Collection.class)); - interfaces(Collection.class); - difference(Set.class, Collection.class); - difference(HashSet.class, Set.class); - difference(LinkedHashSet.class, HashSet.class); - difference(TreeSet.class, Set.class); - difference(List.class, Collection.class); - difference(ArrayList.class, List.class); - difference(LinkedList.class, List.class); - difference(Queue.class, Collection.class); - difference(PriorityQueue.class, Queue.class); - System.out.println("Map: " + methodSet(Map.class)); - difference(HashMap.class, Map.class); - difference(LinkedHashMap.class, HashMap.class); - difference(SortedMap.class, Map.class); - difference(TreeMap.class, Map.class); - } -} -/* Output: -Collection: [add, addAll, clear, contains, containsAll, -equals, forEach, hashCode, isEmpty, iterator, -parallelStream, remove, removeAll, removeIf, retainAll, -size, spliterator, stream, toArray] -Interfaces in Collection: [Iterable] -Set extends Collection, adds: [] -Interfaces in Set: [Collection] -HashSet extends Set, adds: [] -Interfaces in HashSet: [Set, Cloneable, Serializable] -LinkedHashSet extends HashSet, adds: [] -Interfaces in LinkedHashSet: [Set, Cloneable, -Serializable] -TreeSet extends Set, adds: [headSet, -descendingIterator, descendingSet, pollLast, subSet, -floor, tailSet, ceiling, last, lower, comparator, -pollFirst, first, higher] -Interfaces in TreeSet: [NavigableSet, Cloneable, -Serializable] -List extends Collection, adds: [replaceAll, get, -indexOf, subList, set, sort, lastIndexOf, listIterator] -Interfaces in List: [Collection] -ArrayList extends List, adds: [trimToSize, -ensureCapacity] -Interfaces in ArrayList: [List, RandomAccess, -Cloneable, Serializable] -LinkedList extends List, adds: [offerFirst, poll, -getLast, offer, getFirst, removeFirst, element, -removeLastOccurrence, peekFirst, peekLast, push, -pollFirst, removeFirstOccurrence, descendingIterator, -pollLast, removeLast, pop, addLast, peek, offerLast, -addFirst] -Interfaces in LinkedList: [List, Deque, Cloneable, -Serializable] -Queue extends Collection, adds: [poll, peek, offer, -element] -Interfaces in Queue: [Collection] -PriorityQueue extends Queue, adds: [comparator] -Interfaces in PriorityQueue: [Serializable] -Map: [clear, compute, computeIfAbsent, -computeIfPresent, containsKey, containsValue, entrySet, -equals, forEach, get, getOrDefault, hashCode, isEmpty, -keySet, merge, put, putAll, putIfAbsent, remove, -replace, replaceAll, size, values] -HashMap extends Map, adds: [] -Interfaces in HashMap: [Map, Cloneable, Serializable] -LinkedHashMap extends HashMap, adds: [] -Interfaces in LinkedHashMap: [Map] -SortedMap extends Map, adds: [lastKey, subMap, -comparator, firstKey, headMap, tailMap] -Interfaces in SortedMap: [Map] -TreeMap extends Map, adds: [descendingKeySet, -navigableKeySet, higherEntry, higherKey, floorKey, -subMap, ceilingKey, pollLastEntry, firstKey, lowerKey, -headMap, tailMap, lowerEntry, ceilingEntry, -descendingMap, pollFirstEntry, lastKey, firstEntry, -floorEntry, comparator, lastEntry] -Interfaces in TreeMap: [NavigableMap, Cloneable, -Serializable] -*/ diff --git a/code/onjava/ConvertTo.java b/code/onjava/ConvertTo.java deleted file mode 100644 index cc8febd7..00000000 --- a/code/onjava/ConvertTo.java +++ /dev/null @@ -1,105 +0,0 @@ -// onjava/ConvertTo.java -// (c)2020 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 onjava; - -public interface ConvertTo { - static boolean[] primitive(Boolean[] in) { - boolean[] result = new boolean[in.length]; - for(int i = 0; i < in.length; i++) - result[i] = in[i]; // Autounboxing - return result; - } - static char[] primitive(Character[] in) { - char[] result = new char[in.length]; - for(int i = 0; i < in.length; i++) - result[i] = in[i]; - return result; - } - static byte[] primitive(Byte[] in) { - byte[] result = new byte[in.length]; - for(int i = 0; i < in.length; i++) - result[i] = in[i]; - return result; - } - static short[] primitive(Short[] in) { - short[] result = new short[in.length]; - for(int i = 0; i < in.length; i++) - result[i] = in[i]; - return result; - } - static int[] primitive(Integer[] in) { - int[] result = new int[in.length]; - for(int i = 0; i < in.length; i++) - result[i] = in[i]; - return result; - } - static long[] primitive(Long[] in) { - long[] result = new long[in.length]; - for(int i = 0; i < in.length; i++) - result[i] = in[i]; - return result; - } - static float[] primitive(Float[] in) { - float[] result = new float[in.length]; - for(int i = 0; i < in.length; i++) - result[i] = in[i]; - return result; - } - static double[] primitive(Double[] in) { - double[] result = new double[in.length]; - for(int i = 0; i < in.length; i++) - result[i] = in[i]; - return result; - } - // Convert from primitive array to wrapped array: - static Boolean[] boxed(boolean[] in) { - Boolean[] result = new Boolean[in.length]; - for(int i = 0; i < in.length; i++) - result[i] = in[i]; // Autoboxing - return result; - } - static Character[] boxed(char[] in) { - Character[] result = new Character[in.length]; - for(int i = 0; i < in.length; i++) - result[i] = in[i]; - return result; - } - static Byte[] boxed(byte[] in) { - Byte[] result = new Byte[in.length]; - for(int i = 0; i < in.length; i++) - result[i] = in[i]; - return result; - } - static Short[] boxed(short[] in) { - Short[] result = new Short[in.length]; - for(int i = 0; i < in.length; i++) - result[i] = in[i]; - return result; - } - static Integer[] boxed(int[] in) { - Integer[] result = new Integer[in.length]; - for(int i = 0; i < in.length; i++) - result[i] = in[i]; - return result; - } - static Long[] boxed(long[] in) { - Long[] result = new Long[in.length]; - for(int i = 0; i < in.length; i++) - result[i] = in[i]; - return result; - } - static Float[] boxed(float[] in) { - Float[] result = new Float[in.length]; - for(int i = 0; i < in.length; i++) - result[i] = in[i]; - return result; - } - static Double[] boxed(double[] in) { - Double[] result = new Double[in.length]; - for(int i = 0; i < in.length; i++) - result[i] = in[i]; - return result; - } -} diff --git a/code/onjava/Count.java b/code/onjava/Count.java deleted file mode 100644 index 1f380f87..00000000 --- a/code/onjava/Count.java +++ /dev/null @@ -1,220 +0,0 @@ -// onjava/Count.java -// (c)2020 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. -// Generate incremental values of different types -package onjava; -import java.util.*; -import java.util.function.*; -import static onjava.ConvertTo.*; - -public interface Count { - class Boolean - implements Supplier { - private boolean b = true; - @Override - public java.lang.Boolean get() { - b = !b; - return java.lang.Boolean.valueOf(b); - } - public java.lang.Boolean get(int n) { - return get(); - } - public java.lang.Boolean[] array(int sz) { - java.lang.Boolean[] result = - new java.lang.Boolean[sz]; - Arrays.setAll(result, n -> get()); - return result; - } - } - class Pboolean { - private boolean b = true; - public boolean get() { - b = !b; - return b; - } - public boolean get(int n) { return get(); } - public boolean[] array(int sz) { - return primitive(new Boolean().array(sz)); - } - } - class Byte - implements Supplier { - private byte b; - @Override - public java.lang.Byte get() { return b++; } - public java.lang.Byte get(int n) { - return get(); - } - public java.lang.Byte[] array(int sz) { - java.lang.Byte[] result = - new java.lang.Byte[sz]; - Arrays.setAll(result, n -> get()); - return result; - } - } - class Pbyte { - private byte b; - public byte get() { return b++; } - public byte get(int n) { return get(); } - public byte[] array(int sz) { - return primitive(new Byte().array(sz)); - } - } - char[] CHARS = - "abcdefghijklmnopqrstuvwxyz".toCharArray(); - class Character - implements Supplier { - private int i; - @Override - public java.lang.Character get() { - i = (i + 1) % CHARS.length; - return CHARS[i]; - } - public java.lang.Character get(int n) { - return get(); - } - public java.lang.Character[] array(int sz) { - java.lang.Character[] result = - new java.lang.Character[sz]; - Arrays.setAll(result, n -> get()); - return result; - } - } - class Pchar { - private int i; - public char get() { - i = (i + 1) % CHARS.length; - return CHARS[i]; - } - public char get(int n) { return get(); } - public char[] array(int sz) { - return primitive(new Character().array(sz)); - } - } - class Short - implements Supplier { - short s; - @Override - public java.lang.Short get() { return s++; } - public java.lang.Short get(int n) { - return get(); - } - public java.lang.Short[] array(int sz) { - java.lang.Short[] result = - new java.lang.Short[sz]; - Arrays.setAll(result, n -> get()); - return result; - } - } - class Pshort { - short s; - public short get() { return s++; } - public short get(int n) { return get(); } - public short[] array(int sz) { - return primitive(new Short().array(sz)); - } - } - class Integer - implements Supplier { - int i; - @Override - public java.lang.Integer get() { return i++; } - public java.lang.Integer get(int n) { - return get(); - } - public java.lang.Integer[] array(int sz) { - java.lang.Integer[] result = - new java.lang.Integer[sz]; - Arrays.setAll(result, n -> get()); - return result; - } - } - class Pint implements IntSupplier { - int i; - public int get() { return i++; } - public int get(int n) { return get(); } - @Override - public int getAsInt() { return get(); } - public int[] array(int sz) { - return primitive(new Integer().array(sz)); - } - } - class Long - implements Supplier { - private long l; - @Override - public java.lang.Long get() { return l++; } - public java.lang.Long get(int n) { - return get(); - } - public java.lang.Long[] array(int sz) { - java.lang.Long[] result = - new java.lang.Long[sz]; - Arrays.setAll(result, n -> get()); - return result; - } - } - class Plong implements LongSupplier { - private long l; - public long get() { return l++; } - public long get(int n) { return get(); } - @Override - public long getAsLong() { return get(); } - public long[] array(int sz) { - return primitive(new Long().array(sz)); - } - } - class Float - implements Supplier { - private int i; - @Override - public java.lang.Float get() { - return java.lang.Float.valueOf(i++); - } - public java.lang.Float get(int n) { - return get(); - } - public java.lang.Float[] array(int sz) { - java.lang.Float[] result = - new java.lang.Float[sz]; - Arrays.setAll(result, n -> get()); - return result; - } - } - class Pfloat { - private int i; - public float get() { return i++; } - public float get(int n) { return get(); } - public float[] array(int sz) { - return primitive(new Float().array(sz)); - } - } - class Double - implements Supplier { - private int i; - @Override - public java.lang.Double get() { - return java.lang.Double.valueOf(i++); - } - public java.lang.Double get(int n) { - return get(); - } - public java.lang.Double[] array(int sz) { - java.lang.Double[] result = - new java.lang.Double[sz]; - Arrays.setAll(result, n -> get()); - return result; - } - } - class Pdouble implements DoubleSupplier { - private int i; - public double get() { return i++; } - public double get(int n) { return get(); } - @Override - public double getAsDouble() { return get(0); } - public double[] array(int sz) { - return primitive(new Double().array(sz)); - } - } -} diff --git a/code/onjava/CountMap.java b/code/onjava/CountMap.java deleted file mode 100644 index e3759053..00000000 --- a/code/onjava/CountMap.java +++ /dev/null @@ -1,97 +0,0 @@ -// onjava/CountMap.java -// (c)2020 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. -// Unlimited-length Map containing sample data -// {java onjava.CountMap} -package onjava; -import java.util.*; -import java.util.stream.*; - -public class CountMap -extends AbstractMap { - private int size; - private static char[] chars = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); - private static String value(int key) { - return - chars[key % chars.length] + - Integer.toString(key / chars.length); - } - public CountMap(int size) { - this.size = size < 0 ? 0 : size; - } - @Override - public String get(Object key) { - return value((Integer)key); - } - private static class Entry - implements Map.Entry { - int index; - Entry(int index) { this.index = index; } - @Override - public boolean equals(Object o) { - return o instanceof Entry && - Objects.equals(index, ((Entry)o).index); - } - @Override - public Integer getKey() { return index; } - @Override - public String getValue() { - return value(index); - } - @Override - public String setValue(String value) { - throw new UnsupportedOperationException(); - } - @Override - public int hashCode() { - return Objects.hashCode(index); - } - } - @Override - public Set> entrySet() { - // LinkedHashSet retains initialization order: - return IntStream.range(0, size) - .mapToObj(Entry::new) - .collect(Collectors - .toCollection(LinkedHashSet::new)); - } - public static void main(String[] args) { - final int size = 6; - CountMap cm = new CountMap(60); - System.out.println(cm); - System.out.println(cm.get(500)); - cm.values().stream() - .limit(size) - .forEach(System.out::println); - System.out.println(); - new Random(47).ints(size, 0, 1000) - .mapToObj(cm::get) - .forEach(System.out::println); - } -} -/* Output: -{0=A0, 1=B0, 2=C0, 3=D0, 4=E0, 5=F0, 6=G0, 7=H0, 8=I0, -9=J0, 10=K0, 11=L0, 12=M0, 13=N0, 14=O0, 15=P0, 16=Q0, -17=R0, 18=S0, 19=T0, 20=U0, 21=V0, 22=W0, 23=X0, 24=Y0, -25=Z0, 26=A1, 27=B1, 28=C1, 29=D1, 30=E1, 31=F1, 32=G1, -33=H1, 34=I1, 35=J1, 36=K1, 37=L1, 38=M1, 39=N1, 40=O1, -41=P1, 42=Q1, 43=R1, 44=S1, 45=T1, 46=U1, 47=V1, 48=W1, -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 - -Y9 -J21 -R26 -D33 -Z36 -N16 -*/ diff --git a/code/onjava/CountingIntegerList.java b/code/onjava/CountingIntegerList.java deleted file mode 100644 index 7d5d4f79..00000000 --- a/code/onjava/CountingIntegerList.java +++ /dev/null @@ -1,34 +0,0 @@ -// onjava/CountingIntegerList.java -// (c)2020 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. -// List of any length, containing sample data -// {java onjava.CountingIntegerList} -package onjava; -import java.util.*; - -public class CountingIntegerList -extends AbstractList { - private int size; - public CountingIntegerList() { size = 0; } - public CountingIntegerList(int size) { - this.size = size < 0 ? 0 : size; - } - @Override - public Integer get(int index) { - return index; - } - @Override - public int size() { return size; } - public static void main(String[] args) { - List cil = - new CountingIntegerList(30); - System.out.println(cil); - System.out.println(cil.get(500)); - } -} -/* Output: -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29] -500 -*/ diff --git a/code/onjava/Countries.java b/code/onjava/Countries.java deleted file mode 100644 index ec42b592..00000000 --- a/code/onjava/Countries.java +++ /dev/null @@ -1,351 +0,0 @@ -// onjava/Countries.java -// (c)2020 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. -// "Flyweight" Maps and Lists of sample data -// {java onjava.Countries} -package onjava; -import java.util.*; - -public class Countries { - public static final String[][] DATA = { - // Africa - {"ALGERIA","Algiers"}, - {"ANGOLA","Luanda"}, - {"BENIN","Porto-Novo"}, - {"BOTSWANA","Gaberone"}, - {"BURKINA FASO","Ouagadougou"}, - {"BURUNDI","Bujumbura"}, - {"CAMEROON","Yaounde"}, - {"CAPE VERDE","Praia"}, - {"CENTRAL AFRICAN REPUBLIC","Bangui"}, - {"CHAD","N'djamena"}, - {"COMOROS","Moroni"}, - {"CONGO","Brazzaville"}, - {"DJIBOUTI","Dijibouti"}, - {"EGYPT","Cairo"}, - {"EQUATORIAL GUINEA","Malabo"}, - {"ERITREA","Asmara"}, - {"ETHIOPIA","Addis Ababa"}, - {"GABON","Libreville"}, - {"THE GAMBIA","Banjul"}, - {"GHANA","Accra"}, - {"GUINEA","Conakry"}, - {"BISSAU","Bissau"}, - {"COTE D'IVOIR (IVORY COAST)","Yamoussoukro"}, - {"KENYA","Nairobi"}, - {"LESOTHO","Maseru"}, - {"LIBERIA","Monrovia"}, - {"LIBYA","Tripoli"}, - {"MADAGASCAR","Antananarivo"}, - {"MALAWI","Lilongwe"}, - {"MALI","Bamako"}, - {"MAURITANIA","Nouakchott"}, - {"MAURITIUS","Port Louis"}, - {"MOROCCO","Rabat"}, - {"MOZAMBIQUE","Maputo"}, - {"NAMIBIA","Windhoek"}, - {"NIGER","Niamey"}, - {"NIGERIA","Abuja"}, - {"RWANDA","Kigali"}, - {"SAO TOME E PRINCIPE","Sao Tome"}, - {"SENEGAL","Dakar"}, - {"SEYCHELLES","Victoria"}, - {"SIERRA LEONE","Freetown"}, - {"SOMALIA","Mogadishu"}, - {"SOUTH AFRICA","Pretoria/Cape Town"}, - {"SUDAN","Khartoum"}, - {"SWAZILAND","Mbabane"}, - {"TANZANIA","Dodoma"}, - {"TOGO","Lome"}, - {"TUNISIA","Tunis"}, - {"UGANDA","Kampala"}, - {"DEMOCRATIC REPUBLIC OF THE CONGO (ZAIRE)", - "Kinshasa"}, - {"ZAMBIA","Lusaka"}, - {"ZIMBABWE","Harare"}, - // Asia - {"AFGHANISTAN","Kabul"}, - {"BAHRAIN","Manama"}, - {"BANGLADESH","Dhaka"}, - {"BHUTAN","Thimphu"}, - {"BRUNEI","Bandar Seri Begawan"}, - {"CAMBODIA","Phnom Penh"}, - {"CHINA","Beijing"}, - {"CYPRUS","Nicosia"}, - {"INDIA","New Delhi"}, - {"INDONESIA","Jakarta"}, - {"IRAN","Tehran"}, - {"IRAQ","Baghdad"}, - {"ISRAEL","Jerusalem"}, - {"JAPAN","Tokyo"}, - {"JORDAN","Amman"}, - {"KUWAIT","Kuwait City"}, - {"LAOS","Vientiane"}, - {"LEBANON","Beirut"}, - {"MALAYSIA","Kuala Lumpur"}, - {"THE MALDIVES","Male"}, - {"MONGOLIA","Ulan Bator"}, - {"MYANMAR (BURMA)","Rangoon"}, - {"NEPAL","Katmandu"}, - {"NORTH KOREA","P'yongyang"}, - {"OMAN","Muscat"}, - {"PAKISTAN","Islamabad"}, - {"PHILIPPINES","Manila"}, - {"QATAR","Doha"}, - {"SAUDI ARABIA","Riyadh"}, - {"SINGAPORE","Singapore"}, - {"SOUTH KOREA","Seoul"}, - {"SRI LANKA","Colombo"}, - {"SYRIA","Damascus"}, - {"TAIWAN (REPUBLIC OF CHINA)","Taipei"}, - {"THAILAND","Bangkok"}, - {"TURKEY","Ankara"}, - {"UNITED ARAB EMIRATES","Abu Dhabi"}, - {"VIETNAM","Hanoi"}, - {"YEMEN","Sana'a"}, - // Australia and Oceania - {"AUSTRALIA","Canberra"}, - {"FIJI","Suva"}, - {"KIRIBATI","Bairiki"}, - {"MARSHALL ISLANDS","Dalap-Uliga-Darrit"}, - {"MICRONESIA","Palikir"}, - {"NAURU","Yaren"}, - {"NEW ZEALAND","Wellington"}, - {"PALAU","Koror"}, - {"PAPUA NEW GUINEA","Port Moresby"}, - {"SOLOMON ISLANDS","Honaira"}, - {"TONGA","Nuku'alofa"}, - {"TUVALU","Fongafale"}, - {"VANUATU","Port Vila"}, - {"WESTERN SAMOA","Apia"}, - // Eastern Europe and former USSR - {"ARMENIA","Yerevan"}, - {"AZERBAIJAN","Baku"}, - {"BELARUS (BYELORUSSIA)","Minsk"}, - {"BULGARIA","Sofia"}, - {"GEORGIA","Tbilisi"}, - {"KAZAKSTAN","Almaty"}, - {"KYRGYZSTAN","Alma-Ata"}, - {"MOLDOVA","Chisinau"}, - {"RUSSIA","Moscow"}, - {"TAJIKISTAN","Dushanbe"}, - {"TURKMENISTAN","Ashkabad"}, - {"UKRAINE","Kyiv"}, - {"UZBEKISTAN","Tashkent"}, - // Europe - {"ALBANIA","Tirana"}, - {"ANDORRA","Andorra la Vella"}, - {"AUSTRIA","Vienna"}, - {"BELGIUM","Brussels"}, - {"BOSNIA-HERZEGOVINA","Sarajevo"}, - {"CROATIA","Zagreb"}, - {"CZECH REPUBLIC","Prague"}, - {"DENMARK","Copenhagen"}, - {"ESTONIA","Tallinn"}, - {"FINLAND","Helsinki"}, - {"FRANCE","Paris"}, - {"GERMANY","Berlin"}, - {"GREECE","Athens"}, - {"HUNGARY","Budapest"}, - {"ICELAND","Reykjavik"}, - {"IRELAND","Dublin"}, - {"ITALY","Rome"}, - {"LATVIA","Riga"}, - {"LIECHTENSTEIN","Vaduz"}, - {"LITHUANIA","Vilnius"}, - {"LUXEMBOURG","Luxembourg"}, - {"MACEDONIA","Skopje"}, - {"MALTA","Valletta"}, - {"MONACO","Monaco"}, - {"MONTENEGRO","Podgorica"}, - {"THE NETHERLANDS","Amsterdam"}, - {"NORWAY","Oslo"}, - {"POLAND","Warsaw"}, - {"PORTUGAL","Lisbon"}, - {"ROMANIA","Bucharest"}, - {"SAN MARINO","San Marino"}, - {"SERBIA","Belgrade"}, - {"SLOVAKIA","Bratislava"}, - {"SLOVENIA","Ljuijana"}, - {"SPAIN","Madrid"}, - {"SWEDEN","Stockholm"}, - {"SWITZERLAND","Berne"}, - {"UNITED KINGDOM","London"}, - {"VATICAN CITY","Vatican City"}, - // North and Central America - {"ANTIGUA AND BARBUDA","Saint John's"}, - {"BAHAMAS","Nassau"}, - {"BARBADOS","Bridgetown"}, - {"BELIZE","Belmopan"}, - {"CANADA","Ottawa"}, - {"COSTA RICA","San Jose"}, - {"CUBA","Havana"}, - {"DOMINICA","Roseau"}, - {"DOMINICAN REPUBLIC","Santo Domingo"}, - {"EL SALVADOR","San Salvador"}, - {"GRENADA","Saint George's"}, - {"GUATEMALA","Guatemala City"}, - {"HAITI","Port-au-Prince"}, - {"HONDURAS","Tegucigalpa"}, - {"JAMAICA","Kingston"}, - {"MEXICO","Mexico City"}, - {"NICARAGUA","Managua"}, - {"PANAMA","Panama City"}, - {"ST. KITTS AND NEVIS","Basseterre"}, - {"ST. LUCIA","Castries"}, - {"ST. VINCENT AND THE GRENADINES","Kingstown"}, - {"UNITED STATES OF AMERICA","Washington, D.C."}, - // South America - {"ARGENTINA","Buenos Aires"}, - {"BOLIVIA","Sucre (legal)/La Paz(administrative)"}, - {"BRAZIL","Brasilia"}, - {"CHILE","Santiago"}, - {"COLOMBIA","Bogota"}, - {"ECUADOR","Quito"}, - {"GUYANA","Georgetown"}, - {"PARAGUAY","Asuncion"}, - {"PERU","Lima"}, - {"SURINAME","Paramaribo"}, - {"TRINIDAD AND TOBAGO","Port of Spain"}, - {"URUGUAY","Montevideo"}, - {"VENEZUELA","Caracas"}, - }; - // Use AbstractMap by implementing entrySet() - private static class FlyweightMap - extends AbstractMap { - private static class Entry - implements Map.Entry { - int index; - Entry(int index) { this.index = index; } - @Override - public boolean equals(Object o) { - return o instanceof FlyweightMap && - Objects.equals(DATA[index][0], o); - } - @Override - public int hashCode() { - return Objects.hashCode(DATA[index][0]); - } - @Override - public String getKey() { return DATA[index][0]; } - @Override - public String getValue() { - return DATA[index][1]; - } - @Override - public String setValue(String value) { - throw new UnsupportedOperationException(); - } - } - // Implement size() & iterator() for AbstractSet: - static class EntrySet - extends AbstractSet> { - private int size; - EntrySet(int size) { - if(size < 0) - this.size = 0; - // Can't be any bigger than the array: - else if(size > DATA.length) - this.size = DATA.length; - else - this.size = size; - } - @Override - public int size() { return size; } - private class Iter - implements Iterator> { - // Only one Entry object per Iterator: - private Entry entry = new Entry(-1); - @Override - public boolean hasNext() { - return entry.index < size - 1; - } - @Override - public Map.Entry next() { - entry.index++; - return entry; - } - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - } - @Override - public - Iterator> iterator() { - return new Iter(); - } - } - private static - Set> entries = - new EntrySet(DATA.length); - @Override - public Set> entrySet() { - return entries; - } - } - // Create a partial map of 'size' countries: - static Map select(final int size) { - return new FlyweightMap() { - @Override - public Set> entrySet() { - return new EntrySet(size); - } - }; - } - static Map map = new FlyweightMap(); - public static Map capitals() { - return map; // The entire map - } - public static Map capitals(int size) { - return select(size); // A partial map - } - static List names = - new ArrayList<>(map.keySet()); - // All the names: - public static List names() { return names; } - // A partial list: - public static List names(int size) { - return new ArrayList<>(select(size).keySet()); - } - public static void main(String[] args) { - System.out.println(capitals(10)); - System.out.println(names(10)); - System.out.println(new HashMap<>(capitals(3))); - System.out.println( - new LinkedHashMap<>(capitals(3))); - System.out.println(new TreeMap<>(capitals(3))); - System.out.println(new Hashtable<>(capitals(3))); - System.out.println(new HashSet<>(names(6))); - System.out.println(new LinkedHashSet<>(names(6))); - System.out.println(new TreeSet<>(names(6))); - System.out.println(new ArrayList<>(names(6))); - System.out.println(new LinkedList<>(names(6))); - System.out.println(capitals().get("BRAZIL")); - } -} -/* Output: -{ALGERIA=Algiers, ANGOLA=Luanda, BENIN=Porto-Novo, -BOTSWANA=Gaberone, BURKINA FASO=Ouagadougou, -BURUNDI=Bujumbura, CAMEROON=Yaounde, CAPE VERDE=Praia, -CENTRAL AFRICAN REPUBLIC=Bangui, CHAD=N'djamena} -[ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, -BURUNDI, CAMEROON, CAPE VERDE, CENTRAL AFRICAN -REPUBLIC, CHAD] -{BENIN=Porto-Novo, ANGOLA=Luanda, ALGERIA=Algiers} -{ALGERIA=Algiers, ANGOLA=Luanda, BENIN=Porto-Novo} -{ALGERIA=Algiers, ANGOLA=Luanda, BENIN=Porto-Novo} -{ALGERIA=Algiers, ANGOLA=Luanda, BENIN=Porto-Novo} -[BENIN, BOTSWANA, ANGOLA, BURKINA FASO, ALGERIA, -BURUNDI] -[ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, -BURUNDI] -[ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, -BURUNDI] -[ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, -BURUNDI] -[ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, -BURUNDI] -Brasilia -*/ diff --git a/code/onjava/Enums.java b/code/onjava/Enums.java deleted file mode 100644 index 0440802f..00000000 --- a/code/onjava/Enums.java +++ /dev/null @@ -1,17 +0,0 @@ -// onjava/Enums.java -// (c)2020 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 onjava; -import java.util.*; - -public class Enums { - private static Random rand = new Random(47); - public static - > T random(Class ec) { - return random(ec.getEnumConstants()); - } - public static T random(T[] values) { - return values[rand.nextInt(values.length)]; - } -} diff --git a/code/onjava/FillMap.java b/code/onjava/FillMap.java deleted file mode 100644 index eadc5495..00000000 --- a/code/onjava/FillMap.java +++ /dev/null @@ -1,38 +0,0 @@ -// onjava/FillMap.java -// (c)2020 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 onjava; -import java.util.*; -import java.util.function.*; -import java.util.stream.*; - -public class FillMap { - public static Map - basic(Supplier> pairGen, int size) { - return Stream.generate(pairGen) - .limit(size) - .collect(Collectors - .toMap(Pair::key, Pair::value)); - } - public static Map - basic(Supplier keyGen, - Supplier valueGen, int size) { - return Stream.generate( - () -> Pair.make(keyGen.get(), valueGen.get())) - .limit(size) - .collect(Collectors - .toMap(Pair::key, Pair::value)); - } - public static > - M create(Supplier keyGen, - Supplier valueGen, - Supplier mapSupplier, int size) { - return Stream.generate( () -> - Pair.make(keyGen.get(), valueGen.get())) - .limit(size) - .collect(Collectors - .toMap(Pair::key, Pair::value, - (k, v) -> k, mapSupplier)); - } -} diff --git a/code/onjava/HTMLColors.java b/code/onjava/HTMLColors.java deleted file mode 100644 index bdc3458f..00000000 --- a/code/onjava/HTMLColors.java +++ /dev/null @@ -1,236 +0,0 @@ -// onjava/HTMLColors.java -// (c)2020 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. -// Sample data for collection examples -package onjava; -import java.util.*; -import java.util.stream.*; -import java.util.concurrent.*; - -public class HTMLColors { - public static final Object[][] ARRAY = { - { 0xF0F8FF, "AliceBlue" }, - { 0xFAEBD7, "AntiqueWhite" }, - { 0x7FFFD4, "Aquamarine" }, - { 0xF0FFFF, "Azure" }, - { 0xF5F5DC, "Beige" }, - { 0xFFE4C4, "Bisque" }, - { 0x000000, "Black" }, - { 0xFFEBCD, "BlanchedAlmond" }, - { 0x0000FF, "Blue" }, - { 0x8A2BE2, "BlueViolet" }, - { 0xA52A2A, "Brown" }, - { 0xDEB887, "BurlyWood" }, - { 0x5F9EA0, "CadetBlue" }, - { 0x7FFF00, "Chartreuse" }, - { 0xD2691E, "Chocolate" }, - { 0xFF7F50, "Coral" }, - { 0x6495ED, "CornflowerBlue" }, - { 0xFFF8DC, "Cornsilk" }, - { 0xDC143C, "Crimson" }, - { 0x00FFFF, "Cyan" }, - { 0x00008B, "DarkBlue" }, - { 0x008B8B, "DarkCyan" }, - { 0xB8860B, "DarkGoldenRod" }, - { 0xA9A9A9, "DarkGray" }, - { 0x006400, "DarkGreen" }, - { 0xBDB76B, "DarkKhaki" }, - { 0x8B008B, "DarkMagenta" }, - { 0x556B2F, "DarkOliveGreen" }, - { 0xFF8C00, "DarkOrange" }, - { 0x9932CC, "DarkOrchid" }, - { 0x8B0000, "DarkRed" }, - { 0xE9967A, "DarkSalmon" }, - { 0x8FBC8F, "DarkSeaGreen" }, - { 0x483D8B, "DarkSlateBlue" }, - { 0x2F4F4F, "DarkSlateGray" }, - { 0x00CED1, "DarkTurquoise" }, - { 0x9400D3, "DarkViolet" }, - { 0xFF1493, "DeepPink" }, - { 0x00BFFF, "DeepSkyBlue" }, - { 0x696969, "DimGray" }, - { 0x1E90FF, "DodgerBlue" }, - { 0xB22222, "FireBrick" }, - { 0xFFFAF0, "FloralWhite" }, - { 0x228B22, "ForestGreen" }, - { 0xDCDCDC, "Gainsboro" }, - { 0xF8F8FF, "GhostWhite" }, - { 0xFFD700, "Gold" }, - { 0xDAA520, "GoldenRod" }, - { 0x808080, "Gray" }, - { 0x008000, "Green" }, - { 0xADFF2F, "GreenYellow" }, - { 0xF0FFF0, "HoneyDew" }, - { 0xFF69B4, "HotPink" }, - { 0xCD5C5C, "IndianRed" }, - { 0x4B0082, "Indigo" }, - { 0xFFFFF0, "Ivory" }, - { 0xF0E68C, "Khaki" }, - { 0xE6E6FA, "Lavender" }, - { 0xFFF0F5, "LavenderBlush" }, - { 0x7CFC00, "LawnGreen" }, - { 0xFFFACD, "LemonChiffon" }, - { 0xADD8E6, "LightBlue" }, - { 0xF08080, "LightCoral" }, - { 0xE0FFFF, "LightCyan" }, - { 0xFAFAD2, "LightGoldenRodYellow" }, - { 0xD3D3D3, "LightGray" }, - { 0x90EE90, "LightGreen" }, - { 0xFFB6C1, "LightPink" }, - { 0xFFA07A, "LightSalmon" }, - { 0x20B2AA, "LightSeaGreen" }, - { 0x87CEFA, "LightSkyBlue" }, - { 0x778899, "LightSlateGray" }, - { 0xB0C4DE, "LightSteelBlue" }, - { 0xFFFFE0, "LightYellow" }, - { 0x00FF00, "Lime" }, - { 0x32CD32, "LimeGreen" }, - { 0xFAF0E6, "Linen" }, - { 0xFF00FF, "Magenta" }, - { 0x800000, "Maroon" }, - { 0x66CDAA, "MediumAquaMarine" }, - { 0x0000CD, "MediumBlue" }, - { 0xBA55D3, "MediumOrchid" }, - { 0x9370DB, "MediumPurple" }, - { 0x3CB371, "MediumSeaGreen" }, - { 0x7B68EE, "MediumSlateBlue" }, - { 0x00FA9A, "MediumSpringGreen" }, - { 0x48D1CC, "MediumTurquoise" }, - { 0xC71585, "MediumVioletRed" }, - { 0x191970, "MidnightBlue" }, - { 0xF5FFFA, "MintCream" }, - { 0xFFE4E1, "MistyRose" }, - { 0xFFE4B5, "Moccasin" }, - { 0xFFDEAD, "NavajoWhite" }, - { 0x000080, "Navy" }, - { 0xFDF5E6, "OldLace" }, - { 0x808000, "Olive" }, - { 0x6B8E23, "OliveDrab" }, - { 0xFFA500, "Orange" }, - { 0xFF4500, "OrangeRed" }, - { 0xDA70D6, "Orchid" }, - { 0xEEE8AA, "PaleGoldenRod" }, - { 0x98FB98, "PaleGreen" }, - { 0xAFEEEE, "PaleTurquoise" }, - { 0xDB7093, "PaleVioletRed" }, - { 0xFFEFD5, "PapayaWhip" }, - { 0xFFDAB9, "PeachPuff" }, - { 0xCD853F, "Peru" }, - { 0xFFC0CB, "Pink" }, - { 0xDDA0DD, "Plum" }, - { 0xB0E0E6, "PowderBlue" }, - { 0x800080, "Purple" }, - { 0xFF0000, "Red" }, - { 0xBC8F8F, "RosyBrown" }, - { 0x4169E1, "RoyalBlue" }, - { 0x8B4513, "SaddleBrown" }, - { 0xFA8072, "Salmon" }, - { 0xF4A460, "SandyBrown" }, - { 0x2E8B57, "SeaGreen" }, - { 0xFFF5EE, "SeaShell" }, - { 0xA0522D, "Sienna" }, - { 0xC0C0C0, "Silver" }, - { 0x87CEEB, "SkyBlue" }, - { 0x6A5ACD, "SlateBlue" }, - { 0x708090, "SlateGray" }, - { 0xFFFAFA, "Snow" }, - { 0x00FF7F, "SpringGreen" }, - { 0x4682B4, "SteelBlue" }, - { 0xD2B48C, "Tan" }, - { 0x008080, "Teal" }, - { 0xD8BFD8, "Thistle" }, - { 0xFF6347, "Tomato" }, - { 0x40E0D0, "Turquoise" }, - { 0xEE82EE, "Violet" }, - { 0xF5DEB3, "Wheat" }, - { 0xFFFFFF, "White" }, - { 0xF5F5F5, "WhiteSmoke" }, - { 0xFFFF00, "Yellow" }, - { 0x9ACD32, "YellowGreen" }, - }; - public static final Map MAP = - Arrays.stream(ARRAY) - .collect(Collectors.toMap( - element -> (Integer)element[0], - element -> (String)element[1], - (v1, v2) -> { // Merge function - throw new IllegalStateException(); - }, - LinkedHashMap::new - )); - // Inversion only works if values are unique: - public static Map - invert(Map map) { - return map.entrySet().stream() - .collect(Collectors.toMap( - Map.Entry::getValue, - Map.Entry::getKey, - (v1, v2) -> { - throw new IllegalStateException(); - }, - LinkedHashMap::new - )); - } - public static final Map - INVMAP = invert(MAP); - // Look up RGB value given a name: - public static Integer rgb(String colorName) { - return INVMAP.get(colorName); - } - public static final List LIST = - Arrays.stream(ARRAY) - .map(item -> (String)item[1]) - .collect(Collectors.toList()); - public static final List RGBLIST = - Arrays.stream(ARRAY) - .map(item -> (Integer)item[0]) - .collect(Collectors.toList()); - public static - void show(Map.Entry e) { - System.out.format( - "0x%06X: %s%n", e.getKey(), e.getValue()); - } - public static void - show(Map m, int count) { - m.entrySet().stream() - .limit(count) - .forEach(e -> show(e)); - } - public static void show(Map m) { - show(m, m.size()); - } - public static - void show(Collection lst, int count) { - lst.stream() - .limit(count) - .forEach(System.out::println); - } - public static void show(Collection lst) { - show(lst, lst.size()); - } - public static - void showrgb(Collection lst, int count) { - lst.stream() - .limit(count) - .forEach(n -> System.out.format("0x%06X%n", n)); - } - public static void showrgb(Collection lst) { - showrgb(lst, lst.size()); - } - public static - void showInv(Map m, int count) { - m.entrySet().stream() - .limit(count) - .forEach(e -> - System.out.format( - "%-20s 0x%06X%n", e.getKey(), e.getValue())); - } - public static void showInv(Map m) { - showInv(m, m.size()); - } - public static void border() { - System.out.println( - "******************************"); - } -} diff --git a/code/onjava/MouseClick.java b/code/onjava/MouseClick.java deleted file mode 100644 index 70d982f7..00000000 --- a/code/onjava/MouseClick.java +++ /dev/null @@ -1,19 +0,0 @@ -// onjava/MouseClick.java -// (c)2020 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. -// Helper interface to allow lambda expressions -package onjava; -import java.awt.event.*; - -// Default everything except mouseClicked(): -public interface MouseClick extends MouseListener { - @Override - default void mouseEntered(MouseEvent e) {} - @Override - default void mouseExited(MouseEvent e) {} - @Override - default void mousePressed(MouseEvent e) {} - @Override - default void mouseReleased(MouseEvent e) {} -} diff --git a/code/onjava/Nap.java b/code/onjava/Nap.java deleted file mode 100644 index 2b89745b..00000000 --- a/code/onjava/Nap.java +++ /dev/null @@ -1,20 +0,0 @@ -// onjava/Nap.java -// (c)2020 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 onjava; -import java.util.concurrent.*; - -public class Nap { - public Nap(double t) { // Seconds - try { - TimeUnit.MILLISECONDS.sleep((int)(1000 * t)); - } catch(InterruptedException e) { - throw new RuntimeException(e); - } - } - public Nap(double t, String msg) { - this(t); - System.out.println(msg); - } -} diff --git a/code/onjava/Null.java b/code/onjava/Null.java deleted file mode 100644 index f3bb70d6..00000000 --- a/code/onjava/Null.java +++ /dev/null @@ -1,6 +0,0 @@ -// onjava/Null.java -// (c)2020 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 onjava; -public interface Null {} diff --git a/code/onjava/OSExecute.java b/code/onjava/OSExecute.java deleted file mode 100644 index 25ac7f0c..00000000 --- a/code/onjava/OSExecute.java +++ /dev/null @@ -1,37 +0,0 @@ -// onjava/OSExecute.java -// (c)2020 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. -// Run an operating system command -// and send the output to the console -package onjava; -import java.io.*; - -public class OSExecute { - public static void command(String command) { - boolean err = false; - try { - Process process = new ProcessBuilder( - command.split(" ")).start(); - try( - BufferedReader results = new BufferedReader( - new InputStreamReader( - process.getInputStream())); - BufferedReader errors = new BufferedReader( - new InputStreamReader( - process.getErrorStream())) - ) { - results.lines() - .forEach(System.out::println); - err = errors.lines() - .peek(System.err::println) - .count() > 0; - } - } catch(IOException e) { - throw new RuntimeException(e); - } - if(err) - throw new OSExecuteException( - "Errors executing " + command); - } -} diff --git a/code/onjava/OSExecuteException.java b/code/onjava/OSExecuteException.java deleted file mode 100644 index 17d803e1..00000000 --- a/code/onjava/OSExecuteException.java +++ /dev/null @@ -1,12 +0,0 @@ -// onjava/OSExecuteException.java -// (c)2020 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 onjava; - -public class -OSExecuteException extends RuntimeException { - public OSExecuteException(String why) { - super(why); - } -} diff --git a/code/onjava/Operations.java b/code/onjava/Operations.java deleted file mode 100644 index 33b644c6..00000000 --- a/code/onjava/Operations.java +++ /dev/null @@ -1,17 +0,0 @@ -// onjava/Operations.java -// (c)2020 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 onjava; -import java.util.*; - -public interface Operations { - void execute(); - static void runOps(Operations... ops) { - for(Operations op : ops) - op.execute(); - } - static void show(String msg) { - System.out.println(msg); - } -} diff --git a/code/onjava/Pair.java b/code/onjava/Pair.java deleted file mode 100644 index 784ef8ac..00000000 --- a/code/onjava/Pair.java +++ /dev/null @@ -1,19 +0,0 @@ -// onjava/Pair.java -// (c)2020 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 onjava; - -public class Pair { - public final K key; - public final V value; - public Pair(K k, V v) { - key = k; - value = v; - } - public K key() { return key; } - public V value() { return value; } - public static Pair make(K k, V v) { - return new Pair(k, v); - } -} diff --git a/code/onjava/ProcessFiles.java b/code/onjava/ProcessFiles.java deleted file mode 100644 index edcea73a..00000000 --- a/code/onjava/ProcessFiles.java +++ /dev/null @@ -1,48 +0,0 @@ -// onjava/ProcessFiles.java -// (c)2020 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 onjava; -import java.io.*; -import java.nio.file.*; - -public class ProcessFiles { - public interface Strategy { - void process(File file); - } - private Strategy strategy; - private String ext; - public ProcessFiles(Strategy strategy, String ext) { - this.strategy = strategy; - this.ext = ext; - } - public void start(String[] args) { - try { - if(args.length == 0) - processDirectoryTree(new File(".")); - else - for(String arg : args) { - File fileArg = new File(arg); - if(fileArg.isDirectory()) - processDirectoryTree(fileArg); - else { - // Allow user to leave off extension: - if(!arg.endsWith("." + ext)) - arg += "." + ext; - strategy.process( - new File(arg).getCanonicalFile()); - } - } - } catch(IOException e) { - throw new RuntimeException(e); - } - } - public void - processDirectoryTree(File root) throws IOException { - PathMatcher matcher = FileSystems.getDefault() - .getPathMatcher("glob:**/*.{" + ext + "}"); - Files.walk(root.toPath()) - .filter(matcher::matches) - .forEach(p -> strategy.process(p.toFile())); - } -} diff --git a/code/onjava/Rand.java b/code/onjava/Rand.java deleted file mode 100644 index d21c0e2b..00000000 --- a/code/onjava/Rand.java +++ /dev/null @@ -1,248 +0,0 @@ -// onjava/Rand.java -// (c)2020 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. -// Generate random values of different types -package onjava; -import java.util.*; -import java.util.function.*; -import static onjava.ConvertTo.*; - -public interface Rand { - int MOD = 10_000; - class Boolean - implements Supplier { - SplittableRandom r = new SplittableRandom(47); - @Override - public java.lang.Boolean get() { - return r.nextBoolean(); - } - public java.lang.Boolean get(int n) { - return get(); - } - public java.lang.Boolean[] array(int sz) { - java.lang.Boolean[] result = - new java.lang.Boolean[sz]; - Arrays.setAll(result, n -> get()); - return result; - } - } - class Pboolean { - public boolean[] array(int sz) { - return primitive(new Boolean().array(sz)); - } - } - class Byte - implements Supplier { - SplittableRandom r = new SplittableRandom(47); - @Override - public java.lang.Byte get() { - return (byte)r.nextInt(MOD); - } - public java.lang.Byte get(int n) { - return get(); - } - public java.lang.Byte[] array(int sz) { - java.lang.Byte[] result = - new java.lang.Byte[sz]; - Arrays.setAll(result, n -> get()); - return result; - } - } - class Pbyte { - public byte[] array(int sz) { - return primitive(new Byte().array(sz)); - } - } - class Character - implements Supplier { - SplittableRandom r = new SplittableRandom(47); - @Override - public java.lang.Character get() { - return (char)r.nextInt('a', 'z' + 1); - } - public java.lang.Character get(int n) { - return get(); - } - public java.lang.Character[] array(int sz) { - java.lang.Character[] result = - new java.lang.Character[sz]; - Arrays.setAll(result, n -> get()); - return result; - } - } - class Pchar { - public char[] array(int sz) { - return primitive(new Character().array(sz)); - } - } - class Short - implements Supplier { - SplittableRandom r = new SplittableRandom(47); - @Override - public java.lang.Short get() { - return (short)r.nextInt(MOD); - } - public java.lang.Short get(int n) { - return get(); - } - public java.lang.Short[] array(int sz) { - java.lang.Short[] result = - new java.lang.Short[sz]; - Arrays.setAll(result, n -> get()); - return result; - } - } - class Pshort { - public short[] array(int sz) { - return primitive(new Short().array(sz)); - } - } - class Integer - implements Supplier { - SplittableRandom r = new SplittableRandom(47); - @Override - public java.lang.Integer get() { - return r.nextInt(MOD); - } - public java.lang.Integer get(int n) { - return get(); - } - public java.lang.Integer[] array(int sz) { - int[] primitive = new Pint().array(sz); - java.lang.Integer[] result = - new java.lang.Integer[sz]; - for(int i = 0; i < sz; i++) - result[i] = primitive[i]; - return result; - } - } - class Pint implements IntSupplier { - SplittableRandom r = new SplittableRandom(47); - @Override - public int getAsInt() { - return r.nextInt(MOD); - } - public int get(int n) { return getAsInt(); } - public int[] array(int sz) { - return r.ints(sz, 0, MOD).toArray(); - } - } - class Long - implements Supplier { - SplittableRandom r = new SplittableRandom(47); - @Override - public java.lang.Long get() { - return r.nextLong(MOD); - } - public java.lang.Long get(int n) { - return get(); - } - public java.lang.Long[] array(int sz) { - long[] primitive = new Plong().array(sz); - java.lang.Long[] result = - new java.lang.Long[sz]; - for(int i = 0; i < sz; i++) - result[i] = primitive[i]; - return result; - } - } - class Plong implements LongSupplier { - SplittableRandom r = new SplittableRandom(47); - @Override - public long getAsLong() { - return r.nextLong(MOD); - } - public long get(int n) { return getAsLong(); } - public long[] array(int sz) { - return r.longs(sz, 0, MOD).toArray(); - } - } - class Float - implements Supplier { - SplittableRandom r = new SplittableRandom(47); - @Override - public java.lang.Float get() { - return (float)trim(r.nextDouble()); - } - public java.lang.Float get(int n) { - return get(); - } - public java.lang.Float[] array(int sz) { - java.lang.Float[] result = - new java.lang.Float[sz]; - Arrays.setAll(result, n -> get()); - return result; - } - } - class Pfloat { - public float[] array(int sz) { - return primitive(new Float().array(sz)); - } - } - static double trim(double d) { - return - ((double)Math.round(d * 1000.0)) / 100.0; - } - class Double - implements Supplier { - SplittableRandom r = new SplittableRandom(47); - @Override - public java.lang.Double get() { - return trim(r.nextDouble()); - } - public java.lang.Double get(int n) { - return get(); - } - public java.lang.Double[] array(int sz) { - double[] primitive = - new Rand.Pdouble().array(sz); - java.lang.Double[] result = - new java.lang.Double[sz]; - for(int i = 0; i < sz; i++) - result[i] = primitive[i]; - return result; - } - } - class Pdouble implements DoubleSupplier { - SplittableRandom r = new SplittableRandom(47); - @Override - public double getAsDouble() { - return trim(r.nextDouble()); - } - public double get(int n) { - return getAsDouble(); - } - public double[] array(int sz) { - double[] result = r.doubles(sz).toArray(); - Arrays.setAll(result, - n -> result[n] = trim(result[n])); - return result; - } - } - class String - implements Supplier { - SplittableRandom r = new SplittableRandom(47); - private int strlen = 7; // Default length - public String() {} - public String(int strLength) { - strlen = strLength; - } - @Override - public java.lang.String get() { - return r.ints(strlen, 'a', 'z' + 1) - .collect(StringBuilder::new, - StringBuilder::appendCodePoint, - StringBuilder::append).toString(); - } - public java.lang.String get(int n) { - return get(); - } - public java.lang.String[] array(int sz) { - java.lang.String[] result = - new java.lang.String[sz]; - Arrays.setAll(result, n -> get()); - return result; - } - } -} diff --git a/code/onjava/Range.java b/code/onjava/Range.java deleted file mode 100644 index e075c9ba..00000000 --- a/code/onjava/Range.java +++ /dev/null @@ -1,34 +0,0 @@ -// onjava/Range.java -// (c)2020 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. -// Array creation methods that can be used without -// qualifiers, using static imports: -package onjava; - -public class Range { - // Produce a sequence [0..n) - public static int[] range(int n) { - int[] result = new int[n]; - for(int i = 0; i < n; i++) - result[i] = i; - return result; - } - // Produce a sequence [start..end) - public static int[] range(int start, int end) { - int sz = end - start; - int[] result = new int[sz]; - for(int i = 0; i < sz; i++) - result[i] = start + i; - return result; - } - // Produce sequence [start..end) incrementing by step - public static - int[] range(int start, int end, int step) { - int sz = (end - start)/step; - int[] result = new int[sz]; - for(int i = 0; i < sz; i++) - result[i] = start + (i * step); - return result; - } -} diff --git a/code/onjava/Repeat.java b/code/onjava/Repeat.java deleted file mode 100644 index 7ab61fac..00000000 --- a/code/onjava/Repeat.java +++ /dev/null @@ -1,12 +0,0 @@ -// onjava/Repeat.java -// (c)2020 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 onjava; -import static java.util.stream.IntStream.*; - -public class Repeat { - public static void repeat(int n, Runnable action) { - range(0, n).forEach(i -> action.run()); - } -} diff --git a/code/onjava/RmDir.java b/code/onjava/RmDir.java deleted file mode 100644 index be7ea494..00000000 --- a/code/onjava/RmDir.java +++ /dev/null @@ -1,31 +0,0 @@ -// onjava/RmDir.java -// (c)2020 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 onjava; -import java.nio.file.*; -import java.nio.file.attribute.BasicFileAttributes; -import java.io.IOException; - -public class RmDir { - public static void rmdir(Path dir) - throws IOException { - Files.walkFileTree(dir, - new SimpleFileVisitor() { - @Override - public FileVisitResult - visitFile(Path file, BasicFileAttributes attrs) - throws IOException { - Files.delete(file); - return FileVisitResult.CONTINUE; - } - @Override - public FileVisitResult - postVisitDirectory(Path dir, IOException exc) - throws IOException { - Files.delete(dir); - return FileVisitResult.CONTINUE; - } - }); - } -} diff --git a/code/onjava/Sets.java b/code/onjava/Sets.java deleted file mode 100644 index 62258f15..00000000 --- a/code/onjava/Sets.java +++ /dev/null @@ -1,32 +0,0 @@ -// onjava/Sets.java -// (c)2020 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 onjava; -import java.util.*; - -public class Sets { - public static Set union(Set a, Set b) { - Set result = new HashSet<>(a); - result.addAll(b); - return result; - } - public static - Set intersection(Set a, Set b) { - Set result = new HashSet<>(a); - result.retainAll(b); - return result; - } - // Subtract subset from superset: - public static Set - difference(Set superset, Set subset) { - Set result = new HashSet<>(superset); - result.removeAll(subset); - return result; - } - // Reflexive--everything not in the intersection: - public static - Set complement(Set a, Set b) { - return difference(union(a, b), intersection(a, b)); - } -} diff --git a/code/onjava/Stack.java b/code/onjava/Stack.java deleted file mode 100644 index a5108176..00000000 --- a/code/onjava/Stack.java +++ /dev/null @@ -1,20 +0,0 @@ -// onjava/Stack.java -// (c)2020 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. -// A Stack class built with an ArrayDeque -package onjava; -import java.util.Deque; -import java.util.ArrayDeque; - -public class Stack { - private Deque storage = new ArrayDeque<>(); - public void push(T v) { storage.push(v); } - public T peek() { return storage.peek(); } - public T pop() { return storage.pop(); } - public boolean isEmpty() { return storage.isEmpty(); } - @Override - public String toString() { - return storage.toString(); - } -} diff --git a/code/onjava/Suppliers.java b/code/onjava/Suppliers.java deleted file mode 100644 index 226a70cb..00000000 --- a/code/onjava/Suppliers.java +++ /dev/null @@ -1,36 +0,0 @@ -// onjava/Suppliers.java -// (c)2020 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. -// A utility to use with Suppliers -package onjava; -import java.util.*; -import java.util.function.*; -import java.util.stream.*; - -public class Suppliers { - // Create a collection and fill it: - public static > C - create(Supplier factory, Supplier gen, int n) { - return Stream.generate(gen) - .limit(n) - .collect(factory, C::add, C::addAll); - } - // Fill an existing collection: - public static > - C fill(C coll, Supplier gen, int n) { - Stream.generate(gen) - .limit(n) - .forEach(coll::add); - return coll; - } - // Use an unbound method reference to - // produce a more general method: - public static H fill(H holder, - BiConsumer adder, Supplier
gen, int n) { - Stream.generate(gen) - .limit(n) - .forEach(a -> adder.accept(holder, a)); - return holder; - } -} diff --git a/code/onjava/TimedAbort.java b/code/onjava/TimedAbort.java deleted file mode 100644 index 3715cf2e..00000000 --- a/code/onjava/TimedAbort.java +++ /dev/null @@ -1,30 +0,0 @@ -// onjava/TimedAbort.java -// (c)2020 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. -// Terminate a program after t seconds -package onjava; -import java.util.concurrent.*; - -public class TimedAbort { - private volatile boolean restart = true; - public TimedAbort(double t, String msg) { - CompletableFuture.runAsync(() -> { - try { - while(restart) { - restart = false; - TimeUnit.MILLISECONDS - .sleep((int)(1000 * t)); - } - } catch(InterruptedException e) { - throw new RuntimeException(e); - } - System.out.println(msg); - System.exit(0); - }); - } - public TimedAbort(double t) { - this(t, "TimedAbort " + t); - } - public void restart() { restart = true; } -} diff --git a/code/onjava/Timer.java b/code/onjava/Timer.java deleted file mode 100644 index a695f79f..00000000 --- a/code/onjava/Timer.java +++ /dev/null @@ -1,19 +0,0 @@ -// onjava/Timer.java -// (c)2020 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 onjava; -import static java.util.concurrent.TimeUnit.*; - -public class Timer { - private long start = System.nanoTime(); - public long duration() { - return NANOSECONDS.toMillis( - System.nanoTime() - start); - } - public static long duration(Runnable test) { - Timer timer = new Timer(); - test.run(); - return timer.duration(); - } -} diff --git a/code/onjava/Tuple.java b/code/onjava/Tuple.java deleted file mode 100644 index 73cfaa3c..00000000 --- a/code/onjava/Tuple.java +++ /dev/null @@ -1,24 +0,0 @@ -// onjava/Tuple.java -// (c)2020 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. -// Tuple library using type argument inference -package onjava; - -public class Tuple { - public static Tuple2 tuple(A a, B b) { - return new Tuple2<>(a, b); - } - public static Tuple3 - tuple(A a, B b, C c) { - return new Tuple3<>(a, b, c); - } - public static Tuple4 - tuple(A a, B b, C c, D d) { - return new Tuple4<>(a, b, c, d); - } - public static - Tuple5 tuple(A a, B b, C c, D d, E e) { - return new Tuple5<>(a, b, c, d, e); - } -} diff --git a/code/onjava/Tuple2.java b/code/onjava/Tuple2.java deleted file mode 100644 index 7ca8d199..00000000 --- a/code/onjava/Tuple2.java +++ /dev/null @@ -1,16 +0,0 @@ -// onjava/Tuple2.java -// (c)2020 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 onjava; - -public class Tuple2 { - public final A a1; - public final B a2; - public Tuple2(A a, B b) { a1 = a; a2 = b; } - public String rep() { return a1 + ", " + a2; } - @Override - public String toString() { - return "(" + rep() + ")"; - } -} diff --git a/code/onjava/Tuple3.java b/code/onjava/Tuple3.java deleted file mode 100644 index 26780642..00000000 --- a/code/onjava/Tuple3.java +++ /dev/null @@ -1,17 +0,0 @@ -// onjava/Tuple3.java -// (c)2020 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 onjava; - -public class Tuple3 extends Tuple2 { - public final C a3; - public Tuple3(A a, B b, C c) { - super(a, b); - a3 = c; - } - @Override - public String rep() { - return super.rep() + ", " + a3; - } -} diff --git a/code/onjava/Tuple4.java b/code/onjava/Tuple4.java deleted file mode 100644 index 5ab51dc9..00000000 --- a/code/onjava/Tuple4.java +++ /dev/null @@ -1,18 +0,0 @@ -// onjava/Tuple4.java -// (c)2020 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 onjava; - -public class Tuple4 - extends Tuple3 { - public final D a4; - public Tuple4(A a, B b, C c, D d) { - super(a, b, c); - a4 = d; - } - @Override - public String rep() { - return super.rep() + ", " + a4; - } -} diff --git a/code/onjava/Tuple5.java b/code/onjava/Tuple5.java deleted file mode 100644 index 1df88bfd..00000000 --- a/code/onjava/Tuple5.java +++ /dev/null @@ -1,18 +0,0 @@ -// onjava/Tuple5.java -// (c)2020 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 onjava; - -public class Tuple5 -extends Tuple4 { - public final E a5; - public Tuple5(A a, B b, C c, D d, E e) { - super(a, b, c, d); - a5 = e; - } - @Override - public String rep() { - return super.rep() + ", " + a5; - } -} diff --git a/code/onjava/TypeCounter.java b/code/onjava/TypeCounter.java deleted file mode 100644 index d8b262b7..00000000 --- a/code/onjava/TypeCounter.java +++ /dev/null @@ -1,41 +0,0 @@ -// onjava/TypeCounter.java -// (c)2020 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. -// Counts instances of a type family -package onjava; -import java.util.*; -import java.util.stream.*; - -public class -TypeCounter extends HashMap, Integer> { - private Class baseType; - public TypeCounter(Class baseType) { - this.baseType = baseType; - } - public void count(Object obj) { - Class type = obj.getClass(); - if(!baseType.isAssignableFrom(type)) - throw new RuntimeException( - obj + " incorrect type: " + type + - ", should be type or subtype of " + baseType); - countClass(type); - } - private void countClass(Class type) { - Integer quantity = get(type); - put(type, quantity == null ? 1 : quantity + 1); - Class superClass = type.getSuperclass(); - if(superClass != null && - baseType.isAssignableFrom(superClass)) - countClass(superClass); - } - @Override - public String toString() { - String result = entrySet().stream() - .map(pair -> String.format("%s=%s", - pair.getKey().getSimpleName(), - pair.getValue())) - .collect(Collectors.joining(", ")); - return "{" + result + "}"; - } -} diff --git a/code/onjava/atunit/AtUnit.java b/code/onjava/atunit/AtUnit.java deleted file mode 100644 index b1688cbd..00000000 --- a/code/onjava/atunit/AtUnit.java +++ /dev/null @@ -1,177 +0,0 @@ -// onjava/atunit/AtUnit.java -// (c)2020 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. -// An annotation-based unit-test framework -// {java onjava.atunit.AtUnit} -package onjava.atunit; -import java.lang.reflect.*; -import java.io.*; -import java.util.*; -import java.nio.file.*; -import java.util.stream.*; -import onjava.*; - -public class AtUnit implements ProcessFiles.Strategy { - static Class testClass; - static List failedTests= new ArrayList<>(); - static long testsRun = 0; - static long failures = 0; - public static void - main(String[] args) throws Exception { - ClassLoader.getSystemClassLoader() - .setDefaultAssertionStatus(true); // Enable assert - new ProcessFiles(new AtUnit(), "class").start(args); - if(failures == 0) - System.out.println("OK (" + testsRun + " tests)"); - else { - System.out.println("(" + testsRun + " tests)"); - System.out.println( - "\n>>> " + failures + " FAILURE" + - (failures > 1 ? "S" : "") + " <<<"); - for(String failed : failedTests) - System.out.println(" " + failed); - } - } - @Override - public void process(File cFile) { - try { - String cName = ClassNameFinder.thisClass( - Files.readAllBytes(cFile.toPath())); - if(!cName.startsWith("public:")) - return; - cName = cName.split(":")[1]; - if(!cName.contains(".")) - return; // Ignore unpackaged classes - testClass = Class.forName(cName); - } catch(IOException | ClassNotFoundException e) { - throw new RuntimeException(e); - } - TestMethods testMethods = new TestMethods(); - Method creator = null; - Method cleanup = null; - for(Method m : testClass.getDeclaredMethods()) { - testMethods.addIfTestMethod(m); - if(creator == null) - creator = checkForCreatorMethod(m); - if(cleanup == null) - cleanup = checkForCleanupMethod(m); - } - if(testMethods.size() > 0) { - if(creator == null) - try { - if(!Modifier.isPublic(testClass - .getDeclaredConstructor() - .getModifiers())) { - System.out.println("Error: " + testClass + - " no-arg constructor must be public"); - System.exit(1); - } - } catch(NoSuchMethodException e) { - // Synthesized no-arg constructor; OK - } - System.out.println(testClass.getName()); - } - for(Method m : testMethods) { - System.out.print(" . " + m.getName() + " "); - try { - Object testObject = createTestObject(creator); - boolean success = false; - try { - if(m.getReturnType().equals(boolean.class)) - success = (Boolean)m.invoke(testObject); - else { - m.invoke(testObject); - success = true; // If no assert fails - } - } catch(InvocationTargetException e) { - // Actual exception is inside e: - System.out.println(e.getCause()); - } - System.out.println(success ? "" : "(failed)"); - testsRun++; - if(!success) { - failures++; - failedTests.add(testClass.getName() + - ": " + m.getName()); - } - if(cleanup != null) - cleanup.invoke(testObject, testObject); - } catch(IllegalAccessException | - IllegalArgumentException | - InvocationTargetException e) { - throw new RuntimeException(e); - } - } - } - public static - class TestMethods extends ArrayList { - void addIfTestMethod(Method m) { - if(m.getAnnotation(Test.class) == null) - return; - if(!(m.getReturnType().equals(boolean.class) || - m.getReturnType().equals(void.class))) - throw new RuntimeException("@Test method" + - " must return boolean or void"); - m.setAccessible(true); // If it's private, etc. - add(m); - } - } - private static - Method checkForCreatorMethod(Method m) { - if(m.getAnnotation(TestObjectCreate.class) == null) - return null; - if(!m.getReturnType().equals(testClass)) - throw new RuntimeException("@TestObjectCreate " + - "must return instance of Class to be tested"); - if((m.getModifiers() & - java.lang.reflect.Modifier.STATIC) < 1) - throw new RuntimeException("@TestObjectCreate " + - "must be static."); - m.setAccessible(true); - return m; - } - private static - Method checkForCleanupMethod(Method m) { - if(m.getAnnotation(TestObjectCleanup.class) == null) - return null; - if(!m.getReturnType().equals(void.class)) - throw new RuntimeException("@TestObjectCleanup " + - "must return void"); - if((m.getModifiers() & - java.lang.reflect.Modifier.STATIC) < 1) - throw new RuntimeException("@TestObjectCleanup " + - "must be static."); - if(m.getParameterTypes().length == 0 || - m.getParameterTypes()[0] != testClass) - throw new RuntimeException("@TestObjectCleanup " + - "must take an argument of the tested type."); - m.setAccessible(true); - return m; - } - private static Object - createTestObject(Method creator) { - if(creator != null) { - try { - return creator.invoke(testClass); - } catch(IllegalAccessException | - IllegalArgumentException | - InvocationTargetException e) { - throw new RuntimeException("Couldn't run " + - "@TestObject (creator) method."); - } - } else { // Use the no-arg constructor: - try { - return testClass - .getConstructor().newInstance(); - } catch(InstantiationException | - NoSuchMethodException | - InvocationTargetException | - IllegalAccessException e) { - throw new RuntimeException( - "Couldn't create a test object. " + - "Try using a @TestObject method."); - } - } - } -} diff --git a/code/onjava/atunit/ClassNameFinder.java b/code/onjava/atunit/ClassNameFinder.java deleted file mode 100644 index 3fef7faf..00000000 --- a/code/onjava/atunit/ClassNameFinder.java +++ /dev/null @@ -1,180 +0,0 @@ -// onjava/atunit/ClassNameFinder.java -// (c)2020 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. -// {java onjava.atunit.ClassNameFinder} -package onjava.atunit; -import java.io.*; -import java.nio.file.*; -import java.util.*; -import onjava.*; - -public class ClassNameFinder { - public static String thisClass(byte[] classBytes) { - Map offsetTable = new HashMap<>(); - Map classNameTable = - new HashMap<>(); - try { - DataInputStream data = new DataInputStream( - new ByteArrayInputStream(classBytes)); - int magic = data.readInt(); // 0xcafebabe - int minorVersion = data.readShort(); - int majorVersion = data.readShort(); - int constantPoolCount = data.readShort(); - int[] constantPool = new int[constantPoolCount]; - for(int i = 1; i < constantPoolCount; i++) { - int tag = data.read(); - // int tableSize; - switch(tag) { - case 1: // UTF - int length = data.readShort(); - char[] bytes = new char[length]; - for(int k = 0; k < bytes.length; k++) - bytes[k] = (char)data.read(); - String className = new String(bytes); - classNameTable.put(i, className); - break; - case 5: // LONG - case 6: // DOUBLE - data.readLong(); // discard 8 bytes - i++; // Special skip necessary - break; - case 7: // CLASS - int offset = data.readShort(); - offsetTable.put(i, offset); - break; - case 8: // STRING - data.readShort(); // discard 2 bytes - break; - case 3: // INTEGER - case 4: // FLOAT - case 9: // FIELD_REF - case 10: // METHOD_REF - case 11: // INTERFACE_METHOD_REF - case 12: // NAME_AND_TYPE - case 18: // Invoke Dynamic - data.readInt(); // discard 4 bytes - break; - case 15: // Method Handle - data.readByte(); - data.readShort(); - break; - case 16: // Method Type - data.readShort(); - break; - default: - throw - new RuntimeException("Bad tag " + tag); - } - } - short accessFlags = data.readShort(); - String access = (accessFlags & 0x0001) == 0 ? - "nonpublic:" : "public:"; - int thisClass = data.readShort(); - int superClass = data.readShort(); - return access + classNameTable.get( - offsetTable.get(thisClass)).replace('/', '.'); - } catch(IOException | RuntimeException e) { - throw new RuntimeException(e); - } - } - // Demonstration: - public static void - main(String[] args) throws Exception { - PathMatcher matcher = FileSystems.getDefault() - .getPathMatcher("glob:**/*.class"); - // Walk the entire tree: - Files.walk(Paths.get(".")) - .filter(matcher::matches) - .map(p -> { - try { - return thisClass(Files.readAllBytes(p)); - } catch(Exception e) { - throw new RuntimeException(e); - } - }) - .filter(s -> s.startsWith("public:")) - // .filter(s -> s.indexOf('$') >= 0) - .map(s -> s.split(":")[1]) - .filter(s -> !s.startsWith("enums.")) - .filter(s -> s.contains(".")) - .forEach(System.out::println); - } -} -/* Output: -onjava.ArrayShow -onjava.atunit.AtUnit$TestMethods -onjava.atunit.AtUnit -onjava.atunit.ClassNameFinder -onjava.atunit.Test -onjava.atunit.TestObjectCleanup -onjava.atunit.TestObjectCreate -onjava.atunit.TestProperty -onjava.BasicSupplier -onjava.CollectionMethodDifferences -onjava.ConvertTo -onjava.Count$Boolean -onjava.Count$Byte -onjava.Count$Character -onjava.Count$Double -onjava.Count$Float -onjava.Count$Integer -onjava.Count$Long -onjava.Count$Pboolean -onjava.Count$Pbyte -onjava.Count$Pchar -onjava.Count$Pdouble -onjava.Count$Pfloat -onjava.Count$Pint -onjava.Count$Plong -onjava.Count$Pshort -onjava.Count$Short -onjava.Count -onjava.CountingIntegerList -onjava.CountMap -onjava.Countries -onjava.Enums -onjava.FillMap -onjava.HTMLColors -onjava.MouseClick -onjava.Nap -onjava.Null -onjava.Operations -onjava.OSExecute -onjava.OSExecuteException -onjava.Pair -onjava.ProcessFiles$Strategy -onjava.ProcessFiles -onjava.Rand$Boolean -onjava.Rand$Byte -onjava.Rand$Character -onjava.Rand$Double -onjava.Rand$Float -onjava.Rand$Integer -onjava.Rand$Long -onjava.Rand$Pboolean -onjava.Rand$Pbyte -onjava.Rand$Pchar -onjava.Rand$Pdouble -onjava.Rand$Pfloat -onjava.Rand$Pint -onjava.Rand$Plong -onjava.Rand$Pshort -onjava.Rand$Short -onjava.Rand$String -onjava.Rand -onjava.Range -onjava.Repeat -onjava.RmDir -onjava.Sets -onjava.Stack -onjava.Suppliers -onjava.TimedAbort -onjava.Timer -onjava.Tuple -onjava.Tuple2 -onjava.Tuple3 -onjava.Tuple4 -onjava.Tuple5 -onjava.TypeCounter -*/ diff --git a/code/onjava/atunit/Test.java b/code/onjava/atunit/Test.java deleted file mode 100644 index 314dce9b..00000000 --- a/code/onjava/atunit/Test.java +++ /dev/null @@ -1,11 +0,0 @@ -// onjava/atunit/Test.java -// (c)2020 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. -// The @Test tag -package onjava.atunit; -import java.lang.annotation.*; - -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface Test {} diff --git a/code/onjava/atunit/TestObjectCleanup.java b/code/onjava/atunit/TestObjectCleanup.java deleted file mode 100644 index 52231177..00000000 --- a/code/onjava/atunit/TestObjectCleanup.java +++ /dev/null @@ -1,11 +0,0 @@ -// onjava/atunit/TestObjectCleanup.java -// (c)2020 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. -// The @Unit @TestObjectCleanup tag -package onjava.atunit; -import java.lang.annotation.*; - -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface TestObjectCleanup {} diff --git a/code/onjava/atunit/TestObjectCreate.java b/code/onjava/atunit/TestObjectCreate.java deleted file mode 100644 index f8b43a09..00000000 --- a/code/onjava/atunit/TestObjectCreate.java +++ /dev/null @@ -1,11 +0,0 @@ -// onjava/atunit/TestObjectCreate.java -// (c)2020 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. -// The @Unit @TestObjectCreate tag -package onjava.atunit; -import java.lang.annotation.*; - -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface TestObjectCreate {} diff --git a/code/onjava/atunit/TestProperty.java b/code/onjava/atunit/TestProperty.java deleted file mode 100644 index 4e09cf95..00000000 --- a/code/onjava/atunit/TestProperty.java +++ /dev/null @@ -1,12 +0,0 @@ -// onjava/atunit/TestProperty.java -// (c)2020 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. -// The @Unit @TestProperty tag -package onjava.atunit; -import java.lang.annotation.*; - -// Both fields and methods can be tagged as properties: -@Target({ElementType.FIELD, ElementType.METHOD}) -@Retention(RetentionPolicy.RUNTIME) -public @interface TestProperty {} diff --git a/code/operators/AllOps.java b/code/operators/AllOps.java deleted file mode 100644 index bb94e870..00000000 --- a/code/operators/AllOps.java +++ /dev/null @@ -1,411 +0,0 @@ -// operators/AllOps.java -// (c)2020 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. -// Tests all operators on all primitive data types -// to show which ones are accepted by the Java compiler - -public class AllOps { - // To accept the results of a boolean test: - void f(boolean b) {} - void boolTest(boolean x, boolean y) { - // Arithmetic operators: - //- x = x * y; - //- x = x / y; - //- x = x % y; - //- x = x + y; - //- x = x - y; - //- x++; - //- x--; - //- x = +y; - //- x = -y; - // Relational and logical: - //- f(x > y); - //- f(x >= y); - //- f(x < y); - //- f(x <= y); - f(x == y); - f(x != y); - f(!y); - x = x && y; - x = x || y; - // Bitwise operators: - //- x = ~y; - x = x & y; - x = x | y; - x = x ^ y; - //- x = x << 1; - //- x = x >> 1; - //- x = x >>> 1; - // Compound assignment: - //- x += y; - //- x -= y; - //- x *= y; - //- x /= y; - //- x %= y; - //- x <<= 1; - //- x >>= 1; - //- x >>>= 1; - x &= y; - x ^= y; - x |= y; - // Casting: - //- char c = (char)x; - //- byte b = (byte)x; - //- short s = (short)x; - //- int i = (int)x; - //- long l = (long)x; - //- float f = (float)x; - //- double d = (double)x; - } - void charTest(char x, char y) { - // Arithmetic operators: - x = (char)(x * y); - x = (char)(x / y); - x = (char)(x % y); - x = (char)(x + y); - x = (char)(x - y); - x++; - x--; - x = (char) + y; - x = (char) - y; - // Relational and logical: - f(x > y); - f(x >= y); - f(x < y); - f(x <= y); - f(x == y); - f(x != y); - //- f(!x); - //- f(x && y); - //- f(x || y); - // Bitwise operators: - x= (char)~y; - x = (char)(x & y); - x = (char)(x | y); - x = (char)(x ^ y); - x = (char)(x << 1); - x = (char)(x >> 1); - x = (char)(x >>> 1); - // Compound assignment: - x += y; - x -= y; - x *= y; - x /= y; - x %= y; - x <<= 1; - x >>= 1; - x >>>= 1; - x &= y; - x ^= y; - x |= y; - // Casting: - //- boolean bl = (boolean)x; - byte b = (byte)x; - short s = (short)x; - int i = (int)x; - long l = (long)x; - float f = (float)x; - double d = (double)x; - } - void byteTest(byte x, byte y) { - // Arithmetic operators: - x = (byte)(x* y); - x = (byte)(x / y); - x = (byte)(x % y); - x = (byte)(x + y); - x = (byte)(x - y); - x++; - x--; - x = (byte) + y; - x = (byte) - y; - // Relational and logical: - f(x > y); - f(x >= y); - f(x < y); - f(x <= y); - f(x == y); - f(x != y); - //- f(!x); - //- f(x && y); - //- f(x || y); - // Bitwise operators: - x = (byte)~y; - x = (byte)(x & y); - x = (byte)(x | y); - x = (byte)(x ^ y); - x = (byte)(x << 1); - x = (byte)(x >> 1); - x = (byte)(x >>> 1); - // Compound assignment: - x += y; - x -= y; - x *= y; - x /= y; - x %= y; - x <<= 1; - x >>= 1; - x >>>= 1; - x &= y; - x ^= y; - x |= y; - // Casting: - //- boolean bl = (boolean)x; - char c = (char)x; - short s = (short)x; - int i = (int)x; - long l = (long)x; - float f = (float)x; - double d = (double)x; - } - void shortTest(short x, short y) { - // Arithmetic operators: - x = (short)(x * y); - x = (short)(x / y); - x = (short)(x % y); - x = (short)(x + y); - x = (short)(x - y); - x++; - x--; - x = (short) + y; - x = (short) - y; - // Relational and logical: - f(x > y); - f(x >= y); - f(x < y); - f(x <= y); - f(x == y); - f(x != y); - //- f(!x); - //- f(x && y); - //- f(x || y); - // Bitwise operators: - x = (short) ~ y; - x = (short)(x & y); - x = (short)(x | y); - x = (short)(x ^ y); - x = (short)(x << 1); - x = (short)(x >> 1); - x = (short)(x >>> 1); - // Compound assignment: - x += y; - x -= y; - x *= y; - x /= y; - x %= y; - x <<= 1; - x >>= 1; - x >>>= 1; - x &= y; - x ^= y; - x |= y; - // Casting: - //- boolean bl = (boolean)x; - char c = (char)x; - byte b = (byte)x; - int i = (int)x; - long l = (long)x; - float f = (float)x; - double d = (double)x; - } - void intTest(int x, int y) { - // Arithmetic operators: - x = x * y; - x = x / y; - x = x % y; - x = x + y; - x = x - y; - x++; - x--; - x = +y; - x = -y; - // Relational and logical: - f(x > y); - f(x >= y); - f(x < y); - f(x <= y); - f(x == y); - f(x != y); - //- f(!x); - //- f(x && y); - //- f(x || y); - // Bitwise operators: - x = ~y; - x = x & y; - x = x | y; - x = x ^ y; - x = x << 1; - x = x >> 1; - x = x >>> 1; - // Compound assignment: - x += y; - x -= y; - x *= y; - x /= y; - x %= y; - x <<= 1; - x >>= 1; - x >>>= 1; - x &= y; - x ^= y; - x |= y; - // Casting: - //- boolean bl = (boolean)x; - char c = (char)x; - byte b = (byte)x; - short s = (short)x; - long l = (long)x; - float f = (float)x; - double d = (double)x; - } - void longTest(long x, long y) { - // Arithmetic operators: - x = x * y; - x = x / y; - x = x % y; - x = x + y; - x = x - y; - x++; - x--; - x = +y; - x = -y; - // Relational and logical: - f(x > y); - f(x >= y); - f(x < y); - f(x <= y); - f(x == y); - f(x != y); - //- f(!x); - //- f(x && y); - //- f(x || y); - // Bitwise operators: - x = ~y; - x = x & y; - x = x | y; - x = x ^ y; - x = x << 1; - x = x >> 1; - x = x >>> 1; - // Compound assignment: - x += y; - x -= y; - x *= y; - x /= y; - x %= y; - x <<= 1; - x >>= 1; - x >>>= 1; - x &= y; - x ^= y; - x |= y; - // Casting: - //- boolean bl = (boolean)x; - char c = (char)x; - byte b = (byte)x; - short s = (short)x; - int i = (int)x; - float f = (float)x; - double d = (double)x; - } - void floatTest(float x, float y) { - // Arithmetic operators: - x = x * y; - x = x / y; - x = x % y; - x = x + y; - x = x - y; - x++; - x--; - x = +y; - x = -y; - // Relational and logical: - f(x > y); - f(x >= y); - f(x < y); - f(x <= y); - f(x == y); - f(x != y); - //- f(!x); - //- f(x && y); - //- f(x || y); - // Bitwise operators: - //- x = ~y; - //- x = x & y; - //- x = x | y; - //- x = x ^ y; - //- x = x << 1; - //- x = x >> 1; - //- x = x >>> 1; - // Compound assignment: - x += y; - x -= y; - x *= y; - x /= y; - x %= y; - //- x <<= 1; - //- x >>= 1; - //- x >>>= 1; - //- x &= y; - //- x ^= y; - //- x |= y; - // Casting: - //- boolean bl = (boolean)x; - char c = (char)x; - byte b = (byte)x; - short s = (short)x; - int i = (int)x; - long l = (long)x; - double d = (double)x; - } - void doubleTest(double x, double y) { - // Arithmetic operators: - x = x * y; - x = x / y; - x = x % y; - x = x + y; - x = x - y; - x++; - x--; - x = +y; - x = -y; - // Relational and logical: - f(x > y); - f(x >= y); - f(x < y); - f(x <= y); - f(x == y); - f(x != y); - //- f(!x); - //- f(x && y); - //- f(x || y); - // Bitwise operators: - //- x = ~y; - //- x = x & y; - //- x = x | y; - //- x = x ^ y; - //- x = x << 1; - //- x = x >> 1; - //- x = x >>> 1; - // Compound assignment: - x += y; - x -= y; - x *= y; - x /= y; - x %= y; - //- x <<= 1; - //- x >>= 1; - //- x >>>= 1; - //- x &= y; - //- x ^= y; - //- x |= y; - // Casting: - //- boolean bl = (boolean)x; - char c = (char)x; - byte b = (byte)x; - short s = (short)x; - int i = (int)x; - long l = (long)x; - float f = (float)x; - } -} diff --git a/code/operators/Assignment.java b/code/operators/Assignment.java deleted file mode 100644 index 7a573a39..00000000 --- a/code/operators/Assignment.java +++ /dev/null @@ -1,31 +0,0 @@ -// operators/Assignment.java -// (c)2020 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. -// Assignment with objects is a bit tricky - -class Tank { - int level; -} - -public class Assignment { - public static void main(String[] args) { - Tank t1 = new Tank(); - Tank t2 = new Tank(); - t1.level = 9; - t2.level = 47; - System.out.println("1: t1.level: " + t1.level + - ", t2.level: " + t2.level); - t1 = t2; - System.out.println("2: t1.level: " + t1.level + - ", t2.level: " + t2.level); - t1.level = 27; - System.out.println("3: t1.level: " + t1.level + - ", t2.level: " + t2.level); - } -} -/* Output: -1: t1.level: 9, t2.level: 47 -2: t1.level: 47, t2.level: 47 -3: t1.level: 27, t2.level: 27 -*/ diff --git a/code/operators/AutoInc.java b/code/operators/AutoInc.java deleted file mode 100644 index 835875de..00000000 --- a/code/operators/AutoInc.java +++ /dev/null @@ -1,27 +0,0 @@ -// operators/AutoInc.java -// (c)2020 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. -// Demonstrates the ++ and -- operators - -public class AutoInc { - public static void main(String[] args) { - int i = 1; - System.out.println("i: " + i); - System.out.println("++i: " + ++i); // Pre-increment - System.out.println("i++: " + i++); // Post-increment - System.out.println("i: " + i); - System.out.println("--i: " + --i); // Pre-decrement - System.out.println("i--: " + i--); // Post-decrement - System.out.println("i: " + i); - } -} -/* Output: -i: 1 -++i: 2 -i++: 2 -i: 3 ---i: 2 -i--: 2 -i: 1 -*/ diff --git a/code/operators/BitManipulation.java b/code/operators/BitManipulation.java deleted file mode 100644 index dc30c442..00000000 --- a/code/operators/BitManipulation.java +++ /dev/null @@ -1,98 +0,0 @@ -// operators/BitManipulation.java -// (c)2020 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. -// Using the bitwise operators -import java.util.*; - -public class BitManipulation { - public static void main(String[] args) { - Random rand = new Random(47); - int i = rand.nextInt(); - int j = rand.nextInt(); - printBinaryInt("-1", -1); - printBinaryInt("+1", +1); - int maxpos = 2147483647; - printBinaryInt("maxpos", maxpos); - int maxneg = -2147483648; - printBinaryInt("maxneg", maxneg); - printBinaryInt("i", i); - printBinaryInt("~i", ~i); - printBinaryInt("-i", -i); - printBinaryInt("j", j); - printBinaryInt("i & j", i & j); - printBinaryInt("i | j", i | j); - printBinaryInt("i ^ j", i ^ j); - printBinaryInt("i << 5", i << 5); - printBinaryInt("i >> 5", i >> 5); - printBinaryInt("(~i) >> 5", (~i) >> 5); - printBinaryInt("i >>> 5", i >>> 5); - printBinaryInt("(~i) >>> 5", (~i) >>> 5); - - long l = rand.nextLong(); - long m = rand.nextLong(); - printBinaryLong("-1L", -1L); - printBinaryLong("+1L", +1L); - long ll = 9223372036854775807L; - printBinaryLong("maxpos", ll); - long lln = -9223372036854775808L; - printBinaryLong("maxneg", lln); - printBinaryLong("l", l); - printBinaryLong("~l", ~l); - printBinaryLong("-l", -l); - printBinaryLong("m", m); - printBinaryLong("l & m", l & m); - printBinaryLong("l | m", l | m); - printBinaryLong("l ^ m", l ^ m); - printBinaryLong("l << 5", l << 5); - printBinaryLong("l >> 5", l >> 5); - printBinaryLong("(~l) >> 5", (~l) >> 5); - printBinaryLong("l >>> 5", l >>> 5); - printBinaryLong("(~l) >>> 5", (~l) >>> 5); - } - static void printBinaryInt(String s, int i) { - System.out.println( - s + ", int: " + i + ", binary:\n " + - Integer.toBinaryString(i)); - } - static void printBinaryLong(String s, long l) { - System.out.println( - s + ", long: " + l + ", binary:\n " + - Long.toBinaryString(l)); - } -} -/* Output: (First 32 Lines) --1, int: -1, binary: - 11111111111111111111111111111111 -+1, int: 1, binary: - 1 -maxpos, int: 2147483647, binary: - 1111111111111111111111111111111 -maxneg, int: -2147483648, binary: - 10000000000000000000000000000000 -i, int: -1172028779, binary: - 10111010001001000100001010010101 -~i, int: 1172028778, binary: - 1000101110110111011110101101010 --i, int: 1172028779, binary: - 1000101110110111011110101101011 -j, int: 1717241110, binary: - 1100110010110110000010100010110 -i & j, int: 570425364, binary: - 100010000000000000000000010100 -i | j, int: -25213033, binary: - 11111110011111110100011110010111 -i ^ j, int: -595638397, binary: - 11011100011111110100011110000011 -i << 5, int: 1149784736, binary: - 1000100100010000101001010100000 -i >> 5, int: -36625900, binary: - 11111101110100010010001000010100 -(~i) >> 5, int: 36625899, binary: - 10001011101101110111101011 -i >>> 5, int: 97591828, binary: - 101110100010010001000010100 -(~i) >>> 5, int: 36625899, binary: - 10001011101101110111101011 - ... -*/ diff --git a/code/operators/Bool.java b/code/operators/Bool.java deleted file mode 100644 index e9984adb..00000000 --- a/code/operators/Bool.java +++ /dev/null @@ -1,42 +0,0 @@ -// operators/Bool.java -// (c)2020 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. -// Relational and logical operators -import java.util.*; - -public class Bool { - public static void main(String[] args) { - Random rand = new Random(47); - int i = rand.nextInt(100); - int j = rand.nextInt(100); - System.out.println("i = " + i); - System.out.println("j = " + j); - System.out.println("i > j is " + (i > j)); - System.out.println("i < j is " + (i < j)); - System.out.println("i >= j is " + (i >= j)); - System.out.println("i <= j is " + (i <= j)); - System.out.println("i == j is " + (i == j)); - System.out.println("i != j is " + (i != j)); - // Treating an int as a boolean is not legal Java: - //- System.out.println("i && j is " + (i && j)); - //- System.out.println("i || j is " + (i || j)); - //- System.out.println("!i is " + !i); - System.out.println("(i < 10) && (j < 10) is " - + ((i < 10) && (j < 10)) ); - System.out.println("(i < 10) || (j < 10) is " - + ((i < 10) || (j < 10)) ); - } -} -/* Output: -i = 58 -j = 55 -i > j is true -i < j is false -i >= j is true -i <= j is false -i == j is false -i != j is true -(i < 10) && (j < 10) is false -(i < 10) || (j < 10) is false -*/ diff --git a/code/operators/Casting.java b/code/operators/Casting.java deleted file mode 100644 index 337b24fd..00000000 --- a/code/operators/Casting.java +++ /dev/null @@ -1,16 +0,0 @@ -// operators/Casting.java -// (c)2020 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. - -public class Casting { - public static void main(String[] args) { - int i = 200; - long lng = (long)i; - lng = i; // "Widening," so a cast is not required - long lng2 = (long)200; - lng2 = 200; - // A "narrowing conversion": - i = (int)lng2; // Cast required - } -} diff --git a/code/operators/CastingNumbers.java b/code/operators/CastingNumbers.java deleted file mode 100644 index a6c04c6e..00000000 --- a/code/operators/CastingNumbers.java +++ /dev/null @@ -1,23 +0,0 @@ -// operators/CastingNumbers.java -// (c)2020 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 happens when you cast a float -// or double to an integral value? - -public class CastingNumbers { - public static void main(String[] args) { - double above = 0.7, below = 0.4; - float fabove = 0.7f, fbelow = 0.4f; - System.out.println("(int)above: " + (int)above); - System.out.println("(int)below: " + (int)below); - System.out.println("(int)fabove: " + (int)fabove); - System.out.println("(int)fbelow: " + (int)fbelow); - } -} -/* Output: -(int)above: 0 -(int)below: 0 -(int)fabove: 0 -(int)fbelow: 0 -*/ diff --git a/code/operators/EqualsMethod.java b/code/operators/EqualsMethod.java deleted file mode 100644 index f55b1b57..00000000 --- a/code/operators/EqualsMethod.java +++ /dev/null @@ -1,15 +0,0 @@ -// operators/EqualsMethod.java -// (c)2020 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. - -public class EqualsMethod { - public static void main(String[] args) { - Integer n1 = 47; - Integer n2 = 47; - System.out.println(n1.equals(n2)); - } -} -/* Output: -true -*/ diff --git a/code/operators/EqualsMethod2.java b/code/operators/EqualsMethod2.java deleted file mode 100644 index 21393060..00000000 --- a/code/operators/EqualsMethod2.java +++ /dev/null @@ -1,21 +0,0 @@ -// operators/EqualsMethod2.java -// (c)2020 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. -// Default equals() does not compare contents - -class Value { - int i; -} - -public class EqualsMethod2 { - public static void main(String[] args) { - Value v1 = new Value(); - Value v2 = new Value(); - v1.i = v2.i = 100; - System.out.println(v1.equals(v2)); - } -} -/* Output: -false -*/ diff --git a/code/operators/Equivalence.java b/code/operators/Equivalence.java deleted file mode 100644 index cef07d64..00000000 --- a/code/operators/Equivalence.java +++ /dev/null @@ -1,17 +0,0 @@ -// operators/Equivalence.java -// (c)2020 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. - -public class Equivalence { - public static void main(String[] args) { - Integer n1 = 47; - Integer n2 = 47; - System.out.println(n1 == n2); - System.out.println(n1 != n2); - } -} -/* Output: -true -false -*/ diff --git a/code/operators/Exponents.java b/code/operators/Exponents.java deleted file mode 100644 index 924340df..00000000 --- a/code/operators/Exponents.java +++ /dev/null @@ -1,21 +0,0 @@ -// operators/Exponents.java -// (c)2020 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. -// "e" means "10 to the power." - -public class Exponents { - public static void main(String[] args) { - // Uppercase and lowercase 'e' are the same: - float expFloat = 1.39e-43f; - expFloat = 1.39E-43f; - System.out.println(expFloat); - double expDouble = 47e47d; // 'd' is optional - double expDouble2 = 47e47; // Automatically double - System.out.println(expDouble); - } -} -/* Output: -1.39E-43 -4.7E48 -*/ diff --git a/code/operators/Literals.java b/code/operators/Literals.java deleted file mode 100644 index ad00e0b8..00000000 --- a/code/operators/Literals.java +++ /dev/null @@ -1,61 +0,0 @@ -// operators/Literals.java -// (c)2020 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. - -public class Literals { - public static void main(String[] args) { - int i1 = 0x2f; // Hexadecimal (lowercase) - System.out.println( - "i1: " + Integer.toBinaryString(i1)); - int i2 = 0X2F; // Hexadecimal (uppercase) - System.out.println( - "i2: " + Integer.toBinaryString(i2)); - int i3 = 0177; // Octal (leading zero) - System.out.println( - "i3: " + Integer.toBinaryString(i3)); - char c = 0xffff; // max char hex value - System.out.println( - "c: " + Integer.toBinaryString(c)); - byte b = 0x7f; // max byte hex value 10101111; - System.out.println( - "b: " + Integer.toBinaryString(b)); - short s = 0x7fff; // max short hex value - System.out.println( - "s: " + Integer.toBinaryString(s)); - long n1 = 200L; // long suffix - long n2 = 200l; // long suffix (can be confusing) - long n3 = 200; - // Java 7 Binary Literals: - byte blb = (byte)0b00110101; - System.out.println( - "blb: " + Integer.toBinaryString(blb)); - short bls = (short)0B0010111110101111; - System.out.println( - "bls: " + Integer.toBinaryString(bls)); - int bli = 0b00101111101011111010111110101111; - System.out.println( - "bli: " + Integer.toBinaryString(bli)); - long bll = 0b00101111101011111010111110101111; - System.out.println( - "bll: " + Long.toBinaryString(bll)); - float f1 = 1; - float f2 = 1F; // float suffix - float f3 = 1f; // float suffix - double d1 = 1d; // double suffix - double d2 = 1D; // double suffix - // (Hex and Octal also work with long) - } -} -/* Output: -i1: 101111 -i2: 101111 -i3: 1111111 -c: 1111111111111111 -b: 1111111 -s: 111111111111111 -blb: 110101 -bls: 10111110101111 -bli: 101111101011111010111110101111 -bll: 101111101011111010111110101111 -*/ diff --git a/code/operators/MathOps.java b/code/operators/MathOps.java deleted file mode 100644 index a9b08938..00000000 --- a/code/operators/MathOps.java +++ /dev/null @@ -1,75 +0,0 @@ -// operators/MathOps.java -// (c)2020 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. -// The mathematical operators -import java.util.*; - -public class MathOps { - public static void main(String[] args) { - // Create a seeded random number generator: - Random rand = new Random(47); - int i, j, k; - // Choose value from 1 to 100: - j = rand.nextInt(100) + 1; - System.out.println("j : " + j); - k = rand.nextInt(100) + 1; - System.out.println("k : " + k); - i = j + k; - System.out.println("j + k : " + i); - i = j - k; - System.out.println("j - k : " + i); - i = k / j; - System.out.println("k / j : " + i); - i = k * j; - System.out.println("k * j : " + i); - i = k % j; - System.out.println("k % j : " + i); - j %= k; - System.out.println("j %= k : " + j); - // Floating-point number tests: - float u, v, w; // Applies to doubles, too - v = rand.nextFloat(); - System.out.println("v : " + v); - w = rand.nextFloat(); - System.out.println("w : " + w); - u = v + w; - System.out.println("v + w : " + u); - u = v - w; - System.out.println("v - w : " + u); - u = v * w; - System.out.println("v * w : " + u); - u = v / w; - System.out.println("v / w : " + u); - // The following also works for char, - // byte, short, int, long, and double: - u += v; - System.out.println("u += v : " + u); - u -= v; - System.out.println("u -= v : " + u); - u *= v; - System.out.println("u *= v : " + u); - u /= v; - System.out.println("u /= v : " + u); - } -} -/* Output: -j : 59 -k : 56 -j + k : 115 -j - k : 3 -k / j : 0 -k * j : 3304 -k % j : 56 -j %= k : 3 -v : 0.5309454 -w : 0.0534122 -v + w : 0.5843576 -v - w : 0.47753322 -v * w : 0.028358962 -v / w : 9.940527 -u += v : 10.471473 -u -= v : 9.940527 -u *= v : 5.2778773 -u /= v : 9.940527 -*/ diff --git a/code/operators/Overflow.java b/code/operators/Overflow.java deleted file mode 100644 index 851c1456..00000000 --- a/code/operators/Overflow.java +++ /dev/null @@ -1,18 +0,0 @@ -// operators/Overflow.java -// (c)2020 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. -// Surprise! Java lets you overflow - -public class Overflow { - public static void main(String[] args) { - int big = Integer.MAX_VALUE; - System.out.println("big = " + big); - int bigger = big * 4; - System.out.println("bigger = " + bigger); - } -} -/* Output: -big = 2147483647 -bigger = -4 -*/ diff --git a/code/operators/PassObject.java b/code/operators/PassObject.java deleted file mode 100644 index af53ab56..00000000 --- a/code/operators/PassObject.java +++ /dev/null @@ -1,27 +0,0 @@ -// operators/PassObject.java -// (c)2020 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. -// Passing objects to methods might not be -// what you're used to - -class Letter { - char c; -} - -public class PassObject { - static void f(Letter y) { - y.c = 'z'; - } - public static void main(String[] args) { - Letter x = new Letter(); - x.c = 'a'; - System.out.println("1: x.c: " + x.c); - f(x); - System.out.println("2: x.c: " + x.c); - } -} -/* Output: -1: x.c: a -2: x.c: z -*/ diff --git a/code/operators/Precedence.java b/code/operators/Precedence.java deleted file mode 100644 index f0f8140c..00000000 --- a/code/operators/Precedence.java +++ /dev/null @@ -1,18 +0,0 @@ -// operators/Precedence.java -// (c)2020 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. - -public class Precedence { - public static void main(String[] args) { - int x = 1, y = 2, z = 3; - int a = x + y - 2/2 + z; // [1] - int b = x + (y - 2)/(2 + z); // [2] - System.out.println("a = " + a); - System.out.println("b = " + b); - } -} -/* Output: -a = 5 -b = 1 -*/ diff --git a/code/operators/RoundingNumbers.java b/code/operators/RoundingNumbers.java deleted file mode 100644 index e46a2056..00000000 --- a/code/operators/RoundingNumbers.java +++ /dev/null @@ -1,26 +0,0 @@ -// operators/RoundingNumbers.java -// (c)2020 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. -// Rounding floats and doubles - -public class RoundingNumbers { - public static void main(String[] args) { - double above = 0.7, below = 0.4; - float fabove = 0.7f, fbelow = 0.4f; - System.out.println( - "Math.round(above): " + Math.round(above)); - System.out.println( - "Math.round(below): " + Math.round(below)); - System.out.println( - "Math.round(fabove): " + Math.round(fabove)); - System.out.println( - "Math.round(fbelow): " + Math.round(fbelow)); - } -} -/* Output: -Math.round(above): 1 -Math.round(below): 0 -Math.round(fabove): 1 -Math.round(fbelow): 0 -*/ diff --git a/code/operators/ShortCircuit.java b/code/operators/ShortCircuit.java deleted file mode 100644 index 8fc96711..00000000 --- a/code/operators/ShortCircuit.java +++ /dev/null @@ -1,34 +0,0 @@ -// operators/ShortCircuit.java -// (c)2020 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. -// Short-circuiting behavior with logical operators - -public class ShortCircuit { - static boolean test1(int val) { - System.out.println("test1(" + val + ")"); - System.out.println("result: " + (val < 1)); - return val < 1; - } - static boolean test2(int val) { - System.out.println("test2(" + val + ")"); - System.out.println("result: " + (val < 2)); - return val < 2; - } - static boolean test3(int val) { - System.out.println("test3(" + val + ")"); - System.out.println("result: " + (val < 3)); - return val < 3; - } - public static void main(String[] args) { - boolean b = test1(0) && test2(2) && test3(2); - System.out.println("expression is " + b); - } -} -/* Output: -test1(0) -result: true -test2(2) -result: false -expression is false -*/ diff --git a/code/operators/StringOperators.java b/code/operators/StringOperators.java deleted file mode 100644 index b1eb211f..00000000 --- a/code/operators/StringOperators.java +++ /dev/null @@ -1,24 +0,0 @@ -// operators/StringOperators.java -// (c)2020 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. - -public class StringOperators { - public static void main(String[] args) { - int x = 0, y = 1, z = 2; - String s = "x, y, z "; - System.out.println(s + x + y + z); - // Converts x to a String: - System.out.println(x + " " + s); - s += "(summed) = "; // Concatenation operator - System.out.println(s + (x + y + z)); - // Shorthand for Integer.toString(): - System.out.println("" + x); - } -} -/* Output: -x, y, z 012 -0 x, y, z -x, y, z (summed) = 3 -0 -*/ diff --git a/code/operators/TernaryIfElse.java b/code/operators/TernaryIfElse.java deleted file mode 100644 index d11d4e24..00000000 --- a/code/operators/TernaryIfElse.java +++ /dev/null @@ -1,28 +0,0 @@ -// operators/TernaryIfElse.java -// (c)2020 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. - -public class TernaryIfElse { - static int ternary(int i) { - return i < 10 ? i * 100 : i * 10; - } - static int standardIfElse(int i) { - if(i < 10) - return i * 100; - else - return i * 10; - } - public static void main(String[] args) { - System.out.println(ternary(9)); - System.out.println(ternary(10)); - System.out.println(standardIfElse(9)); - System.out.println(standardIfElse(10)); - } -} -/* Output: -900 -100 -900 -100 -*/ diff --git a/code/operators/URShift.java b/code/operators/URShift.java deleted file mode 100644 index 8d24f94b..00000000 --- a/code/operators/URShift.java +++ /dev/null @@ -1,42 +0,0 @@ -// operators/URShift.java -// (c)2020 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. -// Test of unsigned right shift - -public class URShift { - public static void main(String[] args) { - int i = -1; - System.out.println(Integer.toBinaryString(i)); - i >>>= 10; - System.out.println(Integer.toBinaryString(i)); - long l = -1; - System.out.println(Long.toBinaryString(l)); - l >>>= 10; - System.out.println(Long.toBinaryString(l)); - short s = -1; - System.out.println(Integer.toBinaryString(s)); - s >>>= 10; - System.out.println(Integer.toBinaryString(s)); - byte b = -1; - System.out.println(Integer.toBinaryString(b)); - b >>>= 10; - System.out.println(Integer.toBinaryString(b)); - b = -1; - System.out.println(Integer.toBinaryString(b)); - System.out.println(Integer.toBinaryString(b>>>10)); - } -} -/* Output: -11111111111111111111111111111111 -1111111111111111111111 -1111111111111111111111111111111111111111111111111111111 -111111111 -111111111111111111111111111111111111111111111111111111 -11111111111111111111111111111111 -11111111111111111111111111111111 -11111111111111111111111111111111 -11111111111111111111111111111111 -11111111111111111111111111111111 -1111111111111111111111 -*/ diff --git a/code/operators/Underscores.java b/code/operators/Underscores.java deleted file mode 100644 index 4d78cd50..00000000 --- a/code/operators/Underscores.java +++ /dev/null @@ -1,22 +0,0 @@ -// operators/Underscores.java -// (c)2020 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. - -public class Underscores { - public static void main(String[] args) { - double d = 341_435_936.445_667; - System.out.println(d); - int bin = 0b0010_1111_1010_1111_1010_1111_1010_1111; - System.out.println(Integer.toBinaryString(bin)); - System.out.printf("%x%n", bin); // [1] - long hex = 0x7f_e9_b7_aa; - System.out.printf("%x%n", hex); - } -} -/* Output: -3.41435936445667E8 -101111101011111010111110101111 -2fafafaf -7fe9b7aa -*/ diff --git a/code/patterns/BoxObserver.java b/code/patterns/BoxObserver.java deleted file mode 100644 index c6f9ec65..00000000 --- a/code/patterns/BoxObserver.java +++ /dev/null @@ -1,94 +0,0 @@ -// patterns/BoxObserver.java -// (c)2020 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. -// Demonstration of Observer pattern using -// Java's built-in observer classes. -// {ExcludeFromGradle} // Won't work under WSL2 -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import java.util.*; -import onjava.*; -import onjava.MouseClick; - -// You must inherit a new type of Observable: -@SuppressWarnings("deprecation") -class BoxObservable extends Observable { - @Override - public void notifyObservers(Object b) { - // Otherwise it won't propagate changes: - setChanged(); - super.notifyObservers(b); - } -} - -@SuppressWarnings("deprecation") -public class BoxObserver extends JFrame { - Observable notifier = new BoxObservable(); - public BoxObserver(int grid) { - setTitle("Demonstrates Observer pattern"); - Container cp = getContentPane(); - cp.setLayout(new GridLayout(grid, grid)); - for(int x = 0; x < grid; x++) - for(int y = 0; y < grid; y++) - cp.add(new OCBox(x, y, notifier)); - } - public static void main(String[] args) { - // For automated test runs: - // new TimedAbort(4); - int grid = 8; - if(args.length > 0) - grid = Integer.parseInt(args[0]); - JFrame f = new BoxObserver(grid); - f.setSize(500, 400); - f.setVisible(true); - f.setDefaultCloseOperation(DISPOSE_ON_CLOSE); - } -} - -@SuppressWarnings("deprecation") -class OCBox extends JPanel implements Observer { - Observable notifier; - int x, y; // Locations in grid - Color cColor = newColor(); - static final Color[] COLORS = { - Color.black, Color.blue, Color.cyan, - Color.darkGray, Color.gray, Color.green, - Color.lightGray, Color.magenta, - Color.orange, Color.pink, Color.red, - Color.white, Color.yellow - }; - static Color newColor() { - return COLORS[ - (int)(Math.random() * COLORS.length) - ]; - } - OCBox(int x, int y, Observable notifier) { - this.x = x; - this.y = y; - notifier.addObserver(this); - this.notifier = notifier; - addMouseListener((MouseClick) - e -> notifier.notifyObservers(OCBox.this)); - } - @Override - public void paintComponent(Graphics g) { - super.paintComponent(g); - g.setColor(cColor); - Dimension s = getSize(); - g.fillRect(0, 0, s.width, s.height); - } - @Override - public void update(Observable o, Object arg) { - OCBox clicked = (OCBox)arg; - if(nextTo(clicked)) { - cColor = clicked.cColor; - repaint(); - } - } - private boolean nextTo(OCBox b) { - return Math.abs(x - b.x) <= 1 && - Math.abs(y - b.y) <= 1; - } -} diff --git a/code/patterns/CommandPattern.java b/code/patterns/CommandPattern.java deleted file mode 100644 index f84533aa..00000000 --- a/code/patterns/CommandPattern.java +++ /dev/null @@ -1,19 +0,0 @@ -// patterns/CommandPattern.java -// (c)2020 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. -import java.util.*; - -public class CommandPattern { - public static void main(String[] args) { - List macro = Arrays.asList( - () -> System.out.print("Hello "), - () -> System.out.print("World! "), - () -> System.out.print("I'm the command pattern!") - ); - macro.forEach(Runnable::run); - } -} -/* Output: -Hello World! I'm the command pattern! -*/ diff --git a/code/patterns/Facade.java b/code/patterns/Facade.java deleted file mode 100644 index 0c1accf2..00000000 --- a/code/patterns/Facade.java +++ /dev/null @@ -1,24 +0,0 @@ -// patterns/Facade.java -// (c)2020 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. - -class A { A(int x) {} } -class B { B(long x) {} } -class C { C(double x) {} } - -// Other classes that aren't exposed by the -// facade go here ... - -public class Facade { - static A makeA(int x) { return new A(x); } - static B makeB(long x) { return new B(x); } - static C makeC(double x) { return new C(x); } - public static void main(String[] args) { - // The client programmer gets the objects - // by calling the static methods: - A a = Facade.makeA(1); - B b = Facade.makeB(1); - C c = Facade.makeC(1.0); - } -} diff --git a/code/patterns/PaperScissorsRock.java b/code/patterns/PaperScissorsRock.java deleted file mode 100644 index e7a7c44e..00000000 --- a/code/patterns/PaperScissorsRock.java +++ /dev/null @@ -1,135 +0,0 @@ -// patterns/PaperScissorsRock.java -// (c)2020 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. -// Demonstration of multiple dispatching -import java.util.*; -import java.util.function.*; -import java.util.stream.*; -import onjava.*; -import static onjava.Tuple.*; - -enum Outcome { WIN, LOSE, DRAW } - -interface Item { - Outcome compete(Item it); - Outcome eval(Paper p); - Outcome eval(Scissors s); - Outcome eval(Rock r); -} - -class Paper implements Item { - @Override - public Outcome compete(Item it) { - return it.eval(this); - } - @Override - public Outcome eval(Paper p) { - return Outcome.DRAW; - } - @Override - public Outcome eval(Scissors s) { - return Outcome.WIN; - } - @Override - public Outcome eval(Rock r) { - return Outcome.LOSE; - } - @Override - public String toString() { return "Paper"; } -} - -class Scissors implements Item { - @Override - public Outcome compete(Item it) { - return it.eval(this); - } - @Override - public Outcome eval(Paper p) { - return Outcome.LOSE; - } - @Override - public Outcome eval(Scissors s) { - return Outcome.DRAW; - } - @Override - public Outcome eval(Rock r) { - return Outcome.WIN; - } - @Override - public String toString() { return "Scissors"; } -} - -class Rock implements Item { - @Override - public Outcome compete(Item it) { - return it.eval(this); - } - @Override - public Outcome eval(Paper p) { - return Outcome.WIN; - } - @Override - public Outcome eval(Scissors s) { - return Outcome.LOSE; - } - @Override - public Outcome eval(Rock r) { - return Outcome.DRAW; - } - @Override - public String toString() { return "Rock"; } -} - -class ItemFactory { - static List> items = - Arrays.asList( - Scissors::new, Paper::new, Rock::new); - static final int SZ = items.size(); - private static SplittableRandom rand = - new SplittableRandom(47); - public static Item newItem() { - return items.get(rand.nextInt(SZ)).get(); - } - public static Tuple2 newPair() { - return tuple(newItem(), newItem()); - } -} - -class Compete { - public static Outcome match(Tuple2 p) { - System.out.print(p.a1 + " -> " + p.a2 + " : "); - return p.a1.compete(p.a2); - } -} - -public class PaperScissorsRock { - public static void main(String[] args) { - Stream.generate(ItemFactory::newPair) - .limit(20) - .map(Compete::match) - .forEach(System.out::println); - } -} -/* Output: -Scissors -> Rock : LOSE -Scissors -> Paper : WIN -Rock -> Paper : LOSE -Rock -> Rock : DRAW -Rock -> Paper : LOSE -Paper -> Scissors : LOSE -Rock -> Paper : LOSE -Scissors -> Scissors : DRAW -Scissors -> Rock : LOSE -Scissors -> Paper : WIN -Scissors -> Rock : LOSE -Paper -> Scissors : LOSE -Rock -> Rock : DRAW -Scissors -> Scissors : DRAW -Paper -> Paper : DRAW -Scissors -> Paper : WIN -Scissors -> Rock : LOSE -Scissors -> Paper : WIN -Rock -> Paper : LOSE -Rock -> Scissors : WIN -*/ diff --git a/code/patterns/ProxyDemo.java b/code/patterns/ProxyDemo.java deleted file mode 100644 index 58b0e3a8..00000000 --- a/code/patterns/ProxyDemo.java +++ /dev/null @@ -1,51 +0,0 @@ -// patterns/ProxyDemo.java -// (c)2020 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. -// Simple demonstration of the Proxy pattern - -interface ProxyBase { - void f(); - void g(); - void h(); -} - -class Proxy implements ProxyBase { - private ProxyBase implementation; - Proxy() { - implementation = new Implementation(); - } - // Pass method calls to the implementation: - @Override - public void f() { implementation.f(); } - @Override - public void g() { implementation.g(); } - @Override - public void h() { implementation.h(); } -} - -class Implementation implements ProxyBase { - public void f() { - System.out.println("Implementation.f()"); - } - public void g() { - System.out.println("Implementation.g()"); - } - public void h() { - System.out.println("Implementation.h()"); - } -} - -public class ProxyDemo { - public static void main(String[] args) { - Proxy p = new Proxy(); - p.f(); - p.g(); - p.h(); - } -} -/* Output: -Implementation.f() -Implementation.g() -Implementation.h() -*/ diff --git a/code/patterns/ShapeFactory1.java b/code/patterns/ShapeFactory1.java deleted file mode 100644 index dc6f8690..00000000 --- a/code/patterns/ShapeFactory1.java +++ /dev/null @@ -1,39 +0,0 @@ -// patterns/ShapeFactory1.java -// (c)2020 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. -// A simple static factory method -import java.util.*; -import java.util.stream.*; -import patterns.shapes.*; - -public class ShapeFactory1 implements FactoryMethod { - public Shape create(String type) { - switch(type) { - case "Circle": return new Circle(); - case "Square": return new Square(); - case "Triangle": return new Triangle(); - default: - throw new BadShapeCreation(type); - } - } - public static void main(String[] args) { - FactoryTest.test(new ShapeFactory1()); - } -} -/* Output: -Circle[0] draw -Circle[0] erase -Square[1] draw -Square[1] erase -Triangle[2] draw -Triangle[2] erase -Square[3] draw -Square[3] erase -Circle[4] draw -Circle[4] erase -Circle[5] draw -Circle[5] erase -Triangle[6] draw -Triangle[6] erase -*/ diff --git a/code/patterns/ShapeFactory2.java b/code/patterns/ShapeFactory2.java deleted file mode 100644 index 23881105..00000000 --- a/code/patterns/ShapeFactory2.java +++ /dev/null @@ -1,54 +0,0 @@ -// patterns/ShapeFactory2.java -// (c)2020 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. -import java.util.*; -import java.lang.reflect.*; -import java.util.stream.*; -import patterns.shapes.*; - -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(ClassNotFoundException | - NoSuchMethodException e) { - throw new BadShapeCreation(id); - } - } - public Shape create(String id) { - try { - return (Shape)factories - .computeIfAbsent(id, ShapeFactory2::load) - .newInstance(); - } catch(Exception e) { - throw new BadShapeCreation(id); - } - } - public static void main(String[] args) { - FactoryTest.test(new ShapeFactory2()); - } -} -/* Output: -loading Circle -Circle[0] draw -Circle[0] erase -loading Square -Square[1] draw -Square[1] erase -loading Triangle -Triangle[2] draw -Triangle[2] erase -Square[3] draw -Square[3] erase -Circle[4] draw -Circle[4] erase -Circle[5] draw -Circle[5] erase -Triangle[6] draw -Triangle[6] erase -*/ diff --git a/code/patterns/ShapeFactory3.java b/code/patterns/ShapeFactory3.java deleted file mode 100644 index b735a81d..00000000 --- a/code/patterns/ShapeFactory3.java +++ /dev/null @@ -1,52 +0,0 @@ -// patterns/ShapeFactory3.java -// (c)2020 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. -// Polymorphic factory methods -import java.util.*; -import java.util.function.*; -import java.util.stream.*; -import patterns.shapes.*; - -interface PolymorphicFactory { - Shape create(); -} - -class RandomShapes implements Supplier { - private final PolymorphicFactory[] factories; - private Random rand = new Random(42); - RandomShapes(PolymorphicFactory... factories) { - this.factories = factories; - } - public Shape get() { - return factories[ - rand.nextInt(factories.length)].create(); - } -} - -public class ShapeFactory3 { - public static void main(String[] args) { - RandomShapes rs = new RandomShapes( - Circle::new, Square::new, Triangle::new - ); - Stream.generate(rs) - .limit(6) - .peek(Shape::draw) - .peek(Shape::erase) - .count(); - } -} -/* Output: -Triangle[0] draw -Triangle[0] erase -Circle[1] draw -Circle[1] erase -Circle[2] draw -Circle[2] erase -Triangle[3] draw -Triangle[3] erase -Circle[4] draw -Circle[4] erase -Square[5] draw -Square[5] erase -*/ diff --git a/code/patterns/SingletonPattern.java b/code/patterns/SingletonPattern.java deleted file mode 100644 index c2ca1a5f..00000000 --- a/code/patterns/SingletonPattern.java +++ /dev/null @@ -1,58 +0,0 @@ -// patterns/SingletonPattern.java -// (c)2020 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. - -interface Resource { - int getValue(); - void setValue(int x); -} - -// This isn't inherited from a Cloneable -// base class and cloneability isn't added so -// making it final prevents cloneability from -// being added through inheritance. This also -// implements thread-safe lazy initialization: - -final class Singleton { - private static final class - ResourceImpl implements Resource { - private int i; - private ResourceImpl(int i) { - this.i = i; - } - public synchronized int getValue() { - return i; - } - public synchronized void setValue(int x) { - i = x; - } - } - private static class ResourceHolder { - private static Resource resource = - new ResourceImpl(47); - } - public static Resource getResource() { - return ResourceHolder.resource; - } -} - -public class SingletonPattern { - public static void main(String[] args) { - Resource r = Singleton.getResource(); - System.out.println(r.getValue()); - Resource s2 = Singleton.getResource(); - s2.setValue(9); - System.out.println(r.getValue()); - try { - // Can't do this: compile-time error. - // Singleton s3 = (Singleton)s2.clone(); - } catch(Exception e) { - throw new RuntimeException(e); - } - } -} -/* Output: -47 -9 -*/ diff --git a/code/patterns/StateDemo.java b/code/patterns/StateDemo.java deleted file mode 100644 index 9efab5b4..00000000 --- a/code/patterns/StateDemo.java +++ /dev/null @@ -1,87 +0,0 @@ -// patterns/StateDemo.java -// (c)2020 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. -// Simple demonstration of the State pattern - -interface StateBase { - void f(); - void g(); - void h(); - void changeImp(StateBase newImp); -} - -class State implements StateBase { - private StateBase implementation; - State(StateBase imp) { - implementation = imp; - } - @Override - public void changeImp(StateBase newImp) { - implementation = newImp; - } - // Pass method calls to the implementation: - @Override - public void f() { implementation.f(); } - @Override - public void g() { implementation.g(); } - @Override - public void h() { implementation.h(); } -} - -class Implementation1 implements StateBase { - @Override - public void f() { - System.out.println("Implementation1.f()"); - } - @Override - public void g() { - System.out.println("Implementation1.g()"); - } - @Override - public void h() { - System.out.println("Implementation1.h()"); - } - @Override - public void changeImp(StateBase newImp) {} -} - -class Implementation2 implements StateBase { - @Override - public void f() { - System.out.println("Implementation2.f()"); - } - @Override - public void g() { - System.out.println("Implementation2.g()"); - } - @Override - public void h() { - System.out.println("Implementation2.h()"); - } - @Override - public void changeImp(StateBase newImp) {} -} - -public class StateDemo { - static void test(StateBase b) { - b.f(); - b.g(); - b.h(); - } - public static void main(String[] args) { - StateBase b = - new State(new Implementation1()); - test(b); - b.changeImp(new Implementation2()); - test(b); - } -} -/* Output: -Implementation1.f() -Implementation1.g() -Implementation1.h() -Implementation2.f() -Implementation2.g() -Implementation2.h() -*/ diff --git a/code/patterns/TemplateMethod.java b/code/patterns/TemplateMethod.java deleted file mode 100644 index eff6d279..00000000 --- a/code/patterns/TemplateMethod.java +++ /dev/null @@ -1,44 +0,0 @@ -// patterns/TemplateMethod.java -// (c)2020 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. -// Simple demonstration of Template Method -import java.util.stream.*; - -abstract class ApplicationFramework { - ApplicationFramework() { - templateMethod(); - } - abstract void customize1(); - abstract void customize2(); - // "private" means automatically "final": - private void templateMethod() { - IntStream.range(0, 5).forEach( - n -> { customize1(); customize2(); }); - } -} - -// Create a new "application": -class MyApp extends ApplicationFramework { - @Override - void customize1() { - System.out.print("Hello "); - } - @Override - void customize2() { - System.out.println("World!"); - } -} - -public class TemplateMethod { - public static void main(String[] args) { - new MyApp(); - } -} -/* Output: -Hello World! -Hello World! -Hello World! -Hello World! -Hello World! -*/ diff --git a/code/patterns/abstractfactory/GameEnvironment.java b/code/patterns/abstractfactory/GameEnvironment.java deleted file mode 100644 index 8c0abf7b..00000000 --- a/code/patterns/abstractfactory/GameEnvironment.java +++ /dev/null @@ -1,96 +0,0 @@ -// patterns/abstractfactory/GameEnvironment.java -// (c)2020 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. -// An example of the Abstract Factory pattern -// {java patterns.abstractfactory.GameEnvironment} -package patterns.abstractfactory; -import java.util.function.*; - -interface Obstacle { - void action(); -} - -interface Player { - void interactWith(Obstacle o); -} - -class Kitty implements Player { - @Override - public void interactWith(Obstacle ob) { - System.out.print("Kitty has encountered a "); - ob.action(); - } -} - -class KungFuGuy implements Player { - @Override - public void interactWith(Obstacle ob) { - System.out.print("KungFuGuy now battles a "); - ob.action(); - } -} - -class Puzzle implements Obstacle { - @Override - public void action() { - System.out.println("Puzzle"); - } -} - -class NastyWeapon implements Obstacle { - @Override - public void action() { - System.out.println("NastyWeapon"); - } -} - -// The Abstract Factory: -class GameElementFactory { - Supplier player; - Supplier obstacle; -} - -// Concrete factories: -class KittiesAndPuzzles -extends GameElementFactory { - KittiesAndPuzzles() { - player = Kitty::new; - obstacle = Puzzle::new; - } -} - -class KillAndDismember -extends GameElementFactory { - KillAndDismember() { - player = KungFuGuy::new; - obstacle = NastyWeapon::new; - } -} - -public class GameEnvironment { - private Player p; - private Obstacle ob; - public - GameEnvironment(GameElementFactory factory) { - p = factory.player.get(); - ob = factory.obstacle.get(); - } - public void play() { - p.interactWith(ob); - } - public static void main(String[] args) { - GameElementFactory - kp = new KittiesAndPuzzles(), - kd = new KillAndDismember(); - GameEnvironment - g1 = new GameEnvironment(kp), - g2 = new GameEnvironment(kd); - g1.play(); - g2.play(); - } -} -/* Output: -Kitty has encountered a Puzzle -KungFuGuy now battles a NastyWeapon -*/ diff --git a/code/patterns/adapt/Adapter.java b/code/patterns/adapt/Adapter.java deleted file mode 100644 index 5bfcd6bf..00000000 --- a/code/patterns/adapt/Adapter.java +++ /dev/null @@ -1,85 +0,0 @@ -// patterns/adapt/Adapter.java -// (c)2020 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. -// Variations on the Adapter pattern -// {java patterns.adapt.Adapter} -package patterns.adapt; - -class WhatIHave { - public void g() {} - public void h() {} -} - -interface WhatIWant { - void f(); -} - -class ProxyAdapter implements WhatIWant { - WhatIHave whatIHave; - ProxyAdapter(WhatIHave wih) { - whatIHave = wih; - } - @Override - public void f() { - // Implement behavior using - // methods in WhatIHave: - whatIHave.g(); - whatIHave.h(); - } -} - -class WhatIUse { - public void op(WhatIWant wiw) { - wiw.f(); - } -} - -// Approach 2: build adapter use into op(): -class WhatIUse2 extends WhatIUse { - public void op(WhatIHave wih) { - new ProxyAdapter(wih).f(); - } -} - -// Approach 3: build adapter into WhatIHave: -class WhatIHave2 extends WhatIHave -implements WhatIWant { - @Override - public void f() { - g(); - h(); - } -} - -// Approach 4: use an inner class: -class WhatIHave3 extends WhatIHave { - private class InnerAdapter implements WhatIWant{ - @Override - public void f() { - g(); - h(); - } - } - public WhatIWant whatIWant() { - return new InnerAdapter(); - } -} - -public class Adapter { - public static void main(String[] args) { - WhatIUse whatIUse = new WhatIUse(); - WhatIHave whatIHave = new WhatIHave(); - WhatIWant adapt= new ProxyAdapter(whatIHave); - whatIUse.op(adapt); - // Approach 2: - WhatIUse2 whatIUse2 = new WhatIUse2(); - whatIUse2.op(whatIHave); - // Approach 3: - WhatIHave2 whatIHave2 = new WhatIHave2(); - whatIUse.op(whatIHave2); - // Approach 4: - WhatIHave3 whatIHave3 = new WhatIHave3(); - whatIUse.op(whatIHave3.whatIWant()); - } -} diff --git a/code/patterns/chain/ChainOfResponsibility.java b/code/patterns/chain/ChainOfResponsibility.java deleted file mode 100644 index b733e71c..00000000 --- a/code/patterns/chain/ChainOfResponsibility.java +++ /dev/null @@ -1,90 +0,0 @@ -// patterns/chain/ChainOfResponsibility.java -// (c)2020 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. -// Using the Functional interface -// {java patterns.chain.ChainOfResponsibility} -package patterns.chain; -import java.util.*; -import java.util.function.*; - -class Result { - boolean success; - List line; - Result(List data) { - success = true; - line = data; - } - Result() { - success = false; - line = Collections.emptyList(); - } -} - -class Fail extends Result {} - -interface Algorithm { - Result algorithm(List line); -} - -class FindMinima { - public static Result leastSquares(List line) { - System.out.println("LeastSquares.algorithm"); - boolean weSucceed = false; - if(weSucceed) // Actual test/calculation here - return new Result(Arrays.asList(1.1, 2.2)); - else // Try the next one in the chain: - return new Fail(); - } - public static Result perturbation(List line) { - System.out.println("Perturbation.algorithm"); - boolean weSucceed = false; - if(weSucceed) // Actual test/calculation here - return new Result(Arrays.asList(3.3, 4.4)); - else - return new Fail(); - } - public static Result bisection(List line) { - System.out.println("Bisection.algorithm"); - boolean weSucceed = true; - if(weSucceed) // Actual test/calculation here - return new Result(Arrays.asList(5.5, 6.6)); - else - return new Fail(); - } - static List, Result>> - algorithms = Arrays.asList( - FindMinima::leastSquares, - FindMinima::perturbation, - FindMinima::bisection - ); - public static Result minima(List line) { - for(Function, Result> alg : - algorithms) { - Result result = alg.apply(line); - if(result.success) - return result; - } - return new Fail(); - } -} - -public class ChainOfResponsibility { - public static void main(String[] args) { - FindMinima solver = new FindMinima(); - List line = Arrays.asList( - 1.0, 2.0, 1.0, 2.0, -1.0, - 3.0, 4.0, 5.0, 4.0); - Result result = solver.minima(line); - if(result.success) - System.out.println(result.line); - else - System.out.println("No algorithm found"); - } -} -/* Output: -LeastSquares.algorithm -Perturbation.algorithm -Bisection.algorithm -[5.5, 6.6] -*/ diff --git a/code/patterns/doubledispatch/Aluminum.java b/code/patterns/doubledispatch/Aluminum.java deleted file mode 100644 index 5037fac5..00000000 --- a/code/patterns/doubledispatch/Aluminum.java +++ /dev/null @@ -1,18 +0,0 @@ -// patterns/doubledispatch/Aluminum.java -// (c)2020 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. -// Aluminum for double dispatching -package patterns.doubledispatch; -import patterns.trash.*; -import java.util.*; - -public class Aluminum extends patterns.trash.Aluminum - implements TypedBinMember { - public Aluminum(double wt) { super(wt); } - @Override - public boolean addToBin(List tbins) { - return tbins.stream() - .anyMatch(tb -> tb.add(this)); - } -} diff --git a/code/patterns/doubledispatch/Cardboard.java b/code/patterns/doubledispatch/Cardboard.java deleted file mode 100644 index 5046ddaa..00000000 --- a/code/patterns/doubledispatch/Cardboard.java +++ /dev/null @@ -1,18 +0,0 @@ -// patterns/doubledispatch/Cardboard.java -// (c)2020 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. -// Cardboard for double dispatching -package patterns.doubledispatch; -import patterns.trash.*; -import java.util.*; - -public class Cardboard extends patterns.trash.Cardboard - implements TypedBinMember { - public Cardboard(double wt) { super(wt); } - @Override - public boolean addToBin(List tbins) { - return tbins.stream() - .anyMatch(tb -> tb.add(this)); - } -} diff --git a/code/patterns/doubledispatch/DoubleDispatch.java b/code/patterns/doubledispatch/DoubleDispatch.java deleted file mode 100644 index 91bee562..00000000 --- a/code/patterns/doubledispatch/DoubleDispatch.java +++ /dev/null @@ -1,96 +0,0 @@ -// patterns/doubledispatch/DoubleDispatch.java -// (c)2020 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. -// Using multiple dispatching to handle more -// than one unknown type during a method call -// {java patterns.doubledispatch.DoubleDispatch} -package patterns.doubledispatch; -import patterns.trash.*; -import java.util.*; - -class AluminumBin extends TypedBin { - @Override - public boolean add(Aluminum a) { - return addIt(a); - } -} - -class PaperBin extends TypedBin { - @Override - public boolean add(Paper a) { - return addIt(a); - } -} - -class GlassBin extends TypedBin { - @Override - public boolean add(Glass a) { - return addIt(a); - } -} - -class CardboardBin extends TypedBin { - @Override - public boolean add(Cardboard a) { - return addIt(a); - } -} - -class TrashBinSet { - private List binSet = Arrays.asList( - new AluminumBin(), - new PaperBin(), - new GlassBin(), - new CardboardBin() - ); - @SuppressWarnings("unchecked") - public void sortIntoBins(List bin) { - bin.forEach( aBin -> { - TypedBinMember t = (TypedBinMember)aBin; - if(!t.addToBin(binSet)) - System.err.println("Couldn't add " + t); - }); - } - public List binSet() { return binSet; } -} - -public class DoubleDispatch { - public static void main(String[] args) { - List bin = new ArrayList<>(); - TrashBinSet bins = new TrashBinSet(); - // ParseTrash still works, without changes: - ParseTrash.fillBin("doubledispatch", bin); - // Sort from the master bin into the - // individually-typed bins: - bins.sortIntoBins(bin); - // Perform sumValue for each bin... - bins.binSet() - .forEach(tb -> Trash.sumValue(tb.v)); - // ... and for the master bin - Trash.sumValue(bin); - } -} -/* Output: (First and Last 10 Lines) -Loading patterns.doubledispatch.Glass -Loading patterns.doubledispatch.Paper -Loading patterns.doubledispatch.Aluminum -Loading patterns.doubledispatch.Cardboard -weight of patterns.doubledispatch.Aluminum = 89.0 -weight of patterns.doubledispatch.Aluminum = 76.0 -weight of patterns.doubledispatch.Aluminum = 25.0 -weight of patterns.doubledispatch.Aluminum = 34.0 -weight of patterns.doubledispatch.Aluminum = 27.0 -weight of patterns.doubledispatch.Aluminum = 18.0 -...________...________...________...________... -weight of patterns.doubledispatch.Aluminum = 93.0 -weight of patterns.doubledispatch.Glass = 93.0 -weight of patterns.doubledispatch.Paper = 80.0 -weight of patterns.doubledispatch.Glass = 36.0 -weight of patterns.doubledispatch.Glass = 12.0 -weight of patterns.doubledispatch.Glass = 60.0 -weight of patterns.doubledispatch.Paper = 66.0 -weight of patterns.doubledispatch.Aluminum = 36.0 -weight of patterns.doubledispatch.Cardboard = 22.0 -Total value = 1086.0599818825722 -*/ diff --git a/code/patterns/doubledispatch/Glass.java b/code/patterns/doubledispatch/Glass.java deleted file mode 100644 index 79cf7fa2..00000000 --- a/code/patterns/doubledispatch/Glass.java +++ /dev/null @@ -1,18 +0,0 @@ -// patterns/doubledispatch/Glass.java -// (c)2020 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. -// Glass for double dispatching -package patterns.doubledispatch; -import patterns.trash.*; -import java.util.*; - -public class Glass extends patterns.trash.Glass - implements TypedBinMember { - public Glass(double wt) { super(wt); } - @Override - public boolean addToBin(List tbins) { - return tbins.stream() - .anyMatch(tb -> tb.add(this)); - } -} diff --git a/code/patterns/doubledispatch/Paper.java b/code/patterns/doubledispatch/Paper.java deleted file mode 100644 index b542dfd6..00000000 --- a/code/patterns/doubledispatch/Paper.java +++ /dev/null @@ -1,18 +0,0 @@ -// patterns/doubledispatch/Paper.java -// (c)2020 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. -// Paper for double dispatching -package patterns.doubledispatch; -import patterns.trash.*; -import java.util.*; - -public class Paper extends patterns.trash.Paper - implements TypedBinMember { - public Paper(double wt) { super(wt); } - @Override - public boolean addToBin(List tbins) { - return tbins.stream() - .anyMatch(tb -> tb.add(this)); - } -} diff --git a/code/patterns/doubledispatch/TypedBin.java b/code/patterns/doubledispatch/TypedBin.java deleted file mode 100644 index 265874cc..00000000 --- a/code/patterns/doubledispatch/TypedBin.java +++ /dev/null @@ -1,28 +0,0 @@ -// patterns/doubledispatch/TypedBin.java -// (c)2020 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. -// A List that can grab the right type -package patterns.doubledispatch; -import patterns.trash.*; -import java.util.*; - -public class TypedBin { - List v = new ArrayList<>(); - protected boolean addIt(Trash t) { - v.add(t); - return true; - } - public boolean add(Aluminum a) { - return false; - } - public boolean add(Paper a) { - return false; - } - public boolean add(Glass a) { - return false; - } - public boolean add(Cardboard a) { - return false; - } -} diff --git a/code/patterns/doubledispatch/TypedBinMember.java b/code/patterns/doubledispatch/TypedBinMember.java deleted file mode 100644 index c7ce960a..00000000 --- a/code/patterns/doubledispatch/TypedBinMember.java +++ /dev/null @@ -1,14 +0,0 @@ -// patterns/doubledispatch/TypedBinMember.java -// (c)2020 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. -// An interface for adding the double dispatching -// method to the trash hierarchy without -// modifying the original hierarchy -package patterns.doubledispatch; -import java.util.*; - -public interface TypedBinMember { - // The new method: - boolean addToBin(List bins); -} diff --git a/code/patterns/dynatrash/DynaTrash.java b/code/patterns/dynatrash/DynaTrash.java deleted file mode 100644 index 6ce33d8f..00000000 --- a/code/patterns/dynatrash/DynaTrash.java +++ /dev/null @@ -1,74 +0,0 @@ -// patterns/dynatrash/DynaTrash.java -// (c)2020 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. -// Using a Map of Lists and RTTI to automatically -// sort trash into Lists. This solution, despite -// the use of RTTI, is extensible. -// {java patterns.dynatrash.DynaTrash} -package patterns.dynatrash; -import patterns.trash.*; -import java.util.*; -import java.util.stream.*; - -// Generic TypeMap works in any situation: -class TypeMap { - private Map> t = new HashMap<>(); - public void add(T o) { - Class type = o.getClass(); - if(t.containsKey(type)) - t.get(type).add(o); - else { - List v = new ArrayList<>(); - v.add(o); - t.put(type,v); - } - } - public Stream> values() { - return t.values().stream(); - } -} - -// Adapter class for callbacks -// from ParseTrash.fillBin(): -class TypeMapAdapter implements Fillable { - TypeMap map; - TypeMapAdapter(TypeMap tm) { - map = tm; - } - @Override - public void addTrash(Trash t) { map.add(t); } -} - -public class DynaTrash { - @SuppressWarnings("unchecked") - public static void main(String[] args) { - TypeMap bin = new TypeMap<>(); - ParseTrash.fillBin( - "trash", new TypeMapAdapter(bin)); - bin.values().forEach(Trash::sumValue); - } -} -/* Output: (First and Last 10 Lines) -Loading patterns.trash.Glass -Loading patterns.trash.Paper -Loading patterns.trash.Aluminum -Loading patterns.trash.Cardboard -weight of patterns.trash.Paper = 22.0 -weight of patterns.trash.Paper = 11.0 -weight of patterns.trash.Paper = 88.0 -weight of patterns.trash.Paper = 91.0 -weight of patterns.trash.Paper = 80.0 -weight of patterns.trash.Paper = 66.0 -...________...________...________...________... -weight of patterns.trash.Aluminum = 81.0 -weight of patterns.trash.Aluminum = 36.0 -weight of patterns.trash.Aluminum = 93.0 -weight of patterns.trash.Aluminum = 36.0 -Total value = 860.0499778985977 -weight of patterns.trash.Cardboard = 96.0 -weight of patterns.trash.Cardboard = 44.0 -weight of patterns.trash.Cardboard = 12.0 -weight of patterns.trash.Cardboard = 22.0 -Total value = 40.02000072598457 -*/ diff --git a/code/patterns/observer/ObservedFlower.java b/code/patterns/observer/ObservedFlower.java deleted file mode 100644 index 009da63e..00000000 --- a/code/patterns/observer/ObservedFlower.java +++ /dev/null @@ -1,125 +0,0 @@ -// patterns/observer/ObservedFlower.java -// (c)2020 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. -// Demonstration of "Observer" pattern -// {java patterns.observer.ObservedFlower} -package patterns.observer; -import java.util.*; - -@SuppressWarnings("deprecation") -class Flower { - private boolean isOpen; - private boolean alreadyOpen; - private boolean alreadyClosed; - Flower() { isOpen = false; } - OpenNotifier opening = new OpenNotifier(); - CloseNotifier closing = new CloseNotifier(); - public void open() { // Opens its petals - isOpen = true; - opening.notifyObservers(); - alreadyClosed = false; - } - public void close() { // Closes its petals - isOpen = false; - closing.notifyObservers(); - alreadyOpen = false; - } - class OpenNotifier extends Observable { - @Override - public void notifyObservers() { - if(isOpen && !alreadyOpen) { - setChanged(); - super.notifyObservers(); - alreadyOpen = true; - } - } - } - class CloseNotifier extends Observable{ - @Override - public void notifyObservers() { - if(!isOpen && !alreadyClosed) { - setChanged(); - super.notifyObservers(); - alreadyClosed = true; - } - } - } -} - -@SuppressWarnings("deprecation") -class Bee { - private String name; - Bee(String nm) { name = nm; } - // Observe openings: - public Observer openObserver() { - return (ob, a) -> System.out.println( - "Bee " + name + "'s breakfast time!"); - } - // Observe closings: - public Observer closeObserver() { - return (ob, a) -> System.out.println( - "Bee " + name + "'s bed time!"); - } -} - -@SuppressWarnings("deprecation") -class Hummingbird { - private String name; - Hummingbird(String nm) { name = nm; } - public Observer openObserver() { - return (ob, a) -> System.out.println( - "Hummingbird " + name + - "'s breakfast time!"); - } - public Observer closeObserver() { - return (ob, a) -> System.out.println( - "Hummingbird " + name + "'s bed time!"); - } -} - -public class ObservedFlower { - public static void main(String[] args) { - Flower f = new Flower(); - Bee - ba = new Bee("A"), - bb = new Bee("B"); - Hummingbird - ha = new Hummingbird("A"), - hb = new Hummingbird("B"); - f.opening.addObserver(ha.openObserver()); - f.opening.addObserver(hb.openObserver()); - f.opening.addObserver(ba.openObserver()); - f.opening.addObserver(bb.openObserver()); - f.closing.addObserver(ha.closeObserver()); - f.closing.addObserver(hb.closeObserver()); - f.closing.addObserver(ba.closeObserver()); - f.closing.addObserver(bb.closeObserver()); - // Hummingbird B decides to sleep in: - f.opening.deleteObserver(hb.openObserver()); - // A change that interests observers: - f.open(); - f.open(); // It's already open, no change. - // Bee A doesn't want to go to bed: - f.closing.deleteObserver(ba.closeObserver()); - f.close(); - f.close(); // It's already closed; no change - f.opening.deleteObservers(); - f.open(); - f.close(); - } -} -/* Output: -Bee B's breakfast time! -Bee A's breakfast time! -Hummingbird B's breakfast time! -Hummingbird A's breakfast time! -Bee B's bed time! -Bee A's bed time! -Hummingbird B's bed time! -Hummingbird A's bed time! -Bee B's bed time! -Bee A's bed time! -Hummingbird B's bed time! -Hummingbird A's bed time! -*/ diff --git a/code/patterns/recyclea/RecycleA.java b/code/patterns/recyclea/RecycleA.java deleted file mode 100644 index a73f39e7..00000000 --- a/code/patterns/recyclea/RecycleA.java +++ /dev/null @@ -1,127 +0,0 @@ -// patterns/recyclea/RecycleA.java -// (c)2020 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. -// Recycling with RTTI -// {java patterns.recyclea.RecycleA} -package patterns.recyclea; -import java.util.*; -import java.util.function.*; -import java.util.stream.*; - -abstract class Trash { - double weight; - Trash(double wt) { weight = wt; } - abstract double value(); - // Sums the value of Trash in a bin: - private static double val; - static void sumValue(List bin) { - val = 0.0f; - bin.forEach( t -> { - // Polymorphism in action: - val += t.weight * t.value(); - System.out.println( - "weight of " + - // Using RTTI to get type - // information about the class: - t.getClass().getSimpleName() + - " = " + t.weight); - }); - System.out.println("Total value = " + val); - } -} - -class Aluminum extends Trash { - static double val = 1.67f; - Aluminum(double wt) { super(wt); } - @Override - double value() { return val; } - static void value(double newval) { - val = newval; - } -} - -class Paper extends Trash { - static double val = 0.10f; - Paper(double wt) { super(wt); } - @Override - double value() { return val; } - static void value(double newval) { - val = newval; - } -} - -class Glass extends Trash { - static double val = 0.23f; - Glass(double wt) { super(wt); } - @Override - double value() { return val; } - static void value(double newval) { - val = newval; - } -} - -class TrashFactory { - static List> ttypes = - Arrays.asList( - Aluminum::new, Paper::new, Glass::new); - static final int SZ = ttypes.size(); - private static SplittableRandom rand = - new SplittableRandom(47); - public static Trash newTrash() { - return ttypes - .get(rand.nextInt(SZ)) - .apply(rand.nextDouble()); - } -} - -public class RecycleA { - public static void main(String[] args) { - List bin = - Stream.generate(TrashFactory::newTrash) - .limit(25) - .collect(Collectors.toList()); - List glassBin = new ArrayList<>(); - List paperBin = new ArrayList<>(); - List alBin = new ArrayList<>(); - // Sort the Trash: - bin.forEach( t -> { - // RTTI to discover Trash type: - if(t instanceof Aluminum) - alBin.add((Aluminum)t); - if(t instanceof Paper) - paperBin.add((Paper)t); - if(t instanceof Glass) - glassBin.add((Glass)t); - }); - Trash.sumValue(alBin); - Trash.sumValue(paperBin); - Trash.sumValue(glassBin); - Trash.sumValue(bin); - } -} -/* Output: (First and Last 11 Lines) -weight of Aluminum = 0.2893030122276371 -weight of Aluminum = 0.1970234961398979 -weight of Aluminum = 0.36295525806274787 -weight of Aluminum = 0.4825532324565849 -weight of Aluminum = 0.8036398273294586 -weight of Aluminum = 0.510430896154935 -weight of Aluminum = 0.6703377164093444 -weight of Aluminum = 0.41477933066243455 -weight of Aluminum = 0.3603022312124007 -weight of Aluminum = 0.43690089841661006 -weight of Aluminum = 0.6708820087907101 -...________...________...________...________... -weight of Aluminum = 0.41477933066243455 -weight of Aluminum = 0.3603022312124007 -weight of Aluminum = 0.43690089841661006 -weight of Glass = 0.5999637765664924 -weight of Glass = 0.7748836191212746 -weight of Paper = 0.5735994548427199 -weight of Glass = 0.5362827750851034 -weight of Aluminum = 0.6708820087907101 -weight of Paper = 0.8370669795210507 -weight of Glass = 0.3397919679731668 -Total value = 9.90671597531968 -*/ diff --git a/code/patterns/recycleb/RecycleB.java b/code/patterns/recycleb/RecycleB.java deleted file mode 100644 index 1ca38314..00000000 --- a/code/patterns/recycleb/RecycleB.java +++ /dev/null @@ -1,56 +0,0 @@ -// patterns/recycleb/RecycleB.java -// (c)2020 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. -// {java patterns.recycleb.RecycleB} -package patterns.recycleb; -import patterns.trash.*; -import java.util.*; - -public class RecycleB { - public static void main(String[] args) { - List bin = new ArrayList<>(); - // Fill up the Trash bin: - ParseTrash.fillBin("trash", bin); - List glassBin = new ArrayList<>(); - List paperBin = new ArrayList<>(); - List alBin = new ArrayList<>(); - // Sort the Trash: - bin.forEach( t -> { - // RTTI to discover Trash type: - if(t instanceof Aluminum) - alBin.add((Aluminum)t); - if(t instanceof Paper) - paperBin.add((Paper)t); - if(t instanceof Glass) - glassBin.add((Glass)t); - }); - Trash.sumValue(alBin); - Trash.sumValue(paperBin); - Trash.sumValue(glassBin); - Trash.sumValue(bin); - } -} -/* Output: (First and Last 10 Lines) -Loading patterns.trash.Glass -Loading patterns.trash.Paper -Loading patterns.trash.Aluminum -Loading patterns.trash.Cardboard -weight of patterns.trash.Aluminum = 89.0 -weight of patterns.trash.Aluminum = 76.0 -weight of patterns.trash.Aluminum = 25.0 -weight of patterns.trash.Aluminum = 34.0 -weight of patterns.trash.Aluminum = 27.0 -weight of patterns.trash.Aluminum = 18.0 -...________...________...________...________... -weight of patterns.trash.Aluminum = 93.0 -weight of patterns.trash.Glass = 93.0 -weight of patterns.trash.Paper = 80.0 -weight of patterns.trash.Glass = 36.0 -weight of patterns.trash.Glass = 12.0 -weight of patterns.trash.Glass = 60.0 -weight of patterns.trash.Paper = 66.0 -weight of patterns.trash.Aluminum = 36.0 -weight of patterns.trash.Cardboard = 22.0 -Total value = 1086.0599818825722 -*/ diff --git a/code/patterns/recyclec/RecycleC.java b/code/patterns/recyclec/RecycleC.java deleted file mode 100644 index 239e8e79..00000000 --- a/code/patterns/recyclec/RecycleC.java +++ /dev/null @@ -1,84 +0,0 @@ -// patterns/recyclec/RecycleC.java -// (c)2020 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. -// Adding more objects to the recycling problem -// {java patterns.recyclec.RecycleC} -package patterns.recyclec; -import patterns.trash.*; -import java.util.*; - -// A List that admits only the right type: -class Tbin extends ArrayList { - Class binType; - Tbin(Class type) { - binType = type; - } - @SuppressWarnings("unchecked") - boolean grab(Trash t) { - // Comparing class types: - if(t.getClass().equals(binType)) { - add((T)t); // Downcast to this TBin's type - return true; // Object grabbed - } - return false; // Object not grabbed - } -} - -class TbinList -extends ArrayList> { // [1] - boolean sort(T t) { - for(Tbin ts : this) - if(ts.grab(t)) - return true; - return false; // bin not found for t - } - void sortBin(Tbin bin) { // [2] - for(T aBin : bin) - if(!sort(aBin)) - System.err.println("Bin not found"); - } -} - -public class RecycleC { - static Tbin bin = new Tbin<>(Trash.class); - public static void main(String[] args) { - // Fill up the Trash bin: - ParseTrash.fillBin("trash", bin); - - TbinList trashBins = new TbinList<>(); - trashBins.add(new Tbin<>(Aluminum.class)); - trashBins.add(new Tbin<>(Paper.class)); - trashBins.add(new Tbin<>(Glass.class)); - // add one line here: [*3*] - trashBins.add(new Tbin<>(Cardboard.class)); - - trashBins.sortBin(bin); // [4] - - trashBins.forEach(Trash::sumValue); - Trash.sumValue(bin); - } -} -/* Output: (First and Last 10 Lines) -Loading patterns.trash.Glass -Loading patterns.trash.Paper -Loading patterns.trash.Aluminum -Loading patterns.trash.Cardboard -weight of patterns.trash.Aluminum = 89.0 -weight of patterns.trash.Aluminum = 76.0 -weight of patterns.trash.Aluminum = 25.0 -weight of patterns.trash.Aluminum = 34.0 -weight of patterns.trash.Aluminum = 27.0 -weight of patterns.trash.Aluminum = 18.0 -...________...________...________...________... -weight of patterns.trash.Aluminum = 93.0 -weight of patterns.trash.Glass = 93.0 -weight of patterns.trash.Paper = 80.0 -weight of patterns.trash.Glass = 36.0 -weight of patterns.trash.Glass = 12.0 -weight of patterns.trash.Glass = 60.0 -weight of patterns.trash.Paper = 66.0 -weight of patterns.trash.Aluminum = 36.0 -weight of patterns.trash.Cardboard = 22.0 -Total value = 1086.0599818825722 -*/ diff --git a/code/patterns/shapes/BadShapeCreation.java b/code/patterns/shapes/BadShapeCreation.java deleted file mode 100644 index 2ebda8e5..00000000 --- a/code/patterns/shapes/BadShapeCreation.java +++ /dev/null @@ -1,12 +0,0 @@ -// patterns/shapes/BadShapeCreation.java -// (c)2020 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 class BadShapeCreation -extends RuntimeException { - public BadShapeCreation(String msg) { - super(msg); - } -} diff --git a/code/patterns/shapes/Circle.java b/code/patterns/shapes/Circle.java deleted file mode 100644 index 461d55e2..00000000 --- a/code/patterns/shapes/Circle.java +++ /dev/null @@ -1,7 +0,0 @@ -// patterns/shapes/Circle.java -// (c)2020 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 class Circle extends Shape {} diff --git a/code/patterns/shapes/FactoryMethod.java b/code/patterns/shapes/FactoryMethod.java deleted file mode 100644 index c3b22b1f..00000000 --- a/code/patterns/shapes/FactoryMethod.java +++ /dev/null @@ -1,9 +0,0 @@ -// patterns/shapes/FactoryMethod.java -// (c)2020 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/code/patterns/shapes/FactoryTest.java b/code/patterns/shapes/FactoryTest.java deleted file mode 100644 index 301bb1ab..00000000 --- a/code/patterns/shapes/FactoryTest.java +++ /dev/null @@ -1,17 +0,0 @@ -// patterns/shapes/FactoryTest.java -// (c)2020 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/code/patterns/shapes/Shape.java b/code/patterns/shapes/Shape.java deleted file mode 100644 index 12fdf3e7..00000000 --- a/code/patterns/shapes/Shape.java +++ /dev/null @@ -1,21 +0,0 @@ -// patterns/shapes/Shape.java -// (c)2020 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 class Shape { - private static int counter = 0; - private int id = counter++; - @Override - public String toString() { - return - getClass().getSimpleName() + "[" + id + "]"; - } - public void draw() { - System.out.println(this + " draw"); - } - public void erase() { - System.out.println(this + " erase"); - } -} diff --git a/code/patterns/shapes/Square.java b/code/patterns/shapes/Square.java deleted file mode 100644 index 610dd3e4..00000000 --- a/code/patterns/shapes/Square.java +++ /dev/null @@ -1,7 +0,0 @@ -// patterns/shapes/Square.java -// (c)2020 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 class Square extends Shape {} diff --git a/code/patterns/shapes/Triangle.java b/code/patterns/shapes/Triangle.java deleted file mode 100644 index 9fed3d93..00000000 --- a/code/patterns/shapes/Triangle.java +++ /dev/null @@ -1,7 +0,0 @@ -// patterns/shapes/Triangle.java -// (c)2020 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 class Triangle extends Shape {} diff --git a/code/patterns/state/StateMachineDemo.java b/code/patterns/state/StateMachineDemo.java deleted file mode 100644 index 29f8a876..00000000 --- a/code/patterns/state/StateMachineDemo.java +++ /dev/null @@ -1,80 +0,0 @@ -// patterns/state/StateMachineDemo.java -// (c)2020 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. -// The StateMachine pattern and Template method -// {java patterns.state.StateMachineDemo} -package patterns.state; -import onjava.Nap; - -interface State { - void run(); -} - -abstract class StateMachine { - protected State currentState; - protected abstract boolean changeState(); - // Template method: - protected final void runAll() { - while(changeState()) // Customizable - currentState.run(); - } -} - -// A different subclass for each state: - -class Wash implements State { - @Override - public void run() { - System.out.println("Washing"); - new Nap(0.5); - } -} - -class Spin implements State { - @Override - public void run() { - System.out.println("Spinning"); - new Nap(0.5); - } -} - -class Rinse implements State { - @Override - public void run() { - System.out.println("Rinsing"); - new Nap(0.5); - } -} - -class Washer extends StateMachine { - private int i = 0; - // The state table: - private State[] states = { - new Wash(), new Spin(), - new Rinse(), new Spin(), - }; - Washer() { runAll(); } - @Override - public boolean changeState() { - if(i < states.length) { - // Change the state by setting the - // surrogate reference to a new object: - currentState = states[i++]; - return true; - } else - return false; - } -} - -public class StateMachineDemo { - public static void main(String[] args) { - new Washer(); - } -} -/* Output: -Washing -Spinning -Rinsing -Spinning -*/ diff --git a/code/patterns/strategy/StrategyPattern.java b/code/patterns/strategy/StrategyPattern.java deleted file mode 100644 index 52561b4b..00000000 --- a/code/patterns/strategy/StrategyPattern.java +++ /dev/null @@ -1,64 +0,0 @@ -// patterns/strategy/StrategyPattern.java -// (c)2020 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. -// {java patterns.strategy.StrategyPattern} -package patterns.strategy; -import java.util.function.*; -import java.util.*; - -// The common strategy base type: -class FindMinima { - Function, List> algorithm; -} - -// The various strategies: -class LeastSquares extends FindMinima { - LeastSquares() { - // Line is a sequence of points (Dummy data): - algorithm = (line) -> Arrays.asList(1.1, 2.2); - } -} - -class Perturbation extends FindMinima { - Perturbation() { - algorithm = (line) -> Arrays.asList(3.3, 4.4); - } -} - -class Bisection extends FindMinima { - Bisection() { - algorithm = (line) -> Arrays.asList(5.5, 6.6); - } -} - -// The "Context" controls the strategy: -class MinimaSolver { - private FindMinima strategy; - MinimaSolver(FindMinima strat) { - strategy = strat; - } - List minima(List line) { - return strategy.algorithm.apply(line); - } - void changeAlgorithm(FindMinima newAlgorithm) { - strategy = newAlgorithm; - } -} - -public class StrategyPattern { - public static void main(String[] args) { - MinimaSolver solver = - new MinimaSolver(new LeastSquares()); - List line = Arrays.asList( - 1.0, 2.0, 1.0, 2.0, -1.0, - 3.0, 4.0, 5.0, 4.0 ); - System.out.println(solver.minima(line)); - solver.changeAlgorithm(new Bisection()); - System.out.println(solver.minima(line)); - } -} -/* Output: -[1.1, 2.2] -[5.5, 6.6] -*/ diff --git a/code/patterns/strategy/StrategyPattern2.java b/code/patterns/strategy/StrategyPattern2.java deleted file mode 100644 index 09465f3a..00000000 --- a/code/patterns/strategy/StrategyPattern2.java +++ /dev/null @@ -1,43 +0,0 @@ -// patterns/strategy/StrategyPattern2.java -// (c)2020 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. -// {java patterns.strategy.StrategyPattern2} -package patterns.strategy; -import java.util.function.*; -import java.util.*; - -// "Context" is now incorporated: -class FindMinima2 { - Function, List> algorithm; - FindMinima2() { leastSquares(); } // default - // The various strategies: - void leastSquares() { - algorithm = (line) -> Arrays.asList(1.1, 2.2); - } - void perturbation() { - algorithm = (line) -> Arrays.asList(3.3, 4.4); - } - void bisection() { - algorithm = (line) -> Arrays.asList(5.5, 6.6); - } - List minima(List line) { - return algorithm.apply(line); - } -} - -public class StrategyPattern2 { - public static void main(String[] args) { - FindMinima2 solver = new FindMinima2(); - List line = Arrays.asList( - 1.0, 2.0, 1.0, 2.0, -1.0, - 3.0, 4.0, 5.0, 4.0 ); - System.out.println(solver.minima(line)); - solver.bisection(); - System.out.println(solver.minima(line)); - } -} -/* Output: -[1.1, 2.2] -[5.5, 6.6] -*/ diff --git a/code/patterns/trash/Aluminum.java b/code/patterns/trash/Aluminum.java deleted file mode 100644 index 0065e964..00000000 --- a/code/patterns/trash/Aluminum.java +++ /dev/null @@ -1,15 +0,0 @@ -// patterns/trash/Aluminum.java -// (c)2020 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.trash; - -public class Aluminum extends Trash { - private static double val = 1.67f; - public Aluminum(double wt) { super(wt); } - @Override - public double value() { return val; } - public static void value(double newVal) { - val = newVal; - } -} diff --git a/code/patterns/trash/Cardboard.java b/code/patterns/trash/Cardboard.java deleted file mode 100644 index 0b54d135..00000000 --- a/code/patterns/trash/Cardboard.java +++ /dev/null @@ -1,15 +0,0 @@ -// patterns/trash/Cardboard.java -// (c)2020 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.trash; - -public class Cardboard extends Trash { - private static double val = 0.23f; - public Cardboard(double wt) { super(wt); } - @Override - public double value() { return val; } - public static void value(double newVal) { - val = newVal; - } -} diff --git a/code/patterns/trash/Fillable.java b/code/patterns/trash/Fillable.java deleted file mode 100644 index a61cb111..00000000 --- a/code/patterns/trash/Fillable.java +++ /dev/null @@ -1,10 +0,0 @@ -// patterns/trash/Fillable.java -// (c)2020 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. -// Any object that can be filled with Trash -package patterns.trash; - -public interface Fillable { - void addTrash(T t); -} diff --git a/code/patterns/trash/FillableList.java b/code/patterns/trash/FillableList.java deleted file mode 100644 index 989a33ec..00000000 --- a/code/patterns/trash/FillableList.java +++ /dev/null @@ -1,17 +0,0 @@ -// patterns/trash/FillableList.java -// (c)2020 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. -// Adapter that makes a List Fillable -package patterns.trash; -import java.util.*; - -public class FillableList -implements Fillable { - private List v; - public FillableList(List vv) { - v = vv; - } - @Override - public void addTrash(T t) { v.add(t); } -} diff --git a/code/patterns/trash/Glass.java b/code/patterns/trash/Glass.java deleted file mode 100644 index f7563dc4..00000000 --- a/code/patterns/trash/Glass.java +++ /dev/null @@ -1,15 +0,0 @@ -// patterns/trash/Glass.java -// (c)2020 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.trash; - -public class Glass extends Trash { - private static double val = 0.23f; - public Glass(double wt) { super(wt); } - @Override - public double value() { return val; } - public static void value(double newVal) { - val = newVal; - } -} diff --git a/code/patterns/trash/Paper.java b/code/patterns/trash/Paper.java deleted file mode 100644 index 2f0b3666..00000000 --- a/code/patterns/trash/Paper.java +++ /dev/null @@ -1,15 +0,0 @@ -// patterns/trash/Paper.java -// (c)2020 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.trash; - -public class Paper extends Trash { - private static double val = 0.10f; - public Paper(double wt) { super(wt); } - @Override - public double value() { return val; } - public static void value(double newVal) { - val = newVal; - } -} diff --git a/code/patterns/trash/ParseTrash.java b/code/patterns/trash/ParseTrash.java deleted file mode 100644 index fc0c0416..00000000 --- a/code/patterns/trash/ParseTrash.java +++ /dev/null @@ -1,91 +0,0 @@ -// patterns/trash/ParseTrash.java -// (c)2020 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. -// Open a file and parse its contents into -// Trash objects, placing each into a List -// {java patterns.trash.ParseTrash} -package patterns.trash; -import java.util.*; -import java.util.stream.*; -import java.io.*; -import java.nio.file.*; -import java.nio.file.Files; - -public class ParseTrash { - public static void - fillBin(String pckg, Fillable bin) { - try { - Files.lines(Paths.get("trash", "Trash.dat")) - // Remove empty lines and comment lines: - .filter(line -> line.trim().length() != 0) - .filter(line -> !line.startsWith("//")) - .forEach( line -> { - String type = "patterns." + pckg + "." + - line.substring( - 0, line.indexOf(':')).trim(); - double weight = Double.valueOf( - line.substring(line.indexOf(':') + 1) - .trim()); - bin.addTrash(Trash.factory( - new Trash.Info(type, weight))); - }); - } catch(IOException | - NumberFormatException | - Trash.TrashClassNotFoundException | - Trash.CannotCreateTrashException e) { - throw new RuntimeException(e); - } - } - // Special case to handle List: - public static void - fillBin(String pckg, List bin) { - fillBin(pckg, new FillableList<>(bin)); - } - // Basic test: - public static void main(String[] args) { - List t = new ArrayList<>(); - fillBin("trash", t); - t.forEach(System.out::println); - } -} -/* Output: -Loading patterns.trash.Glass -Loading patterns.trash.Paper -Loading patterns.trash.Aluminum -Loading patterns.trash.Cardboard -patterns.trash.Glass w:54.0 v:0.23 -patterns.trash.Paper w:22.0 v:0.10 -patterns.trash.Paper w:11.0 v:0.10 -patterns.trash.Glass w:17.0 v:0.23 -patterns.trash.Aluminum w:89.0 v:1.67 -patterns.trash.Paper w:88.0 v:0.10 -patterns.trash.Aluminum w:76.0 v:1.67 -patterns.trash.Cardboard w:96.0 v:0.23 -patterns.trash.Aluminum w:25.0 v:1.67 -patterns.trash.Aluminum w:34.0 v:1.67 -patterns.trash.Glass w:11.0 v:0.23 -patterns.trash.Glass w:68.0 v:0.23 -patterns.trash.Glass w:43.0 v:0.23 -patterns.trash.Aluminum w:27.0 v:1.67 -patterns.trash.Cardboard w:44.0 v:0.23 -patterns.trash.Aluminum w:18.0 v:1.67 -patterns.trash.Paper w:91.0 v:0.10 -patterns.trash.Glass w:63.0 v:0.23 -patterns.trash.Glass w:50.0 v:0.23 -patterns.trash.Glass w:80.0 v:0.23 -patterns.trash.Aluminum w:81.0 v:1.67 -patterns.trash.Cardboard w:12.0 v:0.23 -patterns.trash.Glass w:12.0 v:0.23 -patterns.trash.Glass w:54.0 v:0.23 -patterns.trash.Aluminum w:36.0 v:1.67 -patterns.trash.Aluminum w:93.0 v:1.67 -patterns.trash.Glass w:93.0 v:0.23 -patterns.trash.Paper w:80.0 v:0.10 -patterns.trash.Glass w:36.0 v:0.23 -patterns.trash.Glass w:12.0 v:0.23 -patterns.trash.Glass w:60.0 v:0.23 -patterns.trash.Paper w:66.0 v:0.10 -patterns.trash.Aluminum w:36.0 v:1.67 -patterns.trash.Cardboard w:22.0 v:0.23 -*/ diff --git a/code/patterns/trash/Trash.dat b/code/patterns/trash/Trash.dat deleted file mode 100644 index 436a7a71..00000000 --- a/code/patterns/trash/Trash.dat +++ /dev/null @@ -1,35 +0,0 @@ -// patterns/trash/Trash.dat -Glass:54 -Paper:22 -Paper:11 -Glass:17 -Aluminum:89 -Paper:88 -Aluminum:76 -Cardboard:96 -Aluminum:25 -Aluminum:34 -Glass:11 -Glass:68 -Glass:43 -Aluminum:27 -Cardboard:44 -Aluminum:18 -Paper:91 -Glass:63 -Glass:50 -Glass:80 -Aluminum:81 -Cardboard:12 -Glass:12 -Glass:54 -Aluminum:36 -Aluminum:93 -Glass:93 -Paper:80 -Glass:36 -Glass:12 -Glass:60 -Paper:66 -Aluminum:36 -Cardboard:22 diff --git a/code/patterns/trash/Trash.java b/code/patterns/trash/Trash.java deleted file mode 100644 index 7d01de8c..00000000 --- a/code/patterns/trash/Trash.java +++ /dev/null @@ -1,92 +0,0 @@ -// patterns/trash/Trash.java -// (c)2020 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. -// Base class for Trash recycling examples -package patterns.trash; -import java.util.*; -import java.lang.reflect.*; - -public abstract class Trash { - private double weight; - public Trash(double wt) { weight = wt; } - public Trash() {} - public abstract double value(); - public double weight() { return weight; } - // Sums the value of Trash in a bin: - static double val; - public static - void sumValue(List bin) { - val = 0.0f; - bin.forEach( t -> { - val += t.weight() * t.value(); - System.out.println("weight of " + - // RTTI gets type information - // about the class: - t.getClass().getName() + - " = " + t.weight()); - }); - System.out.println("Total value = " + val); - } - @Override - public String toString() { - // Print correct subclass name: - return getClass().getName() + - " w:" + weight() + " v:" + - String.format("%.2f", value()); - } - // Remainder of class supports dynamic creation: - public static class CannotCreateTrashException - extends RuntimeException { - public CannotCreateTrashException(Exception why) { - super(why); - } - } - public static class TrashClassNotFoundException - extends RuntimeException { - public TrashClassNotFoundException(Exception why) { - super(why); - } - } - public static class Info { - public String id; - public double data; - public Info(String name, double data) { - id = name; - this.data = data; - } - } - private static List trashTypes = - new ArrayList<>(); - @SuppressWarnings("unchecked") - public static T factory(Info info) { - for(Class trashType : trashTypes) { - // Determine the type and create one: - if(trashType.getName().contains(info.id)) { - try { - // Get the dynamic constructor method - // that takes a double argument: - Constructor ctor = - trashType.getConstructor(double.class); - // Call the constructor to create a - // new object: - return - (T)ctor.newInstance(info.data); - } catch(Exception e) { - throw new CannotCreateTrashException(e); - } - } - } - // The necessary Class was not in the list. Try to - // load it, but it must be in your class path! - try { - System.out.println("Loading " + info.id); - trashTypes.add(Class.forName(info.id)); - } catch(Exception e) { - throw new TrashClassNotFoundException(e); - } - // Loaded successfully. Recursive call - // should work this time: - return factory(info); - } -} diff --git a/code/patterns/trashvisitor/Aluminum.java b/code/patterns/trashvisitor/Aluminum.java deleted file mode 100644 index 85d5fa14..00000000 --- a/code/patterns/trashvisitor/Aluminum.java +++ /dev/null @@ -1,16 +0,0 @@ -// patterns/trashvisitor/Aluminum.java -// (c)2020 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. -// Aluminum for the visitor pattern -package patterns.trashvisitor; -import patterns.trash.*; - -public class Aluminum extends patterns.trash.Aluminum - implements Visitable { - public Aluminum(double wt) { super(wt); } - @Override - public void accept(Visitor v) { - v.visit(this); - } -} diff --git a/code/patterns/trashvisitor/Cardboard.java b/code/patterns/trashvisitor/Cardboard.java deleted file mode 100644 index 978202ef..00000000 --- a/code/patterns/trashvisitor/Cardboard.java +++ /dev/null @@ -1,16 +0,0 @@ -// patterns/trashvisitor/Cardboard.java -// (c)2020 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. -// Cardboard for the visitor pattern -package patterns.trashvisitor; -import patterns.trash.*; - -public class Cardboard extends patterns.trash.Cardboard - implements Visitable { - public Cardboard(double wt) { super(wt); } - @Override - public void accept(Visitor v) { - v.visit(this); - } -} diff --git a/code/patterns/trashvisitor/Glass.java b/code/patterns/trashvisitor/Glass.java deleted file mode 100644 index fbcf4949..00000000 --- a/code/patterns/trashvisitor/Glass.java +++ /dev/null @@ -1,16 +0,0 @@ -// patterns/trashvisitor/Glass.java -// (c)2020 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. -// Glass for the visitor pattern -package patterns.trashvisitor; -import patterns.trash.*; - -public class Glass extends patterns.trash.Glass - implements Visitable { - public Glass(double wt) { super(wt); } - @Override - public void accept(Visitor v) { - v.visit(this); - } -} diff --git a/code/patterns/trashvisitor/Paper.java b/code/patterns/trashvisitor/Paper.java deleted file mode 100644 index 6e9999f1..00000000 --- a/code/patterns/trashvisitor/Paper.java +++ /dev/null @@ -1,16 +0,0 @@ -// patterns/trashvisitor/Paper.java -// (c)2020 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. -// Paper for the visitor pattern -package patterns.trashvisitor; -import patterns.trash.*; - -public class Paper extends patterns.trash.Paper - implements Visitable { - public Paper(double wt) { super(wt); } - @Override - public void accept(Visitor v) { - v.visit(this); - } -} diff --git a/code/patterns/trashvisitor/TrashVisitor.java b/code/patterns/trashvisitor/TrashVisitor.java deleted file mode 100644 index 8f956623..00000000 --- a/code/patterns/trashvisitor/TrashVisitor.java +++ /dev/null @@ -1,127 +0,0 @@ -// patterns/trashvisitor/TrashVisitor.java -// (c)2020 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. -// {java patterns.trashvisitor.TrashVisitor} -package patterns.trashvisitor; -import patterns.trash.*; -import java.util.*; - -// Specific group of algorithms packaged -// in each implementation of Visitor: -class PriceVisitor implements Visitor { - private double alSum; // Aluminum - private double pSum; // Paper - private double gSum; // Glass - private double cSum; // Cardboard - public static void show(String s) { - System.out.println(s); - } - @Override - public void visit(Aluminum al) { - double v = al.weight() * al.value(); - show("value of Aluminum= " + v); - alSum += v; - } - @Override - public void visit(Paper p) { - double v = p.weight() * p.value(); - show("value of Paper= " + v); - pSum += v; - } - @Override - public void visit(Glass g) { - double v = g.weight() * g.value(); - show("value of Glass= " + v); - gSum += v; - } - @Override - public void visit(Cardboard c) { - double v = c.weight() * c.value(); - show("value of Cardboard = " + v); - cSum += v; - } - @Override - public void total() { - show( - "Total Aluminum: $" + alSum + "\n" + - "Total Paper: $" + pSum + "\n" + - "Total Glass: $" + gSum + "\n" + - "Total Cardboard: $" + cSum); - } -} - -class WeightVisitor implements Visitor { - private double alSum; // Aluminum - private double pSum; // Paper - private double gSum; // Glass - private double cSum; // Cardboard - public static void show(String s) { - System.out.println(s); - } - @Override - public void visit(Aluminum al) { - alSum += al.weight(); - show("Aluminum weight = " + al.weight()); - } - @Override - public void visit(Paper p) { - pSum += p.weight(); - show("Paper weight = " + p.weight()); - } - @Override - public void visit(Glass g) { - gSum += g.weight(); - show("Glass weight = " + g.weight()); - } - @Override - public void visit(Cardboard c) { - cSum += c.weight(); - show("Cardboard weight = " + c.weight()); - } - @Override - public void total() { - show("Total weight Aluminum:" + alSum); - show("Total weight Paper:" + pSum); - show("Total weight Glass:" + gSum); - show("Total weight Cardboard:" + cSum); - } -} - -public class TrashVisitor { - public static void main(String[] args) { - List bin = new ArrayList<>(); - // ParseTrash still works, without changes: - ParseTrash.fillBin("trashvisitor", bin); - List visitors = Arrays.asList( - new PriceVisitor(), new WeightVisitor()); - bin.forEach( t -> { - Visitable v = (Visitable) t; - visitors.forEach(visitor -> v.accept(visitor)); - }); - visitors.forEach(Visitor::total); - } -} -/* Output: (First and Last 10 Lines) -Loading patterns.trashvisitor.Glass -Loading patterns.trashvisitor.Paper -Loading patterns.trashvisitor.Aluminum -Loading patterns.trashvisitor.Cardboard -value of Glass= 12.420000225305557 -Glass weight = 54.0 -value of Paper= 2.2000000327825546 -Paper weight = 22.0 -value of Paper= 1.1000000163912773 -Paper weight = 11.0 -...________...________...________...________... -value of Cardboard = 5.060000091791153 -Cardboard weight = 22.0 -Total Aluminum: $860.0499778985977 -Total Paper: $35.80000053346157 -Total Glass: $150.1900027245283 -Total Cardboard: $40.02000072598457 -Total weight Aluminum:515.0 -Total weight Paper:358.0 -Total weight Glass:653.0 -Total weight Cardboard:174.0 -*/ diff --git a/code/patterns/trashvisitor/Visitable.java b/code/patterns/trashvisitor/Visitable.java deleted file mode 100644 index f1f9f1da..00000000 --- a/code/patterns/trashvisitor/Visitable.java +++ /dev/null @@ -1,12 +0,0 @@ -// patterns/trashvisitor/Visitable.java -// (c)2020 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. -// An interface to add visitor functionality to the -// Trash hierarchy without modifying the base class -package patterns.trashvisitor; - -public interface Visitable { - // The new method: - void accept(Visitor v); -} diff --git a/code/patterns/trashvisitor/Visitor.java b/code/patterns/trashvisitor/Visitor.java deleted file mode 100644 index 07ef4622..00000000 --- a/code/patterns/trashvisitor/Visitor.java +++ /dev/null @@ -1,14 +0,0 @@ -// patterns/trashvisitor/Visitor.java -// (c)2020 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. -// The base interface for visitors -package patterns.trashvisitor; - -public interface Visitor { - void visit(Aluminum a); - void visit(Paper p); - void visit(Glass g); - void visit(Cardboard c); - void total(); -} diff --git a/code/patterns/visitor/BeeAndFlowers.java b/code/patterns/visitor/BeeAndFlowers.java deleted file mode 100644 index aa86ebfc..00000000 --- a/code/patterns/visitor/BeeAndFlowers.java +++ /dev/null @@ -1,122 +0,0 @@ -// patterns/visitor/BeeAndFlowers.java -// (c)2020 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. -// Demonstration of "visitor" pattern -// {java patterns.visitor.BeeAndFlowers} -package patterns.visitor; -import java.util.*; -import java.util.function.*; -import java.util.stream.*; - -interface Visitor { - void visit(Gladiolus g); - void visit(Renuculus r); - void visit(Chrysanthemum c); -} - -// The Flower hierarchy cannot be changed: -interface Flower { - void accept(Visitor v); -} - -class Gladiolus implements Flower { - @Override - public void accept(Visitor v) { v.visit(this);} -} - -class Renuculus implements Flower { - @Override - public void accept(Visitor v) { v.visit(this);} -} - -class Chrysanthemum implements Flower { - @Override - public void accept(Visitor v) { v.visit(this);} -} - -// Add the ability to produce a String: -class StringVal implements Visitor { - String s; - @Override - public String toString() { return s; } - @Override - public void visit(Gladiolus g) { - s = "Gladiolus"; - } - @Override - public void visit(Renuculus r) { - s = "Renuculus"; - } - @Override - public void visit(Chrysanthemum c) { - s = "Chrysanthemum"; - } -} - -// Add the ability to do "Bee" activities: -class Bee implements Visitor { - @Override - public void visit(Gladiolus g) { - System.out.println("Bee and Gladiolus"); - } - @Override - public void visit(Renuculus r) { - System.out.println("Bee and Renuculus"); - } - @Override - public void visit(Chrysanthemum c) { - System.out.println("Bee and Chrysanthemum"); - } -} - -class FlowerFactory { - static List> flowers = - Arrays.asList(Gladiolus::new, - Renuculus::new, Chrysanthemum::new); - static final int SZ = flowers.size(); - private static SplittableRandom rand = - new SplittableRandom(47); - public static Flower newFlower() { - return flowers.get(rand.nextInt(SZ)).get(); - } -} - -public class BeeAndFlowers { - public static void main(String[] args) { - List flowers = - Stream.generate(FlowerFactory::newFlower) - .limit(10) - .collect(Collectors.toList()); - StringVal sval = new StringVal(); - flowers.forEach(f -> { - f.accept(sval); - System.out.println(sval); - }); - // Perform "Bee" operation on all Flowers: - Bee bee = new Bee(); - flowers.forEach(f -> f.accept(bee)); - } -} -/* Output: -Gladiolus -Chrysanthemum -Gladiolus -Renuculus -Chrysanthemum -Renuculus -Chrysanthemum -Chrysanthemum -Chrysanthemum -Renuculus -Bee and Gladiolus -Bee and Chrysanthemum -Bee and Gladiolus -Bee and Renuculus -Bee and Chrysanthemum -Bee and Renuculus -Bee and Chrysanthemum -Bee and Chrysanthemum -Bee and Chrysanthemum -Bee and Renuculus -*/ diff --git a/code/polymorphism/CovariantReturn.java b/code/polymorphism/CovariantReturn.java deleted file mode 100644 index e88fe590..00000000 --- a/code/polymorphism/CovariantReturn.java +++ /dev/null @@ -1,38 +0,0 @@ -// polymorphism/CovariantReturn.java -// (c)2020 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. - -class Grain { - @Override - public String toString() { return "Grain"; } -} - -class Wheat extends Grain { - @Override - public String toString() { return "Wheat"; } -} - -class Mill { - Grain process() { return new Grain(); } -} - -class WheatMill extends Mill { - @Override - Wheat process() { return new Wheat(); } -} - -public class CovariantReturn { - public static void main(String[] args) { - Mill m = new Mill(); - Grain g = m.process(); - System.out.println(g); - m = new WheatMill(); - g = m.process(); - System.out.println(g); - } -} -/* Output: -Grain -Wheat -*/ diff --git a/code/polymorphism/FieldAccess.java b/code/polymorphism/FieldAccess.java deleted file mode 100644 index 95e47c5e..00000000 --- a/code/polymorphism/FieldAccess.java +++ /dev/null @@ -1,36 +0,0 @@ -// polymorphism/FieldAccess.java -// (c)2020 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. -// Direct field access is determined at compile time - -class Super { - public int field = 0; - public int getField() { return field; } -} - -class Sub extends Super { - public int field = 1; - @Override - public int getField() { return field; } - public int getSuperField() { return super.field; } -} - -public class FieldAccess { - public static void main(String[] args) { - Super sup = new Sub(); // Upcast - System.out.println("sup.field = " + sup.field + - ", sup.getField() = " + sup.getField()); - Sub sub = new Sub(); - System.out.println("sub.field = " + - sub.field + ", sub.getField() = " + - sub.getField() + - ", sub.getSuperField() = " + - sub.getSuperField()); - } -} -/* Output: -sup.field = 0, sup.getField() = 1 -sub.field = 1, sub.getField() = 1, sub.getSuperField() -= 0 -*/ diff --git a/code/polymorphism/Frog.java b/code/polymorphism/Frog.java deleted file mode 100644 index 9226910d..00000000 --- a/code/polymorphism/Frog.java +++ /dev/null @@ -1,122 +0,0 @@ -// polymorphism/Frog.java -// (c)2020 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. -// Cleanup and inheritance -// {java polymorphism.Frog} -package polymorphism; - -class Characteristic { - private String s; - Characteristic(String s) { - this.s = s; - System.out.println("Creating Characteristic " + s); - } - protected void dispose() { - System.out.println("disposing Characteristic " + s); - } -} - -class Description { - private String s; - Description(String s) { - this.s = s; - System.out.println("Creating Description " + s); - } - protected void dispose() { - System.out.println("disposing Description " + s); - } -} - -class LivingCreature { - private Characteristic p = - new Characteristic("is alive"); - private Description t = - new Description("Basic Living Creature"); - LivingCreature() { - System.out.println("LivingCreature()"); - } - protected void dispose() { - System.out.println("LivingCreature dispose"); - t.dispose(); - p.dispose(); - } -} - -class Animal extends LivingCreature { - private Characteristic p = - new Characteristic("has heart"); - private Description t = - new Description("Animal not Vegetable"); - Animal() { System.out.println("Animal()"); } - @Override - protected void dispose() { - System.out.println("Animal dispose"); - t.dispose(); - p.dispose(); - super.dispose(); - } -} - -class Amphibian extends Animal { - private Characteristic p = - new Characteristic("can live in water"); - private Description t = - new Description("Both water and land"); - Amphibian() { - System.out.println("Amphibian()"); - } - @Override - protected void dispose() { - System.out.println("Amphibian dispose"); - t.dispose(); - p.dispose(); - super.dispose(); - } -} - -public class Frog extends Amphibian { - private Characteristic p = - new Characteristic("Croaks"); - private Description t = new Description("Eats Bugs"); - public Frog() { System.out.println("Frog()"); } - @Override - protected void dispose() { - System.out.println("Frog dispose"); - t.dispose(); - p.dispose(); - super.dispose(); - } - public static void main(String[] args) { - Frog frog = new Frog(); - System.out.println("Bye!"); - frog.dispose(); - } -} -/* Output: -Creating Characteristic is alive -Creating Description Basic Living Creature -LivingCreature() -Creating Characteristic has heart -Creating Description Animal not Vegetable -Animal() -Creating Characteristic can live in water -Creating Description Both water and land -Amphibian() -Creating Characteristic Croaks -Creating Description Eats Bugs -Frog() -Bye! -Frog dispose -disposing Description Eats Bugs -disposing Characteristic Croaks -Amphibian dispose -disposing Description Both water and land -disposing Characteristic can live in water -Animal dispose -disposing Description Animal not Vegetable -disposing Characteristic has heart -LivingCreature dispose -disposing Description Basic Living Creature -disposing Characteristic is alive -*/ diff --git a/code/polymorphism/PolyConstructors.java b/code/polymorphism/PolyConstructors.java deleted file mode 100644 index 3a99f08b..00000000 --- a/code/polymorphism/PolyConstructors.java +++ /dev/null @@ -1,41 +0,0 @@ -// polymorphism/PolyConstructors.java -// (c)2020 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. -// Constructors and polymorphism -// don't produce what you might expect - -class Glyph { - void draw() { System.out.println("Glyph.draw()"); } - Glyph() { - System.out.println("Glyph() before draw()"); - draw(); - System.out.println("Glyph() after draw()"); - } -} - -class RoundGlyph extends Glyph { - private int radius = 1; - RoundGlyph(int r) { - radius = r; - System.out.println( - "RoundGlyph.RoundGlyph(), radius = " + radius); - } - @Override - void draw() { - System.out.println( - "RoundGlyph.draw(), radius = " + radius); - } -} - -public class PolyConstructors { - public static void main(String[] args) { - new RoundGlyph(5); - } -} -/* Output: -Glyph() before draw() -RoundGlyph.draw(), radius = 0 -Glyph() after draw() -RoundGlyph.RoundGlyph(), radius = 5 -*/ diff --git a/code/polymorphism/PrivateOverride.java b/code/polymorphism/PrivateOverride.java deleted file mode 100644 index 9873e03d..00000000 --- a/code/polymorphism/PrivateOverride.java +++ /dev/null @@ -1,24 +0,0 @@ -// polymorphism/PrivateOverride.java -// (c)2020 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. -// Trying to override a private method -// {java polymorphism.PrivateOverride} -package polymorphism; - -public class PrivateOverride { - private void f() { - System.out.println("private f()"); - } - public static void main(String[] args) { - PrivateOverride po = new Derived(); - po.f(); - } -} - -class Derived extends PrivateOverride { - public void f() { System.out.println("public f()"); } -} -/* Output: -private f() -*/ diff --git a/code/polymorphism/PrivateOverride2.java b/code/polymorphism/PrivateOverride2.java deleted file mode 100644 index 664672bc..00000000 --- a/code/polymorphism/PrivateOverride2.java +++ /dev/null @@ -1,22 +0,0 @@ -// polymorphism/PrivateOverride2.java -// (c)2020 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. -// Detecting a mistaken override using @Override -// {WillNotCompile} -package polymorphism; - -public class PrivateOverride2 { - private void f() { - System.out.println("private f()"); - } - public static void main(String[] args) { - PrivateOverride2 po = new Derived2(); - po.f(); - } -} - -class Derived2 extends PrivateOverride2 { - @Override - public void f() { System.out.println("public f()"); } -} diff --git a/code/polymorphism/RTTI.java b/code/polymorphism/RTTI.java deleted file mode 100644 index 39c9029b..00000000 --- a/code/polymorphism/RTTI.java +++ /dev/null @@ -1,43 +0,0 @@ -// polymorphism/RTTI.java -// (c)2020 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. -// Downcasting & Runtime type information (RTTI) -// {ThrowsException} - -class Useful { - public void f() {} - public void g() {} -} - -class MoreUseful extends Useful { - @Override - public void f() {} - @Override - public void g() {} - public void u() {} - public void v() {} - public void w() {} -} - -public class RTTI { - public static void main(String[] args) { - Useful[] x = { - new Useful(), - new MoreUseful() - }; - x[0].f(); - x[1].g(); - // Compile time: method not found in Useful: - //- x[1].u(); - ((MoreUseful)x[1]).u(); // Downcast/RTTI - ((MoreUseful)x[0]).u(); // Exception thrown - } -} -/* Output: -___[ Error Output ]___ -Exception in thread "main" -java.lang.ClassCastException: Useful cannot be cast to -MoreUseful - at RTTI.main(RTTI.java:31) -*/ diff --git a/code/polymorphism/ReferenceCounting.java b/code/polymorphism/ReferenceCounting.java deleted file mode 100644 index b378117f..00000000 --- a/code/polymorphism/ReferenceCounting.java +++ /dev/null @@ -1,71 +0,0 @@ -// polymorphism/ReferenceCounting.java -// (c)2020 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. -// Cleaning up shared member objects - -class Shared { - private int refcount = 0; - private static long counter = 0; - private final long id = counter++; - Shared() { - System.out.println("Creating " + this); - } - public void addRef() { refcount++; } - protected void dispose() { - if(--refcount == 0) - System.out.println("Disposing " + this); - } - @Override - public String toString() { - return "Shared " + id; - } -} - -class Composing { - private Shared shared; - private static long counter = 0; - private final long id = counter++; - Composing(Shared shared) { - System.out.println("Creating " + this); - this.shared = shared; - this.shared.addRef(); - } - protected void dispose() { - System.out.println("disposing " + this); - shared.dispose(); - } - @Override - public String toString() { - return "Composing " + id; - } -} - -public class ReferenceCounting { - public static void main(String[] args) { - Shared shared = new Shared(); - Composing[] composing = { - new Composing(shared), - new Composing(shared), - new Composing(shared), - new Composing(shared), - new Composing(shared) - }; - for(Composing c : composing) - c.dispose(); - } -} -/* Output: -Creating Shared 0 -Creating Composing 0 -Creating Composing 1 -Creating Composing 2 -Creating Composing 3 -Creating Composing 4 -disposing Composing 0 -disposing Composing 1 -disposing Composing 2 -disposing Composing 3 -disposing Composing 4 -Disposing Shared 0 -*/ diff --git a/code/polymorphism/Sandwich.java b/code/polymorphism/Sandwich.java deleted file mode 100644 index 97f80d53..00000000 --- a/code/polymorphism/Sandwich.java +++ /dev/null @@ -1,54 +0,0 @@ -// polymorphism/Sandwich.java -// (c)2020 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. -// Order of constructor calls -// {java polymorphism.Sandwich} -package polymorphism; - -class Meal { - Meal() { System.out.println("Meal()"); } -} - -class Bread { - Bread() { System.out.println("Bread()"); } -} - -class Cheese { - Cheese() { System.out.println("Cheese()"); } -} - -class Lettuce { - Lettuce() { System.out.println("Lettuce()"); } -} - -class Lunch extends Meal { - Lunch() { System.out.println("Lunch()"); } -} - -class PortableLunch extends Lunch { - PortableLunch() { - System.out.println("PortableLunch()"); - } -} - -public class Sandwich extends PortableLunch { - private Bread b = new Bread(); - private Cheese c = new Cheese(); - private Lettuce l = new Lettuce(); - public Sandwich() { - System.out.println("Sandwich()"); - } - public static void main(String[] args) { - new Sandwich(); - } -} -/* Output: -Meal() -Lunch() -PortableLunch() -Bread() -Cheese() -Lettuce() -Sandwich() -*/ diff --git a/code/polymorphism/Shapes.java b/code/polymorphism/Shapes.java deleted file mode 100644 index 4d051e70..00000000 --- a/code/polymorphism/Shapes.java +++ /dev/null @@ -1,26 +0,0 @@ -// polymorphism/Shapes.java -// (c)2020 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. -// Polymorphism in Java -import polymorphism.shape.*; - -public class Shapes { - public static void main(String[] args) { - RandomShapes gen = new RandomShapes(); - // Make polymorphic method calls: - for(Shape shape : gen.array(9)) - shape.draw(); - } -} -/* Output: -Triangle.draw() -Triangle.draw() -Square.draw() -Triangle.draw() -Square.draw() -Triangle.draw() -Square.draw() -Triangle.draw() -Circle.draw() -*/ diff --git a/code/polymorphism/StaticPolymorphism.java b/code/polymorphism/StaticPolymorphism.java deleted file mode 100644 index 1ebe733b..00000000 --- a/code/polymorphism/StaticPolymorphism.java +++ /dev/null @@ -1,36 +0,0 @@ -// polymorphism/StaticPolymorphism.java -// (c)2020 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. -// Static methods are not polymorphic - -class StaticSuper { - public static String staticGet() { - return "Base staticGet()"; - } - public String dynamicGet() { - return "Base dynamicGet()"; - } -} - -class StaticSub extends StaticSuper { - public static String staticGet() { - return "Derived staticGet()"; - } - @Override - public String dynamicGet() { - return "Derived dynamicGet()"; - } -} - -public class StaticPolymorphism { - public static void main(String[] args) { - StaticSuper sup = new StaticSub(); // Upcast - System.out.println(StaticSuper.staticGet()); - System.out.println(sup.dynamicGet()); - } -} -/* Output: -Base staticGet() -Derived dynamicGet() -*/ diff --git a/code/polymorphism/Transmogrify.java b/code/polymorphism/Transmogrify.java deleted file mode 100644 index 09877d53..00000000 --- a/code/polymorphism/Transmogrify.java +++ /dev/null @@ -1,43 +0,0 @@ -// polymorphism/Transmogrify.java -// (c)2020 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. -// Dynamically changing the behavior of an object -// via composition (the "State" design pattern) - -class Actor { - public void act() {} -} - -class HappyActor extends Actor { - @Override - public void act() { - System.out.println("HappyActor"); - } -} - -class SadActor extends Actor { - @Override - public void act() { - System.out.println("SadActor"); - } -} - -class Stage { - private Actor actor = new HappyActor(); - public void change() { actor = new SadActor(); } - public void performPlay() { actor.act(); } -} - -public class Transmogrify { - public static void main(String[] args) { - Stage stage = new Stage(); - stage.performPlay(); - stage.change(); - stage.performPlay(); - } -} -/* Output: -HappyActor -SadActor -*/ diff --git a/code/polymorphism/music/Instrument.java b/code/polymorphism/music/Instrument.java deleted file mode 100644 index fb6c77e3..00000000 --- a/code/polymorphism/music/Instrument.java +++ /dev/null @@ -1,11 +0,0 @@ -// polymorphism/music/Instrument.java -// (c)2020 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 polymorphism.music; - -class Instrument { - public void play(Note n) { - System.out.println("Instrument.play()"); - } -} diff --git a/code/polymorphism/music/Music.java b/code/polymorphism/music/Music.java deleted file mode 100644 index 8e903ec0..00000000 --- a/code/polymorphism/music/Music.java +++ /dev/null @@ -1,21 +0,0 @@ -// polymorphism/music/Music.java -// (c)2020 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. -// Inheritance & upcasting -// {java polymorphism.music.Music} -package polymorphism.music; - -public class Music { - public static void tune(Instrument i) { - // ... - i.play(Note.MIDDLE_C); - } - public static void main(String[] args) { - Wind flute = new Wind(); - tune(flute); // Upcasting - } -} -/* Output: -Wind.play() MIDDLE_C -*/ diff --git a/code/polymorphism/music/Music2.java b/code/polymorphism/music/Music2.java deleted file mode 100644 index a5bff54b..00000000 --- a/code/polymorphism/music/Music2.java +++ /dev/null @@ -1,46 +0,0 @@ -// polymorphism/music/Music2.java -// (c)2020 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. -// Overloading instead of upcasting -// {java polymorphism.music.Music2} -package polymorphism.music; - -class Stringed extends Instrument { - @Override - public void play(Note n) { - System.out.println("Stringed.play() " + n); - } -} - -class Brass extends Instrument { - @Override - public void play(Note n) { - System.out.println("Brass.play() " + n); - } -} - -public class Music2 { - public static void tune(Wind i) { - i.play(Note.MIDDLE_C); - } - public static void tune(Stringed i) { - i.play(Note.MIDDLE_C); - } - public static void tune(Brass i) { - i.play(Note.MIDDLE_C); - } - public static void main(String[] args) { - Wind flute = new Wind(); - Stringed violin = new Stringed(); - Brass frenchHorn = new Brass(); - tune(flute); // No upcasting - tune(violin); - tune(frenchHorn); - } -} -/* Output: -Wind.play() MIDDLE_C -Stringed.play() MIDDLE_C -Brass.play() MIDDLE_C -*/ diff --git a/code/polymorphism/music/Note.java b/code/polymorphism/music/Note.java deleted file mode 100644 index 414367a9..00000000 --- a/code/polymorphism/music/Note.java +++ /dev/null @@ -1,10 +0,0 @@ -// polymorphism/music/Note.java -// (c)2020 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. -// Notes to play on musical instruments -package polymorphism.music; - -public enum Note { - MIDDLE_C, C_SHARP, B_FLAT; // Etc. -} diff --git a/code/polymorphism/music/Wind.java b/code/polymorphism/music/Wind.java deleted file mode 100644 index c38ac497..00000000 --- a/code/polymorphism/music/Wind.java +++ /dev/null @@ -1,15 +0,0 @@ -// polymorphism/music/Wind.java -// (c)2020 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 polymorphism.music; - -// Wind objects are instruments -// because they have the same interface: -public class Wind extends Instrument { - // Redefine interface method: - @Override - public void play(Note n) { - System.out.println("Wind.play() " + n); - } -} diff --git a/code/polymorphism/music3/Music3.java b/code/polymorphism/music3/Music3.java deleted file mode 100644 index da3eb364..00000000 --- a/code/polymorphism/music3/Music3.java +++ /dev/null @@ -1,108 +0,0 @@ -// polymorphism/music3/Music3.java -// (c)2020 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. -// An extensible program -// {java polymorphism.music3.Music3} -package polymorphism.music3; -import polymorphism.music.Note; - -class Instrument { - void play(Note n) { - System.out.println("Instrument.play() " + n); - } - String what() { return "Instrument"; } - void adjust() { - System.out.println("Adjusting Instrument"); - } -} - -class Wind extends Instrument { - @Override - void play(Note n) { - System.out.println("Wind.play() " + n); - } - @Override - String what() { return "Wind"; } - @Override - void adjust() { - System.out.println("Adjusting Wind"); - } -} - -class Percussion extends Instrument { - @Override - void play(Note n) { - System.out.println("Percussion.play() " + n); - } - @Override - String what() { return "Percussion"; } - @Override - void adjust() { - System.out.println("Adjusting Percussion"); - } -} - -class Stringed extends Instrument { - @Override - void play(Note n) { - System.out.println("Stringed.play() " + n); - } - @Override - String what() { return "Stringed"; } - @Override - void adjust() { - System.out.println("Adjusting Stringed"); - } -} - -class Brass extends Wind { - @Override - void play(Note n) { - System.out.println("Brass.play() " + n); - } - @Override - void adjust() { - System.out.println("Adjusting Brass"); - } -} - -class Woodwind extends Wind { - @Override - void play(Note n) { - System.out.println("Woodwind.play() " + n); - } - @Override - String what() { return "Woodwind"; } -} - -public class Music3 { - // Doesn't care about type, so new types - // added to the system still work right: - public static void tune(Instrument i) { - // ... - i.play(Note.MIDDLE_C); - } - public static void tuneAll(Instrument[] e) { - for(Instrument i : e) - tune(i); - } - public static void main(String[] args) { - // Upcasting during addition to the array: - Instrument[] orchestra = { - new Wind(), - new Percussion(), - new Stringed(), - new Brass(), - new Woodwind() - }; - tuneAll(orchestra); - } -} -/* Output: -Wind.play() MIDDLE_C -Percussion.play() MIDDLE_C -Stringed.play() MIDDLE_C -Brass.play() MIDDLE_C -Woodwind.play() MIDDLE_C -*/ diff --git a/code/polymorphism/shape/Circle.java b/code/polymorphism/shape/Circle.java deleted file mode 100644 index fc857950..00000000 --- a/code/polymorphism/shape/Circle.java +++ /dev/null @@ -1,16 +0,0 @@ -// polymorphism/shape/Circle.java -// (c)2020 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 polymorphism.shape; - -public class Circle extends Shape { - @Override - public void draw() { - System.out.println("Circle.draw()"); - } - @Override - public void erase() { - System.out.println("Circle.erase()"); - } -} diff --git a/code/polymorphism/shape/RandomShapes.java b/code/polymorphism/shape/RandomShapes.java deleted file mode 100644 index c1419f4e..00000000 --- a/code/polymorphism/shape/RandomShapes.java +++ /dev/null @@ -1,26 +0,0 @@ -// polymorphism/shape/RandomShapes.java -// (c)2020 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. -// A "factory" that randomly creates shapes -package polymorphism.shape; -import java.util.*; - -public class RandomShapes { - private Random rand = new Random(47); - public Shape get() { - switch(rand.nextInt(3)) { - default: - case 0: return new Circle(); - case 1: return new Square(); - case 2: return new Triangle(); - } - } - public Shape[] array(int sz) { - Shape[] shapes = new Shape[sz]; - // Fill up the array with shapes: - for(int i = 0; i < shapes.length; i++) - shapes[i] = get(); - return shapes; - } -} diff --git a/code/polymorphism/shape/Shape.java b/code/polymorphism/shape/Shape.java deleted file mode 100644 index 4be93c86..00000000 --- a/code/polymorphism/shape/Shape.java +++ /dev/null @@ -1,10 +0,0 @@ -// polymorphism/shape/Shape.java -// (c)2020 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 polymorphism.shape; - -public class Shape { - public void draw() {} - public void erase() {} -} diff --git a/code/polymorphism/shape/Square.java b/code/polymorphism/shape/Square.java deleted file mode 100644 index 4938335b..00000000 --- a/code/polymorphism/shape/Square.java +++ /dev/null @@ -1,16 +0,0 @@ -// polymorphism/shape/Square.java -// (c)2020 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 polymorphism.shape; - -public class Square extends Shape { - @Override - public void draw() { - System.out.println("Square.draw()"); - } - @Override - public void erase() { - System.out.println("Square.erase()"); - } -} diff --git a/code/polymorphism/shape/Triangle.java b/code/polymorphism/shape/Triangle.java deleted file mode 100644 index db7394a3..00000000 --- a/code/polymorphism/shape/Triangle.java +++ /dev/null @@ -1,16 +0,0 @@ -// polymorphism/shape/Triangle.java -// (c)2020 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 polymorphism.shape; - -public class Triangle extends Shape { - @Override - public void draw() { - System.out.println("Triangle.draw()"); - } - @Override - public void erase() { - System.out.println("Triangle.erase()"); - } -} diff --git a/code/references/AddingClone.java b/code/references/AddingClone.java deleted file mode 100644 index 4f03cf06..00000000 --- a/code/references/AddingClone.java +++ /dev/null @@ -1,67 +0,0 @@ -// references/AddingClone.java -// (c)2020 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. -// You must go through a few gyrations -// to add cloning to your own class -import java.util.*; -import java.util.stream.*; - -class Int2 implements Cloneable { - private int i; - Int2(int ii) { i = ii; } - public void increment() { i++; } - @Override - public String toString() { - return Integer.toString(i); - } - @Override - public Int2 clone() { - try { - return (Int2)super.clone(); - } catch(CloneNotSupportedException e) { - throw new RuntimeException(e); - } - } -} - -// Inheritance doesn't remove cloneability: -class Int3 extends Int2 { - private int j; // Automatically duplicated - Int3(int i) { super(i); } -} - -public class AddingClone { - @SuppressWarnings("unchecked") - public static void main(String[] args) { - Int2 x = new Int2(10); - Int2 x2 = x.clone(); - x2.increment(); - System.out.println( - "x = " + x + ", x2 = " + x2); - // Anything inherited is also cloneable: - Int3 x3 = new Int3(7); - x3 = (Int3)x3.clone(); - ArrayList v = IntStream.range(0, 10) - .mapToObj(Int2::new) - .collect(Collectors - .toCollection(ArrayList::new)); - System.out.println("v: " + v); - ArrayList v2 = - (ArrayList)v.clone(); - // Now clone each element: - IntStream.range(0, v.size()) - .forEach(i -> v2.set(i, v.get(i).clone())); - // Increment all v2's elements: - v2.forEach(Int2::increment); - System.out.println("v2: " + v2); - // See if it changed v's elements: - System.out.println("v: " + v); - } -} -/* Output: -x = 10, x2 = 11 -v: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -v2: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] -v: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -*/ diff --git a/code/references/Alias1.java b/code/references/Alias1.java deleted file mode 100644 index 1af594ec..00000000 --- a/code/references/Alias1.java +++ /dev/null @@ -1,27 +0,0 @@ -// references/Alias1.java -// (c)2020 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. -// Aliasing two references to one object - -public class Alias1 { - private int i; - public Alias1(int ii) { i = ii; } - public static void main(String[] args) { - Alias1 x = new Alias1(7); - Alias1 y = x; // Assign the reference (1) - System.out.println("x: " + x.i); - System.out.println("y: " + y.i); - System.out.println("Incrementing x"); - x.i++; // [2] - System.out.println("x: " + x.i); - System.out.println("y: " + y.i); - } -} -/* Output: -x: 7 -y: 7 -Incrementing x -x: 8 -y: 8 -*/ diff --git a/code/references/Alias2.java b/code/references/Alias2.java deleted file mode 100644 index aa37e1a2..00000000 --- a/code/references/Alias2.java +++ /dev/null @@ -1,25 +0,0 @@ -// references/Alias2.java -// (c)2020 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. -// Method calls implicitly alias their arguments - -public class Alias2 { - private int i; - public Alias2(int i) { this.i = i; } - public static void f(Alias2 reference) { - reference.i++; - } - public static void main(String[] args) { - Alias2 x = new Alias2(7); - System.out.println("x: " + x.i); - System.out.println("Calling f(x)"); - f(x); - System.out.println("x: " + x.i); - } -} -/* Output: -x: 7 -Calling f(x) -x: 8 -*/ diff --git a/code/references/CheckCloneable.java b/code/references/CheckCloneable.java deleted file mode 100644 index 137937a9..00000000 --- a/code/references/CheckCloneable.java +++ /dev/null @@ -1,113 +0,0 @@ -// references/CheckCloneable.java -// (c)2020 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. -// Check to see if a reference can be cloned - -// Can't clone this -- doesn't override clone(): -class Ordinary {} - -// Overrides clone, doesn't implement Cloneable: -class WrongClone extends Ordinary { - @Override public Object clone() - throws CloneNotSupportedException { - return super.clone(); // Throws exception - } -} - -// Does all the right things for cloning: -class IsCloneable extends Ordinary -implements Cloneable { - @Override public Object clone() - throws CloneNotSupportedException { - return super.clone(); - } -} - -// Turn off cloning by throwing the exception: -class NoMore extends IsCloneable { - @Override public Object clone() - throws CloneNotSupportedException { - throw new CloneNotSupportedException(); - } -} - -class TryMore extends NoMore { - @Override public Object clone() - throws CloneNotSupportedException { - // Calls NoMore.clone(), throws exception: - return super.clone(); - } -} - -class BackOn extends NoMore { - private BackOn duplicate(BackOn b) { - // Somehow make a copy of b and return that - // copy. A dummy copy, just to make a point: - return new BackOn(); - } - @Override - public Object clone() { - // Doesn't call NoMore.clone(): - return duplicate(this); - } -} - -// You can't inherit from this, so you can't -// override clone() as you can in BackOn: -final class ReallyNoMore extends NoMore {} - -public class CheckCloneable { - public static - Ordinary tryToClone(Ordinary ord) { - String id = ord.getClass().getName(); - System.out.println("Attempting " + id); - Ordinary x = null; - if(ord instanceof Cloneable) { - try { - x = (Ordinary)((IsCloneable)ord).clone(); - System.out.println("Cloned " + id); - } catch(CloneNotSupportedException e) { - System.out.println( - "Could not clone " + id); - } - } else { - System.out.println("Doesn't implement Cloneable"); - } - return x; - } - public static void main(String[] args) { - // Upcasting: - Ordinary[] ord = { - new IsCloneable(), - new WrongClone(), - new NoMore(), - new TryMore(), - new BackOn(), - new ReallyNoMore(), - }; - Ordinary x = new Ordinary(); - // This won't compile because - // clone() is protected in Object: - //- x = (Ordinary)x.clone(); - // Checks first to see if the class - // implements Cloneable: - for(Ordinary ord1 : ord) { - tryToClone(ord1); - } - } -} -/* Output: -Attempting IsCloneable -Cloned IsCloneable -Attempting WrongClone -Doesn't implement Cloneable -Attempting NoMore -Could not clone NoMore -Attempting TryMore -Could not clone TryMore -Attempting BackOn -Cloned BackOn -Attempting ReallyNoMore -Could not clone ReallyNoMore -*/ diff --git a/code/references/CloneArrayList.java b/code/references/CloneArrayList.java deleted file mode 100644 index 601673c2..00000000 --- a/code/references/CloneArrayList.java +++ /dev/null @@ -1,38 +0,0 @@ -// references/CloneArrayList.java -// (c)2020 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. -// The clone() operation works for only a few -// items in the standard Java library -import java.util.*; -import java.util.stream.*; - -class Int { - private int i; - Int(int ii) { i = ii; } - public void increment() { i++; } - @Override - public String toString() { - return Integer.toString(i); - } -} - -public class CloneArrayList { - public static void main(String[] args) { - ArrayList v = IntStream.range(0, 10) - .mapToObj(Int::new) - .collect(Collectors - .toCollection(ArrayList::new)); - System.out.println("v: " + v); - @SuppressWarnings("unchecked") - ArrayList v2 = (ArrayList)v.clone(); - // Increment all v2's elements: - v2.forEach(Int::increment); - // See if it changed v's elements: - System.out.println("v: " + v); - } -} -/* Output: -v: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -v: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] -*/ diff --git a/code/references/Compete.java b/code/references/Compete.java deleted file mode 100644 index 9e77f3a7..00000000 --- a/code/references/Compete.java +++ /dev/null @@ -1,89 +0,0 @@ -// references/Compete.java -// (c)2020 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. -import java.io.*; -import onjava.Timer; - -class Thing1 implements Serializable {} -class Thing2 implements Serializable { - Thing1 t1 = new Thing1(); -} - -class Thing3 implements Cloneable { - @Override - public Thing3 clone() { - try { - return (Thing3)super.clone(); - } catch(CloneNotSupportedException e) { - throw new RuntimeException(e); - } - } -} - -class Thing4 implements Cloneable { - private Thing3 t3 = new Thing3(); - @Override - public Thing4 clone() { - Thing4 t4 = null; - try { - t4 = (Thing4)super.clone(); - } catch(CloneNotSupportedException e) { - throw new RuntimeException(e); - } - // Clone the field, too: - t4.t3 = t3.clone(); - return t4; - } -} - -public class Compete { - public static final int SIZE = 100000; - public static void - main(String[] args) throws Exception { - Thing2[] a = new Thing2[SIZE]; - for(int i = 0; i < SIZE; i++) - a[i] = new Thing2(); - Thing4[] b = new Thing4[SIZE]; - for(int i = 0; i < SIZE; i++) - b[i] = new Thing4(); - Timer timer = new Timer(); - try( - ByteArrayOutputStream buf = - new ByteArrayOutputStream(); - ObjectOutputStream oos = - new ObjectOutputStream(buf) - ) { - for(Thing2 a1 : a) { - oos.writeObject(a1); - } - // Now get copies: - try( - ObjectInputStream in = - new ObjectInputStream( - new ByteArrayInputStream( - buf.toByteArray())) - ) { - Thing2[] c = new Thing2[SIZE]; - for(int i = 0; i < SIZE; i++) - c[i] = (Thing2)in.readObject(); - } - } - System.out.println( - "Duplication via serialization: " + - timer.duration() + " Milliseconds"); - - // Now try cloning: - timer = new Timer(); - Thing4[] d = new Thing4[SIZE]; - for(int i = 0; i < SIZE; i++) - d[i] = b[i].clone(); - System.out.println( - "Duplication via cloning: " + - timer.duration() + " Milliseconds"); - } -} -/* Output: -Duplication via serialization: 516 Milliseconds -Duplication via cloning: 71 Milliseconds -*/ diff --git a/code/references/CopyConstructor.java b/code/references/CopyConstructor.java deleted file mode 100644 index 2617f48b..00000000 --- a/code/references/CopyConstructor.java +++ /dev/null @@ -1,188 +0,0 @@ -// references/CopyConstructor.java -// (c)2020 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. -// A constructor to copy an object of the same -// type, as an attempt to create a local copy -import java.lang.reflect.*; - -class FruitQualities { - private int weight; - private int color; - private int firmness; - private int ripeness; - private int smell; - // etc. - // No-arg constructor: - FruitQualities() { - // Do something meaningful... - } - // Other constructors: - // ... - // Copy constructor: - FruitQualities(FruitQualities f) { - weight = f.weight; - color = f.color; - firmness = f.firmness; - ripeness = f.ripeness; - smell = f.smell; - // etc. - } -} - -class Seed { - // Members... - Seed() { /* No-arg constructor */ } - Seed(Seed s) { /* Copy constructor */ } -} - -class Fruit { - private FruitQualities fq; - private int seeds; - private Seed[] s; - Fruit(FruitQualities q, int seedCount) { - fq = q; - seeds = seedCount; - s = new Seed[seeds]; - for(int i = 0; i < seeds; i++) - s[i] = new Seed(); - } - // Other constructors: - // ... - // Copy constructor: - Fruit(Fruit f) { - fq = new FruitQualities(f.fq); - seeds = f.seeds; - s = new Seed[seeds]; - // Call all Seed copy-constructors: - for(int i = 0; i < seeds; i++) - s[i] = new Seed(f.s[i]); - // Other copy-construction activities... - } - // This allows derived constructors (or other - // methods) to put in different qualities: - protected void addQualities(FruitQualities q) { - fq = q; - } - protected FruitQualities getQualities() { - return fq; - } -} - -class Tomato extends Fruit { - Tomato() { - super(new FruitQualities(), 100); - } - Tomato(Tomato t) { // Copy-constructor - super(t); // Upcast to base copy-constructor - // Other copy-construction activities... - } -} - -class ZebraQualities extends FruitQualities { - private int stripedness; - // No-arg constructor: - ZebraQualities() { - super(); - // do something meaningful... - } - ZebraQualities(ZebraQualities z) { - super(z); - stripedness = z.stripedness; - } -} - -class GreenZebra extends Tomato { - GreenZebra() { - addQualities(new ZebraQualities()); - } - GreenZebra(GreenZebra g) { - super(g); // Calls Tomato(Tomato) - // Restore the right qualities: - addQualities(new ZebraQualities()); - } - public void evaluate() { - ZebraQualities zq = - (ZebraQualities)getQualities(); - // Do something with the qualities - // ... - } -} - -public class CopyConstructor { - public static void ripen(Tomato t) { - // Use the "copy constructor": - t = new Tomato(t); // [1] - System.out.println("In ripen, t is a " + - t.getClass().getName()); - } - public static void slice(Fruit f) { - f = new Fruit(f); // [2] Hmmm... will this work? - System.out.println("In slice, f is a " + - f.getClass().getName()); - } - @SuppressWarnings("unchecked") - public static void ripen2(Tomato t) { - try { - Class c = t.getClass(); - // Use the "copy constructor": - Constructor ct = - c.getConstructor(new Class[] { c }); - Object obj = - ct.newInstance(new Object[] { t }); - System.out.println("In ripen2, t is a " + - obj.getClass().getName()); - } catch(NoSuchMethodException | - SecurityException | - InstantiationException | - IllegalAccessException | - IllegalArgumentException | - InvocationTargetException e) { - System.out.println(e); - } - } - @SuppressWarnings("unchecked") - public static void slice2(Fruit f) { - try { - Class c = f.getClass(); - Constructor ct = - c.getConstructor(new Class[] { c }); - Object obj = - ct.newInstance(new Object[] { f }); - System.out.println("In slice2, f is a " + - obj.getClass().getName()); - } catch(NoSuchMethodException | - SecurityException | - InstantiationException | - IllegalAccessException | - IllegalArgumentException | - InvocationTargetException e) { - System.out.println(e); - } - } - public static void main(String[] args) { - Tomato tomato = new Tomato(); - ripen(tomato); // OK - slice(tomato); // OOPS! - ripen2(tomato); // OK - slice2(tomato); // OK - GreenZebra g = new GreenZebra(); - ripen(g); // OOPS! - slice(g); // OOPS! - ripen2(g); // OK - slice2(g); // OK - g.evaluate(); - } -} -/* Output: -In ripen, t is a Tomato -In slice, f is a Fruit -java.lang.NoSuchMethodException: Tomato.(Tomato) -java.lang.NoSuchMethodException: Tomato.(Tomato) -In ripen, t is a Tomato -In slice, f is a Fruit -java.lang.NoSuchMethodException: -GreenZebra.(GreenZebra) -java.lang.NoSuchMethodException: -GreenZebra.(GreenZebra) -*/ diff --git a/code/references/DepthReading.java b/code/references/DepthReading.java deleted file mode 100644 index 00d9dfda..00000000 --- a/code/references/DepthReading.java +++ /dev/null @@ -1,29 +0,0 @@ -// references/DepthReading.java -// (c)2020 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. -// Cloning a composed object -package references; - -public class DepthReading implements Cloneable { - private double depth; - public DepthReading(double depth) { - this.depth = depth; - } - @Override - public DepthReading clone() { - try { - return (DepthReading)super.clone(); - } catch(CloneNotSupportedException e) { - throw new RuntimeException(e); - } - } - public double getDepth() { return depth; } - public void setDepth(double depth) { - this.depth = depth; - } - @Override - public String toString() { - return String.valueOf(depth); - } -} diff --git a/code/references/HorrorFlick.java b/code/references/HorrorFlick.java deleted file mode 100644 index 709d15bf..00000000 --- a/code/references/HorrorFlick.java +++ /dev/null @@ -1,35 +0,0 @@ -// references/HorrorFlick.java -// (c)2020 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. -// Insert Cloneability at any level of inheritance - -class Person {} - -class Hero extends Person {} - -class Scientist extends Person implements Cloneable { - @Override - public Scientist clone() { - try { - return (Scientist)super.clone(); - } catch(CloneNotSupportedException e) { - throw new RuntimeException(e); - } - } -} - -class MadScientist extends Scientist {} - -public class HorrorFlick { - public static void main(String[] args) { - Person p = new Person(); - Hero h = new Hero(); - Scientist s = new Scientist(); - MadScientist m = new MadScientist(); - //- p = (Person)p.clone(); // Compile error - //- h = (Hero)h.clone(); // Compile error - s = s.clone(); - m = (MadScientist)m.clone(); - } -} diff --git a/code/references/Immutable1.java b/code/references/Immutable1.java deleted file mode 100644 index 55ac1f6a..00000000 --- a/code/references/Immutable1.java +++ /dev/null @@ -1,34 +0,0 @@ -// references/Immutable1.java -// (c)2020 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. -// Immutable objects are immune to aliasing - -public class Immutable1 { - private int data; - public Immutable1(int initVal) { - data = initVal; - } - public int read() { return data; } - public boolean nonzero() { return data != 0; } - public Immutable1 multiply(int multiplier) { - return new Immutable1(data * multiplier); - } - public static void f(Immutable1 i1) { - Immutable1 quad = i1.multiply(4); - System.out.println("i1 = " + i1.read()); - System.out.println("quad = " + quad.read()); - } - public static void main(String[] args) { - Immutable1 x = new Immutable1(47); - System.out.println("x = " + x.read()); - f(x); - System.out.println("x = " + x.read()); - } -} -/* Output: -x = 47 -i1 = 47 -quad = 188 -x = 47 -*/ diff --git a/code/references/Immutable2.java b/code/references/Immutable2.java deleted file mode 100644 index a565f86a..00000000 --- a/code/references/Immutable2.java +++ /dev/null @@ -1,71 +0,0 @@ -// references/Immutable2.java -// (c)2020 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. -// A companion class to modify immutable objects - -class Mutable { - private int data; - Mutable(int initVal) { - data = initVal; - } - public Mutable add(int x) { - data += x; - return this; - } - public Mutable multiply(int x) { - data *= x; - return this; - } - public Immutable2 makeImmutable2() { - return new Immutable2(data); - } -} - -public class Immutable2 { - private int data; - public Immutable2(int initVal) { - data = initVal; - } - public int read() { return data; } - public boolean nonzero() { - return data != 0; - } - public Immutable2 add(int x) { - return new Immutable2(data + x); - } - public Immutable2 multiply(int x) { - return new Immutable2(data * x); - } - public Mutable makeMutable() { - return new Mutable(data); - } - public static - Immutable2 modify1(Immutable2 y) { - Immutable2 val = y.add(12); - val = val.multiply(3); - val = val.add(11); - val = val.multiply(2); - return val; - } - // This produces the same result: - public static - Immutable2 modify2(Immutable2 y) { - Mutable m = y.makeMutable(); - m.add(12).multiply(3).add(11).multiply(2); - return m.makeImmutable2(); - } - public static void main(String[] args) { - Immutable2 i2 = new Immutable2(47); - Immutable2 r1 = modify1(i2); - Immutable2 r2 = modify2(i2); - System.out.println("i2 = " + i2.read()); - System.out.println("r1 = " + r1.read()); - System.out.println("r2 = " + r2.read()); - } -} -/* Output: -i2 = 47 -r1 = 376 -r2 = 376 -*/ diff --git a/code/references/ImmutableInteger.java b/code/references/ImmutableInteger.java deleted file mode 100644 index 906aa7ef..00000000 --- a/code/references/ImmutableInteger.java +++ /dev/null @@ -1,22 +0,0 @@ -// references/ImmutableInteger.java -// (c)2020 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. -// The Integer class cannot be changed -import java.util.*; -import java.util.stream.*; - -public class ImmutableInteger { - public static void main(String[] args) { - @SuppressWarnings("deprecation") - List v = IntStream.range(0, 10) - .mapToObj(Integer::new) - .collect(Collectors.toList()); - System.out.println(v); - // But how do you change the int - // inside the Integer? - } -} -/* Output: -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -*/ diff --git a/code/references/ImmutableStrings.java b/code/references/ImmutableStrings.java deleted file mode 100644 index ad954e3f..00000000 --- a/code/references/ImmutableStrings.java +++ /dev/null @@ -1,25 +0,0 @@ -// references/ImmutableStrings.java -// (c)2020 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. -// Demonstrating StringBuilder - -public class ImmutableStrings { - public static void main(String[] args) { - String foo = "foo"; - String s = "abc" + foo + "def" - + Integer.toString(47); - System.out.println(s); - // The "equivalent" using StringBuilder: - StringBuilder sb = - new StringBuilder("abc"); // Creates String - sb.append(foo); - sb.append("def"); // Creates String - sb.append(Integer.toString(47)); - System.out.println(sb); - } -} -/* Output: -abcfoodef47 -abcfoodef47 -*/ diff --git a/code/references/LocalCopy.java b/code/references/LocalCopy.java deleted file mode 100644 index 9c01c09e..00000000 --- a/code/references/LocalCopy.java +++ /dev/null @@ -1,57 +0,0 @@ -// references/LocalCopy.java -// (c)2020 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. -// Creating local copies with clone() - -class Duplo implements Cloneable { - private int n; - Duplo(int n) { this.n = n; } - @Override - public Duplo clone() { // [1] - try { - return (Duplo)super.clone(); - } catch(CloneNotSupportedException e) { - throw new RuntimeException(e); - } - } - public int getValue() { return n; } - public void setValue(int n) { this.n = n; } - public void increment() { n++; } - @Override - public String toString() { - return Integer.toString(n); - } -} - -public class LocalCopy { - public static Duplo g(Duplo v) { - // Passing a reference, modifies outside object: - v.increment(); - return v; - } - public static Duplo f(Duplo v) { - v = v.clone(); // [2] Local copy - v.increment(); - return v; - } - public static void main(String[] args) { - Duplo a = new Duplo(11); - Duplo b = g(a); - // Reference equivalence, not object equivalence: - System.out.println("a == b: " + (a == b) + - "\na = " + a + "\nb = " + b); - Duplo c = new Duplo(47); - Duplo d = f(c); - System.out.println("c == d: " + (c == d) + - "\nc = " + c + "\nd = " + d); - } -} -/* Output: -a == b: true -a = 12 -b = 12 -c == d: false -c = 47 -d = 48 -*/ diff --git a/code/references/MutableInteger.java b/code/references/MutableInteger.java deleted file mode 100644 index dfe0cc7b..00000000 --- a/code/references/MutableInteger.java +++ /dev/null @@ -1,34 +0,0 @@ -// references/MutableInteger.java -// (c)2020 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. -// A changeable wrapper class -import java.util.*; -import java.util.stream.*; - -class IntValue { - private int n; - IntValue(int x) { n = x; } - public int getValue() { return n; } - public void setValue(int n) { this.n = n; } - public void increment() { n++; } - @Override - public String toString() { - return Integer.toString(n); - } -} - -public class MutableInteger { - public static void main(String[] args) { - List v = IntStream.range(0, 10) - .mapToObj(IntValue::new) - .collect(Collectors.toList()); - System.out.println(v); - v.forEach(IntValue::increment); - System.out.println(v); - } -} -/* Output: -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] -*/ diff --git a/code/references/OceanReading.java b/code/references/OceanReading.java deleted file mode 100644 index b89f1b04..00000000 --- a/code/references/OceanReading.java +++ /dev/null @@ -1,48 +0,0 @@ -// references/OceanReading.java -// (c)2020 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. -// Cloning a composed object -package references; - -public class OceanReading implements Cloneable { - private DepthReading depth; - private TemperatureReading temperature; - public - OceanReading(double tdata, double ddata) { - temperature = new TemperatureReading(tdata); - depth = new DepthReading(ddata); - } - @Override - public OceanReading clone() { - OceanReading or = null; - try { - or = (OceanReading)super.clone(); - } catch(CloneNotSupportedException e) { - throw new RuntimeException(e); - } - // Must clone references: - or.depth = (DepthReading)or.depth.clone(); - or.temperature = - (TemperatureReading)or.temperature.clone(); - return or; - } - public TemperatureReading getTemperatureReading() { - return temperature; - } - public void - setTemperatureReading(TemperatureReading tr) { - temperature = tr; - } - public DepthReading getDepthReading() { - return depth; - } - public void setDepthReading(DepthReading dr) { - this.depth = dr; - } - @Override - public String toString() { - return "temperature: " + temperature + - ", depth: " + depth; - } -} diff --git a/code/references/PassReferences.java b/code/references/PassReferences.java deleted file mode 100644 index 2a163008..00000000 --- a/code/references/PassReferences.java +++ /dev/null @@ -1,19 +0,0 @@ -// references/PassReferences.java -// (c)2020 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. - -public class PassReferences { - public static void f(PassReferences h) { - System.out.println("h inside f(): " + h); - } - public static void main(String[] args) { - PassReferences p = new PassReferences(); - System.out.println("p inside main(): " + p); - f(p); - } -} -/* Output: -p inside main(): PassReferences@15db9742 -h inside f(): PassReferences@15db9742 -*/ diff --git a/code/references/SimplerMutableInteger.java b/code/references/SimplerMutableInteger.java deleted file mode 100644 index 191068ca..00000000 --- a/code/references/SimplerMutableInteger.java +++ /dev/null @@ -1,30 +0,0 @@ -// references/SimplerMutableInteger.java -// (c)2020 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. -// A trivial wrapper class -import java.util.*; -import java.util.stream.*; - -class IntValue2 { - public int n; - IntValue2(int n) { this.n = n; } -} - -public class SimplerMutableInteger { - public static void main(String[] args) { - List v = IntStream.range(0, 10) - .mapToObj(IntValue2::new) - .collect(Collectors.toList()); - v.forEach(iv2 -> - System.out.print(iv2.n + " ")); - System.out.println(); - v.forEach(iv2 -> iv2.n += 1); - v.forEach(iv2 -> - System.out.print(iv2.n + " ")); - } -} -/* Output: -0 1 2 3 4 5 6 7 8 9 -1 2 3 4 5 6 7 8 9 10 -*/ diff --git a/code/references/Snake.java b/code/references/Snake.java deleted file mode 100644 index 004f7e76..00000000 --- a/code/references/Snake.java +++ /dev/null @@ -1,51 +0,0 @@ -// references/Snake.java -// (c)2020 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. -// Tests cloning to see if reference -// destinations are also cloned - -public class Snake implements Cloneable { - private Snake next; - private char c; - // Value of i == number of segments - public Snake(int i, char x) { - c = x; - if(--i > 0) - next = new Snake(i, (char)(x + 1)); - } - public void increment() { - c++; - if(next != null) - next.increment(); - } - @Override - public String toString() { - String s = ":" + c; - if(next != null) - s += next.toString(); - return s; - } - @Override - public Snake clone() { - try { - return (Snake)super.clone(); - } catch(CloneNotSupportedException e) { - throw new RuntimeException(e); - } - } - public static void main(String[] args) { - Snake s = new Snake(5, 'a'); - System.out.println("s = " + s); - Snake s2 = s.clone(); - System.out.println("s2 = " + s2); - s.increment(); - System.out.println( - "after s.increment, s2 = " + s2); - } -} -/* Output: -s = :a:b:c:d:e -s2 = :a:b:c:d:e -after s.increment, s2 = :a:c:d:e:f -*/ diff --git a/code/references/Stringer.java b/code/references/Stringer.java deleted file mode 100644 index 72663bb5..00000000 --- a/code/references/Stringer.java +++ /dev/null @@ -1,22 +0,0 @@ -// references/Stringer.java -// (c)2020 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. - -public class Stringer { - public static String upcase(String s) { - return s.toUpperCase(); - } - public static void main(String[] args) { - String q = new String("howdy"); - System.out.println(q); // howdy - String qq = upcase(q); - System.out.println(qq); // HOWDY - System.out.println(q); // howdy - } -} -/* Output: -howdy -HOWDY -howdy -*/ diff --git a/code/references/TemperatureReading.java b/code/references/TemperatureReading.java deleted file mode 100644 index 9b77cfb2..00000000 --- a/code/references/TemperatureReading.java +++ /dev/null @@ -1,33 +0,0 @@ -// references/TemperatureReading.java -// (c)2020 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. -// Cloning a composed object -package references; - -public class TemperatureReading implements Cloneable { - private long time; - private double temperature; - public TemperatureReading(double temperature) { - time = System.currentTimeMillis(); - this.temperature = temperature; - } - @Override - public TemperatureReading clone() { - try { - return (TemperatureReading)super.clone(); - } catch(CloneNotSupportedException e) { - throw new RuntimeException(e); - } - } - public double getTemperature() { - return temperature; - } - public void setTemperature(double temp) { - this.temperature = temp; - } - @Override - public String toString() { - return String.valueOf(temperature); - } -} diff --git a/code/references/tests/DeepCopyTest.java b/code/references/tests/DeepCopyTest.java deleted file mode 100644 index b65a8d89..00000000 --- a/code/references/tests/DeepCopyTest.java +++ /dev/null @@ -1,28 +0,0 @@ -// references/tests/DeepCopyTest.java -// (c)2020 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 references; -import org.junit.jupiter.api.*; -import static org.junit.jupiter.api.Assertions.*; - -public class DeepCopyTest { - @Test - public void testClone() { - OceanReading reading = - new OceanReading(33.9, 100.5); - // Now clone it: - OceanReading clone = reading.clone(); - TemperatureReading tr = - clone.getTemperatureReading(); - tr.setTemperature(tr.getTemperature() + 1); - clone.setTemperatureReading(tr); - DepthReading dr = clone.getDepthReading(); - dr.setDepth(dr.getDepth() + 1); - clone.setDepthReading(dr); - assertEquals(reading.toString(), - "temperature: 33.9, depth: 100.5"); - assertEquals(clone.toString(), - "temperature: 34.9, depth: 101.5"); - } -} diff --git a/code/reuse/Bath.java b/code/reuse/Bath.java deleted file mode 100644 index 38e5e819..00000000 --- a/code/reuse/Bath.java +++ /dev/null @@ -1,61 +0,0 @@ -// reuse/Bath.java -// (c)2020 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. -// Constructor initialization with composition - -class Soap { - private String s; - Soap() { - System.out.println("Soap()"); - s = "Constructed"; - } - @Override - public String toString() { return s; } -} - -public class Bath { - private String // Initializing at point of definition: - s1 = "Happy", - s2 = "Happy", - s3, s4; - private Soap castille; - private int i; - private float toy; - public Bath() { - System.out.println("Inside Bath()"); - s3 = "Joy"; - toy = 3.14f; - castille = new Soap(); - } - // Instance initialization: - { i = 47; } - @Override - public String toString() { - if(s4 == null) // Delayed initialization: - s4 = "Joy"; - return - "s1 = " + s1 + "\n" + - "s2 = " + s2 + "\n" + - "s3 = " + s3 + "\n" + - "s4 = " + s4 + "\n" + - "i = " + i + "\n" + - "toy = " + toy + "\n" + - "castille = " + castille; - } - public static void main(String[] args) { - Bath b = new Bath(); - System.out.println(b); - } -} -/* Output: -Inside Bath() -Soap() -s1 = Happy -s2 = Happy -s3 = Joy -s4 = Joy -i = 47 -toy = 3.14 -castille = Constructed -*/ diff --git a/code/reuse/Beetle.java b/code/reuse/Beetle.java deleted file mode 100644 index 0a41bc17..00000000 --- a/code/reuse/Beetle.java +++ /dev/null @@ -1,43 +0,0 @@ -// reuse/Beetle.java -// (c)2020 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. -// The full process of initialization - -class Insect { - private int i = 9; - protected int j; - Insect() { - System.out.println("i = " + i + ", j = " + j); - j = 39; - } - private static int x1 = - printInit("static Insect.x1 initialized"); - static int printInit(String s) { - System.out.println(s); - return 47; - } -} - -public class Beetle extends Insect { - private int k = printInit("Beetle.k initialized"); - public Beetle() { - System.out.println("k = " + k); - System.out.println("j = " + j); - } - private static int x2 = - printInit("static Beetle.x2 initialized"); - public static void main(String[] args) { - System.out.println("Beetle constructor"); - Beetle b = new Beetle(); - } -} -/* Output: -static Insect.x1 initialized -static Beetle.x2 initialized -Beetle constructor -i = 9, j = 0 -Beetle.k initialized -k = 47 -j = 39 -*/ diff --git a/code/reuse/BlankFinal.java b/code/reuse/BlankFinal.java deleted file mode 100644 index 93818a06..00000000 --- a/code/reuse/BlankFinal.java +++ /dev/null @@ -1,29 +0,0 @@ -// reuse/BlankFinal.java -// (c)2020 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. -// "Blank" final fields - -class Poppet { - private int i; - Poppet(int ii) { i = ii; } -} - -public class BlankFinal { - private final int i = 0; // Initialized final - private final int j; // Blank final - private final Poppet p; // Blank final reference - // Blank finals MUST be initialized in constructor: - public BlankFinal() { - j = 1; // Initialize blank final - p = new Poppet(1); // Init blank final reference - } - public BlankFinal(int x) { - j = x; // Initialize blank final - p = new Poppet(x); // Init blank final reference - } - public static void main(String[] args) { - new BlankFinal(); - new BlankFinal(47); - } -} diff --git a/code/reuse/CADSystem.java b/code/reuse/CADSystem.java deleted file mode 100644 index 55fbe0d8..00000000 --- a/code/reuse/CADSystem.java +++ /dev/null @@ -1,116 +0,0 @@ -// reuse/CADSystem.java -// (c)2020 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. -// Ensuring proper cleanup -// {java reuse.CADSystem} -package reuse; - -class Shape { - Shape(int i) { - System.out.println("Shape constructor"); - } - void dispose() { - System.out.println("Shape dispose"); - } -} - -class Circle extends Shape { - Circle(int i) { - super(i); - System.out.println("Drawing Circle"); - } - @Override - void dispose() { - System.out.println("Erasing Circle"); - super.dispose(); - } -} - -class Triangle extends Shape { - Triangle(int i) { - super(i); - System.out.println("Drawing Triangle"); - } - @Override - void dispose() { - System.out.println("Erasing Triangle"); - super.dispose(); - } -} - -class Line extends Shape { - private int start, end; - Line(int start, int end) { - super(start); - this.start = start; - this.end = end; - System.out.println( - "Drawing Line: " + start + ", " + end); - } - @Override - void dispose() { - System.out.println( - "Erasing Line: " + start + ", " + end); - super.dispose(); - } -} - -public class CADSystem extends Shape { - private Circle c; - private Triangle t; - private Line[] lines = new Line[3]; - public CADSystem(int i) { - super(i + 1); - for(int j = 0; j < lines.length; j++) - lines[j] = new Line(j, j*j); - c = new Circle(1); - t = new Triangle(1); - System.out.println("Combined constructor"); - } - @Override - public void dispose() { - System.out.println("CADSystem.dispose()"); - // The order of cleanup is the reverse - // of the order of initialization: - t.dispose(); - c.dispose(); - for(int i = lines.length - 1; i >= 0; i--) - lines[i].dispose(); - super.dispose(); - } - public static void main(String[] args) { - CADSystem x = new CADSystem(47); - try { - // Code and exception handling... - } finally { - x.dispose(); - } - } -} -/* Output: -Shape constructor -Shape constructor -Drawing Line: 0, 0 -Shape constructor -Drawing Line: 1, 1 -Shape constructor -Drawing Line: 2, 4 -Shape constructor -Drawing Circle -Shape constructor -Drawing Triangle -Combined constructor -CADSystem.dispose() -Erasing Triangle -Shape dispose -Erasing Circle -Shape dispose -Erasing Line: 2, 4 -Shape dispose -Erasing Line: 1, 1 -Shape dispose -Erasing Line: 0, 0 -Shape dispose -Shape dispose -*/ diff --git a/code/reuse/Car.java b/code/reuse/Car.java deleted file mode 100644 index 1bc4377b..00000000 --- a/code/reuse/Car.java +++ /dev/null @@ -1,43 +0,0 @@ -// reuse/Car.java -// (c)2020 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. -// Composition with public objects - -class Engine { - public void start() {} - public void rev() {} - public void stop() {} -} - -class Wheel { - public void inflate(int psi) {} -} - -class Window { - public void rollup() {} - public void rolldown() {} -} - -class Door { - public Window window = new Window(); - public void open() {} - public void close() {} -} - -public class Car { - public Engine engine = new Engine(); - public Wheel[] wheel = new Wheel[4]; - public Door - left = new Door(), - right = new Door(); // 2-door - public Car() { - for(int i = 0; i < 4; i++) - wheel[i] = new Wheel(); - } - public static void main(String[] args) { - Car car = new Car(); - car.left.window.rollup(); - car.wheel[0].inflate(72); - } -} diff --git a/code/reuse/Cartoon.java b/code/reuse/Cartoon.java deleted file mode 100644 index 48741baf..00000000 --- a/code/reuse/Cartoon.java +++ /dev/null @@ -1,31 +0,0 @@ -// reuse/Cartoon.java -// (c)2020 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. -// Constructor calls during inheritance - -class Art { - Art() { - System.out.println("Art constructor"); - } -} - -class Drawing extends Art { - Drawing() { - System.out.println("Drawing constructor"); - } -} - -public class Cartoon extends Drawing { - public Cartoon() { - System.out.println("Cartoon constructor"); - } - public static void main(String[] args) { - Cartoon x = new Cartoon(); - } -} -/* Output: -Art constructor -Drawing constructor -Cartoon constructor -*/ diff --git a/code/reuse/Chess.java b/code/reuse/Chess.java deleted file mode 100644 index 30f2685b..00000000 --- a/code/reuse/Chess.java +++ /dev/null @@ -1,33 +0,0 @@ -// reuse/Chess.java -// (c)2020 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. -// Inheritance, constructors and arguments - -class Game { - Game(int i) { - System.out.println("Game constructor"); - } -} - -class BoardGame extends Game { - BoardGame(int i) { - super(i); - System.out.println("BoardGame constructor"); - } -} - -public class Chess extends BoardGame { - Chess() { - super(11); - System.out.println("Chess constructor"); - } - public static void main(String[] args) { - Chess x = new Chess(); - } -} -/* Output: -Game constructor -BoardGame constructor -Chess constructor -*/ diff --git a/code/reuse/DerivedSpaceShip.java b/code/reuse/DerivedSpaceShip.java deleted file mode 100644 index dfbe20ac..00000000 --- a/code/reuse/DerivedSpaceShip.java +++ /dev/null @@ -1,19 +0,0 @@ -// reuse/DerivedSpaceShip.java -// (c)2020 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. - -public class -DerivedSpaceShip extends SpaceShipControls { - private String name; - public DerivedSpaceShip(String name) { - this.name = name; - } - @Override - public String toString() { return name; } - public static void main(String[] args) { - DerivedSpaceShip protector = - new DerivedSpaceShip("NSEA Protector"); - protector.forward(100); - } -} diff --git a/code/reuse/Detergent.java b/code/reuse/Detergent.java deleted file mode 100644 index 99f4e7cc..00000000 --- a/code/reuse/Detergent.java +++ /dev/null @@ -1,48 +0,0 @@ -// reuse/Detergent.java -// (c)2020 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. -// Inheritance syntax & properties - -class Cleanser { - private String s = "Cleanser"; - public void append(String a) { s += a; } - public void dilute() { append(" dilute()"); } - public void apply() { append(" apply()"); } - public void scrub() { append(" scrub()"); } - @Override - public String toString() { return s; } - public static void main(String[] args) { - Cleanser x = new Cleanser(); - x.dilute(); x.apply(); x.scrub(); - System.out.println(x); - } -} - -public class Detergent extends Cleanser { - // Change a method: - @Override - public void scrub() { - append(" Detergent.scrub()"); - super.scrub(); // Call base-class version - } - // Add methods to the interface: - public void foam() { append(" foam()"); } - // Test the new class: - public static void main(String[] args) { - Detergent x = new Detergent(); - x.dilute(); - x.apply(); - x.scrub(); - x.foam(); - System.out.println(x); - System.out.println("Testing base class:"); - Cleanser.main(args); - } -} -/* Output: -Cleanser dilute() apply() Detergent.scrub() scrub() -foam() -Testing base class: -Cleanser dilute() apply() scrub() -*/ diff --git a/code/reuse/FinalArguments.java b/code/reuse/FinalArguments.java deleted file mode 100644 index 46efed7e..00000000 --- a/code/reuse/FinalArguments.java +++ /dev/null @@ -1,27 +0,0 @@ -// reuse/FinalArguments.java -// (c)2020 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. -// Using "final" with method arguments - -class Gizmo { - public void spin() {} -} - -public class FinalArguments { - void with(final Gizmo g) { - //- g = new Gizmo(); // Illegal -- g is final - } - void without(Gizmo g) { - g = new Gizmo(); // OK -- g not final - g.spin(); - } - // void f(final int i) { i++; } // Can't change - // You can only read from a final primitive: - int g(final int i) { return i + 1; } - public static void main(String[] args) { - FinalArguments bf = new FinalArguments(); - bf.without(null); - bf.with(null); - } -} diff --git a/code/reuse/FinalData.java b/code/reuse/FinalData.java deleted file mode 100644 index 4376f5c3..00000000 --- a/code/reuse/FinalData.java +++ /dev/null @@ -1,57 +0,0 @@ -// reuse/FinalData.java -// (c)2020 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. -// The effect of final on fields -import java.util.*; - -class Value { - int i; // Package access - Value(int i) { this.i = i; } -} - -public class FinalData { - private static Random rand = new Random(47); - private String id; - public FinalData(String id) { this.id = id; } - // Can be compile-time constants: - private final int valueOne = 9; - private static final int VALUE_TWO = 99; - // Typical public constant: - public static final int VALUE_THREE = 39; - // Cannot be compile-time constants: - private final int i4 = rand.nextInt(20); - static final int INT_5 = rand.nextInt(20); - private Value v1 = new Value(11); - private final Value v2 = new Value(22); - private static final Value VAL_3 = new Value(33); - // Arrays: - private final int[] a = { 1, 2, 3, 4, 5, 6 }; - @Override - public String toString() { - return id + ": " + "i4 = " + i4 - + ", INT_5 = " + INT_5; - } - public static void main(String[] args) { - FinalData fd1 = new FinalData("fd1"); - //- fd1.valueOne++; // Error: can't change value - fd1.v2.i++; // Object isn't constant! - fd1.v1 = new Value(9); // OK -- not final - for(int i = 0; i < fd1.a.length; i++) - fd1.a[i]++; // Object isn't constant! - //- fd1.v2 = new Value(0); // Error: Can't - //- fd1.VAL_3 = new Value(1); // change reference - //- fd1.a = new int[3]; - System.out.println(fd1); - System.out.println("Creating new FinalData"); - FinalData fd2 = new FinalData("fd2"); - System.out.println(fd1); - System.out.println(fd2); - } -} -/* Output: -fd1: i4 = 15, INT_5 = 18 -Creating new FinalData -fd1: i4 = 15, INT_5 = 18 -fd2: i4 = 13, INT_5 = 18 -*/ diff --git a/code/reuse/FinalOverridingIllusion.java b/code/reuse/FinalOverridingIllusion.java deleted file mode 100644 index e5c19ece..00000000 --- a/code/reuse/FinalOverridingIllusion.java +++ /dev/null @@ -1,56 +0,0 @@ -// reuse/FinalOverridingIllusion.java -// (c)2020 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. -// It only looks like you can override -// a private or private final method - -class WithFinals { - // Identical to "private" alone: - private final void f() { - System.out.println("WithFinals.f()"); - } - // Also automatically "final": - private void g() { - System.out.println("WithFinals.g()"); - } -} - -class OverridingPrivate extends WithFinals { - private final void f() { - System.out.println("OverridingPrivate.f()"); - } - private void g() { - System.out.println("OverridingPrivate.g()"); - } -} - -class OverridingPrivate2 extends OverridingPrivate { - public final void f() { - System.out.println("OverridingPrivate2.f()"); - } - public void g() { - System.out.println("OverridingPrivate2.g()"); - } -} - -public class FinalOverridingIllusion { - public static void main(String[] args) { - OverridingPrivate2 op2 = new OverridingPrivate2(); - op2.f(); - op2.g(); - // You can upcast: - OverridingPrivate op = op2; - // But you can't call the methods: - //- op.f(); - //- op.g(); - // Same here: - WithFinals wf = op2; - //- wf.f(); - //- wf.g(); - } -} -/* Output: -OverridingPrivate2.f() -OverridingPrivate2.g() -*/ diff --git a/code/reuse/Hide.java b/code/reuse/Hide.java deleted file mode 100644 index f718e4b0..00000000 --- a/code/reuse/Hide.java +++ /dev/null @@ -1,41 +0,0 @@ -// reuse/Hide.java -// (c)2020 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. -// Overloading a base-class method name in a derived -// class does not hide the base-class versions - -class Homer { - char doh(char c) { - System.out.println("doh(char)"); - return 'd'; - } - float doh(float f) { - System.out.println("doh(float)"); - return 1.0f; - } -} - -class Milhouse {} - -class Bart extends Homer { - void doh(Milhouse m) { - System.out.println("doh(Milhouse)"); - } -} - -public class Hide { - public static void main(String[] args) { - Bart b = new Bart(); - b.doh(1); - b.doh('x'); - b.doh(1.0f); - b.doh(new Milhouse()); - } -} -/* Output: -doh(float) -doh(char) -doh(float) -doh(Milhouse) -*/ diff --git a/code/reuse/Jurassic.java b/code/reuse/Jurassic.java deleted file mode 100644 index 04b7d61c..00000000 --- a/code/reuse/Jurassic.java +++ /dev/null @@ -1,26 +0,0 @@ -// reuse/Jurassic.java -// (c)2020 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. -// Making an entire class final - -class SmallBrain {} - -final class Dinosaur { - int i = 7; - int j = 1; - SmallBrain x = new SmallBrain(); - void f() {} -} - -//- class Further extends Dinosaur {} -// error: Cannot extend final class 'Dinosaur' - -public class Jurassic { - public static void main(String[] args) { - Dinosaur n = new Dinosaur(); - n.f(); - n.i = 40; - n.j++; - } -} diff --git a/code/reuse/Lisa.java b/code/reuse/Lisa.java deleted file mode 100644 index 85ec5cc9..00000000 --- a/code/reuse/Lisa.java +++ /dev/null @@ -1,11 +0,0 @@ -// reuse/Lisa.java -// (c)2020 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. -// {WillNotCompile} - -class Lisa extends Homer { - @Override void doh(Milhouse m) { - System.out.println("doh(Milhouse)"); - } -} diff --git a/code/reuse/Orc.java b/code/reuse/Orc.java deleted file mode 100644 index c3ba40a8..00000000 --- a/code/reuse/Orc.java +++ /dev/null @@ -1,41 +0,0 @@ -// reuse/Orc.java -// (c)2020 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. -// The protected keyword - -class Villain { - private String name; - protected void set(String nm) { name = nm; } - Villain(String name) { this.name = name; } - @Override - public String toString() { - return "I'm a Villain and my name is " + name; - } -} - -public class Orc extends Villain { - private int orcNumber; - public Orc(String name, int orcNumber) { - super(name); - this.orcNumber = orcNumber; - } - public void change(String name, int orcNumber) { - set(name); // Available because it's protected - this.orcNumber = orcNumber; - } - @Override - public String toString() { - return "Orc " + orcNumber + ": " + super.toString(); - } - public static void main(String[] args) { - Orc orc = new Orc("Limburger", 12); - System.out.println(orc); - orc.change("Bob", 19); - System.out.println(orc); - } -} -/* Output: -Orc 12: I'm a Villain and my name is Limburger -Orc 19: I'm a Villain and my name is Bob -*/ diff --git a/code/reuse/PlaceSetting.java b/code/reuse/PlaceSetting.java deleted file mode 100644 index b57d6383..00000000 --- a/code/reuse/PlaceSetting.java +++ /dev/null @@ -1,82 +0,0 @@ -// reuse/PlaceSetting.java -// (c)2020 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. -// Combining composition & inheritance - -class Plate { - Plate(int i) { - System.out.println("Plate constructor"); - } -} - -class DinnerPlate extends Plate { - DinnerPlate(int i) { - super(i); - System.out.println("DinnerPlate constructor"); - } -} - -class Utensil { - Utensil(int i) { - System.out.println("Utensil constructor"); - } -} - -class Spoon extends Utensil { - Spoon(int i) { - super(i); - System.out.println("Spoon constructor"); - } -} - -class Fork extends Utensil { - Fork(int i) { - super(i); - System.out.println("Fork constructor"); - } -} - -class Knife extends Utensil { - Knife(int i) { - super(i); - System.out.println("Knife constructor"); - } -} - -// A cultural way of doing something: -class Custom { - Custom(int i) { - System.out.println("Custom constructor"); - } -} - -public class PlaceSetting extends Custom { - private Spoon sp; - private Fork frk; - private Knife kn; - private DinnerPlate pl; - public PlaceSetting(int i) { - super(i + 1); - sp = new Spoon(i + 2); - frk = new Fork(i + 3); - kn = new Knife(i + 4); - pl = new DinnerPlate(i + 5); - System.out.println("PlaceSetting constructor"); - } - public static void main(String[] args) { - PlaceSetting x = new PlaceSetting(9); - } -} -/* Output: -Custom constructor -Utensil constructor -Spoon constructor -Utensil constructor -Fork constructor -Utensil constructor -Knife constructor -Plate constructor -DinnerPlate constructor -PlaceSetting constructor -*/ diff --git a/code/reuse/SpaceShipControls.java b/code/reuse/SpaceShipControls.java deleted file mode 100644 index 6fde7086..00000000 --- a/code/reuse/SpaceShipControls.java +++ /dev/null @@ -1,14 +0,0 @@ -// reuse/SpaceShipControls.java -// (c)2020 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. - -public class SpaceShipControls { - void up(int velocity) {} - void down(int velocity) {} - void left(int velocity) {} - void right(int velocity) {} - void forward(int velocity) {} - void back(int velocity) {} - void turboBoost() {} -} diff --git a/code/reuse/SpaceShipDelegation.java b/code/reuse/SpaceShipDelegation.java deleted file mode 100644 index c31316b2..00000000 --- a/code/reuse/SpaceShipDelegation.java +++ /dev/null @@ -1,40 +0,0 @@ -// reuse/SpaceShipDelegation.java -// (c)2020 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. - -public class SpaceShipDelegation { - private String name; - private SpaceShipControls controls = - new SpaceShipControls(); - public SpaceShipDelegation(String name) { - this.name = name; - } - // Delegated methods: - public void back(int velocity) { - controls.back(velocity); - } - public void down(int velocity) { - controls.down(velocity); - } - public void forward(int velocity) { - controls.forward(velocity); - } - public void left(int velocity) { - controls.left(velocity); - } - public void right(int velocity) { - controls.right(velocity); - } - public void turboBoost() { - controls.turboBoost(); - } - public void up(int velocity) { - controls.up(velocity); - } - public static void main(String[] args) { - SpaceShipDelegation protector = - new SpaceShipDelegation("NSEA Protector"); - protector.forward(100); - } -} diff --git a/code/reuse/SprinklerSystem.java b/code/reuse/SprinklerSystem.java deleted file mode 100644 index e0ccbe66..00000000 --- a/code/reuse/SprinklerSystem.java +++ /dev/null @@ -1,41 +0,0 @@ -// reuse/SprinklerSystem.java -// (c)2020 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. -// Composition for code reuse - -class WaterSource { - private String s; - WaterSource() { - System.out.println("WaterSource()"); - s = "Constructed"; - } - @Override - public String toString() { return s; } -} - -public class SprinklerSystem { - private String valve1, valve2, valve3, valve4; - private WaterSource source = new WaterSource(); - private int i; - private float f; - @Override - public String toString() { - return - "valve1 = " + valve1 + " " + - "valve2 = " + valve2 + " " + - "valve3 = " + valve3 + " " + - "valve4 = " + valve4 + "\n" + - "i = " + i + " " + "f = " + f + " " + - "source = " + source; // [1] - } - public static void main(String[] args) { - SprinklerSystem sprinklers = new SprinklerSystem(); - System.out.println(sprinklers); - } -} -/* Output: -WaterSource() -valve1 = null valve2 = null valve3 = null valve4 = null -i = 0 f = 0.0 source = Constructed -*/ diff --git a/code/reuse/Wind.java b/code/reuse/Wind.java deleted file mode 100644 index 3e9a05f6..00000000 --- a/code/reuse/Wind.java +++ /dev/null @@ -1,22 +0,0 @@ -// reuse/Wind.java -// (c)2020 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. -// Inheritance & upcasting - -class Instrument { - public void play() {} - static void tune(Instrument i) { - // ... - i.play(); - } -} - -// Wind objects are instruments -// because they have the same interface: -public class Wind extends Instrument { - public static void main(String[] args) { - Wind flute = new Wind(); - Instrument.tune(flute); // Upcasting - } -} diff --git a/code/serialization/APerson.java b/code/serialization/APerson.java deleted file mode 100644 index 1f67eb1c..00000000 --- a/code/serialization/APerson.java +++ /dev/null @@ -1,83 +0,0 @@ -// serialization/APerson.java -// (c)2020 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. -// Use the XOM library to write and read XML -// nu.xom.Node comes from http://www.xom.nu -import nu.xom.*; -import java.io.*; -import java.util.*; - -public class APerson { - private String first, last; - public APerson(String first, String last) { - this.first = first; - this.last = last; - } - // Produce an XML Element from this APerson object: - public Element getXML() { - Element person = new Element("person"); - Element firstName = new Element("first"); - firstName.appendChild(first); - Element lastName = new Element("last"); - lastName.appendChild(last); - person.appendChild(firstName); - person.appendChild(lastName); - return person; - } - // Constructor restores a APerson from XML: - public APerson(Element person) { - first = person - .getFirstChildElement("first").getValue(); - last = person - .getFirstChildElement("last").getValue(); - } - @Override - public String toString() { - return first + " " + last; - } - // Make it human-readable: - public static void - format(OutputStream os, Document doc) - throws Exception { - Serializer serializer = - new Serializer(os,"ISO-8859-1"); - serializer.setIndent(4); - serializer.setMaxLength(60); - serializer.write(doc); - serializer.flush(); - } - public static void - main(String[] args) throws Exception { - List people = Arrays.asList( - new APerson("Dr. Bunsen", "Honeydew"), - new APerson("Gonzo", "The Great"), - new APerson("Phillip J.", "Fry")); - System.out.println(people); - Element root = new Element("people"); - for(APerson p : people) - root.appendChild(p.getXML()); - Document doc = new Document(root); - format(System.out, doc); - format(new BufferedOutputStream( - new FileOutputStream("People.xml")), doc); - } -} -/* Output: -[Dr. Bunsen Honeydew, Gonzo The Great, Phillip J. Fry] - - - - Dr. Bunsen - Honeydew - - - Gonzo - The Great - - - Phillip J. - Fry - - -*/ diff --git a/code/serialization/AStoreCADState.java b/code/serialization/AStoreCADState.java deleted file mode 100644 index 0ce8858a..00000000 --- a/code/serialization/AStoreCADState.java +++ /dev/null @@ -1,120 +0,0 @@ -// serialization/AStoreCADState.java -// (c)2020 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. -// Saving the state of a fictitious CAD system -import java.io.*; -import java.util.*; -import java.util.stream.*; - -enum Color { RED, BLUE, GREEN } - -abstract class Shape implements Serializable { - private int xPos, yPos, dimension; - private static Random rand = new Random(47); - private static int counter = 0; - public abstract void setColor(Color newColor); - public abstract Color getColor(); - Shape(int xVal, int yVal, int dim) { - xPos = xVal; - yPos = yVal; - dimension = dim; - } - public String toString() { - return getClass() + "color[" + getColor() + - "] xPos[" + xPos + "] yPos[" + yPos + - "] dim[" + dimension + "]\n"; - } - public static Shape randomFactory() { - int xVal = rand.nextInt(100); - int yVal = rand.nextInt(100); - int dim = rand.nextInt(100); - switch(counter++ % 3) { - default: - case 0: return new Circle(xVal, yVal, dim); - case 1: return new Square(xVal, yVal, dim); - case 2: return new Line(xVal, yVal, dim); - } - } -} - -class Circle extends Shape { - private static Color color = Color.RED; - Circle(int xVal, int yVal, int dim) { - super(xVal, yVal, dim); - } - public void setColor(Color newColor) { - color = newColor; - } - public Color getColor() { return color; } -} - -class Square extends Shape { - private static Color color = Color.RED; - Square(int xVal, int yVal, int dim) { - super(xVal, yVal, dim); - } - public void setColor(Color newColor) { - color = newColor; - } - public Color getColor() { return color; } -} - -class Line extends Shape { - private static Color color = Color.RED; - public static void - serializeStaticState(ObjectOutputStream os) - throws IOException { os.writeObject(color); } - public static void - deserializeStaticState(ObjectInputStream os) - throws IOException, ClassNotFoundException { - color = (Color)os.readObject(); - } - Line(int xVal, int yVal, int dim) { - super(xVal, yVal, dim); - } - public void setColor(Color newColor) { - color = newColor; - } - public Color getColor() { return color; } -} - -public class AStoreCADState { - public static void main(String[] args) { - List> shapeTypes = - Arrays.asList( - Circle.class, Square.class, Line.class); - List shapes = IntStream.range(0, 10) - .mapToObj(i -> Shape.randomFactory()) - .collect(Collectors.toList()); - // Set all the static colors to GREEN: - shapes.forEach(s -> s.setColor(Color.GREEN)); - // Save the state vector: - try( - ObjectOutputStream out = - new ObjectOutputStream( - new FileOutputStream("CADState.dat")) - ) { - out.writeObject(shapeTypes); - Line.serializeStaticState(out); - out.writeObject(shapes); - } catch(IOException e) { - throw new RuntimeException(e); - } - // Display the shapes: - System.out.println(shapes); - } -} -/* Output: -[class Circlecolor[GREEN] xPos[58] yPos[55] dim[93] -, class Squarecolor[GREEN] xPos[61] yPos[61] dim[29] -, class Linecolor[GREEN] xPos[68] yPos[0] dim[22] -, class Circlecolor[GREEN] xPos[7] yPos[88] dim[28] -, class Squarecolor[GREEN] xPos[51] yPos[89] dim[9] -, class Linecolor[GREEN] xPos[78] yPos[98] dim[61] -, class Circlecolor[GREEN] xPos[20] yPos[58] dim[16] -, class Squarecolor[GREEN] xPos[40] yPos[11] dim[22] -, class Linecolor[GREEN] xPos[4] yPos[83] dim[6] -, class Circlecolor[GREEN] xPos[75] yPos[10] dim[42] -] -*/ diff --git a/code/serialization/Alien.java b/code/serialization/Alien.java deleted file mode 100644 index d0b0f5bf..00000000 --- a/code/serialization/Alien.java +++ /dev/null @@ -1,7 +0,0 @@ -// serialization/Alien.java -// (c)2020 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. -// A serializable class -import java.io.*; -public class Alien implements Serializable {} diff --git a/code/serialization/Blip3.java b/code/serialization/Blip3.java deleted file mode 100644 index 6741298c..00000000 --- a/code/serialization/Blip3.java +++ /dev/null @@ -1,75 +0,0 @@ -// serialization/Blip3.java -// (c)2020 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. -// Reconstructing an externalizable object -import java.io.*; - -public class Blip3 implements Externalizable { - private int i; - private String s; // No initialization - public Blip3() { - System.out.println("Blip3 Constructor"); - // s, i not initialized - } - public Blip3(String x, int a) { - System.out.println("Blip3(String x, int a)"); - s = x; - i = a; - // s & i initialized only in non-no-arg constructor. - } - @Override - public String toString() { return s + i; } - @Override - public void writeExternal(ObjectOutput out) - throws IOException { - System.out.println("Blip3.writeExternal"); - // You must do this: - out.writeObject(s); - out.writeInt(i); - } - @Override - public void readExternal(ObjectInput in) - throws IOException, ClassNotFoundException { - System.out.println("Blip3.readExternal"); - // You must do this: - s = (String)in.readObject(); - i = in.readInt(); - } - public static void main(String[] args) { - System.out.println("Constructing objects:"); - Blip3 b3 = new Blip3("A String ", 47); - System.out.println(b3); - try( - ObjectOutputStream o = new ObjectOutputStream( - new FileOutputStream("Blip3.serialized")) - ) { - System.out.println("Saving object:"); - o.writeObject(b3); - } catch(IOException e) { - throw new RuntimeException(e); - } - // Now get it back: - System.out.println("Recovering b3:"); - try( - ObjectInputStream in = new ObjectInputStream( - new FileInputStream("Blip3.serialized")) - ) { - b3 = (Blip3)in.readObject(); - } catch(IOException | ClassNotFoundException e) { - throw new RuntimeException(e); - } - System.out.println(b3); - } -} -/* Output: -Constructing objects: -Blip3(String x, int a) -A String 47 -Saving object: -Blip3.writeExternal -Recovering b3: -Blip3 Constructor -Blip3.readExternal -A String 47 -*/ diff --git a/code/serialization/Blips.java b/code/serialization/Blips.java deleted file mode 100644 index 88116d84..00000000 --- a/code/serialization/Blips.java +++ /dev/null @@ -1,80 +0,0 @@ -// serialization/Blips.java -// (c)2020 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. -// Simple use of Externalizable & a pitfall -import java.io.*; - -class Blip1 implements Externalizable { - public Blip1() { - System.out.println("Blip1 Constructor"); - } - @Override - public void writeExternal(ObjectOutput out) - throws IOException { - System.out.println("Blip1.writeExternal"); - } - @Override - public void readExternal(ObjectInput in) - throws IOException, ClassNotFoundException { - System.out.println("Blip1.readExternal"); - } -} - -class Blip2 implements Externalizable { - Blip2() { - System.out.println("Blip2 Constructor"); - } - @Override - public void writeExternal(ObjectOutput out) - throws IOException { - System.out.println("Blip2.writeExternal"); - } - @Override - public void readExternal(ObjectInput in) - throws IOException, ClassNotFoundException { - System.out.println("Blip2.readExternal"); - } -} - -public class Blips { - public static void main(String[] args) { - System.out.println("Constructing objects:"); - Blip1 b1 = new Blip1(); - Blip2 b2 = new Blip2(); - try( - ObjectOutputStream o = new ObjectOutputStream( - new FileOutputStream("Blips.serialized")) - ) { - System.out.println("Saving objects:"); - o.writeObject(b1); - o.writeObject(b2); - } catch(IOException e) { - throw new RuntimeException(e); - } - // Now get them back: - System.out.println("Recovering b1:"); - try( - ObjectInputStream in = new ObjectInputStream( - new FileInputStream("Blips.serialized")) - ) { - b1 = (Blip1)in.readObject(); - } catch(IOException | ClassNotFoundException e) { - throw new RuntimeException(e); - } - // OOPS! Throws an exception: - //- System.out.println("Recovering b2:"); - //- b2 = (Blip2)in.readObject(); - } -} -/* Output: -Constructing objects: -Blip1 Constructor -Blip2 Constructor -Saving objects: -Blip1.writeExternal -Blip2.writeExternal -Recovering b1: -Blip1 Constructor -Blip1.readExternal -*/ diff --git a/code/serialization/FreezeAlien.java b/code/serialization/FreezeAlien.java deleted file mode 100644 index 0fe8e831..00000000 --- a/code/serialization/FreezeAlien.java +++ /dev/null @@ -1,19 +0,0 @@ -// serialization/FreezeAlien.java -// (c)2020 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. -// Create a serialized output file -import java.io.*; - -public class FreezeAlien { - public static void - main(String[] args) throws Exception { - try( - ObjectOutputStream out = new ObjectOutputStream( - new FileOutputStream("X.file")); - ) { - Alien quellek = new Alien(); - out.writeObject(quellek); - } - } -} diff --git a/code/serialization/Logon.java b/code/serialization/Logon.java deleted file mode 100644 index 3b910968..00000000 --- a/code/serialization/Logon.java +++ /dev/null @@ -1,62 +0,0 @@ -// serialization/Logon.java -// (c)2020 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. -// Demonstrates the "transient" keyword -import java.util.concurrent.*; -import java.io.*; -import java.util.*; -import onjava.Nap; - -public class Logon implements Serializable { - private Date date = new Date(); - private String username; - private transient String password; - public Logon(String name, String pwd) { - username = name; - password = pwd; - } - @Override - public String toString() { - return "logon info: \n username: " + - username + "\n date: " + date + - "\n password: " + password; - } - public static void main(String[] args) { - Logon a = new Logon("Hulk", "myLittlePony"); - System.out.println("logon a = " + a); - try( - ObjectOutputStream o = - new ObjectOutputStream( - new FileOutputStream("Logon.dat")) - ) { - o.writeObject(a); - } catch(IOException e) { - throw new RuntimeException(e); - } - new Nap(1); - // Now get them back: - try( - ObjectInputStream in = new ObjectInputStream( - new FileInputStream("Logon.dat")) - ) { - System.out.println( - "Recovering object at " + new Date()); - a = (Logon)in.readObject(); - } catch(IOException | ClassNotFoundException e) { - throw new RuntimeException(e); - } - System.out.println("logon a = " + a); - } -} -/* Output: -logon a = logon info: - username: Hulk - date: Tue May 09 06:07:47 MDT 2017 - password: myLittlePony -Recovering object at Tue May 09 06:07:49 MDT 2017 -logon a = logon info: - username: Hulk - date: Tue May 09 06:07:47 MDT 2017 - password: null -*/ diff --git a/code/serialization/MyWorld.java b/code/serialization/MyWorld.java deleted file mode 100644 index 99e39de3..00000000 --- a/code/serialization/MyWorld.java +++ /dev/null @@ -1,100 +0,0 @@ -// serialization/MyWorld.java -// (c)2020 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. -import java.io.*; -import java.util.*; - -class House implements Serializable {} - -class Animal implements Serializable { - private String name; - private House preferredHouse; - Animal(String nm, House h) { - name = nm; - preferredHouse = h; - } - @Override - public String toString() { - return name + "[" + super.toString() + - "], " + preferredHouse + "\n"; - } -} - -public class MyWorld { - public static void main(String[] args) { - House house = new House(); - List animals = new ArrayList<>(); - animals.add( - new Animal("Bosco the dog", house)); - animals.add( - new Animal("Ralph the hamster", house)); - animals.add( - new Animal("Molly the cat", house)); - System.out.println("animals: " + animals); - try( - ByteArrayOutputStream buf1 = - new ByteArrayOutputStream(); - ObjectOutputStream o1 = - new ObjectOutputStream(buf1) - ) { - o1.writeObject(animals); - o1.writeObject(animals); // Write a 2nd set - // Write to a different stream: - try( - ByteArrayOutputStream buf2 = - new ByteArrayOutputStream(); - ObjectOutputStream o2 = - new ObjectOutputStream(buf2) - ) { - o2.writeObject(animals); - // Now get them back: - try( - ObjectInputStream in1 = - new ObjectInputStream( - new ByteArrayInputStream( - buf1.toByteArray())); - ObjectInputStream in2 = - new ObjectInputStream( - new ByteArrayInputStream( - buf2.toByteArray())) - ) { - List - animals1 = (List)in1.readObject(), - animals2 = (List)in1.readObject(), - animals3 = (List)in2.readObject(); - System.out.println( - "animals1: " + animals1); - System.out.println( - "animals2: " + animals2); - System.out.println( - "animals3: " + animals3); - } - } - } catch(IOException | ClassNotFoundException e) { - throw new RuntimeException(e); - } - } -} -/* Output: -animals: [Bosco the dog[Animal@15db9742], -House@6d06d69c -, Ralph the hamster[Animal@7852e922], House@6d06d69c -, Molly the cat[Animal@4e25154f], House@6d06d69c -] -animals1: [Bosco the dog[Animal@7ba4f24f], -House@3b9a45b3 -, Ralph the hamster[Animal@7699a589], House@3b9a45b3 -, Molly the cat[Animal@58372a00], House@3b9a45b3 -] -animals2: [Bosco the dog[Animal@7ba4f24f], -House@3b9a45b3 -, Ralph the hamster[Animal@7699a589], House@3b9a45b3 -, Molly the cat[Animal@58372a00], House@3b9a45b3 -] -animals3: [Bosco the dog[Animal@4dd8dc3], -House@6d03e736 -, Ralph the hamster[Animal@568db2f2], House@6d03e736 -, Molly the cat[Animal@378bf509], House@6d03e736 -] -*/ diff --git a/code/serialization/People.java b/code/serialization/People.java deleted file mode 100644 index 0e588749..00000000 --- a/code/serialization/People.java +++ /dev/null @@ -1,28 +0,0 @@ -// serialization/People.java -// (c)2020 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. -// nu.xom.Node comes from http://www.xom.nu -// {RunFirst: APerson} -import nu.xom.*; -import java.io.File; -import java.util.*; - -public class People extends ArrayList { - public People(String fileName) throws Exception { - Document doc = - new Builder().build(new File(fileName)); - Elements elements = - doc.getRootElement().getChildElements(); - for(int i = 0; i < elements.size(); i++) - add(new APerson(elements.get(i))); - } - public static void - main(String[] args) throws Exception { - People p = new People("People.xml"); - System.out.println(p); - } -} -/* Output: -[Dr. Bunsen Honeydew, Gonzo The Great, Phillip J. Fry] -*/ diff --git a/code/serialization/RecoverCADState.java b/code/serialization/RecoverCADState.java deleted file mode 100644 index 612f501c..00000000 --- a/code/serialization/RecoverCADState.java +++ /dev/null @@ -1,42 +0,0 @@ -// serialization/RecoverCADState.java -// (c)2020 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. -// Restoring the state of the fictitious CAD system -// {RunFirst: AStoreCADState} -import java.io.*; -import java.util.*; - -public class RecoverCADState { - @SuppressWarnings("unchecked") - public static void main(String[] args) { - try( - ObjectInputStream in = - new ObjectInputStream( - new FileInputStream("CADState.dat")) - ) { - // Read in the same order they were written: - List> shapeTypes = - (List>)in.readObject(); - Line.deserializeStaticState(in); - List shapes = - (List)in.readObject(); - System.out.println(shapes); - } catch(IOException | ClassNotFoundException e) { - throw new RuntimeException(e); - } - } -} -/* Output: -[class Circlecolor[RED] xPos[58] yPos[55] dim[93] -, class Squarecolor[RED] xPos[61] yPos[61] dim[29] -, class Linecolor[GREEN] xPos[68] yPos[0] dim[22] -, class Circlecolor[RED] xPos[7] yPos[88] dim[28] -, class Squarecolor[RED] xPos[51] yPos[89] dim[9] -, class Linecolor[GREEN] xPos[78] yPos[98] dim[61] -, class Circlecolor[RED] xPos[20] yPos[58] dim[16] -, class Squarecolor[RED] xPos[40] yPos[11] dim[22] -, class Linecolor[GREEN] xPos[4] yPos[83] dim[6] -, class Circlecolor[RED] xPos[75] yPos[10] dim[42] -] -*/ diff --git a/code/serialization/SerialCtl.java b/code/serialization/SerialCtl.java deleted file mode 100644 index ed891633..00000000 --- a/code/serialization/SerialCtl.java +++ /dev/null @@ -1,60 +0,0 @@ -// serialization/SerialCtl.java -// (c)2020 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. -// Controlling serialization by adding your own -// writeObject() and readObject() methods -import java.io.*; - -public class SerialCtl implements Serializable { - private String a; - private transient String b; - public SerialCtl(String aa, String bb) { - a = "Not Transient: " + aa; - b = "Transient: " + bb; - } - @Override - public String toString() { return a + "\n" + b; } - private void writeObject(ObjectOutputStream stream) - throws IOException { - stream.defaultWriteObject(); - stream.writeObject(b); - } - private void readObject(ObjectInputStream stream) - throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - b = (String)stream.readObject(); - } - public static void main(String[] args) { - SerialCtl sc = new SerialCtl("Test1", "Test2"); - System.out.println("Before:\n" + sc); - try ( - ByteArrayOutputStream buf = - new ByteArrayOutputStream(); - ObjectOutputStream o = - new ObjectOutputStream(buf); - ) { - o.writeObject(sc); - // Now get it back: - try ( - ObjectInputStream in = - new ObjectInputStream( - new ByteArrayInputStream( - buf.toByteArray())); - ) { - SerialCtl sc2 = (SerialCtl)in.readObject(); - System.out.println("After:\n" + sc2); - } - } catch(IOException | ClassNotFoundException e) { - throw new RuntimeException(e); - } - } -} -/* Output: -Before: -Not Transient: Test1 -Transient: Test2 -After: -Not Transient: Test1 -Transient: Test2 -*/ diff --git a/code/serialization/Worm.java b/code/serialization/Worm.java deleted file mode 100644 index 666beb87..00000000 --- a/code/serialization/Worm.java +++ /dev/null @@ -1,102 +0,0 @@ -// serialization/Worm.java -// (c)2020 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. -// Demonstrates object serialization -import java.io.*; -import java.util.*; - -class Data implements Serializable { - private int n; - Data(int n) { this.n = n; } - @Override - public String toString() { - return Integer.toString(n); - } -} - -public class Worm implements Serializable { - private static Random rand = new Random(47); - private Data[] d = { - new Data(rand.nextInt(10)), - new Data(rand.nextInt(10)), - new Data(rand.nextInt(10)) - }; - private Worm next; - private char c; - // Value of i == number of segments - public Worm(int i, char x) { - System.out.println("Worm constructor: " + i); - c = x; - if(--i > 0) - next = new Worm(i, (char)(x + 1)); - } - public Worm() { - System.out.println("No-arg constructor"); - } - @Override - public String toString() { - StringBuilder result = new StringBuilder(":"); - result.append(c); - result.append("("); - for(Data dat : d) - result.append(dat); - result.append(")"); - if(next != null) - result.append(next); - return result.toString(); - } - public static void - main(String[] args) throws ClassNotFoundException, - IOException { - Worm w = new Worm(6, 'a'); - System.out.println("w = " + w); - try( - ObjectOutputStream out = new ObjectOutputStream( - new FileOutputStream("worm.dat")) - ) { - out.writeObject("Worm storage\n"); - out.writeObject(w); - } - try( - ObjectInputStream in = new ObjectInputStream( - new FileInputStream("worm.dat")) - ) { - String s = (String)in.readObject(); - Worm w2 = (Worm)in.readObject(); - System.out.println(s + "w2 = " + w2); - } - try( - ByteArrayOutputStream bout = - new ByteArrayOutputStream(); - ObjectOutputStream out2 = - new ObjectOutputStream(bout) - ) { - out2.writeObject("Worm storage\n"); - out2.writeObject(w); - out2.flush(); - try( - ObjectInputStream in2 = new ObjectInputStream( - new ByteArrayInputStream( - bout.toByteArray())) - ) { - String s = (String)in2.readObject(); - Worm w3 = (Worm)in2.readObject(); - System.out.println(s + "w3 = " + w3); - } - } - } -} -/* Output: -Worm constructor: 6 -Worm constructor: 5 -Worm constructor: 4 -Worm constructor: 3 -Worm constructor: 2 -Worm constructor: 1 -w = :a(853):b(119):c(802):d(788):e(199):f(881) -Worm storage -w2 = :a(853):b(119):c(802):d(788):e(199):f(881) -Worm storage -w3 = :a(853):b(119):c(802):d(788):e(199):f(881) -*/ diff --git a/code/serialization/xfiles/ThawAlien.java b/code/serialization/xfiles/ThawAlien.java deleted file mode 100644 index 1de6ce6a..00000000 --- a/code/serialization/xfiles/ThawAlien.java +++ /dev/null @@ -1,22 +0,0 @@ -// serialization/xfiles/ThawAlien.java -// (c)2020 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. -// Recover a serialized file -// {java serialization.xfiles.ThawAlien} -// {RunFirst: FreezeAlien} -package serialization.xfiles; -import java.io.*; - -public class ThawAlien { - public static void - main(String[] args) throws Exception { - ObjectInputStream in = new ObjectInputStream( - new FileInputStream(new File("X.file"))); - Object mystery = in.readObject(); - System.out.println(mystery.getClass()); - } -} -/* Output: -class Alien -*/ diff --git a/code/settings.gradle b/code/settings.gradle deleted file mode 100644 index 376ca105..00000000 --- a/code/settings.gradle +++ /dev/null @@ -1,13 +0,0 @@ -def isSubproject = { File file -> - file.isDirectory() && - !file.name.contains('.git') && - !file.name.contains('.gradle') && - !file.name.contains('.idea') && - !file.name.contains('build') && - !file.name.contains('gradle') && - !file.name.contains('test') -} - -String[] subprojects = rootDir.listFiles().findAll(isSubproject).collect { it.name } - -include subprojects diff --git a/code/standardio/ChangeSystemOut.java b/code/standardio/ChangeSystemOut.java deleted file mode 100644 index 2b37acb8..00000000 --- a/code/standardio/ChangeSystemOut.java +++ /dev/null @@ -1,17 +0,0 @@ -// standardio/ChangeSystemOut.java -// (c)2020 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. -// Turn System.out into a PrintWriter -import java.io.*; - -public class ChangeSystemOut { - public static void main(String[] args) { - PrintWriter out = - new PrintWriter(System.out, true); - out.println("Hello, world"); - } -} -/* Output: -Hello, world -*/ diff --git a/code/standardio/Echo.java b/code/standardio/Echo.java deleted file mode 100644 index d1a6103e..00000000 --- a/code/standardio/Echo.java +++ /dev/null @@ -1,20 +0,0 @@ -// standardio/Echo.java -// (c)2020 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. -// How to read from standard input -import java.io.*; -import onjava.TimedAbort; - -public class Echo { - public static void main(String[] args) { - TimedAbort abort = new TimedAbort(2); - new BufferedReader( - new InputStreamReader(System.in)) - .lines() - .peek(ln -> abort.restart()) - .forEach(System.out::println); - // Ctrl-Z or two seconds inactivity - // terminates the program - } -} diff --git a/code/standardio/OSExecuteDemo.java b/code/standardio/OSExecuteDemo.java deleted file mode 100644 index cc2fd4b0..00000000 --- a/code/standardio/OSExecuteDemo.java +++ /dev/null @@ -1,16 +0,0 @@ -// standardio/OSExecuteDemo.java -// (c)2020 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. -// Demonstrates standard I/O redirection -// javap -cp build/classes/java/main OSExecuteDemo -// {ExcludeFromGradle} -import onjava.*; - -public class OSExecuteDemo {} -/* Output: -Compiled from "OSExecuteDemo.java" -public class OSExecuteDemo { - public OSExecuteDemo(); -} -*/ diff --git a/code/standardio/Redirecting.java b/code/standardio/Redirecting.java deleted file mode 100644 index c2986a2b..00000000 --- a/code/standardio/Redirecting.java +++ /dev/null @@ -1,31 +0,0 @@ -// standardio/Redirecting.java -// (c)2020 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. -// Demonstrates standard I/O redirection -import java.io.*; - -public class Redirecting { - public static void main(String[] args) { - PrintStream console = System.out; - try( - BufferedInputStream in = new BufferedInputStream( - new FileInputStream("Redirecting.java")); - PrintStream out = new PrintStream( - new BufferedOutputStream( - new FileOutputStream("Redirecting.txt"))) - ) { - System.setIn(in); - System.setOut(out); - System.setErr(out); - new BufferedReader( - new InputStreamReader(System.in)) - .lines() - .forEach(System.out::println); - } catch(IOException e) { - throw new RuntimeException(e); - } finally { - System.setOut(console); - } - } -} diff --git a/code/staticchecking/DogsAndRobots.cpp b/code/staticchecking/DogsAndRobots.cpp deleted file mode 100644 index 03b69a96..00000000 --- a/code/staticchecking/DogsAndRobots.cpp +++ /dev/null @@ -1,33 +0,0 @@ -// staticchecking/DogsAndRobots.cpp -// (c)2020 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. -#include -using namespace std; - -class Dog { -public: - void talk() { cout << "Arf!" << endl; } - void reproduce() {} -}; - -class Robot { -public: - void talk() { cout << "Click!" << endl; } - void oilChange() {} -}; - -template void speak(T speaker) { - speaker.talk(); -} - -int main() { - Dog d; - Robot r; - speak(d); - speak(r); -} -/* Output: -Arf! -Click! -*/ diff --git a/code/staticchecking/DogsAndRobots.py b/code/staticchecking/DogsAndRobots.py deleted file mode 100644 index a6b239da..00000000 --- a/code/staticchecking/DogsAndRobots.py +++ /dev/null @@ -1,26 +0,0 @@ -# staticchecking/DogsAndRobots.py -# (c)2020 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. - -def speak(anything): - anything.talk() - -class Dog: - def talk(self): print("Arf!") - def reproduce(self): pass - -class Robot: - def talk(self): print("Click!") - def oilChange(self): pass - -a = Dog() -b = Robot() - -speak(a) -speak(b) - -output = """ -Arf! -Click! -""" diff --git a/code/staticchecking/NoBasePetSpeak.py b/code/staticchecking/NoBasePetSpeak.py deleted file mode 100644 index cbe6c82b..00000000 --- a/code/staticchecking/NoBasePetSpeak.py +++ /dev/null @@ -1,35 +0,0 @@ -# staticchecking/NoBasePetSpeak.py -# (c)2020 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. -#- Speaking pets without base classes - -class Cat: - def speak(self): - print("meow!") - -class Dog: - def speak(self): - print("woof!") - -class Bob: - def bow(self): - print("thank you, thank you!") - def speak(self): - print("Welcome to the neighborhood!") - def drive(self): - print("beep, beep!") - -def command(pet): - pet.speak() - -pets = [ Cat(), Dog(), Bob() ] - -for pet in pets: - command(pet) - -output = """ -meow! -woof! -Welcome to the neighborhood! -""" diff --git a/code/staticchecking/PetSpeak.py b/code/staticchecking/PetSpeak.py deleted file mode 100644 index e3734e2f..00000000 --- a/code/staticchecking/PetSpeak.py +++ /dev/null @@ -1,28 +0,0 @@ -# staticchecking/PetSpeak.py -# (c)2020 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. -#- Speaking pets in Python - -class Pet: - def speak(self): pass - -class Cat(Pet): - def speak(self): - print("meow!") - -class Dog(Pet): - def speak(self): - print("woof!") - -def command(pet): - pet.speak() - -pets = [ Cat(), Dog() ] # (1) -for pet in pets: # (2) - command(pet) - -output = """ -meow! -woof! -""" diff --git a/code/staticchecking/dogsandrobots.go b/code/staticchecking/dogsandrobots.go deleted file mode 100644 index d3dd10cb..00000000 --- a/code/staticchecking/dogsandrobots.go +++ /dev/null @@ -1,27 +0,0 @@ -// staticchecking/dogsandrobots.go -// (c)2020 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 main -import "fmt" - -type Dog struct {} -func (this Dog) talk() { fmt.Printf("woof!\n")} -func (this Dog) reproduce() {} - -type Robot struct {} -func (this Robot) talk() { fmt.Printf("Click!\n") } -func (this Robot) oilChange() {} - -func speak(speaker interface { talk() }) { - speaker.talk(); -} - -func main() { - speak(Dog{}) - speak(Robot{}) -} -/* Output: -woof! -Click! -*/ diff --git a/code/staticchecking/dr/DogsAndRobots.java b/code/staticchecking/dr/DogsAndRobots.java deleted file mode 100644 index 9bede804..00000000 --- a/code/staticchecking/dr/DogsAndRobots.java +++ /dev/null @@ -1,42 +0,0 @@ -// staticchecking/dr/DogsAndRobots.java -// (c)2020 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. -// {java staticchecking.dr.DogsAndRobots} -package staticchecking.dr; - -interface Speaks { void talk(); } - -class Dog implements Speaks { - public void talk() { - System.out.println("Woof!"); - } - public void reproduce() { } -} - -class Robot implements Speaks { - public void talk() { - System.out.println("Click!"); - } - public void oilChange() { } -} - -class Communicate { - public static - void speak(T speaker) { - speaker.talk(); - } -} - -public class DogsAndRobots { - public static void main(String[] args) { - Dog d = new Dog(); - Robot r = new Robot(); - Communicate.speak(d); - Communicate.speak(r); - } -} -/* Output: -Woof! -Click! -*/ diff --git a/code/staticchecking/drc/DogAndRobotCollections.java b/code/staticchecking/drc/DogAndRobotCollections.java deleted file mode 100644 index 16a82ed5..00000000 --- a/code/staticchecking/drc/DogAndRobotCollections.java +++ /dev/null @@ -1,58 +0,0 @@ -// staticchecking/drc/DogAndRobotCollections.java -// (c)2020 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. -// {java staticchecking.drc.DogAndRobotCollections} -package staticchecking.drc; -import java.util.*; - -class Dog { - public void talk() { - System.out.println("Woof!"); - } - public void reproduce() { } -} - -class Robot { - public void talk() { - System.out.println("Click!"); - } - public void oilChange() { } -} - -public class DogAndRobotCollections { - public static void main(String[] args) { - List dogList = new ArrayList<>(); - List robotList = new ArrayList<>(); - for(int i = 0; i < 10; i++) - dogList.add(new Dog()); - //- dogList.add(new Robot()); // Compile-time error - for(int i = 0; i < 10; i++) - robotList.add(new Robot()); - //- robotList.add(new Dog()); // Compile-time error - dogList.forEach(Dog::talk); - robotList.forEach(Robot::talk); - } -} -/* Output: -Woof! -Woof! -Woof! -Woof! -Woof! -Woof! -Woof! -Woof! -Woof! -Woof! -Click! -Click! -Click! -Click! -Click! -Click! -Click! -Click! -Click! -Click! -*/ diff --git a/code/staticchecking/latent/Latent.java b/code/staticchecking/latent/Latent.java deleted file mode 100644 index 29e53713..00000000 --- a/code/staticchecking/latent/Latent.java +++ /dev/null @@ -1,60 +0,0 @@ -// staticchecking/latent/Latent.java -// (c)2020 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. -// {java staticchecking.latent.Latent} -package staticchecking.latent; -import java.lang.reflect.*; - -class Dog { - public void talk() { - System.out.println("Woof!"); - } - public void reproduce() {} -} - -class Robot { - public void talk() { - System.out.println("Click!"); - } - public void oilChange() {} -} - -class Mime { - public void walkAgainstTheWind() {} - public String toString() { return "Mime"; } -} - -class Communicate { - public static void speak(Object speaker) { - try { - Class spkr = - speaker.getClass(); - Method talk = - spkr.getMethod("talk", (Class[])null); - talk.invoke(speaker, new Object[]{}); - } catch(NoSuchMethodException e) { - System.out.println( - speaker + " cannot talk"); - } catch(IllegalAccessException e) { - System.out.println( - speaker + " IllegalAccessException"); - } catch(InvocationTargetException e) { - System.out.println( - speaker + " InvocationTargetException"); - } - } -} - -public class Latent { - public static void main(String[] args) { - Communicate.speak(new Dog()); - Communicate.speak(new Robot()); - Communicate.speak(new Mime()); - } -} -/* Output: -Woof! -Click! -Mime cannot talk -*/ diff --git a/code/staticchecking/petspeak.go b/code/staticchecking/petspeak.go deleted file mode 100644 index 1d5c5e46..00000000 --- a/code/staticchecking/petspeak.go +++ /dev/null @@ -1,51 +0,0 @@ -// staticchecking/petspeak.go -// (c)2020 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 main -import "fmt" - -type Cat struct {} -func (this Cat) speak() { fmt.Printf("meow!\n")} - -type Dog struct {} -func (this Dog) speak() { fmt.Printf("woof!\n")} - -type Bob struct {} -func (this Bob) bow() { - fmt.Printf("thank you, thank you!\n") -} -func (this Bob) speak() { - fmt.Printf("Welcome to the neighborhood!\n") -} -func (this Bob) drive() { - fmt.Printf("beep, beep!\n") -} - -type Speaker interface { - speak() -} - -func command(s Speaker) { s.speak() } - -// If "Speaker" is never used -// anywhere else, it can be anonymous: -func command2(s interface { speak() }) { s.speak() } - -func main() { - command(Cat{}) - command(Dog{}) - command(Bob{}) - command2(Cat{}) - command2(Dog{}) - command2(Bob{}) -} - -/* Output: -meow! -woof! -Welcome to the neighborhood! -meow! -woof! -Welcome to the neighborhood! -*/ diff --git a/code/staticchecking/petspeak/PetSpeak.java b/code/staticchecking/petspeak/PetSpeak.java deleted file mode 100644 index 0b850c3b..00000000 --- a/code/staticchecking/petspeak/PetSpeak.java +++ /dev/null @@ -1,36 +0,0 @@ -// staticchecking/petspeak/PetSpeak.java -// (c)2020 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. -// Speaking pets in Java -// {java staticchecking.petspeak.PetSpeak} -package staticchecking.petspeak; - -interface Pet { - void speak(); -} - -class Cat implements Pet { - public void speak() { - System.out.println("meow!"); - } -} - -class Dog implements Pet { - public void speak() { - System.out.println("woof!"); - } -} - -public class PetSpeak { - static void command(Pet p) { p.speak(); } - public static void main(String[] args) { - Pet[] pets = { new Cat(), new Dog() }; - for(Pet pet : pets) - command(pet); - } -} -/* Output: -meow! -woof! -*/ diff --git a/code/streams/ArrayStreams.java b/code/streams/ArrayStreams.java deleted file mode 100644 index dfed6e83..00000000 --- a/code/streams/ArrayStreams.java +++ /dev/null @@ -1,31 +0,0 @@ -// streams/ArrayStreams.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; - -public class ArrayStreams { - public static void main(String[] args) { - Arrays.stream( - new double[] { 3.14159, 2.718, 1.618 }) - .forEach(n -> System.out.format("%f ", n)); - System.out.println(); - Arrays.stream(new int[] { 1, 3, 5 }) - .forEach(n -> System.out.format("%d ", n)); - System.out.println(); - Arrays.stream(new long[] { 11, 22, 44, 66 }) - .forEach(n -> System.out.format("%d ", n)); - System.out.println(); - // Select a subrange: - Arrays.stream( - new int[] { 1, 3, 5, 7, 15, 28, 37 }, 3, 6) - .forEach(n -> System.out.format("%d ", n)); - } -} -/* Output: -3.141590 2.718000 1.618000 -1 3 5 -11 22 44 66 -7 15 28 -*/ diff --git a/code/streams/Bubble.java b/code/streams/Bubble.java deleted file mode 100644 index 5650e5ae..00000000 --- a/code/streams/Bubble.java +++ /dev/null @@ -1,18 +0,0 @@ -// streams/Bubble.java -// (c)2020 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. -import java.util.function.*; - -public class Bubble { - public final int i; - public Bubble(int n) { i = n; } - @Override - public String toString() { - return "Bubble(" + i + ")"; - } - private static int count = 0; - public static Bubble bubbler() { - return new Bubble(count++); - } -} diff --git a/code/streams/Bubbles.java b/code/streams/Bubbles.java deleted file mode 100644 index 1b3bd2b9..00000000 --- a/code/streams/Bubbles.java +++ /dev/null @@ -1,20 +0,0 @@ -// streams/Bubbles.java -// (c)2020 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. -import java.util.stream.*; - -public class Bubbles { - public static void main(String[] args) { - Stream.generate(Bubble::bubbler) - .limit(5) - .forEach(System.out::println); - } -} -/* Output: -Bubble(0) -Bubble(1) -Bubble(2) -Bubble(3) -Bubble(4) -*/ diff --git a/code/streams/Cheese.dat b/code/streams/Cheese.dat deleted file mode 100644 index 936666ed..00000000 --- a/code/streams/Cheese.dat +++ /dev/null @@ -1,6 +0,0 @@ -// streams/Cheese.dat -Not much of a cheese shop really, is it? -Finest in the district, sir. -And what leads you to that conclusion? -Well, it's so clean. -It's certainly uncontaminated by cheese. diff --git a/code/streams/CollectionToStream.java b/code/streams/CollectionToStream.java deleted file mode 100644 index 93236ef1..00000000 --- a/code/streams/CollectionToStream.java +++ /dev/null @@ -1,39 +0,0 @@ -// streams/CollectionToStream.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; - -public class CollectionToStream { - public static void main(String[] args) { - List bubbles = Arrays.asList( - new Bubble(1), new Bubble(2), new Bubble(3)); - System.out.println( - bubbles.stream() - .mapToInt(b -> b.i) - .sum()); - - Set w = new HashSet<>(Arrays.asList( - "It's a wonderful day for pie!".split(" "))); - w.stream() - .map(x -> x + " ") - .forEach(System.out::print); - System.out.println(); - - Map m = new HashMap<>(); - m.put("pi", 3.14159); - m.put("e", 2.718); - m.put("phi", 1.618); - m.entrySet().stream() - .map(e -> e.getKey() + ": " + e.getValue()) - .forEach(System.out::println); - } -} -/* Output: -6 -a pie! It's for wonderful day -phi: 1.618 -e: 2.718 -pi: 3.14159 -*/ diff --git a/code/streams/CreatingOptionals.java b/code/streams/CreatingOptionals.java deleted file mode 100644 index 7e886ddc..00000000 --- a/code/streams/CreatingOptionals.java +++ /dev/null @@ -1,37 +0,0 @@ -// streams/CreatingOptionals.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import java.util.function.*; - -class CreatingOptionals { - static void - test(String testName, Optional opt) { - System.out.println(" === " + testName + " === "); - System.out.println(opt.orElse("Null")); - } - public static void main(String[] args) { - test("empty", Optional.empty()); - test("of", Optional.of("Howdy")); - try { - test("of", Optional.of(null)); - } catch(Exception e) { - System.out.println(e); - } - test("ofNullable", Optional.ofNullable("Hi")); - test("ofNullable", Optional.ofNullable(null)); - } -} -/* Output: - === empty === -Null - === of === -Howdy -java.lang.NullPointerException - === ofNullable === -Hi - === ofNullable === -Null -*/ diff --git a/code/streams/Duplicator.java b/code/streams/Duplicator.java deleted file mode 100644 index 267279c7..00000000 --- a/code/streams/Duplicator.java +++ /dev/null @@ -1,18 +0,0 @@ -// streams/Duplicator.java -// (c)2020 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. -import java.util.stream.*; - -public class Duplicator { - public static void main(String[] args) { - Stream.generate(() -> "duplicate") - .limit(3) - .forEach(System.out::println); - } -} -/* Output: -duplicate -duplicate -duplicate -*/ diff --git a/code/streams/Fibonacci.java b/code/streams/Fibonacci.java deleted file mode 100644 index fa53c687..00000000 --- a/code/streams/Fibonacci.java +++ /dev/null @@ -1,34 +0,0 @@ -// streams/Fibonacci.java -// (c)2020 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. -import java.util.stream.*; - -public class Fibonacci { - int x = 1; - Stream numbers() { - return Stream.iterate(0, i -> { - int result = x + i; - x = i; - return result; - }); - } - public static void main(String[] args) { - new Fibonacci().numbers() - .skip(20) // Don't use the first 20 - .limit(10) // Then take 10 of them - .forEach(System.out::println); - } -} -/* Output: -6765 -10946 -17711 -28657 -46368 -75025 -121393 -196418 -317811 -514229 -*/ diff --git a/code/streams/FileToWords.java b/code/streams/FileToWords.java deleted file mode 100644 index 7f7174cb..00000000 --- a/code/streams/FileToWords.java +++ /dev/null @@ -1,17 +0,0 @@ -// streams/FileToWords.java -// (c)2020 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. -import java.nio.file.*; -import java.util.stream.*; -import java.util.regex.Pattern; - -public class FileToWords { - public static Stream stream(String filePath) - throws Exception { - return Files.lines(Paths.get(filePath)) - .skip(1) // First (comment) line - .flatMap(line -> - Pattern.compile("\\W+").splitAsStream(line)); - } -} diff --git a/code/streams/FileToWordsBuilder.java b/code/streams/FileToWordsBuilder.java deleted file mode 100644 index d5ac62be..00000000 --- a/code/streams/FileToWordsBuilder.java +++ /dev/null @@ -1,31 +0,0 @@ -// streams/FileToWordsBuilder.java -// (c)2020 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. -import java.io.*; -import java.nio.file.*; -import java.util.stream.*; - -public class FileToWordsBuilder { - Stream.Builder builder = Stream.builder(); - public FileToWordsBuilder(String filePath) - throws Exception { - Files.lines(Paths.get(filePath)) - .skip(1) // Skip the comment line at the beginning - .forEach(line -> { - for(String w : line.split("[ .?,]+")) - builder.add(w); - }); - } - Stream stream() { return builder.build(); } - public static void - main(String[] args) throws Exception { - new FileToWordsBuilder("Cheese.dat").stream() - .limit(7) - .map(w -> w + " ") - .forEach(System.out::print); - } -} -/* Output: -Not much of a cheese shop really -*/ diff --git a/code/streams/FileToWordsRegexp.java b/code/streams/FileToWordsRegexp.java deleted file mode 100644 index dfff507e..00000000 --- a/code/streams/FileToWordsRegexp.java +++ /dev/null @@ -1,39 +0,0 @@ -// streams/FileToWordsRegexp.java -// (c)2020 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. -import java.io.*; -import java.nio.file.*; -import java.util.stream.*; -import java.util.regex.Pattern; - -public class FileToWordsRegexp { - private String all; - public FileToWordsRegexp(String filePath) - throws Exception { - all = Files.lines(Paths.get(filePath)) - .skip(1) // First (comment) line - .collect(Collectors.joining(" ")); - } - public Stream stream() { - return Pattern - .compile("[ .,?]+").splitAsStream(all); - } - public static void - main(String[] args) throws Exception { - FileToWordsRegexp fw = - new FileToWordsRegexp("Cheese.dat"); - fw.stream() - .limit(7) - .map(w -> w + " ") - .forEach(System.out::print); - fw.stream() - .skip(7) - .limit(2) - .map(w -> w + " ") - .forEach(System.out::print); - } -} -/* Output: -Not much of a cheese shop really is it -*/ diff --git a/code/streams/FileToWordsTest.java b/code/streams/FileToWordsTest.java deleted file mode 100644 index a81f7209..00000000 --- a/code/streams/FileToWordsTest.java +++ /dev/null @@ -1,23 +0,0 @@ -// streams/FileToWordsTest.java -// (c)2020 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. -import java.util.stream.*; - -public class FileToWordsTest { - public static void - main(String[] args) throws Exception { - FileToWords.stream("Cheese.dat") - .limit(7) - .forEach(s -> System.out.format("%s ", s)); - System.out.println(); - FileToWords.stream("Cheese.dat") - .skip(7) - .limit(2) - .forEach(s -> System.out.format("%s ", s)); - } -} -/* Output: -Not much of a cheese shop really -is it -*/ diff --git a/code/streams/FlatMap.java b/code/streams/FlatMap.java deleted file mode 100644 index e2b3137f..00000000 --- a/code/streams/FlatMap.java +++ /dev/null @@ -1,25 +0,0 @@ -// streams/FlatMap.java -// (c)2020 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. -import java.util.stream.*; - -public class FlatMap { - public static void main(String[] args) { - Stream.of(1, 2, 3) - .flatMap( - i -> Stream.of("Gonzo", "Fozzie", "Beaker")) - .forEach(System.out::println); - } -} -/* Output: -Gonzo -Fozzie -Beaker -Gonzo -Fozzie -Beaker -Gonzo -Fozzie -Beaker -*/ diff --git a/code/streams/ForEach.java b/code/streams/ForEach.java deleted file mode 100644 index f0abe255..00000000 --- a/code/streams/ForEach.java +++ /dev/null @@ -1,28 +0,0 @@ -// streams/ForEach.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import static streams.RandInts.*; - -public class ForEach { - static final int SZ = 14; - public static void main(String[] args) { - rands().limit(SZ) - .forEach(n -> System.out.format("%d ", n)); - System.out.println(); - rands().limit(SZ) - .parallel() - .forEach(n -> System.out.format("%d ", n)); - System.out.println(); - rands().limit(SZ) - .parallel() - .forEachOrdered(n -> System.out.format("%d ", n)); - } -} -/* Output: -258 555 693 861 961 429 868 200 522 207 288 128 551 589 -551 861 429 589 200 522 555 693 258 128 868 288 961 207 -258 555 693 861 961 429 868 200 522 207 288 128 551 589 -*/ diff --git a/code/streams/FunctionMap.java b/code/streams/FunctionMap.java deleted file mode 100644 index 3c7c90e7..00000000 --- a/code/streams/FunctionMap.java +++ /dev/null @@ -1,60 +0,0 @@ -// streams/FunctionMap.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import java.util.function.*; - -class FunctionMap { - static String[] elements = { "12", "", "23", "45" }; - static Stream testStream() { - return Arrays.stream(elements); - } - static void - test(String descr, Function func) { - System.out.println(" ---( " + descr + " )---"); - testStream() - .map(func) - .forEach(System.out::println); - } - public static void main(String[] args) { - - test("add brackets", s -> "[" + s + "]"); - - test("Increment", s -> { - try { - return Integer.parseInt(s) + 1 + ""; - } catch(NumberFormatException e) { - return s; - } - }); - - test("Replace", s -> s.replace("2", "9")); - - test("Take last digit", s -> s.length() > 0 ? - s.charAt(s.length() - 1) + "" : s); - } -} -/* Output: - ---( add brackets )--- -[12] -[] -[23] -[45] - ---( Increment )--- -13 - -24 -46 - ---( Replace )--- -19 - -93 -45 - ---( Take last digit )--- -2 - -3 -5 -*/ diff --git a/code/streams/FunctionMap2.java b/code/streams/FunctionMap2.java deleted file mode 100644 index 4d9f2972..00000000 --- a/code/streams/FunctionMap2.java +++ /dev/null @@ -1,32 +0,0 @@ -// streams/FunctionMap2.java -// (c)2020 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. -// Different input and output types -import java.util.*; -import java.util.stream.*; - -class Numbered { - final int n; - Numbered(int n) { this.n = n; } - @Override - public String toString() { - return "Numbered(" + n + ")"; - } -} - -class FunctionMap2 { - public static void main(String[] args) { - Stream.of(1, 5, 7, 9, 11, 13) - .map(Numbered::new) - .forEach(System.out::println); - } -} -/* Output: -Numbered(1) -Numbered(5) -Numbered(7) -Numbered(9) -Numbered(11) -Numbered(13) -*/ diff --git a/code/streams/FunctionMap3.java b/code/streams/FunctionMap3.java deleted file mode 100644 index 74236af3..00000000 --- a/code/streams/FunctionMap3.java +++ /dev/null @@ -1,28 +0,0 @@ -// streams/FunctionMap3.java -// (c)2020 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. -// Producing numeric output streams -import java.util.*; -import java.util.stream.*; - -class FunctionMap3 { - public static void main(String[] args) { - Stream.of("5", "7", "9") - .mapToInt(Integer::parseInt) - .forEach(n -> System.out.format("%d ", n)); - System.out.println(); - Stream.of("17", "19", "23") - .mapToLong(Long::parseLong) - .forEach(n -> System.out.format("%d ", n)); - System.out.println(); - Stream.of("17", "1.9", ".23") - .mapToDouble(Double::parseDouble) - .forEach(n -> System.out.format("%f ", n)); - } -} -/* Output: -5 7 9 -17 19 23 -17.000000 1.900000 0.230000 -*/ diff --git a/code/streams/Generator.java b/code/streams/Generator.java deleted file mode 100644 index c9aba740..00000000 --- a/code/streams/Generator.java +++ /dev/null @@ -1,25 +0,0 @@ -// streams/Generator.java -// (c)2020 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. -import java.util.*; -import java.util.function.*; -import java.util.stream.*; - -public class Generator implements Supplier { - Random rand = new Random(47); - char[] letters = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); - public String get() { - return "" + letters[rand.nextInt(letters.length)]; - } - public static void main(String[] args) { - String word = Stream.generate(new Generator()) - .limit(30) - .collect(Collectors.joining()); - System.out.println(word); - } -} -/* Output: -YNZBRNYGCFOWZNTCQRGSEGZMMJMROE -*/ diff --git a/code/streams/ImperativeRandoms.java b/code/streams/ImperativeRandoms.java deleted file mode 100644 index f9baaca5..00000000 --- a/code/streams/ImperativeRandoms.java +++ /dev/null @@ -1,21 +0,0 @@ -// streams/ImperativeRandoms.java -// (c)2020 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. -import java.util.*; - -public class ImperativeRandoms { - public static void main(String[] args) { - Random rand = new Random(47); - SortedSet rints = new TreeSet<>(); - while(rints.size() < 7) { - int r = rand.nextInt(20); - if(r < 5) continue; - rints.add(r); - } - System.out.println(rints); - } -} -/* Output: -[7, 8, 9, 11, 13, 15, 18] -*/ diff --git a/code/streams/Informational.java b/code/streams/Informational.java deleted file mode 100644 index dd80585c..00000000 --- a/code/streams/Informational.java +++ /dev/null @@ -1,27 +0,0 @@ -// streams/Informational.java -// (c)2020 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. -import java.util.stream.*; -import java.util.function.*; - -public class Informational { - public static void - main(String[] args) throws Exception { - System.out.println( - FileToWords.stream("Cheese.dat").count()); - System.out.println( - FileToWords.stream("Cheese.dat") - .min(String.CASE_INSENSITIVE_ORDER) - .orElse("NONE")); - System.out.println( - FileToWords.stream("Cheese.dat") - .max(String.CASE_INSENSITIVE_ORDER) - .orElse("NONE")); - } -} -/* Output: -32 -a -you -*/ diff --git a/code/streams/LastElement.java b/code/streams/LastElement.java deleted file mode 100644 index 398b0488..00000000 --- a/code/streams/LastElement.java +++ /dev/null @@ -1,24 +0,0 @@ -// streams/LastElement.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; - -public class LastElement { - public static void main(String[] args) { - OptionalInt last = IntStream.range(10, 20) - .reduce((n1, n2) -> n2); - System.out.println(last.orElse(-1)); - // Non-numeric object: - Optional lastobj = - Stream.of("one", "two", "three") - .reduce((n1, n2) -> n2); - System.out.println( - lastobj.orElse("Nothing there!")); - } -} -/* Output: -19 -three -*/ diff --git a/code/streams/Looping.java b/code/streams/Looping.java deleted file mode 100644 index 715ad052..00000000 --- a/code/streams/Looping.java +++ /dev/null @@ -1,20 +0,0 @@ -// streams/Looping.java -// (c)2020 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. -import static onjava.Repeat.*; - -public class Looping { - static void hi() { System.out.println("Hi!"); } - public static void main(String[] args) { - repeat(3, () -> System.out.println("Looping!")); - repeat(2, Looping::hi); - } -} -/* Output: -Looping! -Looping! -Looping! -Hi! -Hi! -*/ diff --git a/code/streams/Machine2.java b/code/streams/Machine2.java deleted file mode 100644 index 3d407185..00000000 --- a/code/streams/Machine2.java +++ /dev/null @@ -1,23 +0,0 @@ -// streams/Machine2.java -// (c)2020 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. -import java.util.*; -import onjava.Operations; - -public class Machine2 { - public static void main(String[] args) { - Arrays.stream(new Operations[] { - () -> Operations.show("Bing"), - () -> Operations.show("Crack"), - () -> Operations.show("Twist"), - () -> Operations.show("Pop") - }).forEach(Operations::execute); - } -} -/* Output: -Bing -Crack -Twist -Pop -*/ diff --git a/code/streams/MapCollector.java b/code/streams/MapCollector.java deleted file mode 100644 index 95811e4b..00000000 --- a/code/streams/MapCollector.java +++ /dev/null @@ -1,48 +0,0 @@ -// streams/MapCollector.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; - -class Pair { - public final Character c; - public final Integer i; - Pair(Character c, Integer i) { - this.c = c; - this.i = i; - } - public Character getC() { return c; } - public Integer getI() { return i; } - @Override - public String toString() { - return "Pair(" + c + ", " + i + ")"; - } -} - -class RandomPair { - Random rand = new Random(47); - // An infinite iterator of random capital letters: - Iterator capChars = rand.ints(65,91) - .mapToObj(i -> (char)i) - .iterator(); - public Stream stream() { - return rand.ints(100, 1000).distinct() - .mapToObj(i -> new Pair(capChars.next(), i)); - } -} - -public class MapCollector { - public static void main(String[] args) { - Map map = - new RandomPair().stream() - .limit(8) - .collect( - Collectors.toMap(Pair::getI, Pair::getC)); - System.out.println(map); - } -} -/* Output: -{688=W, 309=C, 293=B, 761=N, 858=N, 668=G, 622=F, -751=N} -*/ diff --git a/code/streams/Matching.java b/code/streams/Matching.java deleted file mode 100644 index f5c01bc6..00000000 --- a/code/streams/Matching.java +++ /dev/null @@ -1,38 +0,0 @@ -// streams/Matching.java -// (c)2020 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. -// Demonstrates short-circuiting of *Match() operations -import java.util.stream.*; -import java.util.function.*; -import static streams.RandInts.*; - -interface Matcher extends - BiPredicate, Predicate> {} - -public class Matching { - static void show(Matcher match, int val) { - System.out.println( - match.test( - IntStream.rangeClosed(1, 9) - .boxed() - .peek(n -> System.out.format("%d ", n)), - n -> n < val)); - } - public static void main(String[] args) { - show(Stream::allMatch, 10); - show(Stream::allMatch, 4); - show(Stream::anyMatch, 2); - show(Stream::anyMatch, 0); - show(Stream::noneMatch, 5); - show(Stream::noneMatch, 0); - } -} -/* Output: -1 2 3 4 5 6 7 8 9 true -1 2 3 4 false -1 true -1 2 3 4 5 6 7 8 9 false -1 false -1 2 3 4 5 6 7 8 9 true -*/ diff --git a/code/streams/NumericStreamInfo.java b/code/streams/NumericStreamInfo.java deleted file mode 100644 index 0d04b6ef..00000000 --- a/code/streams/NumericStreamInfo.java +++ /dev/null @@ -1,24 +0,0 @@ -// streams/NumericStreamInfo.java -// (c)2020 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. -import java.util.stream.*; -import static streams.RandInts.*; - -public class NumericStreamInfo { - public static void main(String[] args) { - System.out.println(rands().average().getAsDouble()); - System.out.println(rands().max().getAsInt()); - System.out.println(rands().min().getAsInt()); - System.out.println(rands().sum()); - System.out.println(rands().summaryStatistics()); - } -} -/* Output: -507.94 -998 -8 -50794 -IntSummaryStatistics{count=100, sum=50794, min=8, -average=507.940000, max=998} -*/ diff --git a/code/streams/OptionalBasics.java b/code/streams/OptionalBasics.java deleted file mode 100644 index 625c450a..00000000 --- a/code/streams/OptionalBasics.java +++ /dev/null @@ -1,23 +0,0 @@ -// streams/OptionalBasics.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; - -class OptionalBasics { - static void test(Optional optString) { - if(optString.isPresent()) - System.out.println(optString.get()); - else - System.out.println("Nothing inside!"); - } - public static void main(String[] args) { - test(Stream.of("Epithets").findFirst()); - test(Stream.empty().findFirst()); - } -} -/* Output: -Epithets -Nothing inside! -*/ diff --git a/code/streams/OptionalFilter.java b/code/streams/OptionalFilter.java deleted file mode 100644 index a2095ec3..00000000 --- a/code/streams/OptionalFilter.java +++ /dev/null @@ -1,72 +0,0 @@ -// streams/OptionalFilter.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import java.util.function.*; - -class OptionalFilter { - static String[] elements = { - "Foo", "", "Bar", "Baz", "Bingo" - }; - static Stream testStream() { - return Arrays.stream(elements); - } - static void - test(String descr, Predicate pred) { - System.out.println(" ---( " + descr + " )---"); - for(int i = 0; i <= elements.length; i++) { - System.out.println( - testStream() - .skip(i) - .findFirst() - .filter(pred)); - } - } - public static void main(String[] args) { - test("true", str -> true); - test("false", str -> false); - test("str != \"\"", str -> str != ""); - test("str.length() == 3", str -> str.length() == 3); - test("startsWith(\"B\")", - str -> str.startsWith("B")); - } -} -/* Output: - ---( true )--- -Optional[Foo] -Optional[] -Optional[Bar] -Optional[Baz] -Optional[Bingo] -Optional.empty - ---( false )--- -Optional.empty -Optional.empty -Optional.empty -Optional.empty -Optional.empty -Optional.empty - ---( str != "" )--- -Optional[Foo] -Optional.empty -Optional[Bar] -Optional[Baz] -Optional[Bingo] -Optional.empty - ---( str.length() == 3 )--- -Optional[Foo] -Optional.empty -Optional[Bar] -Optional[Baz] -Optional.empty -Optional.empty - ---( startsWith("B") )--- -Optional.empty -Optional.empty -Optional[Bar] -Optional[Baz] -Optional[Bingo] -Optional.empty -*/ diff --git a/code/streams/OptionalFlatMap.java b/code/streams/OptionalFlatMap.java deleted file mode 100644 index 52e8e81e..00000000 --- a/code/streams/OptionalFlatMap.java +++ /dev/null @@ -1,73 +0,0 @@ -// streams/OptionalFlatMap.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import java.util.function.*; - -class OptionalFlatMap { - static String[] elements = { "12", "", "23", "45" }; - static Stream testStream() { - return Arrays.stream(elements); - } - static void test(String descr, - Function> func) { - System.out.println(" ---( " + descr + " )---"); - for(int i = 0; i <= elements.length; i++) { - System.out.println( - testStream() - .skip(i) - .findFirst() - .flatMap(func)); - } - } - public static void main(String[] args) { - - test("Add brackets", - s -> Optional.of("[" + s + "]")); - - test("Increment", s -> { - try { - return Optional.of( - Integer.parseInt(s) + 1 + ""); - } catch(NumberFormatException e) { - return Optional.of(s); - } - }); - - test("Replace", - s -> Optional.of(s.replace("2", "9"))); - - test("Take last digit", - s -> Optional.of(s.length() > 0 ? - s.charAt(s.length() - 1) + "" - : s)); - } -} -/* Output: - ---( Add brackets )--- -Optional[[12]] -Optional[[]] -Optional[[23]] -Optional[[45]] -Optional.empty - ---( Increment )--- -Optional[13] -Optional[] -Optional[24] -Optional[46] -Optional.empty - ---( Replace )--- -Optional[19] -Optional[] -Optional[93] -Optional[45] -Optional.empty - ---( Take last digit )--- -Optional[2] -Optional[] -Optional[3] -Optional[5] -Optional.empty -*/ diff --git a/code/streams/OptionalMap.java b/code/streams/OptionalMap.java deleted file mode 100644 index 83ae4396..00000000 --- a/code/streams/OptionalMap.java +++ /dev/null @@ -1,74 +0,0 @@ -// streams/OptionalMap.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import java.util.function.*; - -class OptionalMap { - static String[] elements = { "12", "", "23", "45" }; - static Stream testStream() { - return Arrays.stream(elements); - } - static void - test(String descr, Function func) { - System.out.println(" ---( " + descr + " )---"); - for(int i = 0; i <= elements.length; i++) { - System.out.println( - testStream() - .skip(i) - .findFirst() // Produces an Optional - .map(func)); - } - } - public static void main(String[] args) { - - // If Optional is not empty, map() first extracts - // the contents which it then passes - // to the function: - - test("Add brackets", s -> "[" + s + "]"); - - test("Increment", s -> { - try { - return Integer.parseInt(s) + 1 + ""; - } catch(NumberFormatException e) { - return s; - } - }); - - test("Replace", s -> s.replace("2", "9")); - - test("Take last digit", s -> s.length() > 0 ? - s.charAt(s.length() - 1) + "" : s); - } - // After the function is finished, map() wraps the - // result in an Optional before returning it: -} -/* Output: - ---( Add brackets )--- -Optional[[12]] -Optional[[]] -Optional[[23]] -Optional[[45]] -Optional.empty - ---( Increment )--- -Optional[13] -Optional[] -Optional[24] -Optional[46] -Optional.empty - ---( Replace )--- -Optional[19] -Optional[] -Optional[93] -Optional[45] -Optional.empty - ---( Take last digit )--- -Optional[2] -Optional[] -Optional[3] -Optional[5] -Optional.empty -*/ diff --git a/code/streams/Optionals.java b/code/streams/Optionals.java deleted file mode 100644 index 4d0d96cb..00000000 --- a/code/streams/Optionals.java +++ /dev/null @@ -1,63 +0,0 @@ -// streams/Optionals.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import java.util.function.*; - -public class Optionals { - static void basics(Optional optString) { - if(optString.isPresent()) - System.out.println(optString.get()); - else - System.out.println("Nothing inside!"); - } - static void ifPresent(Optional optString) { - optString.ifPresent(System.out::println); - } - static void orElse(Optional optString) { - System.out.println(optString.orElse("Nada")); - } - static void orElseGet(Optional optString) { - System.out.println( - optString.orElseGet(() -> "Generated")); - } - static void orElseThrow(Optional optString) { - try { - System.out.println(optString.orElseThrow( - () -> new Exception("Supplied"))); - } catch(Exception e) { - System.out.println("Caught " + e); - } - } - static void test(String testName, - Consumer> cos) { - System.out.println(" === " + testName + " === "); - cos.accept(Stream.of("Epithets").findFirst()); - cos.accept(Stream.empty().findFirst()); - } - public static void main(String[] args) { - test("basics", Optionals::basics); - test("ifPresent", Optionals::ifPresent); - test("orElse", Optionals::orElse); - test("orElseGet", Optionals::orElseGet); - test("orElseThrow", Optionals::orElseThrow); - } -} -/* Output: - === basics === -Epithets -Nothing inside! - === ifPresent === -Epithets - === orElse === -Epithets -Nada - === orElseGet === -Epithets -Generated - === orElseThrow === -Epithets -Caught java.lang.Exception: Supplied -*/ diff --git a/code/streams/OptionalsFromEmptyStreams.java b/code/streams/OptionalsFromEmptyStreams.java deleted file mode 100644 index 771a84c0..00000000 --- a/code/streams/OptionalsFromEmptyStreams.java +++ /dev/null @@ -1,31 +0,0 @@ -// streams/OptionalsFromEmptyStreams.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; - -class OptionalsFromEmptyStreams { - public static void main(String[] args) { - System.out.println(Stream.empty() - .findFirst()); - System.out.println(Stream.empty() - .findAny()); - System.out.println(Stream.empty() - .max(String.CASE_INSENSITIVE_ORDER)); - System.out.println(Stream.empty() - .min(String.CASE_INSENSITIVE_ORDER)); - System.out.println(Stream.empty() - .reduce((s1, s2) -> s1 + s2)); - System.out.println(IntStream.empty() - .average()); - } -} -/* Output: -Optional.empty -Optional.empty -Optional.empty -Optional.empty -Optional.empty -OptionalDouble.empty -*/ diff --git a/code/streams/Peeking.java b/code/streams/Peeking.java deleted file mode 100644 index d8800515..00000000 --- a/code/streams/Peeking.java +++ /dev/null @@ -1,22 +0,0 @@ -// streams/Peeking.java -// (c)2020 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. - -class Peeking { - public static void - main(String[] args) throws Exception { - FileToWords.stream("Cheese.dat") - .skip(21) - .limit(4) - .map(w -> w + " ") - .peek(System.out::print) - .map(String::toUpperCase) - .peek(System.out::print) - .map(String::toLowerCase) - .forEach(System.out::print); - } -} -/* Output: -Well WELL well it IT it s S s so SO so -*/ diff --git a/code/streams/Prime.java b/code/streams/Prime.java deleted file mode 100644 index e14459d1..00000000 --- a/code/streams/Prime.java +++ /dev/null @@ -1,31 +0,0 @@ -// streams/Prime.java -// (c)2020 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. -import java.util.stream.*; -import static java.util.stream.LongStream.*; - -public class Prime { - public static boolean isPrime(long n) { - return rangeClosed(2, (long)Math.sqrt(n)) - .noneMatch(i -> n % i == 0); - } - public LongStream numbers() { - return iterate(2, i -> i + 1) - .filter(Prime::isPrime); - } - public static void main(String[] args) { - new Prime().numbers() - .limit(10) - .forEach(n -> System.out.format("%d ", n)); - System.out.println(); - new Prime().numbers() - .skip(90) - .limit(10) - .forEach(n -> System.out.format("%d ", n)); - } -} -/* Output: -2 3 5 7 11 13 17 19 23 29 -467 479 487 491 499 503 509 521 523 541 -*/ diff --git a/code/streams/RandInts.java b/code/streams/RandInts.java deleted file mode 100644 index 8adfc60e..00000000 --- a/code/streams/RandInts.java +++ /dev/null @@ -1,15 +0,0 @@ -// streams/RandInts.java -// (c)2020 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 streams; -import java.util.*; -import java.util.stream.*; - -public class RandInts { - private static int[] rints = - new Random(47).ints(0, 1000).limit(100).toArray(); - public static IntStream rands() { - return Arrays.stream(rints); - } -} diff --git a/code/streams/RandomGenerators.java b/code/streams/RandomGenerators.java deleted file mode 100644 index 904216ac..00000000 --- a/code/streams/RandomGenerators.java +++ /dev/null @@ -1,86 +0,0 @@ -// streams/RandomGenerators.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; - -public class RandomGenerators { - public static void show(Stream stream) { - stream - .limit(4) - .forEach(System.out::println); - System.out.println("++++++++"); - } - public static void main(String[] args) { - Random rand = new Random(47); - show(rand.ints().boxed()); - show(rand.longs().boxed()); - show(rand.doubles().boxed()); - // Control the lower and upper bounds: - show(rand.ints(10, 20).boxed()); - show(rand.longs(50, 100).boxed()); - show(rand.doubles(20, 30).boxed()); - // Control the stream size: - show(rand.ints(2).boxed()); - show(rand.longs(2).boxed()); - show(rand.doubles(2).boxed()); - // Control the stream size and bounds: - show(rand.ints(3, 3, 9).boxed()); - show(rand.longs(3, 12, 22).boxed()); - show(rand.doubles(3, 11.5, 12.3).boxed()); - } -} -/* Output: --1172028779 -1717241110 --2014573909 -229403722 -++++++++ -2955289354441303771 -3476817843704654257 --8917117694134521474 -4941259272818818752 -++++++++ -0.2613610344283964 -0.0508673570556899 -0.8037155449603999 -0.7620665811558285 -++++++++ -16 -10 -11 -12 -++++++++ -65 -99 -54 -58 -++++++++ -29.86777681078574 -24.83968447804611 -20.09247112332014 -24.046793846338723 -++++++++ -1169976606 -1947946283 -++++++++ -2970202997824602425 --2325326920272830366 -++++++++ -0.7024254510631527 -0.6648552384607359 -++++++++ -6 -7 -7 -++++++++ -17 -12 -20 -++++++++ -12.27872414236691 -11.732085449736195 -12.196509449817267 -++++++++ -*/ diff --git a/code/streams/RandomWords.java b/code/streams/RandomWords.java deleted file mode 100644 index 3bf2e51b..00000000 --- a/code/streams/RandomWords.java +++ /dev/null @@ -1,41 +0,0 @@ -// streams/RandomWords.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import java.util.function.*; -import java.io.*; -import java.nio.file.*; - -public class RandomWords implements Supplier { - List words = new ArrayList<>(); - Random rand = new Random(47); - RandomWords(String fname) throws IOException { - List lines = - Files.readAllLines(Paths.get(fname)); - // Skip the first line: - for(String line : lines.subList(1, lines.size())) { - for(String word : line.split("[ .?,]+")) - words.add(word.toLowerCase()); - } - } - public String get() { - return words.get(rand.nextInt(words.size())); - } - @Override - public String toString() { - return words.stream() - .collect(Collectors.joining(" ")); - } - public static void - main(String[] args) throws Exception { - System.out.println( - Stream.generate(new RandomWords("Cheese.dat")) - .limit(10) - .collect(Collectors.joining(" "))); - } -} -/* Output: -it shop sir the much cheese by conclusion district is -*/ diff --git a/code/streams/Randoms.java b/code/streams/Randoms.java deleted file mode 100644 index f2b5f6a8..00000000 --- a/code/streams/Randoms.java +++ /dev/null @@ -1,25 +0,0 @@ -// streams/Randoms.java -// (c)2020 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. -import java.util.*; - -public class Randoms { - public static void main(String[] args) { - new Random(47) - .ints(5, 20) - .distinct() - .limit(7) - .sorted() - .forEach(System.out::println); - } -} -/* Output: -6 -10 -13 -16 -17 -18 -19 -*/ diff --git a/code/streams/Ranges.java b/code/streams/Ranges.java deleted file mode 100644 index d8fc681a..00000000 --- a/code/streams/Ranges.java +++ /dev/null @@ -1,29 +0,0 @@ -// streams/Ranges.java -// (c)2020 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. -import static java.util.stream.IntStream.*; - -public class Ranges { - public static void main(String[] args) { - // The traditional way: - int result = 0; - for(int i = 10; i < 20; i++) - result += i; - System.out.println(result); - - // for-in with a range: - result = 0; - for(int i : range(10, 20).toArray()) - result += i; - System.out.println(result); - - // Use streams: - System.out.println(range(10, 20).sum()); - } -} -/* Output: -145 -145 -145 -*/ diff --git a/code/streams/Reduce.java b/code/streams/Reduce.java deleted file mode 100644 index 0e9f07ba..00000000 --- a/code/streams/Reduce.java +++ /dev/null @@ -1,44 +0,0 @@ -// streams/Reduce.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; - -class Frobnitz { - int size; - Frobnitz(int sz) { size = sz; } - @Override - public String toString() { - return "Frobnitz(" + size + ")"; - } - // Generator: - static Random rand = new Random(47); - static final int BOUND = 100; - static Frobnitz supply() { - return new Frobnitz(rand.nextInt(BOUND)); - } -} - -public class Reduce { - public static void main(String[] args) { - Stream.generate(Frobnitz::supply) - .limit(10) - .peek(System.out::println) - .reduce((fr0, fr1) -> fr0.size < 50 ? fr0 : fr1) - .ifPresent(System.out::println); - } -} -/* Output: -Frobnitz(58) -Frobnitz(55) -Frobnitz(93) -Frobnitz(61) -Frobnitz(61) -Frobnitz(29) -Frobnitz(68) -Frobnitz(0) -Frobnitz(22) -Frobnitz(7) -Frobnitz(29) -*/ diff --git a/code/streams/SelectElement.java b/code/streams/SelectElement.java deleted file mode 100644 index 86846e40..00000000 --- a/code/streams/SelectElement.java +++ /dev/null @@ -1,24 +0,0 @@ -// streams/SelectElement.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import static streams.RandInts.*; - -public class SelectElement { - public static void main(String[] args) { - System.out.println(rands().findFirst().getAsInt()); - System.out.println( - rands().parallel().findFirst().getAsInt()); - System.out.println(rands().findAny().getAsInt()); - System.out.println( - rands().parallel().findAny().getAsInt()); - } -} -/* Output: -258 -258 -258 -242 -*/ diff --git a/code/streams/Signal.java b/code/streams/Signal.java deleted file mode 100644 index 9dc2a9f4..00000000 --- a/code/streams/Signal.java +++ /dev/null @@ -1,29 +0,0 @@ -// streams/Signal.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import java.util.function.*; - -public class Signal { - private final String msg; - public Signal(String msg) { this.msg = msg; } - public String getMsg() { return msg; } - @Override - public String toString() { - return "Signal(" + msg + ")"; - } - static Random rand = new Random(47); - public static Signal morse() { - switch(rand.nextInt(4)) { - case 1: return new Signal("dot"); - case 2: return new Signal("dash"); - default: return null; - } - } - public static Stream> stream() { - return Stream.generate(Signal::morse) - .map(signal -> Optional.ofNullable(signal)); - } -} diff --git a/code/streams/SortedComparator.java b/code/streams/SortedComparator.java deleted file mode 100644 index 070d60a7..00000000 --- a/code/streams/SortedComparator.java +++ /dev/null @@ -1,20 +0,0 @@ -// streams/SortedComparator.java -// (c)2020 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. -import java.util.*; - -public class SortedComparator { - public static void - main(String[] args) throws Exception { - FileToWords.stream("Cheese.dat") - .skip(10) - .limit(10) - .sorted(Comparator.reverseOrder()) - .map(w -> w + " ") - .forEach(System.out::print); - } -} -/* Output: -you what to the that sir leads in district And -*/ diff --git a/code/streams/SpecialCollector.java b/code/streams/SpecialCollector.java deleted file mode 100644 index 9526a73e..00000000 --- a/code/streams/SpecialCollector.java +++ /dev/null @@ -1,24 +0,0 @@ -// streams/SpecialCollector.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; - -public class SpecialCollector { - public static void - main(String[] args) throws Exception { - ArrayList words = - FileToWords.stream("Cheese.dat") - .collect(ArrayList::new, - ArrayList::add, - ArrayList::addAll); - words.stream() - .filter(s -> s.equals("cheese")) - .forEach(System.out::println); - } -} -/* Output: -cheese -cheese -*/ diff --git a/code/streams/StreamOf.java b/code/streams/StreamOf.java deleted file mode 100644 index c143388a..00000000 --- a/code/streams/StreamOf.java +++ /dev/null @@ -1,28 +0,0 @@ -// streams/StreamOf.java -// (c)2020 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. -import java.util.stream.*; - -public class StreamOf { - public static void main(String[] args) { - Stream.of( - new Bubble(1), new Bubble(2), new Bubble(3)) - .forEach(System.out::println); - Stream.of("It's ", "a ", "wonderful ", - "day ", "for ", "pie!") - .forEach(System.out::print); - System.out.println(); - Stream.of(3.14159, 2.718, 1.618) - .forEach(System.out::println); - } -} -/* Output: -Bubble(1) -Bubble(2) -Bubble(3) -It's a wonderful day for pie! -3.14159 -2.718 -1.618 -*/ diff --git a/code/streams/StreamOfOptionals.java b/code/streams/StreamOfOptionals.java deleted file mode 100644 index f725df57..00000000 --- a/code/streams/StreamOfOptionals.java +++ /dev/null @@ -1,37 +0,0 @@ -// streams/StreamOfOptionals.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; - -public class StreamOfOptionals { - public static void main(String[] args) { - Signal.stream() - .limit(10) - .forEach(System.out::println); - System.out.println(" ---"); - Signal.stream() - .limit(10) - .filter(Optional::isPresent) - .map(Optional::get) - .forEach(System.out::println); - } -} -/* Output: -Optional[Signal(dash)] -Optional[Signal(dot)] -Optional[Signal(dash)] -Optional.empty -Optional.empty -Optional[Signal(dash)] -Optional.empty -Optional[Signal(dot)] -Optional[Signal(dash)] -Optional[Signal(dash)] - --- -Signal(dot) -Signal(dot) -Signal(dash) -Signal(dash) -*/ diff --git a/code/streams/StreamOfRandoms.java b/code/streams/StreamOfRandoms.java deleted file mode 100644 index 66bf2bc7..00000000 --- a/code/streams/StreamOfRandoms.java +++ /dev/null @@ -1,20 +0,0 @@ -// streams/StreamOfRandoms.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; - -public class StreamOfRandoms { - static Random rand = new Random(47); - public static void main(String[] args) { - Stream.of(1, 2, 3, 4, 5) - .flatMapToInt(i -> IntStream.concat( - rand.ints(0, 100).limit(i), IntStream.of(-1))) - .forEach(n -> System.out.format("%d ", n)); - } -} -/* Output: -58 -1 55 93 -1 61 61 29 -1 68 0 22 7 -1 88 28 51 89 9 --1 -*/ diff --git a/code/streams/StreamOfStreams.java b/code/streams/StreamOfStreams.java deleted file mode 100644 index 973d83a6..00000000 --- a/code/streams/StreamOfStreams.java +++ /dev/null @@ -1,19 +0,0 @@ -// streams/StreamOfStreams.java -// (c)2020 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. -import java.util.stream.*; - -public class StreamOfStreams { - public static void main(String[] args) { - Stream.of(1, 2, 3) - .map(i -> Stream.of("Gonzo", "Kermit", "Beaker")) - .map(e-> e.getClass().getName()) - .forEach(System.out::println); - } -} -/* Output: -java.util.stream.ReferencePipeline$Head -java.util.stream.ReferencePipeline$Head -java.util.stream.ReferencePipeline$Head -*/ diff --git a/code/streams/TreeSetOfWords.java b/code/streams/TreeSetOfWords.java deleted file mode 100644 index feaa56a2..00000000 --- a/code/streams/TreeSetOfWords.java +++ /dev/null @@ -1,31 +0,0 @@ -// streams/TreeSetOfWords.java -// (c)2020 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. -import java.util.*; -import java.nio.file.*; -import java.util.stream.*; - -public class TreeSetOfWords { - public static void - main(String[] args) throws Exception { - Set words2 = - Files.lines(Paths.get("TreeSetOfWords.java")) - .flatMap(s -> Arrays.stream(s.split("\\W+"))) - .filter(s -> !s.matches("\\d+")) // No numbers - .map(String::trim) - .filter(s -> s.length() > 2) - .limit(100) - .collect(Collectors.toCollection(TreeSet::new)); - System.out.println(words2); - } -} -/* Output: -[Arrays, Collectors, Exception, Files, Output, Paths, -Set, String, System, TreeSet, TreeSetOfWords, args, -class, collect, file, filter, flatMap, get, import, -java, length, limit, lines, main, map, matches, new, -nio, numbers, out, println, public, split, static, -stream, streams, throws, toCollection, trim, util, -void, words2] -*/ diff --git a/code/strings/ArrayListDisplay.java b/code/strings/ArrayListDisplay.java deleted file mode 100644 index 7b83296f..00000000 --- a/code/strings/ArrayListDisplay.java +++ /dev/null @@ -1,22 +0,0 @@ -// strings/ArrayListDisplay.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; -import generics.coffee.*; - -public class ArrayListDisplay { - public static void main(String[] args) { - List coffees = - Stream.generate(new CoffeeSupplier()) - .limit(10) - .collect(Collectors.toList()); - System.out.println(coffees); - } -} -/* Output: -[Americano 0, Latte 1, Americano 2, Mocha 3, Mocha 4, -Breve 5, Americano 6, Latte 7, Cappuccino 8, Cappuccino -9] -*/ diff --git a/code/strings/BetterRead.java b/code/strings/BetterRead.java deleted file mode 100644 index a3b7aaa2..00000000 --- a/code/strings/BetterRead.java +++ /dev/null @@ -1,37 +0,0 @@ -// strings/BetterRead.java -// (c)2020 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. -import java.util.*; - -public class BetterRead { - public static void main(String[] args) { - Scanner stdin = new Scanner(SimpleRead.input); - System.out.println("What is your name?"); - String name = stdin.nextLine(); - System.out.println(name); - System.out.println( - "How old are you? What is your favorite double?"); - System.out.println("(input: )"); - int age = stdin.nextInt(); - double favorite = stdin.nextDouble(); - System.out.println(age); - System.out.println(favorite); - System.out.format("Hi %s.%n", name); - System.out.format("In 5 years you will be %d.%n", - age + 5); - System.out.format("My favorite double is %f.", - favorite / 2); - } -} -/* Output: -What is your name? -Sir Robin of Camelot -How old are you? What is your favorite double? -(input: ) -22 -1.61803 -Hi Sir Robin of Camelot. -In 5 years you will be 27. -My favorite double is 0.809015. -*/ diff --git a/code/strings/Concatenation.java b/code/strings/Concatenation.java deleted file mode 100644 index 685f4dbb..00000000 --- a/code/strings/Concatenation.java +++ /dev/null @@ -1,15 +0,0 @@ -// strings/Concatenation.java -// (c)2020 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. - -public class Concatenation { - public static void main(String[] args) { - String mango = "mango"; - String s = "abc" + mango + "def" + 47; - System.out.println(s); - } -} -/* Output: -abcmangodef47 -*/ diff --git a/code/strings/Conversion.java b/code/strings/Conversion.java deleted file mode 100644 index f839e81a..00000000 --- a/code/strings/Conversion.java +++ /dev/null @@ -1,113 +0,0 @@ -// strings/Conversion.java -// (c)2020 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. -import java.math.*; -import java.util.*; - -public class Conversion { - public static void main(String[] args) { - Formatter f = new Formatter(System.out); - - char u = 'a'; - System.out.println("u = 'a'"); - f.format("s: %s%n", u); - // f.format("d: %d%n", u); - f.format("c: %c%n", u); - f.format("b: %b%n", u); - // f.format("f: %f%n", u); - // f.format("e: %e%n", u); - // f.format("x: %x%n", u); - f.format("h: %h%n", u); - - int v = 121; - System.out.println("v = 121"); - f.format("d: %d%n", v); - f.format("c: %c%n", v); - f.format("b: %b%n", v); - f.format("s: %s%n", v); - // f.format("f: %f%n", v); - // f.format("e: %e%n", v); - f.format("x: %x%n", v); - f.format("h: %h%n", v); - - BigInteger w = new BigInteger("50000000000000"); - System.out.println( - "w = new BigInteger(\"50000000000000\")"); - f.format("d: %d%n", w); - // f.format("c: %c%n", w); - f.format("b: %b%n", w); - f.format("s: %s%n", w); - // f.format("f: %f%n", w); - // f.format("e: %e%n", w); - f.format("x: %x%n", w); - f.format("h: %h%n", w); - - double x = 179.543; - System.out.println("x = 179.543"); - // f.format("d: %d%n", x); - // f.format("c: %c%n", x); - f.format("b: %b%n", x); - f.format("s: %s%n", x); - f.format("f: %f%n", x); - f.format("e: %e%n", x); - // f.format("x: %x%n", x); - f.format("h: %h%n", x); - - Conversion y = new Conversion(); - System.out.println("y = new Conversion()"); - // f.format("d: %d%n", y); - // f.format("c: %c%n", y); - f.format("b: %b%n", y); - f.format("s: %s%n", y); - // f.format("f: %f%n", y); - // f.format("e: %e%n", y); - // f.format("x: %x%n", y); - f.format("h: %h%n", y); - - boolean z = false; - System.out.println("z = false"); - // f.format("d: %d%n", z); - // f.format("c: %c%n", z); - f.format("b: %b%n", z); - f.format("s: %s%n", z); - // f.format("f: %f%n", z); - // f.format("e: %e%n", z); - // f.format("x: %x%n", z); - f.format("h: %h%n", z); - } -} -/* Output: -u = 'a' -s: a -c: a -b: true -h: 61 -v = 121 -d: 121 -c: y -b: true -s: 121 -x: 79 -h: 79 -w = new BigInteger("50000000000000") -d: 50000000000000 -b: true -s: 50000000000000 -x: 2d79883d2000 -h: 8842a1a7 -x = 179.543 -b: true -s: 179.543 -f: 179.543000 -e: 1.795430e+02 -h: 1ef462c -y = new Conversion() -b: true -s: Conversion@15db9742 -h: 15db9742 -z = false -b: false -s: false -h: 4d5 -*/ diff --git a/code/strings/DatabaseException.java b/code/strings/DatabaseException.java deleted file mode 100644 index e8441254..00000000 --- a/code/strings/DatabaseException.java +++ /dev/null @@ -1,22 +0,0 @@ -// strings/DatabaseException.java -// (c)2020 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. - -public class DatabaseException extends Exception { - public DatabaseException(int transactionID, - int queryID, String message) { - super(String.format("(t%d, q%d) %s", transactionID, - queryID, message)); - } - public static void main(String[] args) { - try { - throw new DatabaseException(3, 7, "Write failed"); - } catch(Exception e) { - System.out.println(e); - } - } -} -/* Output: -DatabaseException: (t3, q7) Write failed -*/ diff --git a/code/strings/Finding.java b/code/strings/Finding.java deleted file mode 100644 index f8d7cbbc..00000000 --- a/code/strings/Finding.java +++ /dev/null @@ -1,27 +0,0 @@ -// strings/Finding.java -// (c)2020 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. -import java.util.regex.*; - -public class Finding { - public static void main(String[] args) { - Matcher m = Pattern.compile("\\w+") - .matcher( - "Evening is full of the linnet's wings"); - while(m.find()) - System.out.print(m.group() + " "); - System.out.println(); - int i = 0; - while(m.find(i)) { - System.out.print(m.group() + " "); - i++; - } - } -} -/* Output: -Evening is full of the linnet s wings -Evening vening ening ning ing ng g is is s full full -ull ll l of of f the the he e linnet linnet innet nnet -net et t s s wings wings ings ngs gs s -*/ diff --git a/code/strings/Groups.java b/code/strings/Groups.java deleted file mode 100644 index 298caf62..00000000 --- a/code/strings/Groups.java +++ /dev/null @@ -1,40 +0,0 @@ -// strings/Groups.java -// (c)2020 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. -import java.util.regex.*; - -public class Groups { - public static final String POEM = - "Twas brillig, and the slithy toves\n" + - "Did gyre and gimble in the wabe.\n" + - "All mimsy were the borogoves,\n" + - "And the mome raths outgrabe.\n\n" + - "Beware the Jabberwock, my son,\n" + - "The jaws that bite, the claws that catch.\n" + - "Beware the Jubjub bird, and shun\n" + - "The frumious Bandersnatch."; - public static void main(String[] args) { - Matcher m = Pattern.compile( - "(?m)(\\S+)\\s+((\\S+)\\s+(\\S+))$") - .matcher(POEM); - while(m.find()) { - for(int j = 0; j <= m.groupCount(); j++) - System.out.print("[" + m.group(j) + "]"); - System.out.println(); - } - } -} -/* Output: -[the slithy toves][the][slithy toves][slithy][toves] -[in the wabe.][in][the wabe.][the][wabe.] -[were the borogoves,][were][the -borogoves,][the][borogoves,] -[mome raths outgrabe.][mome][raths -outgrabe.][raths][outgrabe.] -[Jabberwock, my son,][Jabberwock,][my son,][my][son,] -[claws that catch.][claws][that catch.][that][catch.] -[bird, and shun][bird,][and shun][and][shun] -[The frumious Bandersnatch.][The][frumious -Bandersnatch.][frumious][Bandersnatch.] -*/ diff --git a/code/strings/Hex.java b/code/strings/Hex.java deleted file mode 100644 index 0fbcea8e..00000000 --- a/code/strings/Hex.java +++ /dev/null @@ -1,44 +0,0 @@ -// strings/Hex.java -// (c)2020 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. -// {java onjava.Hex} -package onjava; -import java.io.*; -import java.nio.file.*; - -public class Hex { - public static String format(byte[] data) { - StringBuilder result = new StringBuilder(); - int n = 0; - for(byte b : data) { - if(n % 16 == 0) - result.append(String.format("%05X: ", n)); - result.append(String.format("%02X ", b)); - n++; - if(n % 16 == 0) result.append("\n"); - } - result.append("\n"); - return result.toString(); - } - public static void - main(String[] args) throws Exception { - if(args.length == 0) - // Test by displaying this class file: - System.out.println(format( - Files.readAllBytes(Paths.get( - "build/classes/java/main/onjava/Hex.class")))); - else - System.out.println(format( - Files.readAllBytes(Paths.get(args[0])))); - } -} -/* Output: (First 6 Lines) -00000: CA FE BA BE 00 00 00 34 00 61 0A 00 05 00 31 07 -00010: 00 32 0A 00 02 00 31 08 00 33 07 00 34 0A 00 35 -00020: 00 36 0A 00 0F 00 37 0A 00 02 00 38 08 00 39 0A -00030: 00 3A 00 3B 08 00 3C 0A 00 02 00 3D 09 00 3E 00 -00040: 3F 08 00 40 07 00 41 0A 00 42 00 43 0A 00 44 00 -00050: 45 0A 00 14 00 46 0A 00 47 00 48 07 00 49 01 00 - ... -*/ diff --git a/code/strings/Immutable.java b/code/strings/Immutable.java deleted file mode 100644 index 4c8b529e..00000000 --- a/code/strings/Immutable.java +++ /dev/null @@ -1,22 +0,0 @@ -// strings/Immutable.java -// (c)2020 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. - -public class Immutable { - public static String upcase(String s) { - return s.toUpperCase(); - } - public static void main(String[] args) { - String q = "howdy"; - System.out.println(q); // howdy - String qq = upcase(q); - System.out.println(qq); // HOWDY - System.out.println(q); // howdy - } -} -/* Output: -howdy -HOWDY -howdy -*/ diff --git a/code/strings/InfiniteRecursion.java b/code/strings/InfiniteRecursion.java deleted file mode 100644 index 6941490a..00000000 --- a/code/strings/InfiniteRecursion.java +++ /dev/null @@ -1,22 +0,0 @@ -// strings/InfiniteRecursion.java -// (c)2020 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. -// Accidental recursion -// {ThrowsException} -// {VisuallyInspectOutput} Throws very long exception -import java.util.*; -import java.util.stream.*; - -public class InfiniteRecursion { - @Override - public String toString() { - return - " InfiniteRecursion address: " + this + "\n"; - } - public static void main(String[] args) { - Stream.generate(InfiniteRecursion::new) - .limit(10) - .forEach(System.out::println); - } -} diff --git a/code/strings/IntegerMatch.java b/code/strings/IntegerMatch.java deleted file mode 100644 index 5a3a38ac..00000000 --- a/code/strings/IntegerMatch.java +++ /dev/null @@ -1,19 +0,0 @@ -// strings/IntegerMatch.java -// (c)2020 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. - -public class IntegerMatch { - public static void main(String[] args) { - System.out.println("-1234".matches("-?\\d+")); - System.out.println("5678".matches("-?\\d+")); - System.out.println("+911".matches("-?\\d+")); - System.out.println("+911".matches("(-|\\+)?\\d+")); - } -} -/* Output: -true -true -false -true -*/ diff --git a/code/strings/JGrep.java b/code/strings/JGrep.java deleted file mode 100644 index 49cec954..00000000 --- a/code/strings/JGrep.java +++ /dev/null @@ -1,36 +0,0 @@ -// strings/JGrep.java -// (c)2020 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. -// A very simple version of the "grep" program -// {java JGrep -// WhitherStringBuilder.java 'return|for|String'} -import java.util.regex.*; -import java.nio.file.*; -import java.util.stream.*; - -public class JGrep { - public static void - main(String[] args) throws Exception { - if(args.length < 2) { - System.out.println( - "Usage: java JGrep file regex"); - System.exit(0); - } - Pattern p = Pattern.compile(args[1]); - // Iterate through the lines of the input file: - int index = 0; - Matcher m = p.matcher(""); - for(String line : - Files.readAllLines(Paths.get(args[0]))) { - m.reset(line); - while(m.find()) - System.out.println(index++ + ": " + - m.group() + ": " + m.start()); - } - } -} -/* Output: -0: for: 4 -1: for: 4 -*/ diff --git a/code/strings/ReFlags.java b/code/strings/ReFlags.java deleted file mode 100644 index 856806ee..00000000 --- a/code/strings/ReFlags.java +++ /dev/null @@ -1,23 +0,0 @@ -// strings/ReFlags.java -// (c)2020 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. -import java.util.regex.*; - -public class ReFlags { - public static void main(String[] args) { - Pattern p = Pattern.compile("^java", - Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - Matcher m = p.matcher( - "java has regex\nJava has regex\n" + - "JAVA has pretty good regular expressions\n" + - "Regular expressions are in Java"); - while(m.find()) - System.out.println(m.group()); - } -} -/* Output: -java -Java -JAVA -*/ diff --git a/code/strings/ReceiptBuilder.java b/code/strings/ReceiptBuilder.java deleted file mode 100644 index 234ca1e6..00000000 --- a/code/strings/ReceiptBuilder.java +++ /dev/null @@ -1,48 +0,0 @@ -// strings/ReceiptBuilder.java -// (c)2020 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. -import java.util.*; - -public class ReceiptBuilder { - private double total = 0; - private Formatter f = - new Formatter(new StringBuilder()); - public ReceiptBuilder() { - f.format( - "%-15s %5s %10s%n", "Item", "Qty", "Price"); - f.format( - "%-15s %5s %10s%n", "----", "---", "-----"); - } - public void add(String name, int qty, double price) { - f.format("%-15.15s %5d %10.2f%n", name, qty, price); - total += price * qty; - } - public String build() { - f.format("%-15s %5s %10.2f%n", "Tax", "", - total * 0.06); - f.format("%-15s %5s %10s%n", "", "", "-----"); - f.format("%-15s %5s %10.2f%n", "Total", "", - total * 1.06); - return f.toString(); - } - public static void main(String[] args) { - ReceiptBuilder receiptBuilder = - new ReceiptBuilder(); - receiptBuilder.add("Jack's Magic Beans", 4, 4.25); - receiptBuilder.add("Princess Peas", 3, 5.1); - receiptBuilder.add( - "Three Bears Porridge", 1, 14.29); - System.out.println(receiptBuilder.build()); - } -} -/* Output: -Item Qty Price ----- --- ----- -Jack's Magic Be 4 4.25 -Princess Peas 3 5.10 -Three Bears Por 1 14.29 -Tax 2.80 - ----- -Total 49.39 -*/ diff --git a/code/strings/Replacing.java b/code/strings/Replacing.java deleted file mode 100644 index dbc21afe..00000000 --- a/code/strings/Replacing.java +++ /dev/null @@ -1,21 +0,0 @@ -// strings/Replacing.java -// (c)2020 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. - -public class Replacing { - static String s = Splitting.knights; - public static void main(String[] args) { - System.out.println( - s.replaceFirst("f\\w+", "located")); - System.out.println( - s.replaceAll("shrubbery|tree|herring","banana")); - } -} -/* Output: -Then, when you have located the shrubbery, you must cut -down the mightiest tree in the forest...with... a -herring! -Then, when you have found the banana, you must cut down -the mightiest banana in the forest...with... a banana! -*/ diff --git a/code/strings/ReplacingStringTokenizer.java b/code/strings/ReplacingStringTokenizer.java deleted file mode 100644 index 60fad184..00000000 --- a/code/strings/ReplacingStringTokenizer.java +++ /dev/null @@ -1,26 +0,0 @@ -// strings/ReplacingStringTokenizer.java -// (c)2020 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. -import java.util.*; - -public class ReplacingStringTokenizer { - public static void main(String[] args) { - String input = - "But I'm not dead yet! I feel happy!"; - StringTokenizer stoke = new StringTokenizer(input); - while(stoke.hasMoreElements()) - System.out.print(stoke.nextToken() + " "); - System.out.println(); - System.out.println( - Arrays.toString(input.split(" "))); - Scanner scanner = new Scanner(input); - while(scanner.hasNext()) - System.out.print(scanner.next() + " "); - } -} -/* Output: -But I'm not dead yet! I feel happy! -[But, I'm, not, dead, yet!, I, feel, happy!] -But I'm not dead yet! I feel happy! -*/ diff --git a/code/strings/Resetting.java b/code/strings/Resetting.java deleted file mode 100644 index f1565390..00000000 --- a/code/strings/Resetting.java +++ /dev/null @@ -1,23 +0,0 @@ -// strings/Resetting.java -// (c)2020 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. -import java.util.regex.*; - -public class Resetting { - public static void - main(String[] args) throws Exception { - Matcher m = Pattern.compile("[frb][aiu][gx]") - .matcher("fix the rug with bags"); - while(m.find()) - System.out.print(m.group() + " "); - System.out.println(); - m.reset("fix the rig with rags"); - while(m.find()) - System.out.print(m.group() + " "); - } -} -/* Output: -fix rug bag -fix rig rag -*/ diff --git a/code/strings/Rudolph.java b/code/strings/Rudolph.java deleted file mode 100644 index 7a338510..00000000 --- a/code/strings/Rudolph.java +++ /dev/null @@ -1,21 +0,0 @@ -// strings/Rudolph.java -// (c)2020 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. - -public class Rudolph { - public static void main(String[] args) { - for(String pattern : new String[]{ - "Rudolph", - "[rR]udolph", - "[rR][aeiou][a-z]ol.*", - "R.*" }) - System.out.println("Rudolph".matches(pattern)); - } -} -/* Output: -true -true -true -true -*/ diff --git a/code/strings/ScannerDelimiter.java b/code/strings/ScannerDelimiter.java deleted file mode 100644 index a06ed990..00000000 --- a/code/strings/ScannerDelimiter.java +++ /dev/null @@ -1,21 +0,0 @@ -// strings/ScannerDelimiter.java -// (c)2020 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. -import java.util.*; - -public class ScannerDelimiter { - public static void main(String[] args) { - Scanner scanner = new Scanner("12, 42, 78, 99, 42"); - scanner.useDelimiter("\\s*,\\s*"); - while(scanner.hasNextInt()) - System.out.println(scanner.nextInt()); - } -} -/* Output: -12 -42 -78 -99 -42 -*/ diff --git a/code/strings/SimpleFormat.java b/code/strings/SimpleFormat.java deleted file mode 100644 index a3a6e52f..00000000 --- a/code/strings/SimpleFormat.java +++ /dev/null @@ -1,22 +0,0 @@ -// strings/SimpleFormat.java -// (c)2020 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. - -public class SimpleFormat { - public static void main(String[] args) { - int x = 5; - double y = 5.332542; - // The old way: - System.out.println("Row 1: [" + x + " " + y + "]"); - // The new way: - System.out.format("Row 1: [%d %f]%n", x, y); - // or - System.out.printf("Row 1: [%d %f]%n", x, y); - } -} -/* Output: -Row 1: [5 5.332542] -Row 1: [5 5.332542] -Row 1: [5 5.332542] -*/ diff --git a/code/strings/SimpleRead.java b/code/strings/SimpleRead.java deleted file mode 100644 index e85a058a..00000000 --- a/code/strings/SimpleRead.java +++ /dev/null @@ -1,43 +0,0 @@ -// strings/SimpleRead.java -// (c)2020 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. -import java.io.*; - -public class SimpleRead { - public static BufferedReader input = - new BufferedReader(new StringReader( - "Sir Robin of Camelot\n22 1.61803")); - public static void main(String[] args) { - try { - System.out.println("What is your name?"); - String name = input.readLine(); - System.out.println(name); - System.out.println("How old are you? " + - "What is your favorite double?"); - System.out.println("(input: )"); - String numbers = input.readLine(); - System.out.println(numbers); - String[] numArray = numbers.split(" "); - int age = Integer.parseInt(numArray[0]); - double favorite = Double.parseDouble(numArray[1]); - System.out.format("Hi %s.%n", name); - System.out.format("In 5 years you will be %d.%n", - age + 5); - System.out.format("My favorite double is %f.", - favorite / 2); - } catch(IOException e) { - System.err.println("I/O exception"); - } - } -} -/* Output: -What is your name? -Sir Robin of Camelot -How old are you? What is your favorite double? -(input: ) -22 1.61803 -Hi Sir Robin of Camelot. -In 5 years you will be 27. -My favorite double is 0.809015. -*/ diff --git a/code/strings/SplitDemo.java b/code/strings/SplitDemo.java deleted file mode 100644 index 65745392..00000000 --- a/code/strings/SplitDemo.java +++ /dev/null @@ -1,22 +0,0 @@ -// strings/SplitDemo.java -// (c)2020 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. -import java.util.regex.*; -import java.util.*; - -public class SplitDemo { - public static void main(String[] args) { - String input = - "This!!unusual use!!of exclamation!!points"; - System.out.println(Arrays.toString( - Pattern.compile("!!").split(input))); - // Only do the first three: - System.out.println(Arrays.toString( - Pattern.compile("!!").split(input, 3))); - } -} -/* Output: -[This, unusual use, of exclamation, points] -[This, unusual use, of exclamation!!points] -*/ diff --git a/code/strings/Splitting.java b/code/strings/Splitting.java deleted file mode 100644 index 0afe3a40..00000000 --- a/code/strings/Splitting.java +++ /dev/null @@ -1,32 +0,0 @@ -// strings/Splitting.java -// (c)2020 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. -import java.util.*; - -public class Splitting { - public static String knights = - "Then, when you have found the shrubbery, " + - "you must cut down the mightiest tree in the " + - "forest...with... a herring!"; - public static void split(String regex) { - System.out.println( - Arrays.toString(knights.split(regex))); - } - public static void main(String[] args) { - split(" "); // Doesn't have to contain regex chars - split("\\W+"); // Non-word characters - split("n\\W+"); // 'n' followed by non-words - } -} -/* Output: -[Then,, when, you, have, found, the, shrubbery,, you, -must, cut, down, the, mightiest, tree, in, the, -forest...with..., a, herring!] -[Then, when, you, have, found, the, shrubbery, you, -must, cut, down, the, mightiest, tree, in, the, forest, -with, a, herring] -[The, whe, you have found the shrubbery, you must cut -dow, the mightiest tree i, the forest...with... a -herring!] -*/ diff --git a/code/strings/StartEnd.java b/code/strings/StartEnd.java deleted file mode 100644 index 03caf520..00000000 --- a/code/strings/StartEnd.java +++ /dev/null @@ -1,82 +0,0 @@ -// strings/StartEnd.java -// (c)2020 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. -import java.util.regex.*; - -public class StartEnd { - public static String input = - "As long as there is injustice, whenever a\n" + - "Targathian baby cries out, wherever a distress\n" + - "signal sounds among the stars " + - "... We'll be there.\n"+ - "This fine ship, and this fine crew ...\n" + - "Never give up! Never surrender!"; - private static class Display { - private boolean regexPrinted = false; - private String regex; - Display(String regex) { this.regex = regex; } - void display(String message) { - if(!regexPrinted) { - System.out.println(regex); - regexPrinted = true; - } - System.out.println(message); - } - } - static void examine(String s, String regex) { - Display d = new Display(regex); - Pattern p = Pattern.compile(regex); - Matcher m = p.matcher(s); - while(m.find()) - d.display("find() '" + m.group() + - "' start = "+ m.start() + " end = " + m.end()); - if(m.lookingAt()) // No reset() necessary - d.display("lookingAt() start = " - + m.start() + " end = " + m.end()); - if(m.matches()) // No reset() necessary - d.display("matches() start = " - + m.start() + " end = " + m.end()); - } - public static void main(String[] args) { - for(String in : input.split("\n")) { - System.out.println("input : " + in); - for(String regex : new String[]{"\\w*ere\\w*", - "\\w*ever", "T\\w+", "Never.*?!"}) - examine(in, regex); - } - } -} -/* Output: -input : As long as there is injustice, whenever a -\w*ere\w* -find() 'there' start = 11 end = 16 -\w*ever -find() 'whenever' start = 31 end = 39 -input : Targathian baby cries out, wherever a distress -\w*ere\w* -find() 'wherever' start = 27 end = 35 -\w*ever -find() 'wherever' start = 27 end = 35 -T\w+ -find() 'Targathian' start = 0 end = 10 -lookingAt() start = 0 end = 10 -input : signal sounds among the stars ... We'll be -there. -\w*ere\w* -find() 'there' start = 43 end = 48 -input : This fine ship, and this fine crew ... -T\w+ -find() 'This' start = 0 end = 4 -lookingAt() start = 0 end = 4 -input : Never give up! Never surrender! -\w*ever -find() 'Never' start = 0 end = 5 -find() 'Never' start = 15 end = 20 -lookingAt() start = 0 end = 5 -Never.*?! -find() 'Never give up!' start = 0 end = 14 -find() 'Never surrender!' start = 15 end = 31 -lookingAt() start = 0 end = 14 -matches() start = 0 end = 31 -*/ diff --git a/code/strings/TestRegularExpression.java b/code/strings/TestRegularExpression.java deleted file mode 100644 index fe79ce8b..00000000 --- a/code/strings/TestRegularExpression.java +++ /dev/null @@ -1,44 +0,0 @@ -// strings/TestRegularExpression.java -// (c)2020 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. -// Simple regular expression demonstration -// {java TestRegularExpression -// abcabcabcdefabc "abc+" "(abc)+" } -import java.util.regex.*; - -public class TestRegularExpression { - public static void main(String[] args) { - if(args.length < 2) { - System.out.println( - "Usage:\njava TestRegularExpression " + - "characterSequence regularExpression+"); - System.exit(0); - } - System.out.println("Input: \"" + args[0] + "\""); - for(String arg : args) { - System.out.println( - "Regular expression: \"" + arg + "\""); - Pattern p = Pattern.compile(arg); - Matcher m = p.matcher(args[0]); - while(m.find()) { - System.out.println( - "Match \"" + m.group() + "\" at positions " + - m.start() + "-" + (m.end() - 1)); - } - } - } -} -/* Output: -Input: "abcabcabcdefabc" -Regular expression: "abcabcabcdefabc" -Match "abcabcabcdefabc" at positions 0-14 -Regular expression: "abc+" -Match "abc" at positions 0-2 -Match "abc" at positions 3-5 -Match "abc" at positions 6-8 -Match "abc" at positions 12-14 -Regular expression: "(abc)+" -Match "abcabcabc" at positions 0-8 -Match "abc" at positions 12-14 -*/ diff --git a/code/strings/TheReplacements.java b/code/strings/TheReplacements.java deleted file mode 100644 index 2319552f..00000000 --- a/code/strings/TheReplacements.java +++ /dev/null @@ -1,57 +0,0 @@ -// strings/TheReplacements.java -// (c)2020 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. -import java.util.regex.*; -import java.nio.file.*; -import java.util.stream.*; - -/*! Here's a block of text to use as input to - the regular expression matcher. Note that we - first extract the block of text by looking for - the special delimiters, then process the - extracted block. !*/ - -public class TheReplacements { - public static void - main(String[] args) throws Exception { - String s = Files.lines( - Paths.get("TheReplacements.java")) - .collect(Collectors.joining("\n")); - // Match specially commented block of text above: - Matcher mInput = Pattern.compile( - "/\\*!(.*)!\\*/", Pattern.DOTALL).matcher(s); - if(mInput.find()) - s = mInput.group(1); // Captured by parentheses - // Replace two or more spaces with a single space: - s = s.replaceAll(" {2,}", " "); - // Replace 1+ spaces at the beginning of each - // line with no spaces. Must enable MULTILINE mode: - s = s.replaceAll("(?m)^ +", ""); - System.out.println(s); - s = s.replaceFirst("[aeiou]", "(VOWEL1)"); - StringBuffer sbuf = new StringBuffer(); - Pattern p = Pattern.compile("[aeiou]"); - Matcher m = p.matcher(s); - // Process the find information as you - // perform the replacements: - while(m.find()) - m.appendReplacement( - sbuf, m.group().toUpperCase()); - // Put in the remainder of the text: - m.appendTail(sbuf); - System.out.println(sbuf); - } -} -/* Output: -Here's a block of text to use as input to -the regular expression matcher. Note that we -first extract the block of text by looking for -the special delimiters, then process the -extracted block. -H(VOWEL1)rE's A blOck Of tExt tO UsE As InpUt tO -thE rEgUlAr ExprEssIOn mAtchEr. NOtE thAt wE -fIrst ExtrAct thE blOck Of tExt by lOOkIng fOr -thE spEcIAl dElImItErs, thEn prOcEss thE -ExtrActEd blOck. -*/ diff --git a/code/strings/ThreatAnalyzer.java b/code/strings/ThreatAnalyzer.java deleted file mode 100644 index fc145c86..00000000 --- a/code/strings/ThreatAnalyzer.java +++ /dev/null @@ -1,36 +0,0 @@ -// strings/ThreatAnalyzer.java -// (c)2020 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. -import java.util.regex.*; -import java.util.*; - -public class ThreatAnalyzer { - static String threatData = - "58.27.82.161@08/10/2015\n" + - "204.45.234.40@08/11/2015\n" + - "58.27.82.161@08/11/2015\n" + - "58.27.82.161@08/12/2015\n" + - "58.27.82.161@08/12/2015\n" + - "[Next log section with different data format]"; - public static void main(String[] args) { - Scanner scanner = new Scanner(threatData); - String pattern = "(\\d+[.]\\d+[.]\\d+[.]\\d+)@" + - "(\\d{2}/\\d{2}/\\d{4})"; - while(scanner.hasNext(pattern)) { - scanner.next(pattern); - MatchResult match = scanner.match(); - String ip = match.group(1); - String date = match.group(2); - System.out.format( - "Threat on %s from %s%n", date,ip); - } - } -} -/* Output: -Threat on 08/10/2015 from 58.27.82.161 -Threat on 08/11/2015 from 204.45.234.40 -Threat on 08/11/2015 from 58.27.82.161 -Threat on 08/12/2015 from 58.27.82.161 -Threat on 08/12/2015 from 58.27.82.161 -*/ diff --git a/code/strings/Turtle.java b/code/strings/Turtle.java deleted file mode 100644 index 68977bfc..00000000 --- a/code/strings/Turtle.java +++ /dev/null @@ -1,40 +0,0 @@ -// strings/Turtle.java -// (c)2020 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. -import java.io.*; -import java.util.*; - -public class Turtle { - private String name; - private Formatter f; - public Turtle(String name, Formatter f) { - this.name = name; - this.f = f; - } - public void move(int x, int y) { - f.format("%s The Turtle is at (%d,%d)%n", - name, x, y); - } - public static void main(String[] args) { - PrintStream outAlias = System.out; - Turtle tommy = new Turtle("Tommy", - new Formatter(System.out)); - Turtle terry = new Turtle("Terry", - new Formatter(outAlias)); - tommy.move(0,0); - terry.move(4,8); - tommy.move(3,4); - terry.move(2,5); - tommy.move(3,3); - terry.move(3,3); - } -} -/* Output: -Tommy The Turtle is at (0,0) -Terry The Turtle is at (4,8) -Tommy The Turtle is at (3,4) -Terry The Turtle is at (2,5) -Tommy The Turtle is at (3,3) -Terry The Turtle is at (3,3) -*/ diff --git a/code/strings/UsingStringBuilder.java b/code/strings/UsingStringBuilder.java deleted file mode 100644 index 0ff32410..00000000 --- a/code/strings/UsingStringBuilder.java +++ /dev/null @@ -1,37 +0,0 @@ -// strings/UsingStringBuilder.java -// (c)2020 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. -import java.util.*; -import java.util.stream.*; - -public class UsingStringBuilder { - public static String string1() { - Random rand = new Random(47); - StringBuilder result = new StringBuilder("["); - for(int i = 0; i < 25; i++) { - result.append(rand.nextInt(100)); - result.append(", "); - } - result.delete(result.length()-2, result.length()); - result.append("]"); - return result.toString(); - } - public static String string2() { - String result = new Random(47) - .ints(25, 0, 100) - .mapToObj(Integer::toString) - .collect(Collectors.joining(", ")); - return "[" + result + "]"; - } - public static void main(String[] args) { - System.out.println(string1()); - System.out.println(string2()); - } -} -/* Output: -[58, 55, 93, 61, 61, 29, 68, 0, 22, 7, 88, 28, 51, 89, -9, 78, 98, 61, 20, 58, 16, 40, 11, 22, 4] -[58, 55, 93, 61, 61, 29, 68, 0, 22, 7, 88, 28, 51, 89, -9, 78, 98, 61, 20, 58, 16, 40, 11, 22, 4] -*/ diff --git a/code/strings/WhitherStringBuilder.java b/code/strings/WhitherStringBuilder.java deleted file mode 100644 index 0c46cae3..00000000 --- a/code/strings/WhitherStringBuilder.java +++ /dev/null @@ -1,21 +0,0 @@ -// strings/WhitherStringBuilder.java -// (c)2020 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. - -public class WhitherStringBuilder { - public String implicit(String[] fields) { - String result = ""; - for(String field : fields) { - result += field; - } - return result; - } - public String explicit(String[] fields) { - StringBuilder result = new StringBuilder(); - for(String field : fields) { - result.append(field); - } - return result.toString(); - } -} diff --git a/code/typeinfo/AnonymousImplementation.java b/code/typeinfo/AnonymousImplementation.java deleted file mode 100644 index 34fa7832..00000000 --- a/code/typeinfo/AnonymousImplementation.java +++ /dev/null @@ -1,50 +0,0 @@ -// typeinfo/AnonymousImplementation.java -// (c)2020 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. -// Anonymous inner classes can't hide from reflection -import typeinfo.interfacea.*; - -class AnonymousA { - public static A makeA() { - return new A() { - public void f() { - System.out.println("public C.f()"); - } - public void g() { - System.out.println("public C.g()"); - } - void u() { - System.out.println("package C.u()"); - } - protected void v() { - System.out.println("protected C.v()"); - } - private void w() { - System.out.println("private C.w()"); - } - }; - } -} - -public class AnonymousImplementation { - public static void - main(String[] args) throws Exception { - A a = AnonymousA.makeA(); - a.f(); - System.out.println(a.getClass().getName()); - // Reflection still gets into the anonymous class: - HiddenImplementation.callHiddenMethod(a, "g"); - HiddenImplementation.callHiddenMethod(a, "u"); - HiddenImplementation.callHiddenMethod(a, "v"); - HiddenImplementation.callHiddenMethod(a, "w"); - } -} -/* Output: -public C.f() -AnonymousA$1 -public C.g() -package C.u() -protected C.v() -private C.w() -*/ diff --git a/code/typeinfo/BoundedClassReferences.java b/code/typeinfo/BoundedClassReferences.java deleted file mode 100644 index ed0945e6..00000000 --- a/code/typeinfo/BoundedClassReferences.java +++ /dev/null @@ -1,13 +0,0 @@ -// typeinfo/BoundedClassReferences.java -// (c)2020 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. - -public class BoundedClassReferences { - public static void main(String[] args) { - Class bounded = int.class; - bounded = double.class; - bounded = Number.class; - // Or anything else derived from Number. - } -} diff --git a/code/typeinfo/ClassCasts.java b/code/typeinfo/ClassCasts.java deleted file mode 100644 index fd0e17cf..00000000 --- a/code/typeinfo/ClassCasts.java +++ /dev/null @@ -1,16 +0,0 @@ -// typeinfo/ClassCasts.java -// (c)2020 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. - -class Building {} -class House extends Building {} - -public class ClassCasts { - public static void main(String[] args) { - Building b = new House(); - Class houseType = House.class; - House h = houseType.cast(b); - h = (House)b; // ... or just do this. - } -} diff --git a/code/typeinfo/ClassInitialization.java b/code/typeinfo/ClassInitialization.java deleted file mode 100644 index ba1d50e8..00000000 --- a/code/typeinfo/ClassInitialization.java +++ /dev/null @@ -1,57 +0,0 @@ -// typeinfo/ClassInitialization.java -// (c)2020 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. -import java.util.*; - -class Initable { - static final int STATIC_FINAL = 47; - static final int STATIC_FINAL2 = - ClassInitialization.rand.nextInt(1000); - static { - System.out.println("Initializing Initable"); - } -} - -class Initable2 { - static int staticNonFinal = 147; - static { - System.out.println("Initializing Initable2"); - } -} - -class Initable3 { - static int staticNonFinal = 74; - static { - System.out.println("Initializing Initable3"); - } -} - -public class ClassInitialization { - public static Random rand = new Random(47); - public static void - main(String[] args) throws Exception { - Class initable = Initable.class; - System.out.println("After creating Initable ref"); - // Does not trigger initialization: - System.out.println(Initable.STATIC_FINAL); - // Does trigger initialization: - System.out.println(Initable.STATIC_FINAL2); - // Does trigger initialization: - System.out.println(Initable2.staticNonFinal); - Class initable3 = Class.forName("Initable3"); - System.out.println("After creating Initable3 ref"); - System.out.println(Initable3.staticNonFinal); - } -} -/* Output: -After creating Initable ref -47 -Initializing Initable -258 -Initializing Initable2 -147 -Initializing Initable3 -After creating Initable3 ref -74 -*/ diff --git a/code/typeinfo/DynamicSupplier.java b/code/typeinfo/DynamicSupplier.java deleted file mode 100644 index 271af639..00000000 --- a/code/typeinfo/DynamicSupplier.java +++ /dev/null @@ -1,42 +0,0 @@ -// typeinfo/DynamicSupplier.java -// (c)2020 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. -import java.util.function.*; -import java.util.stream.*; - -class CountedInteger { - private static long counter; - private final long id = counter++; - @Override - public String toString() { return Long.toString(id); } -} - -public class DynamicSupplier implements Supplier { - private Class type; - public DynamicSupplier(Class type) { - this.type = type; - } - @SuppressWarnings("deprecation") - public T get() { - try { - return type.newInstance(); - } catch(Exception e) { - throw new RuntimeException(e); - } - } - public static void main(String[] args) { - Stream.generate( - new DynamicSupplier<>(CountedInteger.class)) - .skip(10) - .limit(5) - .forEach(System.out::println); - } -} -/* Output: -10 -11 -12 -13 -14 -*/ diff --git a/code/typeinfo/FamilyVsExactType.java b/code/typeinfo/FamilyVsExactType.java deleted file mode 100644 index 5981bbe6..00000000 --- a/code/typeinfo/FamilyVsExactType.java +++ /dev/null @@ -1,62 +0,0 @@ -// typeinfo/FamilyVsExactType.java -// (c)2020 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. -// The difference between instanceof and class -// {java typeinfo.FamilyVsExactType} -package typeinfo; - -class Base {} -class Derived extends Base {} - -public class FamilyVsExactType { - static void test(Object x) { - System.out.println( - "Testing x of type " + x.getClass()); - System.out.println( - "x instanceof Base " + (x instanceof Base)); - System.out.println( - "x instanceof Derived " + (x instanceof Derived)); - System.out.println( - "Base.isInstance(x) " + Base.class.isInstance(x)); - System.out.println( - "Derived.isInstance(x) " + - Derived.class.isInstance(x)); - System.out.println( - "x.getClass() == Base.class " + - (x.getClass() == Base.class)); - System.out.println( - "x.getClass() == Derived.class " + - (x.getClass() == Derived.class)); - System.out.println( - "x.getClass().equals(Base.class)) "+ - (x.getClass().equals(Base.class))); - System.out.println( - "x.getClass().equals(Derived.class)) " + - (x.getClass().equals(Derived.class))); - } - public static void main(String[] args) { - test(new Base()); - test(new Derived()); - } -} -/* Output: -Testing x of type class typeinfo.Base -x instanceof Base true -x instanceof Derived false -Base.isInstance(x) true -Derived.isInstance(x) false -x.getClass() == Base.class true -x.getClass() == Derived.class false -x.getClass().equals(Base.class)) true -x.getClass().equals(Derived.class)) false -Testing x of type class typeinfo.Derived -x instanceof Base true -x instanceof Derived true -Base.isInstance(x) true -Derived.isInstance(x) true -x.getClass() == Base.class false -x.getClass() == Derived.class true -x.getClass().equals(Base.class)) false -x.getClass().equals(Derived.class)) true -*/ diff --git a/code/typeinfo/GenericClassReferences.java b/code/typeinfo/GenericClassReferences.java deleted file mode 100644 index 81ba7f7d..00000000 --- a/code/typeinfo/GenericClassReferences.java +++ /dev/null @@ -1,14 +0,0 @@ -// typeinfo/GenericClassReferences.java -// (c)2020 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. - -public class GenericClassReferences { - public static void main(String[] args) { - Class intClass = int.class; - Class genericIntClass = int.class; - genericIntClass = Integer.class; // Same thing - intClass = double.class; - // genericIntClass = double.class; // Illegal - } -} diff --git a/code/typeinfo/HiddenImplementation.java b/code/typeinfo/HiddenImplementation.java deleted file mode 100644 index 7b41f657..00000000 --- a/code/typeinfo/HiddenImplementation.java +++ /dev/null @@ -1,44 +0,0 @@ -// typeinfo/HiddenImplementation.java -// (c)2020 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. -// Sneaking around package hiding -import typeinfo.interfacea.*; -import typeinfo.packageaccess.*; -import java.lang.reflect.*; - -public class HiddenImplementation { - public static void - main(String[] args) throws Exception { - A a = HiddenC.makeA(); - a.f(); - System.out.println(a.getClass().getName()); - // Compile error: cannot find symbol 'C': - /* if(a instanceof C) { - C c = (C)a; - c.g(); - } */ - // Oops! Reflection still allows us to call g(): - callHiddenMethod(a, "g"); - // And even less accessible methods! - callHiddenMethod(a, "u"); - callHiddenMethod(a, "v"); - callHiddenMethod(a, "w"); - } - static void - callHiddenMethod(Object a, String methodName) - throws Exception { - Method g = - a.getClass().getDeclaredMethod(methodName); - g.setAccessible(true); - g.invoke(a); - } -} -/* Output: -public C.f() -typeinfo.packageaccess.C -public C.g() -package C.u() -protected C.v() -private C.w() -*/ diff --git a/code/typeinfo/InnerImplementation.java b/code/typeinfo/InnerImplementation.java deleted file mode 100644 index 2b6541fa..00000000 --- a/code/typeinfo/InnerImplementation.java +++ /dev/null @@ -1,49 +0,0 @@ -// typeinfo/InnerImplementation.java -// (c)2020 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. -// Private inner classes can't hide from reflection -import typeinfo.interfacea.*; - -class InnerA { - private static class C implements A { - public void f() { - System.out.println("public C.f()"); - } - public void g() { - System.out.println("public C.g()"); - } - void u() { - System.out.println("package C.u()"); - } - protected void v() { - System.out.println("protected C.v()"); - } - private void w() { - System.out.println("private C.w()"); - } - } - public static A makeA() { return new C(); } -} - -public class InnerImplementation { - public static void - main(String[] args) throws Exception { - A a = InnerA.makeA(); - a.f(); - System.out.println(a.getClass().getName()); - // Reflection still gets into the private class: - HiddenImplementation.callHiddenMethod(a, "g"); - HiddenImplementation.callHiddenMethod(a, "u"); - HiddenImplementation.callHiddenMethod(a, "v"); - HiddenImplementation.callHiddenMethod(a, "w"); - } -} -/* Output: -public C.f() -InnerA$C -public C.g() -package C.u() -protected C.v() -private C.w() -*/ diff --git a/code/typeinfo/InterfaceViolation.java b/code/typeinfo/InterfaceViolation.java deleted file mode 100644 index 06b13f65..00000000 --- a/code/typeinfo/InterfaceViolation.java +++ /dev/null @@ -1,27 +0,0 @@ -// typeinfo/InterfaceViolation.java -// (c)2020 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. -// Sneaking around an interface -import typeinfo.interfacea.*; - -class B implements A { - public void f() {} - public void g() {} -} - -public class InterfaceViolation { - public static void main(String[] args) { - A a = new B(); - a.f(); - // a.g(); // Compile error - System.out.println(a.getClass().getName()); - if(a instanceof B) { - B b = (B)a; - b.g(); - } - } -} -/* Output: -B -*/ diff --git a/code/typeinfo/ModifyingPrivateFields.java b/code/typeinfo/ModifyingPrivateFields.java deleted file mode 100644 index fa1a175d..00000000 --- a/code/typeinfo/ModifyingPrivateFields.java +++ /dev/null @@ -1,49 +0,0 @@ -// typeinfo/ModifyingPrivateFields.java -// (c)2020 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. -import java.lang.reflect.*; - -class WithPrivateFinalField { - private int i = 1; - private final String s = "I'm totally safe"; - private String s2 = "Am I safe?"; - @Override - public String toString() { - return "i = " + i + ", " + s + ", " + s2; - } -} - -public class ModifyingPrivateFields { - public static void - main(String[] args) throws Exception { - WithPrivateFinalField pf = - new WithPrivateFinalField(); - System.out.println(pf); - Field f = pf.getClass().getDeclaredField("i"); - f.setAccessible(true); - System.out.println( - "f.getInt(pf): " + f.getInt(pf)); - f.setInt(pf, 47); - System.out.println(pf); - f = pf.getClass().getDeclaredField("s"); - f.setAccessible(true); - System.out.println("f.get(pf): " + f.get(pf)); - f.set(pf, "No, you're not!"); - System.out.println(pf); - f = pf.getClass().getDeclaredField("s2"); - f.setAccessible(true); - System.out.println("f.get(pf): " + f.get(pf)); - f.set(pf, "No, you're not!"); - System.out.println(pf); - } -} -/* Output: -i = 1, I'm totally safe, Am I safe? -f.getInt(pf): 1 -i = 47, I'm totally safe, Am I safe? -f.get(pf): I'm totally safe -i = 47, I'm totally safe, Am I safe? -f.get(pf): Am I safe? -i = 47, I'm totally safe, No, you're not! -*/ diff --git a/code/typeinfo/NullRobot.java b/code/typeinfo/NullRobot.java deleted file mode 100644 index d174ca94..00000000 --- a/code/typeinfo/NullRobot.java +++ /dev/null @@ -1,63 +0,0 @@ -// typeinfo/NullRobot.java -// (c)2020 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. -// Using a dynamic proxy to create an Optional -import java.lang.reflect.*; -import java.util.*; -import java.util.stream.*; -import onjava.*; - -class NullRobotProxyHandler -implements InvocationHandler { - private String nullName; - private Robot proxied = new NRobot(); - NullRobotProxyHandler(Class type) { - nullName = type.getSimpleName() + " NullRobot"; - } - private class NRobot implements Null, Robot { - @Override - public String name() { return nullName; } - @Override - public String model() { return nullName; } - @Override - public List operations() { - return Collections.emptyList(); - } - } - @Override - public Object - invoke(Object proxy, Method method, Object[] args) - throws Throwable { - return method.invoke(proxied, args); - } -} - -public class NullRobot { - public static Robot - newNullRobot(Class type) { - return (Robot)Proxy.newProxyInstance( - NullRobot.class.getClassLoader(), - new Class[]{ Null.class, Robot.class }, - new NullRobotProxyHandler(type)); - } - public static void main(String[] args) { - Stream.of( - new SnowRemovalRobot("SnowBee"), - newNullRobot(SnowRemovalRobot.class) - ).forEach(Robot::test); - } -} -/* Output: -Robot name: SnowBee -Robot model: SnowBot Series 11 -SnowBee can shovel snow -SnowBee shoveling snow -SnowBee can chip ice -SnowBee chipping ice -SnowBee can clear the roof -SnowBee clearing roof -[Null Robot] -Robot name: SnowRemovalRobot NullRobot -Robot model: SnowRemovalRobot NullRobot -*/ diff --git a/code/typeinfo/Operation.java b/code/typeinfo/Operation.java deleted file mode 100644 index dc872230..00000000 --- a/code/typeinfo/Operation.java +++ /dev/null @@ -1,15 +0,0 @@ -// typeinfo/Operation.java -// (c)2020 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. -import java.util.function.*; - -public class Operation { - public final Supplier description; - public final Runnable command; - public - Operation(Supplier descr, Runnable cmd) { - description = descr; - command = cmd; - } -} diff --git a/code/typeinfo/Person.java b/code/typeinfo/Person.java deleted file mode 100644 index 7a9807c0..00000000 --- a/code/typeinfo/Person.java +++ /dev/null @@ -1,49 +0,0 @@ -// typeinfo/Person.java -// (c)2020 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. -// Using Optional with regular classes -import onjava.*; -import java.util.*; - -class Person { - public final Optional first; - public final Optional last; - public final Optional address; - // etc. - public final boolean empty; - Person(String first, String last, String address) { - this.first = Optional.ofNullable(first); - this.last = Optional.ofNullable(last); - this.address = Optional.ofNullable(address); - empty = !this.first.isPresent() - && !this.last.isPresent() - && !this.address.isPresent(); - } - Person(String first, String last) { - this(first, last, null); - } - Person(String last) { this(null, last, null); } - Person() { this(null, null, null); } - @Override - public String toString() { - if(empty) - return ""; - return (first.orElse("") + - " " + last.orElse("") + - " " + address.orElse("")).trim(); - } - public static void main(String[] args) { - System.out.println(new Person()); - System.out.println(new Person("Smith")); - System.out.println(new Person("Bob", "Smith")); - System.out.println(new Person("Bob", "Smith", - "11 Degree Lane, Frostbite Falls, MN")); - } -} -/* Output: - -Smith -Bob Smith -Bob Smith 11 Degree Lane, Frostbite Falls, MN -*/ diff --git a/code/typeinfo/PetCount.java b/code/typeinfo/PetCount.java deleted file mode 100644 index 53438d29..00000000 --- a/code/typeinfo/PetCount.java +++ /dev/null @@ -1,65 +0,0 @@ -// typeinfo/PetCount.java -// (c)2020 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. -// Using instanceof -import typeinfo.pets.*; -import java.util.*; - -public class PetCount { - static class Counter extends HashMap { - public void count(String type) { - Integer quantity = get(type); - if(quantity == null) - put(type, 1); - else - put(type, quantity + 1); - } - } - public static void - countPets(PetCreator creator) { - Counter counter = new Counter(); - for(Pet pet : Pets.array(20)) { - // List each individual pet: - System.out.print( - pet.getClass().getSimpleName() + " "); - if(pet instanceof Pet) - counter.count("Pet"); - if(pet instanceof Dog) - counter.count("Dog"); - if(pet instanceof Mutt) - counter.count("Mutt"); - if(pet instanceof Pug) - counter.count("Pug"); - if(pet instanceof Cat) - counter.count("Cat"); - if(pet instanceof EgyptianMau) - counter.count("EgyptianMau"); - if(pet instanceof Manx) - counter.count("Manx"); - if(pet instanceof Cymric) - counter.count("Cymric"); - if(pet instanceof Rodent) - counter.count("Rodent"); - if(pet instanceof Rat) - counter.count("Rat"); - if(pet instanceof Mouse) - counter.count("Mouse"); - if(pet instanceof Hamster) - counter.count("Hamster"); - } - // Show the counts: - System.out.println(); - System.out.println(counter); - } - public static void main(String[] args) { - countPets(new ForNameCreator()); - } -} -/* Output: -Rat Manx Cymric Mutt Pug Cymric Pug Manx Cymric Rat -EgyptianMau Hamster EgyptianMau Mutt Mutt Cymric Mouse -Pug Mouse Cymric -{EgyptianMau=2, Pug=3, Rat=2, Cymric=5, Mouse=2, Cat=9, -Manx=7, Rodent=5, Mutt=3, Dog=6, Pet=20, Hamster=1} -*/ diff --git a/code/typeinfo/PetCount2.java b/code/typeinfo/PetCount2.java deleted file mode 100644 index c65e0138..00000000 --- a/code/typeinfo/PetCount2.java +++ /dev/null @@ -1,18 +0,0 @@ -// typeinfo/PetCount2.java -// (c)2020 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. -import typeinfo.pets.*; - -public class PetCount2 { - public static void main(String[] args) { - PetCount.countPets(Pets.CREATOR); - } -} -/* Output: -Rat Manx Cymric Mutt Pug Cymric Pug Manx Cymric Rat -EgyptianMau Hamster EgyptianMau Mutt Mutt Cymric Mouse -Pug Mouse Cymric -{EgyptianMau=2, Pug=3, Rat=2, Cymric=5, Mouse=2, Cat=9, -Manx=7, Rodent=5, Mutt=3, Dog=6, Pet=20, Hamster=1} -*/ diff --git a/code/typeinfo/PetCount3.java b/code/typeinfo/PetCount3.java deleted file mode 100644 index 5b08fb66..00000000 --- a/code/typeinfo/PetCount3.java +++ /dev/null @@ -1,53 +0,0 @@ -// typeinfo/PetCount3.java -// (c)2020 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. -// Using isInstance() -import java.util.*; -import java.util.stream.*; -import onjava.*; -import typeinfo.pets.*; - -public class PetCount3 { - static class Counter extends - LinkedHashMap, Integer> { - Counter() { - super(LiteralPetCreator.ALL_TYPES.stream() - .map(lpc -> Pair.make(lpc, 0)) - .collect( - Collectors.toMap(Pair::key, Pair::value))); - } - public void count(Pet pet) { - // Class.isInstance() eliminates instanceofs: - entrySet().stream() - .filter(pair -> pair.getKey().isInstance(pet)) - .forEach(pair -> - put(pair.getKey(), pair.getValue() + 1)); - } - @Override - public String toString() { - String result = entrySet().stream() - .map(pair -> String.format("%s=%s", - pair.getKey().getSimpleName(), - pair.getValue())) - .collect(Collectors.joining(", ")); - return "{" + result + "}"; - } - } - public static void main(String[] args) { - Counter petCount = new Counter(); - Pets.stream() - .limit(20) - .peek(petCount::count) - .forEach(p -> System.out.print( - p.getClass().getSimpleName() + " ")); - System.out.println("\n" + petCount); - } -} -/* Output: -Rat Manx Cymric Mutt Pug Cymric Pug Manx Cymric Rat -EgyptianMau Hamster EgyptianMau Mutt Mutt Cymric Mouse -Pug Mouse Cymric -{Rat=2, Pug=3, Mutt=3, Mouse=2, Cat=9, Dog=6, Cymric=5, -EgyptianMau=2, Rodent=5, Hamster=1, Manx=7, Pet=20} -*/ diff --git a/code/typeinfo/PetCount4.java b/code/typeinfo/PetCount4.java deleted file mode 100644 index 1ea4873a..00000000 --- a/code/typeinfo/PetCount4.java +++ /dev/null @@ -1,26 +0,0 @@ -// typeinfo/PetCount4.java -// (c)2020 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. -import typeinfo.pets.*; -import onjava.*; - -public class PetCount4 { - public static void main(String[] args) { - TypeCounter counter = new TypeCounter(Pet.class); - Pets.stream() - .limit(20) - .peek(counter::count) - .forEach(p -> System.out.print( - p.getClass().getSimpleName() + " ")); - System.out.println("\n" + counter); - } -} -/* Output: -Rat Manx Cymric Mutt Pug Cymric Pug Manx Cymric Rat -EgyptianMau Hamster EgyptianMau Mutt Mutt Cymric Mouse -Pug Mouse Cymric -{Dog=6, Manx=7, Cat=9, Rodent=5, Hamster=1, Rat=2, -Pug=3, Mutt=3, Cymric=5, EgyptianMau=2, Pet=20, -Mouse=2} -*/ diff --git a/code/typeinfo/Position.java b/code/typeinfo/Position.java deleted file mode 100644 index ca81643b..00000000 --- a/code/typeinfo/Position.java +++ /dev/null @@ -1,51 +0,0 @@ -// typeinfo/Position.java -// (c)2020 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. -import java.util.*; - -class EmptyTitleException extends RuntimeException {} - -class Position { - private String title; - private Person person; - Position(String jobTitle, Person employee) { - setTitle(jobTitle); - setPerson(employee); - } - Position(String jobTitle) { - this(jobTitle, null); - } - public String getTitle() { return title; } - public void setTitle(String newTitle) { - // Throws EmptyTitleException if newTitle is null: - title = Optional.ofNullable(newTitle) - .orElseThrow(EmptyTitleException::new); - } - public Person getPerson() { return person; } - public void setPerson(Person newPerson) { - // Uses empty Person if newPerson is null: - person = Optional.ofNullable(newPerson) - .orElse(new Person()); - } - @Override - public String toString() { - return "Position: " + title + - ", Employee: " + person; - } - public static void main(String[] args) { - System.out.println(new Position("CEO")); - System.out.println(new Position("Programmer", - new Person("Arthur", "Fonzarelli"))); - try { - new Position(null); - } catch(Exception e) { - System.out.println("caught " + e); - } - } -} -/* Output: -Position: CEO, Employee: -Position: Programmer, Employee: Arthur Fonzarelli -caught EmptyTitleException -*/ diff --git a/code/typeinfo/RegisteredFactories.java b/code/typeinfo/RegisteredFactories.java deleted file mode 100644 index 7708cc4e..00000000 --- a/code/typeinfo/RegisteredFactories.java +++ /dev/null @@ -1,95 +0,0 @@ -// typeinfo/RegisteredFactories.java -// (c)2020 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. -// Registering Factories in the base class -import java.util.*; -import java.util.function.*; -import java.util.stream.*; - -class Part implements Supplier { - @Override - public String toString() { - return getClass().getSimpleName(); - } - static List> prototypes = - Arrays.asList( - new FuelFilter(), - new AirFilter(), - new CabinAirFilter(), - new OilFilter(), - new FanBelt(), - new PowerSteeringBelt(), - new GeneratorBelt() - ); - private static Random rand = new Random(47); - public Part get() { - int n = rand.nextInt(prototypes.size()); - return prototypes.get(n).get(); - } -} - -class Filter extends Part {} - -class FuelFilter extends Filter { - @Override - public FuelFilter get() { return new FuelFilter(); } -} - -class AirFilter extends Filter { - @Override - public AirFilter get() { return new AirFilter(); } -} - -class CabinAirFilter extends Filter { - @Override - public CabinAirFilter get() { - return new CabinAirFilter(); - } -} - -class OilFilter extends Filter { - @Override - public OilFilter get() { return new OilFilter(); } -} - -class Belt extends Part {} - -class FanBelt extends Belt { - @Override - public FanBelt get() { return new FanBelt(); } -} - -class GeneratorBelt extends Belt { - @Override - public GeneratorBelt get() { - return new GeneratorBelt(); - } -} - -class PowerSteeringBelt extends Belt { - @Override - public PowerSteeringBelt get() { - return new PowerSteeringBelt(); - } -} - -public class RegisteredFactories { - public static void main(String[] args) { - Stream.generate(new Part()) - .limit(10) - .forEach(System.out::println); - } -} -/* Output: -GeneratorBelt -CabinAirFilter -GeneratorBelt -AirFilter -PowerSteeringBelt -CabinAirFilter -FuelFilter -PowerSteeringBelt -PowerSteeringBelt -FuelFilter -*/ diff --git a/code/typeinfo/Robot.java b/code/typeinfo/Robot.java deleted file mode 100644 index 803ee9fe..00000000 --- a/code/typeinfo/Robot.java +++ /dev/null @@ -1,22 +0,0 @@ -// typeinfo/Robot.java -// (c)2020 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. -import onjava.*; -import java.util.*; - -public interface Robot { - String name(); - String model(); - List operations(); - static void test(Robot r) { - if(r instanceof Null) - System.out.println("[Null Robot]"); - System.out.println("Robot name: " + r.name()); - System.out.println("Robot model: " + r.model()); - for(Operation operation : r.operations()) { - System.out.println(operation.description.get()); - operation.command.run(); - } - } -} diff --git a/code/typeinfo/SelectingMethods.java b/code/typeinfo/SelectingMethods.java deleted file mode 100644 index d87e928b..00000000 --- a/code/typeinfo/SelectingMethods.java +++ /dev/null @@ -1,69 +0,0 @@ -// typeinfo/SelectingMethods.java -// (c)2020 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. -// Looking for particular methods in a dynamic proxy -import java.lang.reflect.*; - -class MethodSelector implements InvocationHandler { - private Object proxied; - MethodSelector(Object proxied) { - this.proxied = proxied; - } - @Override - public Object - invoke(Object proxy, Method method, Object[] args) - throws Throwable { - if(method.getName().equals("interesting")) - System.out.println( - "Proxy detected the interesting method"); - return method.invoke(proxied, args); - } -} - -interface SomeMethods { - void boring1(); - void boring2(); - void interesting(String arg); - void boring3(); -} - -class Implementation implements SomeMethods { - @Override - public void boring1() { - System.out.println("boring1"); - } - @Override - public void boring2() { - System.out.println("boring2"); - } - @Override - public void interesting(String arg) { - System.out.println("interesting " + arg); - } - @Override - public void boring3() { - System.out.println("boring3"); - } -} - -class SelectingMethods { - public static void main(String[] args) { - SomeMethods proxy = - (SomeMethods)Proxy.newProxyInstance( - SomeMethods.class.getClassLoader(), - new Class[]{ SomeMethods.class }, - new MethodSelector(new Implementation())); - proxy.boring1(); - proxy.boring2(); - proxy.interesting("bonobo"); - proxy.boring3(); - } -} -/* Output: -boring1 -boring2 -Proxy detected the interesting method -interesting bonobo -boring3 -*/ diff --git a/code/typeinfo/Shapes.java b/code/typeinfo/Shapes.java deleted file mode 100644 index 34a2bc56..00000000 --- a/code/typeinfo/Shapes.java +++ /dev/null @@ -1,39 +0,0 @@ -// typeinfo/Shapes.java -// (c)2020 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. -import java.util.stream.*; - -abstract class Shape { - void draw() { System.out.println(this + ".draw()"); } - @Override - public abstract String toString(); -} - -class Circle extends Shape { - @Override - public String toString() { return "Circle"; } -} - -class Square extends Shape { - @Override - public String toString() { return "Square"; } -} - -class Triangle extends Shape { - @Override - public String toString() { return "Triangle"; } -} - -public class Shapes { - public static void main(String[] args) { - Stream.of( - new Circle(), new Square(), new Triangle()) - .forEach(Shape::draw); - } -} -/* Output: -Circle.draw() -Square.draw() -Triangle.draw() -*/ diff --git a/code/typeinfo/ShowMethods.java b/code/typeinfo/ShowMethods.java deleted file mode 100644 index be1b635b..00000000 --- a/code/typeinfo/ShowMethods.java +++ /dev/null @@ -1,71 +0,0 @@ -// typeinfo/ShowMethods.java -// (c)2020 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. -// Using reflection to show all the methods of a class, -// even if the methods are defined in the base class -// {java ShowMethods ShowMethods} -import java.lang.reflect.*; -import java.util.regex.*; - -public class ShowMethods { - private static String usage = - "usage:\n" + - "ShowMethods qualified.class.name\n" + - "To show all methods in class or:\n" + - "ShowMethods qualified.class.name word\n" + - "To search for methods involving 'word'"; - private static Pattern p = Pattern.compile("\\w+\\."); - public static void main(String[] args) { - if(args.length < 1) { - System.out.println(usage); - System.exit(0); - } - int lines = 0; - try { - Class c = Class.forName(args[0]); - Method[] methods = c.getMethods(); - Constructor[] ctors = c.getConstructors(); - if(args.length == 1) { - for(Method method : methods) - System.out.println( - p.matcher( - method.toString()).replaceAll("")); - for(Constructor ctor : ctors) - System.out.println( - p.matcher(ctor.toString()).replaceAll("")); - lines = methods.length + ctors.length; - } else { - for(Method method : methods) - if(method.toString().contains(args[1])) { - System.out.println(p.matcher( - method.toString()).replaceAll("")); - lines++; - } - for(Constructor ctor : ctors) - if(ctor.toString().contains(args[1])) { - System.out.println(p.matcher( - ctor.toString()).replaceAll("")); - lines++; - } - } - } catch(ClassNotFoundException e) { - System.out.println("No such class: " + e); - } - } -} -/* Output: -public static void main(String[]) -public final void wait() throws InterruptedException -public final void wait(long,int) throws -InterruptedException -public final native void wait(long) throws -InterruptedException -public boolean equals(Object) -public String toString() -public native int hashCode() -public final native Class getClass() -public final native void notify() -public final native void notifyAll() -public ShowMethods() -*/ diff --git a/code/typeinfo/SimpleDynamicProxy.java b/code/typeinfo/SimpleDynamicProxy.java deleted file mode 100644 index bece57f8..00000000 --- a/code/typeinfo/SimpleDynamicProxy.java +++ /dev/null @@ -1,53 +0,0 @@ -// typeinfo/SimpleDynamicProxy.java -// (c)2020 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. -import java.lang.reflect.*; - -class DynamicProxyHandler implements InvocationHandler { - private Object proxied; - DynamicProxyHandler(Object proxied) { - this.proxied = proxied; - } - @Override - public Object - invoke(Object proxy, Method method, Object[] args) - throws Throwable { - System.out.println( - "**** proxy: " + proxy.getClass() + - ", method: " + method + ", args: " + args); - if(args != null) - for(Object arg : args) - System.out.println(" " + arg); - return method.invoke(proxied, args); - } -} - -class SimpleDynamicProxy { - public static void consumer(Interface iface) { - iface.doSomething(); - iface.somethingElse("bonobo"); - } - public static void main(String[] args) { - RealObject real = new RealObject(); - consumer(real); - // Insert a proxy and call again: - Interface proxy = (Interface)Proxy.newProxyInstance( - Interface.class.getClassLoader(), - new Class[]{ Interface.class }, - new DynamicProxyHandler(real)); - consumer(proxy); - } -} -/* Output: -doSomething -somethingElse bonobo -**** proxy: class $Proxy0, method: public abstract void -Interface.doSomething(), args: null -doSomething -**** proxy: class $Proxy0, method: public abstract void -Interface.somethingElse(java.lang.String), args: -[Ljava.lang.Object;@6bc7c054 - bonobo -somethingElse bonobo -*/ diff --git a/code/typeinfo/SimpleProxyDemo.java b/code/typeinfo/SimpleProxyDemo.java deleted file mode 100644 index 24c3c2c2..00000000 --- a/code/typeinfo/SimpleProxyDemo.java +++ /dev/null @@ -1,57 +0,0 @@ -// typeinfo/SimpleProxyDemo.java -// (c)2020 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. - -interface Interface { - void doSomething(); - void somethingElse(String arg); -} - -class RealObject implements Interface { - @Override - public void doSomething() { - System.out.println("doSomething"); - } - @Override - public void somethingElse(String arg) { - System.out.println("somethingElse " + arg); - } -} - -class SimpleProxy implements Interface { - private Interface proxied; - SimpleProxy(Interface proxied) { - this.proxied = proxied; - } - @Override - public void doSomething() { - System.out.println("SimpleProxy doSomething"); - proxied.doSomething(); - } - @Override - public void somethingElse(String arg) { - System.out.println( - "SimpleProxy somethingElse " + arg); - proxied.somethingElse(arg); - } -} - -class SimpleProxyDemo { - public static void consumer(Interface iface) { - iface.doSomething(); - iface.somethingElse("bonobo"); - } - public static void main(String[] args) { - consumer(new RealObject()); - consumer(new SimpleProxy(new RealObject())); - } -} -/* Output: -doSomething -somethingElse bonobo -SimpleProxy doSomething -doSomething -SimpleProxy somethingElse bonobo -somethingElse bonobo -*/ diff --git a/code/typeinfo/SnowRemovalRobot.java b/code/typeinfo/SnowRemovalRobot.java deleted file mode 100644 index af5b46cd..00000000 --- a/code/typeinfo/SnowRemovalRobot.java +++ /dev/null @@ -1,42 +0,0 @@ -// typeinfo/SnowRemovalRobot.java -// (c)2020 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. -import java.util.*; - -public class SnowRemovalRobot implements Robot { - private String name; - public SnowRemovalRobot(String name) { - this.name = name; - } - @Override - public String name() { return name; } - @Override - public String model() { return "SnowBot Series 11"; } - private List ops = Arrays.asList( - new Operation( - () -> name + " can shovel snow", - () -> System.out.println( - name + " shoveling snow")), - new Operation( - () -> name + " can chip ice", - () -> System.out.println(name + " chipping ice")), - new Operation( - () -> name + " can clear the roof", - () -> System.out.println( - name + " clearing roof"))); - public List operations() { return ops; } - public static void main(String[] args) { - Robot.test(new SnowRemovalRobot("Slusher")); - } -} -/* Output: -Robot name: Slusher -Robot model: SnowBot Series 11 -Slusher can shovel snow -Slusher shoveling snow -Slusher can chip ice -Slusher chipping ice -Slusher can clear the roof -Slusher clearing roof -*/ diff --git a/code/typeinfo/Staff.java b/code/typeinfo/Staff.java deleted file mode 100644 index 569e598f..00000000 --- a/code/typeinfo/Staff.java +++ /dev/null @@ -1,63 +0,0 @@ -// typeinfo/Staff.java -// (c)2020 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. -import java.util.*; - -public class Staff extends ArrayList { - public void add(String title, Person person) { - add(new Position(title, person)); - } - public void add(String... titles) { - for(String title : titles) - add(new Position(title)); - } - public Staff(String... titles) { add(titles); } - public boolean positionAvailable(String title) { - for(Position position : this) - if(position.getTitle().equals(title) && - position.getPerson().empty) - return true; - return false; - } - public void fillPosition(String title, Person hire) { - for(Position position : this) - if(position.getTitle().equals(title) && - position.getPerson().empty) { - position.setPerson(hire); - return; - } - throw new RuntimeException( - "Position " + title + " not available"); - } - public static void main(String[] args) { - Staff staff = new Staff("President", "CTO", - "Marketing Manager", "Product Manager", - "Project Lead", "Software Engineer", - "Software Engineer", "Software Engineer", - "Software Engineer", "Test Engineer", - "Technical Writer"); - staff.fillPosition("President", - new Person("Me", "Last", "The Top, Lonely At")); - staff.fillPosition("Project Lead", - new Person("Janet", "Planner", "The Burbs")); - if(staff.positionAvailable("Software Engineer")) - staff.fillPosition("Software Engineer", - new Person( - "Bob", "Coder", "Bright Light City")); - System.out.println(staff); - } -} -/* Output: -[Position: President, Employee: Me Last The Top, Lonely -At, Position: CTO, Employee: , Position: -Marketing Manager, Employee: , Position: Product -Manager, Employee: , Position: Project Lead, -Employee: Janet Planner The Burbs, Position: Software -Engineer, Employee: Bob Coder Bright Light City, -Position: Software Engineer, Employee: , -Position: Software Engineer, Employee: , -Position: Software Engineer, Employee: , -Position: Test Engineer, Employee: , Position: -Technical Writer, Employee: ] -*/ diff --git a/code/typeinfo/SweetShop.java b/code/typeinfo/SweetShop.java deleted file mode 100644 index f85b8c3f..00000000 --- a/code/typeinfo/SweetShop.java +++ /dev/null @@ -1,42 +0,0 @@ -// typeinfo/SweetShop.java -// (c)2020 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. -// Examination of the way the class loader works - -class Cookie { - static { System.out.println("Loading Cookie"); } -} - -class Gum { - static { System.out.println("Loading Gum"); } -} - -class Candy { - static { System.out.println("Loading Candy"); } -} - -public class SweetShop { - public static void main(String[] args) { - System.out.println("inside main"); - new Candy(); - System.out.println("After creating Candy"); - try { - Class.forName("Gum"); - } catch(ClassNotFoundException e) { - System.out.println("Couldn't find Gum"); - } - System.out.println("After Class.forName(\"Gum\")"); - new Cookie(); - System.out.println("After creating Cookie"); - } -} -/* Output: -inside main -Loading Candy -After creating Candy -Loading Gum -After Class.forName("Gum") -Loading Cookie -After creating Cookie -*/ diff --git a/code/typeinfo/WildcardClassReferences.java b/code/typeinfo/WildcardClassReferences.java deleted file mode 100644 index 32d75e86..00000000 --- a/code/typeinfo/WildcardClassReferences.java +++ /dev/null @@ -1,11 +0,0 @@ -// typeinfo/WildcardClassReferences.java -// (c)2020 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. - -public class WildcardClassReferences { - public static void main(String[] args) { - Class intClass = int.class; - intClass = double.class; - } -} diff --git a/code/typeinfo/interfacea/A.java b/code/typeinfo/interfacea/A.java deleted file mode 100644 index 2ebb99d3..00000000 --- a/code/typeinfo/interfacea/A.java +++ /dev/null @@ -1,9 +0,0 @@ -// typeinfo/interfacea/A.java -// (c)2020 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 typeinfo.interfacea; - -public interface A { - void f(); -} diff --git a/code/typeinfo/packageaccess/HiddenC.java b/code/typeinfo/packageaccess/HiddenC.java deleted file mode 100644 index 9fb8ffde..00000000 --- a/code/typeinfo/packageaccess/HiddenC.java +++ /dev/null @@ -1,29 +0,0 @@ -// typeinfo/packageaccess/HiddenC.java -// (c)2020 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 typeinfo.packageaccess; -import typeinfo.interfacea.*; - -class C implements A { - @Override - public void f() { - System.out.println("public C.f()"); - } - public void g() { - System.out.println("public C.g()"); - } - void u() { - System.out.println("package C.u()"); - } - protected void v() { - System.out.println("protected C.v()"); - } - private void w() { - System.out.println("private C.w()"); - } -} - -public class HiddenC { - public static A makeA() { return new C(); } -} diff --git a/code/typeinfo/pets/Cat.java b/code/typeinfo/pets/Cat.java deleted file mode 100644 index 75781fd7..00000000 --- a/code/typeinfo/pets/Cat.java +++ /dev/null @@ -1,10 +0,0 @@ -// typeinfo/pets/Cat.java -// (c)2020 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 typeinfo.pets; - -public class Cat extends Pet { - public Cat(String name) { super(name); } - public Cat() { super(); } -} diff --git a/code/typeinfo/pets/Cymric.java b/code/typeinfo/pets/Cymric.java deleted file mode 100644 index fd86fa95..00000000 --- a/code/typeinfo/pets/Cymric.java +++ /dev/null @@ -1,10 +0,0 @@ -// typeinfo/pets/Cymric.java -// (c)2020 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 typeinfo.pets; - -public class Cymric extends Manx { - public Cymric(String name) { super(name); } - public Cymric() { super(); } -} diff --git a/code/typeinfo/pets/Dog.java b/code/typeinfo/pets/Dog.java deleted file mode 100644 index 68f43a32..00000000 --- a/code/typeinfo/pets/Dog.java +++ /dev/null @@ -1,10 +0,0 @@ -// typeinfo/pets/Dog.java -// (c)2020 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 typeinfo.pets; - -public class Dog extends Pet { - public Dog(String name) { super(name); } - public Dog() { super(); } -} diff --git a/code/typeinfo/pets/EgyptianMau.java b/code/typeinfo/pets/EgyptianMau.java deleted file mode 100644 index adbdfbb1..00000000 --- a/code/typeinfo/pets/EgyptianMau.java +++ /dev/null @@ -1,10 +0,0 @@ -// typeinfo/pets/EgyptianMau.java -// (c)2020 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 typeinfo.pets; - -public class EgyptianMau extends Cat { - public EgyptianMau(String name) { super(name); } - public EgyptianMau() { super(); } -} diff --git a/code/typeinfo/pets/ForNameCreator.java b/code/typeinfo/pets/ForNameCreator.java deleted file mode 100644 index 29351efa..00000000 --- a/code/typeinfo/pets/ForNameCreator.java +++ /dev/null @@ -1,37 +0,0 @@ -// typeinfo/pets/ForNameCreator.java -// (c)2020 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 typeinfo.pets; -import java.util.*; - -public class ForNameCreator extends PetCreator { - private static List> types = - new ArrayList<>(); - // Types you want randomly created: - private static String[] typeNames = { - "typeinfo.pets.Mutt", - "typeinfo.pets.Pug", - "typeinfo.pets.EgyptianMau", - "typeinfo.pets.Manx", - "typeinfo.pets.Cymric", - "typeinfo.pets.Rat", - "typeinfo.pets.Mouse", - "typeinfo.pets.Hamster" - }; - @SuppressWarnings("unchecked") - private static void loader() { - try { - for(String name : typeNames) - types.add( - (Class)Class.forName(name)); - } catch(ClassNotFoundException e) { - throw new RuntimeException(e); - } - } - static { loader(); } - @Override - public List> types() { - return types; - } -} diff --git a/code/typeinfo/pets/Hamster.java b/code/typeinfo/pets/Hamster.java deleted file mode 100644 index 8408ef62..00000000 --- a/code/typeinfo/pets/Hamster.java +++ /dev/null @@ -1,10 +0,0 @@ -// typeinfo/pets/Hamster.java -// (c)2020 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 typeinfo.pets; - -public class Hamster extends Rodent { - public Hamster(String name) { super(name); } - public Hamster() { super(); } -} diff --git a/code/typeinfo/pets/Individual.java b/code/typeinfo/pets/Individual.java deleted file mode 100644 index e3c87dac..00000000 --- a/code/typeinfo/pets/Individual.java +++ /dev/null @@ -1,46 +0,0 @@ -// typeinfo/pets/Individual.java -// (c)2020 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 typeinfo.pets; -import java.util.*; - -public class -Individual implements Comparable { - private static long counter = 0; - private final long id = counter++; - private String name; - public Individual(String name) { this.name = name; } - // 'name' is optional: - public Individual() {} - @Override - public String toString() { - return getClass().getSimpleName() + - (name == null ? "" : " " + name); - } - public long id() { return id; } - @Override - public boolean equals(Object o) { - return o instanceof Individual && - Objects.equals(id, ((Individual)o).id); - } - @Override - public int hashCode() { - return Objects.hash(name, id); - } - @Override - public int compareTo(Individual arg) { - // Compare by class name first: - String first = getClass().getSimpleName(); - String argFirst = arg.getClass().getSimpleName(); - int firstCompare = first.compareTo(argFirst); - if(firstCompare != 0) - return firstCompare; - if(name != null && arg.name != null) { - int secondCompare = name.compareTo(arg.name); - if(secondCompare != 0) - return secondCompare; - } - return (arg.id < id ? -1 : (arg.id == id ? 0 : 1)); - } -} diff --git a/code/typeinfo/pets/LiteralPetCreator.java b/code/typeinfo/pets/LiteralPetCreator.java deleted file mode 100644 index 398baac8..00000000 --- a/code/typeinfo/pets/LiteralPetCreator.java +++ /dev/null @@ -1,39 +0,0 @@ -// typeinfo/pets/LiteralPetCreator.java -// (c)2020 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. -// Using class literals -// {java typeinfo.pets.LiteralPetCreator} -package typeinfo.pets; -import java.util.*; - -public class LiteralPetCreator extends PetCreator { - // No try block needed. - @SuppressWarnings("unchecked") - public static - final List> ALL_TYPES = - Collections.unmodifiableList(Arrays.asList( - Pet.class, Dog.class, Cat.class, Rodent.class, - Mutt.class, Pug.class, EgyptianMau.class, - Manx.class, Cymric.class, Rat.class, - Mouse.class, Hamster.class)); - // Types for random creation: - private static final - List> TYPES = - ALL_TYPES.subList(ALL_TYPES.indexOf(Mutt.class), - ALL_TYPES.size()); - @Override - public List> types() { - return TYPES; - } - public static void main(String[] args) { - System.out.println(TYPES); - } -} -/* Output: -[class typeinfo.pets.Mutt, class typeinfo.pets.Pug, -class typeinfo.pets.EgyptianMau, class -typeinfo.pets.Manx, class typeinfo.pets.Cymric, class -typeinfo.pets.Rat, class typeinfo.pets.Mouse, class -typeinfo.pets.Hamster] -*/ diff --git a/code/typeinfo/pets/Manx.java b/code/typeinfo/pets/Manx.java deleted file mode 100644 index 6a5534b1..00000000 --- a/code/typeinfo/pets/Manx.java +++ /dev/null @@ -1,10 +0,0 @@ -// typeinfo/pets/Manx.java -// (c)2020 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 typeinfo.pets; - -public class Manx extends Cat { - public Manx(String name) { super(name); } - public Manx() { super(); } -} diff --git a/code/typeinfo/pets/Mouse.java b/code/typeinfo/pets/Mouse.java deleted file mode 100644 index bbb97cda..00000000 --- a/code/typeinfo/pets/Mouse.java +++ /dev/null @@ -1,10 +0,0 @@ -// typeinfo/pets/Mouse.java -// (c)2020 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 typeinfo.pets; - -public class Mouse extends Rodent { - public Mouse(String name) { super(name); } - public Mouse() { super(); } -} diff --git a/code/typeinfo/pets/Mutt.java b/code/typeinfo/pets/Mutt.java deleted file mode 100644 index f51814b9..00000000 --- a/code/typeinfo/pets/Mutt.java +++ /dev/null @@ -1,10 +0,0 @@ -// typeinfo/pets/Mutt.java -// (c)2020 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 typeinfo.pets; - -public class Mutt extends Dog { - public Mutt(String name) { super(name); } - public Mutt() { super(); } -} diff --git a/code/typeinfo/pets/Person.java b/code/typeinfo/pets/Person.java deleted file mode 100644 index 4dcfff2c..00000000 --- a/code/typeinfo/pets/Person.java +++ /dev/null @@ -1,9 +0,0 @@ -// typeinfo/pets/Person.java -// (c)2020 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 typeinfo.pets; - -public class Person extends Individual { - public Person(String name) { super(name); } -} diff --git a/code/typeinfo/pets/Pet.java b/code/typeinfo/pets/Pet.java deleted file mode 100644 index dcbfd4ab..00000000 --- a/code/typeinfo/pets/Pet.java +++ /dev/null @@ -1,10 +0,0 @@ -// typeinfo/pets/Pet.java -// (c)2020 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 typeinfo.pets; - -public class Pet extends Individual { - public Pet(String name) { super(name); } - public Pet() { super(); } -} diff --git a/code/typeinfo/pets/PetCreator.java b/code/typeinfo/pets/PetCreator.java deleted file mode 100644 index 76909aa9..00000000 --- a/code/typeinfo/pets/PetCreator.java +++ /dev/null @@ -1,28 +0,0 @@ -// typeinfo/pets/PetCreator.java -// (c)2020 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. -// Creates random sequences of Pets -package typeinfo.pets; -import java.util.*; -import java.util.function.*; -import java.lang.reflect.InvocationTargetException; - -public abstract -class PetCreator implements Supplier { - private Random rand = new Random(47); - // The List of the different types of Pet to create: - public abstract List> types(); - public Pet get() { // Create one random Pet - int n = rand.nextInt(types().size()); - try { - return types().get(n) - .getConstructor().newInstance(); - } catch(InstantiationException | - NoSuchMethodException | - InvocationTargetException | - IllegalAccessException e) { - throw new RuntimeException(e); - } - } -} diff --git a/code/typeinfo/pets/Pets.java b/code/typeinfo/pets/Pets.java deleted file mode 100644 index be3037a1..00000000 --- a/code/typeinfo/pets/Pets.java +++ /dev/null @@ -1,30 +0,0 @@ -// typeinfo/pets/Pets.java -// (c)2020 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. -// Facade to produce a default PetCreator -package typeinfo.pets; -import java.util.*; -import java.util.stream.*; - -public class Pets { - public static final PetCreator CREATOR = - new LiteralPetCreator(); - public static Pet get() { - return CREATOR.get(); - } - public static Pet[] array(int size) { - Pet[] result = new Pet[size]; - for(int i = 0; i < size; i++) - result[i] = CREATOR.get(); - return result; - } - public static List list(int size) { - List result = new ArrayList<>(); - Collections.addAll(result, array(size)); - return result; - } - public static Stream stream() { - return Stream.generate(CREATOR); - } -} diff --git a/code/typeinfo/pets/Pug.java b/code/typeinfo/pets/Pug.java deleted file mode 100644 index 9d8ab467..00000000 --- a/code/typeinfo/pets/Pug.java +++ /dev/null @@ -1,10 +0,0 @@ -// typeinfo/pets/Pug.java -// (c)2020 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 typeinfo.pets; - -public class Pug extends Dog { - public Pug(String name) { super(name); } - public Pug() { super(); } -} diff --git a/code/typeinfo/pets/Rat.java b/code/typeinfo/pets/Rat.java deleted file mode 100644 index 2ce5534b..00000000 --- a/code/typeinfo/pets/Rat.java +++ /dev/null @@ -1,10 +0,0 @@ -// typeinfo/pets/Rat.java -// (c)2020 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 typeinfo.pets; - -public class Rat extends Rodent { - public Rat(String name) { super(name); } - public Rat() { super(); } -} diff --git a/code/typeinfo/pets/Rodent.java b/code/typeinfo/pets/Rodent.java deleted file mode 100644 index 7b998d0a..00000000 --- a/code/typeinfo/pets/Rodent.java +++ /dev/null @@ -1,10 +0,0 @@ -// typeinfo/pets/Rodent.java -// (c)2020 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 typeinfo.pets; - -public class Rodent extends Pet { - public Rodent(String name) { super(name); } - public Rodent() { super(); } -} diff --git a/code/typeinfo/toys/GenericToyTest.java b/code/typeinfo/toys/GenericToyTest.java deleted file mode 100644 index 7dc016cd..00000000 --- a/code/typeinfo/toys/GenericToyTest.java +++ /dev/null @@ -1,23 +0,0 @@ -// typeinfo/toys/GenericToyTest.java -// (c)2020 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. -// Testing class Class -// {java typeinfo.toys.GenericToyTest} -package typeinfo.toys; - -public class GenericToyTest { - @SuppressWarnings("deprecation") - public static void - main(String[] args) throws Exception { - Class ftClass = FancyToy.class; - // Produces exact type: - FancyToy fancyToy = ftClass.newInstance(); - Class up = - ftClass.getSuperclass(); - // This won't compile: - // Class up2 = ftClass.getSuperclass(); - // Only produces Object: - Object obj = up.newInstance(); - } -} diff --git a/code/typeinfo/toys/ToyTest.java b/code/typeinfo/toys/ToyTest.java deleted file mode 100644 index e4e5e92d..00000000 --- a/code/typeinfo/toys/ToyTest.java +++ /dev/null @@ -1,78 +0,0 @@ -// typeinfo/toys/ToyTest.java -// (c)2020 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. -// Testing class Class -// {java typeinfo.toys.ToyTest} -package typeinfo.toys; -import java.lang.reflect.InvocationTargetException; - -interface HasBatteries {} -interface Waterproof {} -interface Shoots {} - -class Toy { - // Comment out the following no-arg - // constructor to see NoSuchMethodError - Toy() {} - Toy(int i) {} -} - -class FancyToy extends Toy -implements HasBatteries, Waterproof, Shoots { - FancyToy() { super(1); } -} - -public class ToyTest { - static void printInfo(Class cc) { - System.out.println("Class name: " + cc.getName() + - " is interface? [" + cc.isInterface() + "]"); - System.out.println( - "Simple name: " + cc.getSimpleName()); - System.out.println( - "Canonical name : " + cc.getCanonicalName()); - } - @SuppressWarnings("deprecation") - public static void main(String[] args) { - Class c = null; - try { - c = Class.forName("typeinfo.toys.FancyToy"); - } catch(ClassNotFoundException e) { - System.out.println("Can't find FancyToy"); - System.exit(1); - } - printInfo(c); - for(Class face : c.getInterfaces()) - printInfo(face); - Class up = c.getSuperclass(); - Object obj = null; - try { - // Requires no-arg constructor: - obj = up.newInstance(); - } catch(Exception e) { - throw new - RuntimeException("Cannot instantiate"); - } - printInfo(obj.getClass()); - } -} -/* Output: -Class name: typeinfo.toys.FancyToy is interface? -[false] -Simple name: FancyToy -Canonical name : typeinfo.toys.FancyToy -Class name: typeinfo.toys.HasBatteries is interface? -[true] -Simple name: HasBatteries -Canonical name : typeinfo.toys.HasBatteries -Class name: typeinfo.toys.Waterproof is interface? -[true] -Simple name: Waterproof -Canonical name : typeinfo.toys.Waterproof -Class name: typeinfo.toys.Shoots is interface? [true] -Simple name: Shoots -Canonical name : typeinfo.toys.Shoots -Class name: typeinfo.toys.Toy is interface? [false] -Simple name: Toy -Canonical name : typeinfo.toys.Toy -*/ diff --git a/code/validating/Assert1.java b/code/validating/Assert1.java deleted file mode 100644 index 013a72f6..00000000 --- a/code/validating/Assert1.java +++ /dev/null @@ -1,19 +0,0 @@ -// validating/Assert1.java -// (c)2020 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. -// Non-informative style of assert -// Must run using -ea flag: -// {java -ea Assert1} -// {ThrowsException} - -public class Assert1 { - public static void main(String[] args) { - assert false; - } -} -/* Output: -___[ Error Output ]___ -Exception in thread "main" java.lang.AssertionError - at Assert1.main(Assert1.java:9) -*/ diff --git a/code/validating/Assert2.java b/code/validating/Assert2.java deleted file mode 100644 index 61b4827d..00000000 --- a/code/validating/Assert2.java +++ /dev/null @@ -1,20 +0,0 @@ -// validating/Assert2.java -// (c)2020 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. -// Assert with an information-expression -// {java Assert2 -ea} -// {ThrowsException} - -public class Assert2 { - public static void main(String[] args) { - assert false: - "Here's a message saying what happened"; - } -} -/* Output: -___[ Error Output ]___ -Exception in thread "main" java.lang.AssertionError: -Here's a message saying what happened - at Assert2.main(Assert2.java:8) -*/ diff --git a/code/validating/BadMicroBenchmark.java b/code/validating/BadMicroBenchmark.java deleted file mode 100644 index 2634e67c..00000000 --- a/code/validating/BadMicroBenchmark.java +++ /dev/null @@ -1,29 +0,0 @@ -// validating/BadMicroBenchmark.java -// (c)2020 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. -// {ExcludeFromTravisCI} -import java.util.*; -import onjava.Timer; - -public class BadMicroBenchmark { - static final int SIZE = 250_000_000; - public static void main(String[] args) { - try { // For machines with insufficient memory - long[] la = new long[SIZE]; - System.out.println("setAll: " + - Timer.duration(() -> - Arrays.setAll(la, n -> n))); - System.out.println("parallelSetAll: " + - Timer.duration(() -> - Arrays.parallelSetAll(la, n -> n))); - } catch(OutOfMemoryError e) { - System.out.println("Insufficient memory"); - System.exit(0); - } - } -} -/* Output: -setAll: 272 -parallelSetAll: 301 -*/ diff --git a/code/validating/BadMicroBenchmark2.java b/code/validating/BadMicroBenchmark2.java deleted file mode 100644 index 123036a0..00000000 --- a/code/validating/BadMicroBenchmark2.java +++ /dev/null @@ -1,35 +0,0 @@ -// validating/BadMicroBenchmark2.java -// (c)2020 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. -// Relying on a common resource -import java.util.*; -import onjava.Timer; - -public class BadMicroBenchmark2 { - // SIZE reduced to make it run faster: - static final int SIZE = 5_000_000; - public static void main(String[] args) { - long[] la = new long[SIZE]; - Random r = new Random(); - System.out.println("parallelSetAll: " + - Timer.duration(() -> - Arrays.parallelSetAll(la, n -> r.nextLong()))); - System.out.println("setAll: " + - Timer.duration(() -> - Arrays.setAll(la, n -> r.nextLong()))); - SplittableRandom sr = new SplittableRandom(); - System.out.println("parallelSetAll: " + - Timer.duration(() -> - Arrays.parallelSetAll(la, n -> sr.nextLong()))); - System.out.println("setAll: " + - Timer.duration(() -> - Arrays.setAll(la, n -> sr.nextLong()))); - } -} -/* Output: -parallelSetAll: 1147 -setAll: 174 -parallelSetAll: 86 -setAll: 39 -*/ diff --git a/code/validating/CircularQueue.java b/code/validating/CircularQueue.java deleted file mode 100644 index 405e4410..00000000 --- a/code/validating/CircularQueue.java +++ /dev/null @@ -1,91 +0,0 @@ -// validating/CircularQueue.java -// (c)2020 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. -// Demonstration of Design by Contract (DbC) -package validating; -import java.util.*; - -public class CircularQueue { - private Object[] data; - private int - in = 0, // Next available storage space - out = 0; // Next gettable object - // Has it wrapped around the circular queue? - private boolean wrapped = false; - public CircularQueue(int size) { - data = new Object[size]; - // Must be true after construction: - assert invariant(); - } - public boolean empty() { - return !wrapped && in == out; - } - public boolean full() { - return wrapped && in == out; - } - public boolean isWrapped() { return wrapped; } - public void put(Object item) { - precondition(item != null, "put() null item"); - precondition(!full(), - "put() into full CircularQueue"); - assert invariant(); - data[in++] = item; - if(in >= data.length) { - in = 0; - wrapped = true; - } - assert invariant(); - } - public Object get() { - precondition(!empty(), - "get() from empty CircularQueue"); - assert invariant(); - Object returnVal = data[out]; - data[out] = null; - out++; - if(out >= data.length) { - out = 0; - wrapped = false; - } - assert postcondition( - returnVal != null, - "Null item in CircularQueue"); - assert invariant(); - return returnVal; - } - // Design-by-contract support methods: - private static void - precondition(boolean cond, String msg) { - if(!cond) throw new CircularQueueException(msg); - } - private static boolean - postcondition(boolean cond, String msg) { - if(!cond) throw new CircularQueueException(msg); - return true; - } - private boolean invariant() { - // Guarantee that no null values are in the - // region of 'data' that holds objects: - for(int i = out; i != in; i = (i + 1) % data.length) - if(data[i] == null) - throw new CircularQueueException( - "null in CircularQueue"); - // Guarantee that only null values are outside the - // region of 'data' that holds objects: - if(full()) return true; - for(int i = in; i != out; i = (i + 1) % data.length) - if(data[i] != null) - throw new CircularQueueException( - "non-null outside of CircularQueue range: " - + dump()); - return true; - } - public String dump() { - return "in = " + in + - ", out = " + out + - ", full() = " + full() + - ", empty() = " + empty() + - ", CircularQueue = " + Arrays.asList(data); - } -} diff --git a/code/validating/CircularQueueException.java b/code/validating/CircularQueueException.java deleted file mode 100644 index 142b8ece..00000000 --- a/code/validating/CircularQueueException.java +++ /dev/null @@ -1,12 +0,0 @@ -// validating/CircularQueueException.java -// (c)2020 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 validating; - -public class -CircularQueueException extends RuntimeException { - public CircularQueueException(String why) { - super(why); - } -} diff --git a/code/validating/CountedList.java b/code/validating/CountedList.java deleted file mode 100644 index 6c780f21..00000000 --- a/code/validating/CountedList.java +++ /dev/null @@ -1,16 +0,0 @@ -// validating/CountedList.java -// (c)2020 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. -// Keeps track of how many of itself are created. -package validating; -import java.util.*; - -public class CountedList extends ArrayList { - private static int counter = 0; - private int id = counter++; - public CountedList() { - System.out.println("CountedList #" + id); - } - public int getId() { return id; } -} diff --git a/code/validating/GuavaAssertions.java b/code/validating/GuavaAssertions.java deleted file mode 100644 index a499f079..00000000 --- a/code/validating/GuavaAssertions.java +++ /dev/null @@ -1,49 +0,0 @@ -// validating/GuavaAssertions.java -// (c)2020 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. -// Assertions that are always enabled. -import com.google.common.base.*; -import static com.google.common.base.Verify.*; - -public class GuavaAssertions { - public static void main(String[] args) { - verify(2 + 2 == 4); - try { - verify(1 + 2 == 4); - } catch(VerifyException e) { - System.out.println(e); - } - try { - verify(1 + 2 == 4, "Bad math"); - } catch(VerifyException e) { - System.out.println(e.getMessage()); - } - try { - verify(1 + 2 == 4, "Bad math: %s", "not 4"); - } catch(VerifyException e) { - System.out.println(e.getMessage()); - } - String s = ""; - s = verifyNotNull(s); - s = null; - try { - verifyNotNull(s); - } catch(VerifyException e) { - System.out.println(e.getMessage()); - } - try { - verifyNotNull( - s, "Shouldn't be null: %s", "arg s"); - } catch(VerifyException e) { - System.out.println(e.getMessage()); - } - } -} -/* Output: -com.google.common.base.VerifyException -Bad math -Bad math: not 4 -expected a non-null reference -Shouldn't be null: arg s -*/ diff --git a/code/validating/GuavaPreconditions.java b/code/validating/GuavaPreconditions.java deleted file mode 100644 index 3cfc66ae..00000000 --- a/code/validating/GuavaPreconditions.java +++ /dev/null @@ -1,125 +0,0 @@ -// validating/GuavaPreconditions.java -// (c)2020 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. -// Demonstrating Guava Preconditions -import java.util.function.*; -import static com.google.common.base.Preconditions.*; - -public class GuavaPreconditions { - static void test(Consumer c, String s) { - try { - System.out.println(s); - c.accept(s); - System.out.println("Success"); - } catch(Exception e) { - String type = e.getClass().getSimpleName(); - String msg = e.getMessage(); - System.out.println(type + - (msg == null ? "" : ": " + msg)); - } - } - public static void main(String[] args) { - test(s -> s = checkNotNull(s), "X"); - test(s -> s = checkNotNull(s), null); - test(s -> s = checkNotNull(s, "s was null"), null); - test(s -> s = checkNotNull( - s, "s was null, %s %s", "arg2", "arg3"), null); - - test(s -> checkArgument(s == "Fozzie"), "Fozzie"); - test(s -> checkArgument(s == "Fozzie"), "X"); - test(s -> checkArgument(s == "Fozzie"), null); - test(s -> checkArgument( - s == "Fozzie", "Bear Left!"), null); - test(s -> checkArgument( - s == "Fozzie", "Bear Left! %s Right!", "Frog"), - null); - - test(s -> checkState(s.length() > 6), "Mortimer"); - test(s -> checkState(s.length() > 6), "Mort"); - test(s -> checkState(s.length() > 6), null); - - test(s -> - checkElementIndex(6, s.length()), "Robert"); - test(s -> - checkElementIndex(6, s.length()), "Bob"); - test(s -> - checkElementIndex(6, s.length()), null); - - test(s -> - checkPositionIndex(6, s.length()), "Robert"); - test(s -> - checkPositionIndex(6, s.length()), "Bob"); - test(s -> - checkPositionIndex(6, s.length()), null); - - test(s -> checkPositionIndexes( - 0, 6, s.length()), "Hieronymus"); - test(s -> checkPositionIndexes( - 0, 10, s.length()), "Hieronymus"); - test(s -> checkPositionIndexes( - 0, 11, s.length()), "Hieronymus"); - test(s -> checkPositionIndexes( - -1, 6, s.length()), "Hieronymus"); - test(s -> checkPositionIndexes( - 7, 6, s.length()), "Hieronymus"); - test(s -> checkPositionIndexes( - 0, 6, s.length()), null); - } -} -/* Output: -X -Success -null -NullPointerException -null -NullPointerException: s was null -null -NullPointerException: s was null, arg2 arg3 -Fozzie -Success -X -IllegalArgumentException -null -IllegalArgumentException -null -IllegalArgumentException: Bear Left! -null -IllegalArgumentException: Bear Left! Frog Right! -Mortimer -Success -Mort -IllegalStateException -null -NullPointerException -Robert -IndexOutOfBoundsException: index (6) must be less than -size (6) -Bob -IndexOutOfBoundsException: index (6) must be less than -size (3) -null -NullPointerException -Robert -Success -Bob -IndexOutOfBoundsException: index (6) must not be -greater than size (3) -null -NullPointerException -Hieronymus -Success -Hieronymus -Success -Hieronymus -IndexOutOfBoundsException: end index (11) must not be -greater than size (10) -Hieronymus -IndexOutOfBoundsException: start index (-1) must not be -negative -Hieronymus -IndexOutOfBoundsException: end index (6) must not be -less than start index (7) -null -NullPointerException -*/ diff --git a/code/validating/Inverter1.java b/code/validating/Inverter1.java deleted file mode 100644 index 8ef828d6..00000000 --- a/code/validating/Inverter1.java +++ /dev/null @@ -1,9 +0,0 @@ -// validating/Inverter1.java -// (c)2020 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 validating; - -public class Inverter1 implements StringInverter { - public String invert(String str) { return str; } -} diff --git a/code/validating/Inverter2.java b/code/validating/Inverter2.java deleted file mode 100644 index 3fb862fd..00000000 --- a/code/validating/Inverter2.java +++ /dev/null @@ -1,19 +0,0 @@ -// validating/Inverter2.java -// (c)2020 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 validating; -import static java.lang.Character.*; - -public class Inverter2 implements StringInverter { - public String invert(String str) { - String result = ""; - for(int i = 0; i < str.length(); i++) { - char c = str.charAt(i); - result += isUpperCase(c) ? - toLowerCase(c) : - toUpperCase(c); - } - return result; - } -} diff --git a/code/validating/Inverter3.java b/code/validating/Inverter3.java deleted file mode 100644 index 4bd53c82..00000000 --- a/code/validating/Inverter3.java +++ /dev/null @@ -1,21 +0,0 @@ -// validating/Inverter3.java -// (c)2020 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 validating; -import static java.lang.Character.*; - -public class Inverter3 implements StringInverter { - public String invert(String str) { - if(str.length() > 30) - throw new RuntimeException("argument too long!"); - String result = ""; - for(int i = 0; i < str.length(); i++) { - char c = str.charAt(i); - result += isUpperCase(c) ? - toLowerCase(c) : - toUpperCase(c); - } - return result; - } -} diff --git a/code/validating/Inverter4.java b/code/validating/Inverter4.java deleted file mode 100644 index 0b787059..00000000 --- a/code/validating/Inverter4.java +++ /dev/null @@ -1,26 +0,0 @@ -// validating/Inverter4.java -// (c)2020 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 validating; -import static java.lang.Character.*; - -public class Inverter4 implements StringInverter { - static final String ALLOWED = - "abcdefghijklmnopqrstuvwxyz ,." + - "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - public String invert(String str) { - if(str.length() > 30) - throw new RuntimeException("argument too long!"); - String result = ""; - for(int i = 0; i < str.length(); i++) { - char c = str.charAt(i); - if(ALLOWED.indexOf(c) == -1) - throw new RuntimeException(c + " Not allowed"); - result += isUpperCase(c) ? - toLowerCase(c) : - toUpperCase(c); - } - return result; - } -} diff --git a/code/validating/LoaderAssertions.java b/code/validating/LoaderAssertions.java deleted file mode 100644 index 52cac347..00000000 --- a/code/validating/LoaderAssertions.java +++ /dev/null @@ -1,28 +0,0 @@ -// validating/LoaderAssertions.java -// (c)2020 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. -// Using the class loader to enable assertions -// {ThrowsException} - -public class LoaderAssertions { - public static void main(String[] args) { - ClassLoader.getSystemClassLoader() - .setDefaultAssertionStatus(true); - new Loaded().go(); - } -} - -class Loaded { - public void go() { - assert false: "Loaded.go()"; - } -} -/* Output: -___[ Error Output ]___ -Exception in thread "main" java.lang.AssertionError: -Loaded.go() - at Loaded.go(LoaderAssertions.java:15) - at -LoaderAssertions.main(LoaderAssertions.java:9) -*/ diff --git a/code/validating/NonNullConstruction.java b/code/validating/NonNullConstruction.java deleted file mode 100644 index a95483dd..00000000 --- a/code/validating/NonNullConstruction.java +++ /dev/null @@ -1,18 +0,0 @@ -// validating/NonNullConstruction.java -// (c)2020 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. -import static com.google.common.base.Preconditions.*; - -public class NonNullConstruction { - private Integer n; - private String s; - NonNullConstruction(Integer n, String s) { - this.n = checkNotNull(n); - this.s = checkNotNull(s); - } - public static void main(String[] args) { - NonNullConstruction nnc = - new NonNullConstruction(3, "Trousers"); - } -} diff --git a/code/validating/SLF4JLevels.java b/code/validating/SLF4JLevels.java deleted file mode 100644 index c851e7c3..00000000 --- a/code/validating/SLF4JLevels.java +++ /dev/null @@ -1,29 +0,0 @@ -// validating/SLF4JLevels.java -// (c)2020 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. -import org.slf4j.*; - -public class SLF4JLevels { - private static Logger log = - LoggerFactory.getLogger(SLF4JLevels.class); - public static void main(String[] args) { - log.trace("Hello"); - log.debug("Logging"); - log.info("Using"); - log.warn("the SLF4J"); - log.error("Facade"); - } -} -/* Output: -2017-05-09T06:07:52.846 -[main] TRACE SLF4JLevels - Hello -2017-05-09T06:07:52.849 -[main] DEBUG SLF4JLevels - Logging -2017-05-09T06:07:52.849 -[main] INFO SLF4JLevels - Using -2017-05-09T06:07:52.850 -[main] WARN SLF4JLevels - the SLF4J -2017-05-09T06:07:52.851 -[main] ERROR SLF4JLevels - Facade -*/ diff --git a/code/validating/SLF4JLogging.java b/code/validating/SLF4JLogging.java deleted file mode 100644 index f2e94d6e..00000000 --- a/code/validating/SLF4JLogging.java +++ /dev/null @@ -1,17 +0,0 @@ -// validating/SLF4JLogging.java -// (c)2020 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. -import org.slf4j.*; - -public class SLF4JLogging { - private static Logger log = - LoggerFactory.getLogger(SLF4JLogging.class); - public static void main(String[] args) { - log.info("hello logging"); - } -} -/* Output: -2017-05-09T06:07:53.418 -[main] INFO SLF4JLogging - hello logging -*/ diff --git a/code/validating/SimpleDebugging.java b/code/validating/SimpleDebugging.java deleted file mode 100644 index 863e7de3..00000000 --- a/code/validating/SimpleDebugging.java +++ /dev/null @@ -1,40 +0,0 @@ -// validating/SimpleDebugging.java -// (c)2020 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. -// {ThrowsException} - -public class SimpleDebugging { - private static void foo1() { - System.out.println("In foo1"); - foo2(); - } - private static void foo2() { - System.out.println("In foo2"); - foo3(); - } - private static void foo3() { - System.out.println("In foo3"); - int j = 1; - j--; - int i = 5 / j; - } - public static void main(String[] args) { - foo1(); - } -} -/* Output: -In foo1 -In foo2 -In foo3 -___[ Error Output ]___ -Exception in thread "main" -java.lang.ArithmeticException: / by zero - at -SimpleDebugging.foo3(SimpleDebugging.java:17) - at -SimpleDebugging.foo2(SimpleDebugging.java:11) - at SimpleDebugging.foo1(SimpleDebugging.java:7) - at -SimpleDebugging.main(SimpleDebugging.java:20) -*/ diff --git a/code/validating/StringInverter.java b/code/validating/StringInverter.java deleted file mode 100644 index 34c933a7..00000000 --- a/code/validating/StringInverter.java +++ /dev/null @@ -1,9 +0,0 @@ -// validating/StringInverter.java -// (c)2020 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 validating; - -interface StringInverter { - String invert(String str); -} diff --git a/code/validating/jmh/JMH1.java b/code/validating/jmh/JMH1.java deleted file mode 100644 index 79eb749a..00000000 --- a/code/validating/jmh/JMH1.java +++ /dev/null @@ -1,31 +0,0 @@ -// validating/jmh/JMH1.java -// (c)2020 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 validating.jmh; -import java.util.*; -import org.openjdk.jmh.annotations.*; -import java.util.concurrent.TimeUnit; - -@State(Scope.Thread) -@BenchmarkMode(Mode.AverageTime) -@OutputTimeUnit(TimeUnit.MICROSECONDS) -// Increase these three for more accuracy: -@Warmup(iterations = 5) -@Measurement(iterations = 5) -@Fork(1) -public class JMH1 { - private long[] la; - @Setup - public void setup() { - la = new long[250_000_000]; - } - @Benchmark - public void setAll() { - Arrays.setAll(la, n -> n); - } - @Benchmark - public void parallelSetAll() { - Arrays.parallelSetAll(la, n -> n); - } -} diff --git a/code/validating/jmh/JMH2.java b/code/validating/jmh/JMH2.java deleted file mode 100644 index ae7b56f9..00000000 --- a/code/validating/jmh/JMH2.java +++ /dev/null @@ -1,44 +0,0 @@ -// validating/jmh/JMH2.java -// (c)2020 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 validating.jmh; -import java.util.*; -import org.openjdk.jmh.annotations.*; -import java.util.concurrent.TimeUnit; - -@State(Scope.Thread) -@BenchmarkMode(Mode.AverageTime) -@OutputTimeUnit(TimeUnit.MICROSECONDS) -@Warmup(iterations = 5) -@Measurement(iterations = 5) -@Fork(1) -public class JMH2 { - private long[] la; - @Param({ - "1", - "10", - "100", - "1000", - "10000", - "100000", - "1000000", - "10000000", - "100000000", - "250000000" - }) - int size; - - @Setup - public void setup() { - la = new long[size]; - } - @Benchmark - public void setAll() { - Arrays.setAll(la, n -> n); - } - @Benchmark - public void parallelSetAll() { - Arrays.parallelSetAll(la, n -> n); - } -} diff --git a/code/validating/jmh/JMH3.java b/code/validating/jmh/JMH3.java deleted file mode 100644 index 8ce9bb0c..00000000 --- a/code/validating/jmh/JMH3.java +++ /dev/null @@ -1,48 +0,0 @@ -// validating/jmh/JMH3.java -// (c)2020 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 validating.jmh; -import java.util.*; -import org.openjdk.jmh.annotations.*; -import java.util.concurrent.TimeUnit; - -@State(Scope.Thread) -@BenchmarkMode(Mode.AverageTime) -@OutputTimeUnit(TimeUnit.MICROSECONDS) -@Warmup(iterations = 5) -@Measurement(iterations = 5) -@Fork(1) -public class JMH3 { - private long[] la; - @Param({ - "1", - "10", - "100", - "1000", - "10000", - "100000", - "1000000", - "10000000", - "100000000", - "250000000" - }) - int size; - - @Setup - public void setup() { - la = new long[size]; - } - public static long f(long x) { - long quadratic = 42 * x * x + 19 * x + 47; - return Long.divideUnsigned(quadratic, x + 1); - } - @Benchmark - public void setAll() { - Arrays.setAll(la, n -> f(n)); - } - @Benchmark - public void parallelSetAll() { - Arrays.parallelSetAll(la, n -> f(n)); - } -} diff --git a/code/validating/logback.xml b/code/validating/logback.xml deleted file mode 100644 index 0a774e44..00000000 --- a/code/validating/logback.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - -%d{yyyy-MM-dd'T'HH:mm:ss.SSS} -[%thread] %-5level %logger - %msg%n - - - - - - - \ No newline at end of file diff --git a/code/validating/tests/CircularQueueTest.java b/code/validating/tests/CircularQueueTest.java deleted file mode 100644 index 8da6dc27..00000000 --- a/code/validating/tests/CircularQueueTest.java +++ /dev/null @@ -1,150 +0,0 @@ -// validating/tests/CircularQueueTest.java -// (c)2020 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 validating; -import org.junit.jupiter.api.*; -import static org.junit.jupiter.api.Assertions.*; - -public class CircularQueueTest { - private CircularQueue queue = new CircularQueue(10); - private int i = 0; - @BeforeEach - public void initialize() { - while(i < 5) // Pre-load with some data - queue.put(Integer.toString(i++)); - } - // Support methods: - private void showFullness() { - assertTrue(queue.full()); - assertFalse(queue.empty()); - System.out.println(queue.dump()); - } - private void showEmptiness() { - assertFalse(queue.full()); - assertTrue(queue.empty()); - System.out.println(queue.dump()); - } - @Test - public void full() { - System.out.println("testFull"); - System.out.println(queue.dump()); - System.out.println(queue.get()); - System.out.println(queue.get()); - while(!queue.full()) - queue.put(Integer.toString(i++)); - String msg = ""; - try { - queue.put(""); - } catch(CircularQueueException e) { - msg = e.getMessage(); - System.out.println(msg); - } - assertEquals(msg, "put() into full CircularQueue"); - showFullness(); - } - @Test - public void empty() { - System.out.println("testEmpty"); - while(!queue.empty()) - System.out.println(queue.get()); - String msg = ""; - try { - queue.get(); - } catch(CircularQueueException e) { - msg = e.getMessage(); - System.out.println(msg); - } - assertEquals(msg, "get() from empty CircularQueue"); - showEmptiness(); - } - @Test - public void nullPut() { - System.out.println("testNullPut"); - String msg = ""; - try { - queue.put(null); - } catch(CircularQueueException e) { - msg = e.getMessage(); - System.out.println(msg); - } - assertEquals(msg, "put() null item"); - } - @Test - public void circularity() { - System.out.println("testCircularity"); - while(!queue.full()) - queue.put(Integer.toString(i++)); - showFullness(); - assertTrue(queue.isWrapped()); - while(!queue.empty()) - System.out.println(queue.get()); - showEmptiness(); - while(!queue.full()) - queue.put(Integer.toString(i++)); - showFullness(); - while(!queue.empty()) - System.out.println(queue.get()); - showEmptiness(); - } -} -/* Output: -testNullPut -put() null item -testCircularity -in = 0, out = 0, full() = true, empty() = false, -CircularQueue = -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -in = 0, out = 0, full() = false, empty() = true, -CircularQueue = -[null, null, null, null, null, null, null, null, null, -null] -in = 0, out = 0, full() = true, empty() = false, -CircularQueue = -[10, 11, 12, 13, 14, 15, 16, 17, 18, 19] -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -in = 0, out = 0, full() = false, empty() = true, -CircularQueue = -[null, null, null, null, null, null, null, null, null, -null] -testFull -in = 5, out = 0, full() = false, empty() = false, -CircularQueue = -[0, 1, 2, 3, 4, null, null, null, null, null] -0 -1 -put() into full CircularQueue -in = 2, out = 2, full() = true, empty() = false, -CircularQueue = -[10, 11, 2, 3, 4, 5, 6, 7, 8, 9] -testEmpty -0 -1 -2 -3 -4 -get() from empty CircularQueue -in = 5, out = 5, full() = false, empty() = true, -CircularQueue = -[null, null, null, null, null, null, null, null, null, -null] -*/ diff --git a/code/validating/tests/CountedListTest.java b/code/validating/tests/CountedListTest.java deleted file mode 100644 index a9dc0c71..00000000 --- a/code/validating/tests/CountedListTest.java +++ /dev/null @@ -1,101 +0,0 @@ -// validating/tests/CountedListTest.java -// (c)2020 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. -// Simple use of JUnit to test CountedList. -package validating; -import java.util.*; -import org.junit.jupiter.api.*; -import static org.junit.jupiter.api.Assertions.*; - -public class CountedListTest { - private CountedList list; - @BeforeAll - static void beforeAllMsg() { - System.out.println(">>> Starting CountedListTest"); - } - @AfterAll - static void afterAllMsg() { - System.out.println(">>> Finished CountedListTest"); - } - @BeforeEach - public void initialize() { - list = new CountedList(); - System.out.println("Set up for " + list.getId()); - for(int i = 0; i < 3; i++) - list.add(Integer.toString(i)); - } - @AfterEach - public void cleanup() { - System.out.println("Cleaning up " + list.getId()); - } - @Test - public void insert() { - System.out.println("Running testInsert()"); - assertEquals(list.size(), 3); - list.add(1, "Insert"); - assertEquals(list.size(), 4); - assertEquals(list.get(1), "Insert"); - } - @Test - public void replace() { - System.out.println("Running testReplace()"); - assertEquals(list.size(), 3); - list.set(1, "Replace"); - assertEquals(list.size(), 3); - assertEquals(list.get(1), "Replace"); - } - // A helper method to simplify the code. As - // long as it's not annotated with @Test, it will - // not be automatically executed by JUnit. - private - void compare(List lst, String[] strs) { - assertArrayEquals(lst.toArray(new String[0]), strs); - } - @Test - public void order() { - System.out.println("Running testOrder()"); - compare(list, new String[] { "0", "1", "2" }); - } - @Test - public void remove() { - System.out.println("Running testRemove()"); - assertEquals(list.size(), 3); - list.remove(1); - assertEquals(list.size(), 2); - compare(list, new String[] { "0", "2" }); - } - @Test - public void addAll() { - System.out.println("Running testAddAll()"); - list.addAll(Arrays.asList(new String[] { - "An", "African", "Swallow"})); - assertEquals(list.size(), 6); - compare(list, new String[] { "0", "1", "2", - "An", "African", "Swallow" }); - } -} -/* Output: ->>> Starting CountedListTest -CountedList #0 -Set up for 0 -Running testRemove() -Cleaning up 0 -CountedList #1 -Set up for 1 -Running testReplace() -Cleaning up 1 -CountedList #2 -Set up for 2 -Running testAddAll() -Cleaning up 2 -CountedList #3 -Set up for 3 -Running testInsert() -Cleaning up 3 -CountedList #4 -Set up for 4 -Running testOrder() -Cleaning up 4 ->>> Finished CountedListTest -*/ diff --git a/code/validating/tests/DynamicStringInverterTests.java b/code/validating/tests/DynamicStringInverterTests.java deleted file mode 100644 index dc980971..00000000 --- a/code/validating/tests/DynamicStringInverterTests.java +++ /dev/null @@ -1,122 +0,0 @@ -// validating/tests/DynamicStringInverterTests.java -// (c)2020 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 validating; -import java.util.*; -import java.util.function.*; -import java.util.stream.*; -import org.junit.jupiter.api.*; -import static org.junit.jupiter.api.Assertions.*; -import static org.junit.jupiter.api.DynamicTest.*; - -class DynamicStringInverterTests { - // Combine operations to prevent code duplication: - Stream testVersions(String id, - Function test) { - List versions = Arrays.asList( - new Inverter1(), new Inverter2(), - new Inverter3(), new Inverter4()); - return DynamicTest.stream( - versions.iterator(), - inverter -> inverter.getClass().getSimpleName(), - inverter -> { - System.out.println( - inverter.getClass().getSimpleName() + - ": " + id); - try { - if(test.apply(inverter) != "fail") - System.out.println("Success"); - } catch(Exception | Error e) { - System.out.println( - "Exception: " + e.getMessage()); - } - } - ); - } - String isEqual(String lval, String rval) { - if(lval.equals(rval)) - return "success"; - System.out.println("FAIL: " + lval + " != " + rval); - return "fail"; - } - @BeforeAll - static void startMsg() { - System.out.println( - ">>> Starting DynamicStringInverterTests <<<"); - } - @AfterAll - static void endMsg() { - System.out.println( - ">>> Finished DynamicStringInverterTests <<<"); - } - @TestFactory - Stream basicInversion1() { - String in = "Exit, Pursued by a Bear."; - String out = "eXIT, pURSUED BY A bEAR."; - return testVersions( - "Basic inversion (should succeed)", - inverter -> isEqual(inverter.invert(in), out) - ); - } - @TestFactory - Stream basicInversion2() { - return testVersions( - "Basic inversion (should fail)", - inverter -> isEqual(inverter.invert("X"), "X")); - } - @TestFactory - Stream disallowedCharacters() { - String disallowed = ";-_()*&^%$#@!~`0123456789"; - return testVersions( - "Disallowed characters", - inverter -> { - String result = disallowed.chars() - .mapToObj(c -> { - String cc = Character.toString((char)c); - try { - inverter.invert(cc); - return ""; - } catch(RuntimeException e) { - return cc; - } - }).collect(Collectors.joining("")); - if(result.length() == 0) - return "success"; - System.out.println("Bad characters: " + result); - return "fail"; - } - ); - } - @TestFactory - Stream allowedCharacters() { - String lowcase = "abcdefghijklmnopqrstuvwxyz ,."; - String upcase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ ,."; - return testVersions( - "Allowed characters (should succeed)", - inverter -> { - assertEquals(inverter.invert(lowcase), upcase); - assertEquals(inverter.invert(upcase), lowcase); - return "success"; - } - ); - } - @TestFactory - Stream lengthNoGreaterThan30() { - String str = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; - assertTrue(str.length() > 30); - return testVersions( - "Length must be less than 31 (throws exception)", - inverter -> inverter.invert(str) - ); - } - @TestFactory - Stream lengthLessThan31() { - String str = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; - assertTrue(str.length() < 31); - return testVersions( - "Length must be less than 31 (should succeed)", - inverter -> inverter.invert(str) - ); - } -} diff --git a/code/validating/tests/StringInverterTests.java b/code/validating/tests/StringInverterTests.java deleted file mode 100644 index e32873b8..00000000 --- a/code/validating/tests/StringInverterTests.java +++ /dev/null @@ -1,65 +0,0 @@ -// validating/tests/StringInverterTests.java -// (c)2020 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 validating; -import java.util.*; -import java.util.stream.*; -import org.junit.jupiter.api.*; -import static org.junit.jupiter.api.Assertions.*; - -public class StringInverterTests { - StringInverter inverter = new Inverter4(); - @BeforeAll - static void startMsg() { - System.out.println(">>> StringInverterTests <<<"); - } - @Test - void basicInversion1() { - String in = "Exit, Pursued by a Bear."; - String out = "eXIT, pURSUED BY A bEAR."; - assertEquals(inverter.invert(in), out); - } - @Test - void basicInversion2() { - assertThrows(Error.class, () -> { - assertEquals(inverter.invert("X"), "X"); - }); - } - @Test - void disallowedCharacters() { - String disallowed = ";-_()*&^%$#@!~`0123456789"; - String result = disallowed.chars() - .mapToObj(c -> { - String cc = Character.toString((char)c); - try { - inverter.invert(cc); - return ""; - } catch(RuntimeException e) { - return cc; - } - }).collect(Collectors.joining("")); - assertEquals(result, disallowed); - } - @Test - void allowedCharacters() { - String lowcase = "abcdefghijklmnopqrstuvwxyz ,."; - String upcase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ ,."; - assertEquals(inverter.invert(lowcase), upcase); - assertEquals(inverter.invert(upcase), lowcase); - } - @Test - void lengthNoGreaterThan30() { - String str = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; - assertTrue(str.length() > 30); - assertThrows(RuntimeException.class, () -> { - inverter.invert(str); - }); - } - @Test - void lengthLessThan31() { - String str = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; - assertTrue(str.length() < 31); - inverter.invert(str); - } -} From 7fbae68d1707baae6a54d1ae5e6a55d2e5db2274 Mon Sep 17 00:00:00 2001 From: "jim.deng" Date: Tue, 24 Nov 2020 17:56:01 +0800 Subject: [PATCH 03/12] =?UTF-8?q?=E6=B2=A1=E6=9C=89=E7=AC=AC=E4=B8=89?= =?UTF-8?q?=E7=A7=8D=E5=BD=A2=E5=BC=8F=E5=90=A7=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book/06-Housekeeping.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/book/06-Housekeeping.md b/docs/book/06-Housekeeping.md index 0a7a5f1c..0248808c 100644 --- a/docs/book/06-Housekeeping.md +++ b/docs/book/06-Housekeeping.md @@ -1379,7 +1379,7 @@ public class ArrayInit { 在这两种形式中,初始化列表的最后一个逗号是可选的(这一特性使维护长列表变得更容易)。 -尽管第一种形式很有用,但是它更加受限,因为它只能用于数组定义处。第二种和第三种形式可以用在任何地方,甚至用在方法的内部。例如,你创建了一个 **String** 数组,将其传递给另一个类的 `main()` 方法,如下: +尽管第一种形式很有用,但是它更加受限,因为它只能用于数组定义处。第二种形式可以用在任何地方,甚至用在方法的内部。例如,你创建了一个 **String** 数组,将其传递给另一个类的 `main()` 方法,如下: ```java // housekeeping/DynamicArray.java From 84e298c79dbb73e850b43ec49a86a7cc06c521b3 Mon Sep 17 00:00:00 2001 From: "jim.deng" Date: Wed, 25 Nov 2020 17:10:16 +0800 Subject: [PATCH 04/12] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AF=AD=E5=8F=A5?= =?UTF-8?q?=E6=8B=97=E5=8F=A3=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book/08-Reuse.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/book/08-Reuse.md b/docs/book/08-Reuse.md index 824d59b9..c3f7abf7 100644 --- a/docs/book/08-Reuse.md +++ b/docs/book/08-Reuse.md @@ -690,7 +690,7 @@ doh(Milhouse) ```` -**Homer** 的所有重载方法在 **Bart** 中都是可用的,尽管 **Bart** 引入了一种新的重载方法。在下一章中你将看到,使用与基类中完全相同的签名和返回类型覆盖相同名称的方法要常见得多。否则就会令人困惑。 +**Homer** 的所有重载方法在 **Bart** 中都是可用的,尽管 **Bart** 引入了一种新的重载方法。在下一章中你将看到,使用重写(与基类中完全相同的方法签名和返回类型覆盖相同名称的方法)比起重载会更为常见,否则就会令人困惑。 你已经看到了Java 5 **@Override**注释,它不是关键字,但是可以像使用关键字一样使用它。当你打算重写一个方法时,你可以选择添加这个注释,如果你不小心用了重载而不是重写,编译器会产生一个错误消息: From 429c653bc4418cded07773a32a56a18d3c5c6230 Mon Sep 17 00:00:00 2001 From: "jim.deng" Date: Wed, 25 Nov 2020 17:57:35 +0800 Subject: [PATCH 05/12] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AF=AD=E5=8F=A5?= =?UTF-8?q?=E6=8B=97=E5=8F=A3=E9=97=AE=E9=A2=98=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book/08-Reuse.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/book/08-Reuse.md b/docs/book/08-Reuse.md index c3f7abf7..96bd5b9b 100644 --- a/docs/book/08-Reuse.md +++ b/docs/book/08-Reuse.md @@ -690,9 +690,9 @@ doh(Milhouse) ```` -**Homer** 的所有重载方法在 **Bart** 中都是可用的,尽管 **Bart** 引入了一种新的重载方法。在下一章中你将看到,使用重写(与基类中完全相同的方法签名和返回类型覆盖相同名称的方法)比起重载会更为常见,否则就会令人困惑。 +**Homer** 的所有重载方法在 **Bart** 中都是可用的,尽管 **Bart** 引入了一种新的重载方法。正如你将在下一章中看到的那样,比起重载,更常见的是覆盖同名方法,使用与基类中完全相同的方法签名(方法名和参数类型)和返回类型。否则会让人感到困惑。 -你已经看到了Java 5 **@Override**注释,它不是关键字,但是可以像使用关键字一样使用它。当你打算重写一个方法时,你可以选择添加这个注释,如果你不小心用了重载而不是重写,编译器会产生一个错误消息: +你已经看到了Java 5 **@Override**注释,它不是关键字,但是可以像使用关键字一样使用它。当你打算重写一个方法(覆盖同名方法)时,你可以选择添加这个注释,如果你不小心用了重载而不是重写,编译器会产生一个错误消息: ```java // reuse/Lisa.java @@ -709,7 +709,7 @@ class Lisa extends Homer { ``` -**{WillNotCompile}** 标记将该文件排除在本书的 **Gradle** 构建之外,但是如果你手工编译它,你将看到:方法不会覆盖超类中的方法, **@Override** 注释防止你意外地重载。 +**{WillNotCompile}** 标记将该文件排除在本书的 **Gradle** 构建之外,但是如果你手工编译它,你将看到:method does not override a method from its superclass.方法不会覆盖(重写)超类中的方法, **@Override** 注释能防止你意外地重载。 From 34e5908b67f226464a98d357aaec517faa212743 Mon Sep 17 00:00:00 2001 From: "jim.deng" Date: Wed, 25 Nov 2020 18:40:19 +0800 Subject: [PATCH 06/12] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AF=AD=E5=8F=A5?= =?UTF-8?q?=E6=8B=97=E5=8F=A3=E9=97=AE=E9=A2=98=203?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book/08-Reuse.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/book/08-Reuse.md b/docs/book/08-Reuse.md index 96bd5b9b..8e4725a6 100644 --- a/docs/book/08-Reuse.md +++ b/docs/book/08-Reuse.md @@ -690,9 +690,10 @@ doh(Milhouse) ```` -**Homer** 的所有重载方法在 **Bart** 中都是可用的,尽管 **Bart** 引入了一种新的重载方法。正如你将在下一章中看到的那样,比起重载,更常见的是覆盖同名方法,使用与基类中完全相同的方法签名(方法名和参数类型)和返回类型。否则会让人感到困惑。 +**Homer** 的所有重载方法在 **Bart** 中都是可用的,尽管 **Bart** 引入了一种新的重载方法。正如你将在下一章中看到的那样,比起重载,更常见的是覆盖同名方法,使用与基类中完全相同的方法签名[^1]和返回类型。否则会让人感到困惑。 + +你已经看到了Java 5 **@Override**注释,它不是关键字,但是可以像使用关键字一样使用它。当你打算重写一个方法[^2]时,你可以选择添加这个注释,如果你不小心用了重载而不是重写,编译器会产生一个错误消息: -你已经看到了Java 5 **@Override**注释,它不是关键字,但是可以像使用关键字一样使用它。当你打算重写一个方法(覆盖同名方法)时,你可以选择添加这个注释,如果你不小心用了重载而不是重写,编译器会产生一个错误消息: ```java // reuse/Lisa.java @@ -709,8 +710,14 @@ class Lisa extends Homer { ``` -**{WillNotCompile}** 标记将该文件排除在本书的 **Gradle** 构建之外,但是如果你手工编译它,你将看到:method does not override a method from its superclass.方法不会覆盖(重写)超类中的方法, **@Override** 注释能防止你意外地重载。 +**{WillNotCompile}** 标记将该文件排除在本书的 **Gradle** 构建之外,但是如果你手工编译它,你将看到:method does not override a method from its superclass.方法不会重写超类中的方法, **@Override** 注释能防止你意外地重载。 + +- **[1]** 方法签名——方法名和参数类型的合称 + +- **[2]** 重写——覆盖同名方法,使用与基类中完全相同的方法签名和返回类型[^3] +- **[3]** 在java 1.4版本以前,重写方法的返回值类型被要求必须与被重写方法一致,但是在java 5.0中放宽了这一个限制,添加了对协变返回类型的支持,在重写的时候,重写方法的返回值类型可以是被重写方法返回值类型的子类。 + ## 组合与继承的选择 From b027cf39e158164c2b1afe3fbec646b732caa077 Mon Sep 17 00:00:00 2001 From: "jim.deng" Date: Thu, 26 Nov 2020 14:16:46 +0800 Subject: [PATCH 07/12] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AF=AD=E5=8F=A5?= =?UTF-8?q?=E6=8B=97=E5=8F=A3=E9=97=AE=E9=A2=98=204?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book/08-Reuse.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/book/08-Reuse.md b/docs/book/08-Reuse.md index 8e4725a6..729d4ca3 100644 --- a/docs/book/08-Reuse.md +++ b/docs/book/08-Reuse.md @@ -68,7 +68,7 @@ i = 0 f = 0.0 source = Constructed ``` -这两个类中定义的一个方法是特殊的: `toString()`。每个非基本类型对象都有一个 `toString()` 方法,在编译器需要字符串但它有对象的特殊情况下调用该方法。因此,在 [1] 中,编译器看到你试图“添加”一个 **WaterSource** 类型的字符串对象 。因为字符串只能拼接另一个字符串,所以它就先会调用 `toString()` 将 **source** 转换成一个字符串。然后,它可以拼接这两个字符串并将结果字符串传递给 `System.out.println()`。要对创建的任何类允许这种行为,只需要编写一个 **toString()** 方法。在 `toString()` 上使用 **@Override** 注释来告诉编译器,以确保正确地覆盖。**@Override** 是可选的,但它有助于验证你没有拼写错误 (或者更微妙地说,大小写字母输入错误)。类中的基本类型字段自动初始化为零,正如 **object Everywhere** 一章中所述。但是对象引用被初始化为 **null**,如果你尝试调用其任何一个方法,你将得到一个异常(一个运行时错误)。方便的是,打印 **null** 引用却不会得到异常。 +这两个类中定义的一个方法是特殊的: `toString()`。每个非基本类型对象都有一个 `toString()` 方法,在编译器需要字符串但它有对象的特殊情况下调用该方法。因此,在 [1] 中,编译器看到你试图“添加”一个 **WaterSource** 类型的字符串对象 。因为字符串只能拼接另一个字符串,所以它就先会调用 `toString()` 将 **source** 转换成一个字符串。然后,它可以拼接这两个字符串并将结果字符串传递给 `System.out.println()`。要对创建的任何类允许这种行为,只需要编写一个 **toString()** 方法。在 `toString()` 上使用 **@Override** 注解来告诉编译器,以确保正确地覆盖。**@Override** 是可选的,但它有助于验证你没有拼写错误 (或者更微妙地说,大小写字母输入错误)。类中的基本类型字段自动初始化为零,正如 **object Everywhere** 一章中所述。但是对象引用被初始化为 **null**,如果你尝试调用其任何一个方法,你将得到一个异常(一个运行时错误)。方便的是,打印 **null** 引用却不会得到异常。 编译器不会为每个引用创建一个默认对象,这是有意义的,因为在许多情况下,这会导致不必要的开销。初始化引用有四种方法: @@ -692,7 +692,7 @@ doh(Milhouse) **Homer** 的所有重载方法在 **Bart** 中都是可用的,尽管 **Bart** 引入了一种新的重载方法。正如你将在下一章中看到的那样,比起重载,更常见的是覆盖同名方法,使用与基类中完全相同的方法签名[^1]和返回类型。否则会让人感到困惑。 -你已经看到了Java 5 **@Override**注释,它不是关键字,但是可以像使用关键字一样使用它。当你打算重写一个方法[^2]时,你可以选择添加这个注释,如果你不小心用了重载而不是重写,编译器会产生一个错误消息: +你已经看到了Java 5 **@Override**注解,它不是关键字,但是可以像使用关键字一样使用它。当你打算重写一个方法[^2]时,你可以选择添加这个注解,如果你不小心用了重载而不是重写,编译器会产生一个错误消息: ```java @@ -710,7 +710,7 @@ class Lisa extends Homer { ``` -**{WillNotCompile}** 标记将该文件排除在本书的 **Gradle** 构建之外,但是如果你手工编译它,你将看到:method does not override a method from its superclass.方法不会重写超类中的方法, **@Override** 注释能防止你意外地重载。 +**{WillNotCompile}** 标记将该文件排除在本书的 **Gradle** 构建之外,但是如果你手工编译它,你将看到:method does not override a method from its superclass.方法不会重写超类中的方法, **@Override** 注解能防止你意外地重载。 - **[1]** 方法签名——方法名和参数类型的合称 From 7ddf47f41ce98aaaa334015c0f9ef033e4797067 Mon Sep 17 00:00:00 2001 From: "jim.deng" Date: Thu, 26 Nov 2020 17:52:33 +0800 Subject: [PATCH 08/12] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AF=AD=E5=8F=A5?= =?UTF-8?q?=E6=8B=97=E5=8F=A3=E9=97=AE=E9=A2=98=205?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book/08-Reuse.md | 4 +++- docs/book/10-Interfaces.md | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/book/08-Reuse.md b/docs/book/08-Reuse.md index 729d4ca3..e10f8751 100644 --- a/docs/book/08-Reuse.md +++ b/docs/book/08-Reuse.md @@ -1176,12 +1176,14 @@ public class Jurassic { 但请留意你的假设。通常来说,预见一个类如何被复用是很困难的,特别是通用类。如果将一个方法指定为 **final**,可能会防止其他程序员的项目中通过继承来复用你的类,而这仅仅是因为你没有想到它被以那种方式使用。 -Java 标准类库就是一个很好的例子。尤其是 Java 1.0/1.1 的 **Vector** 类被广泛地使用,如果它的所有方法没有因为从效率考虑(这近乎是个幻想),而被指定为 **final**,可能会更加有用。很容易想到,你可能会继承并覆写这么一个基础类,但是设计者们认为这么做不合适。有两个讽刺的原因。第一,**Stack** 继承自 **Vector**,就是说 **Stack** 是个 **Vector**,但从逻辑上来说不对。尽管如此,Java 设计者们仍然这么做,在用这种方式创建 **Stack** 时,他们应该意识到了 **final** 方法过于约束。 +Java 标准类库就是一个很好的例子。尤其是 Java 1.0/1.1 的 **Vector** 类被广泛地使用,然而它的所有方法出于"效率"考虑(然而并没有提升效率,只是幻觉)全被指定为 **final** ,如果不指定 **final** 的话,可能会更加有用[^1]。很容易想到,你可能会继承并覆写这么一个基础类,但是设计者们认为这么做不合适。有两个讽刺的原因。第一,**Stack** 继承自 **Vector**,就是说 **Stack** 是个 **Vector**,但从逻辑上来说不对。尽管如此,Java 设计者们仍然这么做,在用这种方式创建 **Stack** 时,他们应该意识到了 **final** 方法过于约束。 第二,**Vector** 中的很多重要方法,比如 `addElement()` 和 `elementAt()` 方法都是同步的。在“并发编程”一章中会看到同步会导致很大的执行开销,可能会抹煞 **final** 带来的好处。这加强了程序员永远无法正确猜到优化应该发生在何处的观点。如此笨拙的设计却出现在每个人都要使用的标准库中,太糟糕了。庆幸的是,现代 Java 容器用 **ArrayList** 代替了 **Vector**,它的行为要合理得多。不幸的是,仍然有很多新代码使用旧的集合类库,其中就包括 **Vector**。 Java 1.0/1.1 标准类库中另一个重要的类是 **Hashtable**(后来被 **HashMap** 取代),它不含任何 **final** 方法。本书中其他地方也提到,很明显不同的类是由不同的人设计的。**Hashtable** 就比 **Vector** 中的方法名简洁得多,这又是一条证据。对于类库的使用者来说,这是一个本不应该如此草率的事情。这种不规则的情况造成用户需要做更多的工作——这是对粗糙的设计和代码的又一讽刺。 +- **[1]** Java 1.4 开始已将 **Vector** 类大多数方法的 **final** 去掉 + ## 类初始化和加载 diff --git a/docs/book/10-Interfaces.md b/docs/book/10-Interfaces.md index f2bc527e..7eb5cf49 100644 --- a/docs/book/10-Interfaces.md +++ b/docs/book/10-Interfaces.md @@ -104,7 +104,7 @@ public class Instantiable extends Uninstantiable { } ``` -留意 `@Override` 的使用。没有这个注解的话,如果你没有定义相同的方法名或签名,抽象机制会认为你没有实现抽象方法从而产生编译时错误。因此,你可能认为这里的 `@Override` 是多余的。但是,`@Override` 还提示了这个方法被覆写——我认为这是有用的,所以我会使用 `@Override`,即使在没有这个注解,编译器告诉我错误的时候。 +留意 `@Override` 的使用。没有这个注解的话,如果你没有定义相同的方法名或签名,抽象机制会认为你没有实现抽象方法从而产生编译时错误。因此,你可能认为这里的 `@Override` 是多余的。但是,`@Override` 还提示了这个方法被覆写——我认为这是有用的,所以我会使用 `@Override`,不仅仅是因为当没有这个注解时,编译器会告诉我出错。 记住,事实上的访问权限是“friendly”。你很快会看到接口自动将其方法指明为 **public**。事实上,接口只允许 **public** 方法,如果不加访问修饰符的话,接口的方法不是 **friendly** 而是 **public**。然而,抽象类允许每件事: From 82aedb03a048b2f785e9a40240e4a11fe0c61f01 Mon Sep 17 00:00:00 2001 From: "jim.deng" Date: Fri, 27 Nov 2020 12:24:29 +0800 Subject: [PATCH 09/12] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AF=AD=E5=8F=A5?= =?UTF-8?q?=E6=8B=97=E5=8F=A3=E9=97=AE=E9=A2=98=206?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book/09-Polymorphism.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/book/09-Polymorphism.md b/docs/book/09-Polymorphism.md index 63075630..f589aca2 100644 --- a/docs/book/09-Polymorphism.md +++ b/docs/book/09-Polymorphism.md @@ -964,7 +964,7 @@ Disposing Shared 0 **static long counter** 跟踪所创建的 **Shared** 实例数量,还提供了 **id** 的值。**counter** 的类型是 **long** 而不是 **int**,以防溢出(这只是个良好实践,对于本书的所有示例,**counter** 不会溢出)。**id** 是 **final** 的,因为它的值在初始化时确定后不应该变化。 -在将一个 **shared** 对象附着在类上时,必须记住调用 `addRef()`,而 `dispose()` 方法会跟踪引用数,以确定在何时真正地执行清理工作。使用这种技巧需要加倍细心,但是如果正在共享需要被清理的对象,就没有太多选择了。 +在将一个 **shared** 对象附着在类上时,必须记住调用 `addRef()`,而 `dispose()` 方法会跟踪引用数,以确定在何时真正地执行清理工作。使用这种技巧需要加倍细心,但是如果正在共享的对象需要被清理,你没有太多选择。 ### 构造器内部多态方法的行为 @@ -1154,7 +1154,7 @@ HappyActor SadActor ``` -**Stage** 对象中包含了 **Actor** 引用,该引用被初始化为指向一个 **HappyActor** 对象,这意味着 `performPlay()` 会产生一个特殊行为。但是既然引用可以在运行时与其他不同的对象绑定,那么它就可以被替换成对 **SadActor** 的引用,`performPlay()` 的行为随之改变。这样你就获得了运行时的动态灵活性(这被称为状态模式)。与之相反,我们不能在运行时决定继承不同的对象,那在编译时就完全确定下来了。 +**Stage** 对象中包含了 **Actor** 引用,该引用被初始化为指向一个 **HappyActor** 对象,这意味着 `performPlay()` 会产生一个特殊行为。但是既然引用可以在运行时与其他不同的对象绑定,那么它就可以被替换成对 **SadActor** 的引用,`performPlay()` 的行为随之改变。这样你就获得了运行时的动态灵活性(这被称为状态模式)。与之相反,我们不能在运行时才决定继承不同的对象;那在编译时就完全决定好了。 有一条通用准则:使用继承表达行为的差异,使用属性表达状态的变化。在上个例子中,两者都用到了。通过继承得到的两个不同类在 `act()` 方法中表达了不同的行为,**Stage** 通过组合使自己的状态发生变化。这里状态的改变产生了行为的改变。 From 07231d75bae189957c90d3707804f9bc7507902b Mon Sep 17 00:00:00 2001 From: "jim.deng" Date: Fri, 27 Nov 2020 16:09:05 +0800 Subject: [PATCH 10/12] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AF=AD=E5=8F=A5?= =?UTF-8?q?=E6=8B=97=E5=8F=A3=E9=97=AE=E9=A2=98=207?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book/10-Interfaces.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/book/10-Interfaces.md b/docs/book/10-Interfaces.md index 7eb5cf49..6af03da0 100644 --- a/docs/book/10-Interfaces.md +++ b/docs/book/10-Interfaces.md @@ -602,7 +602,7 @@ public interface Operations { } ``` -这是模版方法设计模式的一个版本(在“设计模式”一章中详细描述),`runOps()` 是一个模版方法。`runOps()` 使用可变参数列表,因而我们可以传入任意多的 **Operation** 参数并按顺序运行它们: +这是*模版*方法设计模式的一个版本(在“设计模式”一章中详细描述),`runOps()` 是一个模版方法。`runOps()` 使用可变参数列表,因而我们可以传入任意多的 **Operation** 参数并按顺序运行它们: ```java // interface/Machine.java @@ -768,17 +768,17 @@ Woodwind.play() MIDDLE_C | 状态 | 不能包含属性(除了静态属性,不支持对象状态) | 可以包含属性,非抽象方法可能引用这些属性 | | 默认方法 和 抽象方法 | 不需要在子类中实现默认方法。默认方法可以引用其他接口的方法 | 必须在子类中实现抽象方法 | | 构造器 | 没有构造器 | 可以有构造器 | -| 可见性 | 隐式 **public** | 可以是 **protected** 或友元 | +| 可见性 | 隐式 **public** | 可以是 **protected** 或 "friendly" | 抽象类仍然是一个类,在创建新类时只能继承它一个。而创建类的过程中可以实现多个接口。 -有一条实际经验:尽可能地抽象。因此,更倾向使用接口而不是抽象类。只有当必要时才使用抽象类。除非必须使用,否则不要用接口和抽象类。大多数时候,普通类已经做得很好,如果不行的话,再移动到接口或抽象类中。 +有一条实际经验:在合理的范围内尽可能地抽象。因此,更倾向使用接口而不是抽象类。只有当必要时才使用抽象类。除非必须使用,否则不要用接口和抽象类。大多数时候,普通类已经做得很好,如果不行的话,再移动到接口或抽象类中。 ## 完全解耦 -当方法操纵的是一个类而非接口时,它就只能作用于那个类或其子类。如果想把方法应用于那个继承层级结构之外的类,就会触霉头。接口在很大程度上放宽了这个限制,因而使用接口可以编写复用性更好的代码。 +每当一个方法与一个类而不是接口一起工作时,你只能应用那个类或它的子类。如果你想把这方法应用到一个继承层次之外的类,是做不到的。接口在很大程度上放宽了这个限制,因而使用接口可以编写复用性更好的代码。 例如有一个类 **Processor** 有两个方法 `name()` 和 `process()`。`process()` 方法接受输入,修改并输出。把这个类作为基类用来创建各种不同类型的 **Processor**。下例中,**Processor** 的各个子类修改 String 对象(注意,返回类型可能是协变类型而非参数类型): From b0d16e7d49a38ff1b079308b989148bdf9629ae2 Mon Sep 17 00:00:00 2001 From: "jim.deng" Date: Fri, 27 Nov 2020 17:23:00 +0800 Subject: [PATCH 11/12] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AF=AD=E5=8F=A5?= =?UTF-8?q?=E6=8B=97=E5=8F=A3=E9=97=AE=E9=A2=98=208?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book/10-Interfaces.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/book/10-Interfaces.md b/docs/book/10-Interfaces.md index 6af03da0..b7cf5cb5 100644 --- a/docs/book/10-Interfaces.md +++ b/docs/book/10-Interfaces.md @@ -778,7 +778,7 @@ Woodwind.play() MIDDLE_C ## 完全解耦 -每当一个方法与一个类而不是接口一起工作时,你只能应用那个类或它的子类。如果你想把这方法应用到一个继承层次之外的类,是做不到的。接口在很大程度上放宽了这个限制,因而使用接口可以编写复用性更好的代码。 +每当一个方法与一个类而不是接口一起工作时(当方法的参数是类而不是接口),你只能应用那个类或它的子类。如果你想把这方法应用到一个继承层次之外的类,是做不到的。接口在很大程度上放宽了这个限制,因而使用接口可以编写复用性更好的代码。 例如有一个类 **Processor** 有两个方法 `name()` 和 `process()`。`process()` 方法接受输入,修改并输出。把这个类作为基类用来创建各种不同类型的 **Processor**。下例中,**Processor** 的各个子类修改 String 对象(注意,返回类型可能是协变类型而非参数类型): From 95a4cbbabd701476a08764120f23dabbcc77fc0a Mon Sep 17 00:00:00 2001 From: "jim.deng" Date: Fri, 27 Nov 2020 17:56:34 +0800 Subject: [PATCH 12/12] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AF=AD=E5=8F=A5?= =?UTF-8?q?=E6=8B=97=E5=8F=A3=E9=97=AE=E9=A2=98=209?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book/09-Polymorphism.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/book/09-Polymorphism.md b/docs/book/09-Polymorphism.md index f589aca2..ddca482d 100644 --- a/docs/book/09-Polymorphism.md +++ b/docs/book/09-Polymorphism.md @@ -964,7 +964,7 @@ Disposing Shared 0 **static long counter** 跟踪所创建的 **Shared** 实例数量,还提供了 **id** 的值。**counter** 的类型是 **long** 而不是 **int**,以防溢出(这只是个良好实践,对于本书的所有示例,**counter** 不会溢出)。**id** 是 **final** 的,因为它的值在初始化时确定后不应该变化。 -在将一个 **shared** 对象附着在类上时,必须记住调用 `addRef()`,而 `dispose()` 方法会跟踪引用数,以确定在何时真正地执行清理工作。使用这种技巧需要加倍细心,但是如果正在共享的对象需要被清理,你没有太多选择。 +在将一个 **shared** 对象附着在类上时,必须记住调用 `addRef()`,而 `dispose()` 方法会跟踪引用数,以确定在何时真正地执行清理工作。使用这种技巧需要加倍细心,但是如果需要清理正在共享的对象,你没有太多选择。 ### 构造器内部多态方法的行为 @@ -1154,7 +1154,7 @@ HappyActor SadActor ``` -**Stage** 对象中包含了 **Actor** 引用,该引用被初始化为指向一个 **HappyActor** 对象,这意味着 `performPlay()` 会产生一个特殊行为。但是既然引用可以在运行时与其他不同的对象绑定,那么它就可以被替换成对 **SadActor** 的引用,`performPlay()` 的行为随之改变。这样你就获得了运行时的动态灵活性(这被称为状态模式)。与之相反,我们不能在运行时才决定继承不同的对象;那在编译时就完全决定好了。 +**Stage** 对象中包含了 **Actor** 引用,该引用被初始化为指向一个 **HappyActor** 对象,这意味着 `performPlay()` 会产生一个特殊行为。但是既然引用可以在运行时与其他不同的对象绑定,那么它就可以被替换成对 **SadActor** 的引用,`performPlay()` 的行为随之改变。这样你就获得了运行时的动态灵活性(这被称为状态模式)。与之相反,我们无法在运行时才决定继承不同的对象;那在编译时就完全决定好了。 有一条通用准则:使用继承表达行为的差异,使用属性表达状态的变化。在上个例子中,两者都用到了。通过继承得到的两个不同类在 `act()` 方法中表达了不同的行为,**Stage** 通过组合使自己的状态发生变化。这里状态的改变产生了行为的改变。