diff --git a/.gitignore b/.gitignore index abe3365fc..48292956e 100644 --- a/.gitignore +++ b/.gitignore @@ -49,6 +49,7 @@ Generated.txt *-results.txt *-out.txt OutputErrors.txt +report.txt failures People.xml annotations/Test0.txt @@ -71,9 +72,40 @@ io/X.file /files/Cheese.txt /files/StreamInAndOut.txt -/.gradle/ +.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/.travis.yml b/.travis.yml deleted file mode 100644 index 48faf18b4..000000000 --- a/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: java -jdk: - - oraclejdk8 -install: true -script: ./gradlew run diff --git a/.travisXX.yml b/.travisXX.yml new file mode 100644 index 000000000..54fee6592 --- /dev/null +++ b/.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/Ant-Clean.xml b/Ant-Clean.xml deleted file mode 100644 index b15cb6f14..000000000 --- a/Ant-Clean.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - For this file to be included in all build.xml files - at all directory levels, the single entries with the - "**/" syntax must be used everywhere. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Ant-Common.xml b/Ant-Common.xml deleted file mode 100644 index 43ef0b064..000000000 --- a/Ant-Common.xml +++ /dev/null @@ -1,216 +0,0 @@ - - - - - - - Ant build.xml for the source code for chapter ${chapter} - Bruce Eckel On Java - Code available at https://github.com/BruceEckel/OnJava-Examples - See installation instructions in README.md - See copyright notice in CopyRight.txt - - Ant available from http://ant.apache.org - - To see options, type: ant -p - - - - - - - - - - - - - - - - - [${chapter}] java @{cls} @{arguments} - [${chapter}] java @{cls} @{arguments} - - - - - [${chapter}] Finished: java @{cls} @{arguments} - @{msg} - -------------------------------- - - - - - - - - - - - - - - [${chapter}] java @{cls} @{arguments} - [${chapter}] java @{cls} @{arguments} - - - - [${chapter}] Finished: java @{cls} @{arguments} - @{msg} - -------------------------------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Copyright.txt b/Copyright.txt index 2b0c56fec..8eb3289e0 100644 --- a/Copyright.txt +++ b/Copyright.txt @@ -1,5 +1,5 @@ // Copyright.txt -This computer source code is Copyright ©2016 MindView LLC +This computer source code is Copyright ©2021 MindView LLC. All Rights Reserved. Permission to use, copy, modify, and distribute this @@ -16,7 +16,7 @@ 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" is cited as the origin. +Java 8" is cited as the origin. 3. Permission to incorporate the Source Code into printed media may be obtained by contacting: @@ -64,9 +64,9 @@ 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/OnJava-Examples, +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/OnJava-Examples/issues +https://github.com/BruceEckel/OnJava8-examples/issues diff --git a/HelloDate.java b/HelloDate.java deleted file mode 100644 index dce03d0ba..000000000 --- a/HelloDate.java +++ /dev/null @@ -1,12 +0,0 @@ -// HelloDate.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ 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/NOTES.md b/NOTES.md new file mode 100644 index 000000000..5401db816 --- /dev/null +++ b/NOTES.md @@ -0,0 +1,3 @@ +For generating table of contents in README.md +https://ecotrust-canada.github.io/markdown-toc/ +(Replace double hyphens with single hyphens after generation) diff --git a/README.md b/README.md new file mode 100644 index 000000000..ad462ebc0 --- /dev/null +++ b/README.md @@ -0,0 +1,375 @@ +# Examples for *On Java 8* by Bruce Eckel + +If you want to experiment with the code examples from the book [On Java +8](https://www.onjava8.com/), you're in the right place. + +These examples are automatically extracted directly from the book. This repository +includes tests to verify that the code in the book is correct. + +> NOTE: Do not attempt to use JDK 16 or greater with gradle. +> This produces a `BUG!` message from Gradle, which is broken for those versions. + +## Contents + +- [Building From the Command Line: Quick Version](#building-from-the-command-line-quick-version) +- [Building From the Command Line: Detailed Instructions](#building-from-the-command-line-detailed-instructions) + * [Install Java](#install-java) + + [Windows](#windows) + + [Macintosh](#macintosh) + + [Linux](#linux) + * [Verify Your Installation](#verify-your-installation) + * [Installing and Running the Book Examples](#installing-and-running-the-book-examples) +- [Appendix A: Command-Line Basics](#appendix-a-command-line-basics) + * [Editors](#editors) + * [The Shell](#the-shell) + + [Starting a Shell](#starting-a-shell) + + [Directories](#directories) + + [Basic Shell Operations](#basic-shell-operations) + + [Unpacking a Zip Archive](#unpacking-a-zip-archive) +- [Appendix B: Testing](#appendix-b-testing) +- [Appendix C: Troubleshooting](#appendix-c-troubleshooting) + +# Building From the Command Line: Quick Version + +Before you can run the examples from this repository, you must install +[JDK8](http://www.oracle.com/technetwork/java/javase/downloads/index.html), the +*Java Development Kit* for version 8 of the language. + +If you just want to download and check the code, [Download +Here](https://github.com/BruceEckel/OnJava8-Examples/archive/refs/heads/master.zip) +and [unzip it](#unpacking-a-zip-archive) into your destination directory. Open +a [shell/command window](#appendix-a-command-line-basics) and move into the +root of that directory. You'll know you are in the right directory if you see +the files `gradlew` and `gradlew.bat`. + +You'll need an Internet connection the first time you compile the code, +because Gradle needs to first install itself, then all the support libraries. +Once these are installed you can perform additional compiling and running +offline. + +On Mac/Linux, enter: + +``` +./gradlew test +``` + +(If you get a *Permission denied* error, run `chmod +x ./gradlew`) + +On Windows, enter + +``` +gradlew test +``` + +If all goes well, the tests will run. Everything should complete without errors. + +All the book examples are in the subdirectory `Examples` in subdirectories +corresponding to the atom names. + +# Building From the Command Line: Detailed Instructions + +If you are not familiar with the command line, first read [Command-Line +Basics](#appendix-a-command-line-basics). + +## Install Java + +You must first install the *Java Development Kit* (JDK). + +### Windows + +1. Follow the instructions to [install Chocolatey](https://chocolatey.org/). + +2. At a [shell prompt](#appendix-a-command-line-basics), type: `choco install +jdk8` (you may also select a more recent version, like `jdk11`). The +installation process takes some time, but when it's finished Java is installed +and the necessary environment variables are set. + +### Macintosh + +The Mac comes with a much older version of Java that won't work for the +examples in this book, so you'll need to update it to (at least) Java 8. + + 1. Follow the instructions at this link to [Install HomeBrew](http://brew.sh/) + + 2. At a [shell prompt](#appendix-a-command-line-basics), first type + `brew update`. When that completes, enter `brew cask install java`. + +**NOTE:** Sometimes the default version of Java that you get with the above +installation will be too recent and not validated by the Mac's security +system. If this happens you'll either need to turn off the security by hand +or install an earlier version of Java. For either choice, you'll need to Google +for answers on how to solve the problem (often the easiest approach is to just +search for the error message produced by the Mac). + +### Linux + +Use the standard package installer with the following [shell commands](#appendix-a-command-line-basics): + +*Ubuntu/Debian*: + + 1. `sudo apt-get update` + + 2. `sudo apt-get install default-jdk` + +*Fedora/Redhat*: + +``` +su -c "yum install java-1.8.0-openjdk" +``` + +## Verify Your Installation + +[Open a new shell](#appendix-a-command-line-basics) and type: + +``` +java -version +``` + +You should see something like the following (Version numbers and actual text +will vary): + +``` +openjdk version "11" 2018-09-25 +OpenJDK Runtime Environment 18.9 (build 11+28) +OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode) +``` + +If you see a message that the command is not found or not recognized, review +the installation instructions. If you still can't get it to work, check +[StackOverflow](http://stackoverflow.com/search?q=installing+java). + +## Installing and Running the Book Examples + +Once you have Java installed, the process to install and run the book examples +is the same for all platforms: + +1. Download the book examples from the +[GitHub Repository](https://github.com/BruceEckel/OnJava8-Examples/archive/refs/heads/master.zip). + +2. [Unzip](#unpacking-a-zip-archive) the downloaded file into the directory of your choice. + +3. Use the Windows Explorer, the Mac Finder, or Nautilus or equivalent on Linux +to browse to the directory where you uzipped `OnJava8-Examples`, and +[open a shell](#appendix-a-command-line-basics) there. + +4. If you're in the right directory, you should see files named `gradlew` and +`gradlew.bat` in that directory, along with numerous other files and +directories. The directories correspond to the chapters in the book. + +5. At the shell prompt, type `gradlew test` (Windows) or `./gradlew test` +(Mac/Linux). + +The first time you do this, Gradle will install itself and numerous other +packages, so it will take some time. After everything is installed, subsequent +builds and runs will be much faster. + +Note that you must be connected to the Internet the first time you run `gradlew` +so that Gradle can download the necessary packages. + +# Appendix A: Command-Line Basics + +Because it is possible for a "dedicated beginner" to learn programming from +this book, you may not have previously used your computer's command-line shell. +If you have, you can go directly to the +[installation instructions](#building-from-the-command-line-detailed-instructions). + +## Editors + +To create and modify Java program files—the code listings shown in this +book—you need a program called an *editor*. You'll also need the editor to +make changes to your system configuration files, which is sometimes required +during installation. + +Programming editors vary from heavyweight *Integrated Development Environments* +(IDEs, like Eclipse, NetBeans and IntelliJ IDEA) to more basic text +manipulation applications. If you already have an IDE and are comfortable with +it, feel free to use that for this book. + +Numerous explanations in this book are specific to IntelliJ IDEA so if you +don't already have an IDE you might as well start with IDEA. There are many +other editors; these are a subculture unto themselves and people sometimes get +into heated arguments about their merits. If you find one you like better, it's +not too hard to change. The important thing is to choose one and get +comfortable with it. + +## The Shell + +If you haven't programmed before, you might be unfamiliar with your operating +system *shell* (also called the *command prompt* in Windows). The shell harkens +back to the early days of computing when everything happened by typing commands +and the computer responded by displaying responses—everything was text-based. + +Although it can seem primitive in the age of graphical user interfaces, a shell +provides a surprising number of valuable features. + +To learn more about your shell than we cover here, see +[Bash Shell](https://en.wikipedia.org/wiki/Bash_(Unix_shell)) for Mac/Linux +or [Windows Shell](https://en.wikipedia.org/wiki/Windows_shell). + +### Starting a Shell + +**Mac**: Click on the *Spotlight* (the magnifying-glass icon in the upper-right +corner of the screen) and type "terminal." Click on the application that looks +like a little TV screen (you might also be able to hit "Return"). This starts a +shell in your home directory. + +**Windows**: First, start the Windows Explorer to navigate through your +directories: + +- *Windows 7*: click the "Start" button in the lower left corner of the screen. +In the Start Menu search box area type "explorer" and then press the "Enter" +key. + +- *Windows 8*: click Windows+Q, type "explorer" and then press the "Enter" key. + +- *Windows 10*: click Windows+E. + +Once the Windows Explorer is running, move through the folders on your computer +by double-clicking on them with the mouse. Navigate to the desired folder. Now +click the file tab at the top left of the Explorer window and select "Open +Windows Powershell." This opens a shell in the destination directory. + +**Linux**: To open a shell in your home directory: + +- *Debian*: Press Alt+F2. In the dialog that pops up, type 'gnome-terminal' + +- *Ubuntu*: Either right-click on the desktop and select 'Open Terminal', or + press Ctrl+Alt+T + +- *Redhat*: Right-click on the desktop and select 'Open Terminal' + +- *Fedora*: Press Alt+F2. In the dialog that pops up, type 'gnome-terminal' + + +### Directories + +*Directories* are one of the fundamental elements of a shell. Directories hold +files, as well as other directories. Think of a directory as a tree with +branches. If `books` is a directory on your system and it has two other +directories as branches, for example `math` and `art`, we say that you have a +directory `books` with two *subdirectories* `math` and `art`. We refer to them +as `books/math` and `books/art` since `books` is their *parent* directory. +Note that Windows uses backslashes rather than forward slashes to separate the +parts of a directory. + +### Basic Shell Operations + +The shell operations shown here are approximately identical across operating +systems. For the purposes of this book, here are the essential operations in a +shell: + +- **Change directory**: Use `cd` followed by the name of the + directory where you want to move, or `cd ..` if you want to move + up a directory. If you want to move to a different directory while + remembering where you came from, use `pushd` followed by the different + directory name. Then, to return to the previous directory, just say + `popd`. + +- **Directory listing**: `ls` (`dir` in Windows) displays all the files and + subdirectory names in the current directory. Use the wildcard `*` (asterisk) to + narrow your search. For example, if you want to list all the files ending in + ".kt," you say `ls *.kt` (Windows: `dir *.kt`). If you want to list the + files starting with "F" and ending in ".kt," you say `ls F*.kt` (Windows: + `dir F*.kt`). + +- **Create a directory**: use the `mkdir` ("make directory") command + (Windows: `md`), followed by the name of the directory you want to create. + For example, `mkdir books` (Windows: `md books`). + +- **Remove a file**: Use `rm` ("remove") followed by the name of the file + you wish to remove (Windows: `del`). For example, `rm somefile.kt` (Windows: + `del somefile.kt`). + +- **Remove a directory**: use the `rm -r` command to remove the files in + the directory and the directory itself (Windows: `deltree`). For example, + `rm -r books` (Windows: `deltree books`). + +- **Repeat a command**: The "up arrow" on all three operating + systems moves through previous commands so you can edit and + repeat them. On Mac/Linux, `!!` repeats the last command and + `!n` repeats the nth command. + +- **Command history**: Use `history` in Mac/Linux or press the F7 key in Windows. + This gives you a list of all the commands you've entered. Mac/Linux provides + numbers to refer to when you want to repeat a command. + +### Unpacking a Zip Archive + +A file name ending with `.zip` is an archive containing other files in a +compressed format. Both Linux and Mac have command-line `unzip` utilities, and +it's possible to install a command-line `unzip` for Windows via the Internet. + +However, in all three systems the graphical file browser (Windows Explorer, the +Mac Finder, or Nautilus or equivalent on Linux) will browse to the directory +containing your zip file. Then right-mouse-click on the file and select "Open" +on the Mac, "Extract Here" on Linux, or "Extract all ..." on Windows. + +# Appendix B: Testing + +The test system is built in so that we (the authors) can verify the correctness +of what goes into the book. + +You don't need to run the tests, but if you want to, you can just run `gradlew +test` (on Windows) or `./gradlew test` (Mac/Linux). + +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. + +# Appendix C: Troubleshooting + +If any terminology or processes described here remain unclear to you, you can +usually find explanations or answers through [Google](https://www.google.com/). +For more specific issues or problems, try +[StackOverflow](http://stackoverflow.com/). Sometimes you can find installation +instructions on [YouTube](https://www.youtube.com/). + +Sometimes a Gradle build will be unable to connect to the internet and download +the necessary components, producing an error message containing: + +``` +javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty +``` + +Normally this means you have multiple Java installations on your machine +(applications built with Java ordinarily install their own version of Java), and +somehow the `cacerts` security file is interfering with the `cacerts` file for +the Java you have installed. It can be difficult to know which `cacerts` file is +interfering with yours. The brute-force approach is to search for all the +`cacerts` files on your machine and begin uninstalling the associated +applications---or in some cases, simply removing the directory containing the +`cacerts` file---until the Gradle build begins to work. You might also need to +adjust some environment variables and/or your path. Once you get the Gradle +build working successfully, you should be able to reinstall any applications you +removed in the process. diff --git a/annotations/AUComposition.java b/annotations/AUComposition.java new file mode 100644 index 000000000..94d51e607 --- /dev/null +++ b/annotations/AUComposition.java @@ -0,0 +1,30 @@ +// annotations/AUComposition.java +// (c)2021 MindView 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 + . tMethodOne + . tMethodTwo This is methodTwo + +OK (2 tests) +*/ diff --git a/annotations/AUExternalTest.java b/annotations/AUExternalTest.java new file mode 100644 index 000000000..71c8f2f4b --- /dev/null +++ b/annotations/AUExternalTest.java @@ -0,0 +1,29 @@ +// annotations/AUExternalTest.java +// (c)2021 MindView 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/annotations/AtUnitComposition.java b/annotations/AtUnitComposition.java deleted file mode 100644 index 714d9b789..000000000 --- a/annotations/AtUnitComposition.java +++ /dev/null @@ -1,31 +0,0 @@ -// annotations/AtUnitComposition.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Creating non-embedded tests -package annotations; -import onjava.atunit.*; -import onjava.*; - -public class AtUnitComposition { - AtUnitExample1 testObject = new AtUnitExample1(); - @Test boolean _methodOne() { - return - testObject.methodOne().equals("This is methodOne"); - } - @Test boolean _methodTwo() { - return testObject.methodTwo() == 2; - } - public static void - main(String[] args) throws Exception { - OSExecute.command("java -cp .. " + - "onjava.atunit.AtUnit AtUnitComposition.class"); - } -} -/* Output: -annotations.AtUnitComposition - . _methodOne - . _methodTwo This is methodTwo - -OK (2 tests) -*/ diff --git a/annotations/AtUnitExample1.java b/annotations/AtUnitExample1.java index 3987752b5..de4cc6c64 100644 --- a/annotations/AtUnitExample1.java +++ b/annotations/AtUnitExample1.java @@ -1,7 +1,9 @@ // annotations/AtUnitExample1.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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.*; @@ -14,18 +16,20 @@ public int methodTwo() { System.out.println("This is methodTwo"); return 2; } - @Test boolean methodOneTest() { + @Test + boolean methodOneTest() { return methodOne().equals("This is methodOne"); } - @Test boolean m2() { return methodTwo() == 2; } - @Test private boolean m3() { return true; } + @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; } - public static void - main(String[] args) throws Exception { - OSExecute.command("java -cp .. " + - "onjava.atunit.AtUnit AtUnitExample1.class"); + @Test + boolean failureTest() { return false; } + @Test + boolean anotherDisappointment() { + return false; } } /* Output: @@ -33,9 +37,9 @@ public int methodTwo() { . anotherDisappointment (failed) . methodOneTest . failureTest (failed) - . m3 . m2 This is methodTwo + . m3 (5 tests) >>> 2 FAILURES <<< diff --git a/annotations/AtUnitExample2.java b/annotations/AtUnitExample2.java index 467e61c12..855c33133 100644 --- a/annotations/AtUnitExample2.java +++ b/annotations/AtUnitExample2.java @@ -1,8 +1,10 @@ // annotations/AtUnitExample2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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.*; @@ -16,37 +18,37 @@ public int methodTwo() { System.out.println("This is methodTwo"); return 2; } - @Test void assertExample() { + @Test + void assertExample() { assert methodOne().equals("This is methodOne"); } - @Test void assertFailureExample() { + @Test + void assertFailureExample() { assert 1 == 2: "What a surprise!"; } - @Test void exceptionExample() throws IOException { - new FileInputStream("nofile.txt"); // Throws + @Test + void exceptionExample() throws IOException { + try(FileInputStream fis = + new FileInputStream("nofile.txt")) {} // Throws } - @Test boolean assertAndReturn() { + @Test + boolean assertAndReturn() { // Assertion with message: assert methodTwo() == 2: "methodTwo must equal 2"; return methodOne().equals("This is methodOne"); } - public static void - main(String[] args) throws Exception { - OSExecute.command("java -cp .. " + - "onjava.atunit.AtUnit AtUnitExample2.class"); - } } /* Output: annotations.AtUnitExample2 - . assertFailureExample java.lang.AssertionError: What a -surprise! + . assertFailureExample java.lang.AssertionError: What +a surprise! (failed) . assertExample - . assertAndReturn This is methodTwo - . exceptionExample java.io.FileNotFoundException: nofile.txt (The system cannot find the file specified) (failed) + . assertAndReturn This is methodTwo + (4 tests) >>> 2 FAILURES <<< diff --git a/annotations/AtUnitExample3.java b/annotations/AtUnitExample3.java index f81eeb53b..ed1a93911 100644 --- a/annotations/AtUnitExample3.java +++ b/annotations/AtUnitExample3.java @@ -1,7 +1,9 @@ // annotations/AtUnitExample3.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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.*; @@ -17,19 +19,18 @@ public int methodTwo() { System.out.println("This is methodTwo"); return 2; } - @TestObjectCreate static AtUnitExample3 create() { + @TestObjectCreate + static AtUnitExample3 create() { return new AtUnitExample3(47); } - @Test boolean initialization() { return n == 47; } - @Test boolean methodOneTest() { + @Test + boolean initialization() { return n == 47; } + @Test + boolean methodOneTest() { return methodOne().equals("This is methodOne"); } - @Test boolean m2() { return methodTwo() == 2; } - public static void - main(String[] args) throws Exception { - OSExecute.command("java -cp .. " + - "onjava.atunit.AtUnit AtUnitExample3.class"); - } + @Test + boolean m2() { return methodTwo() == 2; } } /* Output: annotations.AtUnitExample3 diff --git a/annotations/AtUnitExample4.java b/annotations/AtUnitExample4.java index 2c446ce04..23bc21efb 100644 --- a/annotations/AtUnitExample4.java +++ b/annotations/AtUnitExample4.java @@ -1,7 +1,10 @@ // annotations/AtUnitExample4.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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.*; @@ -13,63 +16,68 @@ public class AtUnitExample4 { "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 AtUnitExample4(String word) { + this.word = word; + } public String getWord() { return word; } public String scrambleWord() { - List chars = - Arrays.asList(ConvertTo.boxed(word.toCharArray())); + 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 = + @TestProperty + static List input = Arrays.asList(theory.split(" ")); @TestProperty - static Iterator words = input.iterator(); - @TestObjectCreate static AtUnitExample4 create() { + static Iterator words = input.iterator(); + @TestObjectCreate + static AtUnitExample4 create() { if(words.hasNext()) return new AtUnitExample4(words.next()); else return null; } - @Test boolean words() { + @Test + boolean words() { System.out.println("'" + getWord() + "'"); return getWord().equals("are"); } - @Test boolean scramble1() { - // Change to specific seed to get verifiable results: + @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() { + @Test + boolean scramble2() { rand = new Random(74); System.out.println("'" + getWord() + "'"); String scrambled = scrambleWord(); System.out.println(scrambled); return scrambled.equals("tsaeborornussu"); } - public static void - main(String[] args) throws Exception { - System.out.println("starting"); - OSExecute.command("java -cp .. " + - "onjava.atunit.AtUnit AtUnitExample4.class"); - } } /* Output: -starting annotations.AtUnitExample4 - . scramble1 'All' -lAl - - . scramble2 'brontosauruses' -tsaeborornussu - - . words 'are' + . words 'All' +(failed) + . scramble1 'brontosauruses' +ntsaueorosurbs +(failed) + . scramble2 'are' +are +(failed) +(3 tests) -OK (3 tests) +>>> 3 FAILURES <<< + annotations.AtUnitExample4: words + annotations.AtUnitExample4: scramble1 + annotations.AtUnitExample4: scramble2 */ diff --git a/annotations/AtUnitExample5.java b/annotations/AtUnitExample5.java index 88370d683..4e4ceb4f4 100644 --- a/annotations/AtUnitExample5.java +++ b/annotations/AtUnitExample5.java @@ -1,7 +1,9 @@ // annotations/AtUnitExample5.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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.*; @@ -9,12 +11,16 @@ 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() { + 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"); @@ -23,36 +29,34 @@ public class AtUnitExample5 { } return new AtUnitExample5(id); } - @TestObjectCleanup static void - cleanup(AtUnitExample5 tobj) { + @TestObjectCleanup + static void cleanup(AtUnitExample5 tobj) { System.out.println("Running cleanup"); output.close(); } - @Test boolean test1() { + @Test + boolean test1() { output.print("test1"); return true; } - @Test boolean test2() { + @Test + boolean test2() { output.print("test2"); return true; } - @Test boolean test3() { + @Test + boolean test3() { output.print("test3"); return true; } - public static void - main(String[] args) throws Exception { - OSExecute.command("java -cp .. " + - "onjava.atunit.AtUnit AtUnitExample5.class"); - } } /* Output: annotations.AtUnitExample5 . test1 -Running cleanup - . test2 Running cleanup . test3 +Running cleanup + . test2 Running cleanup OK (3 tests) */ diff --git a/annotations/AtUnitExternalTest.java b/annotations/AtUnitExternalTest.java deleted file mode 100644 index 2016e0db9..000000000 --- a/annotations/AtUnitExternalTest.java +++ /dev/null @@ -1,27 +0,0 @@ -// annotations/AtUnitExternalTest.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Creating non-embedded tests -package annotations; -import onjava.atunit.*; -import onjava.*; - -public class AtUnitExternalTest extends AtUnitExample1 { - @Test boolean _methodOne() { - return methodOne().equals("This is methodOne"); - } - @Test boolean _methodTwo() { return methodTwo() == 2; } - public static void - main(String[] args) throws Exception { - OSExecute.command("java -cp .. " + - "onjava.atunit.AtUnit AtUnitExternalTest.class"); - } -} -/* Output: -annotations.AtUnitExternalTest - . _methodTwo This is methodTwo - - . _methodOne -OK (2 tests) -*/ diff --git a/annotations/DemoProcessFiles.java b/annotations/DemoProcessFiles.java new file mode 100644 index 000000000..13f12bbf5 --- /dev/null +++ b/annotations/DemoProcessFiles.java @@ -0,0 +1,43 @@ +// annotations/DemoProcessFiles.java +// (c)2021 MindView LLC: 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/annotations/HashSetTest.java b/annotations/HashSetTest.java index 3d72063f1..5b6e7541a 100644 --- a/annotations/HashSetTest.java +++ b/annotations/HashSetTest.java @@ -1,7 +1,9 @@ // annotations/HashSetTest.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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.*; @@ -9,28 +11,26 @@ public class HashSetTest { HashSet testObject = new HashSet<>(); - @Test void initialization() { + @Test + void initialization() { assert testObject.isEmpty(); } - @Test void _contains() { + @Test + void tContains() { testObject.add("one"); assert testObject.contains("one"); } - @Test void _remove() { + @Test + void tRemove() { testObject.add("one"); testObject.remove("one"); assert testObject.isEmpty(); } - public static void - main(String[] args) throws Exception { - OSExecute.command("java -cp .. " + - "onjava.atunit.AtUnit HashSetTest.class"); - } } /* Output: annotations.HashSetTest + . tContains . initialization - . _contains - . _remove + . tRemove OK (3 tests) */ diff --git a/annotations/PasswordUtils.java b/annotations/PasswordUtils.java index 46c17e0aa..549412696 100644 --- a/annotations/PasswordUtils.java +++ b/annotations/PasswordUtils.java @@ -1,7 +1,7 @@ // annotations/PasswordUtils.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class PasswordUtils { @@ -12,7 +12,8 @@ public boolean validatePassword(String passwd) { } @UseCase(id = 48) public String encryptPassword(String passwd) { - return new StringBuilder(passwd).reverse().toString(); + return new StringBuilder(passwd) + .reverse().toString(); } @UseCase(id = 49, description = "New passwords can't equal previously used ones") diff --git a/annotations/SimulatingNull.java b/annotations/SimulatingNull.java index 263052be2..af1282f88 100644 --- a/annotations/SimulatingNull.java +++ b/annotations/SimulatingNull.java @@ -1,12 +1,12 @@ // annotations/SimulatingNull.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.lang.annotation.*; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface SimulatingNull { - public int id() default -1; - public String description() default ""; + int id() default -1; + String description() default ""; } diff --git a/annotations/StackL.java b/annotations/StackL.java index 4ae80f9ee..246454c25 100644 --- a/annotations/StackL.java +++ b/annotations/StackL.java @@ -1,8 +1,8 @@ // annotations/StackL.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// A stack built on a linkedList +// Visit http://OnJava8.com for more book information. +// A stack built on a LinkedList package annotations; import java.util.*; diff --git a/annotations/StackLStringTest.java b/annotations/StackLStringTest.java deleted file mode 100644 index 364038e6b..000000000 --- a/annotations/StackLStringTest.java +++ /dev/null @@ -1,41 +0,0 @@ -// annotations/StackLStringTest.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Applying @Unit to generics -package annotations; -import onjava.atunit.*; -import onjava.*; - -public class StackLStringTest extends StackL { - @Test void _push() { - push("one"); - assert top().equals("one"); - push("two"); - assert top().equals("two"); - } - @Test void _pop() { - push("one"); - push("two"); - assert pop().equals("two"); - assert pop().equals("one"); - } - @Test void _top() { - push("A"); - push("B"); - assert top().equals("B"); - assert top().equals("B"); - } - public static void - main(String[] args) throws Exception { - OSExecute.command("java -cp .. " + - "onjava.atunit.AtUnit StackLStringTest.class"); - } -} -/* Output: -annotations.StackLStringTest - . _top - . _push - . _pop -OK (3 tests) -*/ diff --git a/annotations/StackLStringTst.java b/annotations/StackLStringTst.java new file mode 100644 index 000000000..b7d8250f7 --- /dev/null +++ b/annotations/StackLStringTst.java @@ -0,0 +1,42 @@ +// annotations/StackLStringTst.java +// (c)2021 MindView 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 + . tPop + . tTop + . tPush +OK (3 tests) +*/ diff --git a/annotations/Testable.java b/annotations/Testable.java index 369f2768c..b23d0e620 100644 --- a/annotations/Testable.java +++ b/annotations/Testable.java @@ -1,7 +1,7 @@ // annotations/Testable.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package annotations; import onjava.atunit.*; @@ -9,5 +9,6 @@ public class Testable { public void execute() { System.out.println("Executing.."); } - @Test void testExecute() { execute(); } + @Test + void testExecute() { execute(); } } diff --git a/annotations/UseCase.java b/annotations/UseCase.java index c59a14633..c65735185 100644 --- a/annotations/UseCase.java +++ b/annotations/UseCase.java @@ -1,12 +1,12 @@ // annotations/UseCase.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.lang.annotation.*; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface UseCase { - public int id(); - public String description() default "no description"; + int id(); + String description() default "no description"; } diff --git a/annotations/UseCaseTracker.java b/annotations/UseCaseTracker.java index 91da32e58..53cc92795 100644 --- a/annotations/UseCaseTracker.java +++ b/annotations/UseCaseTracker.java @@ -1,9 +1,10 @@ // annotations/UseCaseTracker.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.lang.reflect.*; +// 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 @@ -11,28 +12,26 @@ public class UseCaseTracker { for(Method m : cl.getDeclaredMethods()) { UseCase uc = m.getAnnotation(UseCase.class); if(uc != null) { - System.out.println("Found Use Case:" + uc.id() + - " " + uc.description()); - useCases.remove(new Integer(uc.id())); + System.out.println("Found Use Case " + + uc.id() + "\n " + uc.description()); + useCases.remove(Integer.valueOf(uc.id())); } } - for(int i : useCases) { - System.out.println( - "Warning: Missing use case-" + i); - } + useCases.forEach(i -> + System.out.println("Missing use case " + i)); } public static void main(String[] args) { - // <* Can't use Arrays.asList() for some reason *> - List useCases = new ArrayList<>(); - Collections.addAll(useCases, 47, 48, 49, 50); + List useCases = IntStream.range(47, 51) + .boxed().collect(Collectors.toList()); trackUseCases(useCases, PasswordUtils.class); } } /* Output: -Found Use Case:49 New passwords can't equal previously used -ones -Found Use Case:47 Passwords must contain at least one -numeric -Found Use Case:48 no description -Warning: Missing use case-50 +Found Use Case 49 + New passwords can't equal previously used ones +Found Use Case 48 + no description +Found Use Case 47 + Passwords must contain at least one numeric +Missing use case 50 */ diff --git a/annotations/build.xml b/annotations/build.xml deleted file mode 100644 index c530c3fab..000000000 --- a/annotations/build.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/annotations/database/Constraints.java b/annotations/database/Constraints.java index b16105e54..5631f52e9 100644 --- a/annotations/database/Constraints.java +++ b/annotations/database/Constraints.java @@ -1,7 +1,7 @@ // annotations/database/Constraints.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package annotations.database; import java.lang.annotation.*; diff --git a/annotations/database/DBTable.java b/annotations/database/DBTable.java index 2ff972fb6..3d345d990 100644 --- a/annotations/database/DBTable.java +++ b/annotations/database/DBTable.java @@ -1,12 +1,12 @@ // annotations/database/DBTable.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 { - public String name() default ""; + String name() default ""; } diff --git a/annotations/database/Member.java b/annotations/database/Member.java index f7b5bf347..ae5723ac8 100644 --- a/annotations/database/Member.java +++ b/annotations/database/Member.java @@ -1,7 +1,7 @@ // annotations/database/Member.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package annotations.database; @DBTable(name = "MEMBER") @@ -11,12 +11,13 @@ public class Member { @SQLInteger Integer age; @SQLString(value = 30, constraints = @Constraints(primaryKey = true)) - String handle; + String reference; static int memberCount; - public String getHandle() { return handle; } + public String getReference() { return reference; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } - @Override - public String toString() { return handle; } + @Override public String toString() { + return reference; + } public Integer getAge() { return age; } } diff --git a/annotations/database/SQLInteger.java b/annotations/database/SQLInteger.java index cffcb86b0..4df1e7dd6 100644 --- a/annotations/database/SQLInteger.java +++ b/annotations/database/SQLInteger.java @@ -1,7 +1,7 @@ // annotations/database/SQLInteger.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package annotations.database; import java.lang.annotation.*; diff --git a/annotations/database/SQLString.java b/annotations/database/SQLString.java index fbb6195aa..c452d1e95 100644 --- a/annotations/database/SQLString.java +++ b/annotations/database/SQLString.java @@ -1,7 +1,7 @@ // annotations/database/SQLString.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package annotations.database; import java.lang.annotation.*; diff --git a/annotations/database/TableCreator.java b/annotations/database/TableCreator.java index ebd70bdd1..d2be7c5e1 100644 --- a/annotations/database/TableCreator.java +++ b/annotations/database/TableCreator.java @@ -1,9 +1,10 @@ // annotations/database/TableCreator.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Reflection-based annotation processor -// {Args: annotations.database.Member} +// {java annotations.database.TableCreator +// annotations.database.Member} package annotations.database; import java.lang.annotation.*; import java.lang.reflect.*; @@ -13,7 +14,8 @@ public class TableCreator { public static void main(String[] args) throws Exception { if(args.length < 1) { - System.out.println("arguments: annotated classes"); + System.out.println( + "arguments: annotated classes"); System.exit(0); } for(String className : args) { @@ -21,7 +23,8 @@ public class TableCreator { DBTable dbTable = cl.getAnnotation(DBTable.class); if(dbTable == null) { System.out.println( - "No DBTable annotations in class " + className); + "No DBTable annotations in class " + + className); continue; } String tableName = dbTable.name(); @@ -65,11 +68,12 @@ public class TableCreator { String tableCreate = createCommand.substring( 0, createCommand.length() - 1) + ");"; System.out.println("Table Creation SQL for " + - className + " is :\n" + tableCreate); + className + " is:\n" + tableCreate); } } } - private static String getConstraints(Constraints con) { + private static + String getConstraints(Constraints con) { String constraints = ""; if(!con.allowNull()) constraints += " NOT NULL"; @@ -81,22 +85,22 @@ private static String getConstraints(Constraints con) { } } /* Output: -Table Creation SQL for annotations.database.Member is : +Table Creation SQL for annotations.database.Member is: CREATE TABLE MEMBER( FIRSTNAME VARCHAR(30)); -Table Creation SQL for annotations.database.Member is : +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 : +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 : +Table Creation SQL for annotations.database.Member is: CREATE TABLE MEMBER( FIRSTNAME VARCHAR(30), LASTNAME VARCHAR(50), AGE INT, - HANDLE VARCHAR(30) PRIMARY KEY); + REFERENCE VARCHAR(30) PRIMARY KEY); */ diff --git a/annotations/database/Uniqueness.java b/annotations/database/Uniqueness.java index 2ede0e41b..7959fe700 100644 --- a/annotations/database/Uniqueness.java +++ b/annotations/database/Uniqueness.java @@ -1,11 +1,11 @@ // annotations/database/Uniqueness.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Sample of nested annotations package annotations.database; public @interface Uniqueness { Constraints constraints() - default @Constraints(unique = true); + default @Constraints(unique = true); } diff --git a/annotations/ifx/ExtractInterface.java b/annotations/ifx/ExtractInterface.java index 68c320380..c823fe9ca 100644 --- a/annotations/ifx/ExtractInterface.java +++ b/annotations/ifx/ExtractInterface.java @@ -1,7 +1,7 @@ // annotations/ifx/ExtractInterface.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // javac-based annotation processing package annotations.ifx; import java.lang.annotation.*; @@ -9,5 +9,5 @@ @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface ExtractInterface { - public String interfaceName() default "-!!-"; + String interfaceName() default "-!!-"; } diff --git a/annotations/ifx/IfaceExtractorProcessor.java b/annotations/ifx/IfaceExtractorProcessor.java index a0e92df97..fae22607c 100644 --- a/annotations/ifx/IfaceExtractorProcessor.java +++ b/annotations/ifx/IfaceExtractorProcessor.java @@ -1,7 +1,7 @@ // annotations/ifx/IfaceExtractorProcessor.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // javac-based annotation processing package annotations.ifx; import javax.annotation.processing.*; @@ -9,6 +9,7 @@ import javax.lang.model.element.*; import javax.lang.model.util.*; import java.util.*; +import java.util.stream.*; import java.io.*; @SupportedAnnotationTypes( @@ -20,14 +21,14 @@ public class IfaceExtractorProcessor interfaceMethods = new ArrayList<>(); Elements elementUtils; private ProcessingEnvironment processingEnv; - @Override public void - init(ProcessingEnvironment processingEnv) { + @Override public void init( + ProcessingEnvironment processingEnv) { this.processingEnv = processingEnv; elementUtils = processingEnv.getElementUtils(); } - @Override public boolean - process(Set annotations, - RoundEnvironment env) { + @Override public boolean process( + Set annotations, + RoundEnvironment env) { for(Element elem:env.getElementsAnnotatedWith( ExtractInterface.class)) { String interfaceName = elem.getAnnotation( @@ -50,9 +51,11 @@ public class IfaceExtractorProcessor } private void writeInterfaceFile(String interfaceName) { - try(Writer writer = processingEnv.getFiler() - .createSourceFile(interfaceName) - .openWriter()) { + try( + Writer writer = processingEnv.getFiler() + .createSourceFile(interfaceName) + .openWriter() + ) { String packageName = elementUtils .getPackageOf(interfaceMethods .get(0)).toString(); @@ -64,7 +67,7 @@ public class IfaceExtractorProcessor ExecutableElement method = (ExecutableElement)elem; String signature = " public "; - signature += method.getReturnType()+" "; + signature += method.getReturnType() + " "; signature += method.getSimpleName(); signature += createArgList( method.getParameters()); @@ -78,15 +81,9 @@ public class IfaceExtractorProcessor } private String createArgList( List parameters) { - if(parameters.size() == 0) - return "()"; - String args = "("; - for(VariableElement p : parameters) { - args += p.asType() + " "; - args += p.getSimpleName() + ", "; - } - args = args.substring(0, args.length() - 2); - args += ")"; - return args; + String args = parameters.stream() + .map(p -> p.asType() + " " + p.getSimpleName()) + .collect(Collectors.joining(", ")); + return "(" + args + ")"; } } diff --git a/annotations/ifx/Multiplier.java b/annotations/ifx/Multiplier.java index d66270f27..25678fd5a 100644 --- a/annotations/ifx/Multiplier.java +++ b/annotations/ifx/Multiplier.java @@ -1,8 +1,9 @@ // annotations/ifx/Multiplier.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // javac-based annotation processing +// {java annotations.ifx.Multiplier} package annotations.ifx; @ExtractInterface(interfaceName="IMultiplier") diff --git a/annotations/simplest/Simple.java b/annotations/simplest/Simple.java index 7e1b8ce96..101b7900a 100644 --- a/annotations/simplest/Simple.java +++ b/annotations/simplest/Simple.java @@ -1,7 +1,7 @@ // annotations/simplest/Simple.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // A bare-bones annotation package annotations.simplest; import java.lang.annotation.Retention; diff --git a/annotations/simplest/SimpleProcessor.java b/annotations/simplest/SimpleProcessor.java index b42f2d6ef..1dda51955 100644 --- a/annotations/simplest/SimpleProcessor.java +++ b/annotations/simplest/SimpleProcessor.java @@ -1,7 +1,7 @@ // annotations/simplest/SimpleProcessor.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // A bare-bones annotation processor package annotations.simplest; import javax.annotation.processing.*; @@ -14,9 +14,9 @@ @SupportedSourceVersion(SourceVersion.RELEASE_8) public class SimpleProcessor extends AbstractProcessor { - @Override public boolean - process(Set annotations, - RoundEnvironment env) { + @Override public boolean process( + Set annotations, + RoundEnvironment env) { for(TypeElement t : annotations) System.out.println(t); for(Element el : diff --git a/annotations/simplest/SimpleTest.java b/annotations/simplest/SimpleTest.java index 2e0caf5de..e97d5871e 100644 --- a/annotations/simplest/SimpleTest.java +++ b/annotations/simplest/SimpleTest.java @@ -1,8 +1,9 @@ // annotations/simplest/SimpleTest.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Test the "Simple" annotation +// {java annotations.simplest.SimpleTest} package annotations.simplest; @Simple diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 013d861cd..000000000 --- a/appveyor.yml +++ /dev/null @@ -1,4 +0,0 @@ -build_script: - - gradlew.bat runconsole --stacktrace - -test: off diff --git a/appveyorXX.yml b/appveyorXX.yml new file mode 100644 index 000000000..5e586b07e --- /dev/null +++ b/appveyorXX.yml @@ -0,0 +1,4 @@ +build_script: + - gradlew.bat --no-daemon --stacktrace run + +test: off diff --git a/arrays/AlphabeticSearch.java b/arrays/AlphabeticSearch.java index 01c768c5b..a6dea2c2e 100644 --- a/arrays/AlphabeticSearch.java +++ b/arrays/AlphabeticSearch.java @@ -1,8 +1,8 @@ // arrays/AlphabeticSearch.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Searching with a Comparator +// Visit http://OnJava8.com for more book information. +// Searching with a Comparator import import java.util.*; import onjava.*; import static onjava.ArrayShow.*; @@ -12,17 +12,18 @@ 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); + int index = Arrays.binarySearch(sa, + sa[10], String.CASE_INSENSITIVE_ORDER); System.out.println( - "Index: "+ index + "\n"+ sa[index]); + "Index: "+ index + "\n"+ sa[index]); } } /* Output: -[bkIna, cQrGs, cXZJo, dLsmw, eGZMm, EqUCB, gwsqP, hKcxr, -HLGEa, HqXum, HxxHv, JMRoE, JmzMs, Mesbt, MNvqe, nyGcF, -ogoYW, OneOE, OWZnT, RFJQA, rUkZP, sgqia, slJrL, suEcU, -uTpnX, vpfFv, WHkjU, xxEAJ, YNzbr, zDyCy] +[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 -HxxHv +gmeinne */ diff --git a/arrays/ArrayCopying.java b/arrays/ArrayCopying.java index 52fa0ff4e..b5dc136f8 100644 --- a/arrays/ArrayCopying.java +++ b/arrays/ArrayCopying.java @@ -1,7 +1,7 @@ // arrays/ArrayCopying.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Demonstrate Arrays.copy() and Arrays.copyOf() import java.util.*; import onjava.*; @@ -9,15 +9,14 @@ class Sup { // Superclass private int id; - public Sup(int n) { id = n; } - @Override - public String toString() { + Sup(int n) { id = n; } + @Override public String toString() { return getClass().getSimpleName() + id; } } class Sub extends Sup { // Subclass - public Sub(int n) { super(n); } + Sub(int n) { super(n); } } public class ArrayCopying { @@ -26,21 +25,21 @@ 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) + 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) + 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) + Integer[] a3 = new Integer[SZ]; // [3] Arrays.setAll(a3, new Count.Integer()::get); Integer[] a4 = Arrays.copyOfRange(a3, 4, 12); show("a4", a4); @@ -49,32 +48,32 @@ public static void main(String[] args) { Arrays.setAll(d, Sub::new); // Produce Sup[] from Sub[]: Sup[] b = - Arrays.copyOf(d, d.length, Sup[].class); // (4) + Arrays.copyOf(d, d.length, Sup[].class); // [4] show(b); // This "downcast" works fine: Sub[] d2 = - Arrays.copyOf(b, b.length, Sub[].class); // (5) + 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) + 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] +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/arrays/ArrayOfGenericType.java b/arrays/ArrayOfGenericType.java index bd89ffddf..6c2df8468 100644 --- a/arrays/ArrayOfGenericType.java +++ b/arrays/ArrayOfGenericType.java @@ -1,14 +1,14 @@ // arrays/ArrayOfGenericType.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 = new T[size]; array = (T[])new Object[size]; // unchecked cast } // error: generic array creation: diff --git a/arrays/ArrayOfGenerics.java b/arrays/ArrayOfGenerics.java index b205e82b5..8040dfa1f 100644 --- a/arrays/ArrayOfGenerics.java +++ b/arrays/ArrayOfGenerics.java @@ -1,7 +1,7 @@ // arrays/ArrayOfGenerics.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class ArrayOfGenerics { @@ -12,7 +12,7 @@ public static void main(String[] args) { ls = (List[])la; // Unchecked cast ls[0] = new ArrayList<>(); - // -ls[1] = new ArrayList(); + //- ls[1] = new ArrayList(); // error: incompatible types: ArrayList // cannot be converted to List // ls[1] = new ArrayList(); diff --git a/arrays/ArrayOptions.java b/arrays/ArrayOptions.java index 2107cae9d..c313d9a29 100644 --- a/arrays/ArrayOptions.java +++ b/arrays/ArrayOptions.java @@ -1,7 +1,7 @@ // arrays/ArrayOptions.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Initialization & re-assignment of arrays import java.util.*; import static onjava.ArrayShow.*; @@ -9,7 +9,7 @@ public class ArrayOptions { public static void main(String[] args) { // Arrays of objects: - BerylliumSphere[] a; // Local uninitialized variable + BerylliumSphere[] a; // Uninitialized local BerylliumSphere[] b = new BerylliumSphere[5]; // The references inside the array are diff --git a/arrays/ArraySearching.java b/arrays/ArraySearching.java index 2868744b9..deae72faf 100644 --- a/arrays/ArraySearching.java +++ b/arrays/ArraySearching.java @@ -1,7 +1,7 @@ // arrays/ArraySearching.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Using Arrays.binarySearch() import java.util.*; import onjava.*; @@ -9,8 +9,8 @@ public class ArraySearching { public static void main(String[] args) { - Rand.int_ rand = new Rand.int_(); - int[] a = new Rand.int_().array(25); + Rand.Pint rand = new Rand.Pint(); + int[] a = new Rand.Pint().array(25); Arrays.sort(a); show("Sorted array", a); while(true) { diff --git a/arrays/AssemblingMultidimensionalArrays.java b/arrays/AssemblingMultidimensionalArrays.java index 5667961f7..945c338e4 100644 --- a/arrays/AssemblingMultidimensionalArrays.java +++ b/arrays/AssemblingMultidimensionalArrays.java @@ -1,7 +1,7 @@ // arrays/AssemblingMultidimensionalArrays.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Creating multidimensional arrays import java.util.*; diff --git a/arrays/AutoboxingArrays.java b/arrays/AutoboxingArrays.java index 08cbe7133..d8601627c 100644 --- a/arrays/AutoboxingArrays.java +++ b/arrays/AutoboxingArrays.java @@ -1,7 +1,7 @@ // arrays/AutoboxingArrays.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class AutoboxingArrays { @@ -16,7 +16,7 @@ public static void main(String[] args) { } } /* 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]] +[[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/arrays/BadMicroBenchmark.java b/arrays/BadMicroBenchmark.java deleted file mode 100644 index 765df060d..000000000 --- a/arrays/BadMicroBenchmark.java +++ /dev/null @@ -1,21 +0,0 @@ -// arrays/BadMicroBenchmark.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.*; -import static onjava.TimeIt.*; - -public class BadMicroBenchmark { - static final int SIZE = 20_000_000; - public static void main(String[] args) { - long[] la = new long[SIZE]; - System.out.print("setAll: "); - timeIt(() -> Arrays.setAll(la, n -> n)); - System.out.print("parallelSetAll: "); - timeIt(() -> Arrays.parallelSetAll(la, n -> n)); - } -} -/* Output: -setAll: 27 -parallelSetAll: 53 -*/ diff --git a/arrays/BadMicroBenchmark2.java b/arrays/BadMicroBenchmark2.java deleted file mode 100644 index b4db07002..000000000 --- a/arrays/BadMicroBenchmark2.java +++ /dev/null @@ -1,22 +0,0 @@ -// arrays/BadMicroBenchmark2.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Reversing the test order -import java.util.*; -import static onjava.TimeIt.*; - -public class BadMicroBenchmark2 { - static final int SIZE = 20_000_000; - public static void main(String[] args) { - long[] la = new long[SIZE]; - System.out.print("parallelSetAll: "); - timeIt(() -> Arrays.parallelSetAll(la, n -> n)); - System.out.print("setAll: "); - timeIt(() -> Arrays.setAll(la, n -> n)); - } -} -/* Output: -parallelSetAll: 38 -setAll: 63 -*/ diff --git a/arrays/BadMicroBenchmark3.java b/arrays/BadMicroBenchmark3.java deleted file mode 100644 index aea7532c6..000000000 --- a/arrays/BadMicroBenchmark3.java +++ /dev/null @@ -1,34 +0,0 @@ -// arrays/BadMicroBenchmark3.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Relying on a common resource -import java.util.*; -import static onjava.TimeIt.*; - -public class BadMicroBenchmark3 { - static final int SIZE = 20_000_000; - public static void main(String[] args) { - long[] la = new long[SIZE]; - Random r = new Random(); - System.out.print("parallelSetAll: "); - timeIt(() -> - Arrays.parallelSetAll(la, n -> r.nextLong())); - System.out.print("setAll: "); - timeIt(() -> - Arrays.setAll(la, n -> r.nextLong())); - SplittableRandom sr = new SplittableRandom(); - System.out.print("parallelSetAll: "); - timeIt(() -> - Arrays.parallelSetAll(la, n -> sr.nextLong())); - System.out.print("setAll: "); - timeIt(() -> - Arrays.setAll(la, n -> sr.nextLong())); - } -} -/* Output: -parallelSetAll: 5150 -setAll: 649 -parallelSetAll: 277 -setAll: 246 -*/ diff --git a/arrays/CollectionComparison.java b/arrays/CollectionComparison.java index 51ae19ade..b5f0b1132 100644 --- a/arrays/CollectionComparison.java +++ b/arrays/CollectionComparison.java @@ -1,7 +1,7 @@ // arrays/CollectionComparison.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import onjava.*; import static onjava.ArrayShow.*; @@ -9,13 +9,15 @@ class BerylliumSphere { private static long counter; private final long id = counter++; - @Override - public String toString() { return "Sphere " + id; } + @Override public String toString() { + return "Sphere " + id; + } } public class CollectionComparison { public static void main(String[] args) { - BerylliumSphere[] spheres = new BerylliumSphere[10]; + BerylliumSphere[] spheres = + new BerylliumSphere[10]; for(int i = 0; i < 5; i++) spheres[i] = new BerylliumSphere(); show(spheres); @@ -38,8 +40,8 @@ public static void main(String[] args) { } } /* Output: -[Sphere 0, Sphere 1, Sphere 2, Sphere 3, Sphere 4, null, -null, null, null, null] +[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 diff --git a/arrays/CompType.java b/arrays/CompType.java index 70a1587e1..8d7e82a33 100644 --- a/arrays/CompType.java +++ b/arrays/CompType.java @@ -1,7 +1,7 @@ // arrays/CompType.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Implementing Comparable in a class import java.util.*; import java.util.function.*; @@ -16,15 +16,13 @@ public CompType(int n1, int n2) { i = n1; j = n2; } - @Override - public String toString() { + @Override public String toString() { String result = "[i = " + i + ", j = " + j + "]"; if(count++ % 3 == 0) result += "\n"; return result; } - @Override - public int compareTo(CompType rv) { + @Override public int compareTo(CompType rv) { return (i < rv.i ? -1 : (i == rv.i ? 0 : 1)); } private static SplittableRandom r = @@ -41,16 +39,16 @@ public static void main(String[] args) { } } /* Output: -before sorting: -[[i = 58, j = 55], [i = 93, j = 61], [i = 61, j = 29] -, [i = 68, j = 0], [i = 22, j = 7], [i = 88, j = 28] -, [i = 51, j = 89], [i = 9, j = 78], [i = 98, j = 61] -, [i = 20, j = 58], [i = 16, j = 40], [i = 11, j = 22] +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 = 9, j = 78], [i = 11, j = 22], [i = 16, j = 40] -, [i = 20, j = 58], [i = 22, j = 7], [i = 51, j = 89] -, [i = 58, j = 55], [i = 61, j = 29], [i = 68, j = 0] -, [i = 88, j = 28], [i = 93, j = 61], [i = 98, j = 61] +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/arrays/ComparatorTest.java b/arrays/ComparatorTest.java index 85abb45a8..fbe385879 100644 --- a/arrays/ComparatorTest.java +++ b/arrays/ComparatorTest.java @@ -1,13 +1,14 @@ // arrays/ComparatorTest.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 { +class CompTypeComparator +implements Comparator { public int compare(CompType o1, CompType o2) { return (o1.j < o2.j ? -1 : (o1.j == o2.j ? 0 : 1)); } @@ -23,16 +24,16 @@ public static void main(String[] args) { } } /* Output: -before sorting: -[[i = 58, j = 55], [i = 93, j = 61], [i = 61, j = 29] -, [i = 68, j = 0], [i = 22, j = 7], [i = 88, j = 28] -, [i = 51, j = 89], [i = 9, j = 78], [i = 98, j = 61] -, [i = 20, j = 58], [i = 16, j = 40], [i = 11, j = 22] +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 = 68, j = 0], [i = 22, j = 7], [i = 11, j = 22] -, [i = 88, j = 28], [i = 61, j = 29], [i = 16, j = 40] -, [i = 58, j = 55], [i = 20, j = 58], [i = 93, j = 61] -, [i = 98, j = 61], [i = 9, j = 78], [i = 51, j = 89] +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/arrays/ComparingArrays.java b/arrays/ComparingArrays.java index bbdcdfe30..c97c22d04 100644 --- a/arrays/ComparingArrays.java +++ b/arrays/ComparingArrays.java @@ -1,14 +1,14 @@ // arrays/ComparingArrays.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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() { + static String[][] twoDArray() { String[][] md = new String[5][]; Arrays.setAll(md, n -> new String[n]); for(int i = 0; i < md.length; i++) @@ -35,7 +35,7 @@ public static void main(String[] args) { System.out.println( "a1w == a2w: " + Arrays.equals(a1w, a2w)); - String[][] md1 = TwoDArray(), md2 = TwoDArray(); + String[][] md1 = twoDArray(), md2 = twoDArray(); System.out.println(Arrays.deepToString(md1)); System.out.println("deepEquals(md1, md2): " + Arrays.deepEquals(md1, md2)); @@ -52,9 +52,11 @@ public static void main(String[] args) { a1 == a2: false a1w == a2w: true a1w == a2w: false -[[], [YNzbrny], [YNzbrny, GcFOWZn], [YNzbrny, GcFOWZn, TcQrGse], [YNzbrny, GcFOWZn, TcQrGse, GZMmJMR]] +[[], [btpenpc], [btpenpc, cuxszgv], [btpenpc, cuxszgv, +gmeinne], [btpenpc, cuxszgv, gmeinne, eloztdv]] deepEquals(md1, md2): true md1 == md2: false -[[], [YNzbrny], [YNzbrny, GcFOWZn], [YNzbrny, GcFOWZn, TcQrGse], [YNzbrny, #$#$#$#, TcQrGse, GZMmJMR]] +[[], [btpenpc], [btpenpc, cuxszgv], [btpenpc, cuxszgv, +gmeinne], [btpenpc, #$#$#$#, gmeinne, eloztdv]] deepEquals(md1, md2): false */ diff --git a/arrays/CountUpward.java b/arrays/CountUpward.java index 490995837..3ac361c86 100644 --- a/arrays/CountUpward.java +++ b/arrays/CountUpward.java @@ -1,7 +1,7 @@ // arrays/CountUpward.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; import static onjava.ArrayShow.*; @@ -19,5 +19,6 @@ public static void main(String[] args) { } } /* Output: -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] +[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, +16, 17, 18, 19] */ diff --git a/arrays/FillingArrays.java b/arrays/FillingArrays.java index 9c27d8323..b7445dfdb 100644 --- a/arrays/FillingArrays.java +++ b/arrays/FillingArrays.java @@ -1,7 +1,7 @@ // arrays/FillingArrays.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Using Arrays.fill() import java.util.*; import static onjava.ArrayShow.*; @@ -42,14 +42,14 @@ public static void main(String[] args) { } } /* 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] +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/arrays/IceCream.java b/arrays/IceCreamFlavors.java similarity index 66% rename from arrays/IceCream.java rename to arrays/IceCreamFlavors.java index 7ee32d7b7..1be802edd 100644 --- a/arrays/IceCream.java +++ b/arrays/IceCreamFlavors.java @@ -1,12 +1,12 @@ -// arrays/IceCream.java -// (c)2016 MindView LLC: see Copyright.txt +// arrays/IceCreamFlavors.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Returning arrays from methods import java.util.*; import static onjava.ArrayShow.*; -public class IceCream { +public class IceCreamFlavors { private static SplittableRandom rand = new SplittableRandom(47); static final String[] FLAVORS = { @@ -35,11 +35,11 @@ public static void main(String[] args) { } } /* Output: -[Rum Raisin, Mint Chip, Mocha Almond Fudge] -[Chocolate, Strawberry, Mocha Almond Fudge] -[Strawberry, Mint Chip, Mocha Almond Fudge] -[Rum Raisin, Vanilla Fudge Swirl, Mud Pie] -[Vanilla Fudge Swirl, Chocolate, Mocha Almond Fudge] -[Praline Cream, Strawberry, Mocha Almond Fudge] -[Mocha Almond Fudge, Strawberry, Mint Chip] +[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/arrays/ModifyExisting.java b/arrays/ModifyExisting.java index 3db997b11..0c33b8d19 100644 --- a/arrays/ModifyExisting.java +++ b/arrays/ModifyExisting.java @@ -1,7 +1,7 @@ // arrays/ModifyExisting.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import onjava.*; import static onjava.ArrayShow.*; @@ -11,11 +11,12 @@ 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) + Arrays.setAll(da, n -> da[n] / 100); // [1] show(da); } } /* Output: -[0.73, 0.53, 0.16, 0.19, 0.52, 0.27, 0.26] -[0.0073, 0.0053, 0.0016, 0.0019, 0.0052, 0.0027, 0.0026] +[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/arrays/MultiDimWrapperArray.java b/arrays/MultiDimWrapperArray.java index 9c6c927a2..5055a1cbf 100644 --- a/arrays/MultiDimWrapperArray.java +++ b/arrays/MultiDimWrapperArray.java @@ -1,7 +1,7 @@ // arrays/MultiDimWrapperArray.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Multidimensional arrays of "wrapper" objects import java.util.*; @@ -19,17 +19,20 @@ public static void main(String[] args) { String[][] a3 = { { "The", "Quick", "Sly", "Fox" }, { "Jumped", "Over" }, - { "The", "Lazy", "Brown", "Dog", "and", "friend" }, + { "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)); + 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, and, friend]] +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/arrays/MultidimensionalObjectArrays.java b/arrays/MultidimensionalObjectArrays.java index 465e5ea25..8c91e7b5a 100644 --- a/arrays/MultidimensionalObjectArrays.java +++ b/arrays/MultidimensionalObjectArrays.java @@ -1,7 +1,7 @@ // arrays/MultidimensionalObjectArrays.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class MultidimensionalObjectArrays { @@ -20,6 +20,6 @@ public static void main(String[] args) { } /* 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]] +Sphere 5], [Sphere 6, Sphere 7, Sphere 8, Sphere 9, +Sphere 10, Sphere 11, Sphere 12, Sphere 13]] */ diff --git a/arrays/MultidimensionalPrimitiveArray.java b/arrays/MultidimensionalPrimitiveArray.java index 1162f60fa..ffebf2b6f 100644 --- a/arrays/MultidimensionalPrimitiveArray.java +++ b/arrays/MultidimensionalPrimitiveArray.java @@ -1,7 +1,7 @@ // arrays/MultidimensionalPrimitiveArray.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class MultidimensionalPrimitiveArray { diff --git a/arrays/Prefix1.java b/arrays/ParallelPrefix1.java similarity index 68% rename from arrays/Prefix1.java rename to arrays/ParallelPrefix1.java index fa3629a3c..243753168 100644 --- a/arrays/Prefix1.java +++ b/arrays/ParallelPrefix1.java @@ -1,21 +1,21 @@ -// arrays/Prefix1.java -// (c)2016 MindView LLC: see Copyright.txt +// arrays/ParallelPrefix1.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import onjava.*; import static onjava.ArrayShow.*; -public class Prefix1 { +public class ParallelPrefix1 { public static void main(String[] args) { - int[] nums = new Count.int_().array(10); + 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.int_().array(6)) + new Count.Pint().array(6)) .reduce(Integer::sum).getAsInt()); } } diff --git a/arrays/Prefix2.java b/arrays/ParallelPrefix2.java similarity index 72% rename from arrays/Prefix2.java rename to arrays/ParallelPrefix2.java index 645482697..c7963fe83 100644 --- a/arrays/Prefix2.java +++ b/arrays/ParallelPrefix2.java @@ -1,12 +1,12 @@ -// arrays/Prefix2.java -// (c)2016 MindView LLC: see Copyright.txt +// arrays/ParallelPrefix2.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import onjava.*; import static onjava.ArrayShow.*; -public class Prefix2 { +public class ParallelPrefix2 { public static void main(String[] args) { String[] strings = new Rand.String(1).array(8); show(strings); diff --git a/arrays/ParallelPrefix.java b/arrays/ParallelPrefix3.java similarity index 64% rename from arrays/ParallelPrefix.java rename to arrays/ParallelPrefix3.java index 104ebfdc5..88d32916e 100644 --- a/arrays/ParallelPrefix.java +++ b/arrays/ParallelPrefix3.java @@ -1,11 +1,12 @@ -// arrays/ParallelPrefix.java -// (c)2016 MindView LLC: see Copyright.txt +// arrays/ParallelPrefix3.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {ExcludeFromTravisCI} import java.util.*; -public class ParallelPrefix { - static final int SIZE = 20_000_000; +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); @@ -18,5 +19,5 @@ public static void main(String[] args) { /* Output: First 20: 190 First 200: 19900 -All: 199999990000000 +All: 49999995000000 */ diff --git a/arrays/ParallelSetAll.java b/arrays/ParallelSetAll.java index c17a0225f..787d2daf9 100644 --- a/arrays/ParallelSetAll.java +++ b/arrays/ParallelSetAll.java @@ -1,21 +1,21 @@ // arrays/ParallelSetAll.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import onjava.*; public class ParallelSetAll { - static final int SIZE = 20_000_000; + static final int SIZE = 10_000_000; static void intArray() { int[] ia = new int[SIZE]; - Arrays.setAll(ia, new Rand.int_()::get); - Arrays.parallelSetAll(ia, new Rand.int_()::get); + 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.long_()::get); - Arrays.parallelSetAll(la, new Rand.long_()::get); + Arrays.setAll(la, new Rand.Plong()::get); + Arrays.parallelSetAll(la, new Rand.Plong()::get); } public static void main(String[] args) { intArray(); diff --git a/arrays/ParallelSort.java b/arrays/ParallelSort.java deleted file mode 100644 index 4b724c80f..000000000 --- a/arrays/ParallelSort.java +++ /dev/null @@ -1,26 +0,0 @@ -// arrays/ParallelSort.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.*; -import java.time.*; -import onjava.*; -import static onjava.TimeIt.*; - -public class ParallelSort { - static final int SZ = 10_000_000; - public static void main(String[] args) { - int[] ia1 = new Rand.int_().array(SZ); - int[] ia2 = Arrays.copyOf(ia1, ia1.length); - System.out.print("sort(): "); - long millis1 = timeIt(() -> Arrays.sort(ia1)); - System.out.print("parallelSort(): "); - long millis2 = timeIt(() -> Arrays.parallelSort(ia2)); - System.out.println(millis1/millis2); - } -} -/* Output: -sort(): 484 -parallelSort(): 149 -3 -*/ diff --git a/arrays/ParameterizedArrayType.java b/arrays/ParameterizedArrayType.java index b8fff08a1..7213afde5 100644 --- a/arrays/ParameterizedArrayType.java +++ b/arrays/ParameterizedArrayType.java @@ -1,7 +1,7 @@ // arrays/ParameterizedArrayType.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class ClassParameter { public T[] f(T[] arg) { return arg; } diff --git a/arrays/PythonLists.py b/arrays/PythonLists.py index 2d8ed47e8..3ed60ee91 100644 --- a/arrays/PythonLists.py +++ b/arrays/PythonLists.py @@ -1,7 +1,7 @@ # arrays/PythonLists.py -# (c)2016 MindView LLC: see Copyright.txt +# (c)2021 MindView LLC: see Copyright.txt # We make no guarantees that this code is fit for any purpose. -# Visit http://mindviewinc.com/Books/OnJava/ for more book information. +# Visit http://OnJava8.com for more book information. aList = [1, 2, 3, 4, 5] print(type(aList)) # @@ -14,13 +14,13 @@ print(aSlice) # [3, 4] class MyList(list): # Inherit from list - # Define a method, 'this' pointer is explicit: + # 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: +# No 'new' necessary for object creation: {#24-no-new-necessary-for-object-creation} list2 = MyList(aList) print(type(list2)) # print(list2.getReversed()) # [8, 7, 6, 5, 4, 3, 2, 1] diff --git a/arrays/RaggedArray.java b/arrays/RaggedArray.java index 78125295c..dfae93d64 100644 --- a/arrays/RaggedArray.java +++ b/arrays/RaggedArray.java @@ -1,7 +1,7 @@ // arrays/RaggedArray.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class RaggedArray { @@ -14,14 +14,13 @@ public static void main(String[] args) { 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) + 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, 13], [14], [15, 16, 17, 18]], [[19, 20, 21], -[22, 23, 24], [25], []], [[26], [], [27]]] +[[[1], []], [[2, 3, 4, 5], [6]], [[7, 8, 9], [10, 11, +12], []]] */ diff --git a/arrays/Reverse.java b/arrays/Reverse.java index 729cf395b..0f2719cec 100644 --- a/arrays/Reverse.java +++ b/arrays/Reverse.java @@ -1,7 +1,7 @@ // arrays/Reverse.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // The Collections.reverseOrder() Comparator import java.util.*; import onjava.*; @@ -17,16 +17,16 @@ public static void main(String[] args) { } } /* Output: -before sorting: -[[i = 58, j = 55], [i = 93, j = 61], [i = 61, j = 29] -, [i = 68, j = 0], [i = 22, j = 7], [i = 88, j = 28] -, [i = 51, j = 89], [i = 9, j = 78], [i = 98, j = 61] -, [i = 20, j = 58], [i = 16, j = 40], [i = 11, j = 22] +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 = 98, j = 61], [i = 93, j = 61], [i = 88, j = 28] -, [i = 68, j = 0], [i = 61, j = 29], [i = 58, j = 55] -, [i = 51, j = 89], [i = 22, j = 7], [i = 20, j = 58] -, [i = 16, j = 40], [i = 11, j = 22], [i = 9, j = 78] +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/arrays/SimpleSetAll.java b/arrays/SimpleSetAll.java index 698fc0c3d..072975b00 100644 --- a/arrays/SimpleSetAll.java +++ b/arrays/SimpleSetAll.java @@ -1,20 +1,21 @@ // arrays/SimpleSetAll.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import static onjava.ArrayShow.*; class Bob { final int id; - public Bob(int n) { id = n; } - @Override - public String toString() { return "Bob" + id; } + Bob(int n) { id = n; } + @Override public String toString() { + return "Bob" + id; + } } public class SimpleSetAll { public static final int SZ = 8; - public static int val = 1; + static int val = 1; static char[] chars = "abcdefghijklmnopqrstuvwxyz" .toCharArray(); static char getChar(int n) { return chars[n]; } @@ -22,13 +23,13 @@ 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(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(ia, n -> val++); // [2] Arrays.setAll(la, n -> val++); Arrays.setAll(da, n -> val++); show(ia); @@ -36,11 +37,11 @@ public static void main(String[] args) { show(da); Bob[] ba = new Bob[SZ]; - Arrays.setAll(ba, Bob::new); // (3) + Arrays.setAll(ba, Bob::new); // [3] show(ba); Character[] ca = new Character[SZ]; - Arrays.setAll(ca, SimpleSetAll::getChar); // (4) + Arrays.setAll(ca, SimpleSetAll::getChar); // [4] show(ca); } } diff --git a/arrays/StreamFromArray.java b/arrays/StreamFromArray.java index 9808bdaad..b30ed6d44 100644 --- a/arrays/StreamFromArray.java +++ b/arrays/StreamFromArray.java @@ -1,7 +1,7 @@ // arrays/StreamFromArray.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import onjava.*; @@ -14,7 +14,7 @@ public static void main(String[] args) { .map(ss -> ss + "!") .forEach(System.out::println); - int[] ia = new Rand.int_().array(10); + int[] ia = new Rand.Pint().array(10); Arrays.stream(ia) .skip(3) .limit(5) @@ -32,7 +32,7 @@ public static void main(String[] args) { //- Arrays.stream(new float[10]); // For the other types you must use wrapped arrays: - float[] fa = new Rand.float_().array(10); + float[] fa = new Rand.Pfloat().array(10); Arrays.stream(ConvertTo.boxed(fa)); Arrays.stream(new Rand.Float().array(10)); } diff --git a/arrays/StringSorting.java b/arrays/StringSorting.java index bbdac6df9..aef57048d 100644 --- a/arrays/StringSorting.java +++ b/arrays/StringSorting.java @@ -1,7 +1,7 @@ // arrays/StringSorting.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Sorting an array of Strings import java.util.*; import onjava.*; @@ -20,16 +20,20 @@ public static void main(String[] args) { } } /* Output: -Before sort: [YNzbr, nyGcF, OWZnT, cQrGs, eGZMm, JMRoE, -suEcU, OneOE, dLsmw, HLGEa, hKcxr, EqUCB, bkIna, Mesbt, -WHkjU, rUkZP, gwsqP, zDyCy, RFJQA, HxxHv] -After sort: [EqUCB, HLGEa, HxxHv, JMRoE, Mesbt, OWZnT, -OneOE, RFJQA, WHkjU, YNzbr, bkIna, cQrGs, dLsmw, eGZMm, -gwsqP, hKcxr, nyGcF, rUkZP, suEcU, zDyCy] -Reverse sort: [zDyCy, suEcU, rUkZP, nyGcF, hKcxr, gwsqP, -eGZMm, dLsmw, cQrGs, bkIna, YNzbr, WHkjU, RFJQA, OneOE, -OWZnT, Mesbt, JMRoE, HxxHv, HLGEa, EqUCB] -Case-insensitive sort: [bkIna, cQrGs, dLsmw, eGZMm, EqUCB, -gwsqP, hKcxr, HLGEa, HxxHv, JMRoE, Mesbt, nyGcF, OneOE, -OWZnT, RFJQA, rUkZP, suEcU, WHkjU, YNzbr, zDyCy] +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/arrays/TestConvertTo.java b/arrays/TestConvertTo.java index 1970be8bb..8b8f849a5 100644 --- a/arrays/TestConvertTo.java +++ b/arrays/TestConvertTo.java @@ -1,65 +1,65 @@ // arrays/TestConvertTo.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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; + static final int SIZE = 6; public static void main(String[] args) { - Boolean[] a1 = new Boolean[size]; + 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]; + 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]; + 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]; + 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]; + 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]; + 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]; + 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]; + Double[] a8 = new Double[SIZE]; Arrays.setAll(a8, new Rand.Double()::get); double[] a8p = primitive(a8); show("a8p", a8p); diff --git a/arrays/TestCount.java b/arrays/TestCount.java index 909f6fb11..b6b3e7b8d 100644 --- a/arrays/TestCount.java +++ b/arrays/TestCount.java @@ -1,7 +1,7 @@ // arrays/TestCount.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Test counting generators import java.util.*; import java.util.stream.*; @@ -15,82 +15,109 @@ public static void main(String[] args) { Boolean[] a1 = new Boolean[SZ]; Arrays.setAll(a1, new Count.Boolean()::get); show(a1); - show(Stream.generate(new Count.Boolean()) - .limit(SZ + 1).toArray()); - show(new Count.Boolean().array(SZ + 2)); - show(new Count.boolean_().array(SZ + 3)); + 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); - show(Stream.generate(new Count.Byte()) - .limit(SZ + 1).toArray()); - show(new Count.Byte().array(SZ + 2)); - show(new Count.byte_().array(SZ + 3)); + 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); - show(Stream.generate(new Count.Character()) - .limit(SZ + 1).toArray()); - show(new Count.Character().array(SZ + 2)); - show(new Count.char_().array(SZ + 3)); + 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); - show(Stream.generate(new Count.Short()) - .limit(SZ + 1).toArray()); - show(new Count.Short().array(SZ + 2)); - show(new Count.short_().array(SZ + 3)); + 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); - show(Stream.generate(new Count.Integer()) - .limit(SZ + 1).toArray()); - show(new Count.Integer().array(SZ + 2)); - a5 = IntStream.generate(new Count.int_()) + 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); - show(new Count.int_().array(SZ + 3)); + 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); - show(Stream.generate(new Count.Long()) - .limit(SZ + 1).toArray()); - show(new Count.Long().array(SZ + 2)); - a6 = LongStream.generate(new Count.long_()) + 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); - show(new Count.long_().array(SZ + 3)); + 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); - show(Stream.generate(new Count.Float()) - .limit(SZ + 1).toArray()); - show(new Count.Float().array(SZ + 2)); - show(new Count.float_().array(SZ + 3)); + 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); - show(Stream.generate(new Count.Double()) - .limit(SZ + 1).toArray()); - show(new Count.Double().array(SZ + 2)); - a8 = DoubleStream.generate(new Count.double_()) + 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); - show(new Count.double_().array(SZ + 3)); + a8 = new Count.Pdouble().array(SZ + 3); + show(a8); } } /* Output: diff --git a/arrays/TestRand.java b/arrays/TestRand.java index 56ee188e6..45d248ade 100644 --- a/arrays/TestRand.java +++ b/arrays/TestRand.java @@ -1,7 +1,7 @@ // arrays/TestRand.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Test random generators import java.util.*; import java.util.stream.*; @@ -15,96 +15,127 @@ public static void main(String[] args) { Boolean[] a1 = new Boolean[SZ]; Arrays.setAll(a1, new Rand.Boolean()::get); show(a1); - show(Stream.generate(new Rand.Boolean()) - .limit(SZ + 1).toArray()); - show(new Rand.Boolean().array(SZ + 2)); - show(new Rand.boolean_().array(SZ + 3)); + 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); - show(Stream.generate(new Rand.Byte()) - .limit(SZ + 1).toArray()); - show(new Rand.Byte().array(SZ + 2)); - show(new Rand.byte_().array(SZ + 3)); + 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); - show(Stream.generate(new Rand.Character()) - .limit(SZ + 1).toArray()); - show(new Rand.Character().array(SZ + 2)); - show(new Rand.char_().array(SZ + 3)); + 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); - show(Stream.generate(new Rand.Short()) - .limit(SZ + 1).toArray()); - show(new Rand.Short().array(SZ + 2)); - show(new Rand.short_().array(SZ + 3)); + 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); - show(Stream.generate(new Rand.Integer()) - .limit(SZ + 1).toArray()); - show(new Rand.Integer().array(SZ + 2)); - a5 = IntStream.generate(new Rand.int_()) + 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); - show(new Rand.int_().array(SZ + 3)); + 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); - show(Stream.generate(new Rand.Long()) - .limit(SZ + 1).toArray()); - show(new Rand.Long().array(SZ + 2)); - a6 = LongStream.generate(new Rand.long_()) + 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); - show(new Rand.long_().array(SZ + 3)); + 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); - show(Stream.generate(new Rand.Float()) - .limit(SZ + 1).toArray()); - show(new Rand.Float().array(SZ + 2)); - show(new Rand.float_().array(SZ + 3)); + 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); - show(Stream.generate(new Rand.Double()) - .limit(SZ + 1).toArray()); - show(new Rand.Double().array(SZ + 2)); - a8 = DoubleStream.generate(new Rand.double_()) - .limit(SZ + 2).toArray(); + 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); - show(new Rand.double_().array(SZ + 3)); System.out.println("String"); String[] s = new String[SZ - 1]; Arrays.setAll(s, new Rand.String()::get); show(s); - show(Stream.generate(new Rand.String()) - .limit(SZ).toArray()); - show(new Rand.String().array(SZ + 1)); + 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); - show(Stream.generate(new Rand.String(4)) - .limit(SZ).toArray()); - show(new Rand.String(4).array(SZ + 1)); + 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: @@ -149,13 +180,13 @@ public static void main(String[] args) { [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] +[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] +[btpe, npcc, uxsz, gvgm, einn, eelo] [btpe, npcc, uxsz, gvgm, einn] [btpe, npcc, uxsz, gvgm, einn, eelo] */ diff --git a/arrays/ThreeDWithNew.java b/arrays/ThreeDWithNew.java index ca175fa29..f1ab3393a 100644 --- a/arrays/ThreeDWithNew.java +++ b/arrays/ThreeDWithNew.java @@ -1,7 +1,7 @@ // arrays/ThreeDWithNew.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class ThreeDWithNew { diff --git a/arrays/build.xml b/arrays/build.xml deleted file mode 100644 index 97d2372da..000000000 --- a/arrays/build.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/arrays/jmh/ParallelSort.java b/arrays/jmh/ParallelSort.java new file mode 100644 index 000000000..64ff004d3 --- /dev/null +++ b/arrays/jmh/ParallelSort.java @@ -0,0 +1,25 @@ +// arrays/jmh/ParallelSort.java +// (c)2021 MindView 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/assertions/Assert2.java b/assertions/Assert2.java deleted file mode 100644 index 0549ede0e..000000000 --- a/assertions/Assert2.java +++ /dev/null @@ -1,20 +0,0 @@ -// assertions/Assert2.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Assert with an information-expression -// {JVMArgs: -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) -___[ Exception is Expected ]___ -*/ diff --git a/assertions/Queue.java b/assertions/Queue.java deleted file mode 100644 index 8d6b43567..000000000 --- a/assertions/Queue.java +++ /dev/null @@ -1,236 +0,0 @@ -// assertions/Queue.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Demonstration of Design by Contract (DbC) -// combined with white-box unit testing -// (Install libraries from www.junit.org) -import java.util.*; -import org.junit.Test; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertFalse; - -public class Queue { - 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 static class - QueueException extends RuntimeException { - public QueueException(String why) { super(why); } - } - public Queue(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 void put(Object item) { - precondition(item != null, "put() null item"); - precondition(!full(), "put() into full Queue"); - assert invariant(); - data[in++] = item; - if(in >= data.length) { - in = 0; - wrapped = true; - } - assert invariant(); - } - public Object get() { - precondition(!empty(), "get() from empty Queue"); - 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 Queue"); - assert invariant(); - return returnVal; - } - // Design-by-contract support methods: - private static void - precondition(boolean cond, String msg) { - if(!cond) throw new QueueException(msg); - } - private static boolean - postcondition(boolean cond, String msg) { - if(!cond) throw new QueueException(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 QueueException("null in queue"); - // 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 QueueException( - "non-null outside of queue range: " + dump()); - return true; - } - private String dump() { - return "in = " + in + - ", out = " + out + - ", full() = " + full() + - ", empty() = " + empty() + - ", queue = " + Arrays.asList(data); - } - // JUnit testing. - // As an inner class, this has access to privates: - public static class WhiteBoxTest { - private Queue queue = new Queue(10); - private int i = 0; - public WhiteBoxTest() { - while(i < 5) // Preload with some data - queue.put("" + i++); - } - // Support methods: - private void showFullness() { - assertTrue(queue.full()); - assertFalse(queue.empty()); - // Dump is private, white-box testing allows access: - 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("" + i++); - String msg = ""; - try { - queue.put(""); - } catch(QueueException e) { - msg = e.getMessage(); - System.out.println(msg); - } - assertEquals(msg, "put() into full Queue"); - showFullness(); - } - @Test - public void empty() { - System.out.println("testEmpty"); - while(!queue.empty()) - System.out.println(queue.get()); - String msg = ""; - try { - queue.get(); - } catch(QueueException e) { - msg = e.getMessage(); - System.out.println(msg); - } - assertEquals(msg, "get() from empty Queue"); - showEmptiness(); - } - @Test - public void nullPut() { - System.out.println("testNullPut"); - String msg = ""; - try { - queue.put(null); - } catch(QueueException 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("" + i++); - showFullness(); - // White-box testing accesses private field: - assertTrue(queue.wrapped); - while(!queue.empty()) - System.out.println(queue.get()); - showEmptiness(); - while(!queue.full()) - queue.put("" + i++); - showFullness(); - while(!queue.empty()) - System.out.println(queue.get()); - showEmptiness(); - } - } - public static void main(String[] args) { - org.junit.runner.JUnitCore.runClasses( - Queue.WhiteBoxTest.class); - } -} -/* Output: -testNullPut -put() null item -testCircularity -in = 0, out = 0, full() = true, empty() = false, queue = -[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, queue = -[null, null, null, null, null, null, null, null, null, -null] -in = 0, out = 0, full() = true, empty() = false, queue = -[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, queue = -[null, null, null, null, null, null, null, null, null, -null] -testFull -in = 5, out = 0, full() = false, empty() = false, queue = -[0, 1, 2, 3, 4, null, null, null, null, null] -0 -1 -put() into full Queue -in = 2, out = 2, full() = true, empty() = false, queue = -[10, 11, 2, 3, 4, 5, 6, 7, 8, 9] -testEmpty -0 -1 -2 -3 -4 -get() from empty Queue -in = 5, out = 5, full() = false, empty() = true, queue = -[null, null, null, null, null, null, null, null, null, -null] -*/ diff --git a/assertions/build.xml b/assertions/build.xml deleted file mode 100644 index e15e1e215..000000000 --- a/assertions/build.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/build.gradle b/build.gradle index 3c70412b1..b4feb13d5 100644 --- a/build.gradle +++ b/build.gradle @@ -1,61 +1,23 @@ -repositories { - mavenLocal() - mavenCentral() - maven { - url 'http://maven-eclipse.github.io/maven' - } -} - -// these java plugin settings don't really need to be specified since ant does the actual build, but it makes things nicer in an IDE that understands gradle projects -apply plugin: 'java' - -sourceCompatibility = '1.8' -targetCompatibility = '1.8' - -sourceSets { - main { - java { - srcDirs 'annotations', 'arrays', 'assertions', 'com', 'compression', 'concurrency', 'containers', 'containersindepth', 'control', 'debugging', 'enums', 'exceptions', 'files', 'functional', 'generics', 'hiding', 'housekeeping', 'innerclasses', 'interfaces', 'iostreams', 'logging', 'network', 'newio', 'objects', 'onjava', 'operators', 'patterns', 'polymorphism', 'preferences', 'references', 'remote', 'reuse', 'serialization', 'standardio', 'staticchecking', 'streams', 'strings', 'swt', 'typeinfo', 'ui', 'unittesting' +buildscript { + repositories { + maven { + url 'https://plugins.gradle.org/m2/' } } -} - -// fix for a xom / xalan transitive dependency issue: http://stackoverflow.com/a/23870656/77409 -configurations.all { - resolutionStrategy { - force 'xml-apis:xml-apis:1.0.b2' + dependencies { + classpath 'me.champeau.gradle:jmh-gradle-plugin:0.5.2' } } +apply plugin: 'com.mindviewinc.example-output-verification' -dependencies { - compile 'org.eclipse.swt:org.eclipse.swt.win32.win32.x86:4.4.2' - compile 'org.eclipse.swt:org.eclipse.swt.win32.win32.x86_64:4.4.2' - compile 'org.eclipse.swt:org.eclipse.swt.gtk.linux.x86:4.4.2' - compile 'org.eclipse.swt:org.eclipse.swt.gtk.linux.x86_64:4.4.2' - compile 'org.eclipse.swt:org.eclipse.swt.cocoa.macosx.x86_64:4.4.2' - compile 'junit:junit:4.12' - compile 'com.io7m.xom:xom:1.2.10' -} - -// this sets the classpath that ant uses to include the dependency jars -ant.properties['java.class.path'] = sourceSets.main.compileClasspath.getAsPath() - -// import the ant build and override a few task names -ant.importBuild('build.xml') { antTaskName -> - if (antTaskName == 'build') 'ant-build' // rename ant's build task to ant-build so it doesn't override the gradle task with that name - else if (antTaskName == 'clean') 'ant-clean' // rename ant's clean task to ant-clean so it doesn't override the gradle task with that name - else antTaskName -} - -// this task is already defined by gradle so we need to tell it to call the ant clean task -clean << { - tasks['ant-clean'].execute() -} - -// this task is already defined by gradle so we need to tell it to call the ant build task -build << { - tasks['ant-build'].execute() +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' } -defaultTasks 'run' \ No newline at end of file +apply from: 'gradle/subprojects.gradle' diff --git a/build.xml b/build.xml deleted file mode 100644 index 1cc30c7c4..000000000 --- a/build.xml +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - - Main build.xml for the source code for - Bruce Eckel On Java - Code available at https://github.com/BruceEckel/OnJava-Examples - See installation instructions in README.md - See copyright notice in CopyRight.txt - - Ant available from http://ant.apache.org - - To see options, type: ant -p - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/buildSrc/src/main/groovy/com/mindviewinc/plugins/ExampleOutputVerificationPlugin.groovy b/buildSrc/src/main/groovy/com/mindviewinc/plugins/ExampleOutputVerificationPlugin.groovy new file mode 100644 index 000000000..0a0a213c7 --- /dev/null +++ b/buildSrc/src/main/groovy/com/mindviewinc/plugins/ExampleOutputVerificationPlugin.groovy @@ -0,0 +1,18 @@ +package com.mindviewinc.plugins + +import org.gradle.api.Project +import org.gradle.api.Plugin +import org.gradle.api.tasks.Exec + +class ExampleOutputVerificationPlugin implements Plugin { + void apply(Project project) { + project.tasks.create('verify', Exec) { + description 'Uses Python tool to verify example output' + commandLine 'python', '_verify_output.py' + doFirst { + println("execute 'gradlew run' first") + } + } + + } +} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/com/mindviewinc/plugins/TaggingPlugin.groovy b/buildSrc/src/main/groovy/com/mindviewinc/plugins/TaggingPlugin.groovy new file mode 100644 index 000000000..518a7d5f2 --- /dev/null +++ b/buildSrc/src/main/groovy/com/mindviewinc/plugins/TaggingPlugin.groovy @@ -0,0 +1,94 @@ +package com.mindviewinc.plugins + +import org.gradle.api.Project +import org.gradle.api.Plugin +import org.gradle.api.tasks.JavaExec +import org.gradle.internal.jvm.Jvm + +import org.apache.tools.ant.util.TeeOutputStream + +class TaggingPlugin implements Plugin { + private final static String DEBUG_PROJECT_PROPERTY_KEY = 'debug' + + void apply(Project project) { + boolean debug = project.hasProperty(DEBUG_PROJECT_PROPERTY_KEY) ? Boolean.valueOf(project.getProperty(DEBUG_PROJECT_PROPERTY_KEY)) : false + List createdTasks = [] + boolean runningInCI = System.getenv('CI') + boolean runningInTravis = System.getenv('TRAVIS') + boolean runningInAppveyor = System.getenv('APPVEYOR') + // println "runningInCI: " + runningInCI + + project.projectDir.eachFileRecurse { file -> + if (file.name.endsWith('.java')) { + + Tags tags = new Tags(file) + if(debug && tags.hasTags()) println tags + + // Exclude java sources that will not compile + if (tags.willNotCompile + || tags.newFeature // Uses a feature introduced after Java 8 + || (tags.lowLevelAppendix && runningInAppveyor) // Exclude entire lowlevel appendix + || (tags.excludeFromAppveyorCI && runningInAppveyor) + || (tags.excludeFromTravisCI && runningInTravis) + || (tags.excludeFromCI && runningInCI) + ) { + project.sourceSets.main.java.excludes.add(file.name) + } else { + JavaExec javaTask = null + // Add tasks for java sources with main methods + if (tags.hasMainMethod || tags.javaCmd) { + javaTask = project.tasks.create(name: tags.fileRoot, type: JavaExec, dependsOn: tags.runFirst) { + main = tags.mainClass + classpath = project.sourceSets.main.runtimeClasspath + args = tags.args + jvmArgs = tags.jVMArgs + } + } else if (tags.javap) { + // Create task for running javap + javaTask = project.tasks.create(name: "${tags.fileRoot}", type: JavaExec, dependsOn: tags.runFirst) { + main = "com.sun.tools.javap.Main" + classpath = project.sourceSets.main.runtimeClasspath + project.files(Jvm.current().toolsJar) + // Assuming javap represents all the args and there's no need to jVMArgs + args tags.javap.split() + } + } + + if (javaTask) { + def baseName = file.name.substring(0, file.name.lastIndexOf('.')) + File outFile = new File(file.parentFile, baseName + '.out') + File errFile = new File(file.parentFile, baseName + '.err') + + javaTask.configure { + ignoreExitValue = tags.excludeFromGradle || tags.throwsException + doFirst { + if(outFile.exists()) + outFile.delete() + if(tags.outputLine) + outFile << tags.outputLine + "\n" + + standardOutput = new TeeOutputStream(new FileOutputStream(outFile, true), System.out) + errorOutput = new TeeOutputStream(new FileOutputStream(errFile), System.err) + } + doLast { + if(outFile.size() == 0) + outFile.delete() + else if(!outFile.text.contains("/* Output:")) + outFile.delete() + if(errFile.size() == 0) errFile.delete() + } + } + + if (!tags.excludeFromGradle) { + // Only add tasks that we know we can run successfully to the task list + createdTasks.add(javaTask) + } + } + } + } + } + + project.tasks.create('run') { + dependsOn createdTasks + } + } +} diff --git a/buildSrc/src/main/groovy/com/mindviewinc/plugins/Tags.groovy b/buildSrc/src/main/groovy/com/mindviewinc/plugins/Tags.groovy new file mode 100644 index 000000000..f61ed4d79 --- /dev/null +++ b/buildSrc/src/main/groovy/com/mindviewinc/plugins/Tags.groovy @@ -0,0 +1,126 @@ +package com.mindviewinc.plugins + +class Tags { + Boolean hasMainMethod = false + Boolean willNotCompile = false + Boolean excludeFromTravisCI = false + Boolean excludeFromAppveyorCI = false + Boolean excludeFromCI = false + Boolean lowLevelAppendix = false + Boolean throwsException = false + Boolean errorOutputExpected = false + Boolean excludeFromGradle = false + Boolean newFeature = false // For language feature introduced after Java 8 + Boolean ignoreOutput = false // This tag isn't used in the build... + String fileRoot + String mainClass + String javaCmd = null + List args = [] + List jVMArgs = [] + String javap = null + String runFirst = null + String outputLine = null + private String block + def Tags(File file) { + block = file.text + hasMainMethod = block.contains('main(String[] args)') + def firstLine = block.substring(0, block.indexOf("\n")) + fileRoot = (firstLine.split("/")[-1] - ".java").trim() // Remove \r if it exists + mainClass = fileRoot + javaCmd = extract('java') + if(javaCmd) { + def pieces = javaCmd.split() + mainClass = pieces[0] + if(pieces.size() > 1) + for(p in pieces[1..-1]) + if(p.startsWith("-")) + jVMArgs << p + else + args << p + } + willNotCompile = hasTag('WillNotCompile') + excludeFromTravisCI = hasTag('ExcludeFromTravisCI') + excludeFromAppveyorCI = hasTag('ExcludeFromAppveyorCI') + excludeFromCI = hasTag('ExcludeFromCI') + lowLevelAppendix = firstLine.contains("// lowlevel/") + throwsException = hasTag('ThrowsException') + errorOutputExpected = hasTag('ErrorOutputExpected') + excludeFromGradle = hasTag('ExcludeFromGradle') + newFeature = hasTag('NewFeature') + ignoreOutput = hasTag('IgnoreOutput') + javap = extract('javap') // Includes only arguments to command + runFirst = extract('RunFirst:') + outputLine = extractOutputLine() + } + private def hasTag(String marker) { + return block.contains("// {" + marker + "}") + } + def extractOutputLine() { + def matcher = (block =~ /(?m)^(\/\* Output:.*)$/) + if (matcher) { + return matcher[0][1] + } else { + return null + } + } + private def extract(String marker) { + // Assume some whitespace is after marker + if(!block.contains("// {${marker} ")) + return null + def matcher = (block =~ /\/\/ \{${marker}\s+([^}]+)/) + if (matcher) { + def matched = matcher[0][1].trim() + return matched.replaceAll("\n?//", "") + } else { + println "Searching for: " + matcher + println block + System.exit(1) + } + } + public boolean hasTags() { + return willNotCompile || + excludeFromTravisCI || + excludeFromAppveyorCI || + excludeFromCI || + throwsException || + errorOutputExpected || + excludeFromGradle || + newFeature || + ignoreOutput || + javaCmd || + args || + jVMArgs || + javap || + runFirst + } + public String toString() { + String result = "" + block.eachLine{ ln -> + if(ln.startsWith("//") || ln.startsWith("package ")) + result += ln + "\n" + } + """ + hasMainMethod + willNotCompile + excludeFromTravisCI + excludeFromAppveyorCI + excludeFromCI + throwsException + errorOutputExpected + excludeFromGradle + newFeature + ignoreOutput + fileRoot + mainClass + javaCmd + args + jVMArgs + javap + runFirst + """.split().each { str -> + if(this[str]) + result += str + ": " + this[str] + "\n" + } + result + } +} diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/com.mindviewinc.example-output-verification.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/com.mindviewinc.example-output-verification.properties new file mode 100644 index 000000000..7a8a7f57b --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/com.mindviewinc.example-output-verification.properties @@ -0,0 +1 @@ +implementation-class=com.mindviewinc.plugins.ExampleOutputVerificationPlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/com.mindviewinc.tagging.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/com.mindviewinc.tagging.properties new file mode 100644 index 000000000..8359e8285 --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/com.mindviewinc.tagging.properties @@ -0,0 +1 @@ +implementation-class=com.mindviewinc.plugins.TaggingPlugin \ No newline at end of file diff --git a/checkstyle.xml b/checkstyle.xml new file mode 100644 index 000000000..aabea2c45 --- /dev/null +++ b/checkstyle.xml @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/chkstyle.bat b/chkstyle.bat new file mode 100644 index 000000000..24838fc01 --- /dev/null +++ b/chkstyle.bat @@ -0,0 +1,2 @@ +@echo run gradlew clean first! +gradlew checkstyleMain 1> checkstyleout.txt 2>&1 diff --git a/collections/AdapterMethodIdiom.java b/collections/AdapterMethodIdiom.java index 5d7d4a272..ffb8fbf5b 100644 --- a/collections/AdapterMethodIdiom.java +++ b/collections/AdapterMethodIdiom.java @@ -1,13 +1,13 @@ // collections/AdapterMethodIdiom.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 { - public ReversibleArrayList(Collection c) { + ReversibleArrayList(Collection c) { super(c); } public Iterable reversed() { @@ -15,10 +15,12 @@ public Iterable reversed() { public Iterator iterator() { return new Iterator() { int current = size() - 1; - public boolean hasNext() { + @Override public boolean hasNext() { return current > -1; } + @Override public T next() { return get(current--); } + @Override public void remove() { // Not implemented throw new UnsupportedOperationException(); } @@ -31,7 +33,7 @@ public void remove() { // Not implemented public class AdapterMethodIdiom { public static void main(String[] args) { ReversibleArrayList ral = - new ReversibleArrayList( + new ReversibleArrayList<>( Arrays.asList("To be or not to be".split(" "))); // Grabs the ordinary iterator via iterator(): for(String s : ral) diff --git a/collections/AddingGroups.java b/collections/AddingGroups.java index 9551639ff..13fcdcaf1 100644 --- a/collections/AddingGroups.java +++ b/collections/AddingGroups.java @@ -1,7 +1,7 @@ // collections/AddingGroups.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Adding groups of elements to Collection objects import java.util.*; diff --git a/collections/ApplesAndOrangesWithGenerics.java b/collections/ApplesAndOrangesWithGenerics.java index ee5db4f04..674ee7b47 100644 --- a/collections/ApplesAndOrangesWithGenerics.java +++ b/collections/ApplesAndOrangesWithGenerics.java @@ -1,7 +1,7 @@ // collections/ApplesAndOrangesWithGenerics.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class ApplesAndOrangesWithGenerics { diff --git a/collections/ApplesAndOrangesWithoutGenerics.java b/collections/ApplesAndOrangesWithoutGenerics.java index 649dfbc4d..4cbe23073 100644 --- a/collections/ApplesAndOrangesWithoutGenerics.java +++ b/collections/ApplesAndOrangesWithoutGenerics.java @@ -1,7 +1,7 @@ // collections/ApplesAndOrangesWithoutGenerics.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Simple collection use (suppressing compiler warnings) // {ThrowsException} import java.util.*; @@ -24,15 +24,15 @@ public static void main(String[] args) { apples.add(new Orange()); for(Object apple : apples) { ((Apple) apple).id(); - // Orange is detected only at run time + // Orange is detected only at runtime } } } /* Output: ___[ Error Output ]___ -Exception in thread "main" java.lang.ClassCastException: -Orange cannot be cast to Apple - at ApplesAndOrangesWithoutGenerics.main(Unknown -Source) -___[ Exception is Expected ]___ +Exception in thread "main" +java.lang.ClassCastException: Orange cannot be cast to +Apple + at ApplesAndOrangesWithoutGenerics.main(ApplesA +ndOrangesWithoutGenerics.java:23) */ diff --git a/collections/ArrayIsNotIterable.java b/collections/ArrayIsNotIterable.java index 87177d448..a9660a67c 100644 --- a/collections/ArrayIsNotIterable.java +++ b/collections/ArrayIsNotIterable.java @@ -1,7 +1,7 @@ // collections/ArrayIsNotIterable.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class ArrayIsNotIterable { diff --git a/collections/AsListInference.java b/collections/AsListInference.java index 1d47b3c50..b25ac8e61 100644 --- a/collections/AsListInference.java +++ b/collections/AsListInference.java @@ -1,7 +1,7 @@ // collections/AsListInference.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; class Snow {} @@ -16,19 +16,23 @@ public static void main(String[] args) { List snow1 = Arrays.asList( new Crusty(), new Slush(), new Powder()); //- snow1.add(new Heavy()); // Exception + //- snow1.remove(0); // Exception List snow2 = Arrays.asList( new Light(), new Heavy()); //- snow2.add(new Slush()); // Exception + //- snow2.remove(0); // Exception List snow3 = new ArrayList<>(); Collections.addAll(snow3, new Light(), new Heavy(), new Powder()); snow3.add(new Crusty()); + snow3.remove(0); // Hint with explicit type argument specification: List snow4 = Arrays.asList( new Light(), new Heavy(), new Slush()); //- snow4.add(new Powder()); // Exception + //- snow4.remove(0); // Exception } } diff --git a/collections/BasicRecord.java b/collections/BasicRecord.java new file mode 100644 index 000000000..0fa0f2510 --- /dev/null +++ b/collections/BasicRecord.java @@ -0,0 +1,29 @@ +// collections/BasicRecord.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 +import java.util.*; + +record Employee(String name, int id) {} + +public class BasicRecord { + public static void main(String[] args) { + var bob = new Employee("Bob Dobbs", 11); + var dot = new Employee("Dorothy Gale", 9); + // bob.id = 12; // Error: + // id has private access in Employee + System.out.println(bob.name()); // Accessor + System.out.println(bob.id()); // Accessor + System.out.println(bob); // toString() + // Employee works as the key in a Map: + var map = Map.of(bob, "A", dot, "B"); + System.out.println(map); + } +} +/* Output: +Bob Dobbs +11 +Employee[name=Bob Dobbs, id=11] +{Employee[name=Dorothy Gale, id=9]=B, Employee[name=Bob Dobbs, id=11]=A} +*/ diff --git a/collections/CollectionDifferences.java b/collections/CollectionDifferences.java new file mode 100644 index 000000000..a8ea09d01 --- /dev/null +++ b/collections/CollectionDifferences.java @@ -0,0 +1,71 @@ +// collections/CollectionDifferences.java +// (c)2021 MindView LLC: 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/collections/CollectionMethods.java b/collections/CollectionMethods.java deleted file mode 100644 index 7339f93af..000000000 --- a/collections/CollectionMethods.java +++ /dev/null @@ -1,67 +0,0 @@ -// collections/CollectionMethods.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import onjava.*; - -public class CollectionMethods { - 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/collections/CollectionSequence.java b/collections/CollectionSequence.java index a444be712..ea0e45740 100644 --- a/collections/CollectionSequence.java +++ b/collections/CollectionSequence.java @@ -1,21 +1,19 @@ // collections/CollectionSequence.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import typeinfo.pets.*; +// Visit http://OnJava8.com for more book information. +import reflection.pets.*; import java.util.*; public class CollectionSequence extends AbstractCollection { - private Pet[] pets = Pets.array(8); + private Pet[] pets = new PetCreator().array(8); @Override public int size() { return pets.length; } - @Override - public Iterator iterator() { - return new Iterator() { // (1) + @Override public Iterator iterator() { + return new Iterator() { // [1] private int index = 0; - @Override - public boolean hasNext() { + @Override public boolean hasNext() { return index < pets.length; } @Override @@ -33,6 +31,8 @@ public static void main(String[] args) { } } /* 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 */ diff --git a/collections/CompactConstructor.java b/collections/CompactConstructor.java new file mode 100644 index 000000000..017dcbf9b --- /dev/null +++ b/collections/CompactConstructor.java @@ -0,0 +1,16 @@ +// collections/CompactConstructor.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 + +record Point(int x, int y) { + void assertPositive(int val) { + if(val < 0) + throw new IllegalArgumentException("negative"); + } + Point { // Compact: No parameter list + assertPositive(x); + assertPositive(y); + } +} diff --git a/collections/ComposedRecord.java b/collections/ComposedRecord.java new file mode 100644 index 000000000..1e234b257 --- /dev/null +++ b/collections/ComposedRecord.java @@ -0,0 +1,10 @@ +// collections/ComposedRecord.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 + +record Company(Employee[] e) {} + +// class Conglomerate extends Company {} +// error: cannot inherit from final Company diff --git a/collections/CopyRecord.java b/collections/CopyRecord.java new file mode 100644 index 000000000..7e2d9dd1b --- /dev/null +++ b/collections/CopyRecord.java @@ -0,0 +1,18 @@ +// collections/CopyRecord.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 + +record R(int a, double b, char c) {} + +public class CopyRecord { + public static void main(String[] args) { + var r1 = new R(11, 2.2, 'z'); + var r2 = new R(r1.a(), r1.b(), r1.c()); + System.out.println(r1.equals(r2)); + } +} +/* Output: +true +*/ diff --git a/collections/CrossCollectionIteration.java b/collections/CrossCollectionIteration.java index 470da4a27..2aaf7e95a 100644 --- a/collections/CrossCollectionIteration.java +++ b/collections/CrossCollectionIteration.java @@ -1,8 +1,8 @@ // collections/CrossCollectionIteration.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import typeinfo.pets.*; +// Visit http://OnJava8.com for more book information. +import reflection.pets.*; import java.util.*; public class CrossCollectionIteration { @@ -14,7 +14,7 @@ public static void display(Iterator it) { System.out.println(); } public static void main(String[] args) { - List pets = Pets.list(8); + List pets = new PetCreator().list(8); LinkedList petsLL = new LinkedList<>(pets); HashSet petsHS = new HashSet<>(pets); TreeSet petsTS = new TreeSet<>(pets); @@ -25,8 +25,12 @@ public static void main(String[] args) { } } /* 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 +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/collections/CrossCollectionIteration2.java b/collections/CrossCollectionIteration2.java index 8eb85f072..e8aa755d0 100644 --- a/collections/CrossCollectionIteration2.java +++ b/collections/CrossCollectionIteration2.java @@ -1,8 +1,8 @@ // collections/CrossCollectionIteration2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import typeinfo.pets.*; +// Visit http://OnJava8.com for more book information. +import reflection.pets.*; import java.util.*; public class CrossCollectionIteration2 { @@ -15,7 +15,7 @@ public static void display(Iterable ip) { System.out.println(); } public static void main(String[] args) { - List pets = Pets.list(8); + List pets = new PetCreator().list(8); LinkedList petsLL = new LinkedList<>(pets); HashSet petsHS = new HashSet<>(pets); TreeSet petsTS = new TreeSet<>(pets); @@ -26,8 +26,12 @@ public static void main(String[] args) { } } /* 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 +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/collections/EnvironmentVariables.java b/collections/EnvironmentVariables.java index 3b083bdaa..6098e4cfc 100644 --- a/collections/EnvironmentVariables.java +++ b/collections/EnvironmentVariables.java @@ -1,7 +1,8 @@ // collections/EnvironmentVariables.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {VisuallyInspectOutput} import java.util.*; public class EnvironmentVariables { @@ -12,4 +13,3 @@ public static void main(String[] args) { } } } -/* Output: (Execute to see) */ diff --git a/collections/FinalFields.java b/collections/FinalFields.java new file mode 100644 index 000000000..1cf0f4f4e --- /dev/null +++ b/collections/FinalFields.java @@ -0,0 +1,12 @@ +// collections/FinalFields.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 +import java.util.*; + +record FinalFields(int i) { + int timesTen() { return i * 10; } + // void tryToChange() { i++; } // Error: + // cannot assign a value to final variable i +} diff --git a/collections/ForInCollections.java b/collections/ForInCollections.java index b37f17666..15ea9bb3a 100644 --- a/collections/ForInCollections.java +++ b/collections/ForInCollections.java @@ -1,7 +1,7 @@ // collections/ForInCollections.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // All collections work with for-in import java.util.*; diff --git a/collections/GenericTypeInference.java b/collections/GenericTypeInference.java new file mode 100644 index 000000000..83264de2c --- /dev/null +++ b/collections/GenericTypeInference.java @@ -0,0 +1,20 @@ +// collections/GenericTypeInference.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 11 +import java.util.*; + +public class GenericTypeInference { + void old() { + ArrayList apples = new ArrayList<>(); + } + void modern() { + var apples = new ArrayList(); + } + void pitFall() { + var apples = new ArrayList<>(); + apples.add(new Apple()); + apples.get(0); // Comes back as plain Object + } +} diff --git a/collections/GenericsAndUpcasting.java b/collections/GenericsAndUpcasting.java index 37853d37d..3462e0b76 100644 --- a/collections/GenericsAndUpcasting.java +++ b/collections/GenericsAndUpcasting.java @@ -1,7 +1,7 @@ // collections/GenericsAndUpcasting.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; class GrannySmith extends Apple {} diff --git a/collections/ImplementingRecord.java b/collections/ImplementingRecord.java new file mode 100644 index 000000000..4a453f775 --- /dev/null +++ b/collections/ImplementingRecord.java @@ -0,0 +1,14 @@ +// collections/ImplementingRecord.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 + +interface Star { + double brightness(); + double density(); +} + +record RedDwarf(double brightness) implements Star { + @Override public double density() { return 100.0; } +} diff --git a/collections/InterfaceVsIterator.java b/collections/InterfaceVsIterator.java index eda990c20..fdb50a588 100644 --- a/collections/InterfaceVsIterator.java +++ b/collections/InterfaceVsIterator.java @@ -1,8 +1,8 @@ // collections/InterfaceVsIterator.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import typeinfo.pets.*; +// Visit http://OnJava8.com for more book information. +import reflection.pets.*; import java.util.*; public class InterfaceVsIterator { @@ -19,7 +19,7 @@ public static void display(Collection pets) { System.out.println(); } public static void main(String[] args) { - List petList = Pets.list(8); + List petList = new PetCreator().list(8); Set petSet = new HashSet<>(petList); Map petMap = new LinkedHashMap<>(); String[] names = ("Ralph, Eric, Robin, Lacey, " + @@ -37,13 +37,19 @@ public static void main(String[] args) { } } /* 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 +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 +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/collections/IterableClass.java b/collections/IterableClass.java index 8f1d43faf..1e64d783a 100644 --- a/collections/IterableClass.java +++ b/collections/IterableClass.java @@ -1,19 +1,18 @@ // collections/IterableClass.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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() { + "we know the Earth to be banana-shaped." + ).split(" "); + @Override public Iterator iterator() { return new Iterator() { private int index = 0; - @Override - public boolean hasNext() { + @Override public boolean hasNext() { return index < words.length; } @Override diff --git a/collections/LinkedListFeatures.java b/collections/LinkedListFeatures.java index 3e794e817..489c699f2 100644 --- a/collections/LinkedListFeatures.java +++ b/collections/LinkedListFeatures.java @@ -1,14 +1,14 @@ // collections/LinkedListFeatures.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import typeinfo.pets.*; +// Visit http://OnJava8.com for more book information. +import reflection.pets.*; import java.util.*; public class LinkedListFeatures { public static void main(String[] args) { LinkedList pets = - new LinkedList<>(Pets.list(5)); + new LinkedList<>(new PetCreator().list(5)); System.out.println(pets); // Identical: System.out.println( @@ -27,9 +27,9 @@ public static void main(String[] args) { System.out.println(pets); pets.addFirst(new Rat()); System.out.println("After addFirst(): " + pets); - pets.offer(Pets.get()); + pets.offer(new PetCreator().get()); System.out.println("After offer(): " + pets); - pets.add(Pets.get()); + pets.add(new PetCreator().get()); System.out.println("After add(): " + pets); pets.addLast(new Hamster()); System.out.println("After addLast(): " + pets); @@ -47,8 +47,8 @@ public static void main(String[] args) { 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] +After offer(): [Rat, Mutt, Pug, Rat] +After add(): [Rat, Mutt, Pug, Rat, Rat] +After addLast(): [Rat, Mutt, Pug, Rat, Rat, Hamster] pets.removeLast(): Hamster */ diff --git a/collections/ListFeatures.java b/collections/ListFeatures.java index 68c32664c..12fb6b4f1 100644 --- a/collections/ListFeatures.java +++ b/collections/ListFeatures.java @@ -1,14 +1,14 @@ // collections/ListFeatures.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import typeinfo.pets.*; +// Visit http://OnJava8.com for more book information. +import reflection.pets.*; import java.util.*; public class ListFeatures { public static void main(String[] args) { Random rand = new Random(47); - List pets = Pets.list(7); + List pets = new PetCreator().list(7); System.out.println("1: " + pets); Hamster h = new Hamster(); pets.add(h); // Automatically resizes @@ -54,7 +54,7 @@ public static void main(String[] args) { pets.clear(); // Remove all elements System.out.println("19: " + pets); System.out.println("20: " + pets.isEmpty()); - pets.addAll(Pets.list(4)); + pets.addAll(new PetCreator().list(4)); System.out.println("21: " + pets); Object[] o = pets.toArray(); System.out.println("22: " + o[3]); @@ -87,7 +87,7 @@ public static void main(String[] args) { 18: false 19: [] 20: true -21: [Manx, Cymric, Rat, EgyptianMau] -22: EgyptianMau +21: [Rat, Manx, Cymric, Mutt] +22: Mutt 23: 14 */ diff --git a/collections/ListIteration.java b/collections/ListIteration.java index 0754768f8..4967f5260 100644 --- a/collections/ListIteration.java +++ b/collections/ListIteration.java @@ -1,16 +1,17 @@ // collections/ListIteration.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import typeinfo.pets.*; +// Visit http://OnJava8.com for more book information. +import reflection.pets.*; import java.util.*; public class ListIteration { public static void main(String[] args) { - List pets = Pets.list(8); + List pets = new PetCreator().list(8); ListIterator it = pets.listIterator(); while(it.hasNext()) - System.out.print(it.next() + ", " + it.nextIndex() + + System.out.print(it.next() + + ", " + it.nextIndex() + ", " + it.previousIndex() + "; "); System.out.println(); // Backwards: @@ -21,16 +22,15 @@ public static void main(String[] args) { it = pets.listIterator(3); while(it.hasNext()) { it.next(); - it.set(Pets.get()); + it.set(new PetCreator().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; +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] +[Rat, Manx, Cymric, Rat, Rat, Rat, Rat, Rat] */ diff --git a/collections/MapOfList.java b/collections/MapOfList.java index c4ea6f0eb..d7357a6ed 100644 --- a/collections/MapOfList.java +++ b/collections/MapOfList.java @@ -1,13 +1,14 @@ // collections/MapOfList.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {java collections.MapOfList} package collections; -import typeinfo.pets.*; +import reflection.pets.*; import java.util.*; public class MapOfList { - public static Map> + public static final Map> petPeople = new HashMap<>(); static { petPeople.put(new Person("Dawn"), @@ -20,10 +21,11 @@ public class MapOfList { petPeople.put(new Person("Marilyn"), Arrays.asList( new Pug("Louie aka Louis Snorkelstein Dupree"), - new Cat("Stanford aka Stinky el Negro"), + new Cat("Stanford"), new Cat("Pinkola"))); petPeople.put(new Person("Luke"), - Arrays.asList(new Rat("Fuzzy"), new Rat("Fizzy"))); + Arrays.asList( + new Rat("Fuzzy"), new Rat("Fizzy"))); petPeople.put(new Person("Isaac"), Arrays.asList(new Rat("Freckly"))); } @@ -38,26 +40,26 @@ public static void main(String[] args) { } } /* Output: -People: [Person Marilyn, Person Dawn, Person Luke, Person -Isaac, Person Kate] -Pets: [[Pug Louie aka Louis Snorkelstein Dupree, Cat -Stanford aka Stinky el Negro, Cat Pinkola], [Cymric Molly, -Mutt Spot], [Rat Fuzzy, Rat Fizzy], [Rat Freckly], [Cat -Shackleton, Cat Elsie May, Dog Margrett]] -Person Marilyn has: - Pug Louie aka Louis Snorkelstein Dupree - Cat Stanford aka Stinky el Negro - Cat Pinkola +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 Luke has: - Rat Fuzzy - Rat Fizzy -Person Isaac has: - Rat Freckly 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/collections/ModifyingArraysAsList.java b/collections/ModifyingArraysAsList.java index 9c3fd86e7..ef50e40ab 100644 --- a/collections/ModifyingArraysAsList.java +++ b/collections/ModifyingArraysAsList.java @@ -1,7 +1,7 @@ // collections/ModifyingArraysAsList.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class ModifyingArraysAsList { diff --git a/collections/MultiIterableClass.java b/collections/MultiIterableClass.java index 00f4245fb..3c5e7ae26 100644 --- a/collections/MultiIterableClass.java +++ b/collections/MultiIterableClass.java @@ -1,7 +1,7 @@ // collections/MultiIterableClass.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Adding several Adapter Methods import java.util.*; @@ -11,12 +11,13 @@ public Iterable reversed() { public Iterator iterator() { return new Iterator() { int current = words.length - 1; - public boolean hasNext() { + @Override public boolean hasNext() { return current > -1; } - public String next() { + @Override public String next() { return words[current--]; } + @Override public void remove() { // Not implemented throw new UnsupportedOperationException(); } @@ -28,7 +29,7 @@ public Iterable randomized() { return new Iterable() { public Iterator iterator() { List shuffled = - new ArrayList(Arrays.asList(words)); + new ArrayList<>(Arrays.asList(words)); Collections.shuffle(shuffled, new Random(47)); return shuffled.iterator(); } diff --git a/collections/NestedLocalRecords.java b/collections/NestedLocalRecords.java new file mode 100644 index 000000000..5ae375668 --- /dev/null +++ b/collections/NestedLocalRecords.java @@ -0,0 +1,12 @@ +// collections/NestedLocalRecords.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 + +public class NestedLocalRecords { + record Nested(String s) {} + void method() { + record Local(String s) {} + } +} diff --git a/collections/NonCollectionSequence.java b/collections/NonCollectionSequence.java index 5ca490cfc..dc8678274 100644 --- a/collections/NonCollectionSequence.java +++ b/collections/NonCollectionSequence.java @@ -1,20 +1,19 @@ // collections/NonCollectionSequence.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import typeinfo.pets.*; +// Visit http://OnJava8.com for more book information. +import reflection.pets.*; import java.util.*; class PetSequence { - protected Pet[] pets = Pets.array(8); + protected Pet[] pets = new PetCreator().array(8); } public class NonCollectionSequence extends PetSequence { public Iterator iterator() { return new Iterator() { private int index = 0; - @Override - public boolean hasNext() { + @Override public boolean hasNext() { return index < pets.length; } @Override @@ -32,5 +31,6 @@ public static void main(String[] args) { } } /* 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/collections/NormalConstructor.java b/collections/NormalConstructor.java new file mode 100644 index 000000000..da926b643 --- /dev/null +++ b/collections/NormalConstructor.java @@ -0,0 +1,11 @@ +// collections/NormalConstructor.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 + +record Value(int x) { + Value(int x) { // With the parameter list + this.x = x; // Must explicitly initialize + } +} diff --git a/collections/PetMap.java b/collections/PetMap.java index e229ff8ba..dc64bf574 100644 --- a/collections/PetMap.java +++ b/collections/PetMap.java @@ -1,8 +1,8 @@ // collections/PetMap.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import typeinfo.pets.*; +// Visit http://OnJava8.com for more book information. +import reflection.pets.*; import java.util.*; public class PetMap { @@ -19,8 +19,8 @@ public static void main(String[] args) { } } /* Output: -{My Dog=Dog Ginger, My Cat=Cat Molly, My Hamster=Hamster -Bosco} +{My Dog=Dog Ginger, My Cat=Cat Molly, My +Hamster=Hamster Bosco} Dog Ginger true true diff --git a/collections/PlusTen.java b/collections/PlusTen.java new file mode 100644 index 000000000..a52bfed5b --- /dev/null +++ b/collections/PlusTen.java @@ -0,0 +1,20 @@ +// collections/PlusTen.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 + +record PlusTen(int x) { + PlusTen { + x += 10; + } + // Adjustment to field can only happen in + // the constructor. Still not legal: + // void mutate() { x += 10; } + public static void main(String[] args) { + System.out.println(new PlusTen(10)); + } +} +/* Output: +PlusTen[x=20] +*/ diff --git a/collections/PrintingCollections.java b/collections/PrintingCollections.java index c5d75af45..c324722a9 100644 --- a/collections/PrintingCollections.java +++ b/collections/PrintingCollections.java @@ -1,12 +1,13 @@ // collections/PrintingCollections.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Collections print themselves automatically import java.util.*; public class PrintingCollections { - static Collection fill(Collection collection) { + static Collection + fill(Collection collection) { collection.add("rat"); collection.add("cat"); collection.add("dog"); diff --git a/collections/PriorityQueueDemo.java b/collections/PriorityQueueDemo.java index 3527e97a2..0e0f553ef 100644 --- a/collections/PriorityQueueDemo.java +++ b/collections/PriorityQueueDemo.java @@ -1,7 +1,7 @@ // collections/PriorityQueueDemo.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class PriorityQueueDemo { @@ -23,7 +23,8 @@ public static void main(String[] args) { QueueDemo.printQ(priorityQueue); String fact = "EDUCATION SHOULD ESCHEW OBFUSCATION"; - List strings = Arrays.asList(fact.split("")); + List strings = + Arrays.asList(fact.split("")); PriorityQueue stringPQ = new PriorityQueue<>(strings); QueueDemo.printQ(stringPQ); @@ -44,9 +45,9 @@ public static void main(String[] args) { 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 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/collections/QueueDemo.java b/collections/QueueDemo.java index 066decc24..a7d30c1c4 100644 --- a/collections/QueueDemo.java +++ b/collections/QueueDemo.java @@ -1,7 +1,7 @@ // collections/QueueDemo.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Upcasting to a Queue from a LinkedList import java.util.*; diff --git a/collections/SetOfInteger.java b/collections/SetOfInteger.java index 2135fea7e..92a403e6c 100644 --- a/collections/SetOfInteger.java +++ b/collections/SetOfInteger.java @@ -1,7 +1,7 @@ // collections/SetOfInteger.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class SetOfInteger { @@ -14,6 +14,6 @@ public static void main(String[] args) { } } /* 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] +[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/collections/SetOfString.java b/collections/SetOfString.java index 4d0201b8f..50a06bc20 100644 --- a/collections/SetOfString.java +++ b/collections/SetOfString.java @@ -1,7 +1,7 @@ // collections/SetOfString.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class SetOfString { diff --git a/collections/SetOperations.java b/collections/SetOperations.java index 72a2f98ce..485588b6c 100644 --- a/collections/SetOperations.java +++ b/collections/SetOperations.java @@ -1,7 +1,7 @@ // collections/SetOperations.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class SetOperations { @@ -24,7 +24,8 @@ public static void main(String[] args) { 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); + System.out.println( + "'X Y Z' added to set1: " + set1); } } /* Output: @@ -34,5 +35,6 @@ public static void main(String[] args) { 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] +'X Y Z' added to set1: [A, B, C, D, E, F, G, M, X, Y, +Z] */ diff --git a/collections/SimpleCollection.java b/collections/SimpleCollection.java index 8fb2347e2..6dcf73b24 100644 --- a/collections/SimpleCollection.java +++ b/collections/SimpleCollection.java @@ -1,7 +1,7 @@ // collections/SimpleCollection.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class SimpleCollection { diff --git a/collections/SimpleIteration.java b/collections/SimpleIteration.java index 071339ca1..089774963 100644 --- a/collections/SimpleIteration.java +++ b/collections/SimpleIteration.java @@ -1,13 +1,13 @@ // collections/SimpleIteration.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import typeinfo.pets.*; +// Visit http://OnJava8.com for more book information. +import reflection.pets.*; import java.util.*; public class SimpleIteration { public static void main(String[] args) { - List pets = Pets.list(12); + List pets = new PetCreator().list(12); Iterator it = pets.iterator(); while(it.hasNext()) { Pet p = it.next(); @@ -28,9 +28,9 @@ public static void main(String[] args) { } } /* 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 +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/collections/SortedSetOfString.java b/collections/SortedSetOfString.java index 139a74695..af6222aac 100644 --- a/collections/SortedSetOfString.java +++ b/collections/SortedSetOfString.java @@ -1,7 +1,7 @@ // collections/SortedSetOfString.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class SortedSetOfString { diff --git a/collections/StackCollision.java b/collections/StackCollision.java index 82b6d57cf..7914e3496 100644 --- a/collections/StackCollision.java +++ b/collections/StackCollision.java @@ -1,14 +1,14 @@ // collections/StackCollision.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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.empty()) + while(!stack.isEmpty()) System.out.print(stack.pop() + " "); System.out.println(); java.util.Stack stack2 = diff --git a/collections/StackTest.java b/collections/StackTest.java index c873b1686..54005700a 100644 --- a/collections/StackTest.java +++ b/collections/StackTest.java @@ -1,15 +1,15 @@ // collections/StackTest.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import onjava.*; +// Visit http://OnJava8.com for more book information. +import java.util.*; public class StackTest { public static void main(String[] args) { - Stack stack = new Stack<>(); + Deque stack = new ArrayDeque<>(); for(String s : "My dog has fleas".split(" ")) stack.push(s); - while(!stack.empty()) + while(!stack.isEmpty()) System.out.print(stack.pop() + " "); } } diff --git a/collections/StackTest2.java b/collections/StackTest2.java new file mode 100644 index 000000000..148a834a8 --- /dev/null +++ b/collections/StackTest2.java @@ -0,0 +1,18 @@ +// collections/StackTest2.java +// (c)2021 MindView LLC: 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/collections/Statistics.java b/collections/Statistics.java index 862b17d08..a3ece359e 100644 --- a/collections/Statistics.java +++ b/collections/Statistics.java @@ -1,7 +1,7 @@ // collections/Statistics.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Simple demonstration of HashMap import java.util.*; @@ -12,14 +12,14 @@ public static void main(String[] args) { 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) + 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} +{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/collections/UniqueWords.java b/collections/UniqueWords.java index f8c3b096d..e39a9b882 100644 --- a/collections/UniqueWords.java +++ b/collections/UniqueWords.java @@ -1,15 +1,15 @@ // collections/UniqueWords.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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")); + List lines = Files.readAllLines( + Paths.get("SetOperations.java")); Set words = new TreeSet<>(); for(String line : lines) for(String word : line.split("\\W+")) @@ -19,10 +19,11 @@ public class UniqueWords { } } /* 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] +[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/collections/UniqueWordsAlphabetic.java b/collections/UniqueWordsAlphabetic.java index 584fa6506..780ddb3f1 100644 --- a/collections/UniqueWordsAlphabetic.java +++ b/collections/UniqueWordsAlphabetic.java @@ -1,7 +1,7 @@ // collections/UniqueWordsAlphabetic.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Producing an alphabetic listing import java.util.*; import java.nio.file.*; @@ -9,8 +9,8 @@ public class UniqueWordsAlphabetic { public static void main(String[] args) throws Exception { - List lines = - Files.readAllLines(Paths.get("SetOperations.java")); + List lines = Files.readAllLines( + Paths.get("SetOperations.java")); Set words = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); for(String line : lines) @@ -22,9 +22,9 @@ public class UniqueWordsAlphabetic { } /* 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] +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/collections/build.xml b/collections/build.xml deleted file mode 100644 index b5ffcc1ae..000000000 --- a/collections/build.xml +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/collectionsindepth/CanonicalMapping.java b/collectionsindepth/CanonicalMapping.java deleted file mode 100644 index a1b241ac5..000000000 --- a/collectionsindepth/CanonicalMapping.java +++ /dev/null @@ -1,52 +0,0 @@ -// collectionsindepth/CanonicalMapping.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Demonstrates WeakHashMap -import java.util.*; - -class Element { - private String ident; - public Element(String id) { ident = id; } - @Override - public String toString() { return ident; } - @Override - public int hashCode() { return ident.hashCode(); } - @Override - public boolean equals(Object r) { - return r instanceof Element && - ident.equals(((Element)r).ident); - } - @Override - protected void finalize() { - System.out.println("Finalizing " + - getClass().getSimpleName() + " " + ident); - } -} - -class Key extends Element { - public Key(String id) { super(id); } -} - -class Value extends Element { - public 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 = new Integer(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/collectionsindepth/CollectionMethods.java b/collectionsindepth/CollectionMethods.java deleted file mode 100644 index a25e43585..000000000 --- a/collectionsindepth/CollectionMethods.java +++ /dev/null @@ -1,88 +0,0 @@ -// collectionsindepth/CollectionMethods.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Things you can do with all Collections -import java.util.*; -import onjava.*; - -public class CollectionMethods { - public static void main(String[] args) { - Collection c = new ArrayList<>(); - c.addAll(Countries.names(6)); - c.add("ten"); - c.add("eleven"); - System.out.println(c); - // 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)); - // Add a Collection to another Collection - Collection c2 = new ArrayList<>(); - c2.addAll(Countries.names(6)); - c.addAll(c2); - System.out.println(c); - c.remove(Countries.DATA[0][0]); - System.out.println(c); - c.remove(Countries.DATA[1][0]); - System.out.println(c); - // Remove all components that are - // in the argument collection: - c.removeAll(c2); - System.out.println(c); - c.addAll(c2); - System.out.println(c); - // Is an element in this Collection? - String val = Countries.DATA[3][0]; - 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); - System.out.println(c2); - // Throw away all the elements - // in c2 that also appear in c3: - c2.removeAll(c3); - System.out.println("c2.isEmpty() = " + c2.isEmpty()); - c = new ArrayList<>(); - c.addAll(Countries.names(6)); - System.out.println(c); - c.clear(); // Remove all elements - System.out.println("after c.clear():" + c); - } -} -/* Output: -[ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, BURUNDI, -ten, eleven] -Collections.max(c) = ten -Collections.min(c) = ALGERIA -[ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, BURUNDI, -ten, eleven, ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA -FASO, BURUNDI] -[ANGOLA, BENIN, BOTSWANA, BURKINA FASO, BURUNDI, ten, -eleven, ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, -BURUNDI] -[BENIN, BOTSWANA, BURKINA FASO, BURUNDI, ten, eleven, -ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, BURUNDI] -[ten, eleven] -[ten, eleven, ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA -FASO, BURUNDI] -c.contains(BOTSWANA) = true -c.containsAll(c2) = true -[ANGOLA, BENIN] -c2.isEmpty() = true -[ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, BURUNDI] -after c.clear():[] -*/ diff --git a/collectionsindepth/DequeTest.java b/collectionsindepth/DequeTest.java deleted file mode 100644 index dca46926d..000000000 --- a/collectionsindepth/DequeTest.java +++ /dev/null @@ -1,30 +0,0 @@ -// collectionsindepth/DequeTest.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import onjava.*; - -public class DequeTest { - static void fillTest(Deque deque) { - for(int i = 20; i < 27; i++) - deque.addFirst(i); - for(int i = 50; i < 55; i++) - deque.addLast(i); - } - public static void main(String[] args) { - Deque di = new Deque<>(); - fillTest(di); - System.out.println(di); - while(di.size() != 0) - System.out.print(di.removeFirst() + " "); - System.out.println(); - fillTest(di); - while(di.size() != 0) - System.out.print(di.removeLast() + " "); - } -} -/* Output: -[26, 25, 24, 23, 22, 21, 20, 50, 51, 52, 53, 54] -26 25 24 23 22 21 20 50 51 52 53 54 -54 53 52 51 50 20 21 22 23 24 25 26 -*/ diff --git a/collectionsindepth/FilledCollectionGeneration.java b/collectionsindepth/FilledCollectionGeneration.java deleted file mode 100644 index 22458de99..000000000 --- a/collectionsindepth/FilledCollectionGeneration.java +++ /dev/null @@ -1,23 +0,0 @@ -// collectionsindepth/FilledCollectionGeneration.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Using the Suppliers defined in the Arrays chapter -import java.util.*; -import onjava.*; - -public class FilledCollectionGeneration { - public static void main(String[] args) { - System.out.println(new ArrayList<>( - FilledCollection.list( // Convenience method - new Rand.String(9), 10))); - System.out.println(new HashSet<>( - new FilledCollection<>( - new Rand.Integer(), 10))); - } -} -/* Output: -[YNzbrnyGc, FOWZnTcQr, GseGZMmJM, RoEsuEcUO, neOEdLsmw, -HLGEahKcx, rEqUCBbkI, naMesbtWH, kjUrUkZPg, wsqPzDyCy] -[2017, 8037, 871, 7882, 6090, 4779, 299, 573, 4367, 3455] -*/ diff --git a/collectionsindepth/FilledCollectionTest.java b/collectionsindepth/FilledCollectionTest.java deleted file mode 100644 index 4f707b4ff..000000000 --- a/collectionsindepth/FilledCollectionTest.java +++ /dev/null @@ -1,31 +0,0 @@ -// collectionsindepth/FilledCollectionTest.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.*; -import java.util.function.*; -import onjava.*; - -class Government implements Supplier { - 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 FilledCollectionTest { - public static void main(String[] args) { - Set set = new LinkedHashSet<>( - new FilledCollection<>(new Government(), 15)); - // Using the convenience method: - set.addAll( - FilledCollection.list(new Government(), 15)); - System.out.println(set); - } -} -/* Output: -[strange, women, lying, in, ponds, distributing, swords, -is, no, basis, for, a, system, of, government] -*/ diff --git a/collectionsindepth/FillingLists.java b/collectionsindepth/FillingLists.java deleted file mode 100644 index 37f7b1bdd..000000000 --- a/collectionsindepth/FillingLists.java +++ /dev/null @@ -1,31 +0,0 @@ -// collectionsindepth/FillingLists.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// The Collections.fill() & Collections.nCopies() methods -import java.util.*; - -class StringAddress { - private String s; - public 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@19e0bfd Hello, StringAddress@19e0bfd Hello, -StringAddress@19e0bfd Hello, StringAddress@19e0bfd Hello] -[StringAddress@139a55 World!, StringAddress@139a55 World!, -StringAddress@139a55 World!, StringAddress@139a55 World!] -*/ diff --git a/collectionsindepth/IndividualTest.java b/collectionsindepth/IndividualTest.java deleted file mode 100644 index 972fdcc97..000000000 --- a/collectionsindepth/IndividualTest.java +++ /dev/null @@ -1,24 +0,0 @@ -// collectionsindepth/IndividualTest.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ 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); - System.out.println(pets); - } -} -/* Output: -[Cat Elsie May, Cat Pinkola, Cat Shackleton, Cat Stanford -aka Stinky el Negro, Cymric Molly, Dog Margrett, Mutt Spot, -Pug Louie aka Louis Snorkelstein Dupree, Rat Fizzy, Rat -Freckly, Rat Fuzzy] -*/ diff --git a/collectionsindepth/ListPerformance.java b/collectionsindepth/ListPerformance.java deleted file mode 100644 index 51e37eef4..000000000 --- a/collectionsindepth/ListPerformance.java +++ /dev/null @@ -1,210 +0,0 @@ -// collectionsindepth/ListPerformance.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Demonstrates performance differences in Lists -// {Args: 100 500} Small to keep build testing short -import java.util.*; -import onjava.*; - -public class ListPerformance { - static SplittableRandom rand = new SplittableRandom(); - static int reps = 1000; - static List>> tests = - new ArrayList<>(); - static List>> qTests = - new ArrayList<>(); - static { - tests.add(new Test>("add") { - @Override - int test(List list, TestParam tp) { - int loops = tp.loops; - int listSize = tp.size; - for(int i = 0; i < loops; i++) { - list.clear(); - for(int j = 0; j < listSize; j++) - list.add(j); - } - return loops * listSize; - } - }); - tests.add(new Test>("get") { - @Override - int test(List list, TestParam tp) { - int loops = tp.loops * reps; - int listSize = list.size(); - for(int i = 0; i < loops; i++) - list.get(rand.nextInt(listSize)); - return loops; - } - }); - tests.add(new Test>("set") { - @Override - int test(List list, TestParam tp) { - int loops = tp.loops * reps; - int listSize = list.size(); - for(int i = 0; i < loops; i++) - list.set(rand.nextInt(listSize), 47); - return loops; - } - }); - tests.add(new Test>("iteradd") { - @Override - int test(List list, TestParam tp) { - final int LOOPS = 1000000; - int half = list.size() / 2; - ListIterator it = - list.listIterator(half); - for(int i = 0; i < LOOPS; i++) - it.add(47); - return LOOPS; - } - }); - tests.add(new Test>("insert") { - @Override - int test(List list, TestParam tp) { - int loops = tp.loops; - for(int i = 0; i < loops; i++) - list.add(5, 47); // Minimize random-access cost - return loops; - } - }); - tests.add(new Test>("remove") { - @Override - int test(List list, TestParam tp) { - int loops = tp.loops; - int size = tp.size; - for(int i = 0; i < loops; i++) { - list.clear(); - list.addAll(new CountingIntegerList(size)); - while(list.size() > 5) - list.remove(5); // Minimize random-access cost - } - return loops * size; - } - }); - // Tests for queue behavior: - qTests.add(new Test>("addFirst") { - @Override - int test(LinkedList list, TestParam tp) { - int loops = tp.loops; - int size = tp.size; - for(int i = 0; i < loops; i++) { - list.clear(); - for(int j = 0; j < size; j++) - list.addFirst(47); - } - return loops * size; - } - }); - qTests.add(new Test>("addLast") { - @Override - int test(LinkedList list, TestParam tp) { - int loops = tp.loops; - int size = tp.size; - for(int i = 0; i < loops; i++) { - list.clear(); - for(int j = 0; j < size; j++) - list.addLast(47); - } - return loops * size; - } - }); - qTests.add( - new Test>("rmFirst") { - @Override - int test(LinkedList list, TestParam tp) { - int loops = tp.loops; - int size = tp.size; - for(int i = 0; i < loops; i++) { - list.clear(); - list.addAll(new CountingIntegerList(size)); - while(list.size() > 0) - list.removeFirst(); - } - return loops * size; - } - }); - qTests.add(new Test>("rmLast") { - @Override - int test(LinkedList list, TestParam tp) { - int loops = tp.loops; - int size = tp.size; - for(int i = 0; i < loops; i++) { - list.clear(); - list.addAll(new CountingIntegerList(size)); - while(list.size() > 0) - list.removeLast(); - } - return loops * size; - } - }); - } - static class ListTester extends Tester> { - public ListTester(List collection, - List>> tests) { - super(collection, tests); - } - // Fill to the appropriate size before each test: - @Override - protected List initialize(int size) { - collection.clear(); - collection.addAll(new CountingIntegerList(size)); - return collection; - } - // Convenience method: - public static void run(List list, - List>> tests) { - new ListTester(list, tests).timedTest(); - } - } - public static void main(String[] args) { - if(args.length > 0) - Tester.defaultParams = TestParam.array(args); - // Can only do these two tests on an array: - Tester> arrayTest = - new Tester>(null, - tests.subList(1, 3)) { - // This is called before each test. It - // produces a non-resizeable array-backed list: - @Override protected - List initialize(int size) { - Integer[] ia = new Integer[size]; - Arrays.setAll(ia, new Count.Integer()::get); - return Arrays.asList(ia); - } - }; - arrayTest.setHeadline("Array as List"); - arrayTest.timedTest(); - Tester.defaultParams= TestParam.array( - 10, 5000, 100, 5000, 1000, 1000, 10000, 200); - if(args.length > 0) - Tester.defaultParams = TestParam.array(args); - ListTester.run(new ArrayList<>(), tests); - ListTester.run(new LinkedList<>(), tests); - ListTester.run(new Vector<>(), tests); - Tester.fieldWidth = 12; - Tester> qTest = - new Tester>( - new LinkedList<>(), qTests); - qTest.setHeadline("Queue tests"); - qTest.timedTest(); - } -} -/* Output: ---- Array as List --- - size get set - 100 19 20 ---------------------- ArrayList --------------------- - size add get set iteradd insert remove - 100 31 19 21 33 158 114 ---------------------- LinkedList --------------------- - size add get set iteradd insert remove - 100 30 44 45 77 143 56 ------------------------ Vector ----------------------- - size add get set iteradd insert remove - 100 26 32 33 64 147 67 --------------------- Queue tests -------------------- - size addFirst addLast rmFirst rmLast - 100 33 71 102 135 -*/ diff --git a/collectionsindepth/MapEntry.java b/collectionsindepth/MapEntry.java deleted file mode 100644 index c14712c7e..000000000 --- a/collectionsindepth/MapEntry.java +++ /dev/null @@ -1,44 +0,0 @@ -// collectionsindepth/MapEntry.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ 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 (key==null ? 0 : key.hashCode()) ^ - (value==null ? 0 : value.hashCode()); - } - @Override - public boolean equals(Object o) { - if(!(o instanceof MapEntry)) return false; - @SuppressWarnings("unchecked") - MapEntry me = (MapEntry)o; - return - (key == null ? me.getKey() == null : - key.equals(me.getKey())) - && - (value == null ? me.getValue() == null : - value.equals(me.getValue())); - } - @Override - public String toString() { return key + "=" + value; } -} diff --git a/collectionsindepth/MapPerformance.java b/collectionsindepth/MapPerformance.java deleted file mode 100644 index 02aca5d79..000000000 --- a/collectionsindepth/MapPerformance.java +++ /dev/null @@ -1,81 +0,0 @@ -// collectionsindepth/MapPerformance.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Demonstrates performance differences in Maps -// {Args: 100 5000} Small to keep build testing short -import java.util.*; - -public class MapPerformance { - static List>> tests = - new ArrayList<>(); - static { - tests.add(new Test>("put") { - @Override - int test(Map map, TestParam tp) { - int loops = tp.loops; - int size = tp.size; - for(int i = 0; i < loops; i++) { - map.clear(); - for(int j = 0; j < size; j++) - map.put(j, j); - } - return loops * size; - } - }); - tests.add(new Test>("get") { - @Override - int test(Map map, TestParam tp) { - int loops = tp.loops; - int span = tp.size * 2; - for(int i = 0; i < loops; i++) - for(int j = 0; j < span; j++) - map.get(j); - return loops * span; - } - }); - tests.add(new Test>("iterate") { - @Override - int test(Map map, TestParam tp) { - int loops = tp.loops * 10; - for(int i = 0; i < loops; i ++) { - Iterator it = map.entrySet().iterator(); - while(it.hasNext()) - it.next(); - } - return loops * map.size(); - } - }); - } - public static void main(String[] args) { - if(args.length > 0) - Tester.defaultParams = TestParam.array(args); - Tester.run(new TreeMap<>(), tests); - Tester.run(new HashMap<>(), tests); - Tester.run(new LinkedHashMap<>(),tests); - Tester.run( - new IdentityHashMap<>(), tests); - Tester.run(new WeakHashMap<>(), tests); - Tester.run(new Hashtable<>(), tests); - } -} -/* Output: ----------- TreeMap ---------- - size put get iterate - 100 86 47 9 ----------- HashMap ---------- - size put get iterate - 100 25 10 12 -------- LinkedHashMap ------- - size put get iterate - 100 27 8 6 ------- IdentityHashMap ------ - size put get iterate - 100 51 47 13 --------- WeakHashMap -------- - size put get iterate - 100 28 11 12 ---------- Hashtable --------- - size put get iterate - 100 31 21 13 -*/ diff --git a/collectionsindepth/Prediction.java b/collectionsindepth/Prediction.java deleted file mode 100644 index 4cbb27f66..000000000 --- a/collectionsindepth/Prediction.java +++ /dev/null @@ -1,18 +0,0 @@ -// collectionsindepth/Prediction.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Predicting the weather with groundhogs -import java.util.*; - -public class Prediction { - private static SplittableRandom rand = new SplittableRandom(47); - private boolean shadow = rand.nextDouble() > 0.5; - @Override - public String toString() { - if(shadow) - return "Six more weeks of Winter!"; - else - return "Early Spring!"; - } -} diff --git a/collectionsindepth/QueueBehavior.java b/collectionsindepth/QueueBehavior.java deleted file mode 100644 index 0701f7227..000000000 --- a/collectionsindepth/QueueBehavior.java +++ /dev/null @@ -1,43 +0,0 @@ -// collectionsindepth/QueueBehavior.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Compares the behavior of some of the queues -import java.util.concurrent.*; -import java.util.*; -import java.util.function.*; -import onjava.*; - -public class QueueBehavior { - private static int count = 10; - static void test(Queue queue, Supplier gen) { - for(int i = 0; i < count; i++) - queue.offer(gen.get()); - while(queue.peek() != null) - System.out.print(queue.remove() + " "); - System.out.println(); - } - static class Gen implements Supplier { - String[] s = ("one two three four five six seven " + - "eight nine ten").split(" "); - int i; - @Override - public String get() { return s[i++]; } - } - public static void main(String[] args) { - test(new LinkedList<>(), new Gen()); - test(new PriorityQueue<>(), new Gen()); - test(new ArrayBlockingQueue<>(count), new Gen()); - test(new ConcurrentLinkedQueue<>(), new Gen()); - test(new LinkedBlockingQueue<>(), new Gen()); - test(new PriorityBlockingQueue<>(), new Gen()); - } -} -/* Output: -one two three four five six seven eight nine ten -eight five four nine one seven six ten three two -one two three four five six seven eight nine ten -one two three four five six seven eight nine ten -one two three four five six seven eight nine ten -eight five four nine one seven six ten three two -*/ diff --git a/collectionsindepth/SetPerformance.java b/collectionsindepth/SetPerformance.java deleted file mode 100644 index 368384e50..000000000 --- a/collectionsindepth/SetPerformance.java +++ /dev/null @@ -1,69 +0,0 @@ -// collectionsindepth/SetPerformance.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Demonstrates performance differences in Sets -// {Args: 100 5000} Small to keep build testing short -import java.util.*; - -public class SetPerformance { - static List>> tests = - new ArrayList<>(); - static { - tests.add(new Test>("add") { - @Override - int test(Set set, TestParam tp) { - int loops = tp.loops; - int size = tp.size; - for(int i = 0; i < loops; i++) { - set.clear(); - for(int j = 0; j < size; j++) - set.add(j); - } - return loops * size; - } - }); - tests.add(new Test>("contains") { - @Override - int test(Set set, TestParam tp) { - int loops = tp.loops; - int span = tp.size * 2; - for(int i = 0; i < loops; i++) - for(int j = 0; j < span; j++) - set.contains(j); - return loops * span; - } - }); - tests.add(new Test>("iterate") { - @Override - int test(Set set, TestParam tp) { - int loops = tp.loops * 10; - for(int i = 0; i < loops; i++) { - Iterator it = set.iterator(); - while(it.hasNext()) - it.next(); - } - return loops * set.size(); - } - }); - } - public static void main(String[] args) { - if(args.length > 0) - Tester.defaultParams = TestParam.array(args); - Tester.fieldWidth = 10; - Tester.run(new TreeSet<>(), tests); - Tester.run(new HashSet<>(), tests); - Tester.run(new LinkedHashSet<>(), tests); - } -} -/* Output: -------------- TreeSet ------------- - size add contains iterate - 100 85 51 9 -------------- HashSet ------------- - size add contains iterate - 100 27 12 12 ----------- LinkedHashSet ---------- - size add contains iterate - 100 28 10 7 -*/ diff --git a/collectionsindepth/SlowMap.java b/collectionsindepth/SlowMap.java deleted file mode 100644 index e80d14a0f..000000000 --- a/collectionsindepth/SlowMap.java +++ /dev/null @@ -1,59 +0,0 @@ -// collectionsindepth/SlowMap.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ 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 is 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(15)); - System.out.println(m); - System.out.println(m.get("BULGARIA")); - System.out.println(m.entrySet()); - } -} -/* Output: -{ANGOLA=Luanda, CAPE VERDE=Praia, EGYPT=Cairo, -BURUNDI=Bujumbura, BENIN=Porto-Novo, ALGERIA=Algiers, -CAMEROON=Yaounde, CONGO=Brazzaville, CENTRAL AFRICAN -REPUBLIC=Bangui, EQUATORIAL GUINEA=Malabo, COMOROS=Moroni, -DJIBOUTI=Dijibouti, BURKINA FASO=Ouagadougou, -CHAD=N'djamena, BOTSWANA=Gaberone} -null -[ANGOLA=Luanda, CAPE VERDE=Praia, EGYPT=Cairo, -BURUNDI=Bujumbura, BENIN=Porto-Novo, ALGERIA=Algiers, -CAMEROON=Yaounde, CONGO=Brazzaville, CENTRAL AFRICAN -REPUBLIC=Bangui, EQUATORIAL GUINEA=Malabo, COMOROS=Moroni, -DJIBOUTI=Dijibouti, BURKINA FASO=Ouagadougou, -CHAD=N'djamena, BOTSWANA=Gaberone] -*/ diff --git a/collectionsindepth/SpringDetector.java b/collectionsindepth/SpringDetector.java deleted file mode 100644 index 7a9e259c4..000000000 --- a/collectionsindepth/SpringDetector.java +++ /dev/null @@ -1,39 +0,0 @@ -// collectionsindepth/SpringDetector.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// What will the weather be? -import java.lang.reflect.*; -import java.util.*; - -public class SpringDetector { - // Uses a Groundhog or class derived from Groundhog: - public static - void detectSpring(Class type) throws Exception { - Constructor ghog = type.getConstructor(int.class); - Map map = new HashMap<>(); - for(int i = 0; i < 10; i++) - map.put(ghog.newInstance(i), new Prediction()); - System.out.println("map = " + map); - 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); - } - public static void - main(String[] args) throws Exception { - detectSpring(Groundhog.class); - } -} -/* Output: -map = {Groundhog #2=Early Spring!, Groundhog #3=Early -Spring!, Groundhog #1=Six more weeks of Winter!, Groundhog -#8=Six more weeks of Winter!, Groundhog #9=Six more weeks -of Winter!, Groundhog #6=Early Spring!, Groundhog #5=Early -Spring!, Groundhog #0=Six more weeks of Winter!, Groundhog -#7=Early Spring!, Groundhog #4=Six more weeks of Winter!} -Looking up prediction for Groundhog #3 -Key not found: Groundhog #3 -*/ diff --git a/collectionsindepth/SpringDetector2.java b/collectionsindepth/SpringDetector2.java deleted file mode 100644 index 4a2081cb6..000000000 --- a/collectionsindepth/SpringDetector2.java +++ /dev/null @@ -1,22 +0,0 @@ -// collectionsindepth/SpringDetector2.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// A working key - -public class SpringDetector2 { - public static void - main(String[] args) throws Exception { - SpringDetector.detectSpring(Groundhog2.class); - } -} -/* Output: -map = {Groundhog #0=Six more weeks of Winter!, Groundhog -#1=Six more weeks of Winter!, Groundhog #2=Early Spring!, -Groundhog #3=Early Spring!, Groundhog #4=Six more weeks of -Winter!, Groundhog #5=Early Spring!, 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/collectionsindepth/Synchronization.java b/collectionsindepth/Synchronization.java deleted file mode 100644 index 9d2adcfd0..000000000 --- a/collectionsindepth/Synchronization.java +++ /dev/null @@ -1,24 +0,0 @@ -// collectionsindepth/Synchronization.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ 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/collectionsindepth/Test.java b/collectionsindepth/Test.java deleted file mode 100644 index 0a9f1b98b..000000000 --- a/collectionsindepth/Test.java +++ /dev/null @@ -1,13 +0,0 @@ -// collectionsindepth/Test.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Framework for performing timed tests of collections - -public abstract class Test { - String name; - public Test(String name) { this.name = name; } - // Override this method for different tests. - // Returns actual number of repetitions of test. - abstract int test(C collection, TestParam tp); -} diff --git a/collectionsindepth/TestParam.java b/collectionsindepth/TestParam.java deleted file mode 100644 index bbf1ae824..000000000 --- a/collectionsindepth/TestParam.java +++ /dev/null @@ -1,30 +0,0 @@ -// collectionsindepth/TestParam.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// A "data transfer object." - -public class TestParam { - public final int size; - public final int loops; - public TestParam(int size, int loops) { - this.size = size; - this.loops = loops; - } - // Create an array of TestParam from a varargs sequence: - public static TestParam[] array(int... values) { - int size = values.length/2; - TestParam[] result = new TestParam[size]; - int n = 0; - for(int i = 0; i < size; i++) - result[i] = new TestParam(values[n++], values[n++]); - return result; - } - // Convert a String array to a TestParam array: - public static TestParam[] array(String[] values) { - int[] vals = new int[values.length]; - for(int i = 0; i < vals.length; i++) - vals[i] = Integer.decode(values[i]); - return array(vals); - } -} diff --git a/collectionsindepth/Tester.java b/collectionsindepth/Tester.java deleted file mode 100644 index abc49add7..000000000 --- a/collectionsindepth/Tester.java +++ /dev/null @@ -1,84 +0,0 @@ -// collectionsindepth/Tester.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Applies Test objects to lists of different collections -import java.util.*; -import java.time.*; - -public class Tester { - public static int fieldWidth = 8; - public static - TestParam[] defaultParams= TestParam.array( - 10, 5000, 100, 5000, 1000, 5000, 10000, 500); - // Override this to modify pre-test initialization: - protected C initialize(int size) { return collection; } - protected C collection; - private String headline = ""; - private List> tests; - private static int sizeWidth = 5; - private static String sizeField = "%" + sizeWidth + "s"; - private TestParam[] paramList = defaultParams; - public Tester(C collection, List> tests) { - this.collection = collection; - this.tests = tests; - if(collection != null) - headline = collection.getClass().getSimpleName(); - } - public Tester(C collection, List> tests, - TestParam[] paramList) { - this(collection, tests); - this.paramList = paramList; - } - public void setHeadline(String newHeadline) { - headline = newHeadline; - } - // Generic methods for convenience : - public static - void run(C cntnr, List> tests) { - new Tester<>(cntnr, tests).timedTest(); - } - public static void run(C cntnr, - List> tests, TestParam[] paramList) { - new Tester<>(cntnr, tests, paramList).timedTest(); - } - private void displayHeader() { - // Calculate width and pad with '-': - int width = fieldWidth * tests.size() + sizeWidth; - int dashLength = width - headline.length() - 1; - StringBuilder head = new StringBuilder(width); - for(int i = 0; i < dashLength/2; i++) - head.append('-'); - head.append(' '); - head.append(headline); - head.append(' '); - for(int i = 0; i < dashLength/2; i++) - head.append('-'); - System.out.println(head); - // Print column headers: - System.out.format(sizeField, "size"); - for(Test test : tests) - System.out.format( - "%" + fieldWidth + "s", test.name); - System.out.println(); - } - // Run the tests for this collection: - public void timedTest() { - displayHeader(); - for(TestParam param : paramList) { - System.out.format(sizeField, param.size); - for(Test test : tests) { - C kontainer = initialize(param.size); - Instant start = Instant.now(); - // Call the overriden method: - int reps = test.test(kontainer, param); - Duration elapsed = - Duration.between(start, Instant.now()); - Duration timePerRep = elapsed.dividedBy(reps); - System.out.format("%" + fieldWidth + "d", - timePerRep.toNanos()); - } - System.out.println(); - } - } -} diff --git a/collectionsindepth/ToDoList.java b/collectionsindepth/ToDoList.java deleted file mode 100644 index fc97aa1cf..000000000 --- a/collectionsindepth/ToDoList.java +++ /dev/null @@ -1,57 +0,0 @@ -// collectionsindepth/ToDoList.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// A more complex use of PriorityQueue -import java.util.*; - -class ToDoList extends PriorityQueue { - static class ToDoItem implements Comparable { - private char primary; - private int secondary; - private String item; - public ToDoItem(String td, char pri, int sec) { - primary = pri; - secondary = sec; - item = td; - } - @Override - public int compareTo(ToDoItem arg) { - if(primary > arg.primary) - 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; - } - } - public void add(String td, char pri, int sec) { - super.add(new ToDoItem(td, pri, sec)); - } - public static void main(String[] args) { - ToDoList toDoList = new ToDoList(); - toDoList.add("Empty trash", 'C', 4); - toDoList.add("Feed dog", 'A', 2); - toDoList.add("Feed bird", 'B', 7); - toDoList.add("Mow lawn", 'C', 3); - toDoList.add("Water lawn", 'A', 1); - toDoList.add("Feed cat", 'B', 1); - while(!toDoList.isEmpty()) - System.out.println(toDoList.remove()); - } -} -/* Output: -A1: Water lawn -A2: Feed dog -B1: Feed cat -B7: Feed bird -C3: Mow lawn -C4: Empty trash -*/ diff --git a/collectionsindepth/TypesForSets.java b/collectionsindepth/TypesForSets.java deleted file mode 100644 index d89527729..000000000 --- a/collectionsindepth/TypesForSets.java +++ /dev/null @@ -1,92 +0,0 @@ -// collectionsindepth/TypesForSets.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Methods necessary to put your own type in a Set -import java.lang.reflect.InvocationTargetException; -import java.util.*; - -class SetType { - int i; - public SetType(int n) { i = n; } - @Override - public boolean equals(Object o) { - return o instanceof SetType && (i == ((SetType)o).i); - } - @Override - public String toString() { return Integer.toString(i); } -} - -class HashType extends SetType { - public HashType(int n) { super(n); } - @Override - public int hashCode() { return i; } -} - -class TreeType extends SetType -implements Comparable { - public TreeType(int n) { super(n); } - @Override - public int compareTo(TreeType arg) { - return (arg.i < i ? -1 : (arg.i == i ? 0 : 1)); - } -} - -public class TypesForSets { - static Set fill(Set set, Class type) { - try { - for(int i = 0; i < 10; i++) - set.add(type.getConstructor(int.class) - .newInstance(i)); - } catch(NoSuchMethodException | - SecurityException | - InstantiationException | - IllegalAccessException | - IllegalArgumentException | - InvocationTargetException e) { - throw new RuntimeException(e); - } - return set; - } - static void test(Set set, Class 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.class); - test(new LinkedHashSet<>(), HashType.class); - test(new TreeSet<>(), TreeType.class); - // Things that don't work: - test(new HashSet<>(), SetType.class); - test(new HashSet<>(), TreeType.class); - test(new LinkedHashSet<>(), SetType.class); - test(new LinkedHashSet<>(), TreeType.class); - try { - test(new TreeSet<>(), SetType.class); - } catch(Exception e) { - System.out.println("Expected: " + e.getMessage()); - } - try { - test(new TreeSet<>(), HashType.class); - } catch(Exception e) { - System.out.println("Expected: " + e.getMessage()); - } - } -} -/* Output: -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -[9, 8, 7, 6, 5, 4, 3, 2, 1, 0] -[6, 9, 2, 0, 8, 5, 4, 8, 0, 2, 7, 8, 9, 1, 4, 5, 0, 4, 3, -1, 6, 3, 2, 7, 7, 6, 5, 3, 9, 1] -[7, 2, 8, 9, 1, 7, 4, 1, 2, 3, 0, 9, 1, 8, 3, 0, 8, 5, 6, -6, 3, 0, 2, 7, 5, 4, 6, 4, 5, 9] -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, -9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, -9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -Expected: SetType cannot be cast to java.lang.Comparable -Expected: HashType cannot be cast to java.lang.Comparable -*/ diff --git a/collectionsindepth/build.xml b/collectionsindepth/build.xml deleted file mode 100644 index 3c003129a..000000000 --- a/collectionsindepth/build.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/collectionsindepth/AssociativeArray.java b/collectiontopics/AssociativeArray.java similarity index 88% rename from collectionsindepth/AssociativeArray.java rename to collectiontopics/AssociativeArray.java index cbc7448bd..37c09da89 100644 --- a/collectionsindepth/AssociativeArray.java +++ b/collectiontopics/AssociativeArray.java @@ -1,7 +1,7 @@ -// collectionsindepth/AssociativeArray.java -// (c)2016 MindView LLC: see Copyright.txt +// collectiontopics/AssociativeArray.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Associates keys with values public class AssociativeArray { @@ -22,8 +22,7 @@ public V get(K key) { return (V)pairs[i][1]; return null; // Did not find key } - @Override - public String toString() { + @Override public String toString() { StringBuilder result = new StringBuilder(); for(int i = 0; i < index; i++) { result.append(pairs[i][0].toString()); diff --git a/collectionsindepth/Bits.java b/collectiontopics/Bits.java similarity index 77% rename from collectionsindepth/Bits.java rename to collectiontopics/Bits.java index e51b836b9..f4f6d506a 100644 --- a/collectionsindepth/Bits.java +++ b/collectiontopics/Bits.java @@ -1,7 +1,7 @@ -// collectionsindepth/Bits.java -// (c)2016 MindView LLC: see Copyright.txt +// collectiontopics/Bits.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Demonstration of BitSet import java.util.*; @@ -14,7 +14,7 @@ public static void printBitSet(BitSet b) { System.out.println("bit pattern: " + bbits); } public static void main(String[] args) { - SplittableRandom rand = new SplittableRandom(47); + Random rand = new Random(47); // Take the LSB of nextInt(): byte bt = (byte)rand.nextInt(); BitSet bb = new BitSet(); @@ -62,17 +62,17 @@ public static void main(String[] args) { /* Output: byte value: -107 bits: {0, 2, 4, 7} -bit pattern: 1010100100000000000000000000000000000000000000 -000000000000000000 +bit pattern: 101010010000000000000000000000000000000000 +0000000000000000000000 short value: 1302 bits: {1, 2, 4, 8, 10} -bit pattern: 0110100010100000000000000000000000000000000000 -000000000000000000 +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: 1101010101010000001101111110000100000000000000 -000000000000000000 +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/collectiontopics/CanonicalMapping.java b/collectiontopics/CanonicalMapping.java new file mode 100644 index 000000000..f464599b5 --- /dev/null +++ b/collectiontopics/CanonicalMapping.java @@ -0,0 +1,32 @@ +// collectiontopics/CanonicalMapping.java +// (c)2021 MindView 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.*; +import java.util.stream.*; + +public class CanonicalMapping { + static void showKeys(Map m) { + // Display sorted keys + List keys = new ArrayList<>(m.keySet()); + Collections.sort(keys); + System.out.println(keys); + } + public static void main(String[] args) { + int size = 100; + String[] savedKeys = new String[size]; + WeakHashMap map = + new WeakHashMap<>(); + for(int i = 0; i < size; i++) { + String key = String.format("%03d", i); + String value = Integer.toString(i); + if(i % 3 == 0) + savedKeys[i] = key; // Save as "real" references + map.put(key, value); + } + showKeys(map); + System.gc(); + showKeys(map); + } +} diff --git a/collectiontopics/CollectionMethods.java b/collectiontopics/CollectionMethods.java new file mode 100644 index 000000000..08660e62e --- /dev/null +++ b/collectiontopics/CollectionMethods.java @@ -0,0 +1,134 @@ +// collectiontopics/CollectionMethods.java +// (c)2021 MindView 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); + // Discard all c2 elements 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/collectionsindepth/Enumerations.java b/collectiontopics/Enumerations.java similarity index 65% rename from collectionsindepth/Enumerations.java rename to collectiontopics/Enumerations.java index 531ae0a42..63d740590 100644 --- a/collectionsindepth/Enumerations.java +++ b/collectiontopics/Enumerations.java @@ -1,7 +1,7 @@ -// collectionsindepth/Enumerations.java -// (c)2016 MindView LLC: see Copyright.txt +// collectiontopics/Enumerations.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Java 1.0/1.1 Vector and Enumeration import java.util.*; import onjava.*; @@ -18,6 +18,7 @@ public static void main(String[] args) { } } /* Output: -ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, BURUNDI, -CAMEROON, CAPE VERDE, CENTRAL AFRICAN REPUBLIC, CHAD, +ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, +BURUNDI, CAMEROON, CAPE VERDE, CENTRAL AFRICAN +REPUBLIC, CHAD, */ diff --git a/collectionsindepth/FailFast.java b/collectiontopics/FailFast.java similarity index 76% rename from collectionsindepth/FailFast.java rename to collectiontopics/FailFast.java index 60a4244ce..9425de28d 100644 --- a/collectionsindepth/FailFast.java +++ b/collectiontopics/FailFast.java @@ -1,7 +1,7 @@ -// collectionsindepth/FailFast.java -// (c)2016 MindView LLC: see Copyright.txt +// collectiontopics/FailFast.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Demonstrates the "fail-fast" behavior import java.util.*; diff --git a/collectiontopics/FillMapTest.java b/collectiontopics/FillMapTest.java new file mode 100644 index 000000000..e96d0263b --- /dev/null +++ b/collectiontopics/FillMapTest.java @@ -0,0 +1,32 @@ +// collectiontopics/FillMapTest.java +// (c)2021 MindView LLC: see Copyright.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/collectiontopics/FillingLists.java b/collectiontopics/FillingLists.java new file mode 100644 index 000000000..29123d01f --- /dev/null +++ b/collectiontopics/FillingLists.java @@ -0,0 +1,34 @@ +// collectiontopics/FillingLists.java +// (c)2021 MindView 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@19e0bfd Hello, StringAddress@19e0bfd +Hello, StringAddress@19e0bfd Hello, +StringAddress@19e0bfd Hello] +[StringAddress@139a55 World!, StringAddress@139a55 +World!, StringAddress@139a55 World!, +StringAddress@139a55 World!] +*/ diff --git a/collectiontopics/FunctionalMap.java b/collectiontopics/FunctionalMap.java new file mode 100644 index 000000000..ef9b48086 --- /dev/null +++ b/collectiontopics/FunctionalMap.java @@ -0,0 +1,38 @@ +// collectiontopics/FunctionalMap.java +// (c)2021 MindView 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/collectiontopics/HTMLColorTest.java b/collectiontopics/HTMLColorTest.java new file mode 100644 index 000000000..cdfeb5bed --- /dev/null +++ b/collectiontopics/HTMLColorTest.java @@ -0,0 +1,103 @@ +// collectiontopics/HTMLColorTest.java +// (c)2021 MindView LLC: 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/collectionsindepth/LinkedHashMapDemo.java b/collectiontopics/LinkedHashMapDemo.java similarity index 66% rename from collectionsindepth/LinkedHashMapDemo.java rename to collectiontopics/LinkedHashMapDemo.java index 164417518..7e9bc16a5 100644 --- a/collectionsindepth/LinkedHashMapDemo.java +++ b/collectiontopics/LinkedHashMapDemo.java @@ -1,7 +1,7 @@ -// collectionsindepth/LinkedHashMapDemo.java -// (c)2016 MindView LLC: see Copyright.txt +// collectiontopics/LinkedHashMapDemo.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // What you can do with a LinkedHashMap import java.util.*; import onjava.*; @@ -9,13 +9,14 @@ public class LinkedHashMapDemo { public static void main(String[] args) { LinkedHashMap linkedMap = - new LinkedHashMap<>(new CountingFilledMap(9)); + new LinkedHashMap<>(new CountMap(9)); System.out.println(linkedMap); // Least-recently-used order: - linkedMap = new LinkedHashMap<>(16, 0.75f, true); - linkedMap.putAll(new CountingFilledMap(9)); + linkedMap = + new LinkedHashMap<>(16, 0.75f, true); + linkedMap.putAll(new CountMap(9)); System.out.println(linkedMap); - for(int i = 0; i < 6; i++) // Cause accesses: + for(int i = 0; i < 6; i++) linkedMap.get(i); System.out.println(linkedMap); linkedMap.get(0); diff --git a/collectionsindepth/Lists.java b/collectiontopics/ListOps.java similarity index 54% rename from collectionsindepth/Lists.java rename to collectiontopics/ListOps.java index 5cf731ac7..dee92d5e5 100644 --- a/collectionsindepth/Lists.java +++ b/collectiontopics/ListOps.java @@ -1,12 +1,15 @@ -// collectionsindepth/Lists.java -// (c)2016 MindView LLC: see Copyright.txt +// collectiontopics/ListOps.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Things you can do with Lists import java.util.*; -import onjava.*; +import onjava.HTMLColors; -public class Lists { +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; @@ -16,12 +19,12 @@ 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(Countries.names(25)); + a.addAll(LIST); // Add a collection starting at location 3: - a.addAll(3, Countries.names(25)); + a.addAll(3, LIST); b = a.contains("1"); // Is it in there? // Is the entire collection in there? - b = a.containsAll(Countries.names(25)); + 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 @@ -29,16 +32,16 @@ public static void basicTest(List a) { b = a.isEmpty(); // Any elements inside? it = a.iterator(); // Ordinary Iterator lit = a.listIterator(); // ListIterator - lit = a.listIterator(3); // Start at loc 3 + 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(Countries.names(25)); + a.retainAll(LIST); // Remove everything that's in the argument: - a.removeAll(Countries.names(25)); + a.removeAll(LIST); i = a.size(); // How big is it? a.clear(); // Remove all elements } @@ -56,7 +59,7 @@ public static void iterManipulation(List a) { it.add("47"); // Must move to an element after add(): it.next(); - // Remove the element after the newly produced one: + // Remove the element after the new one: it.remove(); // Must move to an element after remove(): it.next(); @@ -65,14 +68,15 @@ public static void iterManipulation(List a) { } public static void testVisual(List a) { System.out.println(a); - List b = Countries.names(25); + 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); + ListIterator x = + a.listIterator(a.size()/2); x.add("one"); System.out.println(a); System.out.println(x.next()); @@ -90,7 +94,7 @@ public static void testVisual(List a) { // There are some things that only LinkedLists can do: public static void testLinkedList() { LinkedList ll = new LinkedList<>(); - ll.addAll(Countries.names(25)); + ll.addAll(LIST); System.out.println(ll); // Treat it like a stack, pushing: ll.addFirst("one"); @@ -108,39 +112,56 @@ public static void testLinkedList() { } public static void main(String[] args) { // Make and fill a new list each time: - basicTest( - new LinkedList<>(Countries.names(25))); - basicTest( - new ArrayList<>(Countries.names(25))); - iterMotion( - new LinkedList<>(Countries.names(25))); - iterMotion( - new ArrayList<>(Countries.names(25))); - iterManipulation( - new LinkedList<>(Countries.names(25))); - iterManipulation( - new ArrayList<>(Countries.names(25))); - testVisual( - new LinkedList<>(Countries.names(25))); + 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: (First and last 2 Lines) -[ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, BURUNDI, -CAMEROON, CAPE VERDE, CENTRAL AFRICAN REPUBLIC, CHAD, -COMOROS, CONGO, DJIBOUTI, EGYPT, EQUATORIAL GUINEA, -ERITREA, ETHIOPIA, GABON, THE GAMBIA, GHANA, GUINEA, -BISSAU, COTE D'IVOIR (IVORY COAST), KENYA, LESOTHO] -b = [ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, -BURUNDI, CAMEROON, CAPE VERDE, CENTRAL AFRICAN REPUBLIC, -CHAD, COMOROS, CONGO, DJIBOUTI, EGYPT, EQUATORIAL GUINEA, -ERITREA, ETHIOPIA, GABON, THE GAMBIA, GHANA, GUINEA, -BISSAU, COTE D'IVOIR (IVORY COAST), KENYA, LESOTHO] -________...________...________...________...________ -LESOTHO -[ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, BURUNDI, -CAMEROON, CAPE VERDE, CENTRAL AFRICAN REPUBLIC, CHAD, -COMOROS, CONGO, DJIBOUTI, EGYPT, EQUATORIAL GUINEA, -ERITREA, ETHIOPIA, GABON, THE GAMBIA, GHANA, GUINEA, -BISSAU, COTE D'IVOIR (IVORY COAST), KENYA] +/* 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/collectionsindepth/ListSortSearch.java b/collectiontopics/ListSortSearch.java similarity index 61% rename from collectionsindepth/ListSortSearch.java rename to collectiontopics/ListSortSearch.java index 5811de417..2f2ca2d7e 100644 --- a/collectionsindepth/ListSortSearch.java +++ b/collectiontopics/ListSortSearch.java @@ -1,8 +1,8 @@ -// collectionsindepth/ListSortSearch.java -// (c)2016 MindView LLC: see Copyright.txt +// collectiontopics/ListSortSearch.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Sorting and searching Lists with Collections utilities +// Visit http://OnJava8.com for more book information. +// Sorting/searching Lists with Collections utilities import java.util.*; public class ListSortSearch { @@ -13,9 +13,9 @@ public static void main(String[] args) { System.out.println(list); Collections.shuffle(list, new Random(47)); System.out.println("Shuffled: " + list); - // Use a ListIterator to trim off the last elements: - ListIterator it = list.listIterator(10); - while(it.hasNext()) { + ListIterator it = + list.listIterator(10); // [1] + while(it.hasNext()) { // [2] it.next(); it.remove(); } @@ -26,8 +26,10 @@ public static void main(String[] args) { 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); + ", list.get(" + index + ") = " + + list.get(index)); + Collections.sort(list, + String.CASE_INSENSITIVE_ORDER); System.out.println( "Case-insensitive sorted: " + list); key = list.get(7); @@ -35,20 +37,21 @@ public static void main(String[] args) { String.CASE_INSENSITIVE_ORDER); System.out.println( "Location of " + key + " is " + index + - ", list.get(" + index + ") = " + list.get(index)); + ", list.get(" + index + ") = " + + list.get(index)); } } /* Output: -[one, Two, three, Four, five, six, one, one, Two, three, -Four, five, six, one] +[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] +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] +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/collectionsindepth/Maps.java b/collectiontopics/MapOps.java similarity index 59% rename from collectionsindepth/Maps.java rename to collectiontopics/MapOps.java index 1f568878d..6b6458bb2 100644 --- a/collectionsindepth/Maps.java +++ b/collectiontopics/MapOps.java @@ -1,32 +1,36 @@ -// collectionsindepth/Maps.java -// (c)2016 MindView LLC: see Copyright.txt +// collectiontopics/MapOps.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 Maps { - public static void printKeys(Map map) { +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 CountingFilledMap(25)); + 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 CountingFilledMap(25)); + 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.containsKey(11): " + map.containsKey(11)); - System.out.println("map.get(11): " + map.get(11)); + "map.get(11): " + map.get(11)); System.out.println("map.containsValue(\"F0\"): " + map.containsValue("F0")); Integer key = map.keySet().iterator().next(); @@ -34,11 +38,13 @@ public static void test(Map map) { map.remove(key); printKeys(map); map.clear(); - System.out.println("map.isEmpty(): " + map.isEmpty()); - map.putAll(new CountingFilledMap(25)); + 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()); + System.out.println( + "map.isEmpty(): " + map.isEmpty()); } public static void main(String[] args) { test(new HashMap<>()); @@ -51,10 +57,10 @@ public static void main(String[] args) { } /* 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] +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} @@ -62,8 +68,8 @@ public static void main(String[] args) { 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] +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/collectiontopics/NavMap.java b/collectiontopics/NavMap.java new file mode 100644 index 000000000..2d898268b --- /dev/null +++ b/collectiontopics/NavMap.java @@ -0,0 +1,96 @@ +// collectiontopics/NavMap.java +// (c)2021 MindView 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/collectiontopics/QueueBehavior.java b/collectiontopics/QueueBehavior.java new file mode 100644 index 000000000..16f7582e2 --- /dev/null +++ b/collectiontopics/QueueBehavior.java @@ -0,0 +1,50 @@ +// collectiontopics/QueueBehavior.java +// (c)2021 MindView 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().forEach(queue::offer); + 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/collectionsindepth/ReadOnly.java b/collectiontopics/ReadOnly.java similarity index 73% rename from collectionsindepth/ReadOnly.java rename to collectiontopics/ReadOnly.java index d8fc78511..547c32a5f 100644 --- a/collectionsindepth/ReadOnly.java +++ b/collectiontopics/ReadOnly.java @@ -1,7 +1,7 @@ -// collectionsindepth/ReadOnly.java -// (c)2016 MindView LLC: see Copyright.txt +// collectiontopics/ReadOnly.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Using the Collections.unmodifiable methods import java.util.*; import onjava.*; @@ -28,11 +28,13 @@ public static void main(String[] args) { //- s.add("one"); // Can't change it // For a SortedSet: - Set ss = Collections.unmodifiableSortedSet( - new TreeSet<>(data)); + Set ss = + Collections.unmodifiableSortedSet( + new TreeSet<>(data)); - Map m = Collections.unmodifiableMap( - new HashMap<>(Countries.capitals(6))); + Map m = + Collections.unmodifiableMap( + new HashMap<>(Countries.capitals(6))); System.out.println(m); // Reading is OK //- m.put("Ralph", "Howdy!"); @@ -43,9 +45,11 @@ public static void main(String[] args) { } } /* Output: -[ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, BURUNDI] +[ALGERIA, ANGOLA, BENIN, BOTSWANA, BURKINA FASO, +BURUNDI] ALGERIA -[BENIN, BOTSWANA, ANGOLA, BURKINA FASO, ALGERIA, BURUNDI] +[BENIN, BOTSWANA, ANGOLA, BURKINA FASO, ALGERIA, +BURUNDI] {BENIN=Porto-Novo, BOTSWANA=Gaberone, ANGOLA=Luanda, BURKINA FASO=Ouagadougou, ALGERIA=Algiers, BURUNDI=Bujumbura} diff --git a/collectionsindepth/References.java b/collectiontopics/References.java similarity index 78% rename from collectionsindepth/References.java rename to collectiontopics/References.java index 55fd3d1b8..798e8f31e 100644 --- a/collectionsindepth/References.java +++ b/collectiontopics/References.java @@ -1,7 +1,7 @@ -// collectionsindepth/References.java -// (c)2016 MindView LLC: see Copyright.txt +// collectiontopics/References.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Demonstrates Reference objects import java.lang.ref.*; import java.util.*; @@ -10,11 +10,10 @@ class VeryBig { private static final int SIZE = 10000; private long[] la = new long[SIZE]; private String ident; - public VeryBig(String id) { ident = id; } - @Override - public String toString() { return ident; } - @Override - protected void finalize() { + VeryBig(String id) { ident = id; } + @Override public String toString() { return ident; } + @SuppressWarnings("deprecation") + @Override protected void finalize() { System.out.println("Finalizing " + ident); } } @@ -31,13 +30,14 @@ public static void main(String[] args) { int size = 10; // Or, choose size via the command line: if(args.length > 0) - size = new Integer(args[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()); + System.out.println( + "Just created: " + sa.getLast()); checkQueue(); } LinkedList> wa = @@ -45,7 +45,8 @@ public static void main(String[] args) { for(int i = 0; i < size; i++) { wa.add(new WeakReference<>( new VeryBig("Weak " + i), rq)); - System.out.println("Just created: " + wa.getLast()); + System.out.println( + "Just created: " + wa.getLast()); checkQueue(); } SoftReference s = @@ -58,12 +59,13 @@ public static void main(String[] args) { for(int i = 0; i < size; i++) { pa.add(new PhantomReference<>( new VeryBig("Phantom " + i), rq)); - System.out.println("Just created: " + pa.getLast()); + System.out.println( + "Just created: " + pa.getLast()); checkQueue(); } } } -/* Output: (First and last 10 Lines) +/* Output: (First and Last 10 Lines) Just created: java.lang.ref.SoftReference@19e0bfd Just created: java.lang.ref.SoftReference@139a55 Just created: java.lang.ref.SoftReference@1db9742 @@ -74,7 +76,7 @@ public static void main(String[] args) { Just created: java.lang.ref.SoftReference@647e05 Just created: java.lang.ref.SoftReference@1909752 Just created: java.lang.ref.SoftReference@1f96302 -________...________...________...________...________ +...________...________...________...________... Just created: java.lang.ref.PhantomReference@16f6e28 In queue: null Just created: java.lang.ref.PhantomReference@15fbaa4 diff --git a/collectiontopics/SetOrder.java b/collectiontopics/SetOrder.java new file mode 100644 index 000000000..b167a7c72 --- /dev/null +++ b/collectiontopics/SetOrder.java @@ -0,0 +1,92 @@ +// collectiontopics/SetOrder.java +// (c)2021 MindView LLC: see Copyright.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") + Set set = (Set) + Class.forName(type).getConstructor().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/collectiontopics/SimpleDeques.java b/collectiontopics/SimpleDeques.java new file mode 100644 index 000000000..811c43daa --- /dev/null +++ b/collectiontopics/SimpleDeques.java @@ -0,0 +1,69 @@ +// collectiontopics/SimpleDeques.java +// (c)2021 MindView 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/collectionsindepth/SortedMapDemo.java b/collectiontopics/SortedMapDemo.java similarity index 78% rename from collectionsindepth/SortedMapDemo.java rename to collectiontopics/SortedMapDemo.java index 681c8866c..5601aca04 100644 --- a/collectionsindepth/SortedMapDemo.java +++ b/collectiontopics/SortedMapDemo.java @@ -1,7 +1,7 @@ -// collectionsindepth/SortedMapDemo.java -// (c)2016 MindView LLC: see Copyright.txt +// collectiontopics/SortedMapDemo.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // What you can do with a TreeMap import java.util.*; import onjava.*; @@ -9,13 +9,14 @@ public class SortedMapDemo { public static void main(String[] args) { TreeMap sortedMap = - new TreeMap<>(new CountingFilledMap(10)); + 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(); + Iterator it = + sortedMap.keySet().iterator(); for(int i = 0; i <= 6; i++) { if(i == 3) low = it.next(); if(i == 6) high = it.next(); diff --git a/collectionsindepth/SortedSetDemo.java b/collectiontopics/SortedSetDemo.java similarity index 71% rename from collectionsindepth/SortedSetDemo.java rename to collectiontopics/SortedSetDemo.java index 6dad6425f..91a9b3a54 100644 --- a/collectionsindepth/SortedSetDemo.java +++ b/collectiontopics/SortedSetDemo.java @@ -1,16 +1,17 @@ -// collectionsindepth/SortedSetDemo.java -// (c)2016 MindView LLC: see Copyright.txt +// collectiontopics/SortedSetDemo.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// What you can do with a TreeSet +// 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 = new TreeSet<>(); - Collections.addAll(sortedSet, - "one two three four five six seven eight" - .split(" ")); + SortedSet sortedSet = + Arrays.stream( + "one two three four five six seven eight" + .split(" ")) + .collect(toCollection(TreeSet::new)); System.out.println(sortedSet); String low = sortedSet.first(); String high = sortedSet.last(); diff --git a/collectionsindepth/Stacks.java b/collectiontopics/Stacks.java similarity index 60% rename from collectionsindepth/Stacks.java rename to collectiontopics/Stacks.java index 0c12efae8..a9d306ed3 100644 --- a/collectionsindepth/Stacks.java +++ b/collectiontopics/Stacks.java @@ -1,12 +1,13 @@ -// collectionsindepth/Stacks.java -// (c)2016 MindView LLC: see Copyright.txt +// collectiontopics/Stacks.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 } +enum Month { JANUARY, FEBRUARY, MARCH, APRIL, + MAY, JUNE, JULY, AUGUST, SEPTEMBER, + OCTOBER, NOVEMBER } public class Stacks { public static void main(String[] args) { @@ -37,23 +38,24 @@ public static void main(String[] args) { for(Month m : Month.values()) stack2.push(m.toString()); System.out.println("stack2 = " + stack2); - while(!stack2.empty()) + while(!stack2.isEmpty()) System.out.print(stack2.pop() + " "); } } /* Output: -stack = [JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, -AUGUST, SEPTEMBER, OCTOBER, NOVEMBER] +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, +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 stack2 = [NOVEMBER, OCTOBER, SEPTEMBER, -AUGUST, JULY, JUNE, MAY, APRIL, MARCH, FEBRUARY, JANUARY] -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/collectiontopics/StreamFillMaps.java b/collectiontopics/StreamFillMaps.java new file mode 100644 index 000000000..6df827332 --- /dev/null +++ b/collectiontopics/StreamFillMaps.java @@ -0,0 +1,54 @@ +// collectiontopics/StreamFillMaps.java +// (c)2021 MindView LLC: see Copyright.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/collectiontopics/SuppliersCollectionTest.java b/collectiontopics/SuppliersCollectionTest.java new file mode 100644 index 000000000..58f810bff --- /dev/null +++ b/collectiontopics/SuppliersCollectionTest.java @@ -0,0 +1,66 @@ +// collectiontopics/SuppliersCollectionTest.java +// (c)2021 MindView LLC: see Copyright.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/collectiontopics/Synchronization.java b/collectiontopics/Synchronization.java new file mode 100644 index 000000000..86389da1c --- /dev/null +++ b/collectiontopics/Synchronization.java @@ -0,0 +1,24 @@ +// collectiontopics/Synchronization.java +// (c)2021 MindView 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/collectiontopics/ToDoList.java b/collectiontopics/ToDoList.java new file mode 100644 index 000000000..2be266eeb --- /dev/null +++ b/collectiontopics/ToDoList.java @@ -0,0 +1,54 @@ +// collectiontopics/ToDoList.java +// (c)2021 MindView 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/collectiontopics/TypesForSets.java b/collectiontopics/TypesForSets.java new file mode 100644 index 000000000..e4c745879 --- /dev/null +++ b/collectiontopics/TypesForSets.java @@ -0,0 +1,89 @@ +// collectiontopics/TypesForSets.java +// (c)2021 MindView 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] +[4, 1, 5, 1, 0, 5, 6, 8, 7, 0, 2, 8, 4, 9, 6, 10, 6, 7, +2, 9, 10, 3, 8, 4, 10, 3, 9, 5, 3, 7, 1, 2, 0] +[9, 8, 4, 8, 5, 0, 1, 6, 2, 9, 3, 7, 2, 2, 7, 0, 9, 5, +5, 6, 4, 7, 10, 1, 6, 4, 1, 10, 3, 3, 0, 10, 8] +[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/collectionsindepth/Unsupported.java b/collectiontopics/Unsupported.java similarity index 63% rename from collectionsindepth/Unsupported.java rename to collectiontopics/Unsupported.java index 18e52cc1d..132b760c4 100644 --- a/collectionsindepth/Unsupported.java +++ b/collectiontopics/Unsupported.java @@ -1,46 +1,38 @@ -// collectionsindepth/Unsupported.java -// (c)2016 MindView LLC: see Copyright.txt +// collectiontopics/Unsupported.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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); - try { c.retainAll(c2); } catch(Exception e) { - System.out.println("retainAll(): " + e); - } - try { c.removeAll(c2); } catch(Exception e) { - System.out.println("removeAll(): " + e); - } - try { c.clear(); } catch(Exception e) { - System.out.println("clear(): " + e); - } - try { c.add("X"); } catch(Exception e) { - System.out.println("add(): " + e); - } - try { c.addAll(c2); } catch(Exception e) { - System.out.println("addAll(): " + e); - } - try { c.remove("C"); } catch(Exception e) { - System.out.println("remove(): " + e); - } + 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: - try { - list.set(0, "X"); - } catch(Exception e) { - System.out.println("List.set(): " + e); - } + 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(" ")); + 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()", diff --git a/collectionsindepth/Utilities.java b/collectiontopics/Utilities.java similarity index 87% rename from collectionsindepth/Utilities.java rename to collectiontopics/Utilities.java index 2c45de60b..0b7b0f9a0 100644 --- a/collectionsindepth/Utilities.java +++ b/collectiontopics/Utilities.java @@ -1,7 +1,7 @@ -// collectionsindepth/Utilities.java -// (c)2016 MindView LLC: see Copyright.txt +// collectiontopics/Utilities.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Simple demonstrations of the Collections utilities import java.util.*; @@ -13,8 +13,10 @@ public static void main(String[] args) { 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: " + Collections.max(list)); + System.out.println( + "min: " + Collections.min(list)); System.out.println( "max w/ comparator: " + Collections.max(list, String.CASE_INSENSITIVE_ORDER)); @@ -45,12 +47,14 @@ public static void main(String[] args) { System.out.println("fill: " + list); System.out.println("frequency of 'pop': " + Collections.frequency(list, "pop")); - List dups = Collections.nCopies(3, "snap"); + 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); + Enumeration e = + Collections.enumeration(dups); Vector v = new Vector<>(); while(e.hasMoreElements()) v.addElement(e.nextElement()); diff --git a/com/build.xml b/com/build.xml deleted file mode 100644 index 1dc933bba..000000000 --- a/com/build.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/com/mindviewinc/simple/List.java b/com/mindviewinc/simple/List.java index 8f9d5787b..2b1131a03 100644 --- a/com/mindviewinc/simple/List.java +++ b/com/mindviewinc/simple/List.java @@ -1,7 +1,7 @@ // com/mindviewinc/simple/List.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Creating a package package com.mindviewinc.simple; diff --git a/com/mindviewinc/simple/Vector.java b/com/mindviewinc/simple/Vector.java index 086b13392..af63e03c7 100644 --- a/com/mindviewinc/simple/Vector.java +++ b/com/mindviewinc/simple/Vector.java @@ -1,7 +1,7 @@ // com/mindviewinc/simple/Vector.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Creating a package package com.mindviewinc.simple; diff --git a/compression/GZIPcompress.java b/compression/GZIPcompress.java index b313a3ffa..1b847c57b 100644 --- a/compression/GZIPcompress.java +++ b/compression/GZIPcompress.java @@ -1,14 +1,14 @@ // compression/GZIPcompress.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {Args: GZIPcompress.java} +// 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) throws IOException { + public static void main(String[] args) { if(args.length == 0) { System.out.println( "Usage: \nGZIPcompress file\n" + @@ -16,25 +16,30 @@ public class GZIPcompress { "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")))) { + 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"))))) { - String s; - while((s = in2.readLine()) != null) - System.out.println(s); + 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); } } } -/* Output: (Execute to see) */ diff --git a/compression/ZipCompress.java b/compression/ZipCompress.java index 12fe04393..532316029 100644 --- a/compression/ZipCompress.java +++ b/compression/ZipCompress.java @@ -1,30 +1,34 @@ // compression/ZipCompress.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Uses Zip compression to compress any // number of files given on the command line -// {Args: ZipCompress.java} +// {java ZipCompress ZipCompress.java} +// {VisuallyInspectOutput} import java.util.zip.*; import java.io.*; import java.util.*; public class ZipCompress { - public static void - main(String[] args) throws IOException { - try(FileOutputStream f = - new FileOutputStream("test.zip"); - CheckedOutputStream csum = - new CheckedOutputStream(f, new Adler32()); - ZipOutputStream zos = new ZipOutputStream(csum); - BufferedOutputStream out = - new BufferedOutputStream(zos)) { + 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))) { + try( + InputStream in = new BufferedInputStream( + new FileInputStream(arg)) + ) { zos.putNextEntry(new ZipEntry(arg)); int c; while((c = in.read()) != -1) @@ -35,16 +39,20 @@ public class ZipCompress { // 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)) { + 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); @@ -55,16 +63,21 @@ public class ZipCompress { 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")) { + 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); } } } -/* Output: (Execute to see) */ diff --git a/compression/build.xml b/compression/build.xml deleted file mode 100644 index 5659b0998..000000000 --- a/compression/build.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/concurrent/Baked.java b/concurrent/Baked.java new file mode 100644 index 000000000..105a887d5 --- /dev/null +++ b/concurrent/Baked.java @@ -0,0 +1,31 @@ +// concurrent/Baked.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/Batter.java b/concurrent/Batter.java new file mode 100644 index 000000000..80a9022a3 --- /dev/null +++ b/concurrent/Batter.java @@ -0,0 +1,34 @@ +// concurrent/Batter.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/Breakable.java b/concurrent/Breakable.java new file mode 100644 index 000000000..0fcacb383 --- /dev/null +++ b/concurrent/Breakable.java @@ -0,0 +1,28 @@ +// concurrent/Breakable.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/CachedThreadPool.java b/concurrent/CachedThreadPool.java new file mode 100644 index 000000000..11b6bad3a --- /dev/null +++ b/concurrent/CachedThreadPool.java @@ -0,0 +1,29 @@ +// concurrent/CachedThreadPool.java +// (c)2021 MindView LLC: see Copyright.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[1] pool-1-thread-2 +NapTask[5] pool-1-thread-6 +NapTask[4] pool-1-thread-5 +NapTask[8] pool-1-thread-9 +NapTask[0] pool-1-thread-1 +NapTask[9] pool-1-thread-10 +NapTask[2] pool-1-thread-3 +NapTask[3] pool-1-thread-4 +NapTask[6] pool-1-thread-7 +NapTask[7] pool-1-thread-8 +*/ diff --git a/concurrent/CachedThreadPool2.java b/concurrent/CachedThreadPool2.java new file mode 100644 index 000000000..091241e57 --- /dev/null +++ b/concurrent/CachedThreadPool2.java @@ -0,0 +1,29 @@ +// concurrent/CachedThreadPool2.java +// (c)2021 MindView LLC: see Copyright.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: +3 pool-1-thread-4 100 +2 pool-1-thread-3 200 +6 pool-1-thread-7 300 +7 pool-1-thread-8 400 +0 pool-1-thread-1 514 +1 pool-1-thread-2 527 +4 pool-1-thread-5 627 +5 pool-1-thread-6 727 +9 pool-1-thread-10 827 +8 pool-1-thread-9 927 +*/ diff --git a/concurrent/CachedThreadPool3.java b/concurrent/CachedThreadPool3.java new file mode 100644 index 000000000..919c3c130 --- /dev/null +++ b/concurrent/CachedThreadPool3.java @@ -0,0 +1,47 @@ +// concurrent/CachedThreadPool3.java +// (c)2021 MindView LLC: see Copyright.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: +0 pool-1-thread-1 100 +9 pool-1-thread-1 100 +1 pool-1-thread-2 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 +4 pool-1-thread-5 100 +5 pool-1-thread-6 100 +8 pool-1-thread-9 100 +sum = 1000 +*/ diff --git a/concurrent/CatchCompletableExceptions.java b/concurrent/CatchCompletableExceptions.java new file mode 100644 index 000000000..5c9bcd610 --- /dev/null +++ b/concurrent/CatchCompletableExceptions.java @@ -0,0 +1,81 @@ +// concurrent/CatchCompletableExceptions.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/CollectionIntoStream.java b/concurrent/CollectionIntoStream.java new file mode 100644 index 000000000..4e2f5b3c8 --- /dev/null +++ b/concurrent/CollectionIntoStream.java @@ -0,0 +1,36 @@ +// concurrent/CollectionIntoStream.java +// (c)2021 MindView LLC: 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/concurrent/CompletableApply.java b/concurrent/CompletableApply.java new file mode 100644 index 000000000..aeac0e25e --- /dev/null +++ b/concurrent/CompletableApply.java @@ -0,0 +1,27 @@ +// concurrent/CompletableApply.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/CompletableApplyAsync.java b/concurrent/CompletableApplyAsync.java new file mode 100644 index 000000000..974d99ffe --- /dev/null +++ b/concurrent/CompletableApplyAsync.java @@ -0,0 +1,31 @@ +// concurrent/CompletableApplyAsync.java +// (c)2021 MindView LLC: see Copyright.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: +103 +Machina0: ONE +Machina0: TWO +Machina0: THREE +Machina0: complete +Machina0: complete +545 +*/ diff --git a/concurrent/CompletableApplyChained.java b/concurrent/CompletableApplyChained.java new file mode 100644 index 000000000..6194bc5d8 --- /dev/null +++ b/concurrent/CompletableApplyChained.java @@ -0,0 +1,27 @@ +// concurrent/CompletableApplyChained.java +// (c)2021 MindView LLC: see Copyright.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 +521 +*/ diff --git a/concurrent/CompletableExceptions.java b/concurrent/CompletableExceptions.java new file mode 100644 index 000000000..341a0afc6 --- /dev/null +++ b/concurrent/CompletableExceptions.java @@ -0,0 +1,75 @@ +// concurrent/CompletableExceptions.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/CompletableOperations.java b/concurrent/CompletableOperations.java new file mode 100644 index 000000000..6def117f4 --- /dev/null +++ b/concurrent/CompletableOperations.java @@ -0,0 +1,74 @@ +// concurrent/CompletableOperations.java +// (c)2021 MindView LLC: see Copyright.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@1629346[Complete +d exceptionally] +777 +dependents: 1 +dependents: 2 +*/ diff --git a/concurrent/CompletablePizza.java b/concurrent/CompletablePizza.java new file mode 100644 index 000000000..7003f7d29 --- /dev/null +++ b/concurrent/CompletablePizza.java @@ -0,0 +1,87 @@ +// concurrent/CompletablePizza.java +// (c)2021 MindView LLC: see Copyright.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: +98 +Pizza 1: ROLLED +Pizza 3: ROLLED +Pizza 4: ROLLED +Pizza 2: ROLLED +Pizza 0: ROLLED +Pizza 1: SAUCED +Pizza 2: SAUCED +Pizza 3: SAUCED +Pizza 0: SAUCED +Pizza 4: SAUCED +Pizza 2: CHEESED +Pizza 0: CHEESED +Pizza 3: CHEESED +Pizza 1: CHEESED +Pizza 4: CHEESED +Pizza 2: TOPPED +Pizza 4: TOPPED +Pizza 1: TOPPED +Pizza 3: TOPPED +Pizza 0: TOPPED +Pizza 0: BAKED +Pizza 4: BAKED +Pizza 1: BAKED +Pizza 3: BAKED +Pizza 2: BAKED +Pizza 3: SLICED +Pizza 1: SLICED +Pizza 2: SLICED +Pizza 4: SLICED +Pizza 0: SLICED +Pizza 0: BOXED +Pizza 2: BOXED +Pizza 4: BOXED +Pizza 1: BOXED +Pizza0: complete +Pizza1: complete +Pizza2: complete +Pizza 3: BOXED +Pizza3: complete +Pizza4: complete +1762 +*/ diff --git a/concurrent/CompletableUtilities.java b/concurrent/CompletableUtilities.java new file mode 100644 index 000000000..e1099d6b8 --- /dev/null +++ b/concurrent/CompletableUtilities.java @@ -0,0 +1,27 @@ +// concurrent/CompletableUtilities.java +// (c)2021 MindView 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/concurrent/CompletedMachina.java b/concurrent/CompletedMachina.java new file mode 100644 index 000000000..d6684e962 --- /dev/null +++ b/concurrent/CompletedMachina.java @@ -0,0 +1,19 @@ +// concurrent/CompletedMachina.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/CountingStream.java b/concurrent/CountingStream.java new file mode 100644 index 000000000..47a1a77fb --- /dev/null +++ b/concurrent/CountingStream.java @@ -0,0 +1,32 @@ +// concurrent/CountingStream.java +// (c)2021 MindView 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/concurrent/CountingTask.java b/concurrent/CountingTask.java new file mode 100644 index 000000000..140adfed9 --- /dev/null +++ b/concurrent/CountingTask.java @@ -0,0 +1,18 @@ +// concurrent/CountingTask.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/DiningPhilosophers.java b/concurrent/DiningPhilosophers.java new file mode 100644 index 000000000..8b54820a1 --- /dev/null +++ b/concurrent/DiningPhilosophers.java @@ -0,0 +1,33 @@ +// concurrent/DiningPhilosophers.java +// (c)2021 MindView 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/concurrent/DualCompletableOperations.java b/concurrent/DualCompletableOperations.java new file mode 100644 index 000000000..dd7048d91 --- /dev/null +++ b/concurrent/DualCompletableOperations.java @@ -0,0 +1,115 @@ +// concurrent/DualCompletableOperations.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/FrostedCake.java b/concurrent/FrostedCake.java new file mode 100644 index 000000000..77a15fcfe --- /dev/null +++ b/concurrent/FrostedCake.java @@ -0,0 +1,33 @@ +// concurrent/FrostedCake.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/Futures.java b/concurrent/Futures.java new file mode 100644 index 000000000..55bb483cb --- /dev/null +++ b/concurrent/Futures.java @@ -0,0 +1,23 @@ +// concurrent/Futures.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/GuardedIDField.java b/concurrent/GuardedIDField.java new file mode 100644 index 000000000..8dd2ddd29 --- /dev/null +++ b/concurrent/GuardedIDField.java @@ -0,0 +1,18 @@ +// concurrent/GuardedIDField.java +// (c)2021 MindView LLC: see Copyright.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(); + @Override public int getID() { return id; } + public static void main(String[] args) { + IDChecker.test(GuardedIDField::new); + } +} +/* Output: +0 +*/ diff --git a/concurrent/HasID.java b/concurrent/HasID.java new file mode 100644 index 000000000..a9734e39f --- /dev/null +++ b/concurrent/HasID.java @@ -0,0 +1,8 @@ +// concurrent/HasID.java +// (c)2021 MindView 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/concurrent/IDChecker.java b/concurrent/IDChecker.java new file mode 100644 index 000000000..31c45ef66 --- /dev/null +++ b/concurrent/IDChecker.java @@ -0,0 +1,40 @@ +// concurrent/IDChecker.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/InterferingTask.java b/concurrent/InterferingTask.java new file mode 100644 index 000000000..8715741b8 --- /dev/null +++ b/concurrent/InterferingTask.java @@ -0,0 +1,16 @@ +// concurrent/InterferingTask.java +// (c)2021 MindView 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/concurrent/LambdasAndMethodReferences.java b/concurrent/LambdasAndMethodReferences.java new file mode 100644 index 000000000..cb124b6b7 --- /dev/null +++ b/concurrent/LambdasAndMethodReferences.java @@ -0,0 +1,40 @@ +// concurrent/LambdasAndMethodReferences.java +// (c)2021 MindView LLC: see Copyright.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 +NotRunnable +Lambda2 +NotCallable +*/ diff --git a/concurrent/Machina.java b/concurrent/Machina.java new file mode 100644 index 000000000..57175c267 --- /dev/null +++ b/concurrent/Machina.java @@ -0,0 +1,30 @@ +// concurrent/Machina.java +// (c)2021 MindView LLC: 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/concurrent/MoreTasksAfterShutdown.java b/concurrent/MoreTasksAfterShutdown.java new file mode 100644 index 000000000..31a142e16 --- /dev/null +++ b/concurrent/MoreTasksAfterShutdown.java @@ -0,0 +1,26 @@ +// concurrent/MoreTasksAfterShutdown.java +// (c)2021 MindView LLC: see Copyright.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@106d69c[Shutting down, pool size = 1, active +threads = 1, queued tasks = 0, completed tasks = 0] +NapTask[1] pool-1-thread-1 +*/ diff --git a/concurrent/NapTask.java b/concurrent/NapTask.java new file mode 100644 index 000000000..9206eb4e8 --- /dev/null +++ b/concurrent/NapTask.java @@ -0,0 +1,18 @@ +// concurrent/NapTask.java +// (c)2021 MindView LLC: 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/concurrent/OnePizza.java b/concurrent/OnePizza.java new file mode 100644 index 000000000..b8298ebbc --- /dev/null +++ b/concurrent/OnePizza.java @@ -0,0 +1,26 @@ +// concurrent/OnePizza.java +// (c)2021 MindView LLC: 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 +1665 +*/ diff --git a/concurrent/ParallelPrime.java b/concurrent/ParallelPrime.java new file mode 100644 index 000000000..84ed969db --- /dev/null +++ b/concurrent/ParallelPrime.java @@ -0,0 +1,35 @@ +// concurrent/ParallelPrime.java +// (c)2021 MindView LLC: see Copyright.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: +1635 +*/ diff --git a/concurrent/ParallelStreamPuzzle.java b/concurrent/ParallelStreamPuzzle.java new file mode 100644 index 000000000..0993d7b91 --- /dev/null +++ b/concurrent/ParallelStreamPuzzle.java @@ -0,0 +1,28 @@ +// concurrent/ParallelStreamPuzzle.java +// (c)2021 MindView LLC: see Copyright.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; + @Override 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/concurrent/ParallelStreamPuzzle2.java b/concurrent/ParallelStreamPuzzle2.java new file mode 100644 index 000000000..ff8b5ed15 --- /dev/null +++ b/concurrent/ParallelStreamPuzzle2.java @@ -0,0 +1,38 @@ +// concurrent/ParallelStreamPuzzle2.java +// (c)2021 MindView LLC: see Copyright.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(); + @Override 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: +[1, 5, 7, 8, 9, 11, 13, 15, 18, 21] +*/ diff --git a/concurrent/ParallelStreamPuzzle3.java b/concurrent/ParallelStreamPuzzle3.java new file mode 100644 index 000000000..69a35618f --- /dev/null +++ b/concurrent/ParallelStreamPuzzle3.java @@ -0,0 +1,33 @@ +// concurrent/ParallelStreamPuzzle3.java +// (c)2021 MindView 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/concurrent/Philosopher.java b/concurrent/Philosopher.java new file mode 100644 index 000000000..7fa356846 --- /dev/null +++ b/concurrent/Philosopher.java @@ -0,0 +1,28 @@ +// concurrent/Philosopher.java +// (c)2021 MindView 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/concurrent/Pizza.java b/concurrent/Pizza.java new file mode 100644 index 000000000..6325b930f --- /dev/null +++ b/concurrent/Pizza.java @@ -0,0 +1,48 @@ +// concurrent/Pizza.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/PizzaParallelSteps.java b/concurrent/PizzaParallelSteps.java new file mode 100644 index 000000000..a6ccb3e23 --- /dev/null +++ b/concurrent/PizzaParallelSteps.java @@ -0,0 +1,69 @@ +// concurrent/PizzaParallelSteps.java +// (c)2021 MindView LLC: see Copyright.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 1: ROLLED +Pizza 2: ROLLED +Pizza 0: ROLLED +Pizza 3: ROLLED +Pizza 4: ROLLED +Pizza 4: SAUCED +Pizza 2: SAUCED +Pizza 0: SAUCED +Pizza 1: SAUCED +Pizza 3: SAUCED +Pizza 1: CHEESED +Pizza 3: CHEESED +Pizza 4: CHEESED +Pizza 2: CHEESED +Pizza 0: CHEESED +Pizza 3: TOPPED +Pizza 1: TOPPED +Pizza 0: TOPPED +Pizza 2: TOPPED +Pizza 4: TOPPED +Pizza 2: BAKED +Pizza 3: BAKED +Pizza 1: BAKED +Pizza 0: BAKED +Pizza 4: BAKED +Pizza 3: SLICED +Pizza 1: SLICED +Pizza 2: SLICED +Pizza 0: SLICED +Pizza 4: SLICED +Pizza 3: BOXED +Pizza3: complete +Pizza 1: BOXED +Pizza1: complete +Pizza 2: BOXED +Pizza 0: BOXED +Pizza0: complete +Pizza2: complete +Pizza 4: BOXED +Pizza4: complete +1766 +*/ diff --git a/concurrent/PizzaStreams.java b/concurrent/PizzaStreams.java new file mode 100644 index 000000000..8ec339bee --- /dev/null +++ b/concurrent/PizzaStreams.java @@ -0,0 +1,60 @@ +// concurrent/PizzaStreams.java +// (c)2021 MindView LLC: see Copyright.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 0: ROLLED +Pizza 1: ROLLED +Pizza 2: ROLLED +Pizza 3: ROLLED +Pizza 4: ROLLED +Pizza 1: SAUCED +Pizza 0: SAUCED +Pizza 4: SAUCED +Pizza 2: SAUCED +Pizza 3: SAUCED +Pizza 3: CHEESED +Pizza 2: CHEESED +Pizza 4: CHEESED +Pizza 0: CHEESED +Pizza 1: CHEESED +Pizza 3: TOPPED +Pizza 2: TOPPED +Pizza 4: TOPPED +Pizza 1: TOPPED +Pizza 0: TOPPED +Pizza 4: BAKED +Pizza 2: BAKED +Pizza 3: BAKED +Pizza 0: BAKED +Pizza 1: BAKED +Pizza 4: SLICED +Pizza 3: SLICED +Pizza 2: SLICED +Pizza 0: SLICED +Pizza 1: SLICED +Pizza 2: BOXED +Pizza 4: BOXED +Pizza 3: BOXED +Pizza 1: BOXED +Pizza 0: BOXED +1797 +*/ diff --git a/concurrent/QuittableTask.java b/concurrent/QuittableTask.java new file mode 100644 index 000000000..e2a1bab23 --- /dev/null +++ b/concurrent/QuittableTask.java @@ -0,0 +1,19 @@ +// concurrent/QuittableTask.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/QuittingCompletable.java b/concurrent/QuittingCompletable.java new file mode 100644 index 000000000..7fb9c0fca --- /dev/null +++ b/concurrent/QuittingCompletable.java @@ -0,0 +1,35 @@ +// concurrent/QuittingCompletable.java +// (c)2021 MindView LLC: see Copyright.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: +6 7 5 9 11 12 13 14 15 16 17 18 19 20 21 22 23 10 24 26 +27 28 29 30 31 32 25 33 8 36 37 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 34 110 111 112 113 +114 115 116 117 118 119 120 121 109 123 124 125 126 127 +128 129 130 131 35 132 122 134 133 136 135 138 140 141 +142 143 144 145 146 147 148 149 137 139 3 1 2 4 +*/ diff --git a/concurrent/QuittingTasks.java b/concurrent/QuittingTasks.java new file mode 100644 index 000000000..58618e531 --- /dev/null +++ b/concurrent/QuittingTasks.java @@ -0,0 +1,35 @@ +// concurrent/QuittingTasks.java +// (c)2021 MindView LLC: see Copyright.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: +11 23 20 12 24 16 19 15 35 147 32 27 7 4 28 31 8 83 3 1 +13 9 5 2 6 18 14 17 21 25 22 26 29 30 33 34 37 41 38 46 +45 49 50 53 57 58 54 69 104 112 40 73 74 115 116 70 119 +77 81 56 85 78 82 111 86 90 48 89 36 108 107 44 55 52 +43 60 63 59 64 71 68 67 75 76 72 79 80 84 87 88 66 91 +10 95 65 96 94 92 62 100 61 93 47 39 51 99 103 128 123 +127 124 140 120 139 136 135 143 148 144 105 102 131 101 +132 98 97 149 137 134 42 106 110 109 114 133 113 117 +118 130 129 126 121 125 122 138 141 145 142 146 +*/ diff --git a/concurrent/SharedConstructorArgument.java b/concurrent/SharedConstructorArgument.java new file mode 100644 index 000000000..9746ff761 --- /dev/null +++ b/concurrent/SharedConstructorArgument.java @@ -0,0 +1,43 @@ +// concurrent/SharedConstructorArgument.java +// (c)2021 MindView LLC: see Copyright.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; + @Override public int get() { return i++; } +} + +class Safe implements SharedArg { + private static AtomicInteger counter = + new AtomicInteger(); + @Override 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: +16537 +0 +*/ diff --git a/concurrent/SingleThreadExecutor.java b/concurrent/SingleThreadExecutor.java new file mode 100644 index 000000000..12629d433 --- /dev/null +++ b/concurrent/SingleThreadExecutor.java @@ -0,0 +1,49 @@ +// concurrent/SingleThreadExecutor.java +// (c)2021 MindView LLC: see Copyright.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 +NapTask[2] pool-1-thread-1 +main awaiting termination +NapTask[3] pool-1-thread-1 +main awaiting termination +main awaiting termination +NapTask[4] pool-1-thread-1 +NapTask[5] pool-1-thread-1 +main awaiting termination +NapTask[6] pool-1-thread-1 +main awaiting termination +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/concurrent/SingleThreadExecutor2.java b/concurrent/SingleThreadExecutor2.java new file mode 100644 index 000000000..81657338f --- /dev/null +++ b/concurrent/SingleThreadExecutor2.java @@ -0,0 +1,30 @@ +// concurrent/SingleThreadExecutor2.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/SingleThreadExecutor3.java b/concurrent/SingleThreadExecutor3.java new file mode 100644 index 000000000..d32c667f1 --- /dev/null +++ b/concurrent/SingleThreadExecutor3.java @@ -0,0 +1,30 @@ +// concurrent/SingleThreadExecutor3.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/StaticIDField.java b/concurrent/StaticIDField.java new file mode 100644 index 000000000..deefbb62e --- /dev/null +++ b/concurrent/StaticIDField.java @@ -0,0 +1,10 @@ +// concurrent/StaticIDField.java +// (c)2021 MindView 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++; + @Override public int getID() { return id; } +} diff --git a/concurrent/StickHolder.java b/concurrent/StickHolder.java new file mode 100644 index 000000000..f4f9279ca --- /dev/null +++ b/concurrent/StickHolder.java @@ -0,0 +1,27 @@ +// concurrent/StickHolder.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/StreamExceptions.java b/concurrent/StreamExceptions.java new file mode 100644 index 000000000..e02b42743 --- /dev/null +++ b/concurrent/StreamExceptions.java @@ -0,0 +1,40 @@ +// concurrent/StreamExceptions.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/Summing.java b/concurrent/Summing.java new file mode 100644 index 000000000..ae97efca2 --- /dev/null +++ b/concurrent/Summing.java @@ -0,0 +1,47 @@ +// concurrent/Summing.java +// (c)2021 MindView LLC: see Copyright.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: 841ms +Sum Stream Parallel: 179ms +Sum Iterated: 4051ms +*/ diff --git a/concurrent/Summing2.java b/concurrent/Summing2.java new file mode 100644 index 000000000..257a53138 --- /dev/null +++ b/concurrent/Summing2.java @@ -0,0 +1,44 @@ +// concurrent/Summing2.java +// (c)2021 MindView 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: 166ms +Parallel: 30ms +Basic Sum: 45ms +parallelPrefix: 53ms +*/ diff --git a/concurrent/Summing3.java b/concurrent/Summing3.java new file mode 100644 index 000000000..3af34db21 --- /dev/null +++ b/concurrent/Summing3.java @@ -0,0 +1,42 @@ +// concurrent/Summing3.java +// (c)2021 MindView 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: 1510ms +Long Basic Sum: 35ms +Long parallelPrefix: 4306ms +*/ diff --git a/concurrent/Summing4.java b/concurrent/Summing4.java new file mode 100644 index 000000000..03dc04ba0 --- /dev/null +++ b/concurrent/Summing4.java @@ -0,0 +1,23 @@ +// concurrent/Summing4.java +// (c)2021 MindView 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: 1147ms +*/ diff --git a/concurrent/SynchronizedConstructor.java b/concurrent/SynchronizedConstructor.java new file mode 100644 index 000000000..092c9733b --- /dev/null +++ b/concurrent/SynchronizedConstructor.java @@ -0,0 +1,28 @@ +// concurrent/SynchronizedConstructor.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/SynchronizedFactory.java b/concurrent/SynchronizedFactory.java new file mode 100644 index 000000000..11e5f184b --- /dev/null +++ b/concurrent/SynchronizedFactory.java @@ -0,0 +1,28 @@ +// concurrent/SynchronizedFactory.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/TestStaticIDField.java b/concurrent/TestStaticIDField.java new file mode 100644 index 000000000..6f10da7cf --- /dev/null +++ b/concurrent/TestStaticIDField.java @@ -0,0 +1,13 @@ +// concurrent/TestStaticIDField.java +// (c)2021 MindView 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: +21397 +*/ diff --git a/concurrent/ThrowsChecked.java b/concurrent/ThrowsChecked.java new file mode 100644 index 000000000..f198cc6c0 --- /dev/null +++ b/concurrent/ThrowsChecked.java @@ -0,0 +1,42 @@ +// concurrent/ThrowsChecked.java +// (c)2021 MindView LLC: see Copyright.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/concurrent/Workable.java b/concurrent/Workable.java new file mode 100644 index 000000000..ada83c2f6 --- /dev/null +++ b/concurrent/Workable.java @@ -0,0 +1,31 @@ +// concurrent/Workable.java +// (c)2021 MindView LLC: see Copyright.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/control/BreakAndContinue.java b/control/BreakAndContinue.java index 82a369cc4..d6c39738c 100644 --- a/control/BreakAndContinue.java +++ b/control/BreakAndContinue.java @@ -1,20 +1,20 @@ // control/BreakAndContinue.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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) + 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) + 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 + " "); @@ -22,7 +22,7 @@ public static void main(String[] args) { System.out.println(); int i = 0; // An "infinite loop": - while(true) { // (3) + while(true) { // [3] i++; int j = i * 27; if(j == 1269) break; // Out of loop diff --git a/control/CommaOperator.java b/control/CommaOperator.java index 811637334..995765188 100644 --- a/control/CommaOperator.java +++ b/control/CommaOperator.java @@ -1,7 +1,7 @@ // control/CommaOperator.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class CommaOperator { public static void main(String[] args) { diff --git a/control/ForInFloat.java b/control/ForInFloat.java index 3288b3fe9..c36236ef1 100644 --- a/control/ForInFloat.java +++ b/control/ForInFloat.java @@ -1,13 +1,13 @@ // control/ForInFloat.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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]; + float[] f = new float[10]; for(int i = 0; i < 10; i++) f[i] = rand.nextFloat(); for(float x : f) diff --git a/control/ForInInt.java b/control/ForInInt.java index bca55ebf7..7adf5550d 100644 --- a/control/ForInInt.java +++ b/control/ForInInt.java @@ -1,7 +1,7 @@ // control/ForInInt.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import static onjava.Range.*; public class ForInInt { diff --git a/control/ForInString.java b/control/ForInString.java index 41d4de810..8b5ba601e 100644 --- a/control/ForInString.java +++ b/control/ForInString.java @@ -1,7 +1,7 @@ // control/ForInString.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class ForInString { public static void main(String[] args) { diff --git a/control/IfElse.java b/control/IfElse.java index 2aaa3bb11..b2fd79de9 100644 --- a/control/IfElse.java +++ b/control/IfElse.java @@ -1,14 +1,14 @@ // control/IfElse.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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) + else if(testval < target) // [1] result = -1; else result = 0; // Match diff --git a/control/LabeledFor.java b/control/LabeledFor.java index 4ce2ca01e..0cfe7bd95 100644 --- a/control/LabeledFor.java +++ b/control/LabeledFor.java @@ -1,8 +1,8 @@ // control/LabeledFor.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// For loops with "labeled break" and "labeled continue." +// Visit http://OnJava8.com for more book information. +// For loops with "labeled break"/"labeled continue." public class LabeledFor { public static void main(String[] args) { diff --git a/control/LabeledWhile.java b/control/LabeledWhile.java index 4ebb27c57..6c884cb80 100644 --- a/control/LabeledWhile.java +++ b/control/LabeledWhile.java @@ -1,7 +1,7 @@ // control/LabeledWhile.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // "While" with "labeled break" and "labeled continue." public class LabeledWhile { diff --git a/control/ListCharacters.java b/control/ListCharacters.java index 281c9e4e7..dc4b7d2ca 100644 --- a/control/ListCharacters.java +++ b/control/ListCharacters.java @@ -1,7 +1,7 @@ // control/ListCharacters.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // List all the lowercase ASCII letters public class ListCharacters { diff --git a/collectionsindepth/RandomBounds.java b/control/RandomBounds.java similarity index 52% rename from collectionsindepth/RandomBounds.java rename to control/RandomBounds.java index 8efcd9d7f..e0903f372 100644 --- a/collectionsindepth/RandomBounds.java +++ b/control/RandomBounds.java @@ -1,21 +1,15 @@ -// collectionsindepth/RandomBounds.java -// (c)2016 MindView LLC: see Copyright.txt +// control/RandomBounds.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Does Math.random() produce 0.0 and 1.0? -// {TimeOutDuringTesting} -// {Args: lower} +// {java RandomBounds lower} +import onjava.*; public class RandomBounds { - static void usage() { - System.out.println("Usage:"); - System.out.println("\tRandomBounds lower"); - System.out.println("\tRandomBounds upper"); - System.exit(1); - } public static void main(String[] args) { - if(args.length != 1) usage(); - switch(args[0]) { + new TimedAbort(3); + switch(args.length == 0 ? "" : args[0]) { case "lower": while(Math.random() != 0.0) ; // Keep trying @@ -27,7 +21,10 @@ public static void main(String[] args) { System.out.println("Produced 1.0!"); break; default: - usage(); + System.out.println("Usage:"); + System.out.println("\tRandomBounds lower"); + System.out.println("\tRandomBounds upper"); + System.exit(1); } } } diff --git a/control/StringSwitch.java b/control/StringSwitch.java index 24772ca98..ac4694cf3 100644 --- a/control/StringSwitch.java +++ b/control/StringSwitch.java @@ -1,7 +1,7 @@ // control/StringSwitch.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class StringSwitch { public static void main(String[] args) { diff --git a/control/TestWithReturn.java b/control/TestWithReturn.java index 33c61893e..9b32ee845 100644 --- a/control/TestWithReturn.java +++ b/control/TestWithReturn.java @@ -1,7 +1,7 @@ // control/TestWithReturn.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class TestWithReturn { static int test(int testval, int target) { diff --git a/control/TrueFalse.java b/control/TrueFalse.java index 9321ef1a1..ad2da1a79 100644 --- a/control/TrueFalse.java +++ b/control/TrueFalse.java @@ -1,7 +1,7 @@ // control/TrueFalse.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class TrueFalse { public static void main(String[] args) { diff --git a/control/VowelsAndConsonants.java b/control/VowelsAndConsonants.java index fbe9a631d..2b8b3e959 100644 --- a/control/VowelsAndConsonants.java +++ b/control/VowelsAndConsonants.java @@ -1,7 +1,7 @@ // control/VowelsAndConsonants.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Demonstrates the switch statement import java.util.*; @@ -19,7 +19,7 @@ public static void main(String[] args) { case 'u': System.out.println("vowel"); break; case 'y': - case 'w': System.out.println("Sometimes a vowel"); + case 'w': System.out.println("Sometimes vowel"); break; default: System.out.println("consonant"); } @@ -27,18 +27,18 @@ public static void main(String[] args) { } } /* Output: (First 13 Lines) -y, 121: Sometimes a vowel +y, 121: Sometimes vowel n, 110: consonant z, 122: consonant b, 98: consonant r, 114: consonant n, 110: consonant -y, 121: Sometimes a vowel +y, 121: Sometimes vowel g, 103: consonant c, 99: consonant f, 102: consonant o, 111: vowel -w, 119: Sometimes a vowel +w, 119: Sometimes vowel z, 122: consonant ... */ diff --git a/control/WhileTest.java b/control/WhileTest.java index e3d044ded..a047c166c 100644 --- a/control/WhileTest.java +++ b/control/WhileTest.java @@ -1,13 +1,13 @@ // control/WhileTest.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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.println(result + ", "); + System.out.print(result + ", "); return result; } public static void main(String[] args) { @@ -16,13 +16,13 @@ public static void main(String[] args) { System.out.println("Exited 'while'"); } } -/* Output: (First and last 5 Lines) +/* 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' diff --git a/control/build.xml b/control/build.xml deleted file mode 100644 index 5b0f6b3a3..000000000 --- a/control/build.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/debugging/SimpleDebugging.java b/debugging/SimpleDebugging.java deleted file mode 100644 index 74846b8d3..000000000 --- a/debugging/SimpleDebugging.java +++ /dev/null @@ -1,37 +0,0 @@ -// debugging/SimpleDebugging.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ 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:16) - at SimpleDebugging.foo2(SimpleDebugging.java:10) - at SimpleDebugging.foo1(SimpleDebugging.java:6) - at SimpleDebugging.main(SimpleDebugging.java:19) -___[ Exception is Expected ]___ -*/ diff --git a/debugging/build.xml b/debugging/build.xml deleted file mode 100644 index e253c677f..000000000 --- a/debugging/build.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/enumerations/ArrowInSwitch.java b/enumerations/ArrowInSwitch.java new file mode 100644 index 000000000..f583d7ee2 --- /dev/null +++ b/enumerations/ArrowInSwitch.java @@ -0,0 +1,42 @@ +// enumerations/ArrowInSwitch.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 14 +import static java.util.stream.IntStream.range; + +public class ArrowInSwitch { + static void colons(int i) { + switch(i) { + case 1: System.out.println("one"); + break; + case 2: System.out.println("two"); + break; + case 3: System.out.println("three"); + break; + default: System.out.println("default"); + } + } + static void arrows(int i) { + switch(i) { + case 1 -> System.out.println("one"); + case 2 -> System.out.println("two"); + case 3 -> System.out.println("three"); + default -> System.out.println("default"); + } + } + public static void main(String[] args) { + range(0, 4).forEach(i -> colons(i)); + range(0, 4).forEach(i -> arrows(i)); + } +} +/* Output: +default +one +two +three +default +one +two +three +*/ diff --git a/enumerations/CaseNull.java b/enumerations/CaseNull.java new file mode 100644 index 000000000..6b5004920 --- /dev/null +++ b/enumerations/CaseNull.java @@ -0,0 +1,92 @@ +// enumerations/CaseNull.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Preview in JDK 17 +// Compile with javac flags: +// --enable-preview --source 17 +// Run with java flag: --enable-preview +import java.util.*; +import java.util.function.*; + +public class CaseNull { + static void old(String s) { + if(s == null) { + System.out.println("null"); + return; + } + switch(s) { + case "XX" -> System.out.println("XX"); + default -> System.out.println("default"); + } + } + static void checkNull(String s) { + switch(s) { + case "XX" -> System.out.println("XX"); + case null -> System.out.println("null"); + default -> System.out.println("default"); + } + // Works with colon syntax, too: + switch(s) { + case "XX": System.out.println("XX"); + break; + case null: System.out.println("null"); + break; + default : System.out.println("default"); + } + } + static void defaultOnly(String s) { + switch(s) { + case "XX" -> System.out.println("XX"); + default -> System.out.println("default"); + } + } + static void combineNullAndCase(String s) { + switch(s) { + case "XX", null -> System.out.println("XX|null"); + default -> System.out.println("default"); + } + } + static void combineNullAndDefault(String s) { + switch(s) { + case "XX" -> System.out.println("XX"); + case null, default -> System.out.println("both"); + } + } + static void test(Consumer cs) { + cs.accept("XX"); + cs.accept("YY"); + try { + cs.accept(null); + } catch(NullPointerException e) { + System.out.println(e.getMessage()); + } + } + public static void main(String[] args) { + test(CaseNull::old); + test(CaseNull::checkNull); + test(CaseNull::defaultOnly); + test(CaseNull::combineNullAndCase); + test(CaseNull::combineNullAndDefault); + } +} +/* Output: +XX +default +null +XX +XX +default +default +null +null +XX +default +Cannot invoke "String.hashCode()" because "" is null +XX|null +default +XX|null +XX +both +both +*/ diff --git a/enumerations/Dominance.java b/enumerations/Dominance.java new file mode 100644 index 000000000..893e755e2 --- /dev/null +++ b/enumerations/Dominance.java @@ -0,0 +1,20 @@ +// enumerations/Dominance.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Preview in JDK 17 +// Compile with javac flags: +// --enable-preview --source 17 +import java.util.*; + +sealed interface Base {} +record Derived() implements Base {} + +public class Dominance { + static String test(Base base) { + return switch(base) { + case Derived d -> "Derived"; + case Base b -> "B"; // [1] + }; + } +} diff --git a/enumerations/EnumSwitch.java b/enumerations/EnumSwitch.java new file mode 100644 index 000000000..a17546eab --- /dev/null +++ b/enumerations/EnumSwitch.java @@ -0,0 +1,17 @@ +// enumerations/EnumSwitch.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 14 + +public class EnumSwitch { + enum Signal { GREEN, YELLOW, RED, } + Signal color = Signal.RED; + public void change() { + color = switch(color) { + case RED -> Signal.GREEN; + case GREEN -> Signal.YELLOW; + case YELLOW -> Signal.RED; + }; + } +} diff --git a/enumerations/NormalLiskov.java b/enumerations/NormalLiskov.java new file mode 100644 index 000000000..c121700ab --- /dev/null +++ b/enumerations/NormalLiskov.java @@ -0,0 +1,40 @@ +// enumerations/NormalLiskov.java +// (c)2021 MindView LLC: see Copyright.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.*; + +interface LifeForm { + String move(); + String react(); +} + +class Worm implements LifeForm { + @Override public String move() { + return "Worm::move()"; + } + @Override public String react() { + return "Worm::react()"; + } +} + +class Giraffe implements LifeForm { + @Override public String move() { + return "Giraffe::move()"; + } + @Override public String react() { + return "Giraffe::react()"; + } +} + +public class NormalLiskov { + public static void main(String[] args) { + Stream.of(new Worm(), new Giraffe()) + .forEach(lf -> System.out.println( + lf.move() + " " + lf.react())); + } +} +/* Output: +Worm::move() Worm::react() +Giraffe::move() Giraffe::react() +*/ diff --git a/enumerations/ObjectMatch.java b/enumerations/ObjectMatch.java new file mode 100644 index 000000000..490b79a0b --- /dev/null +++ b/enumerations/ObjectMatch.java @@ -0,0 +1,46 @@ +// enumerations/ObjectMatch.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Preview in JDK 17 +// Compile with javac flags: +// --enable-preview --source 17 +// Run with java flag: --enable-preview +import java.util.*; + +record XX() {} + +public class ObjectMatch { + static String match(Object o) { + return switch(o) { + case Dog d -> "Walk the dog"; + case Fish f -> "Change the fish water"; + case Pet sp -> "Not dog or fish"; + case String s -> "String " + s; + case Integer i -> "Integer " + i; + case String[] sa -> String.join(", ", sa); + case null, XX xx -> "null or XX: " + xx; + default -> "Something else"; + }; + } + public static void main(String[] args) { + List.of(new Dog(), new Fish(), new Pet(), + "Oscar", Integer.valueOf(12), + Double.valueOf("47.74"), + new String[]{ "to", "the", "point" }, + new XX() + ).forEach( + p -> System.out.println(match(p)) + ); + } +} +/* Output: +Walk the dog +Change the fish water +Not dog or fish +String Oscar +Integer 12 +Something else +to, the, point +null or Object: XX[] +*/ diff --git a/enumerations/OddScoping.java b/enumerations/OddScoping.java new file mode 100644 index 000000000..fd938e98a --- /dev/null +++ b/enumerations/OddScoping.java @@ -0,0 +1,27 @@ +// enumerations/OddScoping.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 + +public class OddScoping { + static void f(Object o) { + if(!(o instanceof String s)) { + System.out.println("Not a String"); + throw new RuntimeException(); + } + // s is in scope here! + System.out.println(s.toUpperCase()); // [1] + } + public static void main(String[] args) { + f("Curiouser and Curiouser"); + f(null); + } +} +/* Output: +CURIOUSER AND CURIOUSER +Not a String +Exception in thread "main" java.lang.RuntimeException + at OddScoping.f(OddScoping.java:8) + at OddScoping.main(OddScoping.java:15) +*/ diff --git a/enumerations/People.java b/enumerations/People.java new file mode 100644 index 000000000..183d34c79 --- /dev/null +++ b/enumerations/People.java @@ -0,0 +1,46 @@ +// enumerations/People.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Preview in JDK 17 +// Compile with javac flags: +// --enable-preview --source 17 +// Run with java flag: --enable-preview +import java.util.*; + +record Person(String name, int age) {} + +public class People { + static String categorize(Person person) { + return switch(person) { + case Person p && p.age() > 40 // [1] + -> p + " is middle aged"; + case Person p && + (p.name().contains("D") || p.age() == 14) + -> p + " D or 14"; + case Person p && !(p.age() >= 100) // [2] + -> p + " is not a centenarian"; + case Person p -> p + " Everyone else"; + }; + } + public static void main(String[] args) { + List.of( + new Person("Dorothy", 15), + new Person("John Bigboote", 42), + new Person("Morty", 14), + new Person("Morty Jr.", 1), + new Person("Jose", 39), + new Person("Kane", 118) + ).forEach( + p -> System.out.println(categorize(p)) + ); + } +} +/* Output: +Person[name=Dorothy, age=15] D or 14 +Person[name=John Bigboote, age=42] is middle aged +Person[name=Morty, age=14] D or 14 +Person[name=Morty Jr., age=1] is not a centenarian +Person[name=Jose, age=39] is not a centenarian +Person[name=Kane, age=118] is middle aged +*/ diff --git a/enumerations/Pet.java b/enumerations/Pet.java new file mode 100644 index 000000000..0508905e3 --- /dev/null +++ b/enumerations/Pet.java @@ -0,0 +1,16 @@ +// enumerations/Pet.java +// (c)2021 MindView 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 Pet { + void feed() {} +} + +class Dog extends Pet { + void walk() {} +} + +class Fish extends Pet { + void changeWater() {} +} diff --git a/enumerations/PetPatternMatch.java b/enumerations/PetPatternMatch.java new file mode 100644 index 000000000..d538ef2b8 --- /dev/null +++ b/enumerations/PetPatternMatch.java @@ -0,0 +1,22 @@ +// enumerations/PetPatternMatch.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Preview in JDK 17 +// Compile with javac flags: +// --enable-preview --source 17 +import java.util.*; + +public class PetPatternMatch { + static void careFor(Pet p) { + switch(p) { + case Dog d -> d.walk(); + case Fish f -> f.changeWater(); + case Pet sp -> sp.feed(); + }; + } + static void petCare() { + List.of(new Dog(), new Fish()) + .forEach(p -> careFor(p)); + } +} diff --git a/enumerations/PetPatternMatch2.java b/enumerations/PetPatternMatch2.java new file mode 100644 index 000000000..76b44f4ee --- /dev/null +++ b/enumerations/PetPatternMatch2.java @@ -0,0 +1,36 @@ +// enumerations/PetPatternMatch2.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Preview in JDK 17 +// Compile with javac flags: +// --enable-preview --source 17 +package sealedpet; +import java.util.*; + +sealed interface Pet { + void feed(); +} + +final class Dog implements Pet { + @Override public void feed() {} + void walk() {} +} + +final class Fish implements Pet { + @Override public void feed() {} + void changeWater() {} +} + +public class PetPatternMatch2 { + static void careFor(Pet p) { + switch(p) { + case Dog d -> d.walk(); + case Fish f -> f.changeWater(); + }; + } + static void petCare() { + List.of(new Dog(), new Fish()) + .forEach(p -> careFor(p)); + } +} diff --git a/enumerations/Planets.java b/enumerations/Planets.java new file mode 100644 index 000000000..9554c684f --- /dev/null +++ b/enumerations/Planets.java @@ -0,0 +1,36 @@ +// enumerations/Planets.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 14 + +enum CelestialBody { + MERCURY, VENUS, EARTH, MARS, JUPITER, + SATURN, URANUS, NEPTUNE, PLUTO +} + +public class Planets { + public static String classify(CelestialBody b) { + var result = switch(b) { + case MERCURY, VENUS, EARTH, + MARS, JUPITER, + SATURN, URANUS, NEPTUNE -> { + System.out.print("A planet: "); + yield b.toString(); + } + case PLUTO -> { + System.out.print("Not a planet: "); + yield b.toString(); + } + }; + return result; + } + public static void main(String[] args) { + System.out.println(classify(CelestialBody.MARS)); + System.out.println(classify(CelestialBody.PLUTO)); + } +} +/* Output: +A planet: MARS +Not a planet: PLUTO +*/ diff --git a/enumerations/SealedPatternMatch.java b/enumerations/SealedPatternMatch.java new file mode 100644 index 000000000..b5051303b --- /dev/null +++ b/enumerations/SealedPatternMatch.java @@ -0,0 +1,48 @@ +// enumerations/SealedPatternMatch.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Preview in JDK 17 +// Compile with javac flags: +// --enable-preview --source 17 +// Run with java flag: --enable-preview +import java.util.*; + +sealed interface Transport {}; +record Bicycle(String id) implements Transport {}; +record Glider(int size) implements Transport {}; +record Surfboard(double weight) implements Transport {}; +// If you uncomment this: +// record Skis(int length) implements Transport {}; +// You get an error: "the switch expression +// does not cover all possible input values" + +public class SealedPatternMatch { + static String exhaustive(Transport t) { + return switch(t) { + case Bicycle b -> "Bicycle " + b.id(); + case Glider g -> "Glider " + g.size(); + case Surfboard s -> "Surfboard " + s.weight(); + }; + } + public static void main(String[] args) { + List.of( + new Bicycle("Bob"), + new Glider(65), + new Surfboard(6.4) + ).forEach( + t -> System.out.println(exhaustive(t)) + ); + try { + exhaustive(null); // Always possible! // [1] + } catch(NullPointerException e) { + System.out.println("Not exhaustive: " + e); + } + } +} +/* Output: +Bicycle Bob +Glider 65 +Surfboard 6.4 +Not exhaustive: java.lang.NullPointerException +*/ diff --git a/enumerations/Shapes.java b/enumerations/Shapes.java new file mode 100644 index 000000000..031fc4851 --- /dev/null +++ b/enumerations/Shapes.java @@ -0,0 +1,53 @@ +// enumerations/Shapes.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Preview in JDK 17 +// Compile with javac flags: +// --enable-preview --source 17 +// Run with java flag: --enable-preview +import java.util.*; + +sealed interface Shape { + double area(); +} + +record Circle(double radius) implements Shape { + @Override public double area() { + return Math.PI * radius * radius; + } +} + +record Rectangle(double side1, double side2) + implements Shape { + @Override public double area() { + return side1 * side2; + } +} + +public class Shapes { + static void classify(Shape s) { + System.out.println(switch(s) { + case Circle c && c.area() < 100.0 + -> "Small Circle: " + c; + case Circle c -> "Large Circle: " + c; + case Rectangle r && r.side1() == r.side2() + -> "Square: " + r; + case Rectangle r -> "Rectangle: " + r; + }); + } + public static void main(String[] args) { + List.of( + new Circle(5.0), + new Circle(25.0), + new Rectangle(12.0, 12.0), + new Rectangle(12.0, 15.0) + ).forEach(t -> classify(t)); + } +} +/* Output: +Small Circle: Circle[radius=5.0] +Large Circle: Circle[radius=25.0] +Square: Rectangle[side1=12.0, side2=12.0] +Rectangle: Rectangle[side1=12.0, side2=15.0] +*/ diff --git a/enumerations/SmartCasting.java b/enumerations/SmartCasting.java new file mode 100644 index 000000000..848c0e9de --- /dev/null +++ b/enumerations/SmartCasting.java @@ -0,0 +1,36 @@ +// enumerations/SmartCasting.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 + +public class SmartCasting { + static void dumb(Object x) { + if(x instanceof String) { + String s = (String)x; + if(s.length() > 0) { + System.out.format( + "%d %s%n", s.length(), s.toUpperCase()); + } + } + } + static void smart(Object x) { + if(x instanceof String s && s.length() > 0) { + System.out.format( + "%d %s%n", s.length(), s.toUpperCase()); + } + } + static void wrong(Object x) { + // "Or" never works: + // if(x instanceof String s || s.length() > 0) {} + // error: cannot find symbol ^ + } + public static void main(String[] args) { + dumb("dumb"); + smart("smart"); + } +} +/* Output: +4 DUMB +5 SMART +*/ diff --git a/enumerations/SwitchExpression.java b/enumerations/SwitchExpression.java new file mode 100644 index 000000000..06a0fe49b --- /dev/null +++ b/enumerations/SwitchExpression.java @@ -0,0 +1,38 @@ +// enumerations/SwitchExpression.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 14 +import java.util.*; + +public class SwitchExpression { + static int colon(String s) { + var result = switch(s) { + case "i": yield 1; + case "j": yield 2; + case "k": yield 3; + default: yield 0; + }; + return result; + } + static int arrow(String s) { + var result = switch(s) { + case "i" -> 1; + case "j" -> 2; + case "k" -> 3; + default -> 0; + }; + return result; + } + public static void main(String[] args) { + for(var s: new String[]{"i", "j", "k", "z"}) + System.out.format( + "%s %d %d%n", s, colon(s), arrow(s)); + } +} +/* Output: +i 1 1 +j 2 2 +k 3 3 +z 0 0 +*/ diff --git a/enumerations/Tanks.java b/enumerations/Tanks.java new file mode 100644 index 000000000..0604693f5 --- /dev/null +++ b/enumerations/Tanks.java @@ -0,0 +1,47 @@ +// enumerations/Tanks.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Preview in JDK 17 +// Compile with javac flags: +// --enable-preview --source 17 +// Run with java flag: --enable-preview +import java.util.*; + +enum Type { TOXIC, FLAMMABLE, NEUTRAL } + +record Level(int percent) { + Level { + if(percent < 0 || percent > 100) + throw new IndexOutOfBoundsException( + percent + " percent"); + } +} + +record Tank(Type type, Level level) {} + +public class Tanks { + static String check(Tank tank) { + return switch(tank) { + case Tank t && t.type() == Type.TOXIC + -> "Toxic: " + t; + case Tank t && ( // [1] + t.type() == Type.TOXIC && + t.level().percent() < 50 + ) -> "Toxic, low: " + t; + case Tank t && t.type() == Type.FLAMMABLE + -> "Flammable: " + t; + // Equivalent to "default": + case Tank t -> "Other Tank: " + t; + }; + } + public static void main(String[] args) { + List.of( + new Tank(Type.TOXIC, new Level(49)), + new Tank(Type.FLAMMABLE, new Level(52)), + new Tank(Type.NEUTRAL, new Level(75)) + ).forEach( + t -> System.out.println(check(t)) + ); + } +} diff --git a/enums/AlarmPoints.java b/enums/AlarmPoints.java index 84e95d3d0..484ee4f63 100644 --- a/enums/AlarmPoints.java +++ b/enums/AlarmPoints.java @@ -1,7 +1,7 @@ // enums/AlarmPoints.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package enums; public enum AlarmPoints { STAIR1, STAIR2, LOBBY, OFFICE1, OFFICE2, OFFICE3, diff --git a/enums/BigEnumSet.java b/enums/BigEnumSet.java index 4aabae130..8e2127b7a 100644 --- a/enums/BigEnumSet.java +++ b/enums/BigEnumSet.java @@ -1,17 +1,18 @@ // enums/BigEnumSet.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 } + 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); @@ -19,10 +20,10 @@ public static void main(String[] args) { } /* 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] +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/enums/Burrito.java b/enums/Burrito.java deleted file mode 100644 index 8d7852004..000000000 --- a/enums/Burrito.java +++ /dev/null @@ -1,27 +0,0 @@ -// enums/Burrito.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package enums; -import static enums.Spiciness.*; - -public class Burrito { - Spiciness degree; - public Burrito(Spiciness degree) { - this.degree = degree; - } - @Override - public String toString() { - return "Burrito is "+ degree; - } - public static void main(String[] args) { - System.out.println(new Burrito(NOT)); - System.out.println(new Burrito(MEDIUM)); - System.out.println(new Burrito(HOT)); - } -} -/* Output: -Burrito is NOT -Burrito is MEDIUM -Burrito is HOT -*/ diff --git a/enums/Burrito2.java b/enums/Burrito2.java new file mode 100644 index 000000000..5892eaf73 --- /dev/null +++ b/enums/Burrito2.java @@ -0,0 +1,27 @@ +// enums/Burrito2.java +// (c)2021 MindView 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/enums/CarWash.java b/enums/CarWash.java index 47c9f9e3c..1b6fc856f 100644 --- a/enums/CarWash.java +++ b/enums/CarWash.java @@ -1,50 +1,43 @@ // enums/CarWash.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class CarWash { public enum Cycle { UNDERBODY { - @Override - void action() { + @Override void action() { System.out.println("Spraying the underbody"); } }, WHEELWASH { - @Override - void action() { + @Override void action() { System.out.println("Washing the wheels"); } }, PREWASH { - @Override - void action() { + @Override void action() { System.out.println("Loosening the dirt"); } }, BASIC { - @Override - void action() { + @Override void action() { System.out.println("The basic wash"); } }, HOTWAX { - @Override - void action() { + @Override void action() { System.out.println("Applying hot wax"); } }, RINSE { - @Override - void action() { + @Override void action() { System.out.println("Rinsing"); } }, BLOWDRY { - @Override - void action() { + @Override void action() { System.out.println("Blowing dry"); } }; @@ -52,13 +45,16 @@ void action() { } EnumSet cycles = EnumSet.of(Cycle.BASIC, Cycle.RINSE); - public void add(Cycle cycle) { cycles.add(cycle); } + public void add(Cycle cycle) { + cycles.add(cycle); + } public void washCar() { for(Cycle c : cycles) c.action(); } - @Override - public String toString() { return cycles.toString(); } + @Override public String toString() { + return cycles.toString(); + } public static void main(String[] args) { CarWash wash = new CarWash(); System.out.println(wash); diff --git a/enums/Competitor.java b/enums/Competitor.java index 234008d4f..5232d7d36 100644 --- a/enums/Competitor.java +++ b/enums/Competitor.java @@ -1,7 +1,7 @@ // enums/Competitor.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Switching one enum on another package enums; diff --git a/enums/ConstantSpecificMethod.java b/enums/ConstantSpecificMethod.java index 974acf7c6..04ee956bb 100644 --- a/enums/ConstantSpecificMethod.java +++ b/enums/ConstantSpecificMethod.java @@ -1,27 +1,25 @@ // enums/ConstantSpecificMethod.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.text.*; public enum ConstantSpecificMethod { DATE_TIME { - @Override - String getInfo() { + @Override String getInfo() { return - DateFormat.getDateInstance().format(new Date()); + DateFormat.getDateInstance() + .format(new Date()); } }, CLASSPATH { - @Override - String getInfo() { + @Override String getInfo() { return System.getenv("CLASSPATH"); } }, VERSION { - @Override - String getInfo() { + @Override String getInfo() { return System.getProperty("java.version"); } }; @@ -32,14 +30,8 @@ public static void main(String[] args) { } } /* Output: -Dec 13, 2015 -.;..;C:\Program Files (x86)\Java\xom-1.2.10.jar;C:\Program -Files (x86)\Java\jdk1.8.0_45\lib\tools.jar;C:\Program Files -(x86)\Java\jre1.8.0_45\lib\javaws.jar;C:\Program Files -(x86)\Java\swt-4.4.2-win32-win32-x86\swt.jar;C:\Program -Files (x86)\Java\javassist.jar;C:\Users\Bruce\Documents\Git -Hub\OnJava\ExtractedExamples;C:\Program Files -(x86)\Java\junit-4.12.jar;C:\Program Files -(x86)\Java\hamcrest-core-1.3.jar; -1.8.0_66 +Jan 24, 2021 +C:\Git\OnJava8\ExtractedExamples\\gradle\wrapper\gradle +-wrapper.jar +1.8.0_41 */ diff --git a/enums/EnumClass.java b/enums/EnumClass.java index e44203d3f..a7ec9cea2 100644 --- a/enums/EnumClass.java +++ b/enums/EnumClass.java @@ -1,7 +1,7 @@ // enums/EnumClass.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Capabilities of the Enum class enum Shrubbery { GROUND, CRAWLING, HANGING } @@ -9,7 +9,8 @@ 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.println( + s + " ordinal: " + s.ordinal()); System.out.print( s.compareTo(Shrubbery.CRAWLING) + " "); System.out.print( @@ -17,11 +18,13 @@ public static void main(String[] args) { System.out.println(s == Shrubbery.CRAWLING); System.out.println(s.getDeclaringClass()); System.out.println(s.name()); - System.out.println("----------------------"); + 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); + for(String s : + "HANGING CRAWLING GROUND".split(" ")) { + Shrubbery shrub = + Enum.valueOf(Shrubbery.class, s); System.out.println(shrub); } } @@ -31,17 +34,17 @@ public static void main(String[] args) { -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/enums/EnumMaps.java b/enums/EnumMaps.java index 92cbbc045..2adeffcc9 100644 --- a/enums/EnumMaps.java +++ b/enums/EnumMaps.java @@ -1,8 +1,9 @@ // enums/EnumMaps.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Basics of EnumMaps +// {java enums.EnumMaps} package enums; import java.util.*; import static enums.AlarmPoints.*; @@ -17,7 +18,8 @@ public static void main(String[] args) { () -> System.out.println("Kitchen fire!")); em.put(BATHROOM, () -> System.out.println("Bathroom alert!")); - for(Map.Entry e: em.entrySet()) { + for(Map.Entry e: + em.entrySet()) { System.out.print(e.getKey() + ": "); e.getValue().action(); } diff --git a/enums/EnumSets.java b/enums/EnumSets.java index c25833580..afb9fa7b1 100644 --- a/enums/EnumSets.java +++ b/enums/EnumSets.java @@ -1,8 +1,9 @@ // enums/EnumSets.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Operations on EnumSets +// {java enums.EnumSets} package enums; import java.util.*; import static enums.AlarmPoints.*; @@ -10,15 +11,18 @@ public class EnumSets { public static void main(String[] args) { EnumSet points = - EnumSet.noneOf(AlarmPoints.class); // Empty set + EnumSet.noneOf(AlarmPoints.class); // Empty points.add(BATHROOM); System.out.println(points); - points.addAll(EnumSet.of(STAIR1, STAIR2, KITCHEN)); + points.addAll( + EnumSet.of(STAIR1, STAIR2, KITCHEN)); System.out.println(points); points = EnumSet.allOf(AlarmPoints.class); - points.removeAll(EnumSet.of(STAIR1, STAIR2, KITCHEN)); + points.removeAll( + EnumSet.of(STAIR1, STAIR2, KITCHEN)); System.out.println(points); - points.removeAll(EnumSet.range(OFFICE1, OFFICE4)); + points.removeAll( + EnumSet.range(OFFICE1, OFFICE4)); System.out.println(points); points = EnumSet.complementOf(points); System.out.println(points); diff --git a/enums/Input.java b/enums/Input.java index 56dc2dc90..c7be7babc 100644 --- a/enums/Input.java +++ b/enums/Input.java @@ -1,31 +1,31 @@ // enums/Input.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 + @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()"); + @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 SplittableRandom rand = new SplittableRandom(47); + static Random rand = new Random(47); public static Input randomSelection() { // Don't include STOP: - return values()[rand.nextInt(values().length - 1)]; + return + values()[rand.nextInt(values().length - 1)]; } } diff --git a/enums/Item.java b/enums/Item.java new file mode 100644 index 000000000..1fd45d2fe --- /dev/null +++ b/enums/Item.java @@ -0,0 +1,12 @@ +// enums/Item.java +// (c)2021 MindView 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 interface Item { + Outcome compete(Item it); + Outcome eval(Paper p); + Outcome eval(Scissors s); + Outcome eval(Rock r); +} diff --git a/enums/NonEnum.java b/enums/NonEnum.java index ddfcc0ad2..cbd1e72b5 100644 --- a/enums/NonEnum.java +++ b/enums/NonEnum.java @@ -1,7 +1,7 @@ // enums/NonEnum.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class NonEnum { public static void main(String[] args) { diff --git a/enums/NotClasses.java b/enums/NotClasses.java index 801592212..efd83c8fb 100644 --- a/enums/NotClasses.java +++ b/enums/NotClasses.java @@ -1,21 +1,25 @@ // enums/NotClasses.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {Exec: javap -c LikeClasses} +// Visit http://OnJava8.com for more book information. +// {ExcludeFromGradle} +// javap -c LikeClasses enum LikeClasses { WINKEN { - @Override - void behavior() { System.out.println("Behavior1"); } + @Override void behavior() { + System.out.println("Behavior1"); + } }, BLINKEN { - @Override - void behavior() { System.out.println("Behavior2"); } + @Override void behavior() { + System.out.println("Behavior2"); + } }, NOD { - @Override - void behavior() { System.out.println("Behavior3"); } + @Override void behavior() { + System.out.println("Behavior3"); + } }; abstract void behavior(); } @@ -28,8 +32,11 @@ public class NotClasses { 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 diff --git a/enums/Outcome.java b/enums/Outcome.java index 5255ee6ea..75b343b5f 100644 --- a/enums/Outcome.java +++ b/enums/Outcome.java @@ -1,6 +1,6 @@ // enums/Outcome.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package enums; public enum Outcome { WIN, LOSE, DRAW } diff --git a/enums/OverrideConstantSpecific.java b/enums/OverrideConstantSpecific.java index d3a9824db..a9ba41818 100644 --- a/enums/OverrideConstantSpecific.java +++ b/enums/OverrideConstantSpecific.java @@ -1,15 +1,18 @@ // enums/OverrideConstantSpecific.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public enum OverrideConstantSpecific { NUT, BOLT, WASHER { - @Override - void f() { System.out.println("Overridden method"); } + @Override void f() { + System.out.println("Overridden method"); + } }; - void f() { System.out.println("default behavior"); } + void f() { + System.out.println("default behavior"); + } public static void main(String[] args) { for(OverrideConstantSpecific ocs : values()) { System.out.print(ocs + ": "); diff --git a/enums/OzWitch.java b/enums/OzWitch.java index 9d56b7fb3..275961a12 100644 --- a/enums/OzWitch.java +++ b/enums/OzWitch.java @@ -1,7 +1,7 @@ // enums/OzWitch.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // The witches in the land of Oz public enum OzWitch { diff --git a/enums/Paper.java b/enums/Paper.java new file mode 100644 index 000000000..7273a5c18 --- /dev/null +++ b/enums/Paper.java @@ -0,0 +1,21 @@ +// enums/Paper.java +// (c)2021 MindView 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; +import static enums.Outcome.*; + +public 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"; + } +} diff --git a/enums/PostOffice.java b/enums/PostOffice.java index 7b1837e47..2aef48f95 100644 --- a/enums/PostOffice.java +++ b/enums/PostOffice.java @@ -1,13 +1,13 @@ // enums/PostOffice.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Modeling a post office import java.util.*; import onjava.*; class Mail { - // The NO's lower the probability of random selection: + // 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} @@ -20,12 +20,13 @@ enum ReturnAddress {MISSING,OK1,OK2,OK3,OK4,OK5} ReturnAddress returnAddress; static long counter = 0; long id = counter++; - @Override - public String toString() { return "Mail " + id; } + @Override public String toString() { + return "Mail " + id; + } public String details() { return toString() + ", General Delivery: " + generalDelivery + - ", Address Scanability: " + scannability + + ", Address Scannability: " + scannability + ", Address Readability: " + readability + ", Address Address: " + address + ", Return address: " + returnAddress; @@ -35,23 +36,27 @@ 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.scannability = + Enums.random(Scannability.class); + m.readability = + Enums.random(Readability.class); m.address = Enums.random(Address.class); - m.returnAddress = Enums.random(ReturnAddress.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() { + @Override public Iterator iterator() { return new Iterator() { - @Override - public boolean hasNext() { return n-- > 0; } - @Override - public Mail next() { return randomMail(); } + @Override public boolean hasNext() { + return n-- > 0; + } + @Override public Mail next() { + return randomMail(); + } @Override public void remove() { // Not implemented throw new UnsupportedOperationException(); @@ -65,8 +70,7 @@ public void remove() { // Not implemented public class PostOffice { enum MailHandler { GENERAL_DELIVERY { - @Override - boolean handle(Mail m) { + @Override boolean handle(Mail m) { switch(m.generalDelivery) { case YES: System.out.println( @@ -77,8 +81,7 @@ boolean handle(Mail m) { } }, MACHINE_SCAN { - @Override - boolean handle(Mail m) { + @Override boolean handle(Mail m) { switch(m.scannability) { case UNSCANNABLE: return false; default: @@ -93,8 +96,7 @@ boolean handle(Mail m) { } }, VISUAL_INSPECTION { - @Override - boolean handle(Mail m) { + @Override boolean handle(Mail m) { switch(m.readability) { case ILLEGIBLE: return false; default: @@ -109,8 +111,7 @@ boolean handle(Mail m) { } }, RETURN_TO_SENDER { - @Override - boolean handle(Mail m) { + @Override boolean handle(Mail m) { switch(m.returnAddress) { case MISSING: return false; default: @@ -137,54 +138,54 @@ public static void main(String[] args) { } } /* Output: -Mail 0, General Delivery: NO2, Address Scanability: -UNSCANNABLE, Address Readability: YES3, Address Address: -OK1, Return address: OK1 +Mail 0, General Delivery: NO2, Address Scannability: +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 +Mail 1, General Delivery: NO5, Address Scannability: +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 +Mail 2, General Delivery: YES, Address Scannability: +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 +Mail 3, General Delivery: NO4, Address Scannability: +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 +Mail 4, General Delivery: NO4, Address Scannability: +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 +Mail 5, General Delivery: NO3, Address Scannability: +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 +Mail 6, General Delivery: YES, Address Scannability: +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 +Mail 7, General Delivery: YES, Address Scannability: +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, General Delivery: NO3, Address Scannability: +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 +Mail 9, General Delivery: NO1, Address Scannability: +UNSCANNABLE, Address Readability: YES2, Address +Address: OK1, Return address: OK4 Delivering Mail 9 normally ***** */ diff --git a/enums/RandomTest.java b/enums/RandomTest.java index 70dbc4436..724009735 100644 --- a/enums/RandomTest.java +++ b/enums/RandomTest.java @@ -1,7 +1,7 @@ // enums/RandomTest.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import onjava.*; enum Activity { SITTING, LYING, STANDING, HOPPING, diff --git a/enums/Reflection.java b/enums/Reflection.java index c1359eb0f..d9ac05a7b 100644 --- a/enums/Reflection.java +++ b/enums/Reflection.java @@ -1,7 +1,7 @@ // enums/Reflection.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Analyzing enums using reflection import java.lang.reflect.*; import java.util.*; @@ -10,9 +10,10 @@ enum Explore { HERE, THERE } public class Reflection { - public static Set analyze(Class enumClass) { + public static + Set analyze(Class enumClass) { System.out.println( - "----- Analyzing " + enumClass + " -----"); + "_____ Analyzing " + enumClass + " _____"); System.out.println("Interfaces:"); for(Type t : enumClass.getGenericInterfaces()) System.out.println(t); @@ -26,33 +27,37 @@ public static Set analyze(Class enumClass) { return methods; } public static void main(String[] args) { - Set exploreMethods = analyze(Explore.class); + Set exploreMethods = + analyze(Explore.class); Set enumMethods = analyze(Enum.class); - System.out.println("Explore.containsAll(Enum)? " + + 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 Explore"); + OSExecute.command( + "javap -cp build/classes/java/main Explore"); } } /* Output: ------ Analyzing class Explore ----- +_____ 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 ----- +[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] +[compareTo, equals, getClass, getDeclaringClass, +hashCode, name, notify, notifyAll, ordinal, toString, +valueOf, wait] Explore.containsAll(Enum)? true Explore.removeAll(Enum): [values] Compiled from "Reflection.java" diff --git a/enums/RoShamBo.java b/enums/RoShamBo.java index 168b32020..708584d98 100644 --- a/enums/RoShamBo.java +++ b/enums/RoShamBo.java @@ -1,7 +1,7 @@ // enums/RoShamBo.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Common tools for RoShamBo examples package enums; import onjava.*; diff --git a/enums/RoShamBo1.java b/enums/RoShamBo1.java index 50ae9a0bb..d20f0bbcd 100644 --- a/enums/RoShamBo1.java +++ b/enums/RoShamBo1.java @@ -1,67 +1,15 @@ // enums/RoShamBo1.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 SplittableRandom rand = new SplittableRandom(47); + private static Random rand = new Random(47); public static Item newItem() { switch(rand.nextInt(3)) { default: diff --git a/enums/RoShamBo2.java b/enums/RoShamBo2.java index ce009b7c0..16786562a 100644 --- a/enums/RoShamBo2.java +++ b/enums/RoShamBo2.java @@ -1,8 +1,9 @@ // enums/RoShamBo2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Switching one enum on another +// {java enums.RoShamBo2} package enums; import static enums.Outcome.*; @@ -11,13 +12,13 @@ public enum RoShamBo2 implements Competitor { SCISSORS(WIN, DRAW, LOSE), ROCK(LOSE, WIN, DRAW); private Outcome vPAPER, vSCISSORS, vROCK; - RoShamBo2(Outcome paper,Outcome scissors,Outcome rock) { + RoShamBo2(Outcome paper, + Outcome scissors, Outcome rock) { this.vPAPER = paper; this.vSCISSORS = scissors; this.vROCK = rock; } - @Override - public Outcome compete(RoShamBo2 it) { + @Override public Outcome compete(RoShamBo2 it) { switch(it) { default: case PAPER: return vPAPER; diff --git a/enums/RoShamBo3.java b/enums/RoShamBo3.java index 734a5eed6..91683dce7 100644 --- a/enums/RoShamBo3.java +++ b/enums/RoShamBo3.java @@ -1,15 +1,15 @@ // enums/RoShamBo3.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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) { + @Override public Outcome compete(RoShamBo3 it) { switch(it) { default: // To placate the compiler case PAPER: return DRAW; @@ -19,8 +19,7 @@ public Outcome compete(RoShamBo3 it) { } }, SCISSORS { - @Override - public Outcome compete(RoShamBo3 it) { + @Override public Outcome compete(RoShamBo3 it) { switch(it) { default: case PAPER: return WIN; @@ -30,8 +29,7 @@ public Outcome compete(RoShamBo3 it) { } }, ROCK { - @Override - public Outcome compete(RoShamBo3 it) { + @Override public Outcome compete(RoShamBo3 it) { switch(it) { default: case PAPER: return LOSE; diff --git a/enums/RoShamBo4.java b/enums/RoShamBo4.java index cf679c339..2ad59aa96 100644 --- a/enums/RoShamBo4.java +++ b/enums/RoShamBo4.java @@ -1,7 +1,8 @@ // enums/RoShamBo4.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {java enums.RoShamBo4} package enums; public enum RoShamBo4 implements Competitor { diff --git a/enums/RoShamBo5.java b/enums/RoShamBo5.java index d705aca95..8f6b996ec 100644 --- a/enums/RoShamBo5.java +++ b/enums/RoShamBo5.java @@ -1,8 +1,9 @@ // enums/RoShamBo5.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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.*; @@ -26,8 +27,7 @@ static void initRow(RoShamBo5 it, row.put(RoShamBo5.SCISSORS, vSCISSORS); row.put(RoShamBo5.ROCK, vROCK); } - @Override - public Outcome compete(RoShamBo5 it) { + @Override public Outcome compete(RoShamBo5 it) { return table.get(this).get(it); } public static void main(String[] args) { diff --git a/enums/RoShamBo6.java b/enums/RoShamBo6.java index 54b08f8ee..3d66d894d 100644 --- a/enums/RoShamBo6.java +++ b/enums/RoShamBo6.java @@ -1,8 +1,9 @@ // enums/RoShamBo6.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Enums using "tables" instead of multiple dispatch +// {java enums.RoShamBo6} package enums; import static enums.Outcome.*; @@ -13,8 +14,7 @@ enum RoShamBo6 implements Competitor { { WIN, DRAW, LOSE }, // SCISSORS { LOSE, WIN, DRAW }, // ROCK }; - @Override - public Outcome compete(RoShamBo6 other) { + @Override public Outcome compete(RoShamBo6 other) { return table[this.ordinal()][other.ordinal()]; } public static void main(String[] args) { diff --git a/enums/Rock.java b/enums/Rock.java new file mode 100644 index 000000000..f9e5f7046 --- /dev/null +++ b/enums/Rock.java @@ -0,0 +1,21 @@ +// enums/Rock.java +// (c)2021 MindView 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; +import static enums.Outcome.*; + +public 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"; + } +} diff --git a/enums/Scissors.java b/enums/Scissors.java new file mode 100644 index 000000000..45bab4996 --- /dev/null +++ b/enums/Scissors.java @@ -0,0 +1,21 @@ +// enums/Scissors.java +// (c)2021 MindView 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; +import static enums.Outcome.*; + +public 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"; + } +} diff --git a/enums/SecurityCategory.java b/enums/SecurityCategory.java index 357980d62..18dd0f62a 100644 --- a/enums/SecurityCategory.java +++ b/enums/SecurityCategory.java @@ -1,19 +1,24 @@ // enums/SecurityCategory.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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); + 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 } + enum Stock implements Security { + SHORT, LONG, MARGIN + } + enum Bond implements Security { + MUNICIPAL, JUNK + } } public Security randomSelection() { return Enums.random(values); diff --git a/enums/SpaceShip.java b/enums/SpaceShip.java index 9ff2e3b76..45a5485fb 100644 --- a/enums/SpaceShip.java +++ b/enums/SpaceShip.java @@ -1,20 +1,20 @@ // enums/SpaceShip.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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() { + @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); + Stream.of(values()) + .forEach(System.out::println); } } /* Output: diff --git a/enums/Spiciness.java b/enums/Spiciness.java deleted file mode 100644 index 5eedaf3e7..000000000 --- a/enums/Spiciness.java +++ /dev/null @@ -1,9 +0,0 @@ -// enums/Spiciness.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package enums; - -public enum Spiciness { - NOT, MILD, MEDIUM, HOT, FLAMING -} diff --git a/enums/SpicinessEnum.java b/enums/SpicinessEnum.java new file mode 100644 index 000000000..02b54ee4d --- /dev/null +++ b/enums/SpicinessEnum.java @@ -0,0 +1,9 @@ +// enums/SpicinessEnum.java +// (c)2021 MindView 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/enums/TrafficLight.java b/enums/TrafficLight.java index f315f8d27..a42089a7a 100644 --- a/enums/TrafficLight.java +++ b/enums/TrafficLight.java @@ -1,7 +1,7 @@ // enums/TrafficLight.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Enums in switch statements // Define an enum type: @@ -11,7 +11,7 @@ public class TrafficLight { Signal color = Signal.RED; public void change() { switch(color) { - // Note that you don't have to say Signal.RED + // Note you don't have to say Signal.RED // in the case statement: case RED: color = Signal.GREEN; break; @@ -21,8 +21,7 @@ public void change() { break; } } - @Override - public String toString() { + @Override public String toString() { return "The traffic light is " + color; } public static void main(String[] args) { diff --git a/enums/UpcastEnum.java b/enums/UpcastEnum.java index 85745cecd..5665e2e3d 100644 --- a/enums/UpcastEnum.java +++ b/enums/UpcastEnum.java @@ -1,7 +1,7 @@ // enums/UpcastEnum.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // No values() method if you upcast an enum enum Search { HITHER, YON } diff --git a/enums/VendingMachine.java b/enums/VendingMachine.java index f52705554..269dd0131 100644 --- a/enums/VendingMachine.java +++ b/enums/VendingMachine.java @@ -1,8 +1,8 @@ // enums/VendingMachine.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {Args: VendingMachineInput.txt} +// Visit http://OnJava8.com for more book information. +// {java VendingMachine VendingMachineInput.txt} import java.util.*; import java.io.IOException; import java.util.function.*; @@ -37,8 +37,7 @@ public class VendingMachine { enum StateDuration { TRANSIENT } // Tagging enum enum State { RESTING { - @Override - void next(Input input) { + @Override void next(Input input) { switch(Category.categorize(input)) { case MONEY: amount += input.amount(); @@ -51,8 +50,7 @@ void next(Input input) { } }, ADDING_MONEY { - @Override - void next(Input input) { + @Override void next(Input input) { switch(Category.categorize(input)) { case MONEY: amount += input.amount(); @@ -74,16 +72,14 @@ void next(Input input) { } }, DISPENSING(StateDuration.TRANSIENT) { - @Override - void next() { + @Override void next() { System.out.println("here is your " + selection); amount -= selection.amount(); state = GIVING_CHANGE; } }, GIVING_CHANGE(StateDuration.TRANSIENT) { - @Override - void next() { + @Override void next() { if(amount > 0) { System.out.println("Your change: " + amount); amount = 0; @@ -101,7 +97,8 @@ void next(Input input) { "next(Input input) for non-transient states"); } void next() { - throw new RuntimeException("Only call next() for " + + throw new RuntimeException( + "Only call next() for " + "StateDuration.TRANSIENT states"); } void output() { System.out.println(amount); } @@ -124,14 +121,15 @@ public static void main(String[] args) { // For a basic sanity check: class RandomInputSupplier implements Supplier { - @Override - public Input get() { return Input.randomSelection(); } + @Override public Input get() { + return Input.randomSelection(); + } } // Create Inputs from a file of ';'-separated strings: class FileInputSupplier implements Supplier { private Iterator input; - public FileInputSupplier(String fileName) { + FileInputSupplier(String fileName) { try { input = Files.lines(Paths.get(fileName)) .skip(1) // Skip the comment line @@ -143,11 +141,11 @@ public FileInputSupplier(String fileName) { throw new RuntimeException(e); } } - @Override - public Input get() { + @Override public Input get() { if(!input.hasNext()) return null; - return Enum.valueOf(Input.class, input.next().trim()); + return Enum.valueOf( + Input.class, input.next().trim()); } } /* Output: diff --git a/enums/build.xml b/enums/build.xml deleted file mode 100644 index e624bc0b3..000000000 --- a/enums/build.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/enums/cartoons/EnumImplementation.java b/enums/cartoons/EnumImplementation.java index 013aa3608..5d1cb0d50 100644 --- a/enums/cartoons/EnumImplementation.java +++ b/enums/cartoons/EnumImplementation.java @@ -1,18 +1,20 @@ // enums/cartoons/EnumImplementation.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 SplittableRandom rand = new SplittableRandom(47); - @Override - public CartoonCharacter get() { + SLAPPY, SPANKY, PUNCHY, + SILLY, BOUNCY, NUTTY, BOB; + private Random rand = + new Random(47); + @Override public CartoonCharacter get() { return values()[rand.nextInt(values().length)]; } } diff --git a/enums/menu/Course.java b/enums/menu/Course.java index ed5ae1d9f..7cb54ef1a 100644 --- a/enums/menu/Course.java +++ b/enums/menu/Course.java @@ -1,7 +1,7 @@ // enums/menu/Course.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package enums.menu; import onjava.*; diff --git a/enums/menu/Food.java b/enums/menu/Food.java index 4c2266789..51f4a8a07 100644 --- a/enums/menu/Food.java +++ b/enums/menu/Food.java @@ -1,7 +1,7 @@ // enums/menu/Food.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Subcategorization of enums within interfaces package enums.menu; @@ -11,7 +11,7 @@ enum Appetizer implements Food { } enum MainCourse implements Food { LASAGNE, BURRITO, PAD_THAI, - LENTILS, HUMMOUS, VINDALOO; + LENTILS, HUMMUS, VINDALOO; } enum Dessert implements Food { TIRAMISU, GELATO, BLACK_FOREST_CAKE, diff --git a/enums/menu/Meal.java b/enums/menu/Meal.java index 172ba45ec..48b7f723b 100644 --- a/enums/menu/Meal.java +++ b/enums/menu/Meal.java @@ -1,7 +1,8 @@ // enums/menu/Meal.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {java enums.menu.Meal} package enums.menu; public class Meal { @@ -11,7 +12,7 @@ public static void main(String[] args) { Food food = course.randomSelection(); System.out.println(food); } - System.out.println("---"); + System.out.println("***"); } } } @@ -20,25 +21,25 @@ public static void main(String[] args) { VINDALOO FRUIT DECAF_COFFEE ---- +*** SOUP VINDALOO FRUIT TEA ---- +*** SALAD BURRITO FRUIT TEA ---- +*** SALAD BURRITO CREME_CARAMEL LATTE ---- +*** SOUP BURRITO TIRAMISU ESPRESSO ---- +*** */ diff --git a/enums/menu/Meal2.java b/enums/menu/Meal2.java index 10946f98e..0064926e0 100644 --- a/enums/menu/Meal2.java +++ b/enums/menu/Meal2.java @@ -1,7 +1,8 @@ // enums/menu/Meal2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {java enums.menu.Meal2} package enums.menu; import onjava.*; @@ -20,7 +21,7 @@ enum Appetizer implements Food { } enum MainCourse implements Food { LASAGNE, BURRITO, PAD_THAI, - LENTILS, HUMMOUS, VINDALOO; + LENTILS, HUMMUS, VINDALOO; } enum Dessert implements Food { TIRAMISU, GELATO, BLACK_FOREST_CAKE, @@ -40,7 +41,7 @@ public static void main(String[] args) { Food food = meal.randomSelection(); System.out.println(food); } - System.out.println("---"); + System.out.println("***"); } } } @@ -49,25 +50,25 @@ public static void main(String[] args) { VINDALOO FRUIT DECAF_COFFEE ---- +*** SOUP VINDALOO FRUIT TEA ---- +*** SALAD BURRITO FRUIT TEA ---- +*** SALAD BURRITO CREME_CARAMEL LATTE ---- +*** SOUP BURRITO TIRAMISU ESPRESSO ---- +*** */ diff --git a/enums/menu/TypeOfFood.java b/enums/menu/TypeOfFood.java index f0abb7e5c..d11fce81c 100644 --- a/enums/menu/TypeOfFood.java +++ b/enums/menu/TypeOfFood.java @@ -1,7 +1,8 @@ // enums/menu/TypeOfFood.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {java enums.menu.TypeOfFood} package enums.menu; import static enums.menu.Food.*; diff --git a/equalshashcode/ComposedEquality.java b/equalshashcode/ComposedEquality.java new file mode 100644 index 000000000..58ad001de --- /dev/null +++ b/equalshashcode/ComposedEquality.java @@ -0,0 +1,64 @@ +// equalshashcode/ComposedEquality.java +// (c)2021 MindView LLC: see Copyright.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/collectionsindepth/CountedString.java b/equalshashcode/CountedString.java similarity index 68% rename from collectionsindepth/CountedString.java rename to equalshashcode/CountedString.java index 8c1bb480e..4b7c0aab7 100644 --- a/collectionsindepth/CountedString.java +++ b/equalshashcode/CountedString.java @@ -1,7 +1,7 @@ -// collectionsindepth/CountedString.java -// (c)2016 MindView LLC: see Copyright.txt +// equalshashcode/CountedString.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Creating a good hashCode() import java.util.*; @@ -14,18 +14,16 @@ public CountedString(String str) { s = str; created.add(s); // id is the total number of instances - // of this String in use by CountedString: + // of this String used by CountedString: for(String s2 : created) if(s2.equals(s)) id++; } - @Override - public String toString() { + @Override public String toString() { return "String: " + s + " id: " + id + " hashCode(): " + hashCode(); } - @Override - public int hashCode() { + @Override public int hashCode() { // The very simple approach: // return s.hashCode() * id; // Using Joshua Bloch's recipe: @@ -34,15 +32,13 @@ public int hashCode() { result = 37 * result + id; return result; } - @Override - public boolean equals(Object o) { + @Override public boolean equals(Object o) { return o instanceof CountedString && - s.equals(((CountedString)o).s) && - id == ((CountedString)o).id; + Objects.equals(s, ((CountedString)o).s) && + Objects.equals(id, ((CountedString)o).id); } public static void main(String[] args) { - Map map = - new HashMap<>(); + Map map = new HashMap<>(); CountedString[] cs = new CountedString[5]; for(int i = 0; i < cs.length; i++) { cs[i] = new CountedString("hi"); @@ -56,10 +52,10 @@ public static void main(String[] args) { } } /* 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} +{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 diff --git a/equalshashcode/DefaultComparison.java b/equalshashcode/DefaultComparison.java new file mode 100644 index 000000000..1c5c03ab9 --- /dev/null +++ b/equalshashcode/DefaultComparison.java @@ -0,0 +1,24 @@ +// equalshashcode/DefaultComparison.java +// (c)2021 MindView 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/equalshashcode/Equality.java b/equalshashcode/Equality.java new file mode 100644 index 000000000..46661bc8a --- /dev/null +++ b/equalshashcode/Equality.java @@ -0,0 +1,76 @@ +// equalshashcode/Equality.java +// (c)2021 MindView LLC: see Copyright.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/equalshashcode/EqualityFactory.java b/equalshashcode/EqualityFactory.java new file mode 100644 index 000000000..1718cdba2 --- /dev/null +++ b/equalshashcode/EqualityFactory.java @@ -0,0 +1,9 @@ +// equalshashcode/EqualityFactory.java +// (c)2021 MindView LLC: see Copyright.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/collectionsindepth/Groundhog.java b/equalshashcode/Groundhog.java similarity index 56% rename from collectionsindepth/Groundhog.java rename to equalshashcode/Groundhog.java index 2b0f5a4cb..bdc941114 100644 --- a/collectionsindepth/Groundhog.java +++ b/equalshashcode/Groundhog.java @@ -1,14 +1,13 @@ -// collectionsindepth/Groundhog.java -// (c)2016 MindView LLC: see Copyright.txt +// equalshashcode/Groundhog.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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() { + @Override public String toString() { return "Groundhog #" + number; } } diff --git a/collectionsindepth/Groundhog2.java b/equalshashcode/Groundhog2.java similarity index 56% rename from collectionsindepth/Groundhog2.java rename to equalshashcode/Groundhog2.java index 256e0768e..124eaa9e8 100644 --- a/collectionsindepth/Groundhog2.java +++ b/equalshashcode/Groundhog2.java @@ -1,17 +1,18 @@ -// collectionsindepth/Groundhog2.java -// (c)2016 MindView LLC: see Copyright.txt +// equalshashcode/Groundhog2.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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) { + @Override public boolean equals(Object o) { return o instanceof Groundhog2 && - (number == ((Groundhog2)o).number); + Objects.equals( + number, ((Groundhog2)o).number); } } diff --git a/equalshashcode/IndividualTest.java b/equalshashcode/IndividualTest.java new file mode 100644 index 000000000..0be8de2d9 --- /dev/null +++ b/equalshashcode/IndividualTest.java @@ -0,0 +1,31 @@ +// equalshashcode/IndividualTest.java +// (c)2021 MindView LLC: 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 reflection.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/equalshashcode/MapEntry.java b/equalshashcode/MapEntry.java new file mode 100644 index 000000000..fff73332a --- /dev/null +++ b/equalshashcode/MapEntry.java @@ -0,0 +1,36 @@ +// equalshashcode/MapEntry.java +// (c)2021 MindView 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/equalshashcode/Prediction.java b/equalshashcode/Prediction.java new file mode 100644 index 000000000..ab945fc52 --- /dev/null +++ b/equalshashcode/Prediction.java @@ -0,0 +1,14 @@ +// equalshashcode/Prediction.java +// (c)2021 MindView 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/collectionsindepth/SimpleHashMap.java b/equalshashcode/SimpleHashMap.java similarity index 55% rename from collectionsindepth/SimpleHashMap.java rename to equalshashcode/SimpleHashMap.java index f1c5b3311..b47806441 100644 --- a/collectionsindepth/SimpleHashMap.java +++ b/equalshashcode/SimpleHashMap.java @@ -1,7 +1,7 @@ -// collectionsindepth/SimpleHashMap.java -// (c)2016 MindView LLC: see Copyright.txt +// equalshashcode/SimpleHashMap.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // A demonstration hashed Map import java.util.*; import onjava.*; @@ -16,8 +16,7 @@ class SimpleHashMap extends AbstractMap { @SuppressWarnings("unchecked") LinkedList>[] buckets = new LinkedList[SIZE]; - @Override - public V put(K key, V value) { + @Override public V put(K key, V value) { V oldValue = null; int index = Math.abs(key.hashCode()) % SIZE; if(buckets[index] == null) @@ -40,8 +39,7 @@ public V put(K key, V value) { buckets[index].add(pair); return oldValue; } - @Override - public V get(Object key) { + @Override public V get(Object key) { int index = Math.abs(key.hashCode()) % SIZE; if(buckets[index] == null) return null; for(MapEntry iPair : buckets[index]) @@ -49,8 +47,7 @@ public V get(Object key) { return iPair.getValue(); return null; } - @Override - public Set> entrySet() { + @Override public Set> entrySet() { Set> set= new HashSet<>(); for(LinkedList> bucket : buckets) { if(bucket == null) continue; @@ -62,30 +59,29 @@ public Set> entrySet() { public static void main(String[] args) { SimpleHashMap m = new SimpleHashMap<>(); - m.putAll(Countries.capitals(25)); - System.out.println(m); - System.out.println(m.get("ERITREA")); - System.out.println(m.entrySet()); + 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: -{CAPE VERDE=Praia, ANGOLA=Luanda, ETHIOPIA=Addis Ababa, -BENIN=Porto-Novo, CONGO=Brazzaville, LESOTHO=Maseru, -CENTRAL AFRICAN REPUBLIC=Bangui, EQUATORIAL GUINEA=Malabo, -ERITREA=Asmara, COMOROS=Moroni, BURKINA FASO=Ouagadougou, -GABON=Libreville, THE GAMBIA=Banjul, GUINEA=Conakry, -EGYPT=Cairo, BURUNDI=Bujumbura, ALGERIA=Algiers, -CAMEROON=Yaounde, GHANA=Accra, KENYA=Nairobi, COTE D'IVOIR -(IVORY COAST)=Yamoussoukro, BISSAU=Bissau, -DJIBOUTI=Dijibouti, CHAD=N'djamena, BOTSWANA=Gaberone} -Asmara -[CAPE VERDE=Praia, ANGOLA=Luanda, ETHIOPIA=Addis Ababa, -BENIN=Porto-Novo, CONGO=Brazzaville, LESOTHO=Maseru, -CENTRAL AFRICAN REPUBLIC=Bangui, EQUATORIAL GUINEA=Malabo, -ERITREA=Asmara, COMOROS=Moroni, BURKINA FASO=Ouagadougou, -GABON=Libreville, THE GAMBIA=Banjul, GUINEA=Conakry, -EGYPT=Cairo, BURUNDI=Bujumbura, ALGERIA=Algiers, -CAMEROON=Yaounde, GHANA=Accra, KENYA=Nairobi, COTE D'IVOIR -(IVORY COAST)=Yamoussoukro, BISSAU=Bissau, -DJIBOUTI=Dijibouti, CHAD=N'djamena, BOTSWANA=Gaberone] +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/equalshashcode/SlowMap.java b/equalshashcode/SlowMap.java new file mode 100644 index 000000000..04d0a85d8 --- /dev/null +++ b/equalshashcode/SlowMap.java @@ -0,0 +1,62 @@ +// equalshashcode/SlowMap.java +// (c)2021 MindView 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/equalshashcode/SpringDetector.java b/equalshashcode/SpringDetector.java new file mode 100644 index 000000000..d92f20b54 --- /dev/null +++ b/equalshashcode/SpringDetector.java @@ -0,0 +1,62 @@ +// equalshashcode/SpringDetector.java +// (c)2021 MindView 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 #5: Six more weeks of Winter! +Groundhog #2: Early Spring! +Groundhog #1: Six more weeks of Winter! +Groundhog #0: Early Spring! +Groundhog #8: Early Spring! +Groundhog #6: Six more weeks of Winter! +Groundhog #4: Early Spring! +Groundhog #3: Early Spring! +Groundhog #7: Six more weeks of Winter! +Groundhog #9: Six more weeks of Winter! +Looking up prediction for Groundhog #3 +Key not found: Groundhog #3 +*/ diff --git a/equalshashcode/SpringDetector2.java b/equalshashcode/SpringDetector2.java new file mode 100644 index 000000000..fc0267562 --- /dev/null +++ b/equalshashcode/SpringDetector2.java @@ -0,0 +1,25 @@ +// equalshashcode/SpringDetector2.java +// (c)2021 MindView 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/collectionsindepth/StringHashCode.java b/equalshashcode/StringHashCode.java similarity index 66% rename from collectionsindepth/StringHashCode.java rename to equalshashcode/StringHashCode.java index ad29e3174..e8c2062be 100644 --- a/collectionsindepth/StringHashCode.java +++ b/equalshashcode/StringHashCode.java @@ -1,7 +1,7 @@ -// collectionsindepth/StringHashCode.java -// (c)2016 MindView LLC: see Copyright.txt +// equalshashcode/StringHashCode.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class StringHashCode { public static void main(String[] args) { diff --git a/equalshashcode/SubtypeEquality.java b/equalshashcode/SubtypeEquality.java new file mode 100644 index 000000000..8d86d6bad --- /dev/null +++ b/equalshashcode/SubtypeEquality.java @@ -0,0 +1,57 @@ +// equalshashcode/SubtypeEquality.java +// (c)2021 MindView LLC: see Copyright.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 931523a9 +*/ diff --git a/equalshashcode/SubtypeEquality2.java b/equalshashcode/SubtypeEquality2.java new file mode 100644 index 000000000..a107409ff --- /dev/null +++ b/equalshashcode/SubtypeEquality2.java @@ -0,0 +1,38 @@ +// equalshashcode/SubtypeEquality2.java +// (c)2021 MindView LLC: see Copyright.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 931523a9 +Pig2[1]: Ralph MEDIUM 931523a9 +*/ diff --git a/equalshashcode/SuccinctEquality.java b/equalshashcode/SuccinctEquality.java new file mode 100644 index 000000000..7564d5cc5 --- /dev/null +++ b/equalshashcode/SuccinctEquality.java @@ -0,0 +1,45 @@ +// equalshashcode/SuccinctEquality.java +// (c)2021 MindView LLC: see Copyright.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/exceptions/AlwaysFinally.java b/exceptions/AlwaysFinally.java index 29ab2b7ee..11d1e5dd6 100644 --- a/exceptions/AlwaysFinally.java +++ b/exceptions/AlwaysFinally.java @@ -1,7 +1,7 @@ // exceptions/AlwaysFinally.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Finally is always executed class FourException extends Exception {} diff --git a/exceptions/AutoCloseableDetails.java b/exceptions/AutoCloseableDetails.java index 698c0237b..3c0a0d036 100644 --- a/exceptions/AutoCloseableDetails.java +++ b/exceptions/AutoCloseableDetails.java @@ -1,14 +1,14 @@ // exceptions/AutoCloseableDetails.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class Reporter implements AutoCloseable { String name = getClass().getSimpleName(); - public Reporter() { + Reporter() { System.out.println("Creating " + name); } - public void close() { + @Override public void close() { System.out.println("Closing " + name); } } @@ -18,8 +18,10 @@ class Second extends Reporter {} public class AutoCloseableDetails { public static void main(String[] args) { - try(First f = new First(); - Second s = new Second()) { + try( + First f = new First(); + Second s = new Second() + ) { } } } diff --git a/exceptions/BetterNullPointerReports.java b/exceptions/BetterNullPointerReports.java new file mode 100644 index 000000000..e5ef495b2 --- /dev/null +++ b/exceptions/BetterNullPointerReports.java @@ -0,0 +1,43 @@ +// exceptions/BetterNullPointerReports.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 15 + +class A { + String s; + A(String s) { + this.s = s; + } +} + +class B { + A a; + B(A a) { + this.a = a; + } +} + +class C { + B b; + C(B b) { + this.b = b; + } +} + +public class BetterNullPointerReports { + public static void main(String[] args) { + C[] ca = { + new C(new B(new A(null))), + new C(new B(null)), + new C(null), + }; + for(C c: ca) { + try { + System.out.println(c.b.a.s); + } catch(NullPointerException npe) { + System.out.println(npe); + } + } + } +} diff --git a/exceptions/BodyException.java b/exceptions/BodyException.java index 12d953d2d..25a952a63 100644 --- a/exceptions/BodyException.java +++ b/exceptions/BodyException.java @@ -1,14 +1,16 @@ // exceptions/BodyException.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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()) { + try( + First f = new First(); + Second s2 = new Second() + ) { System.out.println("In body"); Third t = new Third(); new SecondExcept(); diff --git a/exceptions/Cleanup.java b/exceptions/Cleanup.java index 43be678fe..0912783d0 100644 --- a/exceptions/Cleanup.java +++ b/exceptions/Cleanup.java @@ -1,7 +1,7 @@ // exceptions/Cleanup.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Guaranteeing proper cleanup of a resource public class Cleanup { @@ -20,7 +20,8 @@ public static void main(String[] args) { in.dispose(); } } catch(Exception e) { - System.out.println("InputFile construction failed"); + System.out.println( + "InputFile construction failed"); } } } diff --git a/exceptions/CleanupIdiom.java b/exceptions/CleanupIdiom.java index 2728d0458..fdf6bd1c9 100644 --- a/exceptions/CleanupIdiom.java +++ b/exceptions/CleanupIdiom.java @@ -1,7 +1,7 @@ // exceptions/CleanupIdiom.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Disposable objects must be followed by a try-finally class NeedsCleanup { // Construction can't fail @@ -17,12 +17,12 @@ class ConstructionException extends Exception {} class NeedsCleanup2 extends NeedsCleanup { // Construction can fail: - public NeedsCleanup2() throws ConstructionException {} + NeedsCleanup2() throws ConstructionException {} } public class CleanupIdiom { public static void main(String[] args) { - // (1): + // [1]: NeedsCleanup nc1 = new NeedsCleanup(); try { // ... @@ -30,8 +30,9 @@ public static void main(String[] args) { nc1.dispose(); } - // (2): - // If construction cannot fail you can group objects: + // [2]: + // If construction cannot fail, + // you can group objects: NeedsCleanup nc2 = new NeedsCleanup(); NeedsCleanup nc3 = new NeedsCleanup(); try { @@ -41,7 +42,7 @@ public static void main(String[] args) { nc2.dispose(); } - // (3): + // [3]: // If construction can fail you must guard each one: try { NeedsCleanup2 nc4 = new NeedsCleanup2(); diff --git a/exceptions/CloseExceptions.java b/exceptions/CloseExceptions.java index 60ebd0855..bc31496bc 100644 --- a/exceptions/CloseExceptions.java +++ b/exceptions/CloseExceptions.java @@ -1,15 +1,16 @@ // exceptions/CloseExceptions.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class CloseException extends Exception {} class Reporter2 implements AutoCloseable { String name = getClass().getSimpleName(); - public Reporter2() { + Reporter2() { System.out.println("Creating " + name); } + @Override public void close() throws CloseException { System.out.println("Closing " + name); } @@ -25,9 +26,11 @@ public void close() throws CloseException { public class CloseExceptions { public static void main(String[] args) { - try(First f = new First(); - Closer c = new Closer(); - Second s = new Second()) { + 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); diff --git a/exceptions/ConstructorException.java b/exceptions/ConstructorException.java index 8d970cbee..24191d1ce 100644 --- a/exceptions/ConstructorException.java +++ b/exceptions/ConstructorException.java @@ -1,12 +1,12 @@ // exceptions/ConstructorException.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class CE extends Exception {} class SecondExcept extends Reporter { - public SecondExcept() throws CE { + SecondExcept() throws CE { super(); throw new CE(); } @@ -14,9 +14,11 @@ public SecondExcept() throws CE { public class ConstructorException { public static void main(String[] args) { - try(First f = new First(); - SecondExcept s = new SecondExcept(); - Second s2 = new Second()) { + 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); diff --git a/exceptions/DynamicFields.java b/exceptions/DynamicFields.java index 1e115500f..07f02b955 100644 --- a/exceptions/DynamicFields.java +++ b/exceptions/DynamicFields.java @@ -1,7 +1,7 @@ // exceptions/DynamicFields.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // A Class that dynamically adds fields to itself to // demonstrate exception chaining @@ -14,8 +14,7 @@ public DynamicFields(int initialSize) { for(int i = 0; i < initialSize; i++) fields[i] = new Object[] { null, null }; } - @Override - public String toString() { + @Override public String toString() { StringBuilder result = new StringBuilder(); for(Object[] obj : fields) { result.append(obj[0]); @@ -31,8 +30,8 @@ private int hasField(String id) { return i; return -1; } - private int - getFieldNumber(String id) throws NoSuchFieldException { + private int getFieldNumber(String id) + throws NoSuchFieldException { int fieldNum = hasField(id); if(fieldNum == -1) throw new NoSuchFieldException(); @@ -61,9 +60,10 @@ private int makeField(String id) { 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. + // 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()); @@ -95,7 +95,8 @@ public static void main(String[] args) { System.out.println("df: " + df); System.out.println("df.getField(\"d\") : " + df.getField("d")); - Object field = df.setField("d", null); // Exception + Object field = + df.setField("d", null); // Exception } catch(NoSuchFieldException | DynamicFieldsException e) { e.printStackTrace(System.out); @@ -118,9 +119,11 @@ public static void main(String[] args) { df.getField("d") : A new value for d DynamicFieldsException - at DynamicFields.setField(DynamicFields.java:64) - at DynamicFields.main(DynamicFields.java:95) + at +DynamicFields.setField(DynamicFields.java:64) + at DynamicFields.main(DynamicFields.java:96) Caused by: java.lang.NullPointerException - at DynamicFields.setField(DynamicFields.java:66) + at +DynamicFields.setField(DynamicFields.java:66) ... 1 more */ diff --git a/exceptions/EffectivelyFinalTWR.java b/exceptions/EffectivelyFinalTWR.java new file mode 100644 index 000000000..7ebeaf0d0 --- /dev/null +++ b/exceptions/EffectivelyFinalTWR.java @@ -0,0 +1,48 @@ +// exceptions/EffectivelyFinalTWR.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 9 +import java.io.*; + +public class EffectivelyFinalTWR { + static void old() { + try ( + InputStream r1 = new FileInputStream( + new File("TryWithResources.java")); + InputStream r2 = new FileInputStream( + new File("EffectivelyFinalTWR.java")); + ) { + r1.read(); + r2.read(); + } catch(IOException e) { + // Handle exceptions + } + } + static void jdk9() throws IOException { + final InputStream r1 = new FileInputStream( + new File("TryWithResources.java")); + // Effectively final: + InputStream r2 = new FileInputStream( + new File("EffectivelyFinalTWR.java")); + try (r1; r2) { + r1.read(); + r2.read(); + } + // r1 and r2 are still in scope. Accessing + // either one throws an exception: + r1.read(); + r2.read(); + } + public static void main(String[] args) { + old(); + try { + jdk9(); + } catch(IOException e) { + System.out.println(e); + } + } +} +/* Output: +java.io.IOException: Stream Closed +*/ diff --git a/exceptions/ExceptionMethods.java b/exceptions/ExceptionMethods.java index ac4c62610..d94c0b298 100644 --- a/exceptions/ExceptionMethods.java +++ b/exceptions/ExceptionMethods.java @@ -1,7 +1,7 @@ // exceptions/ExceptionMethods.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Demonstrating the Exception Methods public class ExceptionMethods { @@ -27,5 +27,6 @@ public static void main(String[] args) { toString():java.lang.Exception: My Exception printStackTrace(): java.lang.Exception: My Exception - at ExceptionMethods.main(ExceptionMethods.java:7) + at +ExceptionMethods.main(ExceptionMethods.java:7) */ diff --git a/exceptions/ExceptionSilencer.java b/exceptions/ExceptionSilencer.java index d65a3b5a4..c56132efe 100644 --- a/exceptions/ExceptionSilencer.java +++ b/exceptions/ExceptionSilencer.java @@ -1,7 +1,7 @@ // exceptions/ExceptionSilencer.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class ExceptionSilencer { public static void main(String[] args) { diff --git a/exceptions/ExtraFeatures.java b/exceptions/ExtraFeatures.java index 57200ce9c..abf9d0bef 100644 --- a/exceptions/ExtraFeatures.java +++ b/exceptions/ExtraFeatures.java @@ -1,20 +1,19 @@ // exceptions/ExtraFeatures.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Further embellishment of exception classes class MyException2 extends Exception { private int x; - public MyException2() {} - public MyException2(String msg) { super(msg); } - public MyException2(String msg, 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() { + @Override public String getMessage() { return "Detail Message: "+ x + " "+ super.getMessage(); } @@ -22,15 +21,18 @@ public String getMessage() { public class ExtraFeatures { public static void f() throws MyException2 { - System.out.println("Throwing MyException2 from f()"); + System.out.println( + "Throwing MyException2 from f()"); throw new MyException2(); } public static void g() throws MyException2 { - System.out.println("Throwing MyException2 from g()"); + 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()"); + System.out.println( + "Throwing MyException2 from h()"); throw new MyException2("Originated in h()", 47); } public static void main(String[] args) { @@ -55,15 +57,15 @@ public static void main(String[] args) { /* Output: Throwing MyException2 from f() MyException2: Detail Message: 0 null - at ExtraFeatures.f(ExtraFeatures.java:22) - at ExtraFeatures.main(ExtraFeatures.java:34) + at ExtraFeatures.f(ExtraFeatures.java:23) + at ExtraFeatures.main(ExtraFeatures.java:37) Throwing MyException2 from g() MyException2: Detail Message: 0 Originated in g() - at ExtraFeatures.g(ExtraFeatures.java:26) - at ExtraFeatures.main(ExtraFeatures.java:39) + at ExtraFeatures.g(ExtraFeatures.java:28) + at ExtraFeatures.main(ExtraFeatures.java:42) Throwing MyException2 from h() MyException2: Detail Message: 47 Originated in h() - at ExtraFeatures.h(ExtraFeatures.java:30) - at ExtraFeatures.main(ExtraFeatures.java:44) + at ExtraFeatures.h(ExtraFeatures.java:33) + at ExtraFeatures.main(ExtraFeatures.java:47) e.val() = 47 */ diff --git a/exceptions/FinallyWorks.java b/exceptions/FinallyWorks.java index 9856af23f..9870849c3 100644 --- a/exceptions/FinallyWorks.java +++ b/exceptions/FinallyWorks.java @@ -1,7 +1,7 @@ // exceptions/FinallyWorks.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // The finally clause is always executed class ThreeException extends Exception {} diff --git a/exceptions/FullConstructors.java b/exceptions/FullConstructors.java index 2bff925aa..bb10b0f1c 100644 --- a/exceptions/FullConstructors.java +++ b/exceptions/FullConstructors.java @@ -1,11 +1,11 @@ // exceptions/FullConstructors.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class MyException extends Exception { - public MyException() {} - public MyException(String msg) { super(msg); } + MyException() {} + MyException(String msg) { super(msg); } } public class FullConstructors { @@ -34,9 +34,11 @@ public static void main(String[] args) { Throwing MyException from f() MyException at FullConstructors.f(FullConstructors.java:11) - at FullConstructors.main(FullConstructors.java:19) + 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) + at +FullConstructors.main(FullConstructors.java:24) */ diff --git a/exceptions/Human.java b/exceptions/Human.java index a382a908c..b35f77954 100644 --- a/exceptions/Human.java +++ b/exceptions/Human.java @@ -1,7 +1,7 @@ // exceptions/Human.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Catching exception hierarchies class Annoyance extends Exception {} diff --git a/exceptions/InheritingExceptions.java b/exceptions/InheritingExceptions.java index 2e853411b..799134842 100644 --- a/exceptions/InheritingExceptions.java +++ b/exceptions/InheritingExceptions.java @@ -1,18 +1,20 @@ // exceptions/InheritingExceptions.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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()"); + System.out.println( + "Throw SimpleException from f()"); throw new SimpleException(); } public static void main(String[] args) { - InheritingExceptions sed = new InheritingExceptions(); + InheritingExceptions sed = + new InheritingExceptions(); try { sed.f(); } catch(SimpleException e) { diff --git a/exceptions/InputFile.java b/exceptions/InputFile.java index 7522d8488..d843a8347 100644 --- a/exceptions/InputFile.java +++ b/exceptions/InputFile.java @@ -1,7 +1,7 @@ // exceptions/InputFile.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Paying attention to exceptions in constructors import java.io.*; diff --git a/exceptions/InputFile2.java b/exceptions/InputFile2.java index 2544da604..4e8b8c49c 100644 --- a/exceptions/InputFile2.java +++ b/exceptions/InputFile2.java @@ -1,7 +1,7 @@ // exceptions/InputFile2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.io.*; import java.nio.file.*; import java.util.stream.*; diff --git a/exceptions/LoggingExceptions.java b/exceptions/LoggingExceptions.java index 2fe1f0243..67dcac911 100644 --- a/exceptions/LoggingExceptions.java +++ b/exceptions/LoggingExceptions.java @@ -1,7 +1,7 @@ // exceptions/LoggingExceptions.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // An exception that reports through a Logger // {ErrorOutputExpected} import java.util.logging.*; @@ -10,7 +10,7 @@ class LoggingException extends Exception { private static Logger logger = Logger.getLogger("LoggingException"); - public LoggingException() { + LoggingException() { StringWriter trace = new StringWriter(); printStackTrace(new PrintWriter(trace)); logger.severe(trace.toString()); @@ -33,17 +33,16 @@ public static void main(String[] args) { } /* Output: ___[ Error Output ]___ -Dec 15, 2015 10:34:24 PM LoggingException +Jan 24, 2021 8:48:54 AM LoggingException SEVERE: LoggingException at LoggingExceptions.main(LoggingExceptions.java:20) Caught LoggingException -Dec 15, 2015 10:34:24 PM LoggingException +Jan 24, 2021 8:48:54 AM LoggingException SEVERE: LoggingException at LoggingExceptions.main(LoggingExceptions.java:25) Caught LoggingException -___[ Error Output is Expected ]___ */ diff --git a/exceptions/LoggingExceptions2.java b/exceptions/LoggingExceptions2.java index ae7cffd42..2d1c1683c 100644 --- a/exceptions/LoggingExceptions2.java +++ b/exceptions/LoggingExceptions2.java @@ -1,7 +1,7 @@ // exceptions/LoggingExceptions2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Logging caught exceptions // {ErrorOutputExpected} import java.util.logging.*; @@ -25,9 +25,8 @@ public static void main(String[] args) { } /* Output: ___[ Error Output ]___ -Dec 15, 2015 10:34:25 PM LoggingExceptions2 logException +Jan 24, 2021 8:48:54 AM LoggingExceptions2 logException SEVERE: java.lang.NullPointerException at LoggingExceptions2.main(LoggingExceptions2.java:17) -___[ Error Output is Expected ]___ */ diff --git a/exceptions/LostMessage.java b/exceptions/LostMessage.java index e4876e670..75c57e1c2 100644 --- a/exceptions/LostMessage.java +++ b/exceptions/LostMessage.java @@ -1,19 +1,17 @@ // exceptions/LostMessage.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // How an exception can be lost class VeryImportantException extends Exception { - @Override - public String toString() { + @Override public String toString() { return "A very important exception!"; } } class HoHumException extends Exception { - @Override - public String toString() { + @Override public String toString() { return "A trivial exception"; } } diff --git a/exceptions/MainException.java b/exceptions/MainException.java index d42e01a8b..a6378469d 100644 --- a/exceptions/MainException.java +++ b/exceptions/MainException.java @@ -1,7 +1,7 @@ // exceptions/MainException.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.nio.file.*; diff --git a/exceptions/MessyExceptions.java b/exceptions/MessyExceptions.java index a672556ce..1441abd04 100644 --- a/exceptions/MessyExceptions.java +++ b/exceptions/MessyExceptions.java @@ -1,7 +1,7 @@ // exceptions/MessyExceptions.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.io.*; public class MessyExceptions { @@ -13,7 +13,7 @@ public static void main(String[] args) { int contents = in.read(); // Process contents } catch(IOException e) { - // Handle the error + // Handle errors } finally { if(in != null) { try { diff --git a/exceptions/MultiCatch.java b/exceptions/MultiCatch.java index 74e3667bb..c54bab5ea 100644 --- a/exceptions/MultiCatch.java +++ b/exceptions/MultiCatch.java @@ -1,7 +1,7 @@ // exceptions/MultiCatch.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class MultiCatch { void x() throws Except1, Except2, Except3, Except4 {} diff --git a/exceptions/MultiCatch2.java b/exceptions/MultiCatch2.java index b997d48e9..7dfd32dfe 100644 --- a/exceptions/MultiCatch2.java +++ b/exceptions/MultiCatch2.java @@ -1,7 +1,7 @@ // exceptions/MultiCatch2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class MultiCatch2 { void x() throws Except1, Except2, Except3, Except4 {} diff --git a/exceptions/MultipleReturns.java b/exceptions/MultipleReturns.java index 0b201f724..cd8968cb6 100644 --- a/exceptions/MultipleReturns.java +++ b/exceptions/MultipleReturns.java @@ -1,7 +1,7 @@ // exceptions/MultipleReturns.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class MultipleReturns { public static void f(int i) { diff --git a/exceptions/NeverCaught.java b/exceptions/NeverCaught.java index 633417383..bf8e101c2 100644 --- a/exceptions/NeverCaught.java +++ b/exceptions/NeverCaught.java @@ -1,7 +1,7 @@ // exceptions/NeverCaught.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Ignoring RuntimeExceptions // {ThrowsException} @@ -18,10 +18,9 @@ public static void main(String[] args) { } /* Output: ___[ Error Output ]___ -Exception in thread "main" java.lang.RuntimeException: From -f() +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) -___[ Exception is Expected ]___ */ diff --git a/exceptions/OnOffException1.java b/exceptions/OnOffException1.java index e459aad26..28caacc87 100644 --- a/exceptions/OnOffException1.java +++ b/exceptions/OnOffException1.java @@ -1,5 +1,5 @@ // exceptions/OnOffException1.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class OnOffException1 extends Exception {} diff --git a/exceptions/OnOffException2.java b/exceptions/OnOffException2.java index 22c0b6af1..99d149dae 100644 --- a/exceptions/OnOffException2.java +++ b/exceptions/OnOffException2.java @@ -1,5 +1,5 @@ // exceptions/OnOffException2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class OnOffException2 extends Exception {} diff --git a/exceptions/OnOffSwitch.java b/exceptions/OnOffSwitch.java index cee3501b9..f50273e0c 100644 --- a/exceptions/OnOffSwitch.java +++ b/exceptions/OnOffSwitch.java @@ -1,7 +1,7 @@ // exceptions/OnOffSwitch.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Why use finally? public class OnOffSwitch { diff --git a/exceptions/PreciseRethrow.java b/exceptions/PreciseRethrow.java index 81f0a1cce..1dc44e4ce 100644 --- a/exceptions/PreciseRethrow.java +++ b/exceptions/PreciseRethrow.java @@ -1,7 +1,7 @@ // exceptions/PreciseRethrow.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class BaseException extends Exception {} class DerivedException extends BaseException {} diff --git a/exceptions/RethrowNew.java b/exceptions/RethrowNew.java index 8e327ffb9..1725d0a25 100644 --- a/exceptions/RethrowNew.java +++ b/exceptions/RethrowNew.java @@ -1,15 +1,15 @@ // exceptions/RethrowNew.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Rethrow a different object from the one you caught class OneException extends Exception { - public OneException(String s) { super(s); } + OneException(String s) { super(s); } } class TwoException extends Exception { - public TwoException(String s) { super(s); } + TwoException(String s) { super(s); } } public class RethrowNew { diff --git a/exceptions/Rethrowing.java b/exceptions/Rethrowing.java index 734a61806..7a9c7200a 100644 --- a/exceptions/Rethrowing.java +++ b/exceptions/Rethrowing.java @@ -1,7 +1,7 @@ // exceptions/Rethrowing.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Demonstrating fillInStackTrace() public class Rethrowing { diff --git a/exceptions/SameHandler.java b/exceptions/SameHandler.java index 9b319bfa9..0e2b18252 100644 --- a/exceptions/SameHandler.java +++ b/exceptions/SameHandler.java @@ -1,7 +1,7 @@ // exceptions/SameHandler.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class EBase1 extends Exception {} class Except1 extends EBase1 {} diff --git a/exceptions/StormyInning.java b/exceptions/StormyInning.java index 6a792bd2d..b12d3a944 100644 --- a/exceptions/StormyInning.java +++ b/exceptions/StormyInning.java @@ -1,7 +1,7 @@ // exceptions/StormyInning.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 @@ -11,7 +11,7 @@ class Foul extends BaseballException {} class Strike extends BaseballException {} abstract class Inning { - public Inning() throws BaseballException {} + Inning() throws BaseballException {} public void event() throws BaseballException { // Doesn't actually have to throw anything } @@ -24,8 +24,8 @@ class RainedOut extends StormException {} class PopFoul extends Foul {} interface Storm { - public void event() throws RainedOut; - public void rainHard() throws RainedOut; + void event() throws RainedOut; + void rainHard() throws RainedOut; } public @@ -35,7 +35,7 @@ class StormyInning extends Inning implements Storm { public StormyInning() throws RainedOut, BaseballException {} public StormyInning(String s) - throws Foul, BaseballException {} + throws BaseballException {} // Regular methods must conform to base class: //- void walk() throws PopFoul {} //Compile error // Interface CANNOT add exceptions to existing @@ -43,15 +43,12 @@ public StormyInning(String s) //- 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 {} + @Override public void rainHard() throws RainedOut {} // You can choose to not throw any exceptions, // even if the base version does: - @Override - public void event() {} + @Override public void event() {} // Overridden methods can throw inherited exceptions: - @Override - public void atBat() throws PopFoul {} + @Override public void atBat() throws PopFoul {} public static void main(String[] args) { try { StormyInning si = new StormyInning(); diff --git a/exceptions/StreamsAreAutoCloseable.java b/exceptions/StreamsAreAutoCloseable.java index 153c73a9a..e07600c1e 100644 --- a/exceptions/StreamsAreAutoCloseable.java +++ b/exceptions/StreamsAreAutoCloseable.java @@ -1,7 +1,7 @@ // exceptions/StreamsAreAutoCloseable.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.io.*; import java.nio.file.*; import java.util.stream.*; @@ -9,14 +9,16 @@ 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) + 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) + } // [2] } } diff --git a/exceptions/Switch.java b/exceptions/Switch.java index ead8ba04a..6fb0ec780 100644 --- a/exceptions/Switch.java +++ b/exceptions/Switch.java @@ -1,7 +1,7 @@ // exceptions/Switch.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class Switch { private boolean state = false; @@ -14,8 +14,7 @@ public void off() { state = false; System.out.println(this); } - @Override - public String toString() { + @Override public String toString() { return state ? "on" : "off"; } } diff --git a/exceptions/TryAnything.java b/exceptions/TryAnything.java index 92656a698..faa446cd3 100644 --- a/exceptions/TryAnything.java +++ b/exceptions/TryAnything.java @@ -1,14 +1,16 @@ // exceptions/TryAnything.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {CompileTimeError} (Won't compile) +// 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()) { + try( + Anything a = new Anything() + ) { } } } diff --git a/exceptions/TryWithResources.java b/exceptions/TryWithResources.java index 1063cde8d..a82d261c3 100644 --- a/exceptions/TryWithResources.java +++ b/exceptions/TryWithResources.java @@ -1,17 +1,19 @@ // exceptions/TryWithResources.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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"))) { + try( + InputStream in = new FileInputStream( + new File("TryWithResources.java")) + ) { int contents = in.read(); // Process contents } catch(IOException e) { - // Handle the error + // Handle errors } } } diff --git a/exceptions/TurnOffChecking.java b/exceptions/TurnOffChecking.java index 7f916aee2..63e67ae7e 100644 --- a/exceptions/TurnOffChecking.java +++ b/exceptions/TurnOffChecking.java @@ -1,7 +1,7 @@ // exceptions/TurnOffChecking.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // "Turning off" Checked exceptions import java.io.*; @@ -11,7 +11,8 @@ void throwRuntimeException(int type) { switch(type) { case 0: throw new FileNotFoundException(); case 1: throw new IOException(); - case 2: throw new RuntimeException("Where am I?"); + case 2: throw new + RuntimeException("Where am I?"); default: return; } } catch(IOException | RuntimeException e) { @@ -25,9 +26,11 @@ 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: + 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++) @@ -37,7 +40,8 @@ public static void main(String[] args) { else throw new SomeOtherException(); } catch(SomeOtherException e) { - System.out.println("SomeOtherException: " + e); + System.out.println( + "SomeOtherException: " + e); } catch(RuntimeException re) { try { throw re.getCause(); diff --git a/exceptions/WhoCalled.java b/exceptions/WhoCalled.java index dbe1ff7c8..9bdfb5abf 100644 --- a/exceptions/WhoCalled.java +++ b/exceptions/WhoCalled.java @@ -1,7 +1,7 @@ // exceptions/WhoCalled.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Programmatic access to stack trace information public class WhoCalled { @@ -9,7 +9,7 @@ static void f() { // Generate an exception to fill in the stack trace try { throw new Exception(); - } catch (Exception e) { + } catch(Exception e) { for(StackTraceElement ste : e.getStackTrace()) System.out.println(ste.getMethodName()); } @@ -18,20 +18,20 @@ static void f() { static void h() { g(); } public static void main(String[] args) { f(); - System.out.println("-------------------------------"); + System.out.println("*******"); g(); - System.out.println("-------------------------------"); + System.out.println("*******"); h(); } } /* Output: f main -------------------------------- +******* f g main -------------------------------- +******* f g h diff --git a/exceptions/WithFinally.java b/exceptions/WithFinally.java index 40bb5c276..d392d6be8 100644 --- a/exceptions/WithFinally.java +++ b/exceptions/WithFinally.java @@ -1,7 +1,7 @@ // exceptions/WithFinally.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Finally Guarantees cleanup public class WithFinally { diff --git a/exceptions/build.xml b/exceptions/build.xml deleted file mode 100644 index 313fd7fa6..000000000 --- a/exceptions/build.xml +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/files/AddAndSubtractPaths.java b/files/AddAndSubtractPaths.java index d107bf957..06409c9c8 100644 --- a/files/AddAndSubtractPaths.java +++ b/files/AddAndSubtractPaths.java @@ -1,7 +1,7 @@ // files/AddAndSubtractPaths.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.nio.file.*; import java.io.IOException; @@ -18,7 +18,7 @@ static void show(int id, Path result) { try { System.out.println("RealPath: " + result.toRealPath()); - } catch (IOException e) { + } catch(IOException e) { System.out.println(e); } } @@ -53,35 +53,29 @@ public static void main(String[] args) { } /* Output: Windows 10 -C:\Users\Bruce\Documents\Git -(1)r on- -java\ExtractedExamples\files\AddAndSubtractPaths.java -RealPath: C:\Users\Bruce\Documents\Git\on- -java\ExtractedExamples\files\AddAndSubtractPaths.java -(2)r on-java\ExtractedExamples\strings\..\files -RealPath: C:\Users\Bruce\Documents\Git\on- -java\ExtractedExamples\files -(3)r on-java\ExtractedExamples\files -RealPath: C:\Users\Bruce\Documents\Git\on- -java\ExtractedExamples\files +C:\Git +(1)r OnJava8\ExtractedExamples\files\AddAndSubtractPaths.java +RealPath: +C:\Git\OnJava8\ExtractedExamples\files\AddAndSubtractPaths.java +(2)r OnJava8\ExtractedExamples\files +RealPath: C:\Git\OnJava8\ExtractedExamples\files +(3)r OnJava8\ExtractedExamples\files +RealPath: C:\Git\OnJava8\ExtractedExamples\files (4) ..\.. -RealPath: C:\Users\Bruce\Documents\Git\on-java +RealPath: C:\Git\OnJava8 (5) ..\.. -RealPath: C:\Users\Bruce\Documents\Git\on-java -(6)r on-java -RealPath: C:\Users\Bruce\Documents\Git\on-java -(7)r on-java\ExtractedExamples\files\.\..\.. -RealPath: C:\Users\Bruce\Documents\Git\on-java -(8)r on-java -RealPath: C:\Users\Bruce\Documents\Git\on-java -(9)r on-java\ExtractedExamples\files -RealPath: C:\Users\Bruce\Documents\Git\on- -java\ExtractedExamples\files -(10)r on-java\ExtractedExamples\strings -RealPath: C:\Users\Bruce\Documents\Git\on- -java\ExtractedExamples\strings +RealPath: C:\Git\OnJava8 +(6)r OnJava8 +RealPath: C:\Git\OnJava8 +(7)r OnJava8 +RealPath: C:\Git\OnJava8 +(8)r OnJava8 +RealPath: C:\Git\OnJava8 +(9)r OnJava8\ExtractedExamples\files +RealPath: C:\Git\OnJava8\ExtractedExamples\files +(10)r OnJava8\ExtractedExamples\strings +RealPath: C:\Git\OnJava8\ExtractedExamples\strings (11) nonexistent java.nio.file.NoSuchFileException: -C:\Users\Bruce\Documents\Git\on- -java\ExtractedExamples\files\nonexistent +C:\Git\OnJava8\ExtractedExamples\files\nonexistent */ diff --git a/files/Directories.java b/files/Directories.java index 434bf01ec..ffce7ecab 100644 --- a/files/Directories.java +++ b/files/Directories.java @@ -1,7 +1,7 @@ // files/Directories.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.nio.file.*; import onjava.RmDir; @@ -59,7 +59,7 @@ static void populateTestDir() throws Exception { test\bag test\bar test\baz -test\DIR_8446534140186618410 +test\DIR_8683707748599240459 test\foo test\Hello.txt ********* @@ -68,27 +68,27 @@ static void populateTestDir() throws Exception { test\bag\foo test\bag\foo\bar test\bag\foo\bar\baz -test\bag\foo\bar\baz\7681439653764312519.tmp +test\bag\foo\bar\baz\4316127347949967230.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\231438590599434409.tmp +test\bar\baz\bag\foo\1223263495976065729.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\2568963174268478267.tmp +test\baz\bag\foo\bar\6666183168609095028.tmp test\baz\bag\foo\bar\File.txt -test\DIR_8446534140186618410 -test\DIR_8446534140186618410\pre4960544428685536384.non +test\DIR_8683707748599240459 +test\DIR_8683707748599240459\pre6366626804787365549.non test\foo test\foo\bar test\foo\bar\baz test\foo\bar\baz\bag -test\foo\bar\baz\bag\8569628193069437000.tmp +test\foo\bar\baz\bag\4712324129011589115.tmp test\foo\bar\baz\bag\File.txt test\Hello.txt */ diff --git a/files/File_System.java b/files/FileSystemDemo.java similarity index 72% rename from files/File_System.java rename to files/FileSystemDemo.java index d173810de..51f47cabd 100644 --- a/files/File_System.java +++ b/files/FileSystemDemo.java @@ -1,10 +1,10 @@ -// files/File_System.java -// (c)2016 MindView LLC: see Copyright.txt +// files/FileSystemDemo.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.nio.file.*; -public class File_System { +public class FileSystemDemo { static void show(String id, Object o) { System.out.println(id + ": " + o); } @@ -28,14 +28,20 @@ public static void main(String[] args) { /* Output: Windows 10 File Store: (C:) +File Store: System Reserved (E:) +File Store: (F:) +File Store: Google Drive (G:) Root Directory: C:\ Root Directory: D:\ +Root Directory: E:\ +Root Directory: F:\ +Root Directory: G:\ Separator: \ UserPrincipalLookupService: -sun.nio.fs.WindowsFileSystem$LookupService$1@106d69c +sun.nio.fs.WindowsFileSystem$LookupService$1@1bd4fdd isOpen: true isReadOnly: false FileSystemProvider: -sun.nio.fs.WindowsFileSystemProvider@52e922 +sun.nio.fs.WindowsFileSystemProvider@55183b20 File Attribute Views: [owner, dos, acl, basic, user] */ diff --git a/files/Find.java b/files/Find.java index babf8eb5d..d27c69ed7 100644 --- a/files/Find.java +++ b/files/Find.java @@ -1,7 +1,8 @@ // files/Find.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {ExcludeFromGradle} import java.nio.file.*; public class Find { @@ -36,24 +37,24 @@ public class Find { } } /* Output: -test\bag\foo\bar\baz\7875645296823748474.tmp +test\bag\foo\bar\baz\5208762845883213974.tmp test\bag\foo\bar\baz\File.txt -test\bar\baz\bag\foo\8495339501512512468.tmp +test\bar\baz\bag\foo\7918367201207778677.tmp test\bar\baz\bag\foo\File.txt -test\baz\bag\foo\bar\4657930969137717517.tmp +test\baz\bag\foo\bar\8016595521026696632.tmp test\baz\bag\foo\bar\File.txt test\dir.tmp -test\foo\bar\baz\bag\5205870604020775563.tmp +test\foo\bar\baz\bag\5832319279813617280.tmp test\foo\bar\baz\bag\File.txt *************** -7875645296823748474.tmp -8495339501512512468.tmp -4657930969137717517.tmp +5208762845883213974.tmp +7918367201207778677.tmp +8016595521026696632.tmp dir.tmp -5205870604020775563.tmp +5832319279813617280.tmp *************** -7875645296823748474.tmp -8495339501512512468.tmp -4657930969137717517.tmp -5205870604020775563.tmp +5208762845883213974.tmp +7918367201207778677.tmp +8016595521026696632.tmp +5832319279813617280.tmp */ diff --git a/files/ListOfLines.java b/files/ListOfLines.java index 21c4ebc0b..ef1a7c4ec 100644 --- a/files/ListOfLines.java +++ b/files/ListOfLines.java @@ -1,22 +1,20 @@ // files/ListOfLines.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 { - List lines = Files.readAllLines( - Paths.get("../streams/Cheese.dat")); - for(String line : lines) { - if(line.startsWith("//")) - continue; - System.out.println( - line.substring(0, line.length()/2)); - } - + 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: diff --git a/files/PartsOfPaths.java b/files/PartsOfPaths.java index c9627a460..63a581e52 100644 --- a/files/PartsOfPaths.java +++ b/files/PartsOfPaths.java @@ -1,7 +1,7 @@ // files/PartsOfPaths.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.nio.file.*; public class PartsOfPaths { @@ -11,8 +11,6 @@ public static void main(String[] args) { Paths.get("PartsOfPaths.java").toAbsolutePath(); for(int i = 0; i < p.getNameCount(); i++) System.out.println(p.getName(i)); - Path sub = p.subpath(3, p.getNameCount() - 2); - System.out.println(sub); System.out.println("ends with '.java': " + p.endsWith(".java")); for(Path pp : p) { @@ -26,21 +24,14 @@ public static void main(String[] args) { } /* Output: Windows 10 -Users -Bruce -Documents Git -on-java +OnJava8 ExtractedExamples files PartsOfPaths.java -Git\on-java\ExtractedExamples ends with '.java': false -Users: false : false -Bruce: false : false -Documents: false : false Git: false : false -on-java: false : false +OnJava8: false : false ExtractedExamples: false : false files: false : false PartsOfPaths.java: false : true diff --git a/files/PathAnalysis.java b/files/PathAnalysis.java index 77b4603d2..9800ed2c5 100644 --- a/files/PathAnalysis.java +++ b/files/PathAnalysis.java @@ -1,7 +1,7 @@ // files/PathAnalysis.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.nio.file.*; import java.io.IOException; @@ -32,7 +32,7 @@ static void say(String id, Object result) { if(Files.isSymbolicLink(p)) say("SymbolicLink", Files.readSymbolicLink(p)); if(FileSystems.getDefault() - .supportedFileAttributeViews().contains("posix")) + .supportedFileAttributeViews().contains("posix")) say("PosixFilePermissions", Files.getPosixFilePermissions(p)); } @@ -49,8 +49,8 @@ static void say(String id, Object result) { Hidden: false size: 1617 FileStore: (C:) -LastModified: : 2015-12-13T21:24:32.029627Z +LastModified: : 2021-11-08T00:34:52.693768Z Owner: GROOT\Bruce (User) -ContentType: null +ContentType: text/plain SymbolicLink: false */ diff --git a/files/PathInfo.java b/files/PathInfo.java index 3dbae20b8..78ef9e48b 100644 --- a/files/PathInfo.java +++ b/files/PathInfo.java @@ -1,7 +1,7 @@ // files/PathInfo.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.nio.file.*; import java.net.URI; import java.io.File; @@ -9,18 +9,18 @@ public class PathInfo { static void show(String id, Object p) { - System.out.println(id + ": " + 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("----------------"); + show("toString:\n ", 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")); @@ -33,11 +33,11 @@ public static void main(String[] args) { info(ap.getParent()); try { info(p.toRealPath()); - } catch (IOException e) { + } catch(IOException e) { System.out.println(e); } URI u = p.toUri(); - System.out.println("URI: " + u); + System.out.println("URI:\n" + u); Path puri = Paths.get(u); System.out.println(Files.exists(puri)); File f = ap.toFile(); // Don't be fooled @@ -45,7 +45,8 @@ public static void main(String[] args) { } /* Output: Windows 10 -toString: C:\path\to\nowhere\NoFile.txt +toString: + C:\path\to\nowhere\NoFile.txt Exists: false RegularFile: false Directory: false @@ -53,8 +54,9 @@ public static void main(String[] args) { FileName: NoFile.txt Parent: C:\path\to\nowhere Root: C:\ ----------------- -toString: PathInfo.java +****************** +toString: + PathInfo.java Exists: true RegularFile: true Directory: false @@ -62,41 +64,38 @@ public static void main(String[] args) { FileName: PathInfo.java Parent: null Root: null ----------------- -toString: C:\Users\Bruce\Documents\Git\on- -java\ExtractedExamples\files\PathInfo.java +****************** +toString: + C:\Git\OnJava8\ExtractedExamples\files\PathInfo.java Exists: true RegularFile: true Directory: false Absolute: true FileName: PathInfo.java -Parent: C:\Users\Bruce\Documents\Git\on- -java\ExtractedExamples\files +Parent: C:\Git\OnJava8\ExtractedExamples\files Root: C:\ ----------------- -toString: C:\Users\Bruce\Documents\Git\on- -java\ExtractedExamples\files +****************** +toString: + C:\Git\OnJava8\ExtractedExamples\files Exists: true RegularFile: false Directory: true Absolute: true FileName: files -Parent: C:\Users\Bruce\Documents\Git\on- -java\ExtractedExamples +Parent: C:\Git\OnJava8\ExtractedExamples Root: C:\ ----------------- -toString: C:\Users\Bruce\Documents\Git\on- -java\ExtractedExamples\files\PathInfo.java +****************** +toString: + C:\Git\OnJava8\ExtractedExamples\files\PathInfo.java Exists: true RegularFile: true Directory: false Absolute: true FileName: PathInfo.java -Parent: C:\Users\Bruce\Documents\Git\on- -java\ExtractedExamples\files +Parent: C:\Git\OnJava8\ExtractedExamples\files Root: C:\ ----------------- -URI: file:///C:/Users/Bruce/Documents/Git/on- -java/ExtractedExamples/files/PathInfo.java +****************** +URI: +file:///C:/Git/OnJava8/ExtractedExamples/files/PathInfo.java true */ diff --git a/files/PathWatcher.java b/files/PathWatcher.java index bee1dcddf..8a1f46107 100644 --- a/files/PathWatcher.java +++ b/files/PathWatcher.java @@ -1,7 +1,8 @@ // files/PathWatcher.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {ExcludeFromGradle} import java.io.IOException; import java.nio.file.*; import static java.nio.file.StandardWatchEventKinds.*; @@ -34,8 +35,10 @@ static void delTxtFiles() { WatchService watcher = FileSystems.getDefault().newWatchService(); test.register(watcher, ENTRY_DELETE); - Executors.newSingleThreadScheduledExecutor().schedule( - PathWatcher::delTxtFiles,250,TimeUnit.MILLISECONDS); + Executors.newSingleThreadScheduledExecutor() + .schedule( + PathWatcher::delTxtFiles, + 250, TimeUnit.MILLISECONDS); WatchKey key = watcher.take(); for(WatchEvent evt : key.pollEvents()) { System.out.println( diff --git a/files/ReadLineStream.java b/files/ReadLineStream.java index d33a37b43..812ed1058 100644 --- a/files/ReadLineStream.java +++ b/files/ReadLineStream.java @@ -1,7 +1,7 @@ // files/ReadLineStream.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.nio.file.*; public class ReadLineStream { @@ -14,5 +14,5 @@ public class ReadLineStream { } } /* Output: -show("RegularFile", Files.isRegularFile(p)); + show("RegularFile", Files.isRegularFile(p)); */ diff --git a/files/StreamInAndOut.java b/files/StreamInAndOut.java index 1984e6e61..4f7297d55 100644 --- a/files/StreamInAndOut.java +++ b/files/StreamInAndOut.java @@ -1,17 +1,19 @@ // files/StreamInAndOut.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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")) { + try( + Stream input = + Files.lines(Paths.get("StreamInAndOut.java")); + PrintWriter output = + new PrintWriter("StreamInAndOut.txt") + ) { input .map(String::toUpperCase) .forEachOrdered(output::println); diff --git a/files/TreeWatcher.java b/files/TreeWatcher.java index fa7abeeb2..1162ff807 100644 --- a/files/TreeWatcher.java +++ b/files/TreeWatcher.java @@ -1,7 +1,8 @@ // files/TreeWatcher.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {ExcludeFromGradle} import java.io.IOException; import java.nio.file.*; import static java.nio.file.StandardWatchEventKinds.*; @@ -43,8 +44,8 @@ static void watchDir(Path dir) { } /* 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 -deleting test\bar\baz\bag\foo\File.txt */ diff --git a/files/Writing.java b/files/Writing.java index f26d1fb4e..82745e4d5 100644 --- a/files/Writing.java +++ b/files/Writing.java @@ -1,17 +1,17 @@ // files/Writing.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 sz = 1000; + static final int SIZE = 1000; public static void main(String[] args) throws Exception { // Write bytes to a file: - byte[] bytes = new byte[sz]; + byte[] bytes = new byte[SIZE]; rand.nextBytes(bytes); Files.write(Paths.get("bytes.dat"), bytes); System.out.println("bytes.dat: " + diff --git a/files/build.xml b/files/build.xml deleted file mode 100644 index e7be87585..000000000 --- a/files/build.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/functional/AnonymousClosure.java b/functional/AnonymousClosure.java index 9f5b46458..6faa0925e 100644 --- a/functional/AnonymousClosure.java +++ b/functional/AnonymousClosure.java @@ -1,11 +1,11 @@ // functional/AnonymousClosure.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.function.*; public class AnonymousClosure { - IntSupplier make_fun(int x) { + IntSupplier makeFun(int x) { int i = 0; // Same rules apply: // i++; // Not "effectively final" diff --git a/functional/BiConsumerPermutations.java b/functional/BiConsumerPermutations.java index e9f63225c..091967fb1 100644 --- a/functional/BiConsumerPermutations.java +++ b/functional/BiConsumerPermutations.java @@ -1,16 +1,16 @@ // functional/BiConsumerPermutations.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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); + System.out.format("%d, %f%n", i, d); static BiConsumer bicdi = (d, i) -> - System.out.format("%d, %f\n", i, d); + System.out.format("%d, %f%n", i, d); static BiConsumer bicil = (i, l) -> - System.out.format("%d, %d\n", 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); diff --git a/functional/ClassFunctionals.java b/functional/ClassFunctionals.java index 112a74640..eb7548229 100644 --- a/functional/ClassFunctionals.java +++ b/functional/ClassFunctionals.java @@ -1,7 +1,7 @@ // functional/ClassFunctionals.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.function.*; diff --git a/functional/Closure1.java b/functional/Closure1.java index c20798cd4..90bd9671d 100644 --- a/functional/Closure1.java +++ b/functional/Closure1.java @@ -1,12 +1,12 @@ // functional/Closure1.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.function.*; public class Closure1 { int i; - IntSupplier make_fun(int x) { + IntSupplier makeFun(int x) { return () -> x + i++; } } diff --git a/functional/Closure2.java b/functional/Closure2.java index 6e1986021..86129103d 100644 --- a/functional/Closure2.java +++ b/functional/Closure2.java @@ -1,11 +1,11 @@ // functional/Closure2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.function.*; public class Closure2 { - IntSupplier make_fun(int x) { + IntSupplier makeFun(int x) { int i = 0; return () -> x + i; } diff --git a/functional/Closure3.java b/functional/Closure3.java index 0a90848e6..40728b5f3 100644 --- a/functional/Closure3.java +++ b/functional/Closure3.java @@ -1,12 +1,12 @@ // functional/Closure3.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {CompileTimeError} (Won't compile) +// Visit http://OnJava8.com for more book information. +// {WillNotCompile} import java.util.function.*; public class Closure3 { - IntSupplier make_fun(int x) { + IntSupplier makeFun(int x) { int i = 0; // Neither x++ nor i++ will work: return () -> x++ + i++; diff --git a/functional/Closure4.java b/functional/Closure4.java index c253aaf86..06f34afbf 100644 --- a/functional/Closure4.java +++ b/functional/Closure4.java @@ -1,11 +1,11 @@ // functional/Closure4.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.function.*; public class Closure4 { - IntSupplier make_fun(final int x) { + IntSupplier makeFun(final int x) { final int i = 0; return () -> x + i; } diff --git a/functional/Closure5.java b/functional/Closure5.java index f0da51852..dcd7a08f4 100644 --- a/functional/Closure5.java +++ b/functional/Closure5.java @@ -1,12 +1,12 @@ // functional/Closure5.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {CompileTimeError} (Won't compile) +// Visit http://OnJava8.com for more book information. +// {WillNotCompile} import java.util.function.*; public class Closure5 { - IntSupplier make_fun(int x) { + IntSupplier makeFun(int x) { int i = 0; i++; x++; diff --git a/functional/Closure6.java b/functional/Closure6.java index 0251a3e6d..b102a67af 100644 --- a/functional/Closure6.java +++ b/functional/Closure6.java @@ -1,16 +1,16 @@ // functional/Closure6.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.function.*; public class Closure6 { - IntSupplier make_fun(int x) { + IntSupplier makeFun(int x) { int i = 0; i++; x++; - final int i_final = i; - final int x_final = x; - return () -> x_final + i_final; + final int iFinal = i; + final int xFinal = x; + return () -> xFinal + iFinal; } } diff --git a/functional/Closure7.java b/functional/Closure7.java index c9e514c57..098685296 100644 --- a/functional/Closure7.java +++ b/functional/Closure7.java @@ -1,13 +1,13 @@ // functional/Closure7.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {CompileTimeError} (Won't compile) +// Visit http://OnJava8.com for more book information. +// {WillNotCompile} import java.util.function.*; public class Closure7 { - IntSupplier make_fun(int x) { - Integer i = new Integer(0); + IntSupplier makeFun(int x) { + Integer i = 0; i = i + 1; return () -> x + i; } diff --git a/functional/Closure8.java b/functional/Closure8.java index 655dcf45f..8cfa1041b 100644 --- a/functional/Closure8.java +++ b/functional/Closure8.java @@ -1,12 +1,12 @@ // functional/Closure8.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.function.*; public class Closure8 { - Supplier> make_fun() { + Supplier> makeFun() { final List ai = new ArrayList<>(); ai.add(1); return () -> ai; @@ -14,8 +14,8 @@ Supplier> make_fun() { public static void main(String[] args) { Closure8 c7 = new Closure8(); List - l1 = c7.make_fun().get(), - l2 = c7.make_fun().get(); + l1 = c7.makeFun().get(), + l2 = c7.makeFun().get(); System.out.println(l1); System.out.println(l2); l1.add(42); diff --git a/functional/Closure9.java b/functional/Closure9.java index 0201321e6..4679e474e 100644 --- a/functional/Closure9.java +++ b/functional/Closure9.java @@ -1,13 +1,13 @@ // functional/Closure9.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {CompileTimeError} (Won't compile) +// Visit http://OnJava8.com for more book information. +// {WillNotCompile} import java.util.*; import java.util.function.*; public class Closure9 { - Supplier> make_fun() { + Supplier> makeFun() { List ai = new ArrayList<>(); ai = new ArrayList<>(); // Reassignment return () -> ai; diff --git a/functional/ConsumeFunction.java b/functional/ConsumeFunction.java index 9da3e2ceb..328bd9fcf 100644 --- a/functional/ConsumeFunction.java +++ b/functional/ConsumeFunction.java @@ -1,7 +1,7 @@ // functional/ConsumeFunction.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.function.*; class One {} diff --git a/functional/CtorReference.java b/functional/CtorReference.java index 7027d6e1f..ec74b00f7 100644 --- a/functional/CtorReference.java +++ b/functional/CtorReference.java @@ -1,7 +1,7 @@ // functional/CtorReference.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class Dog { String name; @@ -25,9 +25,9 @@ interface Make2Args { public class CtorReference { public static void main(String[] args) { - MakeNoArgs mna = Dog::new; // (1) - Make1Arg m1a = Dog::new; // (2) - Make2Args m2a = Dog::new; // (3) + MakeNoArgs mna = Dog::new; // [1] + Make1Arg m1a = Dog::new; // [2] + Make2Args m2a = Dog::new; // [3] Dog dn = mna.make(); Dog d1 = m1a.make("Comet"); diff --git a/functional/CurriedIntAdd.java b/functional/CurriedIntAdd.java index 041a94bef..6c430f70e 100644 --- a/functional/CurriedIntAdd.java +++ b/functional/CurriedIntAdd.java @@ -1,7 +1,7 @@ // functional/CurriedIntAdd.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.function.*; public class CurriedIntAdd { diff --git a/functional/Curry3Args.java b/functional/Curry3Args.java index 44dc342ce..5a307480f 100644 --- a/functional/Curry3Args.java +++ b/functional/Curry3Args.java @@ -1,7 +1,7 @@ // functional/Curry3Args.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.function.*; public class Curry3Args { diff --git a/functional/CurryingAndPartials.java b/functional/CurryingAndPartials.java index 01b45f671..d92912a72 100644 --- a/functional/CurryingAndPartials.java +++ b/functional/CurryingAndPartials.java @@ -1,7 +1,7 @@ // functional/CurryingAndPartials.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.function.*; public class CurryingAndPartials { @@ -12,16 +12,17 @@ static String uncurried(String a, String b) { public static void main(String[] args) { // Curried function: Function> sum = - a -> b -> a + b; // (1) + a -> b -> a + b; // [1] System.out.println(uncurried("Hi ", "Ho")); Function - hi = sum.apply("Hi "); // (2) + hi = sum.apply("Hi "); // [2] System.out.println(hi.apply("Ho")); // Partial application: - Function sumHi = sum.apply("Hup "); + Function sumHi = + sum.apply("Hup "); System.out.println(sumHi.apply("Ho")); System.out.println(sumHi.apply("Hey")); } diff --git a/functional/FunctionComposition.java b/functional/FunctionComposition.java index 9caed6dcc..f20b115ca 100644 --- a/functional/FunctionComposition.java +++ b/functional/FunctionComposition.java @@ -1,7 +1,7 @@ // functional/FunctionComposition.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.function.*; public class FunctionComposition { diff --git a/functional/FunctionVariants.java b/functional/FunctionVariants.java index ae6f544eb..0c4b42484 100644 --- a/functional/FunctionVariants.java +++ b/functional/FunctionVariants.java @@ -1,33 +1,33 @@ // functional/FunctionVariants.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.function.*; class Foo {} class Bar { Foo f; - public Bar(Foo f) { this.f = f; } + Bar(Foo f) { this.f = f; } } class IBaz { int i; - public IBaz(int i) { + IBaz(int i) { this.i = i; } } class LBaz { long l; - public LBaz(long l) { + LBaz(long l) { this.l = l; } } class DBaz { double d; - public DBaz(double d) { + DBaz(double d) { this.d = d; } } diff --git a/functional/FunctionWithWrapped.java b/functional/FunctionWithWrapped.java index 9f493f17f..253f8820c 100644 --- a/functional/FunctionWithWrapped.java +++ b/functional/FunctionWithWrapped.java @@ -1,7 +1,7 @@ // functional/FunctionWithWrapped.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.function.*; public class FunctionWithWrapped { diff --git a/functional/FunctionalAnnotation.java b/functional/FunctionalAnnotation.java index 780bf78ee..29cc33056 100644 --- a/functional/FunctionalAnnotation.java +++ b/functional/FunctionalAnnotation.java @@ -1,7 +1,7 @@ // functional/FunctionalAnnotation.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. @FunctionalInterface interface Functional { @@ -29,7 +29,8 @@ public String goodbye(String arg) { return "Goodbye, " + arg; } public static void main(String[] args) { - FunctionalAnnotation fa = new FunctionalAnnotation(); + FunctionalAnnotation fa = + new FunctionalAnnotation(); Functional f = fa::goodbye; FunctionalNoAnn fna = fa::goodbye; // Functional fac = fa; // Incompatible diff --git a/functional/IntCall.java b/functional/IntCall.java index ed62e3073..910c2ac35 100644 --- a/functional/IntCall.java +++ b/functional/IntCall.java @@ -1,7 +1,7 @@ // functional/IntCall.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. interface IntCall { int call(int arg); diff --git a/functional/LambdaExpressions.java b/functional/LambdaExpressions.java index 23245a113..3c4a40b03 100644 --- a/functional/LambdaExpressions.java +++ b/functional/LambdaExpressions.java @@ -1,7 +1,7 @@ // functional/LambdaExpressions.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. interface Description { String brief(); @@ -17,15 +17,15 @@ interface Multi { public class LambdaExpressions { - static Body bod = h -> h + " No Parens!"; // (1) + static Body bod = h -> h + " No Parens!"; // [1] - static Body bod2 = (h) -> h + " More details"; // (2) + static Body bod2 = (h) -> h + " More details"; // [2] - static Description desc = () -> "Short info"; // (3) + static Description desc = () -> "Short info"; // [3] - static Multi mult = (h, n) -> h + n; // (4) + static Multi mult = (h, n) -> h + n; // [4] - static Description moreLines = () -> { // (5) + static Description moreLines = () -> { // [5] System.out.println("moreLines()"); return "from moreLines()"; }; diff --git a/functional/MethodConversion.java b/functional/MethodConversion.java index 2b6a7117e..15e780749 100644 --- a/functional/MethodConversion.java +++ b/functional/MethodConversion.java @@ -1,7 +1,7 @@ // functional/MethodConversion.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.function.*; class In1 {} diff --git a/functional/MethodReferences.java b/functional/MethodReferences.java index c2e4176f1..4c1e5f9fb 100644 --- a/functional/MethodReferences.java +++ b/functional/MethodReferences.java @@ -1,47 +1,46 @@ // functional/MethodReferences.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.*; +// Visit http://OnJava8.com for more book information. -interface Callable { // (1) +interface Callable { // [1] void call(String s); } class Describe { - void show(String msg) { // (2) + void show(String msg) { // [2] System.out.println(msg); } } public class MethodReferences { - static void hello(String name) { // (3) + static void hello(String name) { // [3] System.out.println("Hello, " + name); } static class Description { String about; - public Description(String desc) { about = desc; } - void help(String msg) { // (4) + Description(String desc) { about = desc; } + void help(String msg) { // [4] System.out.println(about + " " + msg); } } static class Helper { - static void assist(String msg) { // (5) + 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) + Callable c = d::show; // [6] + c.call("call()"); // [7] - c = MethodReferences::hello; // (8) + c = MethodReferences::hello; // [8] c.call("Bob"); - c = new Description("valuable")::help; // (9) + c = new Description("valuable")::help; // [9] c.call("information"); - c = Helper::assist; // (10) + c = Helper::assist; // [10] c.call("Help!"); } } diff --git a/functional/MultiUnbound.java b/functional/MultiUnbound.java index db0aef3d6..67defb7d5 100644 --- a/functional/MultiUnbound.java +++ b/functional/MultiUnbound.java @@ -1,7 +1,7 @@ // functional/MultiUnbound.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Unbound methods with multiple arguments class This { @@ -11,16 +11,16 @@ void four(int i, double d, String s, char c) {} } interface TwoArgs { - void call2(This _this, int i, double d); + void call2(This athis, int i, double d); } interface ThreeArgs { - void call3(This _this, int i, double d, String s); + void call3(This athis, int i, double d, String s); } interface FourArgs { void call4( - This _this, int i, double d, String s, char c); + This athis, int i, double d, String s, char c); } public class MultiUnbound { @@ -28,9 +28,9 @@ public static void main(String[] args) { TwoArgs twoargs = This::two; ThreeArgs threeargs = This::three; FourArgs fourargs = This::four; - This _this = new This(); - twoargs.call2(_this, 11, 3.14); - threeargs.call3(_this, 11, 3.14, "Three"); - fourargs.call4(_this, 11, 3.14, "Four", 'Z'); + 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/functional/PredicateComposition.java b/functional/PredicateComposition.java index 841ccf6b3..40ddb6001 100644 --- a/functional/PredicateComposition.java +++ b/functional/PredicateComposition.java @@ -1,7 +1,7 @@ // functional/PredicateComposition.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.function.*; import java.util.stream.*; diff --git a/functional/ProduceFunction.java b/functional/ProduceFunction.java index 79f0c9c7e..5f0b0940b 100644 --- a/functional/ProduceFunction.java +++ b/functional/ProduceFunction.java @@ -1,15 +1,15 @@ // functional/ProduceFunction.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.function.*; interface -FuncSS extends Function {} // (1) +FuncSS extends Function {} // [1] public class ProduceFunction { static FuncSS produce() { - return s -> s.toLowerCase(); // (2) + return s -> s.toLowerCase(); // [2] } public static void main(String[] args) { FuncSS f = produce(); diff --git a/functional/RecursiveFactorial.java b/functional/RecursiveFactorial.java index 6cb972e6d..5ddb0860c 100644 --- a/functional/RecursiveFactorial.java +++ b/functional/RecursiveFactorial.java @@ -1,7 +1,7 @@ // functional/RecursiveFactorial.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class RecursiveFactorial { static IntCall fact; diff --git a/functional/RecursiveFibonacci.java b/functional/RecursiveFibonacci.java index 02ee25c1e..4b58bb06c 100644 --- a/functional/RecursiveFibonacci.java +++ b/functional/RecursiveFibonacci.java @@ -1,7 +1,7 @@ // functional/RecursiveFibonacci.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class RecursiveFibonacci { IntCall fib; diff --git a/functional/RunnableMethodReference.java b/functional/RunnableMethodReference.java index 86700a22c..e135d06f6 100644 --- a/functional/RunnableMethodReference.java +++ b/functional/RunnableMethodReference.java @@ -1,7 +1,7 @@ // functional/RunnableMethodReference.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Method references with interface Runnable class Go { diff --git a/functional/SharedStorage.java b/functional/SharedStorage.java index 08161a5a2..0a2489253 100644 --- a/functional/SharedStorage.java +++ b/functional/SharedStorage.java @@ -1,15 +1,15 @@ // functional/SharedStorage.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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.make_fun(0); - IntSupplier f2 = c1.make_fun(0); - IntSupplier f3 = c1.make_fun(0); + 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()); diff --git a/functional/Strategize.java b/functional/Strategize.java index cd046dd35..b4358ee7e 100644 --- a/functional/Strategize.java +++ b/functional/Strategize.java @@ -1,13 +1,14 @@ // functional/Strategize.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. interface Strategy { String approach(String msg); } class Soft implements Strategy { + @Override public String approach(String msg) { return msg.toLowerCase() + "?"; } @@ -23,7 +24,7 @@ public class Strategize { Strategy strategy; String msg; Strategize(String msg) { - strategy = new Soft(); // (1) + strategy = new Soft(); // [1] this.msg = msg; } void communicate() { @@ -34,19 +35,19 @@ void changeStrategy(Strategy strategy) { } public static void main(String[] args) { Strategy[] strategies = { - new Strategy() { // (2) + new Strategy() { // [2] public String approach(String msg) { return msg.toUpperCase() + "!"; } }, - msg -> msg.substring(0, 5), // (3) - Unrelated::twice // (4) + 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) + s.changeStrategy(newStrategy); // [5] + s.communicate(); // [6] } } } diff --git a/functional/TransformFunction.java b/functional/TransformFunction.java index 4b747d723..dd3f7590b 100644 --- a/functional/TransformFunction.java +++ b/functional/TransformFunction.java @@ -1,17 +1,15 @@ // functional/TransformFunction.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.function.*; class I { - @Override - public String toString() { return "I"; } + @Override public String toString() { return "I"; } } class O { - @Override - public String toString() { return "O"; } + @Override public String toString() { return "O"; } } public class TransformFunction { diff --git a/functional/TriFunction.java b/functional/TriFunction.java index 742b0b229..40b91473a 100644 --- a/functional/TriFunction.java +++ b/functional/TriFunction.java @@ -1,7 +1,7 @@ // functional/TriFunction.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. @FunctionalInterface public interface TriFunction { diff --git a/functional/TriFunctionTest.java b/functional/TriFunctionTest.java index 649b74778..5af98922c 100644 --- a/functional/TriFunctionTest.java +++ b/functional/TriFunctionTest.java @@ -1,7 +1,7 @@ // functional/TriFunctionTest.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class TriFunctionTest { static int f(int i, long l, double d) { return 99; } diff --git a/functional/UnboundMethodReference.java b/functional/UnboundMethodReference.java index 99b72c91a..6c02b8b91 100644 --- a/functional/UnboundMethodReference.java +++ b/functional/UnboundMethodReference.java @@ -1,7 +1,7 @@ // functional/UnboundMethodReference.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Method reference without an object class X { @@ -18,10 +18,10 @@ interface TransformX { public class UnboundMethodReference { public static void main(String[] args) { - // MakeString ms = X::f; // (1) + // MakeString ms = X::f; // [1] TransformX sp = X::f; X x = new X(); - System.out.println(sp.transform(x)); // (2) + System.out.println(sp.transform(x)); // [2] System.out.println(x.f()); // Same effect } } diff --git a/functional/build.xml b/functional/build.xml deleted file mode 100644 index 60759bd2c..000000000 --- a/functional/build.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/generics/Amphibian.java b/generics/Amphibian.java new file mode 100644 index 000000000..0dc8647f5 --- /dev/null +++ b/generics/Amphibian.java @@ -0,0 +1,5 @@ +// generics/Amphibian.java +// (c)2021 MindView 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/generics/Apply.java b/generics/Apply.java index 115a84824..8e3a23c97 100644 --- a/generics/Apply.java +++ b/generics/Apply.java @@ -1,7 +1,7 @@ // generics/Apply.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.lang.reflect.*; import java.util.*; diff --git a/generics/ApplyFunctional.java b/generics/ApplyFunctional.java index bda661f45..2275ca854 100644 --- a/generics/ApplyFunctional.java +++ b/generics/ApplyFunctional.java @@ -1,7 +1,7 @@ // generics/ApplyFunctional.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; import java.util.function.*; diff --git a/generics/ApplyTest.java b/generics/ApplyTest.java index 2bf45ad03..2ae0618d4 100644 --- a/generics/ApplyTest.java +++ b/generics/ApplyTest.java @@ -1,45 +1,25 @@ // generics/ApplyTest.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.function.*; import onjava.*; -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); - } -} - -class Square extends Shape {} - -class FilledList extends ArrayList { - public FilledList(Supplier gen, int size) { - Suppliers.fill(this, gen, size); - } -} - public class ApplyTest { - public static void main(String[] args) throws Exception { + 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("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("rotate")); Apply.apply(squares, Shape.class.getMethod("resize", int.class), 7); @@ -53,7 +33,8 @@ public static void main(String[] args) throws Exception { Shape::new, 3); Suppliers.fill(shapeQ, SimpleQueue::add, Square::new, 3); - Apply.apply(shapeQ, Shape.class.getMethod("rotate")); + Apply.apply(shapeQ, + Shape.class.getMethod("rotate")); } } /* Output: diff --git a/generics/ArrayMaker.java b/generics/ArrayMaker.java index fa33c14bc..b728267cd 100644 --- a/generics/ArrayMaker.java +++ b/generics/ArrayMaker.java @@ -1,7 +1,7 @@ // generics/ArrayMaker.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.lang.reflect.*; import java.util.*; diff --git a/generics/ArrayOfGeneric.java b/generics/ArrayOfGeneric.java index 43b9d4602..68f7a5bdf 100644 --- a/generics/ArrayOfGeneric.java +++ b/generics/ArrayOfGeneric.java @@ -1,7 +1,7 @@ // generics/ArrayOfGeneric.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class ArrayOfGeneric { static final int SIZE = 100; diff --git a/generics/ArrayOfGenericReference.java b/generics/ArrayOfGenericReference.java index 345a86c26..3403e3c50 100644 --- a/generics/ArrayOfGenericReference.java +++ b/generics/ArrayOfGenericReference.java @@ -1,7 +1,7 @@ // generics/ArrayOfGenericReference.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class Generic {} diff --git a/generics/BankTeller.java b/generics/BankTeller.java index 4b282f130..51bb12034 100644 --- a/generics/BankTeller.java +++ b/generics/BankTeller.java @@ -1,7 +1,7 @@ // generics/BankTeller.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // A very simple bank teller simulation import java.util.*; import onjava.*; @@ -9,20 +9,25 @@ class Customer { private static long counter = 1; private final long id = counter++; - @Override - public String toString() { return "Customer " + id; } + @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; } + @Override public String toString() { + return "Teller " + id; + } } class Bank { - private List tellers = new ArrayList<>(); - public void put(BankTeller bt) { tellers.add(bt); } + private List tellers = + new ArrayList<>(); + public void put(BankTeller bt) { + tellers.add(bt); + } } public class BankTeller { @@ -32,17 +37,20 @@ public static void serve(Teller t, Customer c) { public static void main(String[] args) { // Demonstrate create(): RandomList tellers = - Suppliers.create(RandomList::new, Teller::new, 4); + 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)); + 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); + new ArrayList<>(), + List::add, Customer::new, 12); } } /* Output: diff --git a/generics/BasicBounds.java b/generics/BasicBounds.java index 2a33cc537..ca2c00dfa 100644 --- a/generics/BasicBounds.java +++ b/generics/BasicBounds.java @@ -1,7 +1,7 @@ // generics/BasicBounds.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. interface HasColor { java.awt.Color getColor(); } @@ -15,7 +15,7 @@ class WithColor { class Coord { public int x, y, z; } -// This won't work. Class must be first, then interfaces: +// This fails. Class must be first, then interfaces: // class WithColorCoord { // Multiple bounds: @@ -48,8 +48,7 @@ class Bounded extends Coord implements HasColor, Weight { @Override public java.awt.Color getColor() { return null; } - @Override - public int weight() { return 0; } + @Override public int weight() { return 0; } } public class BasicBounds { diff --git a/generics/BasicHolder.java b/generics/BasicHolder.java index 5d63c599d..5a6bc5a4e 100644 --- a/generics/BasicHolder.java +++ b/generics/BasicHolder.java @@ -1,7 +1,7 @@ // generics/BasicHolder.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class BasicHolder { T element; diff --git a/generics/BasicSupplierDemo.java b/generics/BasicSupplierDemo.java index 6613fb9ee..bf754154a 100644 --- a/generics/BasicSupplierDemo.java +++ b/generics/BasicSupplierDemo.java @@ -1,7 +1,7 @@ // generics/BasicSupplierDemo.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import onjava.*; import java.util.stream.*; diff --git a/generics/ByteSet.java b/generics/ByteSet.java index b32f83953..860125b6a 100644 --- a/generics/ByteSet.java +++ b/generics/ByteSet.java @@ -1,7 +1,7 @@ // generics/ByteSet.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class ByteSet { diff --git a/generics/CRGWithBasicHolder.java b/generics/CRGWithBasicHolder.java index 52f7f2134..f30f02da7 100644 --- a/generics/CRGWithBasicHolder.java +++ b/generics/CRGWithBasicHolder.java @@ -1,13 +1,15 @@ // generics/CRGWithBasicHolder.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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(); + Subtype + st1 = new Subtype(), + st2 = new Subtype(); st1.set(st2); Subtype st3 = st1.get(); st1.f(); diff --git a/generics/CaptureConversion.java b/generics/CaptureConversion.java index 702e50d41..831ee7e94 100644 --- a/generics/CaptureConversion.java +++ b/generics/CaptureConversion.java @@ -1,7 +1,7 @@ // generics/CaptureConversion.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class CaptureConversion { static void f1(Holder holder) { diff --git a/generics/CheckedList.java b/generics/CheckedList.java index e287dbf00..71ebe3d0a 100644 --- a/generics/CheckedList.java +++ b/generics/CheckedList.java @@ -1,9 +1,9 @@ // generics/CheckedList.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Using Collection.checkedList() -import typeinfo.pets.*; +import reflection.pets.*; import java.util.*; public class CheckedList { @@ -29,7 +29,7 @@ public static void main(String[] args) { } } /* Output: -Expected: java.lang.ClassCastException: Attempt to insert -class typeinfo.pets.Cat element into collection with -element type class typeinfo.pets.Dog +Expected: java.lang.ClassCastException: Attempt to +insert class reflection.pets.Cat element into collection +with element type class reflection.pets.Dog */ diff --git a/generics/ClassCasting.java b/generics/ClassCasting.java index 62e344f6d..9029b298e 100644 --- a/generics/ClassCasting.java +++ b/generics/ClassCasting.java @@ -1,7 +1,7 @@ // generics/ClassCasting.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.io.*; import java.util.*; diff --git a/generics/ClassTypeCapture.java b/generics/ClassTypeCapture.java index 7d4da5307..cd4cb8375 100644 --- a/generics/ClassTypeCapture.java +++ b/generics/ClassTypeCapture.java @@ -1,7 +1,7 @@ // generics/ClassTypeCapture.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class Building {} class House extends Building {} diff --git a/generics/ComparablePet.java b/generics/ComparablePet.java index 173658359..951b6cc15 100644 --- a/generics/ComparablePet.java +++ b/generics/ComparablePet.java @@ -1,10 +1,12 @@ // generics/ComparablePet.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class ComparablePet implements Comparable { @Override - public int compareTo(ComparablePet arg) { return 0; } + public int compareTo(ComparablePet arg) { + return 0; + } } diff --git a/generics/CompilerIntelligence.java b/generics/CompilerIntelligence.java index 1b9673821..6b1bc4155 100644 --- a/generics/CompilerIntelligence.java +++ b/generics/CompilerIntelligence.java @@ -1,7 +1,7 @@ // generics/CompilerIntelligence.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class CompilerIntelligence { diff --git a/generics/CountedObject.java b/generics/CountedObject.java index b49b5e8c8..287b480fb 100644 --- a/generics/CountedObject.java +++ b/generics/CountedObject.java @@ -1,14 +1,13 @@ // generics/CountedObject.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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() { + @Override public String toString() { return "CountedObject " + id; } } diff --git a/generics/CovariantArrays.java b/generics/CovariantArrays.java index e15120bfa..2a56b631e 100644 --- a/generics/CovariantArrays.java +++ b/generics/CovariantArrays.java @@ -1,7 +1,7 @@ // generics/CovariantArrays.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class Fruit {} class Apple extends Fruit {} diff --git a/generics/CovariantReturnTypes.java b/generics/CovariantReturnTypes.java index 4789739fc..870f21e4f 100644 --- a/generics/CovariantReturnTypes.java +++ b/generics/CovariantReturnTypes.java @@ -1,7 +1,7 @@ // generics/CovariantReturnTypes.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class Base {} class Derived extends Base {} @@ -11,9 +11,8 @@ interface OrdinaryGetter { } interface DerivedGetter extends OrdinaryGetter { - // Return type of overridden method is allowed to vary: - @Override - Derived get(); + // Overridden method return type can vary: + @Override Derived get(); } public class CovariantReturnTypes { diff --git a/generics/CreatorGeneric.java b/generics/CreatorGeneric.java index 571df572e..e9a349740 100644 --- a/generics/CreatorGeneric.java +++ b/generics/CreatorGeneric.java @@ -1,7 +1,7 @@ // generics/CreatorGeneric.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. abstract class GenericWithCreate { final T element; @@ -12,8 +12,7 @@ abstract class GenericWithCreate { class X {} class XCreator extends GenericWithCreate { - @Override - X create() { return new X(); } + @Override X create() { return new X(); } void f() { System.out.println( element.getClass().getSimpleName()); diff --git a/generics/CuriouslyRecurringGeneric.java b/generics/CuriouslyRecurringGeneric.java index d0f6b5e44..53977f27b 100644 --- a/generics/CuriouslyRecurringGeneric.java +++ b/generics/CuriouslyRecurringGeneric.java @@ -1,7 +1,7 @@ // generics/CuriouslyRecurringGeneric.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class GenericType {} diff --git a/generics/Diamond.java b/generics/Diamond.java index 3d9465727..9ebc43d37 100644 --- a/generics/Diamond.java +++ b/generics/Diamond.java @@ -1,13 +1,11 @@ // generics/Diamond.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. - -class Bob {} +// Visit http://OnJava8.com for more book information. public class Diamond { public static void main(String[] args) { - GenericHolder h3 = new GenericHolder<>(); - h3.set(new Bob()); + GenericHolder h3 = + new GenericHolder<>(); } } diff --git a/generics/DogsAndRobotMethodReferences.java b/generics/DogsAndRobotMethodReferences.java index 2a2328b38..2e9d003e5 100644 --- a/generics/DogsAndRobotMethodReferences.java +++ b/generics/DogsAndRobotMethodReferences.java @@ -1,24 +1,24 @@ // generics/DogsAndRobotMethodReferences.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // "Assisted Latent Typing" -import typeinfo.pets.*; +import reflection.pets.*; import java.util.function.*; -class PerformingDog_ extends Dog { +class PerformingDogA extends Dog { public void speak() { System.out.println("Woof!"); } public void sit() { System.out.println("Sitting"); } public void reproduce() {} } -class Robot_ { +class RobotA { public void speak() { System.out.println("Click!"); } public void sit() { System.out.println("Clank!"); } public void oilChange() {} } -class Communicate_ { +class CommunicateA { public static

void perform(P performer, Consumer

action1, Consumer

action2) { action1.accept(performer); @@ -28,12 +28,13 @@ public static

void perform(P performer, public class DogsAndRobotMethodReferences { public static void main(String[] args) { - Communicate_.perform(new PerformingDog_(), - PerformingDog_::speak, PerformingDog_::sit); - Communicate_.perform(new Robot_(), - Robot_::speak, Robot_::sit); - Communicate_.perform(new Mime(), - Mime::walkAgainstTheWind, Mime::pushInvisibleWalls); + 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: diff --git a/generics/DogsAndRobots.cpp b/generics/DogsAndRobots.cpp index 354a2fa35..a8b008f23 100644 --- a/generics/DogsAndRobots.cpp +++ b/generics/DogsAndRobots.cpp @@ -1,7 +1,7 @@ // generics/DogsAndRobots.cpp -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. #include using namespace std; diff --git a/generics/DogsAndRobots.java b/generics/DogsAndRobots.java index 2d1454526..228e363d3 100644 --- a/generics/DogsAndRobots.java +++ b/generics/DogsAndRobots.java @@ -1,9 +1,9 @@ // generics/DogsAndRobots.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // No (direct) latent typing in Java -import typeinfo.pets.*; +import reflection.pets.*; class PerformingDog extends Dog implements Performs { @Override @@ -14,7 +14,9 @@ public void reproduce() {} } class Robot implements Performs { + @Override public void speak() { System.out.println("Click!"); } + @Override public void sit() { System.out.println("Clank!"); } public void oilChange() {} } diff --git a/generics/DogsAndRobots.py b/generics/DogsAndRobots.py index 33cce802a..ed3bfd47d 100644 --- a/generics/DogsAndRobots.py +++ b/generics/DogsAndRobots.py @@ -1,7 +1,7 @@ # generics/DogsAndRobots.py -# (c)2016 MindView LLC: see Copyright.txt +# (c)2021 MindView LLC: see Copyright.txt # We make no guarantees that this code is fit for any purpose. -# Visit http://mindviewinc.com/Books/OnJava/ for more book information. +# Visit http://OnJava8.com for more book information. class Dog: def speak(self): diff --git a/generics/DynamicProxyMixin.java b/generics/DynamicProxyMixin.java index ddca21c2a..906278fba 100644 --- a/generics/DynamicProxyMixin.java +++ b/generics/DynamicProxyMixin.java @@ -1,7 +1,7 @@ // generics/DynamicProxyMixin.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.lang.reflect.*; import java.util.*; import onjava.*; @@ -10,15 +10,15 @@ class MixinProxy implements InvocationHandler { Map delegatesByMethod; @SuppressWarnings("unchecked") - public MixinProxy(Tuple2>... pairs) { + MixinProxy(Tuple2>... pairs) { delegatesByMethod = new HashMap<>(); for(Tuple2> pair : pairs) { - for(Method method : pair._2.getMethods()) { + 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._1); + delegatesByMethod.put(methodName, pair.a1); } } } @@ -33,10 +33,10 @@ public Object invoke(Object proxy, Method method, 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]._2; + interfaces[i] = (Class)pairs[i].a2; } ClassLoader cl = - pairs[0]._1.getClass().getClassLoader(); + pairs[0].a1.getClass().getClassLoader(); return Proxy.newProxyInstance( cl, interfaces, new MixinProxy(pairs)); } @@ -44,6 +44,7 @@ public static Object newInstance(Tuple2... 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), @@ -60,6 +61,6 @@ public static void main(String[] args) { } /* Output: Hello -1434408462833 +1611503350927 1 */ diff --git a/generics/EpicBattle.java b/generics/EpicBattle.java index 87729083c..716606608 100644 --- a/generics/EpicBattle.java +++ b/generics/EpicBattle.java @@ -1,7 +1,7 @@ // generics/EpicBattle.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Bounds in Java generics import java.util.*; @@ -31,18 +31,18 @@ class SuperSleuth void see() { power.seeThroughWalls(); } } -class CanineHero +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 SuperHearSmell +implements SuperHearing, SuperSmell { + @Override public void hearSubtleNoises() {} + @Override public void trackBySmell() {} } class DogPerson extends CanineHero { diff --git a/generics/Erased.java b/generics/Erased.java index ff0976632..304385afb 100644 --- a/generics/Erased.java +++ b/generics/Erased.java @@ -1,8 +1,8 @@ // generics/Erased.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {CompileTimeError} (Won't compile) +// Visit http://OnJava8.com for more book information. +// {WillNotCompile} public class Erased { private final int SIZE = 100; diff --git a/generics/ErasedTypeEquivalence.java b/generics/ErasedTypeEquivalence.java index 7d3cec74d..0368a1828 100644 --- a/generics/ErasedTypeEquivalence.java +++ b/generics/ErasedTypeEquivalence.java @@ -1,7 +1,7 @@ // generics/ErasedTypeEquivalence.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class ErasedTypeEquivalence { diff --git a/generics/ErasureAndInheritance.java b/generics/ErasureAndInheritance.java index f31e03554..4a2e2591c 100644 --- a/generics/ErasureAndInheritance.java +++ b/generics/ErasureAndInheritance.java @@ -1,7 +1,7 @@ // generics/ErasureAndInheritance.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class GenericBase { private T element; diff --git a/generics/FactoryConstraint.java b/generics/FactoryConstraint.java index 6e6aaa99a..5e721168b 100644 --- a/generics/FactoryConstraint.java +++ b/generics/FactoryConstraint.java @@ -1,24 +1,22 @@ // generics/FactoryConstraint.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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() { + @Override public Integer get() { return ++i; } } class Widget { private int id; - public Widget(int n) { id = n; } - @Override - public String toString() { + Widget(int n) { id = n; } + @Override public String toString() { return "Widget " + id; } public static @@ -32,24 +30,29 @@ class Factory implements Supplier { class Fudge { private static int count = 1; private int n = count++; - @Override - public String toString() { return "Fudge " + n; } + @Override public String toString() { + return "Fudge " + n; + } } class Foo2 { private List x = new ArrayList<>(); - public Foo2(Supplier factory) { + Foo2(Supplier factory) { Suppliers.fill(x, factory, 5); } - @Override - public String toString() { return x.toString(); } + @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)); + System.out.println( + new Foo2<>(new IntegerFactory())); + System.out.println( + new Foo2<>(new Widget.Factory())); + System.out.println( + new Foo2<>(Fudge::new)); } } /* Output: diff --git a/generics/Fibonacci.java b/generics/Fibonacci.java index 48725bd79..c20bdf225 100644 --- a/generics/Fibonacci.java +++ b/generics/Fibonacci.java @@ -1,7 +1,7 @@ // generics/Fibonacci.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Generate a Fibonacci sequence import java.util.function.*; import java.util.stream.*; @@ -22,5 +22,6 @@ public static void main(String[] args) { } } /* Output: -1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 +1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 +2584 */ diff --git a/generics/FilledList.java b/generics/FilledList.java new file mode 100644 index 000000000..662d50f98 --- /dev/null +++ b/generics/FilledList.java @@ -0,0 +1,28 @@ +// generics/FilledList.java +// (c)2021 MindView LLC: see Copyright.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/generics/FilledListMaker.java b/generics/FilledListMaker.java deleted file mode 100644 index 853931136..000000000 --- a/generics/FilledListMaker.java +++ /dev/null @@ -1,23 +0,0 @@ -// generics/FilledListMaker.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.*; - -public class FilledListMaker { - List create(T t, int n) { - List result = new ArrayList<>(); - for(int i = 0; i < n; i++) - result.add(t); - return result; - } - public static void main(String[] args) { - FilledListMaker stringMaker = - new FilledListMaker<>(); - List list = stringMaker.create("Hello", 4); - System.out.println(list); - } -} -/* Output: -[Hello, Hello, Hello, Hello] -*/ diff --git a/generics/GenericArray.java b/generics/GenericArray.java index 022630e22..39212feca 100644 --- a/generics/GenericArray.java +++ b/generics/GenericArray.java @@ -1,7 +1,7 @@ // generics/GenericArray.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class GenericArray { private T[] array; @@ -27,5 +27,6 @@ public static void main(String[] args) { } } /* Output: -[Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer; +[Ljava.lang.Object; cannot be cast to +[Ljava.lang.Integer; */ diff --git a/generics/GenericArray2.java b/generics/GenericArray2.java index d3df5a9a1..ee7962623 100644 --- a/generics/GenericArray2.java +++ b/generics/GenericArray2.java @@ -1,7 +1,7 @@ // generics/GenericArray2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class GenericArray2 { private Object[] array; @@ -34,6 +34,6 @@ public static void main(String[] args) { } /* Output: 0 1 2 3 4 5 6 7 8 9 -java.lang.ClassCastException: [Ljava.lang.Object; cannot be -cast to [Ljava.lang.Integer; +java.lang.ClassCastException: [Ljava.lang.Object; +cannot be cast to [Ljava.lang.Integer; */ diff --git a/generics/GenericArrayWithTypeToken.java b/generics/GenericArrayWithTypeToken.java index 46e42754e..3005a540d 100644 --- a/generics/GenericArrayWithTypeToken.java +++ b/generics/GenericArrayWithTypeToken.java @@ -1,7 +1,7 @@ // generics/GenericArrayWithTypeToken.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.lang.reflect.*; public class GenericArrayWithTypeToken { diff --git a/generics/GenericCast.java b/generics/GenericCast.java index 6c4470ce9..eb4fb651d 100644 --- a/generics/GenericCast.java +++ b/generics/GenericCast.java @@ -1,31 +1,47 @@ // generics/GenericCast.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +import java.util.*; import java.util.stream.*; class FixedSizeStack { - private int index = 0; + private final int size; private Object[] storage; - public FixedSizeStack(int size) { + private int index = 0; + FixedSizeStack(int size) { + this.size = size; storage = new Object[size]; } - public void push(T item) { storage[index++] = item; } + public void push(T item) { + if(index < size) + storage[index++] = item; + } @SuppressWarnings("unchecked") - public T pop() { return (T)storage[--index]; } + public T pop() { + return index == 0 ? null : (T)storage[--index]; + } + @SuppressWarnings("unchecked") + Stream stream() { + return (Stream)Arrays.stream(storage); + } } public class GenericCast { - public static final int SIZE = 10; + static String[] letters = + "ABCDEFGHIJKLMNOPQRS".split(""); public static void main(String[] args) { FixedSizeStack strings = - new FixedSizeStack<>(SIZE); - Stream.of("A B C D E F G H I J".split(" ")) - .forEach(s -> strings.push(s)); - for(int i = 0; i < SIZE; i++) - System.out.print(strings.pop() + " "); + 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: -J I H G F E D C B A +S +A B C D E F G H I J K L M N O P Q R S */ diff --git a/generics/GenericHolder.java b/generics/GenericHolder.java index 185d46603..15cfbb9e1 100644 --- a/generics/GenericHolder.java +++ b/generics/GenericHolder.java @@ -1,7 +1,7 @@ // generics/GenericHolder.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class GenericHolder { private T a; diff --git a/generics/GenericHolder2.java b/generics/GenericHolder2.java index 8df17d677..59c3e3569 100644 --- a/generics/GenericHolder2.java +++ b/generics/GenericHolder2.java @@ -1,7 +1,7 @@ // generics/GenericHolder2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class GenericHolder2 { private T obj; diff --git a/generics/GenericMethods.java b/generics/GenericMethods.java index 08e41ade8..3ec451f93 100644 --- a/generics/GenericMethods.java +++ b/generics/GenericMethods.java @@ -1,7 +1,7 @@ // generics/GenericMethods.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class GenericMethods { public void f(T x) { diff --git a/generics/GenericReading.java b/generics/GenericReading.java index 95964b23d..a661798c5 100644 --- a/generics/GenericReading.java +++ b/generics/GenericReading.java @@ -1,11 +1,12 @@ // generics/GenericReading.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class GenericReading { - static List apples = Arrays.asList(new Apple()); + static List apples = + Arrays.asList(new Apple()); static List fruit = Arrays.asList(new Fruit()); static T readExact(List list) { return list.get(0); @@ -16,8 +17,8 @@ static void f1() { Fruit f = readExact(fruit); f = readExact(apples); } - // If you have a class, its type is - // established when the class is instantiated: + // A class type is established + // when the class is instantiated: static class Reader { T readExact(List list) { return list.get(0); } } diff --git a/generics/GenericVarargs.java b/generics/GenericVarargs.java index e93383fcb..3dfca7d44 100644 --- a/generics/GenericVarargs.java +++ b/generics/GenericVarargs.java @@ -1,7 +1,7 @@ // generics/GenericVarargs.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class GenericVarargs { @@ -17,13 +17,14 @@ public static void main(String[] args) { System.out.println(ls); ls = makeList("A", "B", "C"); System.out.println(ls); - ls = makeList("ABCDEFFHIJKLMNOPQRSTUVWXYZ".split("")); + 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] +[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/generics/GenericsAndCovariance.java b/generics/GenericsAndCovariance.java index ffd906d60..023bb8763 100644 --- a/generics/GenericsAndCovariance.java +++ b/generics/GenericsAndCovariance.java @@ -1,7 +1,7 @@ // generics/GenericsAndCovariance.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class GenericsAndCovariance { @@ -13,7 +13,7 @@ public static void main(String[] args) { // flist.add(new Fruit()); // flist.add(new Object()); flist.add(null); // Legal but uninteresting - // We know that it returns at least Fruit: + // We know it returns at least Fruit: Fruit f = flist.get(0); } } diff --git a/generics/GenericsAndReturnTypes.java b/generics/GenericsAndReturnTypes.java index afb05e1ae..3eebd91ac 100644 --- a/generics/GenericsAndReturnTypes.java +++ b/generics/GenericsAndReturnTypes.java @@ -1,7 +1,7 @@ // generics/GenericsAndReturnTypes.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. interface GenericGetter> { T get(); diff --git a/generics/HasF.java b/generics/HasF.java index 71eb27606..436c19585 100644 --- a/generics/HasF.java +++ b/generics/HasF.java @@ -1,8 +1,10 @@ // generics/HasF.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class HasF { - public void f() { System.out.println("HasF.f()"); } + public void f() { + System.out.println("HasF.f()"); + } } diff --git a/generics/HijackedInterface.java b/generics/HijackedInterface.java index 843694fa6..edf01b7b2 100644 --- a/generics/HijackedInterface.java +++ b/generics/HijackedInterface.java @@ -1,8 +1,8 @@ // generics/HijackedInterface.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {CompileTimeError} (Won't compile) +// Visit http://OnJava8.com for more book information. +// {WillNotCompile} class Cat extends ComparablePet implements Comparable{ diff --git a/generics/Holder.java b/generics/Holder.java index 75c6a59e6..50d22a3ca 100644 --- a/generics/Holder.java +++ b/generics/Holder.java @@ -1,7 +1,8 @@ // generics/Holder.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +import java.util.Objects; public class Holder { private T value; @@ -9,9 +10,12 @@ 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 obj) { - return value.equals(obj); + @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()); @@ -32,5 +36,5 @@ public static void main(String[] args) { /* Output: java.lang.ClassCastException: Apple cannot be cast to Orange -true +false */ diff --git a/generics/Holder1.java b/generics/Holder1.java index 767551f9c..7af6f1c15 100644 --- a/generics/Holder1.java +++ b/generics/Holder1.java @@ -1,7 +1,7 @@ // generics/Holder1.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class Automobile {} diff --git a/generics/InheritBounds.java b/generics/InheritBounds.java index fea74c3d3..7bd7d22b1 100644 --- a/generics/InheritBounds.java +++ b/generics/InheritBounds.java @@ -1,7 +1,7 @@ // generics/InheritBounds.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class HoldItem { T item; @@ -9,7 +9,8 @@ class HoldItem { T getItem() { return item; } } -class WithColor2 extends HoldItem { +class WithColor2 +extends HoldItem { WithColor2(T item) { super(item); } java.awt.Color color() { return item.getColor(); } } diff --git a/generics/InstantiateGenericType.cpp b/generics/InstantiateGenericType.cpp index b66b74af0..c260c39d5 100644 --- a/generics/InstantiateGenericType.cpp +++ b/generics/InstantiateGenericType.cpp @@ -1,7 +1,7 @@ // generics/InstantiateGenericType.cpp -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // C++, not Java! template class Foo { diff --git a/generics/InstantiateGenericType.java b/generics/InstantiateGenericType.java index d4a05636b..93c8d62a9 100644 --- a/generics/InstantiateGenericType.java +++ b/generics/InstantiateGenericType.java @@ -1,28 +1,29 @@ // generics/InstantiateGenericType.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.function.*; +import java.lang.reflect.InvocationTargetException; class ClassAsFactory implements Supplier { Class kind; - public ClassAsFactory(Class kind) { + ClassAsFactory(Class kind) { this.kind = kind; } - @Override - public T get() { + @Override public T get() { try { - return kind.newInstance(); - } catch(InstantiationException | - IllegalAccessException e) { + return kind.getConstructor().newInstance(); + } catch(Exception e) { throw new RuntimeException(e); } } } class Employee { - @Override - public String toString() { return "Employee"; } + public Employee() {} + @Override public String toString() { + return "Employee"; + } } public class InstantiateGenericType { @@ -41,5 +42,6 @@ public static void main(String[] args) { } /* Output: Employee -java.lang.InstantiationException: java.lang.Integer +java.lang.NoSuchMethodException: +java.lang.Integer.() */ diff --git a/generics/IterableFibonacci.java b/generics/IterableFibonacci.java index ff34d040c..2b56b102a 100644 --- a/generics/IterableFibonacci.java +++ b/generics/IterableFibonacci.java @@ -1,7 +1,7 @@ // generics/IterableFibonacci.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Adapt the Fibonacci class to make it Iterable import java.util.*; @@ -9,13 +9,11 @@ public class IterableFibonacci extends Fibonacci implements Iterable { private int n; public IterableFibonacci(int count) { n = count; } - @Override - public Iterator iterator() { + @Override public Iterator iterator() { return new Iterator() { @Override public boolean hasNext() { return n > 0; } - @Override - public Integer next() { + @Override public Integer next() { n--; return IterableFibonacci.this.get(); } @@ -31,5 +29,6 @@ public static void main(String[] args) { } } /* Output: -1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 +1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 +2584 */ diff --git a/generics/LatentReflection.java b/generics/LatentReflection.java index 4a49a1393..cfd9e751d 100644 --- a/generics/LatentReflection.java +++ b/generics/LatentReflection.java @@ -1,7 +1,7 @@ // generics/LatentReflection.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Using reflection for latent typing import java.lang.reflect.*; @@ -12,8 +12,7 @@ public void sit() { System.out.println("Pretending to sit"); } public void pushInvisibleWalls() {} - @Override - public String toString() { return "Mime"; } + @Override public String toString() { return "Mime"; } } // Does not implement Performs: diff --git a/generics/LinkedStack.java b/generics/LinkedStack.java index 8b9a9b7de..932df84f0 100644 --- a/generics/LinkedStack.java +++ b/generics/LinkedStack.java @@ -1,7 +1,7 @@ // generics/LinkedStack.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // A stack implemented with an internal linked structure public class LinkedStack { diff --git a/generics/ListMaker.java b/generics/ListMaker.java index 2760aaee9..f127e2dde 100644 --- a/generics/ListMaker.java +++ b/generics/ListMaker.java @@ -1,7 +1,7 @@ // generics/ListMaker.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class ListMaker { diff --git a/generics/ListOfGenerics.java b/generics/ListOfGenerics.java index f66997eb5..aa2f61873 100644 --- a/generics/ListOfGenerics.java +++ b/generics/ListOfGenerics.java @@ -1,7 +1,7 @@ // generics/ListOfGenerics.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class ListOfGenerics { diff --git a/generics/ListOfInt.java b/generics/ListOfInt.java index 0d08a5a24..a47754950 100644 --- a/generics/ListOfInt.java +++ b/generics/ListOfInt.java @@ -1,7 +1,7 @@ // generics/ListOfInt.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Autoboxing compensates for the inability // to use primitives in generics import java.util.*; diff --git a/generics/LostInformation.java b/generics/LostInformation.java index 140cb46e6..6ca203424 100644 --- a/generics/LostInformation.java +++ b/generics/LostInformation.java @@ -1,7 +1,7 @@ // generics/LostInformation.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; class Frob {} diff --git a/generics/Manipulation.java b/generics/Manipulation.java index 400afadab..f3857515c 100644 --- a/generics/Manipulation.java +++ b/generics/Manipulation.java @@ -1,12 +1,12 @@ // generics/Manipulation.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {CompileTimeError} (Will not compile) +// Visit http://OnJava8.com for more book information. +// {WillNotCompile} class Manipulator { private T obj; - public Manipulator(T x) { obj = x; } + Manipulator(T x) { obj = x; } // Error: cannot find symbol: method f(): public void manipulate() { obj.f(); } } diff --git a/generics/Manipulator2.java b/generics/Manipulator2.java index b1f7f9693..2d112dc60 100644 --- a/generics/Manipulator2.java +++ b/generics/Manipulator2.java @@ -1,10 +1,10 @@ // generics/Manipulator2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class Manipulator2 { private T obj; - public Manipulator2(T x) { obj = x; } + Manipulator2(T x) { obj = x; } public void manipulate() { obj.f(); } } diff --git a/generics/Manipulator3.java b/generics/Manipulator3.java index b51edcf8a..a737a727b 100644 --- a/generics/Manipulator3.java +++ b/generics/Manipulator3.java @@ -1,10 +1,10 @@ // generics/Manipulator3.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class Manipulator3 { private HasF obj; - public Manipulator3(HasF x) { obj = x; } + Manipulator3(HasF x) { obj = x; } public void manipulate() { obj.f(); } } diff --git a/generics/Mixins.cpp b/generics/Mixins.cpp index e7bba20e5..defcac7d5 100644 --- a/generics/Mixins.cpp +++ b/generics/Mixins.cpp @@ -1,7 +1,7 @@ // generics/Mixins.cpp -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. #include #include #include diff --git a/generics/Mixins.java b/generics/Mixins.java index 1234958ee..d64d07d6d 100644 --- a/generics/Mixins.java +++ b/generics/Mixins.java @@ -1,14 +1,14 @@ // generics/Mixins.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; interface TimeStamped { long getStamp(); } class TimeStampedImp implements TimeStamped { private final long timeStamp; - public TimeStampedImp() { + TimeStampedImp() { timeStamp = new Date().getTime(); } @Override @@ -42,10 +42,10 @@ class Mixin extends BasicImp private TimeStamped timeStamp = new TimeStampedImp(); private SerialNumbered serialNumber = new SerialNumberedImp(); - @Override - public long getStamp() { return timeStamp.getStamp(); } - @Override - public long getSerialNumber() { + @Override public long getStamp() { + return timeStamp.getStamp(); + } + @Override public long getSerialNumber() { return serialNumber.getSerialNumber(); } } @@ -64,6 +64,6 @@ public static void main(String[] args) { } } /* Output: -test string 1 1434408464412 1 -test string 2 1434408464413 2 +test string 1 1611503367257 1 +test string 2 1611503367258 2 */ diff --git a/generics/MultipleInterfaceVariants.java b/generics/MultipleInterfaceVariants.java index e65baefd9..c8a58fdd0 100644 --- a/generics/MultipleInterfaceVariants.java +++ b/generics/MultipleInterfaceVariants.java @@ -1,8 +1,9 @@ // generics/MultipleInterfaceVariants.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {CompileTimeError} (Won't compile) +// Visit http://OnJava8.com for more book information. +// {WillNotCompile} +package generics; interface Payable {} diff --git a/generics/NeedCasting.java b/generics/NeedCasting.java index a47ec23af..e8604e335 100644 --- a/generics/NeedCasting.java +++ b/generics/NeedCasting.java @@ -1,7 +1,7 @@ // generics/NeedCasting.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.io.*; import java.util.*; diff --git a/generics/NonCovariantGenerics.java b/generics/NonCovariantGenerics.java index a79223ee4..9b56a1d95 100644 --- a/generics/NonCovariantGenerics.java +++ b/generics/NonCovariantGenerics.java @@ -1,8 +1,8 @@ // generics/NonCovariantGenerics.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {CompileTimeError} (Won't compile) +// Visit http://OnJava8.com for more book information. +// {WillNotCompile} import java.util.*; public class NonCovariantGenerics { diff --git a/generics/NotSelfBounded.java b/generics/NotSelfBounded.java index 62370f5ac..cdf78eb38 100644 --- a/generics/NotSelfBounded.java +++ b/generics/NotSelfBounded.java @@ -1,7 +1,7 @@ // generics/NotSelfBounded.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class NotSelfBounded { T element; diff --git a/generics/ObjectHolder.java b/generics/ObjectHolder.java index 9088db514..a363f4070 100644 --- a/generics/ObjectHolder.java +++ b/generics/ObjectHolder.java @@ -1,7 +1,7 @@ // generics/ObjectHolder.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class ObjectHolder { private Object a; diff --git a/generics/OrdinaryArguments.java b/generics/OrdinaryArguments.java index 051b4eb48..02f0d5e15 100644 --- a/generics/OrdinaryArguments.java +++ b/generics/OrdinaryArguments.java @@ -1,7 +1,7 @@ // generics/OrdinaryArguments.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class OrdinarySetter { void set(Base base) { @@ -21,7 +21,8 @@ public static void main(String[] args) { Derived derived = new Derived(); DerivedSetter ds = new DerivedSetter(); ds.set(derived); - ds.set(base); // Compiles: overloaded, not overridden! + // Compiles--overloaded, not overridden!: + ds.set(base); } } /* Output: diff --git a/generics/Performs.java b/generics/Performs.java index 49573e736..b9379e21e 100644 --- a/generics/Performs.java +++ b/generics/Performs.java @@ -1,7 +1,7 @@ // generics/Performs.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public interface Performs { void speak(); diff --git a/generics/PlainGenericInheritance.java b/generics/PlainGenericInheritance.java index 6365d6531..57e402768 100644 --- a/generics/PlainGenericInheritance.java +++ b/generics/PlainGenericInheritance.java @@ -1,7 +1,7 @@ // generics/PlainGenericInheritance.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class GenericSetter { // Not self-bounded void set(T arg) { diff --git a/generics/PrimitiveGenericTest.java b/generics/PrimitiveGenericTest.java index e4f95e2fb..b745a8f72 100644 --- a/generics/PrimitiveGenericTest.java +++ b/generics/PrimitiveGenericTest.java @@ -1,7 +1,7 @@ // generics/PrimitiveGenericTest.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import onjava.*; import java.util.*; import java.util.function.*; @@ -9,23 +9,19 @@ // Fill an array using a generator: interface FillArray { static T[] fill(T[] a, Supplier gen) { - for(int i = 0; i < a.length; i++) - a[i] = gen.get(); + Arrays.setAll(a, n -> gen.get()); return a; } static int[] fill(int[] a, IntSupplier gen) { - for(int i = 0; i < a.length; i++) - a[i] = gen.getAsInt(); + Arrays.setAll(a, n -> gen.getAsInt()); return a; } static long[] fill(long[] a, LongSupplier gen) { - for(int i = 0; i < a.length; i++) - a[i] = gen.getAsLong(); + Arrays.setAll(a, n -> gen.getAsLong()); return a; } static double[] fill(double[] a, DoubleSupplier gen) { - for(int i = 0; i < a.length; i++) - a[i] = gen.getAsDouble(); + Arrays.setAll(a, n -> gen.getAsDouble()); return a; } } @@ -36,11 +32,11 @@ public static void main(String[] args) { new String[5], new Rand.String(9)); System.out.println(Arrays.toString(strings)); int[] integers = FillArray.fill( - new int[9], new Rand.int_()); + new int[9], new Rand.Pint()); System.out.println(Arrays.toString(integers)); } } /* Output: -[YNzbrnyGc, FOWZnTcQr, GseGZMmJM, RoEsuEcUO, neOEdLsmw] -[8689, 7185, 6992, 5746, 3976, 2447, 5368, 1854, 1395] +[btpenpccu, xszgvgmei, nneeloztd, vewcippcy, gpoalkljl] +[635, 8737, 3941, 4720, 6177, 8479, 6656, 3768, 4948] */ diff --git a/generics/RandomList.java b/generics/RandomList.java index 3d68999ce..470739f2b 100644 --- a/generics/RandomList.java +++ b/generics/RandomList.java @@ -1,7 +1,7 @@ // generics/RandomList.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; @@ -21,5 +21,6 @@ public static void main(String[] args) { } } /* Output: -brown over fox quick quick dog brown The brown lazy brown +brown over fox quick quick dog brown The brown lazy +brown */ diff --git a/generics/RestrictedComparablePets.java b/generics/RestrictedComparablePets.java index 87f4af3a2..7c87bb49c 100644 --- a/generics/RestrictedComparablePets.java +++ b/generics/RestrictedComparablePets.java @@ -1,15 +1,20 @@ // generics/RestrictedComparablePets.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class Hamster extends ComparablePet implements Comparable { - public int compareTo(ComparablePet arg) { return 0; } + @Override + public int compareTo(ComparablePet arg) { + return 0; + } } // Or just: class Gecko extends ComparablePet { - public int compareTo(ComparablePet arg) { return 0; } + public int compareTo(ComparablePet arg) { + return 0; + } } diff --git a/generics/ReturnGenericType.java b/generics/ReturnGenericType.java index 7571cc008..1e6dc005f 100644 --- a/generics/ReturnGenericType.java +++ b/generics/ReturnGenericType.java @@ -1,10 +1,10 @@ // generics/ReturnGenericType.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class ReturnGenericType { private T obj; - public ReturnGenericType(T x) { obj = x; } + ReturnGenericType(T x) { obj = x; } public T get() { return obj; } } diff --git a/generics/SelfBounding.java b/generics/SelfBounding.java index e5e3afd0b..c0c509c3e 100644 --- a/generics/SelfBounding.java +++ b/generics/SelfBounding.java @@ -1,7 +1,7 @@ // generics/SelfBounding.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class SelfBounded> { T element; @@ -22,7 +22,8 @@ class C extends SelfBounded { class D {} // Can't do this: // class E extends SelfBounded {} -// Compile error: Type parameter D is not within its bound +// 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 {} diff --git a/generics/SelfBoundingAndCovariantArguments.java b/generics/SelfBoundingAndCovariantArguments.java index 89d688d02..eefa864d1 100644 --- a/generics/SelfBoundingAndCovariantArguments.java +++ b/generics/SelfBoundingAndCovariantArguments.java @@ -1,16 +1,18 @@ // generics/SelfBoundingAndCovariantArguments.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. -interface SelfBoundSetter> { +interface +SelfBoundSetter> { void set(T arg); } interface Setter extends SelfBoundSetter {} public class SelfBoundingAndCovariantArguments { - void testA(Setter s1, Setter s2, SelfBoundSetter sbs) { + void + testA(Setter s1, Setter s2, SelfBoundSetter sbs) { s1.set(s2); //- s1.set(sbs); // error: method set in interface SelfBoundSetter diff --git a/generics/SelfBoundingMethods.java b/generics/SelfBoundingMethods.java index 87aadd0e7..aab5b7b77 100644 --- a/generics/SelfBoundingMethods.java +++ b/generics/SelfBoundingMethods.java @@ -1,7 +1,7 @@ // generics/SelfBoundingMethods.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class SelfBoundingMethods { static > T f(T arg) { diff --git a/generics/Shape.java b/generics/Shape.java new file mode 100644 index 000000000..271220b22 --- /dev/null +++ b/generics/Shape.java @@ -0,0 +1,18 @@ +// generics/Shape.java +// (c)2021 MindView 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/generics/SimpleDogsAndRobots.java b/generics/SimpleDogsAndRobots.java index 564147d8c..ebe1c9438 100644 --- a/generics/SimpleDogsAndRobots.java +++ b/generics/SimpleDogsAndRobots.java @@ -1,7 +1,7 @@ // generics/SimpleDogsAndRobots.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Removing the generic; code still works class CommunicateSimply { diff --git a/generics/SimpleHolder.java b/generics/SimpleHolder.java index c06b67614..5bc15f82b 100644 --- a/generics/SimpleHolder.java +++ b/generics/SimpleHolder.java @@ -1,7 +1,7 @@ // generics/SimpleHolder.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class SimpleHolder { private Object obj; diff --git a/generics/SimpleQueue.java b/generics/SimpleQueue.java index 87f643845..18adc1bd7 100644 --- a/generics/SimpleQueue.java +++ b/generics/SimpleQueue.java @@ -1,16 +1,15 @@ // generics/SimpleQueue.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// A different kind of collection that is Iterable +// 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() { + @Override public Iterator iterator() { return storage.iterator(); } } diff --git a/generics/Square.java b/generics/Square.java new file mode 100644 index 000000000..5cca84a2c --- /dev/null +++ b/generics/Square.java @@ -0,0 +1,5 @@ +// generics/Square.java +// (c)2021 MindView 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/generics/Store.java b/generics/Store.java index fe514fb38..921470845 100644 --- a/generics/Store.java +++ b/generics/Store.java @@ -1,7 +1,7 @@ // generics/Store.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Building a complex model using generic collections import java.util.*; import java.util.function.*; @@ -11,16 +11,15 @@ class Product { private final int id; private String description; private double price; - public - Product(int IDnumber, String descr, double price) { - id = IDnumber; + 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; + @Override public String toString() { + return id + ": " + description + + ", price: $" + price; } public void priceChange(double change) { price += change; @@ -28,22 +27,22 @@ public void priceChange(double change) { public static Supplier generator = new Supplier() { private Random rand = new Random(47); - @Override - public Product get() { + @Override public Product get() { return new Product(rand.nextInt(1000), "Test", - Math.round(rand.nextDouble() * 1000.0) + 0.99); + Math.round( + rand.nextDouble() * 1000.0) + 0.99); } }; } class Shelf extends ArrayList { - public Shelf(int nProducts) { + Shelf(int nProducts) { Suppliers.fill(this, Product.generator, nProducts); } } class Aisle extends ArrayList { - public Aisle(int nShelves, int nProducts) { + Aisle(int nShelves, int nProducts) { for(int i = 0; i < nShelves; i++) add(new Shelf(nProducts)); } @@ -56,12 +55,12 @@ public class Store extends ArrayList { private ArrayList checkouts = new ArrayList<>(); private Office office = new Office(); - public Store(int nAisles, int nShelves, int nProducts) { + public Store( + int nAisles, int nShelves, int nProducts) { for(int i = 0; i < nAisles; i++) add(new Aisle(nShelves, nProducts)); } - @Override - public String toString() { + @Override public String toString() { StringBuilder result = new StringBuilder(); for(Aisle a : this) for(Shelf s : a) @@ -72,7 +71,7 @@ public String toString() { return result.toString(); } public static void main(String[] args) { - System.out.println(new Store(14, 5, 10)); + System.out.println(new Store(5, 4, 3)); } } /* Output: (First 8 Lines) diff --git a/generics/SuperTypeWildcards.java b/generics/SuperTypeWildcards.java index 814fca82e..e675bc74e 100644 --- a/generics/SuperTypeWildcards.java +++ b/generics/SuperTypeWildcards.java @@ -1,7 +1,7 @@ // generics/SuperTypeWildcards.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class SuperTypeWildcards { diff --git a/generics/Templates.cpp b/generics/Templates.cpp index 556c08d84..e56fdda7c 100644 --- a/generics/Templates.cpp +++ b/generics/Templates.cpp @@ -1,7 +1,7 @@ // generics/Templates.cpp -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. #include using namespace std; diff --git a/generics/ThrowGenericException.java b/generics/ThrowGenericException.java index 679fc8bc5..2a8ddb5e9 100644 --- a/generics/ThrowGenericException.java +++ b/generics/ThrowGenericException.java @@ -1,7 +1,7 @@ // generics/ThrowGenericException.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; interface Processor { @@ -20,11 +20,12 @@ List processAll() throws E { class Failure1 extends Exception {} -class Processor1 implements Processor { +class Processor1 +implements Processor { static int count = 3; @Override - public void - process(List resultCollector) throws Failure1 { + public void process(List resultCollector) + throws Failure1 { if(count-- > 1) resultCollector.add("Hep!"); else @@ -36,11 +37,12 @@ class Processor1 implements Processor { class Failure2 extends Exception {} -class Processor2 implements Processor { +class Processor2 +implements Processor { static int count = 2; @Override - public void - process(List resultCollector) throws Failure2 { + public void process(List resultCollector) + throws Failure2 { if(count-- == 0) resultCollector.add(47); else { diff --git a/generics/TupleList.java b/generics/TupleList.java index 2c96a07b3..896530b40 100644 --- a/generics/TupleList.java +++ b/generics/TupleList.java @@ -1,7 +1,7 @@ // generics/TupleList.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Combining generic types to make complex generic types import java.util.*; import onjava.*; @@ -18,6 +18,6 @@ public static void main(String[] args) { } } /* Output: -(Vehicle@18025c, Amphibian@16f27d, hi, 47) -(Vehicle@7aac27, Amphibian@3abc88, hi, 47) +(Vehicle@ec7777, Amphibian@107d329, hi, 47) +(Vehicle@1629346, Amphibian@4b9385, hi, 47) */ diff --git a/generics/TupleTest.java b/generics/TupleTest.java index 8cafff708..0df194a2f 100644 --- a/generics/TupleTest.java +++ b/generics/TupleTest.java @@ -1,12 +1,9 @@ // generics/TupleTest.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import onjava.*; -class Amphibian {} -class Vehicle {} - public class TupleTest { static Tuple2 f() { // Autoboxing converts the int to Integer: @@ -22,7 +19,8 @@ Tuple4 h() { new Vehicle(), new Amphibian(), "hi", 47); } static - Tuple5 k() { + Tuple5 k() { return new Tuple5<>( new Vehicle(), new Amphibian(), "hi", 47, 11.1); @@ -30,7 +28,7 @@ Tuple5 k() { public static void main(String[] args) { Tuple2 ttsi = f(); System.out.println(ttsi); - // ttsi._1 = "there"; // Compile error: final + // ttsi.a1 = "there"; // Compile error: final System.out.println(g()); System.out.println(h()); System.out.println(k()); @@ -38,7 +36,7 @@ public static void main(String[] args) { } /* Output: (hi, 47) -(Amphibian@139a55, hi, 47) -(Vehicle@1db9742, Amphibian@106d69c, hi, 47) -(Vehicle@52e922, Amphibian@25154f, hi, 47, 11.1) +(Amphibian@1c7c054, hi, 47) +(Vehicle@14991ad, Amphibian@d93b30, hi, 47) +(Vehicle@a14482, Amphibian@140e19d, hi, 47, 11.1) */ diff --git a/generics/TupleTest2.java b/generics/TupleTest2.java index d1ad478f0..f889d59f3 100644 --- a/generics/TupleTest2.java +++ b/generics/TupleTest2.java @@ -1,7 +1,7 @@ // generics/TupleTest2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import onjava.*; import static onjava.Tuple.*; @@ -19,7 +19,8 @@ Tuple4 h() { new Vehicle(), new Amphibian(), "hi", 47); } static - Tuple5 k() { + Tuple5 k() { return tuple(new Vehicle(), new Amphibian(), "hi", 47, 11.1); } @@ -35,7 +36,7 @@ public static void main(String[] args) { /* Output: (hi, 47) (hi, 47) -(Amphibian@139a55, hi, 47) -(Vehicle@1db9742, Amphibian@106d69c, hi, 47) -(Vehicle@52e922, Amphibian@25154f, hi, 47, 11.1) +(Amphibian@a298b7, hi, 47) +(Vehicle@16d3586, Amphibian@154617c, hi, 47) +(Vehicle@17327b6, Amphibian@14ae5a5, hi, 47, 11.1) */ diff --git a/generics/UnboundedWildcards1.java b/generics/UnboundedWildcards1.java index 513e52113..7aada9a6c 100644 --- a/generics/UnboundedWildcards1.java +++ b/generics/UnboundedWildcards1.java @@ -1,7 +1,7 @@ // generics/UnboundedWildcards1.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class UnboundedWildcards1 { diff --git a/generics/UnboundedWildcards2.java b/generics/UnboundedWildcards2.java index a01461643..f1e17630e 100644 --- a/generics/UnboundedWildcards2.java +++ b/generics/UnboundedWildcards2.java @@ -1,7 +1,7 @@ // generics/UnboundedWildcards2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class UnboundedWildcards2 { diff --git a/generics/Unconstrained.java b/generics/Unconstrained.java index 051ccdb8f..66c6bebd6 100644 --- a/generics/Unconstrained.java +++ b/generics/Unconstrained.java @@ -1,7 +1,7 @@ // generics/Unconstrained.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class Other {} class BasicOther extends BasicHolder {} diff --git a/generics/UseList.java b/generics/UseList.java index 29a7e53ff..3c9073aff 100644 --- a/generics/UseList.java +++ b/generics/UseList.java @@ -1,8 +1,9 @@ // generics/UseList.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {CompileTimeError} (Will not compile) +// Visit http://OnJava8.com for more book information. +// {WillNotCompile} +import java.util.*; public class UseList { void f(List v) {} diff --git a/generics/UseList2.java b/generics/UseList2.java index c6e05533a..bee17d0dc 100644 --- a/generics/UseList2.java +++ b/generics/UseList2.java @@ -1,7 +1,7 @@ // generics/UseList2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class UseList2 { diff --git a/generics/Vehicle.java b/generics/Vehicle.java new file mode 100644 index 000000000..dfe502c97 --- /dev/null +++ b/generics/Vehicle.java @@ -0,0 +1,5 @@ +// generics/Vehicle.java +// (c)2021 MindView 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/generics/WatercolorSets.java b/generics/WatercolorSets.java index 673bf0be8..2b285eaaa 100644 --- a/generics/WatercolorSets.java +++ b/generics/WatercolorSets.java @@ -1,7 +1,7 @@ // generics/WatercolorSets.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import generics.watercolors.*; import java.util.*; import static onjava.Sets.*; @@ -33,21 +33,22 @@ public static void main(String[] args) { 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): [MAGENTA, ROSE_MADDER, CRIMSON, -PERMANENT_GREEN, BURNT_UMBER, SAP_GREEN, CERULEAN_BLUE_HUE, -RAW_UMBER, YELLOW_OCHRE, BRILLIANT_RED, ULTRAMARINE, -BURNT_SIENNA, COBALT_BLUE_HUE, VIRIDIAN_HUE, PHTHALO_BLUE, -VIOLET] +COBALT_BLUE_HUE, PERMANENT_GREEN, VIRIDIAN_HUE, +SAP_GREEN, YELLOW_OCHRE, BURNT_SIENNA, RAW_UMBER, +BURNT_UMBER] +union(set1, set2): [MAGENTA, COBALT_BLUE_HUE, VIOLET, +VIRIDIAN_HUE, BURNT_SIENNA, ULTRAMARINE, +CERULEAN_BLUE_HUE, BURNT_UMBER, BRILLIANT_RED, +PHTHALO_BLUE, YELLOW_OCHRE, SAP_GREEN, CRIMSON, +ROSE_MADDER, RAW_UMBER, PERMANENT_GREEN] intersection(set1, set2): [COBALT_BLUE_HUE, -PERMANENT_GREEN, VIRIDIAN_HUE, PHTHALO_BLUE, -CERULEAN_BLUE_HUE, ULTRAMARINE] -difference(set1, subset): [MAGENTA, ROSE_MADDER, CRIMSON, -BRILLIANT_RED, VIOLET] -difference(set2, subset): [BURNT_UMBER, SAP_GREEN, -RAW_UMBER, YELLOW_OCHRE, BURNT_SIENNA] -complement(set1, set2): [MAGENTA, ROSE_MADDER, CRIMSON, -BURNT_UMBER, SAP_GREEN, RAW_UMBER, YELLOW_OCHRE, -BRILLIANT_RED, BURNT_SIENNA, VIOLET] +VIRIDIAN_HUE, ULTRAMARINE, CERULEAN_BLUE_HUE, +PHTHALO_BLUE, PERMANENT_GREEN] +difference(set1, subset): [CRIMSON, MAGENTA, VIOLET, +ROSE_MADDER, BRILLIANT_RED] +difference(set2, subset): [BURNT_SIENNA, BURNT_UMBER, +YELLOW_OCHRE, RAW_UMBER, SAP_GREEN] +complement(set1, set2): [MAGENTA, VIOLET, BURNT_SIENNA, +BURNT_UMBER, BRILLIANT_RED, YELLOW_OCHRE, SAP_GREEN, +CRIMSON, ROSE_MADDER, RAW_UMBER] */ diff --git a/generics/Wildcards.java b/generics/Wildcards.java index 549a93bc3..7c854bb43 100644 --- a/generics/Wildcards.java +++ b/generics/Wildcards.java @@ -1,7 +1,7 @@ // generics/Wildcards.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Exploring the meaning of wildcards public class Wildcards { @@ -22,8 +22,9 @@ static void rawArgs(Holder holder, Object arg) { // OK, but type information is lost: Object obj = holder.get(); } - // Similar to rawArgs(), but errors instead of warnings: - static void unboundedArg(Holder holder, Object arg) { + // 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; @@ -68,7 +69,8 @@ T wildSubtype(Holder holder, T arg) { // 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 + // CAP#1 extends T#1 from + // capture of ? extends T#1 // 1 error return holder.get(); @@ -214,7 +216,7 @@ public static void main(String[] args) { // found: Holder // where T is a type-variable: // T extends Object declared in - // method wildSubtype(Holder,T) + // method wildSubtype(Holder,T) // 2 warnings Long r10 = wildSubtype(qualified, lng); diff --git a/generics/build.xml b/generics/build.xml deleted file mode 100644 index 6b9ac5f9e..000000000 --- a/generics/build.xml +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/generics/coffee/Americano.java b/generics/coffee/Americano.java index f8174744d..86c628288 100644 --- a/generics/coffee/Americano.java +++ b/generics/coffee/Americano.java @@ -1,6 +1,6 @@ // generics/coffee/Americano.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package generics.coffee; public class Americano extends Coffee {} diff --git a/generics/coffee/Breve.java b/generics/coffee/Breve.java index 8f32b139d..5afed481d 100644 --- a/generics/coffee/Breve.java +++ b/generics/coffee/Breve.java @@ -1,6 +1,6 @@ // generics/coffee/Breve.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package generics.coffee; public class Breve extends Coffee {} diff --git a/generics/coffee/Cappuccino.java b/generics/coffee/Cappuccino.java index f5b936383..f50486849 100644 --- a/generics/coffee/Cappuccino.java +++ b/generics/coffee/Cappuccino.java @@ -1,6 +1,6 @@ // generics/coffee/Cappuccino.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package generics.coffee; public class Cappuccino extends Coffee {} diff --git a/generics/coffee/Coffee.java b/generics/coffee/Coffee.java index 81f653c7a..3c893cb48 100644 --- a/generics/coffee/Coffee.java +++ b/generics/coffee/Coffee.java @@ -1,14 +1,13 @@ // generics/coffee/Coffee.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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() { + @Override public String toString() { return getClass().getSimpleName() + " " + id; } } diff --git a/generics/coffee/CoffeeSupplier.java b/generics/coffee/CoffeeSupplier.java index 464e6a4f2..90df2e463 100644 --- a/generics/coffee/CoffeeSupplier.java +++ b/generics/coffee/CoffeeSupplier.java @@ -1,11 +1,13 @@ // generics/coffee/CoffeeSupplier.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 { @@ -16,14 +18,16 @@ public CoffeeSupplier() {} // For iteration: private int size = 0; public CoffeeSupplier(int sz) { size = sz; } - @Override - public Coffee get() { + @Override public Coffee get() { try { return (Coffee) - types[rand.nextInt(types.length)].newInstance(); - // Report programmer errors at run time: - } catch(InstantiationException | - IllegalAccessException e) { + types[rand.nextInt(types.length)] + .getConstructor().newInstance(); + // Report programmer errors at runtime: + } catch(InstantiationException | + NoSuchMethodException | + InvocationTargetException | + IllegalAccessException e) { throw new RuntimeException(e); } } @@ -31,8 +35,7 @@ class CoffeeIterator implements Iterator { int count = size; @Override public boolean hasNext() { return count > 0; } - @Override - public Coffee next() { + @Override public Coffee next() { count--; return CoffeeSupplier.this.get(); } @@ -41,8 +44,7 @@ public void remove() { // Not implemented throw new UnsupportedOperationException(); } } - @Override - public Iterator iterator() { + @Override public Iterator iterator() { return new CoffeeIterator(); } public static void main(String[] args) { diff --git a/generics/coffee/Latte.java b/generics/coffee/Latte.java index 95bf319f2..bf4d25831 100644 --- a/generics/coffee/Latte.java +++ b/generics/coffee/Latte.java @@ -1,6 +1,6 @@ // generics/coffee/Latte.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package generics.coffee; public class Latte extends Coffee {} diff --git a/generics/coffee/Mocha.java b/generics/coffee/Mocha.java index 9c73fcd5a..e4eaa5a20 100644 --- a/generics/coffee/Mocha.java +++ b/generics/coffee/Mocha.java @@ -1,6 +1,6 @@ // generics/coffee/Mocha.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package generics.coffee; public class Mocha extends Coffee {} diff --git a/generics/decorator/Decoration.java b/generics/decorator/Decoration.java index f54d7f41c..07651bb35 100644 --- a/generics/decorator/Decoration.java +++ b/generics/decorator/Decoration.java @@ -1,7 +1,8 @@ // generics/decorator/Decoration.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {java generics.decorator.Decoration} package generics.decorator; import java.util.*; @@ -13,7 +14,7 @@ class Basic { class Decorator extends Basic { protected Basic basic; - public Decorator(Basic basic) { this.basic = basic; } + Decorator(Basic basic) { this.basic = basic; } @Override public void set(String val) { basic.set(val); } @Override @@ -22,7 +23,7 @@ class Decorator extends Basic { class TimeStamped extends Decorator { private final long timeStamp; - public TimeStamped(Basic basic) { + TimeStamped(Basic basic) { super(basic); timeStamp = new Date().getTime(); } @@ -32,7 +33,7 @@ public TimeStamped(Basic basic) { class SerialNumbered extends Decorator { private static long counter = 1; private final long serialNumber = counter++; - public SerialNumbered(Basic basic) { super(basic); } + SerialNumbered(Basic basic) { super(basic); } public long getSerialNumber() { return serialNumber; } } diff --git a/generics/dogsandrobots.go b/generics/dogsandrobots.go index 6c9493020..cba1e10c3 100644 --- a/generics/dogsandrobots.go +++ b/generics/dogsandrobots.go @@ -1,7 +1,7 @@ // generics/dogsandrobots.go -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package main import "fmt" diff --git a/generics/watercolors/Watercolors.java b/generics/watercolors/Watercolors.java index aa5e80972..33922ba10 100644 --- a/generics/watercolors/Watercolors.java +++ b/generics/watercolors/Watercolors.java @@ -1,14 +1,15 @@ // generics/watercolors/Watercolors.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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, + 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/gradle.properties b/gradle.properties new file mode 100644 index 000000000..1cb5556b7 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.parallel=true +org.gradle.caching=true +org.gradle.warning.mode=none diff --git a/gradle/checkstyle.gradle b/gradle/checkstyle.gradle new file mode 100644 index 000000000..0f0e60865 --- /dev/null +++ b/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/gradle/findbugs.gradle b/gradle/findbugs.gradle new file mode 100644 index 000000000..ac628cb29 --- /dev/null +++ b/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/gradle/java.gradle b/gradle/java.gradle new file mode 100644 index 000000000..99898c1d0 --- /dev/null +++ b/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: + implementation 'org.slf4j:slf4j-api:1.7.21' + implementation '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' +} diff --git a/gradle/jmh.gradle b/gradle/jmh.gradle new file mode 100644 index 000000000..ce61db4bd --- /dev/null +++ b/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/gradle/junit-jupiter.gradle b/gradle/junit-jupiter.gradle new file mode 100644 index 000000000..98a778434 --- /dev/null +++ b/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/gradle/subprojects.gradle b/gradle/subprojects.gradle new file mode 100644 index 000000000..945aa9231 --- /dev/null +++ b/gradle/subprojects.gradle @@ -0,0 +1,73 @@ +project(':validating') { + jmh { + include = 'validating.jmh.*' + } +} + +project(':equalshashcode') { + dependencies { + compile project(':reflection') + 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(':reflection') + } +} + +project(':collections') { + dependencies { + compile project(':reflection') + } +} + +project(':patterns') { + dependencies { + compile project(':enums') + } +} + +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/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 941144813..e708b1c02 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 53102c17a..28ff446a2 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Fri Dec 11 12:37:50 MST 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.9-bin.zip diff --git a/gradlew b/gradlew index 9d82f7891..4f906e0c8 100755 --- a/gradlew +++ b/gradlew @@ -1,4 +1,20 @@ -#!/usr/bin/env bash +#!/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. +# ############################################################################## ## @@ -6,20 +22,38 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# 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 ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -30,6 +64,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,28 +75,14 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# 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 - 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 @@ -85,7 +106,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +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 @@ -105,10 +126,11 @@ if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then +# 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 @@ -134,27 +156,30 @@ if $cygwin ; then else eval `echo args$i`="\"$arg\"" fi - i=$((i+1)) + 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" ;; + 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 -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +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" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 8a0b282aa..107acd32c 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@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 @@ -8,20 +24,23 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@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= - 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 init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -35,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -45,34 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - :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 %CMD_LINE_ARGS% +"%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 diff --git a/hiding/Cake.java b/hiding/Cake.java index 833149b3c..e4ee6698c 100644 --- a/hiding/Cake.java +++ b/hiding/Cake.java @@ -1,7 +1,7 @@ // hiding/Cake.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Accesses a class in a separate compilation unit class Cake { diff --git a/hiding/ChocolateChip.java b/hiding/ChocolateChip.java index e058f14df..dd98cc883 100644 --- a/hiding/ChocolateChip.java +++ b/hiding/ChocolateChip.java @@ -1,7 +1,7 @@ // hiding/ChocolateChip.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Can't use package-access member from another package import hiding.dessert.*; diff --git a/hiding/ChocolateChip2.java b/hiding/ChocolateChip2.java index 96226a476..bc85fb95f 100644 --- a/hiding/ChocolateChip2.java +++ b/hiding/ChocolateChip2.java @@ -1,7 +1,7 @@ // hiding/ChocolateChip2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import hiding.cookie2.*; public class ChocolateChip2 extends Cookie { diff --git a/hiding/CreatePackageAccessObject.java b/hiding/CreatePackageAccessObject.java new file mode 100644 index 000000000..823d6b265 --- /dev/null +++ b/hiding/CreatePackageAccessObject.java @@ -0,0 +1,12 @@ +// hiding/CreatePackageAccessObject.java +// (c)2021 MindView 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/hiding/Dinner.java b/hiding/Dinner.java index 69f6e4162..e027e6aa0 100644 --- a/hiding/Dinner.java +++ b/hiding/Dinner.java @@ -1,7 +1,7 @@ // hiding/Dinner.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Uses the library import hiding.dessert.*; diff --git a/hiding/FullQualification.java b/hiding/FullQualification.java index 9de01e4e4..e0a74371e 100644 --- a/hiding/FullQualification.java +++ b/hiding/FullQualification.java @@ -1,10 +1,11 @@ // hiding/FullQualification.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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(); + java.util.ArrayList list = + new java.util.ArrayList(); } } diff --git a/hiding/IceCream.java b/hiding/IceCream.java index 765b97f99..ad78cd7e4 100644 --- a/hiding/IceCream.java +++ b/hiding/IceCream.java @@ -1,7 +1,7 @@ // hiding/IceCream.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Demonstrates "private" keyword class Sundae { diff --git a/hiding/ImportedMyClass.java b/hiding/ImportedMyClass.java index d26f347d8..dfd0fc111 100644 --- a/hiding/ImportedMyClass.java +++ b/hiding/ImportedMyClass.java @@ -1,7 +1,7 @@ // hiding/ImportedMyClass.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import hiding.mypackage.*; public class ImportedMyClass { diff --git a/hiding/LibTest.java b/hiding/LibTest.java index 70d092a0b..4c2e970f9 100644 --- a/hiding/LibTest.java +++ b/hiding/LibTest.java @@ -1,7 +1,7 @@ // hiding/LibTest.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Uses the library import com.mindviewinc.simple.*; diff --git a/hiding/Lunch.java b/hiding/Lunch.java index e470fcc8b..81b46791a 100644 --- a/hiding/Lunch.java +++ b/hiding/Lunch.java @@ -1,20 +1,20 @@ // hiding/Lunch.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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) + public static Soup1 makeSoup() { // [1] return new Soup1(); } } class Soup2 { private Soup2() {} - private static Soup2 ps1 = new Soup2(); // (2) + private static Soup2 ps1 = new Soup2(); // [2] public static Soup2 access() { return ps1; } diff --git a/hiding/OrganizedByAccess.java b/hiding/OrganizedByAccess.java index 5709f77ae..9553a7805 100644 --- a/hiding/OrganizedByAccess.java +++ b/hiding/OrganizedByAccess.java @@ -1,7 +1,7 @@ // hiding/OrganizedByAccess.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class OrganizedByAccess { public void pub1() { /* ... */ } diff --git a/hiding/Pie.java b/hiding/Pie.java index 1cf63321e..5cf3c12d7 100644 --- a/hiding/Pie.java +++ b/hiding/Pie.java @@ -1,7 +1,7 @@ // hiding/Pie.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // The other class class Pie { diff --git a/hiding/QualifiedMyClass.java b/hiding/QualifiedMyClass.java index cf4a6ee54..6b0beafcb 100644 --- a/hiding/QualifiedMyClass.java +++ b/hiding/QualifiedMyClass.java @@ -1,7 +1,7 @@ // hiding/QualifiedMyClass.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class QualifiedMyClass { public static void main(String[] args) { diff --git a/hiding/SingleImport.java b/hiding/SingleImport.java index 200b4ef60..4e7b26dc4 100644 --- a/hiding/SingleImport.java +++ b/hiding/SingleImport.java @@ -1,7 +1,7 @@ // hiding/SingleImport.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.ArrayList; public class SingleImport { diff --git a/hiding/build.xml b/hiding/build.xml deleted file mode 100644 index a1bf2c129..000000000 --- a/hiding/build.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/hiding/cookie2/Cookie.java b/hiding/cookie2/Cookie.java index 25865ab4d..faa9bd5a9 100644 --- a/hiding/cookie2/Cookie.java +++ b/hiding/cookie2/Cookie.java @@ -1,7 +1,7 @@ // hiding/cookie2/Cookie.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package hiding.cookie2; public class Cookie { diff --git a/hiding/dessert/Cookie.java b/hiding/dessert/Cookie.java index cb63ff698..b6de1bdb9 100644 --- a/hiding/dessert/Cookie.java +++ b/hiding/dessert/Cookie.java @@ -1,7 +1,7 @@ // hiding/dessert/Cookie.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Creates a library package hiding.dessert; diff --git a/hiding/mypackage/MyClass.java b/hiding/mypackage/MyClass.java index b4281de6b..c029f6646 100644 --- a/hiding/mypackage/MyClass.java +++ b/hiding/mypackage/MyClass.java @@ -1,7 +1,7 @@ // hiding/mypackage/MyClass.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package hiding.mypackage; public class MyClass { diff --git a/hiding/packageaccess/PublicConstructor.java b/hiding/packageaccess/PublicConstructor.java new file mode 100644 index 000000000..250090505 --- /dev/null +++ b/hiding/packageaccess/PublicConstructor.java @@ -0,0 +1,9 @@ +// hiding/packageaccess/PublicConstructor.java +// (c)2021 MindView 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/housekeeping/Apricot.java b/housekeeping/Apricot.java index ee15434fd..81932eaba 100644 --- a/housekeeping/Apricot.java +++ b/housekeeping/Apricot.java @@ -1,7 +1,8 @@ // housekeeping/Apricot.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. + public class Apricot { void pick() { /* ... */ } void pit() { pick(); /* ... */ } diff --git a/housekeeping/ArrayClassObj.java b/housekeeping/ArrayClassObj.java index 397699ad4..440087080 100644 --- a/housekeeping/ArrayClassObj.java +++ b/housekeeping/ArrayClassObj.java @@ -1,7 +1,7 @@ // housekeeping/ArrayClassObj.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Creating an array of nonprimitive objects import java.util.*; @@ -17,6 +17,6 @@ public static void main(String[] args) { } /* Output: length of a = 18 -[55, 193, 361, 461, 429, 368, 200, 22, 207, 288, 128, 51, -89, 309, 278, 498, 361, 20] +[55, 193, 361, 461, 429, 368, 200, 22, 207, 288, 128, +51, 89, 309, 278, 498, 361, 20] */ diff --git a/housekeeping/ArrayInit.java b/housekeeping/ArrayInit.java index 0b59bde17..fc5ffb1ef 100644 --- a/housekeeping/ArrayInit.java +++ b/housekeeping/ArrayInit.java @@ -1,20 +1,14 @@ // housekeeping/ArrayInit.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 - }; + Integer[] a = { 1, 2, 3, }; + Integer[] b = new Integer[]{ 1, 2, 3, }; System.out.println(Arrays.toString(a)); System.out.println(Arrays.toString(b)); } diff --git a/housekeeping/ArrayNew.java b/housekeeping/ArrayNew.java index 74a6466a7..8cba539a9 100644 --- a/housekeeping/ArrayNew.java +++ b/housekeeping/ArrayNew.java @@ -1,7 +1,7 @@ // housekeeping/ArrayNew.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Creating arrays with new import java.util.*; diff --git a/housekeeping/ArraysOfPrimitives.java b/housekeeping/ArraysOfPrimitives.java index 665650130..cfd0cf2f6 100644 --- a/housekeeping/ArraysOfPrimitives.java +++ b/housekeeping/ArraysOfPrimitives.java @@ -1,7 +1,7 @@ // housekeeping/ArraysOfPrimitives.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class ArraysOfPrimitives { public static void main(String[] args) { diff --git a/housekeeping/AutoboxingVarargs.java b/housekeeping/AutoboxingVarargs.java index 5d25d4dca..76bb5a7b0 100644 --- a/housekeeping/AutoboxingVarargs.java +++ b/housekeeping/AutoboxingVarargs.java @@ -1,7 +1,7 @@ // housekeeping/AutoboxingVarargs.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class AutoboxingVarargs { public static void f(Integer... args) { diff --git a/housekeeping/BananaPeel.java b/housekeeping/BananaPeel.java index 4eadf14b8..30d1e8095 100644 --- a/housekeeping/BananaPeel.java +++ b/housekeeping/BananaPeel.java @@ -1,7 +1,7 @@ // housekeeping/BananaPeel.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class Banana { void peel(int i) { /* ... */ } } diff --git a/housekeeping/Burrito.java b/housekeeping/Burrito.java index d356d48a2..88bf16fc0 100644 --- a/housekeeping/Burrito.java +++ b/housekeeping/Burrito.java @@ -1,7 +1,7 @@ // housekeeping/Burrito.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class Burrito { Spiciness degree; diff --git a/housekeeping/Counter.java b/housekeeping/Counter.java index 7bb5c6835..ef5733e72 100644 --- a/housekeeping/Counter.java +++ b/housekeeping/Counter.java @@ -1,7 +1,7 @@ // housekeeping/Counter.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class Counter { int i; Counter() { i = 7; } diff --git a/housekeeping/DefaultConstructor.java b/housekeeping/DefaultConstructor.java index f74eb10c9..ac8971130 100644 --- a/housekeeping/DefaultConstructor.java +++ b/housekeeping/DefaultConstructor.java @@ -1,7 +1,7 @@ // housekeeping/DefaultConstructor.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class Bird {} diff --git a/housekeeping/Demotion.java b/housekeeping/Demotion.java index cd87c11e3..5534bccb1 100644 --- a/housekeeping/Demotion.java +++ b/housekeeping/Demotion.java @@ -1,11 +1,13 @@ // housekeeping/Demotion.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Demotion of primitives public class Demotion { - void f1(double x) { System.out.println("f1(double)"); } + 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)"); } diff --git a/housekeeping/DynamicArray.java b/housekeeping/DynamicArray.java index ac7a2770a..d94536e30 100644 --- a/housekeeping/DynamicArray.java +++ b/housekeeping/DynamicArray.java @@ -1,7 +1,7 @@ // housekeeping/DynamicArray.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Array initialization public class DynamicArray { diff --git a/housekeeping/EnumOrder.java b/housekeeping/EnumOrder.java index 7a311ff21..8927ae50f 100644 --- a/housekeeping/EnumOrder.java +++ b/housekeeping/EnumOrder.java @@ -1,12 +1,13 @@ // housekeeping/EnumOrder.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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()); + System.out.println( + s + ", ordinal " + s.ordinal()); } } /* Output: diff --git a/housekeeping/ExplicitStatic.java b/housekeeping/ExplicitStatic.java index 761beb96c..034fbd417 100644 --- a/housekeeping/ExplicitStatic.java +++ b/housekeeping/ExplicitStatic.java @@ -1,8 +1,8 @@ // housekeeping/ExplicitStatic.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Explicit static initialization with the "static" clause +// Visit http://OnJava8.com for more book information. +// Explicit static initialization with "static" clause class Cup { Cup(int marker) { @@ -28,10 +28,10 @@ class Cups { public class ExplicitStatic { public static void main(String[] args) { System.out.println("Inside main()"); - Cups.cup1.f(99); // (1) + Cups.cup1.f(99); // [1] } - // static Cups cups1 = new Cups(); // (2) - // static Cups cups2 = new Cups(); // (2) + // static Cups cups1 = new Cups(); // [2] + // static Cups cups2 = new Cups(); // [2] } /* Output: Inside main() diff --git a/housekeeping/Flower.java b/housekeeping/Flower.java index adf106caf..fa519d1d6 100644 --- a/housekeeping/Flower.java +++ b/housekeeping/Flower.java @@ -1,7 +1,7 @@ // housekeeping/Flower.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Calling constructors with "this" public class Flower { @@ -26,7 +26,7 @@ public class Flower { } Flower() { this("hi", 47); - System.out.println("no-arg constructor"); + System.out.println("Zero-argument constructor"); } void printPetalCount() { //- this(11); // Not inside non-constructor! @@ -41,6 +41,6 @@ public static void main(String[] args) { /* Output: Constructor w/ int arg only, petalCount= 47 String & int args -no-arg constructor +Zero-argument constructor petalCount = 47 s = hi */ diff --git a/housekeeping/ForTypeInference.java b/housekeeping/ForTypeInference.java new file mode 100644 index 000000000..8db4b9034 --- /dev/null +++ b/housekeeping/ForTypeInference.java @@ -0,0 +1,19 @@ +// housekeeping/ForTypeInference.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 11 + +public class ForTypeInference { + public static void main(String[] args) { + for(var s : Spiciness.values()) + System.out.println(s); + } +} +/* Output: +NOT +MILD +MEDIUM +HOT +FLAMING +*/ diff --git a/housekeeping/InitialValues.java b/housekeeping/InitialValues.java index 826a924c8..90c82ce14 100644 --- a/housekeeping/InitialValues.java +++ b/housekeeping/InitialValues.java @@ -1,7 +1,7 @@ // housekeeping/InitialValues.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Shows default initial values public class InitialValues { diff --git a/housekeeping/InitialValues2.java b/housekeeping/InitialValues2.java index 9361381b5..678331e26 100644 --- a/housekeeping/InitialValues2.java +++ b/housekeeping/InitialValues2.java @@ -1,7 +1,7 @@ // housekeeping/InitialValues2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Providing explicit initial values public class InitialValues2 { diff --git a/housekeeping/Leaf.java b/housekeeping/Leaf.java index b75ae3150..dc559c98d 100644 --- a/housekeeping/Leaf.java +++ b/housekeeping/Leaf.java @@ -1,7 +1,7 @@ // housekeeping/Leaf.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Simple use of the "this" keyword public class Leaf { diff --git a/housekeeping/Measurement.java b/housekeeping/Measurement.java index 20912a423..c97bfbd9f 100644 --- a/housekeeping/Measurement.java +++ b/housekeeping/Measurement.java @@ -1,7 +1,7 @@ // housekeeping/Measurement.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class Depth {} public class Measurement { diff --git a/housekeeping/MethodInit.java b/housekeeping/MethodInit.java index 77edae51c..242866b16 100644 --- a/housekeeping/MethodInit.java +++ b/housekeeping/MethodInit.java @@ -1,7 +1,7 @@ // housekeeping/MethodInit.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class MethodInit { int i = f(); int f() { return 11; } diff --git a/housekeeping/MethodInit2.java b/housekeeping/MethodInit2.java index 14f3fb02b..d00d17900 100644 --- a/housekeeping/MethodInit2.java +++ b/housekeeping/MethodInit2.java @@ -1,7 +1,7 @@ // housekeeping/MethodInit2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class MethodInit2 { int i = f(); int j = g(i); diff --git a/housekeeping/MethodInit3.java b/housekeeping/MethodInit3.java index 5a39920a2..7b201f306 100644 --- a/housekeeping/MethodInit3.java +++ b/housekeeping/MethodInit3.java @@ -1,7 +1,7 @@ // housekeeping/MethodInit3.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class MethodInit3 { //- int j = g(i); // Illegal forward reference int i = f(); diff --git a/housekeeping/Mugs.java b/housekeeping/Mugs.java index 645e3a771..bdb6f1518 100644 --- a/housekeeping/Mugs.java +++ b/housekeeping/Mugs.java @@ -1,22 +1,19 @@ // housekeeping/Mugs.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Instance initialization class Mug { Mug(int marker) { System.out.println("Mug(" + marker + ")"); } - void f(int marker) { - System.out.println("f(" + marker + ")"); - } } public class Mugs { Mug mug1; Mug mug2; - { // (1) + { // [1] mug1 = new Mug(1); mug2 = new Mug(2); System.out.println("mug1 & mug2 initialized"); diff --git a/housekeeping/NewVarArgs.java b/housekeeping/NewVarArgs.java index 749c2c1bf..6ee8d4a72 100644 --- a/housekeeping/NewVarArgs.java +++ b/housekeeping/NewVarArgs.java @@ -1,8 +1,8 @@ // housekeeping/NewVarArgs.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Using array syntax to create variable argument lists +// Visit http://OnJava8.com for more book information. +// Using ellipses to define a variable argument list public class NewVarArgs { static void printArray(Object... args) { diff --git a/housekeeping/NoSynthesis.java b/housekeeping/NoSynthesis.java index ee5c1f1e6..7cb90130d 100644 --- a/housekeeping/NoSynthesis.java +++ b/housekeeping/NoSynthesis.java @@ -1,7 +1,7 @@ // housekeeping/NoSynthesis.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class Bird2 { Bird2(int i) {} diff --git a/housekeeping/OptionalTrailingArguments.java b/housekeeping/OptionalTrailingArguments.java index dc96aba7c..62b2a92f8 100644 --- a/housekeeping/OptionalTrailingArguments.java +++ b/housekeeping/OptionalTrailingArguments.java @@ -1,7 +1,7 @@ // housekeeping/OptionalTrailingArguments.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class OptionalTrailingArguments { static void f(int required, String... trailing) { diff --git a/housekeeping/OrderOfInitialization.java b/housekeeping/OrderOfInitialization.java index 6bb1977e5..dc175d315 100644 --- a/housekeeping/OrderOfInitialization.java +++ b/housekeeping/OrderOfInitialization.java @@ -1,7 +1,7 @@ // housekeeping/OrderOfInitialization.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Demonstrates initialization order // When the constructor is called to create a diff --git a/housekeeping/Overloading.java b/housekeeping/Overloading.java index 7cc506dbf..55307f4fa 100644 --- a/housekeeping/Overloading.java +++ b/housekeeping/Overloading.java @@ -1,7 +1,7 @@ // housekeeping/Overloading.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Both constructor and ordinary method overloading class Tree { @@ -32,7 +32,7 @@ public static void main(String[] args) { t.info(); t.info("overloaded method"); } - // Overloaded constructor: + // Calls overloaded constructor: new Tree(); } } diff --git a/housekeeping/OverloadingOrder.java b/housekeeping/OverloadingOrder.java index 4d239dece..434768d77 100644 --- a/housekeeping/OverloadingOrder.java +++ b/housekeeping/OverloadingOrder.java @@ -1,8 +1,8 @@ // housekeeping/OverloadingOrder.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Overloading based on the order of the arguments +// Visit http://OnJava8.com for more book information. +// Overloading based on parameter order public class OverloadingOrder { static void f(String s, int i) { diff --git a/housekeeping/OverloadingVarargs.java b/housekeeping/OverloadingVarargs.java index a9757c973..dea4785c5 100644 --- a/housekeeping/OverloadingVarargs.java +++ b/housekeeping/OverloadingVarargs.java @@ -1,7 +1,7 @@ // housekeeping/OverloadingVarargs.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class OverloadingVarargs { static void f(Character... args) { diff --git a/housekeeping/OverloadingVarargs2.java b/housekeeping/OverloadingVarargs2.java index 00fa37aae..2c1755d41 100644 --- a/housekeeping/OverloadingVarargs2.java +++ b/housekeeping/OverloadingVarargs2.java @@ -1,8 +1,8 @@ // housekeeping/OverloadingVarargs2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {CompileTimeError} (Won't compile) +// Visit http://OnJava8.com for more book information. +// {WillNotCompile} public class OverloadingVarargs2 { static void f(float i, Character... args) { diff --git a/housekeeping/OverloadingVarargs3.java b/housekeeping/OverloadingVarargs3.java index 03db29fe8..c49f472ea 100644 --- a/housekeeping/OverloadingVarargs3.java +++ b/housekeeping/OverloadingVarargs3.java @@ -1,7 +1,7 @@ // housekeeping/OverloadingVarargs3.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class OverloadingVarargs3 { static void f(float i, Character... args) { diff --git a/housekeeping/PassingThis.java b/housekeeping/PassingThis.java index ae4310a1f..5a6bb9396 100644 --- a/housekeeping/PassingThis.java +++ b/housekeeping/PassingThis.java @@ -1,7 +1,7 @@ // housekeeping/PassingThis.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class Person { public void eat(Apple apple) { diff --git a/housekeeping/PrimitiveOverloading.java b/housekeeping/PrimitiveOverloading.java index d8dca1517..6a120b0cd 100644 --- a/housekeeping/PrimitiveOverloading.java +++ b/housekeeping/PrimitiveOverloading.java @@ -1,7 +1,7 @@ // housekeeping/PrimitiveOverloading.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Promotion of primitives and overloading public class PrimitiveOverloading { @@ -101,20 +101,12 @@ public static void main(String[] args) { } } /* 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) +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/housekeeping/SimpleConstructor.java b/housekeeping/SimpleConstructor.java index 06a73e73f..ff28bd063 100644 --- a/housekeeping/SimpleConstructor.java +++ b/housekeeping/SimpleConstructor.java @@ -1,7 +1,7 @@ // housekeeping/SimpleConstructor.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Demonstration of a simple constructor class Rock { diff --git a/housekeeping/SimpleConstructor2.java b/housekeeping/SimpleConstructor2.java index e08e79e21..2a002daf6 100644 --- a/housekeeping/SimpleConstructor2.java +++ b/housekeeping/SimpleConstructor2.java @@ -1,8 +1,8 @@ // housekeeping/SimpleConstructor2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Constructors can have arguments +// Visit http://OnJava8.com for more book information. +// Constructors can have parameters class Rock2 { Rock2(int i) { diff --git a/housekeeping/SimpleEnumUse.java b/housekeeping/SimpleEnumUse.java index bc24bddd5..d1c69f024 100644 --- a/housekeeping/SimpleEnumUse.java +++ b/housekeeping/SimpleEnumUse.java @@ -1,7 +1,7 @@ // housekeeping/SimpleEnumUse.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class SimpleEnumUse { public static void main(String[] args) { diff --git a/housekeeping/Spiciness.java b/housekeeping/Spiciness.java index aeff179f4..94ccfe85e 100644 --- a/housekeeping/Spiciness.java +++ b/housekeeping/Spiciness.java @@ -1,7 +1,7 @@ // housekeeping/Spiciness.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public enum Spiciness { NOT, MILD, MEDIUM, HOT, FLAMING diff --git a/housekeeping/Spoon.java b/housekeeping/Spoon.java index e18afe846..bf9257689 100644 --- a/housekeeping/Spoon.java +++ b/housekeeping/Spoon.java @@ -1,7 +1,7 @@ // housekeeping/Spoon.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class Spoon { static int i; static { diff --git a/housekeeping/StaticInitialization.java b/housekeeping/StaticInitialization.java index e7bd12a56..eaa743d84 100644 --- a/housekeeping/StaticInitialization.java +++ b/housekeeping/StaticInitialization.java @@ -1,7 +1,7 @@ // housekeeping/StaticInitialization.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Specifying initial values in a class definition class Bowl { @@ -40,9 +40,9 @@ void f3(int marker) { public class StaticInitialization { public static void main(String[] args) { - System.out.println("Creating new Cupboard() in main"); + System.out.println("main creating new Cupboard()"); new Cupboard(); - System.out.println("Creating new Cupboard() in main"); + System.out.println("main creating new Cupboard()"); new Cupboard(); table.f2(1); cupboard.f3(1); @@ -60,11 +60,11 @@ public static void main(String[] args) { Bowl(3) Cupboard() f1(2) -Creating new Cupboard() in main +main creating new Cupboard() Bowl(3) Cupboard() f1(2) -Creating new Cupboard() in main +main creating new Cupboard() Bowl(3) Cupboard() f1(2) diff --git a/housekeeping/TerminationCondition.java b/housekeeping/TerminationCondition.java index 32d05bc34..532053b7c 100644 --- a/housekeeping/TerminationCondition.java +++ b/housekeeping/TerminationCondition.java @@ -1,7 +1,7 @@ // housekeeping/TerminationCondition.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Using finalize() to detect an object that // hasn't been properly cleaned up import onjava.*; @@ -14,8 +14,8 @@ class Book { void checkIn() { checkedOut = false; } - @Override - public void finalize() { + @SuppressWarnings("deprecation") + @Override public void finalize() { if(checkedOut) System.out.println("Error: checked out"); // Normally, you'll also do this: @@ -32,7 +32,7 @@ public static void main(String[] args) { new Book(true); // Force garbage collection & finalization: System.gc(); - new Sleep(1); // Delay + new Nap(1); // One second delay } } /* Output: diff --git a/housekeeping/TypeInference.java b/housekeeping/TypeInference.java new file mode 100644 index 000000000..9f06fc2d8 --- /dev/null +++ b/housekeeping/TypeInference.java @@ -0,0 +1,36 @@ +// housekeeping/TypeInference.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 11 + +class Plumbus {} + +public class TypeInference { + void method() { + // Explicit type: + String hello1 = "Hello"; + // Type inference: + var hello = "Hello!"; + // Works for user-defined types: + Plumbus pb1 = new Plumbus(); + var pb2 = new Plumbus(); + } + // Also works for static methods: + static void staticMethod() { + var hello = "Hello!"; + var pb2 = new Plumbus(); + } +} + +class NoInference { + String field1 = "Field initialization"; + // var field2 = "Can't do this"; + // void method() { + // var noInitializer; // No inference data + // var aNull = null; // No inference data + // } + // var inferReturnType() { + // return "Can't infer return type"; + // } +} diff --git a/housekeeping/VarArgs.java b/housekeeping/VarArgs.java index eb8b3bd51..0899b8614 100644 --- a/housekeeping/VarArgs.java +++ b/housekeeping/VarArgs.java @@ -1,7 +1,7 @@ // housekeeping/VarArgs.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Using array syntax to create variable argument lists class A {} @@ -13,8 +13,7 @@ static void printArray(Object[] args) { System.out.println(); } public static void main(String[] args) { - printArray(new Object[]{ - 47, (float) 3.14, 11.11}); + printArray(new Object[]{47, (float) 3.14, 11.11}); printArray(new Object[]{"one", "two", "three" }); printArray(new Object[]{new A(), new A(), new A()}); } diff --git a/housekeeping/VarargType.java b/housekeeping/VarargType.java index 67be35c33..b6ea406bc 100644 --- a/housekeeping/VarargType.java +++ b/housekeeping/VarargType.java @@ -1,7 +1,7 @@ // housekeeping/VarargType.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class VarargType { static void f(Character... args) { @@ -17,7 +17,8 @@ public static void main(String[] args) { f(); g(1); g(); - System.out.println("int[]: " + new int[0].getClass()); + System.out.println("int[]: " + + new int[0].getClass()); } } /* Output: diff --git a/housekeeping/build.xml b/housekeeping/build.xml deleted file mode 100644 index 9584fc313..000000000 --- a/housekeeping/build.xml +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/innerclasses/AnonymousConstructor.java b/innerclasses/AnonymousConstructor.java index 5398c0fc3..10a6b6433 100644 --- a/innerclasses/AnonymousConstructor.java +++ b/innerclasses/AnonymousConstructor.java @@ -1,11 +1,11 @@ // innerclasses/AnonymousConstructor.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Creating a constructor for an anonymous inner class abstract class Base { - public Base(int i) { + Base(int i) { System.out.println("Base constructor, i = " + i); } public abstract void f(); @@ -16,8 +16,7 @@ public static Base getBase(int i) { return new Base(i) { { System.out.println( "Inside instance initializer"); } - @Override - public void f() { + @Override public void f() { System.out.println("In anonymous f()"); } }; diff --git a/innerclasses/BigEgg.java b/innerclasses/BigEgg.java index 6f430bd37..96cb06f3a 100644 --- a/innerclasses/BigEgg.java +++ b/innerclasses/BigEgg.java @@ -1,8 +1,8 @@ // innerclasses/BigEgg.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// An inner class cannot be overriden like a method +// Visit http://OnJava8.com for more book information. +// An inner class cannot be overridden like a method class Egg { private Yolk y; @@ -11,7 +11,7 @@ public Yolk() { System.out.println("Egg.Yolk()"); } } - public Egg() { + Egg() { System.out.println("New Egg()"); y = new Yolk(); } diff --git a/innerclasses/BigEgg2.java b/innerclasses/BigEgg2.java index 5de932677..847165f3c 100644 --- a/innerclasses/BigEgg2.java +++ b/innerclasses/BigEgg2.java @@ -1,7 +1,7 @@ // innerclasses/BigEgg2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Proper inheritance of an inner class class Egg2 { @@ -14,7 +14,7 @@ public void f() { } } private Yolk y = new Yolk(); - public Egg2() { System.out.println("New Egg2()"); } + Egg2() { System.out.println("New Egg2()"); } public void insertYolk(Yolk yy) { y = yy; } public void g() { y.f(); } } @@ -24,8 +24,7 @@ public class Yolk extends Egg2.Yolk { public Yolk() { System.out.println("BigEgg2.Yolk()"); } - @Override - public void f() { + @Override public void f() { System.out.println("BigEgg2.Yolk.f()"); } } diff --git a/innerclasses/Callbacks.java b/innerclasses/Callbacks.java index 94ff1cb00..9031ea242 100644 --- a/innerclasses/Callbacks.java +++ b/innerclasses/Callbacks.java @@ -1,8 +1,9 @@ // innerclasses/Callbacks.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Using inner classes for callbacks +// {java innerclasses.Callbacks} package innerclasses; interface Incrementable { @@ -12,8 +13,7 @@ interface Incrementable { // Very simple to just implement the interface: class Callee1 implements Incrementable { private int i = 0; - @Override - public void increment() { + @Override public void increment() { i++; System.out.println(i); } @@ -30,15 +30,13 @@ public void increment() { // some other way, you must use an inner class: class Callee2 extends MyIncrement { private int i = 0; - @Override - public void increment() { + @Override public void increment() { super.increment(); i++; System.out.println(i); } private class Closure implements Incrementable { - @Override - public void increment() { + @Override public void increment() { // Specify outer-class method, otherwise // you'll get an infinite recursion: Callee2.this.increment(); diff --git a/innerclasses/ClassInInterface.java b/innerclasses/ClassInInterface.java index dfdc63d34..b06042743 100644 --- a/innerclasses/ClassInInterface.java +++ b/innerclasses/ClassInInterface.java @@ -1,14 +1,13 @@ // innerclasses/ClassInInterface.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {main: ClassInInterface$Test} +// Visit http://OnJava8.com for more book information. +// {java ClassInInterface$Test} public interface ClassInInterface { void howdy(); class Test implements ClassInInterface { - @Override - public void howdy() { + @Override public void howdy() { System.out.println("Howdy!"); } public static void main(String[] args) { diff --git a/innerclasses/Contents.java b/innerclasses/Contents.java index f770e413c..e31519124 100644 --- a/innerclasses/Contents.java +++ b/innerclasses/Contents.java @@ -1,7 +1,7 @@ // innerclasses/Contents.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public interface Contents { int value(); } diff --git a/innerclasses/Destination.java b/innerclasses/Destination.java index a87b7bb0c..0702be02f 100644 --- a/innerclasses/Destination.java +++ b/innerclasses/Destination.java @@ -1,7 +1,7 @@ // innerclasses/Destination.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public interface Destination { String readLabel(); } diff --git a/innerclasses/DotNew.java b/innerclasses/DotNew.java index 2846907ce..3f77dc608 100644 --- a/innerclasses/DotNew.java +++ b/innerclasses/DotNew.java @@ -1,8 +1,8 @@ // innerclasses/DotNew.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Creating an inner class directly using the .new syntax +// Visit http://OnJava8.com for more book information. +// Creating an inner class directly using .new syntax public class DotNew { public class Inner {} diff --git a/innerclasses/DotThis.java b/innerclasses/DotThis.java index 20b9ab8cc..881ba9a9e 100644 --- a/innerclasses/DotThis.java +++ b/innerclasses/DotThis.java @@ -1,7 +1,7 @@ // innerclasses/DotThis.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Accessing the outer-class object public class DotThis { diff --git a/innerclasses/GreenhouseController.java b/innerclasses/GreenhouseController.java index 6b00fedac..5ec13cab6 100644 --- a/innerclasses/GreenhouseController.java +++ b/innerclasses/GreenhouseController.java @@ -1,9 +1,8 @@ // innerclasses/GreenhouseController.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Configure and execute the greenhouse system -// {Args: 5000} import innerclasses.controller.*; public class GreenhouseController { @@ -21,21 +20,35 @@ gc.new WaterOff(800), gc.new ThermostatDay(1400) }; gc.addEvent(gc.new Restart(2000, eventList)); - if(args.length == 1) - gc.addEvent( - new GreenhouseControls.Terminate( - new Integer(args[0]))); + 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/innerclasses/GreenhouseControls.java b/innerclasses/GreenhouseControls.java index aac65a362..4836f8c5e 100644 --- a/innerclasses/GreenhouseControls.java +++ b/innerclasses/GreenhouseControls.java @@ -1,7 +1,7 @@ // innerclasses/GreenhouseControls.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 @@ -14,14 +14,12 @@ public class LightOn extends Event { public LightOn(long delayTime) { super(delayTime); } - @Override - public void action() { + @Override public void action() { // Put hardware control code here to // physically turn on the light. light = true; } - @Override - public String toString() { + @Override public String toString() { return "Light is on"; } } @@ -29,14 +27,12 @@ public class LightOff extends Event { public LightOff(long delayTime) { super(delayTime); } - @Override - public void action() { + @Override public void action() { // Put hardware control code here to // physically turn off the light. light = false; } - @Override - public String toString() { + @Override public String toString() { return "Light is off"; } } @@ -45,13 +41,11 @@ public class WaterOn extends Event { public WaterOn(long delayTime) { super(delayTime); } - @Override - public void action() { + @Override public void action() { // Put hardware control code here. water = true; } - @Override - public String toString() { + @Override public String toString() { return "Greenhouse water is on"; } } @@ -59,13 +53,11 @@ public class WaterOff extends Event { public WaterOff(long delayTime) { super(delayTime); } - @Override - public void action() { + @Override public void action() { // Put hardware control code here. water = false; } - @Override - public String toString() { + @Override public String toString() { return "Greenhouse water is off"; } } @@ -74,13 +66,11 @@ public class ThermostatNight extends Event { public ThermostatNight(long delayTime) { super(delayTime); } - @Override - public void action() { + @Override public void action() { // Put hardware control code here. thermostat = "Night"; } - @Override - public String toString() { + @Override public String toString() { return "Thermostat on night setting"; } } @@ -88,13 +78,11 @@ public class ThermostatDay extends Event { public ThermostatDay(long delayTime) { super(delayTime); } - @Override - public void action() { + @Override public void action() { // Put hardware control code here. thermostat = "Day"; } - @Override - public String toString() { + @Override public String toString() { return "Thermostat on day setting"; } } @@ -104,12 +92,10 @@ public class Bell extends Event { public Bell(long delayTime) { super(delayTime); } - @Override - public void action() { + @Override public void action() { addEvent(new Bell(delayTime.toMillis())); } - @Override - public String toString() { + @Override public String toString() { return "Bing!"; } } @@ -122,8 +108,7 @@ public class Restart extends Event { for(Event e : eventList) addEvent(e); } - @Override - public void action() { + @Override public void action() { for(Event e : eventList) { e.start(); // Rerun each event addEvent(e); @@ -131,8 +116,7 @@ public void action() { start(); // Rerun this Event addEvent(this); } - @Override - public String toString() { + @Override public String toString() { return "Restarting system"; } } @@ -142,8 +126,7 @@ public Terminate(long delayTime) { } @Override public void action() { System.exit(0); } - @Override - public String toString() { + @Override public String toString() { return "Terminating"; } } diff --git a/innerclasses/InheritInner.java b/innerclasses/InheritInner.java index 5450d5ce7..5e89cbe11 100644 --- a/innerclasses/InheritInner.java +++ b/innerclasses/InheritInner.java @@ -1,7 +1,7 @@ // innerclasses/InheritInner.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Inheriting an inner class class WithInner { diff --git a/innerclasses/LocalInnerClass.java b/innerclasses/LocalInnerClass.java index 019dd4ce2..efc2ec555 100644 --- a/innerclasses/LocalInnerClass.java +++ b/innerclasses/LocalInnerClass.java @@ -1,7 +1,7 @@ // innerclasses/LocalInnerClass.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Holds a sequence of Objects interface Counter { @@ -13,12 +13,11 @@ public class LocalInnerClass { Counter getCounter(final String name) { // A local inner class: class LocalCounter implements Counter { - public LocalCounter() { + LocalCounter() { // Local inner class can have a constructor System.out.println("LocalCounter()"); } - @Override - public int next() { + @Override public int next() { System.out.print(name); // Access local final return count++; } @@ -33,8 +32,7 @@ Counter getCounter2(final String name) { { System.out.println("Counter()"); } - @Override - public int next() { + @Override public int next() { System.out.print(name); // Access local final return count++; } diff --git a/innerclasses/MultiImplementation.java b/innerclasses/MultiImplementation.java index d94017f46..d5e4869af 100644 --- a/innerclasses/MultiImplementation.java +++ b/innerclasses/MultiImplementation.java @@ -1,9 +1,10 @@ // innerclasses/MultiImplementation.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 {} diff --git a/innerclasses/MultiNestingAccess.java b/innerclasses/MultiNestingAccess.java index c90999ee7..a97ffcfed 100644 --- a/innerclasses/MultiNestingAccess.java +++ b/innerclasses/MultiNestingAccess.java @@ -1,7 +1,7 @@ // innerclasses/MultiNestingAccess.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Nested classes can access all members of all // levels of the classes they are nested within diff --git a/innerclasses/Parcel1.java b/innerclasses/Parcel1.java index 0fe971dad..270134080 100644 --- a/innerclasses/Parcel1.java +++ b/innerclasses/Parcel1.java @@ -1,7 +1,7 @@ // innerclasses/Parcel1.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Creating inner classes public class Parcel1 { diff --git a/innerclasses/Parcel10.java b/innerclasses/Parcel10.java index 7f0bfdc24..1d02fb7a1 100644 --- a/innerclasses/Parcel10.java +++ b/innerclasses/Parcel10.java @@ -1,7 +1,7 @@ // innerclasses/Parcel10.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Using "instance initialization" to perform // construction on an anonymous inner class diff --git a/innerclasses/Parcel11.java b/innerclasses/Parcel11.java index 0a91afbae..ccedb3b40 100644 --- a/innerclasses/Parcel11.java +++ b/innerclasses/Parcel11.java @@ -1,17 +1,16 @@ // innerclasses/Parcel11.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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; } + @Override public int value() { return i; } } - protected static class ParcelDestination + protected static final class ParcelDestination implements Destination { private String label; private ParcelDestination(String whereTo) { diff --git a/innerclasses/Parcel2.java b/innerclasses/Parcel2.java index 384d00281..e7e106d98 100644 --- a/innerclasses/Parcel2.java +++ b/innerclasses/Parcel2.java @@ -1,7 +1,7 @@ // innerclasses/Parcel2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Returning a reference to an inner class public class Parcel2 { diff --git a/innerclasses/Parcel3.java b/innerclasses/Parcel3.java index 18435451c..d35f9d6aa 100644 --- a/innerclasses/Parcel3.java +++ b/innerclasses/Parcel3.java @@ -1,7 +1,7 @@ // innerclasses/Parcel3.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Using .new to create instances of inner classes public class Parcel3 { @@ -19,6 +19,7 @@ public static void main(String[] args) { // 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"); + Parcel3.Destination d = + p.new Destination("Tasmania"); } } diff --git a/innerclasses/Parcel5.java b/innerclasses/Parcel5.java index fe4259752..79ea40a89 100644 --- a/innerclasses/Parcel5.java +++ b/innerclasses/Parcel5.java @@ -1,12 +1,12 @@ // innerclasses/Parcel5.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Nesting a class within a method public class Parcel5 { public Destination destination(String s) { - class PDestination implements Destination { + final class PDestination implements Destination { private String label; private PDestination(String whereTo) { label = whereTo; diff --git a/innerclasses/Parcel6.java b/innerclasses/Parcel6.java index 20c9c5b65..4c4325ba9 100644 --- a/innerclasses/Parcel6.java +++ b/innerclasses/Parcel6.java @@ -1,7 +1,7 @@ // innerclasses/Parcel6.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Nesting a class within a scope public class Parcel6 { diff --git a/innerclasses/Parcel7.java b/innerclasses/Parcel7.java index 363555237..c98947d49 100644 --- a/innerclasses/Parcel7.java +++ b/innerclasses/Parcel7.java @@ -1,15 +1,14 @@ // innerclasses/Parcel7.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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; } + @Override public int value() { return i; } }; // Semicolon required } public static void main(String[] args) { diff --git a/innerclasses/Parcel7b.java b/innerclasses/Parcel7b.java index ab194144b..31521df9e 100644 --- a/innerclasses/Parcel7b.java +++ b/innerclasses/Parcel7b.java @@ -1,14 +1,13 @@ // innerclasses/Parcel7b.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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; } + @Override public int value() { return i; } } public Contents contents() { return new MyContents(); diff --git a/innerclasses/Parcel8.java b/innerclasses/Parcel8.java index 3846839cc..4ee309935 100644 --- a/innerclasses/Parcel8.java +++ b/innerclasses/Parcel8.java @@ -1,18 +1,17 @@ // innerclasses/Parcel8.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 new Wrapping(x) { // [1] + @Override public int value() { return super.value() * 47; } - }; // (2) + }; // [2] } public static void main(String[] args) { Parcel8 p = new Parcel8(); diff --git a/innerclasses/Parcel9.java b/innerclasses/Parcel9.java index c68a72472..53053cd16 100644 --- a/innerclasses/Parcel9.java +++ b/innerclasses/Parcel9.java @@ -1,7 +1,7 @@ // innerclasses/Parcel9.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class Parcel9 { // Argument must be final or "effectively final" diff --git a/innerclasses/Sequence.java b/innerclasses/Sequence.java index 983881a62..ad9869177 100644 --- a/innerclasses/Sequence.java +++ b/innerclasses/Sequence.java @@ -1,7 +1,7 @@ // innerclasses/Sequence.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Holds a sequence of Objects interface Selector { diff --git a/innerclasses/TestBed.java b/innerclasses/TestBed.java index b8ee7d3b1..35a7fade2 100644 --- a/innerclasses/TestBed.java +++ b/innerclasses/TestBed.java @@ -1,9 +1,9 @@ // innerclasses/TestBed.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Putting test code in a nested class -// {main: TestBed$Tester} +// {java TestBed$Tester} public class TestBed { public void f() { System.out.println("f()"); } diff --git a/innerclasses/TestParcel.java b/innerclasses/TestParcel.java index c87fcd1ac..76ec51bda 100644 --- a/innerclasses/TestParcel.java +++ b/innerclasses/TestParcel.java @@ -1,15 +1,15 @@ // innerclasses/TestParcel.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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; } + @Override public int value() { return i; } } - protected class PDestination implements Destination { + protected final class + PDestination implements Destination { private String label; private PDestination(String whereTo) { label = whereTo; diff --git a/innerclasses/Wrapping.java b/innerclasses/Wrapping.java index 33584d4cf..74e9e9ab8 100644 --- a/innerclasses/Wrapping.java +++ b/innerclasses/Wrapping.java @@ -1,7 +1,7 @@ // innerclasses/Wrapping.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class Wrapping { private int i; public Wrapping(int x) { i = x; } diff --git a/innerclasses/build.xml b/innerclasses/build.xml deleted file mode 100644 index ba4280c06..000000000 --- a/innerclasses/build.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/innerclasses/controller/Controller.java b/innerclasses/controller/Controller.java index 05c74b6b2..de766961a 100644 --- a/innerclasses/controller/Controller.java +++ b/innerclasses/controller/Controller.java @@ -1,7 +1,7 @@ // innerclasses/controller/Controller.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // The reusable framework for control systems package innerclasses.controller; import java.util.*; diff --git a/innerclasses/controller/Event.java b/innerclasses/controller/Event.java index bb21a2f52..247e4c90b 100644 --- a/innerclasses/controller/Event.java +++ b/innerclasses/controller/Event.java @@ -1,7 +1,7 @@ // innerclasses/controller/Event.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 @@ -9,8 +9,8 @@ public abstract class Event { private Instant eventTime; protected final Duration delayTime; - public Event(long millisecond_delay) { - delayTime = Duration.ofMillis(millisecond_delay); + public Event(long millisecondDelay) { + delayTime = Duration.ofMillis(millisecondDelay); start(); } public void start() { // Allows restarting diff --git a/innerclasses/mui/MultiInterfaces.java b/innerclasses/mui/MultiInterfaces.java index d7e27f4d3..ee69f61ab 100644 --- a/innerclasses/mui/MultiInterfaces.java +++ b/innerclasses/mui/MultiInterfaces.java @@ -1,8 +1,9 @@ // innerclasses/mui/MultiInterfaces.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Two ways that a class can implement multiple interfaces +// 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 {} diff --git a/interfaces/AbstractAccess.java b/interfaces/AbstractAccess.java index c58988ddd..8645d9f36 100644 --- a/interfaces/AbstractAccess.java +++ b/interfaces/AbstractAccess.java @@ -1,7 +1,7 @@ // interfaces/AbstractAccess.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. abstract class AbstractAccess { private void m1() {} @@ -11,5 +11,5 @@ protected void m2() {} void m3() {} abstract void m3a(); public void m4() {} - abstract public void m4a(); + public abstract void m4a(); } diff --git a/interfaces/AbstractWithoutAbstracts.java b/interfaces/AbstractWithoutAbstracts.java index d2a84fda9..587248a02 100644 --- a/interfaces/AbstractWithoutAbstracts.java +++ b/interfaces/AbstractWithoutAbstracts.java @@ -1,7 +1,7 @@ // interfaces/AbstractWithoutAbstracts.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. abstract class Basic3 { int f() { return 111; } diff --git a/interfaces/AdaptedRandomDoubles.java b/interfaces/AdaptedRandomDoubles.java index 7dd6be66e..d965e5add 100644 --- a/interfaces/AdaptedRandomDoubles.java +++ b/interfaces/AdaptedRandomDoubles.java @@ -1,7 +1,7 @@ // interfaces/AdaptedRandomDoubles.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Creating an adapter with inheritance import java.nio.*; import java.util.*; @@ -12,8 +12,7 @@ public class AdaptedRandomDoubles public AdaptedRandomDoubles(int count) { this.count = count; } - @Override - public int read(CharBuffer cb) { + @Override public int read(CharBuffer cb) { if(count-- == 0) return -1; String result = Double.toString(next()) + " "; @@ -21,13 +20,15 @@ public int read(CharBuffer cb) { return result.length(); } public static void main(String[] args) { - Scanner s = new Scanner(new AdaptedRandomDoubles(7)); + 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.7271157860730044 0.5309454508634242 +0.16020656493302599 0.18847866977771732 +0.5166020801268457 0.2678662084200585 0.2613610344283964 */ diff --git a/interfaces/Adventure.java b/interfaces/Adventure.java index dacd94148..4e0bbbde2 100644 --- a/interfaces/Adventure.java +++ b/interfaces/Adventure.java @@ -1,7 +1,7 @@ // interfaces/Adventure.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Multiple interfaces interface CanFight { @@ -22,8 +22,8 @@ public void fight() {} class Hero extends ActionCharacter implements CanFight, CanSwim, CanFly { - public void swim() {} - public void fly() {} + @Override public void swim() {} + @Override public void fly() {} } public class Adventure { diff --git a/interfaces/AnImplementation.java b/interfaces/AnImplementation.java index 7b510d2ec..29ca8df57 100644 --- a/interfaces/AnImplementation.java +++ b/interfaces/AnImplementation.java @@ -1,13 +1,13 @@ // interfaces/AnImplementation.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class AnImplementation implements AnInterface { - public void firstMethod() { + @Override public void firstMethod() { System.out.println("firstMethod"); } - public void secondMethod() { + @Override public void secondMethod() { System.out.println("secondMethod"); } public static void main(String[] args) { diff --git a/interfaces/AnInterface.java b/interfaces/AnInterface.java index 925da5202..333dbe2b5 100644 --- a/interfaces/AnInterface.java +++ b/interfaces/AnInterface.java @@ -1,7 +1,7 @@ // interfaces/AnInterface.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. interface AnInterface { void firstMethod(); diff --git a/interfaces/Applicator.java b/interfaces/Applicator.java index ce148e750..1082629a1 100644 --- a/interfaces/Applicator.java +++ b/interfaces/Applicator.java @@ -1,7 +1,7 @@ // interfaces/Applicator.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; class Processor { @@ -30,7 +30,7 @@ public String process(Object input) { class Splitter extends Processor { @Override public String process(Object input) { - // The split() argument divides a String into pieces: + // split() divides a String into pieces: return Arrays.toString(((String)input).split(" ")); } } @@ -40,9 +40,9 @@ public static void apply(Processor p, Object s) { System.out.println("Using Processor " + p.name()); System.out.println(p.process(s)); } - public static String s = - "Disagreement with beliefs is by definition incorrect"; 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); @@ -50,10 +50,9 @@ public static void main(String[] args) { } /* Output: Using Processor Upcase -DISAGREEMENT WITH BELIEFS IS BY DEFINITION INCORRECT +WE ARE SUCH STUFF AS DREAMS ARE MADE ON Using Processor Downcase -disagreement with beliefs is by definition incorrect +we are such stuff as dreams are made on Using Processor Splitter -[Disagreement, with, beliefs, is, by, definition, -incorrect] +[We, are, such, stuff, as, dreams, are, made, on] */ diff --git a/interfaces/AttemptToUseBasic.java b/interfaces/AttemptToUseBasic.java index ab1decf9a..d8e67f72b 100644 --- a/interfaces/AttemptToUseBasic.java +++ b/interfaces/AttemptToUseBasic.java @@ -1,8 +1,8 @@ // interfaces/AttemptToUseBasic.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {CompileTimeError} (Won't compile) +// Visit http://OnJava8.com for more book information. +// {WillNotCompile} public class AttemptToUseBasic { Basic b = new Basic(); diff --git a/interfaces/Basic.java b/interfaces/Basic.java index f11569948..943392b02 100644 --- a/interfaces/Basic.java +++ b/interfaces/Basic.java @@ -1,7 +1,7 @@ // interfaces/Basic.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. abstract class Basic { abstract void unimplemented(); diff --git a/interfaces/Basic2.java b/interfaces/Basic2.java index 5676ab638..1c33a54f9 100644 --- a/interfaces/Basic2.java +++ b/interfaces/Basic2.java @@ -1,7 +1,7 @@ // interfaces/Basic2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. abstract class Basic2 extends Basic { int f() { return 111; } diff --git a/interfaces/CheckedDowncast.java b/interfaces/CheckedDowncast.java new file mode 100644 index 000000000..90689585d --- /dev/null +++ b/interfaces/CheckedDowncast.java @@ -0,0 +1,19 @@ +// interfaces/CheckedDowncast.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 + +sealed interface II permits JJ {} +final class JJ implements II {} +class Something {} + +public class CheckedDowncast { + public void f() { + II i = new JJ(); + JJ j = (JJ)i; + // Something s = (Something)i; + // error: incompatible types: II cannot + // be converted to Something + } +} diff --git a/interfaces/Factories.java b/interfaces/Factories.java index 3d42dfedc..8ab076014 100644 --- a/interfaces/Factories.java +++ b/interfaces/Factories.java @@ -1,7 +1,7 @@ // interfaces/Factories.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. interface Service { void method1(); @@ -14,34 +14,32 @@ interface ServiceFactory { class Service1 implements Service { Service1() {} // Package access - public void method1() { + @Override public void method1() { System.out.println("Service1 method1"); } - public void method2() { + @Override public void method2() { System.out.println("Service1 method2"); } } class Service1Factory implements ServiceFactory { - @Override - public Service getService() { + @Override public Service getService() { return new Service1(); } } class Service2 implements Service { Service2() {} // Package access - public void method1() { + @Override public void method1() { System.out.println("Service2 method1"); } - public void method2() { + @Override public void method2() { System.out.println("Service2 method2"); } } class Service2Factory implements ServiceFactory { - @Override - public Service getService() { + @Override public Service getService() { return new Service2(); } } diff --git a/interfaces/Games.java b/interfaces/Games.java index faa04206f..3190d3b1e 100644 --- a/interfaces/Games.java +++ b/interfaces/Games.java @@ -1,7 +1,7 @@ // interfaces/Games.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // A Game framework using Factory Methods interface Game { boolean move(); } @@ -10,8 +10,7 @@ interface GameFactory { Game getGame(); } class Checkers implements Game { private int moves = 0; private static final int MOVES = 3; - @Override - public boolean move() { + @Override public boolean move() { System.out.println("Checkers move " + moves); return ++moves != MOVES; } @@ -25,8 +24,7 @@ class CheckersFactory implements GameFactory { class Chess implements Game { private int moves = 0; private static final int MOVES = 4; - @Override - public boolean move() { + @Override public boolean move() { System.out.println("Chess move " + moves); return ++moves != MOVES; } diff --git a/interfaces/HorrorShow.java b/interfaces/HorrorShow.java index 694ac6062..079fe2ce3 100644 --- a/interfaces/HorrorShow.java +++ b/interfaces/HorrorShow.java @@ -1,7 +1,7 @@ // interfaces/HorrorShow.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Extending an interface with inheritance interface Monster { @@ -17,10 +17,8 @@ interface Lethal { } class DragonZilla implements DangerousMonster { - @Override - public void menace() {} - @Override - public void destroy() {} + @Override public void menace() {} + @Override public void destroy() {} } interface Vampire extends DangerousMonster, Lethal { @@ -28,14 +26,10 @@ interface Vampire extends DangerousMonster, Lethal { } class VeryBadVampire implements Vampire { - @Override - public void menace() {} - @Override - public void destroy() {} - @Override - public void kill() {} - @Override - public void drinkBlood() {} + @Override public void menace() {} + @Override public void destroy() {} + @Override public void kill() {} + @Override public void drinkBlood() {} } public class HorrorShow { diff --git a/interfaces/Implementation2.java b/interfaces/Implementation2.java index 0d307d9ad..07fb48324 100644 --- a/interfaces/Implementation2.java +++ b/interfaces/Implementation2.java @@ -1,14 +1,14 @@ // interfaces/Implementation2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class Implementation2 implements InterfaceWithDefault { - public void firstMethod() { + @Override public void firstMethod() { System.out.println("firstMethod"); } - public void secondMethod() { + @Override public void secondMethod() { System.out.println("secondMethod"); } public static void main(String[] args) { diff --git a/interfaces/ImplementingAnInterface.java b/interfaces/ImplementingAnInterface.java index adc49b426..1504667fe 100644 --- a/interfaces/ImplementingAnInterface.java +++ b/interfaces/ImplementingAnInterface.java @@ -1,7 +1,7 @@ // interfaces/ImplementingAnInterface.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. interface Concept { // Package access void idea1(); @@ -9,6 +9,10 @@ interface Concept { // Package access } class Implementation implements Concept { - public void idea1() { System.out.println("idea1"); } - public void idea2() { System.out.println("idea2"); } + @Override public void idea1() { + System.out.println("idea1"); + } + @Override public void idea2() { + System.out.println("idea2"); + } } diff --git a/interfaces/Instantiable.java b/interfaces/Instantiable.java index 80fc254d4..80b689895 100644 --- a/interfaces/Instantiable.java +++ b/interfaces/Instantiable.java @@ -1,7 +1,7 @@ // interfaces/Instantiable.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. abstract class Uninstantiable { abstract void f(); @@ -9,10 +9,8 @@ abstract class Uninstantiable { } public class Instantiable extends Uninstantiable { - @Override - void f() { System.out.println("f()"); } - @Override - int g() { return 22; } + @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/interfaces/InterfaceCollision.java b/interfaces/InterfaceCollision.java index 4d761b9bd..e00fb8a84 100644 --- a/interfaces/InterfaceCollision.java +++ b/interfaces/InterfaceCollision.java @@ -1,7 +1,7 @@ // interfaces/InterfaceCollision.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. interface I1 { void f(); } interface I2 { int f(int i); } @@ -12,18 +12,17 @@ class C2 implements I1, I2 { @Override public void f() {} @Override - public int f(int i) { return 1; } // overloaded + public int f(int i) { return 1; } // Overloaded } class C3 extends C implements I2 { @Override - public int f(int i) { return 1; } // overloaded + public int f(int i) { return 1; } // Overloaded } class C4 extends C implements I3 { // Identical, no problem: - @Override - public int f() { return 1; } + @Override public int f() { return 1; } } // Methods differ only by return type: diff --git a/interfaces/InterfaceWithDefault.java b/interfaces/InterfaceWithDefault.java index 8b378d492..983beb4b4 100644 --- a/interfaces/InterfaceWithDefault.java +++ b/interfaces/InterfaceWithDefault.java @@ -1,7 +1,7 @@ // interfaces/InterfaceWithDefault.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. interface InterfaceWithDefault { void firstMethod(); diff --git a/interfaces/Jim.java b/interfaces/Jim.java index 6867be772..a22f53dd3 100644 --- a/interfaces/Jim.java +++ b/interfaces/Jim.java @@ -1,20 +1,25 @@ // interfaces/Jim.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; interface Jim1 { - default void jim() { System.out.println("Jim1::jim"); } + default void jim() { + System.out.println("Jim1::jim"); + } } interface Jim2 { - default void jim() { System.out.println("Jim2::jim"); } + default void jim() { + System.out.println("Jim2::jim"); + } } public class Jim implements Jim1, Jim2 { - @Override - public void jim() { Jim2.super.jim(); } + @Override public void jim() { + Jim2.super.jim(); + } public static void main(String[] args) { new Jim().jim(); } diff --git a/interfaces/MICollision.java b/interfaces/MICollision.java index f257c27d2..ab1c8090f 100644 --- a/interfaces/MICollision.java +++ b/interfaces/MICollision.java @@ -1,15 +1,19 @@ // interfaces/MICollision.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; interface Bob1 { - default void bob() { System.out.println("Bob1::bob"); } + default void bob() { + System.out.println("Bob1::bob"); + } } interface Bob2 { - default void bob() { System.out.println("Bob2::bob"); } + default void bob() { + System.out.println("Bob2::bob"); + } } // class Bob implements Bob1, Bob2 {} @@ -22,18 +26,24 @@ class Bob implements Bob1, Bob2 {} */ interface Sam1 { - default void sam() { System.out.println("Sam1::sam"); } + default void sam() { + System.out.println("Sam1::sam"); + } } interface Sam2 { - default void sam(int i) { System.out.println(i * 2); } + default void sam(int i) { + System.out.println(i * 2); + } } -// This works because the argument lists are distinct: +// Works because the argument lists are distinct: class Sam implements Sam1, Sam2 {} interface Max1 { - default void max() { System.out.println("Max1::max"); } + default void max() { + System.out.println("Max1::max"); + } } interface Max2 { diff --git a/interfaces/Machine.java b/interfaces/Machine.java deleted file mode 100644 index d807bd256..000000000 --- a/interfaces/Machine.java +++ /dev/null @@ -1,36 +0,0 @@ -// interfaces/Machine.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.*; -import onjava.Operation; - -class Bing implements Operation { - public void execute() { - Operation.show("Bing"); - } -} - -class Crack implements Operation { - public void execute() { - Operation.show("Crack"); - } -} - -class Twist implements Operation { - public void execute() { - Operation.show("Twist"); - } -} - -public class Machine { - public static void main(String[] args) { - Operation.runOps( - new Bing(), new Crack(), new Twist()); - } -} -/* Output: -Bing -Crack -Twist -*/ diff --git a/interfaces/MetalWork.java b/interfaces/MetalWork.java new file mode 100644 index 000000000..071b13ac9 --- /dev/null +++ b/interfaces/MetalWork.java @@ -0,0 +1,39 @@ +// interfaces/MetalWork.java +// (c)2021 MindView LLC: 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.Operation; + +class Heat implements Operation { + @Override public void execute() { + Operation.show("Heat"); + } +} + +public class MetalWork { + public static void main(String[] args) { + // Must be defined in a static context + // to access a method reference: + Operation twist = new Operation() { + public void execute() { + Operation.show("Twist"); + } + }; + Operation.runOps( + new Heat(), // [1] + new Operation() { // [2] + public void execute() { + Operation.show("Hammer"); + } + }, + twist::execute, // [3] + () -> Operation.show("Anneal") // [4] + ); + } +} +/* Output: +Heat +Hammer +Twist +Anneal +*/ diff --git a/interfaces/Months.java b/interfaces/Months.java index baec98922..d475340b1 100644 --- a/interfaces/Months.java +++ b/interfaces/Months.java @@ -1,7 +1,7 @@ // interfaces/Months.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Using interfaces to create groups of constants public interface Months { diff --git a/interfaces/MultipleInheritance.java b/interfaces/MultipleInheritance.java index ce47d8b86..e2b96777c 100644 --- a/interfaces/MultipleInheritance.java +++ b/interfaces/MultipleInheritance.java @@ -1,7 +1,7 @@ // interfaces/MultipleInheritance.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; interface One { @@ -9,7 +9,9 @@ interface One { } interface Two { - default void second() { System.out.println("second"); } + default void second() { + System.out.println("second"); + } } interface Three { diff --git a/interfaces/NonSealed.java b/interfaces/NonSealed.java new file mode 100644 index 000000000..8bc4b8fae --- /dev/null +++ b/interfaces/NonSealed.java @@ -0,0 +1,11 @@ +// interfaces/NonSealed.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 + +sealed class Super permits Sub1, Sub2 {} +final class Sub1 extends Super {} +non-sealed class Sub2 extends Super {} +class Any1 extends Sub2 {} +class Any2 extends Sub2 {} diff --git a/interfaces/PermittedSubclasses.java b/interfaces/PermittedSubclasses.java new file mode 100644 index 000000000..73afd6eb7 --- /dev/null +++ b/interfaces/PermittedSubclasses.java @@ -0,0 +1,22 @@ +// interfaces/PermittedSubclasses.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 + +sealed class Color permits Red, Green, Blue {} +final class Red extends Color {} +final class Green extends Color {} +final class Blue extends Color {} + +public class PermittedSubclasses { + public static void main(String[] args) { + for(var p: Color.class.getPermittedSubclasses()) + System.out.println(p.getSimpleName()); + } +} +/* Output: +Red +Green +Blue +*/ diff --git a/interfaces/PrivateInterfaceMethods.java b/interfaces/PrivateInterfaceMethods.java new file mode 100644 index 000000000..ebad9bd5b --- /dev/null +++ b/interfaces/PrivateInterfaceMethods.java @@ -0,0 +1,54 @@ +// interfaces/PrivateInterfaceMethods.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 9 + +interface Old { + default void fd() { + System.out.println("Old::fd()"); + } + static void fs() { + System.out.println("Old::fs()"); + } + default void f() { + fd(); + } + static void g() { + fs(); + } +} + +class ImplOld implements Old {} + +interface JDK9 { + private void fd() { // Automatically default + System.out.println("JDK9::fd()"); + } + private static void fs() { + System.out.println("JDK9::fs()"); + } + default void f() { + fd(); + } + static void g() { + fs(); + } +} + +class ImplJDK9 implements JDK9 {} + +public class PrivateInterfaceMethods { + public static void main(String[] args) { + new ImplOld().f(); + Old.g(); + new ImplJDK9().f(); + JDK9.g(); + } +} +/* Output: +Old::fd() +Old::fs() +JDK9::fd() +JDK9::fs() +*/ diff --git a/interfaces/PureInterface.java b/interfaces/PureInterface.java index 8b8ea0e66..ef7732be1 100644 --- a/interfaces/PureInterface.java +++ b/interfaces/PureInterface.java @@ -1,7 +1,7 @@ // interfaces/PureInterface.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Interface only looked like this before Java 8 public interface PureInterface { diff --git a/interfaces/RandVals.java b/interfaces/RandVals.java index 756314960..449ae3f0e 100644 --- a/interfaces/RandVals.java +++ b/interfaces/RandVals.java @@ -1,7 +1,7 @@ // interfaces/RandVals.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Initializing interface fields with // non-constant initializers import java.util.*; diff --git a/interfaces/RandomDoubles.java b/interfaces/RandomDoubles.java index c393c4ae7..afe18dc0a 100644 --- a/interfaces/RandomDoubles.java +++ b/interfaces/RandomDoubles.java @@ -1,20 +1,21 @@ // interfaces/RandomDoubles.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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(); } - public static void main(String[] args) { + 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.7271157860730044 0.5309454508634242 +0.16020656493302599 0.18847866977771732 +0.5166020801268457 0.2678662084200585 0.2613610344283964 */ diff --git a/interfaces/RandomWords.java b/interfaces/RandomStrings.java similarity index 54% rename from interfaces/RandomWords.java rename to interfaces/RandomStrings.java index e1769bbdf..da45cf48e 100644 --- a/interfaces/RandomWords.java +++ b/interfaces/RandomStrings.java @@ -1,35 +1,36 @@ -// interfaces/RandomWords.java -// (c)2016 MindView LLC: see Copyright.txt +// interfaces/RandomStrings.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Implementing an interface to conform to a method import java.nio.*; import java.util.*; -public class RandomWords implements Readable { +public class RandomStrings implements Readable { private static Random rand = new Random(47); - private static final char[] capitals = + private static final char[] CAPITALS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); - private static final char[] lowers = + private static final char[] LOWERS = "abcdefghijklmnopqrstuvwxyz".toCharArray(); - private static final char[] vowels = + private static final char[] VOWELS = "aeiou".toCharArray(); private int count; - public RandomWords(int count) { this.count = count; } - @Override - public int read(CharBuffer cb) { + 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)]); + 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(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 RandomWords(10)); + Scanner s = new Scanner(new RandomStrings(10)); while(s.hasNext()) System.out.println(s.next()); } diff --git a/interfaces/SameFile.java b/interfaces/SameFile.java new file mode 100644 index 000000000..e20e93ae7 --- /dev/null +++ b/interfaces/SameFile.java @@ -0,0 +1,9 @@ +// interfaces/SameFile.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 + +sealed class Shape {} +final class Circle extends Shape {} +final class Triangle extends Shape {} diff --git a/interfaces/Sealed.java b/interfaces/Sealed.java new file mode 100644 index 000000000..5124606c0 --- /dev/null +++ b/interfaces/Sealed.java @@ -0,0 +1,12 @@ +// interfaces/Sealed.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 + +sealed class Base permits D1, D2 {} + +final class D1 extends Base {} +final class D2 extends Base {} +// Illegal: +// final class D3 extends Base {} diff --git a/interfaces/SealedCat.java b/interfaces/SealedCat.java new file mode 100644 index 000000000..0356ccac8 --- /dev/null +++ b/interfaces/SealedCat.java @@ -0,0 +1,6 @@ +// interfaces/SealedCat.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 +final class Cat extends Pet {} diff --git a/interfaces/SealedDog.java b/interfaces/SealedDog.java new file mode 100644 index 000000000..f0441afde --- /dev/null +++ b/interfaces/SealedDog.java @@ -0,0 +1,6 @@ +// interfaces/SealedDog.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 +final class Dog extends Pet {} diff --git a/interfaces/SealedInterface.java b/interfaces/SealedInterface.java new file mode 100644 index 000000000..315517bb1 --- /dev/null +++ b/interfaces/SealedInterface.java @@ -0,0 +1,12 @@ +// interfaces/SealedInterface.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 + +sealed interface Ifc permits Imp1, Imp2 {} +final class Imp1 implements Ifc {} +final class Imp2 implements Ifc {} + +sealed abstract class AC permits X {} +final class X extends AC {} diff --git a/interfaces/SealedPets.java b/interfaces/SealedPets.java new file mode 100644 index 000000000..79ab9e5bc --- /dev/null +++ b/interfaces/SealedPets.java @@ -0,0 +1,6 @@ +// interfaces/SealedPets.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 +sealed class Pet permits Dog, Cat {} diff --git a/interfaces/SealedRecords.java b/interfaces/SealedRecords.java new file mode 100644 index 000000000..c1fd7b7eb --- /dev/null +++ b/interfaces/SealedRecords.java @@ -0,0 +1,12 @@ +// interfaces/SealedRecords.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 + +sealed interface Employee + permits CLevel, Programmer {} +record CLevel(String type) + implements Employee {} +record Programmer(String experience) + implements Employee {} diff --git a/interfaces/SealedSubclasses.java b/interfaces/SealedSubclasses.java new file mode 100644 index 000000000..68b83af3e --- /dev/null +++ b/interfaces/SealedSubclasses.java @@ -0,0 +1,10 @@ +// interfaces/SealedSubclasses.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 + +sealed class Bottom permits Level1 {} +sealed class Level1 extends Bottom permits Level2 {} +sealed class Level2 extends Level1 permits Level3 {} +final class Level3 extends Level2 {} diff --git a/interfaces/TestRandVals.java b/interfaces/TestRandVals.java index 17467e3c1..132d7af89 100644 --- a/interfaces/TestRandVals.java +++ b/interfaces/TestRandVals.java @@ -1,7 +1,7 @@ // interfaces/TestRandVals.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class TestRandVals { public static void main(String[] args) { diff --git a/interfaces/build.xml b/interfaces/build.xml deleted file mode 100644 index 4e978be1c..000000000 --- a/interfaces/build.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/interfaces/filters/BandPass.java b/interfaces/filters/BandPass.java index 28bad56c3..e0e233904 100644 --- a/interfaces/filters/BandPass.java +++ b/interfaces/filters/BandPass.java @@ -1,7 +1,7 @@ // interfaces/filters/BandPass.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package interfaces.filters; public class BandPass extends Filter { diff --git a/interfaces/filters/Filter.java b/interfaces/filters/Filter.java index 59b2661d5..e2d0ae6dc 100644 --- a/interfaces/filters/Filter.java +++ b/interfaces/filters/Filter.java @@ -1,7 +1,7 @@ // interfaces/filters/Filter.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package interfaces.filters; public class Filter { diff --git a/interfaces/filters/HighPass.java b/interfaces/filters/HighPass.java index 03b1600eb..8167e1b8b 100644 --- a/interfaces/filters/HighPass.java +++ b/interfaces/filters/HighPass.java @@ -1,7 +1,7 @@ // interfaces/filters/HighPass.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package interfaces.filters; public class HighPass extends Filter { diff --git a/interfaces/filters/LowPass.java b/interfaces/filters/LowPass.java index 4a21ba14d..77bedf515 100644 --- a/interfaces/filters/LowPass.java +++ b/interfaces/filters/LowPass.java @@ -1,7 +1,7 @@ // interfaces/filters/LowPass.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package interfaces.filters; public class LowPass extends Filter { diff --git a/interfaces/filters/Waveform.java b/interfaces/filters/Waveform.java index b2a9d6f71..8262fc102 100644 --- a/interfaces/filters/Waveform.java +++ b/interfaces/filters/Waveform.java @@ -1,14 +1,13 @@ // interfaces/filters/Waveform.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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() { + @Override public String toString() { return "Waveform " + id; } } diff --git a/interfaces/interfaceprocessor/Applicator.java b/interfaces/interfaceprocessor/Applicator.java index 12474a77c..3b063a473 100644 --- a/interfaces/interfaceprocessor/Applicator.java +++ b/interfaces/interfaceprocessor/Applicator.java @@ -1,7 +1,7 @@ // interfaces/interfaceprocessor/Applicator.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package interfaces.interfaceprocessor; public class Applicator { diff --git a/interfaces/interfaceprocessor/FilterProcessor.java b/interfaces/interfaceprocessor/FilterProcessor.java index f4eb8aaf0..066be331a 100644 --- a/interfaces/interfaceprocessor/FilterProcessor.java +++ b/interfaces/interfaceprocessor/FilterProcessor.java @@ -1,13 +1,14 @@ // interfaces/interfaceprocessor/FilterProcessor.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {java interfaces.interfaceprocessor.FilterProcessor} package interfaces.interfaceprocessor; import interfaces.filters.*; class FilterAdapter implements Processor { Filter filter; - public FilterAdapter(Filter filter) { + FilterAdapter(Filter filter) { this.filter = filter; } @Override diff --git a/interfaces/interfaceprocessor/Processor.java b/interfaces/interfaceprocessor/Processor.java index e0a1ebf50..343803194 100644 --- a/interfaces/interfaceprocessor/Processor.java +++ b/interfaces/interfaceprocessor/Processor.java @@ -1,7 +1,7 @@ // interfaces/interfaceprocessor/Processor.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package interfaces.interfaceprocessor; public interface Processor { diff --git a/interfaces/interfaceprocessor/StringProcessor.java b/interfaces/interfaceprocessor/StringProcessor.java index 4074aa032..f97472b7c 100644 --- a/interfaces/interfaceprocessor/StringProcessor.java +++ b/interfaces/interfaceprocessor/StringProcessor.java @@ -1,19 +1,21 @@ // interfaces/interfaceprocessor/StringProcessor.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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"; - public static void main(String[] args) { // (3) - Applicator.apply(new Upcase(), s); - Applicator.apply(new Downcase(), s); - Applicator.apply(new Splitter(), s); + 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); } } @@ -43,6 +45,6 @@ public String process(Object input) { 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] +[If, she, weighs, the, same, as, a, duck,, she's, made, +of, wood] */ diff --git a/interfaces/music4/Music4.java b/interfaces/music4/Music4.java index 776d80e67..a875d4c4e 100644 --- a/interfaces/music4/Music4.java +++ b/interfaces/music4/Music4.java @@ -1,8 +1,9 @@ // interfaces/music4/Music4.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Abstract classes and methods +// {java interfaces.music4.Music4} package interfaces.music4; import polymorphism.music.Note; @@ -14,62 +15,51 @@ abstract class Instrument { } class Wind extends Instrument { - @Override - public void play(Note n) { + @Override public void play(Note n) { System.out.println("Wind.play() " + n); } - @Override - public String what() { return "Wind"; } - @Override - public void adjust() { + @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) { + @Override public void play(Note n) { System.out.println("Percussion.play() " + n); } - @Override - public String what() { return "Percussion"; } - @Override - public void adjust() { + @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) { + @Override public void play(Note n) { System.out.println("Stringed.play() " + n); } - @Override - public String what() { return "Stringed"; } - @Override - public void adjust() { + @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) { + @Override public void play(Note n) { System.out.println("Brass.play() " + n); } - @Override - public void adjust() { + @Override public void adjust() { System.out.println("Adjusting Brass"); } } class Woodwind extends Wind { - @Override - public void play(Note n) { + @Override public void play(Note n) { System.out.println("Woodwind.play() " + n); } - @Override - public String what() { return "Woodwind"; } + @Override public String what() { return "Woodwind"; } } public class Music4 { diff --git a/interfaces/music5/Music5.java b/interfaces/music5/Music5.java index a2d490ca2..775e656b8 100644 --- a/interfaces/music5/Music5.java +++ b/interfaces/music5/Music5.java @@ -1,7 +1,8 @@ // interfaces/music5/Music5.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {java interfaces.music5.Music5} package interfaces.music5; import polymorphism.music.Note; @@ -17,28 +18,33 @@ default void adjust() { } class Wind implements Instrument { - @Override - public String toString() { return "Wind"; } + @Override public String toString() { + return "Wind"; + } } class Percussion implements Instrument { - @Override - public String toString() { return "Percussion"; } + @Override public String toString() { + return "Percussion"; + } } class Stringed implements Instrument { - @Override - public String toString() { return "Stringed"; } + @Override public String toString() { + return "Stringed"; + } } class Brass extends Wind { - @Override - public String toString() { return "Brass"; } + @Override public String toString() { + return "Brass"; + } } class Woodwind extends Wind { - @Override - public String toString() { return "Woodwind"; } + @Override public String toString() { + return "Woodwind"; + } } public class Music5 { diff --git a/interfaces/nesting/NestingInterfaces.java b/interfaces/nesting/NestingInterfaces.java index 555e6bf3f..fa4d482ce 100644 --- a/interfaces/nesting/NestingInterfaces.java +++ b/interfaces/nesting/NestingInterfaces.java @@ -1,7 +1,8 @@ // interfaces/nesting/NestingInterfaces.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {java interfaces.nesting.NestingInterfaces} package interfaces.nesting; class A { @@ -9,34 +10,28 @@ interface B { void f(); } public class BImp implements B { - @Override - public void f() {} + @Override public void f() {} } private class BImp2 implements B { - @Override - public void f() {} + @Override public void f() {} } public interface C { void f(); } class CImp implements C { - @Override - public void f() {} + @Override public void f() {} } private class CImp2 implements C { - @Override - public void f() {} + @Override public void f() {} } private interface D { void f(); } private class DImp implements D { - @Override - public void f() {} + @Override public void f() {} } public class DImp2 implements D { - @Override - public void f() {} + @Override public void f() {} } public D getD() { return new DImp2(); } private D dRef; @@ -61,12 +56,10 @@ public interface H { public class NestingInterfaces { public class BImp implements A.B { - @Override - public void f() {} + @Override public void f() {} } class CImp implements A.C { - @Override - public void f() {} + @Override public void f() {} } // Cannot implement a private interface except // within that interface's defining class: @@ -74,19 +67,15 @@ public void f() {} //- public void f() {} //- } class EImp implements E { - @Override - public void g() {} + @Override public void g() {} } class EGImp implements E.G { - @Override - public void f() {} + @Override public void f() {} } class EImp2 implements E { - @Override - public void g() {} + @Override public void g() {} class EG implements E.G { - @Override - public void f() {} + @Override public void f() {} } } public static void main(String[] args) { diff --git a/iostreams/BasicFileOutput.java b/iostreams/BasicFileOutput.java index 36a06c415..c31cf7f21 100644 --- a/iostreams/BasicFileOutput.java +++ b/iostreams/BasicFileOutput.java @@ -1,26 +1,26 @@ // iostreams/BasicFileOutput.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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) throws IOException { - try(BufferedReader in = new BufferedReader( - new StringReader( - BufferedInputFile.read( - "BasicFileOutput.java"))); - PrintWriter out = new PrintWriter( - new BufferedWriter(new FileWriter(file)))) { - int lineCount = 1; - String s; - while((s = in.readLine()) != null ) - out.println(lineCount++ + ": " + s); + 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)); } } -/* Output: (Execute to see) */ diff --git a/iostreams/BufferedInputFile.java b/iostreams/BufferedInputFile.java index 950067992..2c5c8ae7f 100644 --- a/iostreams/BufferedInputFile.java +++ b/iostreams/BufferedInputFile.java @@ -1,24 +1,23 @@ // iostreams/BufferedInputFile.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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) throws IOException { + public static String read(String filename) { try(BufferedReader in = new BufferedReader( - new FileReader(filename))) { - String s; - StringBuilder sb = new StringBuilder(); - while((s = in.readLine())!= null) - sb.append(s + "\n"); - return sb.toString(); + new FileReader(filename))) { + return in.lines() + .collect(Collectors.joining("\n")); + } catch(IOException e) { + throw new RuntimeException(e); } } - public static void - main(String[] args) throws IOException { - System.out.print(read("BufferedInputFile.java")); + public static void main(String[] args) { + System.out.print( + read("BufferedInputFile.java")); } } -/* Output: (Execute to see) */ diff --git a/iostreams/FileOutputShortcut.java b/iostreams/FileOutputShortcut.java index 6e7607f6b..54d3e0597 100644 --- a/iostreams/FileOutputShortcut.java +++ b/iostreams/FileOutputShortcut.java @@ -1,25 +1,24 @@ // iostreams/FileOutputShortcut.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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) throws IOException { - try(BufferedReader in = new BufferedReader( - new StringReader(BufferedInputFile.read( - "FileOutputShortcut.java"))); - // Here's the shortcut: - PrintWriter out = new PrintWriter(file)) { - int lineCount = 1; - String s; - while((s = in.readLine()) != null ) - out.println(lineCount++ + ": " + s); + 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); } - // Show the stored file: System.out.println(BufferedInputFile.read(file)); } } -/* Output: (Execute to see) */ diff --git a/iostreams/FormattedMemoryInput.java b/iostreams/FormattedMemoryInput.java index aa60ec523..f29e75128 100644 --- a/iostreams/FormattedMemoryInput.java +++ b/iostreams/FormattedMemoryInput.java @@ -1,22 +1,25 @@ // iostreams/FormattedMemoryInput.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {VisuallyInspectOutput} import java.io.*; public class FormattedMemoryInput { - public static void - main(String[] args) throws IOException { - try(DataInputStream in = new DataInputStream( - new ByteArrayInputStream( - BufferedInputFile.read( - "FormattedMemoryInput.java") - .getBytes()))) { + 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("End of stream"); + System.out.println("\nEnd of stream"); + } catch(IOException e) { + throw new RuntimeException(e); } } } -/* Output: (Execute to see) */ diff --git a/iostreams/MemoryInput.java b/iostreams/MemoryInput.java index 9ef9e1f1d..db5f8d4f9 100644 --- a/iostreams/MemoryInput.java +++ b/iostreams/MemoryInput.java @@ -1,7 +1,8 @@ // iostreams/MemoryInput.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {VisuallyInspectOutput} import java.io.*; public class MemoryInput { @@ -14,4 +15,3 @@ public class MemoryInput { System.out.print((char)c); } } -/* Output: (Execute to see) */ diff --git a/iostreams/StoringAndRecoveringData.java b/iostreams/StoringAndRecoveringData.java index b5a000965..961f418d7 100644 --- a/iostreams/StoringAndRecoveringData.java +++ b/iostreams/StoringAndRecoveringData.java @@ -1,29 +1,36 @@ // iostreams/StoringAndRecoveringData.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.io.*; public class StoringAndRecoveringData { - public static void - main(String[] args) throws IOException { - try(DataOutputStream out = new DataOutputStream( - new BufferedOutputStream( - new FileOutputStream("Data.txt")))) { + 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")))) { + 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); } } } diff --git a/iostreams/TestEOF.java b/iostreams/TestEOF.java index e5cc1a1a9..a1c939667 100644 --- a/iostreams/TestEOF.java +++ b/iostreams/TestEOF.java @@ -1,19 +1,22 @@ // iostreams/TestEOF.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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) throws IOException { - try(DataInputStream in = new DataInputStream( - new BufferedInputStream( - new FileInputStream("TestEOF.java")))) { + 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); } } } -/* Output: (Execute to see) */ diff --git a/iostreams/UsingRandomAccessFile.java b/iostreams/UsingRandomAccessFile.java index d7a6e0e79..98969a1d2 100644 --- a/iostreams/UsingRandomAccessFile.java +++ b/iostreams/UsingRandomAccessFile.java @@ -1,36 +1,47 @@ // iostreams/UsingRandomAccessFile.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.io.*; public class UsingRandomAccessFile { static String file = "rtest.dat"; - static void display() throws IOException { - try(RandomAccessFile rf = - new RandomAccessFile(file, "r")) { + 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) throws IOException { - try(RandomAccessFile rf = - new RandomAccessFile(file, "rw")) { + 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")) { + 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); } } } diff --git a/iostreams/build.xml b/iostreams/build.xml deleted file mode 100644 index 3e3c247c1..000000000 --- a/iostreams/build.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/objects/Documentation1.java b/javadoc/Documentation1.java similarity index 58% rename from objects/Documentation1.java rename to javadoc/Documentation1.java index a9476975f..790f69fd5 100644 --- a/objects/Documentation1.java +++ b/javadoc/Documentation1.java @@ -1,7 +1,7 @@ -// objects/Documentation1.java -// (c)2016 MindView LLC: see Copyright.txt +// javadoc/Documentation1.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. /** A class comment */ public class Documentation1 { /** A field comment */ diff --git a/objects/Documentation2.java b/javadoc/Documentation2.java similarity index 51% rename from objects/Documentation2.java rename to javadoc/Documentation2.java index 0a403f2ca..397009e4c 100644 --- a/objects/Documentation2.java +++ b/javadoc/Documentation2.java @@ -1,7 +1,7 @@ -// objects/Documentation2.java -// (c)2016 MindView LLC: see Copyright.txt +// javadoc/Documentation2.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. /**

  * System.out.println(new Date());
  * 
diff --git a/objects/Documentation3.java b/javadoc/Documentation3.java similarity index 58% rename from objects/Documentation3.java rename to javadoc/Documentation3.java index f69f452e6..c48351ea5 100644 --- a/objects/Documentation3.java +++ b/javadoc/Documentation3.java @@ -1,7 +1,8 @@ -// objects/Documentation3.java -// (c)2016 MindView LLC: see Copyright.txt +// javadoc/Documentation3.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. + /** You can even insert a list: *
    *
  1. Item one @@ -9,4 +10,5 @@ *
  2. Item three *
*/ + public class Documentation3 {} diff --git a/javadoc/HelloDateDoc.java b/javadoc/HelloDateDoc.java new file mode 100644 index 000000000..b6ebe8b47 --- /dev/null +++ b/javadoc/HelloDateDoc.java @@ -0,0 +1,26 @@ +// javadoc/HelloDateDoc.java +// (c)2021 MindView LLC: see Copyright.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: +Sun Jan 24 08:49:10 MST 2021 +*/ diff --git a/logging/ConfigureLogging.java b/logging/ConfigureLogging.java deleted file mode 100644 index b378f82ba..000000000 --- a/logging/ConfigureLogging.java +++ /dev/null @@ -1,84 +0,0 @@ -// logging/ConfigureLogging.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {JVMArgs: -Djava.util.logging.config.file=log.prop} -// {ErrorOutputExpected} -import java.util.logging.*; - -public class ConfigureLogging { - static Logger - lgr = Logger.getLogger("com"), - lgr2 = Logger.getLogger("com.mindviewinc"), - util= Logger.getLogger("onjava"), - test= Logger.getLogger("com.mindviewinc.test"), - rand = Logger.getLogger("random"); - public ConfigureLogging() { - /* - Set Additional formatters, Filters and - Handlers for the loggers here. You cannot - specify the Handlers for loggers except - the root logger from the configuration - file. - */ - } - public static void main(String[] args) { - sendLogMessages(lgr); - sendLogMessages(lgr2); - sendLogMessages(util); - sendLogMessages(test); - sendLogMessages(rand); - } - private static void - sendLogMessages(Logger logger) { - System.out.println(" Logger Name : " - + logger.getName() + " Level: " - + logger.getLevel()); - logger.finest("Finest"); - logger.finer("Finer"); - logger.fine("Fine"); - logger.config("Config"); - logger.info("Info"); - logger.warning("Warning"); - logger.severe("Severe"); - } -} -/* Output: -Logger Name : com Level: null - Logger Name : com.mindviewinc Level: null - Logger Name : onjava Level: null - Logger Name : com.mindviewinc.test Level: null - Logger Name : random Level: null -___[ Error Output ]___ -Dec 15, 2015 9:58:42 PM ConfigureLogging sendLogMessages -INFO: Info -Dec 15, 2015 9:58:42 PM ConfigureLogging sendLogMessages -WARNING: Warning -Dec 15, 2015 9:58:42 PM ConfigureLogging sendLogMessages -SEVERE: Severe -Dec 15, 2015 9:58:42 PM ConfigureLogging sendLogMessages -INFO: Info -Dec 15, 2015 9:58:42 PM ConfigureLogging sendLogMessages -WARNING: Warning -Dec 15, 2015 9:58:42 PM ConfigureLogging sendLogMessages -SEVERE: Severe -Dec 15, 2015 9:58:42 PM ConfigureLogging sendLogMessages -INFO: Info -Dec 15, 2015 9:58:42 PM ConfigureLogging sendLogMessages -WARNING: Warning -Dec 15, 2015 9:58:42 PM ConfigureLogging sendLogMessages -SEVERE: Severe -Dec 15, 2015 9:58:42 PM ConfigureLogging sendLogMessages -INFO: Info -Dec 15, 2015 9:58:42 PM ConfigureLogging sendLogMessages -WARNING: Warning -Dec 15, 2015 9:58:42 PM ConfigureLogging sendLogMessages -SEVERE: Severe -Dec 15, 2015 9:58:42 PM ConfigureLogging sendLogMessages -INFO: Info -Dec 15, 2015 9:58:42 PM ConfigureLogging sendLogMessages -WARNING: Warning -Dec 15, 2015 9:58:42 PM ConfigureLogging sendLogMessages -SEVERE: Severe -___[ Error Output is Expected ]___ -*/ diff --git a/logging/CustomHandler.java b/logging/CustomHandler.java deleted file mode 100644 index b111b003a..000000000 --- a/logging/CustomHandler.java +++ /dev/null @@ -1,48 +0,0 @@ -// logging/CustomHandler.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// How to write custom handler -// {ErrorOutputExpected} -import java.util.logging.*; -import java.util.*; - -public class CustomHandler { - private static Logger logger = - Logger.getLogger("CustomHandler"); - private static List trace = - new ArrayList<>(); - public static void main(String[] args) { - logger.addHandler(new Handler() { - @Override - public void publish(LogRecord logRecord) { - trace.add(logRecord.getLevel() + ":"); - trace.add(logRecord.getSourceClassName() - + ":"); - trace.add( - logRecord.getSourceMethodName() +":"); - trace.add("<" + logRecord.getMessage() - + ">"); - trace.add("\n"); - } - @Override - public void flush() {} - @Override - public void close() {} - }); - logger.warning("Logging Warning"); - logger.info("Logging Info"); - System.out.print(trace); - } -} -/* Output: -[WARNING:, CustomHandler:, main:, , -, INFO:, CustomHandler:, main:, , -] -___[ Error Output ]___ -Dec 15, 2015 9:58:42 PM CustomHandler main -WARNING: Logging Warning -Dec 15, 2015 9:58:42 PM CustomHandler main -INFO: Logging Info -___[ Error Output is Expected ]___ -*/ diff --git a/logging/InfoLogging.java b/logging/InfoLogging.java deleted file mode 100644 index 9e987fcda..000000000 --- a/logging/InfoLogging.java +++ /dev/null @@ -1,20 +0,0 @@ -// logging/InfoLogging.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {ErrorOutputExpected} -import java.util.logging.*; - -public class InfoLogging { - private static Logger logger = - Logger.getLogger("InfoLogging"); - public static void main(String[] args) { - logger.info("Logging: INFO-level message"); - } -} -/* Output: -___[ Error Output ]___ -Dec 15, 2015 9:58:43 PM InfoLogging main -INFO: Logging: INFO-level message -___[ Error Output is Expected ]___ -*/ diff --git a/logging/InfoLogging2.java b/logging/InfoLogging2.java deleted file mode 100644 index b3ba0c6f2..000000000 --- a/logging/InfoLogging2.java +++ /dev/null @@ -1,22 +0,0 @@ -// logging/InfoLogging2.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Guaranteeing proper class and method names -// {ErrorOutputExpected} -import java.util.logging.*; - -public class InfoLogging2 { - private static Logger logger = - Logger.getLogger("InfoLogging2"); - public static void main(String[] args) { - logger.logp(Level.INFO, "InfoLogging2", - "main", "Logging an INFO-level message"); - } -} -/* Output: -___[ Error Output ]___ -Dec 15, 2015 9:58:43 PM InfoLogging2 main -INFO: Logging an INFO-level message -___[ Error Output is Expected ]___ -*/ diff --git a/logging/LogToFile.java b/logging/LogToFile.java deleted file mode 100644 index 8337ee9c4..000000000 --- a/logging/LogToFile.java +++ /dev/null @@ -1,23 +0,0 @@ -// logging/LogToFile.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {ErrorOutputExpected} -import java.util.logging.*; - -public class LogToFile { - private static Logger logger = - Logger.getLogger("LogToFile"); - public static void - main(String[] args) throws Exception { - logger.addHandler( - new FileHandler("LogToFile.xml")); - logger.info("A message logged to the file"); - } -} -/* Output: -___[ Error Output ]___ -Dec 15, 2015 9:58:43 PM LogToFile main -INFO: A message logged to the file -___[ Error Output is Expected ]___ -*/ diff --git a/logging/LogToFile2.java b/logging/LogToFile2.java deleted file mode 100644 index 4fd6d5d02..000000000 --- a/logging/LogToFile2.java +++ /dev/null @@ -1,25 +0,0 @@ -// logging/LogToFile2.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {ErrorOutputExpected} -import java.util.logging.*; - -public class LogToFile2 { - private static Logger logger = - Logger.getLogger("LogToFile2"); - public static void - main(String[] args) throws Exception { - FileHandler logFile = - new FileHandler("LogToFile2.txt"); - logFile.setFormatter(new SimpleFormatter()); - logger.addHandler(logFile); - logger.info("A message logged to the file"); - } -} -/* Output: -___[ Error Output ]___ -Dec 15, 2015 9:58:43 PM LogToFile2 main -INFO: A message logged to the file -___[ Error Output is Expected ]___ -*/ diff --git a/logging/LoggingLevelManipulation.java b/logging/LoggingLevelManipulation.java deleted file mode 100644 index e88c51625..000000000 --- a/logging/LoggingLevelManipulation.java +++ /dev/null @@ -1,185 +0,0 @@ -// logging/LoggingLevelManipulation.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {ErrorOutputExpected} -import java.util.logging.Level; -import java.util.logging.Logger; - -public class LoggingLevelManipulation { - private static Logger - lgr = Logger.getLogger("com"), - lgr2 = Logger.getLogger("com.mindviewinc"), - util= Logger.getLogger("onjava"), - test= Logger.getLogger("com.mindviewinc.test"), - rand = Logger.getLogger("random"); - static void printLogMessages(Logger logger) { - logger.finest(logger.getName() + " Finest"); - logger.finer(logger.getName() + " Finer"); - logger.fine(logger.getName() + " Fine"); - logger.config(logger.getName() + " Config"); - logger.info(logger.getName() + " Info"); - logger.warning(logger.getName()+" Warning"); - logger.severe(logger.getName() + " Severe"); - } - static void logMessages() { - printLogMessages(lgr); - printLogMessages(lgr2); - printLogMessages(util); - printLogMessages(test); - printLogMessages(rand); - } - static void printLevels() { - System.out.println(" -- printing levels -- " - + lgr.getName() - + " : " + lgr.getLevel() - + " " + lgr2.getName() - + " : " + lgr2.getLevel() - + " " + util.getName() - + " : " + util.getLevel() - + " " + test.getName() - + " : " + test.getLevel() - + " " + rand.getName() - + " : " + rand.getLevel()); - } - public static void main(String[] args) { - printLevels(); - lgr.setLevel(Level.SEVERE); - printLevels(); - System.out.println("net level: SEVERE"); - logMessages(); - util.setLevel(Level.FINEST); - test.setLevel(Level.FINEST); - rand.setLevel(Level.FINEST); - printLevels(); - System.out.println( - "individual loggers set to FINEST"); - logMessages(); - lgr.setLevel(Level.FINEST); - printLevels(); - System.out.println("net level: FINEST"); - logMessages(); - } -} -/* Output: --- printing levels -- com : null com.mindviewinc : null -onjava : null com.mindviewinc.test : null random : null - -- printing levels -- com : SEVERE com.mindviewinc : null -onjava : null com.mindviewinc.test : null random : null -net level: SEVERE - -- printing levels -- com : SEVERE com.mindviewinc : null -onjava : FINEST com.mindviewinc.test : FINEST random : -FINEST -individual loggers set to FINEST - -- printing levels -- com : FINEST com.mindviewinc : null -onjava : FINEST com.mindviewinc.test : FINEST random : -FINEST -net level: FINEST -___[ Error Output ]___ -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -SEVERE: com Severe -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -SEVERE: com.mindviewinc Severe -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -INFO: onjava Info -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -WARNING: onjava Warning -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -SEVERE: onjava Severe -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -SEVERE: com.mindviewinc.test Severe -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -INFO: random Info -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -WARNING: random Warning -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -SEVERE: random Severe -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -SEVERE: com Severe -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -SEVERE: com.mindviewinc Severe -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -INFO: onjava Info -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -WARNING: onjava Warning -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -SEVERE: onjava Severe -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -INFO: com.mindviewinc.test Info -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -WARNING: com.mindviewinc.test Warning -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -SEVERE: com.mindviewinc.test Severe -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -INFO: random Info -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -WARNING: random Warning -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -SEVERE: random Severe -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -INFO: com Info -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -WARNING: com Warning -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -SEVERE: com Severe -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -INFO: com.mindviewinc Info -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -WARNING: com.mindviewinc Warning -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -SEVERE: com.mindviewinc Severe -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -INFO: onjava Info -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -WARNING: onjava Warning -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -SEVERE: onjava Severe -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -INFO: com.mindviewinc.test Info -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -WARNING: com.mindviewinc.test Warning -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -SEVERE: com.mindviewinc.test Severe -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -INFO: random Info -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -WARNING: random Warning -Dec 15, 2015 9:58:43 PM LoggingLevelManipulation -printLogMessages -SEVERE: random Severe -___[ Error Output is Expected ]___ -*/ diff --git a/logging/LoggingLevels.java b/logging/LoggingLevels.java deleted file mode 100644 index baa8e7031..000000000 --- a/logging/LoggingLevels.java +++ /dev/null @@ -1,62 +0,0 @@ -// logging/LoggingLevels.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {ErrorOutputExpected} -import java.util.logging.Level; -import java.util.logging.Logger; - -public class LoggingLevels { - private static Logger - lgr = Logger.getLogger("com"), - lgr2 = Logger.getLogger("com.mindviewinc"), - util= Logger.getLogger("onjava"), - test= Logger.getLogger("com.mindviewinc.test"), - rand = Logger.getLogger("random"); - private static void logMessages() { - lgr.info("com : info"); - lgr2.info("com.mindviewinc : info"); - util.info("util : info"); - test.severe("test : severe"); - rand.info("random : info"); - } - public static void main(String[] args) { - lgr.setLevel(Level.SEVERE); - System.out.println("com level: SEVERE"); - logMessages(); - util.setLevel(Level.FINEST); - test.setLevel(Level.FINEST); - rand.setLevel(Level.FINEST); - System.out.println( - "individual loggers set to FINEST"); - logMessages(); - lgr.setLevel(Level.SEVERE); - System.out.println("com level: SEVERE"); - logMessages(); - } -} -/* Output: -com level: SEVERE -individual loggers set to FINEST -com level: SEVERE -___[ Error Output ]___ -Dec 15, 2015 9:58:43 PM LoggingLevels logMessages -INFO: util : info -Dec 15, 2015 9:58:43 PM LoggingLevels logMessages -SEVERE: test : severe -Dec 15, 2015 9:58:43 PM LoggingLevels logMessages -INFO: random : info -Dec 15, 2015 9:58:43 PM LoggingLevels logMessages -INFO: util : info -Dec 15, 2015 9:58:43 PM LoggingLevels logMessages -SEVERE: test : severe -Dec 15, 2015 9:58:43 PM LoggingLevels logMessages -INFO: random : info -Dec 15, 2015 9:58:43 PM LoggingLevels logMessages -INFO: util : info -Dec 15, 2015 9:58:43 PM LoggingLevels logMessages -SEVERE: test : severe -Dec 15, 2015 9:58:43 PM LoggingLevels logMessages -INFO: random : info -___[ Error Output is Expected ]___ -*/ diff --git a/logging/MultipleHandlers.java b/logging/MultipleHandlers.java deleted file mode 100644 index e8eaa51ed..000000000 --- a/logging/MultipleHandlers.java +++ /dev/null @@ -1,28 +0,0 @@ -// logging/MultipleHandlers.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {ErrorOutputExpected} -import java.util.logging.*; - -public class MultipleHandlers { - private static Logger logger = - Logger.getLogger("MultipleHandlers"); - public static void - main(String[] args) throws Exception { - FileHandler logFile = - new FileHandler("MultipleHandlers.xml"); - logger.addHandler(logFile); - logger.addHandler(new ConsoleHandler()); - logger.warning( - "Output to multiple handlers"); - } -} -/* Output: -___[ Error Output ]___ -Dec 15, 2015 9:58:43 PM MultipleHandlers main -WARNING: Output to multiple handlers -Dec 15, 2015 9:58:43 PM MultipleHandlers main -WARNING: Output to multiple handlers -___[ Error Output is Expected ]___ -*/ diff --git a/logging/MultipleHandlers2.java b/logging/MultipleHandlers2.java deleted file mode 100644 index ec3d0678f..000000000 --- a/logging/MultipleHandlers2.java +++ /dev/null @@ -1,27 +0,0 @@ -// logging/MultipleHandlers2.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {ErrorOutputExpected} -import java.util.logging.*; - -public class MultipleHandlers2 { - private static Logger logger = - Logger.getLogger("MultipleHandlers2"); - public static void - main(String[] args) throws Exception { - FileHandler logFile = - new FileHandler("MultipleHandlers2.xml"); - logger.addHandler(logFile); - logger.addHandler(new ConsoleHandler()); - logger.setUseParentHandlers(false); - logger.warning( - "Output to multiple handlers"); - } -} -/* Output: -___[ Error Output ]___ -Dec 15, 2015 9:58:43 PM MultipleHandlers2 main -WARNING: Output to multiple handlers -___[ Error Output is Expected ]___ -*/ diff --git a/logging/PrintableLogRecord.java b/logging/PrintableLogRecord.java deleted file mode 100644 index fb4d31d73..000000000 --- a/logging/PrintableLogRecord.java +++ /dev/null @@ -1,60 +0,0 @@ -// logging/PrintableLogRecord.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Override LogRecord toString() -import java.util.logging.*; - -public class PrintableLogRecord extends LogRecord { - public PrintableLogRecord(Level level, String str) { - super(level, str); - } - @Override - public String toString() { - String result = "Level<" + getLevel()+ ">\n" - + "LoggerName<" + getLoggerName() + ">\n" - + "Message<" + getMessage() + ">\n" - + "CurrentMillis<" + getMillis() + ">\n" - + "Params"; - Object[] objParams = getParameters(); - if(objParams == null) - result += "\n"; - else - for(int i = 0; i < objParams.length; i++) - result += " Param # <" + i + " value "+ - objParams[i].toString() + ">\n"; - result += "ResourceBundle<" - + getResourceBundle() - + ">\nResourceBundleName<" - + getResourceBundleName() - + ">\nSequenceNumber<" - + getSequenceNumber() - + ">\nSourceClassName<" - + getSourceClassName() - + ">\nSourceMethodName<" - + getSourceMethodName() - + ">\nThread Id<" + getThreadID() - + ">\nThrown<" + getThrown() + ">"; - return result; - } - public static void main(String[] args) { - PrintableLogRecord logRecord = - new PrintableLogRecord( - Level.FINEST, "Simple Log Record"); - System.out.println(logRecord); - } -} -/* Output: -Level -LoggerName -Message -CurrentMillis<1434408472765> -Params -ResourceBundle -ResourceBundleName -SequenceNumber<0> -SourceClassName -SourceMethodName -Thread Id<1> -Thrown -*/ diff --git a/logging/SimpleFilter.java b/logging/SimpleFilter.java deleted file mode 100644 index cf52ae4d5..000000000 --- a/logging/SimpleFilter.java +++ /dev/null @@ -1,46 +0,0 @@ -// logging/SimpleFilter.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {ErrorOutputExpected} -import java.util.logging.*; - -public class SimpleFilter { - private static Logger logger = - Logger.getLogger("SimpleFilter"); - static class Duck {}; - static class Wombat {}; - static void sendLogMessages() { - logger.log(Level.WARNING, - "A duck in the house!", new Duck()); - logger.log(Level.WARNING, - "A Wombat at large!", new Wombat()); - } - public static void main(String[] args) { - sendLogMessages(); - logger.setFilter(record -> { - Object[] params = - record.getParameters(); - if(params == null) - return true; // No parameters - if(record.getParameters()[0] - instanceof Duck) - return true; // Only log Ducks - return false; - }); - logger.info("After setting filter.."); - sendLogMessages(); - } -} -/* Output: -___[ Error Output ]___ -Dec 15, 2015 9:58:44 PM SimpleFilter sendLogMessages -WARNING: A duck in the house! -Dec 15, 2015 9:58:44 PM SimpleFilter sendLogMessages -WARNING: A Wombat at large! -Dec 15, 2015 9:58:44 PM SimpleFilter main -INFO: After setting filter.. -Dec 15, 2015 9:58:44 PM SimpleFilter sendLogMessages -WARNING: A duck in the house! -___[ Error Output is Expected ]___ -*/ diff --git a/logging/SimpleFormatterExample.java b/logging/SimpleFormatterExample.java deleted file mode 100644 index 1cab2fda0..000000000 --- a/logging/SimpleFormatterExample.java +++ /dev/null @@ -1,39 +0,0 @@ -// logging/SimpleFormatterExample.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {ErrorOutputExpected} -import java.util.logging.*; - -public class SimpleFormatterExample { - private static Logger logger = - Logger.getLogger("SimpleFormatterExample"); - private static void logMessages() { - logger.info("Line One"); - logger.info("Line Two"); - } - public static void main(String[] args) { - logger.setUseParentHandlers(false); - Handler conHdlr = new ConsoleHandler(); - conHdlr.setFormatter(new Formatter() { - public String format(LogRecord record) { - return record.getLevel() + " : " - + record.getSourceClassName() - + " -:- " - + record.getSourceMethodName() - + " -:- " - + record.getMessage() + "\n"; - } - }); - logger.addHandler(conHdlr); - logMessages(); - } -} -/* Output: -___[ Error Output ]___ -INFO : SimpleFormatterExample -:- logMessages -:- Line -One -INFO : SimpleFormatterExample -:- logMessages -:- Line -Two -___[ Error Output is Expected ]___ -*/ diff --git a/logging/build.xml b/logging/build.xml deleted file mode 100644 index da20fbfe2..000000000 --- a/logging/build.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/logging/log.prop b/logging/log.prop deleted file mode 100644 index 59f2f7ff5..000000000 --- a/logging/log.prop +++ /dev/null @@ -1,32 +0,0 @@ -// logging/log.prop -#### Configuration File #### -# Global Params -# Handlers installed for the root logger -handlers= java.util.logging.ConsoleHandler java.util.logging.FileHandler -# Level for root logger--is used by any logger -# that does not have its level set -.level= FINEST -# Initialization class--the public no-arg constructor -# of this class is called by the Logging framework -config = ConfigureLogging - -# Configure FileHandler -# Logging file name - %u specifies unique -java.util.logging.FileHandler.pattern = java%g.log -# Write 100000 bytes before rotating this file -java.util.logging.FileHandler.limit = 100000 -# Number of rotating files -java.util.logging.FileHandler.count = 3 -# Formatter for this FileHandler -java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter - -# Configure ConsoleHandler -java.util.logging.ConsoleHandler.level = FINEST -java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter - -# Set Logger Levels # -net.level=SEVERE -com.mindviewinc.level = FINEST -onjava.level = INFO -com.mindviewinc.test.level = FINER -random.level= SEVERE diff --git a/lowlevel/AtomicEvenProducer.java b/lowlevel/AtomicEvenProducer.java new file mode 100644 index 000000000..d45592c93 --- /dev/null +++ b/lowlevel/AtomicEvenProducer.java @@ -0,0 +1,20 @@ +// lowlevel/AtomicEvenProducer.java +// (c)2021 MindView 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/lowlevel/AtomicIntegerTest.java b/lowlevel/AtomicIntegerTest.java new file mode 100644 index 000000000..a93134a8e --- /dev/null +++ b/lowlevel/AtomicIntegerTest.java @@ -0,0 +1,21 @@ +// lowlevel/AtomicIntegerTest.java +// (c)2021 MindView LLC: see Copyright.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(); } + @Override + public void evenIncrement() { i.addAndGet(2); } + public static void main(String[] args) { + Atomicity.test(new AtomicIntegerTest()); + } +} +/* Output: +No failures found +*/ diff --git a/lowlevel/AtomicSerialNumbers.java b/lowlevel/AtomicSerialNumbers.java new file mode 100644 index 000000000..ef1cdff51 --- /dev/null +++ b/lowlevel/AtomicSerialNumbers.java @@ -0,0 +1,21 @@ +// lowlevel/AtomicSerialNumbers.java +// (c)2021 MindView LLC: see Copyright.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(); + @Override public int nextSerialNumber() { + return serialNumber.getAndIncrement(); + } + public static void main(String[] args) { + SerialNumberChecker.test( + new AtomicSerialNumbers()); + } +} +/* Output: +No duplicates detected +*/ diff --git a/lowlevel/Atomicity.java b/lowlevel/Atomicity.java new file mode 100644 index 000000000..f8f01d641 --- /dev/null +++ b/lowlevel/Atomicity.java @@ -0,0 +1,20 @@ +// lowlevel/Atomicity.java +// (c)2021 MindView LLC: see Copyright.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/tasks/AttemptLocking.java b/lowlevel/AttemptLocking.java similarity index 75% rename from tasks/AttemptLocking.java rename to lowlevel/AttemptLocking.java index 8c0bbb589..8632fd58b 100644 --- a/tasks/AttemptLocking.java +++ b/lowlevel/AttemptLocking.java @@ -1,11 +1,12 @@ -// tasks/AttemptLocking.java -// (c)2016 MindView LLC: see Copyright.txt +// lowlevel/AttemptLocking.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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(); @@ -37,16 +38,12 @@ 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 separate task to grab the lock: - new Thread() { - { setDaemon(true); } - @Override - public void run() { + // Now create a second task to grab the lock: + CompletableFuture.runAsync( () -> { al.lock.lock(); System.out.println("acquired"); - } - }.start(); - Thread.yield(); // Give the 2nd task a chance + }); + new Nap(0.1); // Give the second task a chance al.untimed(); // False -- lock grabbed by task al.timed(); // False -- lock grabbed by task } @@ -54,7 +51,7 @@ public void run() { /* Output: tryLock(): true tryLock(2, TimeUnit.SECONDS): true -tryLock(): true -tryLock(2, TimeUnit.SECONDS): true acquired +tryLock(): false +tryLock(2, TimeUnit.SECONDS): false */ diff --git a/tasks/CaptureUncaughtException.java b/lowlevel/CaptureUncaughtException.java similarity index 60% rename from tasks/CaptureUncaughtException.java rename to lowlevel/CaptureUncaughtException.java index 45fb52ce7..90458aee5 100644 --- a/tasks/CaptureUncaughtException.java +++ b/lowlevel/CaptureUncaughtException.java @@ -1,15 +1,13 @@ -// tasks/CaptureUncaughtException.java -// (c)2016 MindView LLC: see Copyright.txt +// lowlevel/CaptureUncaughtException.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {TimeOutDuringTesting} +// Visit http://OnJava8.com for more book information. import java.util.concurrent.*; class ExceptionThread2 implements Runnable { - @Override - public void run() { + @Override public void run() { Thread t = Thread.currentThread(); - System.out.println("run() by " + t); + System.out.println("run() by " + t.getName()); System.out.println( "eh = " + t.getUncaughtExceptionHandler()); throw new RuntimeException(); @@ -25,8 +23,7 @@ public void uncaughtException(Thread t, Throwable e) { } class HandlerThreadFactory implements ThreadFactory { - @Override - public Thread newThread(Runnable r) { + @Override public Thread newThread(Runnable r) { System.out.println(this + " creating new Thread"); Thread t = new Thread(r); System.out.println("created " + t); @@ -40,19 +37,18 @@ public Thread newThread(Runnable r) { public class CaptureUncaughtException { public static void main(String[] args) { - ExecutorService exec = Executors.newCachedThreadPool( - new HandlerThreadFactory()); + ExecutorService exec = + Executors.newCachedThreadPool( + new HandlerThreadFactory()); exec.execute(new ExceptionThread2()); + exec.shutdown(); } } /* Output: -HandlerThreadFactory@10dea4e creating new Thread +HandlerThreadFactory@106d69c creating new Thread created Thread[Thread-0,5,main] -eh = MyUncaughtExceptionHandler@647e05 -run() by Thread[Thread-0,5,main] -eh = MyUncaughtExceptionHandler@647e05 -HandlerThreadFactory@10dea4e creating new Thread -created Thread[Thread-1,5,main] -eh = MyUncaughtExceptionHandler@c34ec2 +eh = MyUncaughtExceptionHandler@52e922 +run() by Thread-0 +eh = MyUncaughtExceptionHandler@52e922 caught java.lang.RuntimeException */ diff --git a/lowlevel/CircularSet.java b/lowlevel/CircularSet.java new file mode 100644 index 000000000..f0ab28334 --- /dev/null +++ b/lowlevel/CircularSet.java @@ -0,0 +1,29 @@ +// lowlevel/CircularSet.java +// (c)2021 MindView 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/lowlevel/DelayQueueDemo.java b/lowlevel/DelayQueueDemo.java new file mode 100644 index 000000000..bce53a85f --- /dev/null +++ b/lowlevel/DelayQueueDemo.java @@ -0,0 +1,94 @@ +// lowlevel/DelayQueueDemo.java +// (c)2021 MindView LLC: see Copyright.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 [555] Task 2 [551] Task 13 +[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/lowlevel/EvenChecker.java b/lowlevel/EvenChecker.java new file mode 100644 index 000000000..4ba64637e --- /dev/null +++ b/lowlevel/EvenChecker.java @@ -0,0 +1,40 @@ +// lowlevel/EvenChecker.java +// (c)2021 MindView LLC: see Copyright.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/lowlevel/EvenProducer.java b/lowlevel/EvenProducer.java new file mode 100644 index 000000000..67774aa24 --- /dev/null +++ b/lowlevel/EvenProducer.java @@ -0,0 +1,25 @@ +// lowlevel/EvenProducer.java +// (c)2021 MindView 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/lowlevel/ExceptionThread.java b/lowlevel/ExceptionThread.java new file mode 100644 index 000000000..9fee108c9 --- /dev/null +++ b/lowlevel/ExceptionThread.java @@ -0,0 +1,29 @@ +// lowlevel/ExceptionThread.java +// (c)2021 MindView 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:7) + 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/lowlevel/IntGenerator.java b/lowlevel/IntGenerator.java new file mode 100644 index 000000000..a5078a955 --- /dev/null +++ b/lowlevel/IntGenerator.java @@ -0,0 +1,15 @@ +// lowlevel/IntGenerator.java +// (c)2021 MindView LLC: see Copyright.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/lowlevel/IntTestable.java b/lowlevel/IntTestable.java new file mode 100644 index 000000000..bd2f2abde --- /dev/null +++ b/lowlevel/IntTestable.java @@ -0,0 +1,14 @@ +// lowlevel/IntTestable.java +// (c)2021 MindView LLC: see Copyright.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/tasks/MutexEvenSupplier.java b/lowlevel/MutexEvenProducer.java similarity index 52% rename from tasks/MutexEvenSupplier.java rename to lowlevel/MutexEvenProducer.java index 6511e53dc..24ce0448a 100644 --- a/tasks/MutexEvenSupplier.java +++ b/lowlevel/MutexEvenProducer.java @@ -1,21 +1,19 @@ -// tasks/MutexEvenSupplier.java -// (c)2016 MindView LLC: see Copyright.txt +// lowlevel/MutexEvenProducer.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Preventing thread collisions with mutexes -// {TimeOutDuringTesting} -// {IgnoreOutput} // No output validation import java.util.concurrent.locks.*; +import onjava.Nap; -public class MutexEvenSupplier extends IntSupplier { +public class MutexEvenProducer extends IntGenerator { private int currentEvenValue = 0; private Lock lock = new ReentrantLock(); - @Override - public int next() { + @Override public int next() { lock.lock(); try { ++currentEvenValue; - Thread.yield(); // Cause failure faster + new Nap(0.01); // Cause failure faster ++currentEvenValue; return currentEvenValue; } finally { @@ -23,6 +21,9 @@ public int next() { } } public static void main(String[] args) { - EvenChecker.test(new MutexEvenSupplier()); + EvenChecker.test(new MutexEvenProducer()); } } +/* +No odd numbers discovered +*/ diff --git a/lowlevel/NaiveExceptionHandling.java b/lowlevel/NaiveExceptionHandling.java new file mode 100644 index 000000000..efda2778e --- /dev/null +++ b/lowlevel/NaiveExceptionHandling.java @@ -0,0 +1,32 @@ +// lowlevel/NaiveExceptionHandling.java +// (c)2021 MindView 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:7) + 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/lowlevel/NotAtomic.java b/lowlevel/NotAtomic.java new file mode 100644 index 000000000..00a1b0102 --- /dev/null +++ b/lowlevel/NotAtomic.java @@ -0,0 +1,49 @@ +// lowlevel/NotAtomic.java +// (c)2021 MindView 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/lowlevel/NumberOfProcessors.java b/lowlevel/NumberOfProcessors.java new file mode 100644 index 000000000..3c3abf81f --- /dev/null +++ b/lowlevel/NumberOfProcessors.java @@ -0,0 +1,14 @@ +// lowlevel/NumberOfProcessors.java +// (c)2021 MindView 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/lowlevel/PriorityBlockingQueueDemo.java b/lowlevel/PriorityBlockingQueueDemo.java new file mode 100644 index 000000000..4683ed841 --- /dev/null +++ b/lowlevel/PriorityBlockingQueueDemo.java @@ -0,0 +1,135 @@ +// lowlevel/PriorityBlockingQueueDemo.java +// (c)2021 MindView LLC: see Copyright.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 1 +[17] Prioritized 0 +[17] Prioritized 5 +[16] Prioritized 6 +[14] Prioritized 9 +[12] Prioritized 2 +[11] Prioritized 4 +[11] Prioritized 12 +[13] Prioritized 13 +[12] Prioritized 16 +[14] Prioritized 17 +[15] Prioritized 23 +[18] Prioritized 26 +[16] Prioritized 29 +[12] Prioritized 18 +[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:17)(1:15)(2:12)(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:14)(18:12)(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/lowlevel/ReOrdering.java b/lowlevel/ReOrdering.java new file mode 100644 index 000000000..77f07469e --- /dev/null +++ b/lowlevel/ReOrdering.java @@ -0,0 +1,18 @@ +// lowlevel/ReOrdering.java +// (c)2021 MindView 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/lowlevel/SafeReturn.java b/lowlevel/SafeReturn.java new file mode 100644 index 000000000..70d21454e --- /dev/null +++ b/lowlevel/SafeReturn.java @@ -0,0 +1,21 @@ +// lowlevel/SafeReturn.java +// (c)2021 MindView LLC: see Copyright.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; } + @Override + public synchronized void evenIncrement() { + i++; i++; + } + public static void main(String[] args) { + Atomicity.test(new SafeReturn()); + } +} +/* Output: +No failures found +*/ diff --git a/lowlevel/SerialNumberChecker.java b/lowlevel/SerialNumberChecker.java new file mode 100644 index 000000000..d539411ee --- /dev/null +++ b/lowlevel/SerialNumberChecker.java @@ -0,0 +1,31 @@ +// lowlevel/SerialNumberChecker.java +// (c)2021 MindView 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/lowlevel/SerialNumberTest.java b/lowlevel/SerialNumberTest.java new file mode 100644 index 000000000..9c740d259 --- /dev/null +++ b/lowlevel/SerialNumberTest.java @@ -0,0 +1,16 @@ +// lowlevel/SerialNumberTest.java +// (c)2021 MindView 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: 33280 +Duplicate: 33278 +Duplicate: 33290 +Duplicate: 33277 +*/ diff --git a/lowlevel/SerialNumbers.java b/lowlevel/SerialNumbers.java new file mode 100644 index 000000000..aaaf74bda --- /dev/null +++ b/lowlevel/SerialNumbers.java @@ -0,0 +1,11 @@ +// lowlevel/SerialNumbers.java +// (c)2021 MindView 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/tasks/SettingDefaultHandler.java b/lowlevel/SettingDefaultHandler.java similarity index 60% rename from tasks/SettingDefaultHandler.java rename to lowlevel/SettingDefaultHandler.java index 8215d2698..7fe2d5c8a 100644 --- a/tasks/SettingDefaultHandler.java +++ b/lowlevel/SettingDefaultHandler.java @@ -1,16 +1,17 @@ -// tasks/SettingDefaultHandler.java -// (c)2016 MindView LLC: see Copyright.txt +// lowlevel/SettingDefaultHandler.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {TimeOutDuringTesting} +// 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(); + ExecutorService es = + Executors.newCachedThreadPool(); es.execute(new ExceptionThread()); + es.shutdown(); } } /* Output: diff --git a/lowlevel/SwallowedException.java b/lowlevel/SwallowedException.java new file mode 100644 index 000000000..7f70f0cb4 --- /dev/null +++ b/lowlevel/SwallowedException.java @@ -0,0 +1,17 @@ +// lowlevel/SwallowedException.java +// (c)2021 MindView LLC: see Copyright.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/lowlevel/SyncOnObject.java b/lowlevel/SyncOnObject.java new file mode 100644 index 000000000..d81ad9f4b --- /dev/null +++ b/lowlevel/SyncOnObject.java @@ -0,0 +1,70 @@ +// lowlevel/SyncOnObject.java +// (c)2021 MindView 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/lowlevel/SynchronizedComparison.java b/lowlevel/SynchronizedComparison.java new file mode 100644 index 000000000..274f1f0b3 --- /dev/null +++ b/lowlevel/SynchronizedComparison.java @@ -0,0 +1,87 @@ +// lowlevel/SynchronizedComparison.java +// (c)2021 MindView 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 { + @Override public synchronized void method() { + new Nap(0.01); + callCount.incrementAndGet(); + } +} + +class CriticalSection extends Guarded { + @Override 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: +-> 159 +-> 159 +-> 159 +-> 159 +CriticalSection: 636 +-> 65 +-> 21 +-> 11 +-> 68 +SynchronizedMethod: 165 +*/ diff --git a/lowlevel/SynchronizedEvenProducer.java b/lowlevel/SynchronizedEvenProducer.java new file mode 100644 index 000000000..7fb9b06f3 --- /dev/null +++ b/lowlevel/SynchronizedEvenProducer.java @@ -0,0 +1,23 @@ +// lowlevel/SynchronizedEvenProducer.java +// (c)2021 MindView 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/lowlevel/SynchronizedSerialNumbers.java b/lowlevel/SynchronizedSerialNumbers.java new file mode 100644 index 000000000..c73cd48ee --- /dev/null +++ b/lowlevel/SynchronizedSerialNumbers.java @@ -0,0 +1,20 @@ +// lowlevel/SynchronizedSerialNumbers.java +// (c)2021 MindView 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; + @Override + public synchronized int nextSerialNumber() { + return serialNumber++; + } + public static void main(String[] args) { + SerialNumberChecker.test( + new SynchronizedSerialNumbers()); + } +} +/* Output: +No duplicates detected +*/ diff --git a/lowlevel/TestAbort.java b/lowlevel/TestAbort.java new file mode 100644 index 000000000..ae2477e1d --- /dev/null +++ b/lowlevel/TestAbort.java @@ -0,0 +1,17 @@ +// lowlevel/TestAbort.java +// (c)2021 MindView LLC: 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/lowlevel/ThreadSize.java b/lowlevel/ThreadSize.java new file mode 100644 index 000000000..ff6f91fb5 --- /dev/null +++ b/lowlevel/ThreadSize.java @@ -0,0 +1,30 @@ +// lowlevel/ThreadSize.java +// (c)2021 MindView 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/lowlevel/UnsafeReturn.java b/lowlevel/UnsafeReturn.java new file mode 100644 index 000000000..964cc3af4 --- /dev/null +++ b/lowlevel/UnsafeReturn.java @@ -0,0 +1,21 @@ +// lowlevel/UnsafeReturn.java +// (c)2021 MindView LLC: see Copyright.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; } + @Override + public synchronized void evenIncrement() { + i++; i++; + } + public static void main(String[] args) { + Atomicity.test(new UnsafeReturn()); + } +} +/* Output: +failed with: 39 +*/ diff --git a/lowlevel/WorkStealingPool.java b/lowlevel/WorkStealingPool.java new file mode 100644 index 000000000..9848b019d --- /dev/null +++ b/lowlevel/WorkStealingPool.java @@ -0,0 +1,40 @@ +// lowlevel/WorkStealingPool.java +// (c)2021 MindView LLC: see Copyright.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-1 +ForkJoinPool-1-worker-2 +ForkJoinPool-1-worker-1 +ForkJoinPool-1-worker-3 +ForkJoinPool-1-worker-4 +ForkJoinPool-1-worker-4 +ForkJoinPool-1-worker-2 +ForkJoinPool-1-worker-3 +ForkJoinPool-1-worker-5 +ForkJoinPool-1-worker-1 +*/ diff --git a/network/ChatterClient.java b/network/ChatterClient.java deleted file mode 100644 index 13ec4c4d3..000000000 --- a/network/ChatterClient.java +++ /dev/null @@ -1,66 +0,0 @@ -// network/ChatterClient.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {ValidateByHand} -// Tests the ChatterServer by starting multiple -// clients, each of which sends datagrams -import java.net.*; -import java.io.*; -import onjava.*; - -public class ChatterClient extends Thread { - // Can listen & send on the same socket: - private DatagramSocket s; - private InetAddress hostAddress; - private byte[] buf = new byte[1000]; - private DatagramPacket dp = - new DatagramPacket(buf, buf.length); - private int id; - - public ChatterClient(int identifier) { - id = identifier; - try { - // Auto-assign port number: - s = new DatagramSocket(); - hostAddress = - InetAddress.getByName("localhost"); - } catch(UnknownHostException e) { - System.err.println("Cannot find host"); - System.exit(1); - } catch(SocketException e) { - System.err.println("Can't open socket"); - throw new RuntimeException(e); - } - System.out.println("ChatterClient starting"); - } - public void sendAndEcho(String msg) { - try { - // Make and send a datagram: - s.send(Dgram.toDatagram(msg, - hostAddress, - ChatterServer.INPORT)); - // Block until it echoes back: - s.receive(dp); - // Print out the echoed contents: - String rcvd = "Client #" + id + - ", rcvd from " + - dp.getAddress() + ", " + - dp.getPort() + ": " + - Dgram.toString(dp); - System.out.println(rcvd); - } catch(IOException e) { - throw new RuntimeException(e); - } - } - @Override - public void run() { - for(int i = 0; i <= 25; i++) - sendAndEcho("Client #" + id + ", message #" + i); - } - public static void main(String[] args) { - new TimedAbort(5); // Terminate after 5 seconds - for(int i = 0; i <= 10; i++) - new ChatterClient(i).start(); - } -} diff --git a/network/ChatterServer.bat b/network/ChatterServer.bat deleted file mode 100644 index ef7fe4860..000000000 --- a/network/ChatterServer.bat +++ /dev/null @@ -1,3 +0,0 @@ -start java ChatterServer -timeout /t 1 -java ChatterClient diff --git a/network/ChatterServer.java b/network/ChatterServer.java deleted file mode 100644 index c1e47ff65..000000000 --- a/network/ChatterServer.java +++ /dev/null @@ -1,52 +0,0 @@ -// network/ChatterServer.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {ValidateByHand} -// A server that echoes datagrams -import java.net.*; -import java.io.*; -import onjava.*; - -public class ChatterServer { - static final int INPORT = 1711; - private byte[] buf = new byte[1000]; - private DatagramPacket dp = - new DatagramPacket(buf, buf.length); - // Can listen & send on the same socket: - private DatagramSocket socket; - - public ChatterServer() { - try { - socket = new DatagramSocket(INPORT); - System.out.println("Server started"); - while(true) { - // Block until a datagram appears: - socket.receive(dp); - String rcvd = Dgram.toString(dp) + - ", from address: " + dp.getAddress() + - ", port: " + dp.getPort(); - System.out.println(rcvd); - String echoString = - "Echoed: " + rcvd; - // Extract the address and port from the - // received datagram to find out where to - // send it back: - DatagramPacket echo = - Dgram.toDatagram(echoString, - dp.getAddress(), dp.getPort()); - socket.send(echo); - } - } catch(SocketException e) { - System.err.println("Can't open socket"); - System.exit(1); - } catch(IOException e) { - System.out.println("Communication error"); - throw new RuntimeException(e); - } - } - public static void main(String[] args) { - new TimedAbort(5); // Terminate after 5 seconds - new ChatterServer(); - } -} diff --git a/network/ChatterServer.sh b/network/ChatterServer.sh deleted file mode 100644 index 5c867beab..000000000 --- a/network/ChatterServer.sh +++ /dev/null @@ -1,3 +0,0 @@ -java -cp ..:. ChatterServer & -sleep 1 -java -cp ..:. ChatterClient diff --git a/network/Dgram.java b/network/Dgram.java deleted file mode 100644 index f4d96ae82..000000000 --- a/network/Dgram.java +++ /dev/null @@ -1,20 +0,0 @@ -// network/Dgram.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Converts back and forth -// between Strings and DataGramPackets -import java.net.*; - -public class Dgram { - public static DatagramPacket toDatagram( - String s, InetAddress destIA, int destPort) { - byte[] buf = s.getBytes(); - return new DatagramPacket(buf, buf.length, - destIA, destPort); - } - public static String toString(DatagramPacket p) { - return - new String(p.getData(), 0, p.getLength()); - } -} diff --git a/network/LocalHost.java b/network/LocalHost.java deleted file mode 100644 index f191c1148..000000000 --- a/network/LocalHost.java +++ /dev/null @@ -1,27 +0,0 @@ -// network/LocalHost.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// The local loopback IP address -import java.net.*; - -public class LocalHost { - public static void - main(String[] args) throws Exception { - InetAddress - local1 = InetAddress.getByName(null), - local2 = InetAddress.getByName("localhost"), - local3 = InetAddress.getByName("127.0.0.1"), - local4 = InetAddress.getLoopbackAddress(); - System.out.println(local1); - System.out.println(local2); - System.out.println(local3); - System.out.println(local4); - } -} -/* Output: -localhost/127.0.0.1 -localhost/127.0.0.1 -/127.0.0.1 -localhost/127.0.0.1 -*/ diff --git a/network/MultiSimpleClient.java b/network/MultiSimpleClient.java deleted file mode 100644 index 18a41e5e4..000000000 --- a/network/MultiSimpleClient.java +++ /dev/null @@ -1,89 +0,0 @@ -// network/MultiSimpleClient.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Testing MultiSimpleServer with multiple clients -// {ValidateByHand} -import java.net.*; -import java.io.*; -import onjava.*; - -class SimpleClientThread extends Thread { - private Socket socket; - private BufferedReader in; - private PrintWriter out; - private static int counter = 0; - private int id = counter++; - private static int threadcount = 0; - public static int threadCount() { - return threadcount; - } - public SimpleClientThread(InetAddress addr) { - System.out.println("Making client " + id); - threadcount++; - try { - socket = - new Socket(addr, MultiSimpleServer.PORT); - } catch(IOException e) { - // If the creation of the socket fails, - // nothing needs cleanup. - } - try { - in = - new BufferedReader( - new InputStreamReader( - socket.getInputStream())); - // Enable auto-flush: - out = - new PrintWriter( - new BufferedWriter( - new OutputStreamWriter( - socket.getOutputStream())), true); - start(); - } catch(IOException e) { - // The socket should be closed on any - // failures other than the socket - // constructor: - try { - socket.close(); - } catch(IOException e2) {} - } - // Otherwise the socket will be closed by - // the run() method of the thread. - } - @Override - public void run() { - try { - for(int i = 0; i < 25; i++) { - out.println("Client " + id + ": " + i); - String str = in.readLine(); - System.out.println(str); - } - out.println("END"); - } catch(IOException e) { - } finally { - // Always close it: - try { - socket.close(); - } catch(IOException e) {} - threadcount--; // Ending this thread - } - } -} - -public class MultiSimpleClient { - static final int MAX_THREADS = 40; - public static void - main(String[] args) throws IOException, - InterruptedException { - new TimedAbort(5); // Terminate after 5 seconds - InetAddress addr = - InetAddress.getByName(null); - while(true) { - if(SimpleClientThread.threadCount() - < MAX_THREADS) - new SimpleClientThread(addr); - Thread.sleep(100); - } - } -} diff --git a/network/MultiSimpleServer.bat b/network/MultiSimpleServer.bat deleted file mode 100644 index 4d20bd013..000000000 --- a/network/MultiSimpleServer.bat +++ /dev/null @@ -1,3 +0,0 @@ -start java MultiSimpleServer -timeout /t 1 -java MultiSimpleClient diff --git a/network/MultiSimpleServer.java b/network/MultiSimpleServer.java deleted file mode 100644 index 3a6bea587..000000000 --- a/network/MultiSimpleServer.java +++ /dev/null @@ -1,76 +0,0 @@ -// network/MultiSimpleServer.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Uses multithreading to handle any number of clients -// {ValidateByHand} -import java.io.*; -import java.net.*; -import onjava.*; - -class ServeOneSimple extends Thread { - private Socket socket; - private BufferedReader in; - private PrintWriter out; - public ServeOneSimple(Socket s) - throws IOException { - socket = s; - in = - new BufferedReader( - new InputStreamReader( - socket.getInputStream())); - // Enable auto-flush: - out = - new PrintWriter( - new BufferedWriter( - new OutputStreamWriter( - socket.getOutputStream())), true); - // If any of the above calls throw an - // exception, the caller is responsible for - // closing the socket. Otherwise the thread - // will close it. - start(); // Calls run() - } - @Override - public void run() { - try { - while (true) { - String str = in.readLine(); - if(str.equals("END")) break; - System.out.println("Echoing: " + str); - out.println(str); - } - System.out.println("closing..."); - } catch (IOException e) { - } finally { - try { - socket.close(); - } catch(IOException e) {} - } - } -} - -public class MultiSimpleServer { - static final int PORT = 8080; - public static void - main(String[] args) throws IOException { - new TimedAbort(5); // Terminate after 5 seconds - ServerSocket s = new ServerSocket(PORT); - System.out.println("Server Started"); - try { - while(true) { - // Blocks until a connection occurs: - Socket socket = s.accept(); - try { - new ServeOneSimple(socket); - } catch(IOException e) { - // If it fails, close the socket, - // otherwise the thread will close it: - socket.close(); - } - } - } finally { - s.close(); - } - } -} diff --git a/network/MultiSimpleServer.sh b/network/MultiSimpleServer.sh deleted file mode 100644 index deeb4b0ad..000000000 --- a/network/MultiSimpleServer.sh +++ /dev/null @@ -1,3 +0,0 @@ -java -cp ..:. MultiSimpleServer & -sleep 1 -java -cp ..:. MultiSimpleClient diff --git a/network/SimpleClient.java b/network/SimpleClient.java deleted file mode 100644 index ae6abd159..000000000 --- a/network/SimpleClient.java +++ /dev/null @@ -1,48 +0,0 @@ -// network/SimpleClient.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Sends lines to the server and -// reads lines the server sends -// {ValidateByHand} -import java.net.*; -import java.io.*; - -public class SimpleClient { - public static void - main(String[] args) throws IOException { - // Passing null to getByName() produces the - // special "Local Loopback" IP address, for - // testing on one machine w/o a network: - InetAddress addr = - InetAddress.getLoopbackAddress(); - System.out.println("addr = " + addr); - Socket socket = - new Socket(addr, SimpleServer.PORT); - // Guard everything in a try-finally to make - // sure that the socket is closed: - try { - System.out.println("socket = " + socket); - BufferedReader in = - new BufferedReader( - new InputStreamReader( - socket.getInputStream())); - // Output is automatically flushed - // by PrintWriter: - PrintWriter out = - new PrintWriter( - new BufferedWriter( - new OutputStreamWriter( - socket.getOutputStream())),true); - for(int i = 0; i < 10; i ++) { - out.println("howdy " + i); - String str = in.readLine(); - System.out.println(str); - } - out.println("END"); - } finally { - System.out.println("closing..."); - socket.close(); - } - } -} diff --git a/network/SimpleServer.bat b/network/SimpleServer.bat deleted file mode 100644 index 095c330a8..000000000 --- a/network/SimpleServer.bat +++ /dev/null @@ -1,2 +0,0 @@ -start java SimpleServer -java SimpleClient diff --git a/network/SimpleServer.java b/network/SimpleServer.java deleted file mode 100644 index 9295fd495..000000000 --- a/network/SimpleServer.java +++ /dev/null @@ -1,49 +0,0 @@ -// network/SimpleServer.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Just echoes whatever the client sends -// {ValidateByHand} -import java.io.*; -import java.net.*; - -public class SimpleServer { - // Choose a port outside of the range 1-1024: - public static final int PORT = 8080; - public static void - main(String[] args) throws IOException { - ServerSocket s = new ServerSocket(PORT); - System.out.println("Started: " + s); - try { - // Blocks until a connection occurs: - Socket socket = s.accept(); - try { - System.out.println( - "Connection accepted: "+ socket); - BufferedReader in = - new BufferedReader( - new InputStreamReader( - socket.getInputStream())); - // Output is automatically flushed - // by PrintWriter: - PrintWriter out = - new PrintWriter( - new BufferedWriter( - new OutputStreamWriter( - socket.getOutputStream())),true); - while (true) { - String str = in.readLine(); - if(str.equals("END")) break; - System.out.println("Echoing: " + str); - out.println(str); - } - // Always close the two sockets... - } finally { - System.out.println("closing..."); - socket.close(); - } - } finally { - s.close(); - } - } -} diff --git a/network/SimpleServer.sh b/network/SimpleServer.sh deleted file mode 100644 index 2c1335c71..000000000 --- a/network/SimpleServer.sh +++ /dev/null @@ -1,3 +0,0 @@ -java SimpleServer & -sleep 1 -java SimpleClient diff --git a/network/WhoAmI.java b/network/WhoAmI.java deleted file mode 100644 index aab56a1f7..000000000 --- a/network/WhoAmI.java +++ /dev/null @@ -1,20 +0,0 @@ -// network/WhoAmI.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Finds out your machine name and network address -// when you're connected to the Internet -import java.net.*; - -public class WhoAmI { - public static void - main(String[] args) throws Exception { - InetAddress whoami = InetAddress.getLocalHost(); - System.out.println(whoami.getHostName()); - System.out.println(whoami.getHostAddress()); - } -} -/* Output: -groot -192.168.70.108 -*/ diff --git a/network/build.xml b/network/build.xml deleted file mode 100644 index 039355807..000000000 --- a/network/build.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/newio/AvailableCharSets.java b/newio/AvailableCharSets.java index 00f7326e6..bb60164c9 100644 --- a/newio/AvailableCharSets.java +++ b/newio/AvailableCharSets.java @@ -1,7 +1,7 @@ // newio/AvailableCharSets.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Displays Charsets and aliases import java.nio.charset.*; import java.util.*; @@ -32,10 +32,10 @@ public static void main(String[] args) { 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 +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 +GB2312: gb2312, euc-cn, x-EUC-CN, euccn, EUC_CN, +gb2312-80, gb2312-1980 ... */ diff --git a/newio/BufferToText.java b/newio/BufferToText.java index 7de658b81..147c8857b 100644 --- a/newio/BufferToText.java +++ b/newio/BufferToText.java @@ -1,7 +1,7 @@ // newio/BufferToText.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Converting text to and from ByteBuffers import java.nio.*; import java.nio.channels.*; @@ -10,51 +10,76 @@ public class BufferToText { private static final int BSIZE = 1024; - public static void - main(String[] args) throws Exception { - try(FileChannel fc = new FileOutputStream( - "data2.txt").getChannel()) { + 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()) { + 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 + ": " + String encoding = + System.getProperty("file.encoding"); + System.out.println("Decoded using " + + encoding + ": " + Charset.forName(encoding).decode(buff)); - // Or, we could encode with something that prints: - try(FileChannel fc = new FileOutputStream( - "data2.txt").getChannel()) { + // 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()) { + 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); // More than needed + buff = ByteBuffer.allocate(24); buff.asCharBuffer().put("Some text"); - try(FileChannel fc = new FileOutputStream( - "data2.txt").getChannel()) { + 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()) { + 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()); @@ -62,7 +87,7 @@ public class BufferToText { } /* Output: ???? -Decoded using Cp1252: Some text +Decoded using windows-1252: Some text Some text Some textNULNULNUL */ diff --git a/newio/ChannelCopy.java b/newio/ChannelCopy.java index 9af679cc5..039cecd67 100644 --- a/newio/ChannelCopy.java +++ b/newio/ChannelCopy.java @@ -1,32 +1,35 @@ // newio/ChannelCopy.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Copying a file using channels and buffers -// {Args: ChannelCopy.java test.txt} +// {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) throws Exception { + 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()) { + 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/newio/Endians.java b/newio/Endians.java index a0fc87608..183019e36 100644 --- a/newio/Endians.java +++ b/newio/Endians.java @@ -1,7 +1,7 @@ // newio/Endians.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Endian differences and data storage import java.nio.*; import java.util.*; diff --git a/newio/FileLocking.java b/newio/FileLocking.java index 0cfd1cd5e..7bd335244 100644 --- a/newio/FileLocking.java +++ b/newio/FileLocking.java @@ -1,23 +1,26 @@ // newio/FileLocking.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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) throws Exception { - try(FileOutputStream fos = - new FileOutputStream("file.txt"); - FileLock fl = fos.getChannel().tryLock()) { + 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); } } } diff --git a/newio/GetChannel.java b/newio/GetChannel.java new file mode 100644 index 000000000..1c16f1274 --- /dev/null +++ b/newio/GetChannel.java @@ -0,0 +1,53 @@ +// newio/GetChannel.java +// (c)2021 MindView 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/newio/GetData.java b/newio/GetData.java index 9d0421c3b..aafbdbad0 100644 --- a/newio/GetData.java +++ b/newio/GetData.java @@ -1,7 +1,7 @@ // newio/GetData.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Getting different representations from a ByteBuffer import java.nio.*; diff --git a/newio/IntBufferDemo.java b/newio/IntBufferDemo.java index dd11d3ece..ae88d9a84 100644 --- a/newio/IntBufferDemo.java +++ b/newio/IntBufferDemo.java @@ -1,7 +1,7 @@ // newio/IntBufferDemo.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Manipulating ints in a ByteBuffer with an IntBuffer import java.nio.*; diff --git a/newio/LargeMappedFiles.java b/newio/LargeMappedFiles.java index 2b9e9ad2e..dba19f8b5 100644 --- a/newio/LargeMappedFiles.java +++ b/newio/LargeMappedFiles.java @@ -1,7 +1,7 @@ // newio/LargeMappedFiles.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Creating a very large file using mapping import java.nio.*; import java.nio.channels.*; @@ -11,10 +11,12 @@ 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); + 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"); diff --git a/newio/LockingMappedFiles.java b/newio/LockingMappedFiles.java index fb01d8f48..eec5a46ec 100644 --- a/newio/LockingMappedFiles.java +++ b/newio/LockingMappedFiles.java @@ -1,7 +1,7 @@ // newio/LockingMappedFiles.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Locking portions of a mapped file import java.nio.*; import java.nio.channels.*; @@ -12,14 +12,15 @@ public class LockingMappedFiles { 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); + 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); + new LockAndModify( + out, LENGTH/2, LENGTH/2 + LENGTH/4); } private static class LockAndModify extends Thread { private ByteBuffer buff; @@ -32,8 +33,7 @@ private static class LockAndModify extends Thread { buff = mbb.slice(); start(); } - @Override - public void run() { + @Override public void run() { try { // Exclusive lock with no overlap: FileLock fl = fc.lock(start, end, false); diff --git a/newio/MappedIO.java b/newio/MappedIO.java index c1cbc0edd..f098ae269 100644 --- a/newio/MappedIO.java +++ b/newio/MappedIO.java @@ -1,119 +1,139 @@ // newio/MappedIO.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 = 1_000_000; + private static int numOfUbuffInts = 100_000; private abstract static class Tester { private String name; - public Tester(String name) { this.name = name; } + Tester(String name) { + this.name = name; + } public void runTest() { System.out.print(name + ": "); - try { - long start = System.nanoTime(); - test(); - double duration = System.nanoTime() - start; - System.out.format("%.3f\n", duration/1.0e9); - } catch(IOException e) { - throw new RuntimeException(e); - } + long start = System.nanoTime(); + test(); + double duration = System.nanoTime() - start; + System.out.format("%.3f%n", duration/1.0e9); } - public abstract void test() throws IOException; + public abstract void test(); } private static Tester[] tests = { new Tester("Stream Write") { - @Override - public void test() throws IOException { - try(DataOutputStream dos = new DataOutputStream( + @Override public void test() { + try( + DataOutputStream dos = + new DataOutputStream( new BufferedOutputStream( new FileOutputStream( - new File("temp.tmp"))))) { + 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() throws IOException { - try(FileChannel fc = - new RandomAccessFile("temp.tmp", "rw") - .getChannel()) { - IntBuffer ib = fc.map( - FileChannel.MapMode.READ_WRITE, 0, fc.size()) - .asIntBuffer(); + @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() throws IOException { - try(DataInputStream dis = new DataInputStream( + @Override public void test() { + try( + DataInputStream dis = + new DataInputStream( new BufferedInputStream( - new FileInputStream("temp.tmp")))) { + 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() throws IOException { - try(FileChannel fc = new FileInputStream( - new File("temp.tmp")).getChannel()) { - IntBuffer ib = fc.map( - FileChannel.MapMode.READ_ONLY, 0, fc.size()) - .asIntBuffer(); + @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() throws IOException { - try(RandomAccessFile raf = new RandomAccessFile( - new File("temp.tmp"), "rw")) { + @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() throws IOException { - try(FileChannel fc = new RandomAccessFile( - new File("temp.tmp"), "rw").getChannel()) { - IntBuffer ib = fc.map( - FileChannel.MapMode.READ_WRITE, 0, fc.size()) - .asIntBuffer(); + @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) { - for(Tester test : tests) - test.runTest(); + Arrays.stream(tests).forEach(Tester::runTest); } } /* Output: -Stream Write: 0.329 -Mapped Write: 0.024 -Stream Read: 0.319 -Mapped Read: 0.019 -Stream Read/Write: 12.778 -Mapped Read/Write: 0.010 +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/newio/TransferTo.java b/newio/TransferTo.java index 786955c03..cafc1dc18 100644 --- a/newio/TransferTo.java +++ b/newio/TransferTo.java @@ -1,27 +1,30 @@ // newio/TransferTo.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Using transferTo() between channels -// {Args: TransferTo.java TransferTo.txt} +// {java TransferTo TransferTo.java TransferTo.txt} import java.nio.channels.*; import java.io.*; public class TransferTo { - public static void - main(String[] args) throws Exception { + 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()) { + 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/newio/UsingBuffers.java b/newio/UsingBuffers.java index 3acf6c7a1..213132a34 100644 --- a/newio/UsingBuffers.java +++ b/newio/UsingBuffers.java @@ -1,7 +1,7 @@ // newio/UsingBuffers.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.nio.*; public class UsingBuffers { @@ -17,7 +17,8 @@ void symmetricScramble(CharBuffer buffer) { } public static void main(String[] args) { char[] data = "UsingBuffers".toCharArray(); - ByteBuffer bb = ByteBuffer.allocate(data.length * 2); + ByteBuffer bb = + ByteBuffer.allocate(data.length * 2); CharBuffer cb = bb.asCharBuffer(); cb.put(data); System.out.println(cb.rewind()); diff --git a/newio/ViewBuffers.java b/newio/ViewBuffers.java index a3fa9b057..0806f4df0 100644 --- a/newio/ViewBuffers.java +++ b/newio/ViewBuffers.java @@ -1,7 +1,7 @@ // newio/ViewBuffers.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.nio.*; public class ViewBuffers { @@ -58,8 +58,8 @@ public static void main(String[] args) { } } /* Output: -Byte Buffer 0 -> 0, 1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0, 5 -> 0, -6 -> 0, 7 -> 97, +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, diff --git a/newio/build.xml b/newio/build.xml deleted file mode 100644 index 1f0e5062e..000000000 --- a/newio/build.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/objects/HelloDate.java b/objects/HelloDate.java index 4fd4a4ba0..b408b1f48 100644 --- a/objects/HelloDate.java +++ b/objects/HelloDate.java @@ -1,26 +1,12 @@ // objects/HelloDate.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; -/** The first On Java example program. - * Displays a String and today's date. - * @author Bruce Eckel - * @author www.MindviewInc.com - * @version 5.0 - */ public class HelloDate { - /** 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: -Mon Jun 15 15:47:53 PDT 2015 -*/ diff --git a/objects/ShowProperties.java b/objects/ShowProperties.java index 02db099ef..f61e1aaca 100644 --- a/objects/ShowProperties.java +++ b/objects/ShowProperties.java @@ -1,7 +1,7 @@ // objects/ShowProperties.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class ShowProperties { public static void main(String[] args) { @@ -13,14 +13,14 @@ public static void main(String[] args) { } /* Output: (First 20 Lines) -- listing properties -- -java.runtime.name=Java(TM) SE Runtime Environment -sun.boot.library.path=C:\Program Files -(x86)\Java\jre1.8.0_... -java.vm.version=25.60-b23 +java.runtime.name=OpenJDK Runtime Environment +sun.boot.library.path=C:\Program Files\OpenJDK\java- +se-8u41... +java.vm.version=25.40-b25 java.vm.vendor=Oracle Corporation java.vendor.url=http://java.oracle.com/ path.separator=; -java.vm.name=Java HotSpot(TM) Client VM +java.vm.name=OpenJDK Client VM file.encoding.pkg=sun.io user.script= user.country=US @@ -28,10 +28,11 @@ public static void main(String[] args) { sun.os.patch.level= java.vm.specification.name=Java Virtual Machine Specification -user.dir=C:\Users\Bruce\Documents\GitHub\OnJav... -java.runtime.version=1.8.0_60-b27 +user.dir=C:\Git\OnJava8\ExtractedExamples\objects +java.runtime.version=1.8.0_41-b04 java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment -java.endorsed.dirs=C:\Program Files (x86)\Java\jre1.8.0_... +java.endorsed.dirs=C:\Program Files\OpenJDK\java- +se-8u41... os.arch=x86 java.io.tmpdir=C:\Users\Bruce\AppData\Local\Temp\ ... diff --git a/objects/build.xml b/objects/build.xml deleted file mode 100644 index a841bc9ae..000000000 --- a/objects/build.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/onjava/ArrayShow.java b/onjava/ArrayShow.java index 078d93737..1e87754b2 100644 --- a/onjava/ArrayShow.java +++ b/onjava/ArrayShow.java @@ -1,7 +1,7 @@ // onjava/ArrayShow.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package onjava; import java.util.*; diff --git a/onjava/BasicSupplier.java b/onjava/BasicSupplier.java index e1c7e855f..45bb58111 100644 --- a/onjava/BasicSupplier.java +++ b/onjava/BasicSupplier.java @@ -1,22 +1,24 @@ // onjava/BasicSupplier.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Supplier from a class with a no-arg constructor +// Visit http://OnJava8.com for more book information. +// Supplier from a class with a zero-argument 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() { + @Override public T get() { try { // Assumes type is a public class: - return type.newInstance(); + return type.getConstructor().newInstance(); } catch(InstantiationException | + NoSuchMethodException | + InvocationTargetException | IllegalAccessException e) { throw new RuntimeException(e); } diff --git a/onjava/CollectionMethodDifferences.java b/onjava/CollectionMethodDifferences.java index 7e82604eb..43262312b 100644 --- a/onjava/CollectionMethodDifferences.java +++ b/onjava/CollectionMethodDifferences.java @@ -1,7 +1,8 @@ // onjava/CollectionMethodDifferences.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {java onjava.CollectionMethodDifferences} package onjava; import java.lang.reflect.*; import java.util.*; @@ -26,10 +27,11 @@ static void interfaces(Class type) { static void difference(Class superset, Class subset) { System.out.print(superset.getSimpleName() + - " extends " + subset.getSimpleName() + ", adds: "); + " extends " + subset.getSimpleName() + + ", adds: "); Set comp = Sets.difference( methodSet(superset), methodSet(subset)); - comp.removeAll(object); // Don't show 'Object' methods + comp.removeAll(object); // Ignore 'Object' methods System.out.println(comp); interfaces(superset); } @@ -64,23 +66,27 @@ public static void main(String[] args) { 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 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] +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] +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, @@ -88,24 +94,24 @@ public static void main(String[] args) { 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] +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] +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] +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/onjava/ConvertTo.java b/onjava/ConvertTo.java index 3d4fd8504..070723118 100644 --- a/onjava/ConvertTo.java +++ b/onjava/ConvertTo.java @@ -1,102 +1,102 @@ // onjava/ConvertTo.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package onjava; public interface ConvertTo { - public static boolean[] primitive(Boolean[] in) { + 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; } - public static char[] primitive(Character[] in) { + 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; } - public static byte[] primitive(Byte[] in) { + 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; } - public static short[] primitive(Short[] in) { + 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; } - public static int[] primitive(Integer[] in) { + 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; } - public static long[] primitive(Long[] in) { + 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; } - public static float[] primitive(Float[] in) { + 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; } - public static double[] primitive(Double[] in) { + 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: - public static Boolean[] boxed(boolean[] in) { + static Boolean[] boxed(boolean[] in) { Boolean[] result = new Boolean[in.length]; for(int i = 0; i < in.length; i++) - result[i] = in[i]; // Autboxing + result[i] = in[i]; // Autoboxing return result; } - public static Character[] boxed(char[] in) { + 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; } - public static Byte[] boxed(byte[] in) { + 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; } - public static Short[] boxed(short[] in) { + 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; } - public static Integer[] boxed(int[] in) { + 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; } - public static Long[] boxed(long[] in) { + 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; } - public static Float[] boxed(float[] in) { + 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; } - public static Double[] boxed(double[] in) { + static Double[] boxed(double[] in) { Double[] result = new Double[in.length]; for(int i = 0; i < in.length; i++) result[i] = in[i]; diff --git a/onjava/Count.java b/onjava/Count.java index aba219703..e2382f57b 100644 --- a/onjava/Count.java +++ b/onjava/Count.java @@ -1,7 +1,7 @@ // onjava/Count.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Generate incremental values of different types package onjava; import java.util.*; @@ -9,15 +9,16 @@ import static onjava.ConvertTo.*; public interface Count { - public static class Boolean + class Boolean implements Supplier { private boolean b = true; - @Override - public java.lang.Boolean get() { + @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 get(int n) { + return get(); + } public java.lang.Boolean[] array(int sz) { java.lang.Boolean[] result = new java.lang.Boolean[sz]; @@ -25,7 +26,7 @@ public java.lang.Boolean[] array(int sz) { return result; } } - public static class boolean_ { + class Pboolean { private boolean b = true; public boolean get() { b = !b; @@ -36,19 +37,22 @@ public boolean[] array(int sz) { return primitive(new Boolean().array(sz)); } } - public static class Byte + 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 get(int n) { + return get(); + } public java.lang.Byte[] array(int sz) { - java.lang.Byte[] result = new java.lang.Byte[sz]; + java.lang.Byte[] result = + new java.lang.Byte[sz]; Arrays.setAll(result, n -> get()); return result; } } - public static class byte_ { + class Pbyte { private byte b; public byte get() { return b++; } public byte get(int n) { return get(); } @@ -56,15 +60,14 @@ public byte[] array(int sz) { return primitive(new Byte().array(sz)); } } - static final char[] chars = + char[] CHARS = "abcdefghijklmnopqrstuvwxyz".toCharArray(); - public static class Character + class Character implements Supplier { private int i; - @Override - public java.lang.Character get() { - i = (i + 1) % chars.length; - return chars[i]; + @Override public java.lang.Character get() { + i = (i + 1) % CHARS.length; + return CHARS[i]; } public java.lang.Character get(int n) { return get(); @@ -76,30 +79,33 @@ public java.lang.Character[] array(int sz) { return result; } } - public static class char_ { + class Pchar { private int i; public char get() { - i = (i + 1) % chars.length; - return chars[i]; + 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)); } } - public static class Short + 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 get(int n) { + return get(); + } public java.lang.Short[] array(int sz) { - java.lang.Short[] result = new java.lang.Short[sz]; + java.lang.Short[] result = + new java.lang.Short[sz]; Arrays.setAll(result, n -> get()); return result; } } - public static class short_ { + class Pshort { short s; public short get() { return s++; } public short get(int n) { return get(); } @@ -107,12 +113,14 @@ public short[] array(int sz) { return primitive(new Short().array(sz)); } } - public static class Integer + 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 get(int n) { + return get(); + } public java.lang.Integer[] array(int sz) { java.lang.Integer[] result = new java.lang.Integer[sz]; @@ -120,7 +128,7 @@ public java.lang.Integer[] array(int sz) { return result; } } - public static class int_ implements IntSupplier { + class Pint implements IntSupplier { int i; public int get() { return i++; } public int get(int n) { return get(); } @@ -130,19 +138,22 @@ public int[] array(int sz) { return primitive(new Integer().array(sz)); } } - public static class Long + 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 get(int n) { + return get(); + } public java.lang.Long[] array(int sz) { - java.lang.Long[] result = new java.lang.Long[sz]; + java.lang.Long[] result = + new java.lang.Long[sz]; Arrays.setAll(result, n -> get()); return result; } } - public static class long_ implements LongSupplier { + class Plong implements LongSupplier { private long l; public long get() { return l++; } public long get(int n) { return get(); } @@ -152,21 +163,23 @@ public long[] array(int sz) { return primitive(new Long().array(sz)); } } - public class Float + class Float implements Supplier { private int i; - @Override - public java.lang.Float get() { + @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 get(int n) { + return get(); + } public java.lang.Float[] array(int sz) { - java.lang.Float[] result = new java.lang.Float[sz]; + java.lang.Float[] result = + new java.lang.Float[sz]; Arrays.setAll(result, n -> get()); return result; } } - public class float_ { + class Pfloat { private int i; public float get() { return i++; } public float get(int n) { return get(); } @@ -174,14 +187,15 @@ public float[] array(int sz) { return primitive(new Float().array(sz)); } } - public class Double + class Double implements Supplier { private int i; - @Override - public java.lang.Double get() { + @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 get(int n) { + return get(); + } public java.lang.Double[] array(int sz) { java.lang.Double[] result = new java.lang.Double[sz]; @@ -189,7 +203,7 @@ public java.lang.Double[] array(int sz) { return result; } } - public class double_ implements DoubleSupplier { + class Pdouble implements DoubleSupplier { private int i; public double get() { return i++; } public double get(int n) { return get(); } diff --git a/onjava/CountMap.java b/onjava/CountMap.java new file mode 100644 index 000000000..e4f08e7a5 --- /dev/null +++ b/onjava/CountMap.java @@ -0,0 +1,91 @@ +// onjava/CountMap.java +// (c)2021 MindView 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/onjava/CountingFilledMap.java b/onjava/CountingFilledMap.java deleted file mode 100644 index d7c857844..000000000 --- a/onjava/CountingFilledMap.java +++ /dev/null @@ -1,66 +0,0 @@ -// onjava/CountingFilledMap.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Unlimited-length Map containing sample data -package onjava; -import java.util.*; - -public class CountingFilledMap -extends AbstractMap { - private int size; - private static String[] chars = - "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z" - .split(" "); - public CountingFilledMap(int size) { - if(size < 0) this.size = 0; - else this.size = size; - } - private static class Entry - implements Map.Entry { - int index; - Entry(int index) { this.index = index; } - @Override - public boolean equals(Object o) { - return Integer.valueOf(index).equals(o); - } - @Override - public Integer getKey() { return index; } - @Override - public String getValue() { - return - chars[index % chars.length] + - Integer.toString(index / chars.length); - } - @Override - public String setValue(String value) { - throw new UnsupportedOperationException(); - } - @Override - public int hashCode() { - return Integer.valueOf(index).hashCode(); - } - } - @Override - public Set> entrySet() { - // LinkedHashSet retains initialization order: - Set> entries = - new LinkedHashSet<>(); - for(int i = 0; i < size; i++) - entries.add(new Entry(i)); - return entries; - } - public static void main(String[] args) { - System.out.println(new CountingFilledMap(60)); - } -} -/* 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} -*/ diff --git a/onjava/CountingIntegerList.java b/onjava/CountingIntegerList.java index 9036632db..d7f73a1b5 100644 --- a/onjava/CountingIntegerList.java +++ b/onjava/CountingIntegerList.java @@ -1,28 +1,32 @@ // onjava/CountingIntegerList.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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) { + @Override public Integer get(int index) { return index; } - @Override - public int size() { return size; } + @Override public int size() { return size; } public static void main(String[] args) { - System.out.println(new CountingIntegerList(30)); + 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] +[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/onjava/Countries.java b/onjava/Countries.java index e1d983bd8..666dda293 100644 --- a/onjava/Countries.java +++ b/onjava/Countries.java @@ -1,137 +1,215 @@ // onjava/Countries.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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"}, + {"ALGERIA","Algiers"}, + {"ANGOLA","Luanda"}, + {"BENIN","Porto-Novo"}, + {"BOTSWANA","Gaberone"}, {"BURKINA FASO","Ouagadougou"}, {"BURUNDI","Bujumbura"}, - {"CAMEROON","Yaounde"}, {"CAPE VERDE","Praia"}, + {"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"}, + {"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"}, + {"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"}, + {"SENEGAL","Dakar"}, + {"SEYCHELLES","Victoria"}, + {"SIERRA LEONE","Freetown"}, + {"SOMALIA","Mogadishu"}, {"SOUTH AFRICA","Pretoria/Cape Town"}, {"SUDAN","Khartoum"}, - {"SWAZILAND","Mbabane"}, {"TANZANIA","Dodoma"}, - {"TOGO","Lome"}, {"TUNISIA","Tunis"}, + {"SWAZILAND","Mbabane"}, + {"TANZANIA","Dodoma"}, + {"TOGO","Lome"}, + {"TUNISIA","Tunis"}, {"UGANDA","Kampala"}, {"DEMOCRATIC REPUBLIC OF THE CONGO (ZAIRE)", "Kinshasa"}, - {"ZAMBIA","Lusaka"}, {"ZIMBABWE","Harare"}, + {"ZAMBIA","Lusaka"}, + {"ZIMBABWE","Harare"}, // Asia - {"AFGHANISTAN","Kabul"}, {"BAHRAIN","Manama"}, - {"BANGLADESH","Dhaka"}, {"BHUTAN","Thimphu"}, + {"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"}, + {"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"}, + {"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"}, + {"THAILAND","Bangkok"}, + {"TURKEY","Ankara"}, {"UNITED ARAB EMIRATES","Abu Dhabi"}, - {"VIETNAM","Hanoi"}, {"YEMEN","Sana'a"}, + {"VIETNAM","Hanoi"}, + {"YEMEN","Sana'a"}, // Australia and Oceania - {"AUSTRALIA","Canberra"}, {"FIJI","Suva"}, + {"AUSTRALIA","Canberra"}, + {"FIJI","Suva"}, {"KIRIBATI","Bairiki"}, {"MARSHALL ISLANDS","Dalap-Uliga-Darrit"}, - {"MICRONESIA","Palikir"}, {"NAURU","Yaren"}, - {"NEW ZEALAND","Wellington"}, {"PALAU","Koror"}, + {"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"}, + {"SOLOMON ISLANDS","Honaira"}, + {"TONGA","Nuku'alofa"}, + {"TUVALU","Fongafale"}, + {"VANUATU","Port Vila"}, {"WESTERN SAMOA","Apia"}, // Eastern Europe and former USSR - {"ARMENIA","Yerevan"}, {"AZERBAIJAN","Baku"}, + {"ARMENIA","Yerevan"}, + {"AZERBAIJAN","Baku"}, {"BELARUS (BYELORUSSIA)","Minsk"}, - {"BULGARIA","Sofia"}, {"GEORGIA","Tbilisi"}, - {"KAZAKSTAN","Almaty"}, {"KYRGYZSTAN","Alma-Ata"}, - {"MOLDOVA","Chisinau"}, {"RUSSIA","Moscow"}, + {"BULGARIA","Sofia"}, + {"GEORGIA","Tbilisi"}, + {"KAZAKSTAN","Almaty"}, + {"KYRGYZSTAN","Alma-Ata"}, + {"MOLDOVA","Chisinau"}, + {"RUSSIA","Moscow"}, {"TAJIKISTAN","Dushanbe"}, - {"TURKMENISTAN","Ashkabad"}, - {"UKRAINE","Kyiv"}, {"UZBEKISTAN","Tashkent"}, + {"TURKMENISTAN","Ashkhabad"}, + {"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","---"}, + {"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"}, + {"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","-"}, - {"NEVIS","Basseterre"}, {"ST. LUCIA","Castries"}, + {"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"}, + {"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"}, + {"URUGUAY","Montevideo"}, + {"VENEZUELA","Caracas"}, }; // Use AbstractMap by implementing entrySet() private static class FlyweightMap @@ -140,24 +218,23 @@ private static class Entry implements Map.Entry { int index; Entry(int index) { this.index = index; } - @Override - public boolean equals(Object o) { - return DATA[index][0].equals(o); + @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(); + @Override public String getValue() { + return DATA[index][1]; } - @Override - public int hashCode() { - return DATA[index][0].hashCode(); + @Override public String setValue(String value) { + throw new UnsupportedOperationException(); } } - // Use AbstractSet by implementing size() & iterator() + // Implement size() & iterator() for AbstractSet: static class EntrySet extends AbstractSet> { private int size; @@ -170,14 +247,12 @@ else if(size > DATA.length) else this.size = size; } - @Override - public int size() { return 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() { + @Override public boolean hasNext() { return entry.index < size - 1; } @Override @@ -185,18 +260,17 @@ public Map.Entry next() { entry.index++; return entry; } - @Override - public void remove() { + @Override public void remove() { throw new UnsupportedOperationException(); } } - @Override - public + @Override public Iterator> iterator() { return new Iter(); } } - private static Set> entries = + private static + Set> entries = new EntrySet(DATA.length); @Override public Set> entrySet() { @@ -231,7 +305,8 @@ 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 LinkedHashMap<>(capitals(3))); System.out.println(new TreeMap<>(capitals(3))); System.out.println(new Hashtable<>(capitals(3))); System.out.println(new HashSet<>(names(6))); @@ -247,16 +322,22 @@ public static void main(String[] args) { 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] +[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] +[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/onjava/DaemonThreadFactory.java b/onjava/DaemonThreadFactory.java deleted file mode 100644 index 9fb59c52b..000000000 --- a/onjava/DaemonThreadFactory.java +++ /dev/null @@ -1,16 +0,0 @@ -// onjava/DaemonThreadFactory.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package onjava; -import java.util.concurrent.*; - -public class -DaemonThreadFactory implements ThreadFactory { - @Override - public Thread newThread(Runnable r) { - Thread t = new Thread(r); - t.setDaemon(true); - return t; - } -} diff --git a/onjava/DaemonThreadPoolExecutor.java b/onjava/DaemonThreadPoolExecutor.java deleted file mode 100644 index e903081e4..000000000 --- a/onjava/DaemonThreadPoolExecutor.java +++ /dev/null @@ -1,15 +0,0 @@ -// onjava/DaemonThreadPoolExecutor.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package onjava; -import java.util.concurrent.*; - -public class DaemonThreadPoolExecutor -extends ThreadPoolExecutor { - public DaemonThreadPoolExecutor() { - super(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, - new SynchronousQueue<>(), - new DaemonThreadFactory()); - } -} diff --git a/onjava/Deque.java b/onjava/Deque.java deleted file mode 100644 index c83da38ec..000000000 --- a/onjava/Deque.java +++ /dev/null @@ -1,21 +0,0 @@ -// onjava/Deque.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Creating a Deque from a LinkedList -package onjava; -import java.util.*; - -public class Deque { - private LinkedList deque = new LinkedList<>(); - public void addFirst(T e) { deque.addFirst(e); } - public void addLast(T e) { deque.addLast(e); } - public T getFirst() { return deque.getFirst(); } - public T getLast() { return deque.getLast(); } - public T removeFirst() { return deque.removeFirst(); } - public T removeLast() { return deque.removeLast(); } - public int size() { return deque.size(); } - @Override - public String toString() { return deque.toString(); } - // And other methods as necessary... -} diff --git a/onjava/Enums.java b/onjava/Enums.java index a9d1c85b0..2af4b0840 100644 --- a/onjava/Enums.java +++ b/onjava/Enums.java @@ -1,12 +1,12 @@ // onjava/Enums.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package onjava; import java.util.*; public class Enums { - private static SplittableRandom rand = new SplittableRandom(47); + private static Random rand = new Random(47); public static > T random(Class ec) { return random(ec.getEnumConstants()); diff --git a/onjava/FillMap.java b/onjava/FillMap.java new file mode 100644 index 000000000..4f1650d52 --- /dev/null +++ b/onjava/FillMap.java @@ -0,0 +1,38 @@ +// onjava/FillMap.java +// (c)2021 MindView 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/onjava/FilledCollection.java b/onjava/FilledCollection.java deleted file mode 100644 index 382954a6b..000000000 --- a/onjava/FilledCollection.java +++ /dev/null @@ -1,20 +0,0 @@ -// onjava/FilledCollection.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// A Collection filled with data using a generator object -package onjava; -import java.util.*; -import java.util.function.*; - -public class FilledCollection extends ArrayList { - public FilledCollection(Supplier gen, int quantity) { - for(int i = 0; i < quantity; i++) - add(gen.get()); - } - // A generic convenience method: - public static FilledCollection - list(Supplier gen, int quantity) { - return new FilledCollection<>(gen, quantity); - } -} diff --git a/onjava/FilledMap.java b/onjava/FilledMap.java deleted file mode 100644 index 7bd7afede..000000000 --- a/onjava/FilledMap.java +++ /dev/null @@ -1,65 +0,0 @@ -// onjava/FilledMap.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Fill a Map with data using a generator object -package onjava; -import java.util.*; -import java.util.function.*; - -public class FilledMap extends LinkedHashMap { - // A single Pair Supplier: - public FilledMap(Supplier> gen, int quantity) { - for(int i = 0; i < quantity; i++) { - Pair p = gen.get(); - put(p.key, p.value); - } - } - // Two separate Suppliers: - public FilledMap(Supplier genK, Supplier genV, - int quantity) { - for(int i = 0; i < quantity; i++) { - put(genK.get(), genV.get()); - } - } - // A key Supplier and a single value: - public - FilledMap(Supplier genK, V value, int quantity) { - for(int i = 0; i < quantity; i++) { - put(genK.get(), value); - } - } - // An Iterable and a value Supplier: - public FilledMap(Iterable genK, Supplier genV) { - for(K key : genK) { - put(key, genV.get()); - } - } - // An Iterable and a single value: - public FilledMap(Iterable genK, V value) { - for(K key : genK) { - put(key, value); - } - } - // Generic convenience methods: - public static FilledMap - map(Supplier> gen, int quantity) { - return new FilledMap<>(gen, quantity); - } - public static FilledMap - map(Supplier genK, Supplier genV, int quantity) { - return new FilledMap<>(genK, genV, quantity); - } - public static FilledMap - map(Supplier genK, V value, int quantity) { - return new FilledMap<>(genK, value, quantity); - } - public static FilledMap - map(Iterable genK, Supplier genV) { - return new FilledMap<>(genK, genV); - } - public static FilledMap - map(Iterable genK, V value) { - return new FilledMap<>(genK, value); - } -} diff --git a/onjava/HTMLColors.java b/onjava/HTMLColors.java new file mode 100644 index 000000000..7a6421546 --- /dev/null +++ b/onjava/HTMLColors.java @@ -0,0 +1,236 @@ +// onjava/HTMLColors.java +// (c)2021 MindView 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/onjava/MouseClick.java b/onjava/MouseClick.java index 801a8ff5d..ea7e530da 100644 --- a/onjava/MouseClick.java +++ b/onjava/MouseClick.java @@ -1,19 +1,19 @@ // onjava/MouseClick.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Helper interface to allow lambda expressions +// 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 - public default void mouseEntered(MouseEvent e) {} + default void mouseEntered(MouseEvent e) {} @Override - public default void mouseExited(MouseEvent e) {} + default void mouseExited(MouseEvent e) {} @Override - public default void mousePressed(MouseEvent e) {} + default void mousePressed(MouseEvent e) {} @Override - public default void mouseReleased(MouseEvent e) {} + default void mouseReleased(MouseEvent e) {} } diff --git a/onjava/Nap.java b/onjava/Nap.java new file mode 100644 index 000000000..264d7e69d --- /dev/null +++ b/onjava/Nap.java @@ -0,0 +1,20 @@ +// onjava/Nap.java +// (c)2021 MindView 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/onjava/Null.java b/onjava/Null.java index 6d5cdc67b..9dfae5f2f 100644 --- a/onjava/Null.java +++ b/onjava/Null.java @@ -1,6 +1,6 @@ // onjava/Null.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package onjava; public interface Null {} diff --git a/onjava/OSExecute.java b/onjava/OSExecute.java index 5ba9195b7..918f67e77 100644 --- a/onjava/OSExecute.java +++ b/onjava/OSExecute.java @@ -1,7 +1,7 @@ // onjava/OSExecute.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Run an operating system command // and send the output to the console package onjava; @@ -11,24 +11,23 @@ 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()))) { - String s; - while((s = results.readLine())!= null) - System.out.println(s); - // Report errors and return nonzero value - // to calling process if there are problems: - while((s = errors.readLine())!= null) { - System.err.println(s); - err = true; - } + 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(Exception e) { + } catch(IOException e) { throw new RuntimeException(e); } if(err) diff --git a/onjava/OSExecuteException.java b/onjava/OSExecuteException.java index e8cb89192..1bf097b89 100644 --- a/onjava/OSExecuteException.java +++ b/onjava/OSExecuteException.java @@ -1,9 +1,12 @@ // onjava/OSExecuteException.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package onjava; -public class OSExecuteException extends RuntimeException { - public OSExecuteException(String why) { super(why); } +public class +OSExecuteException extends RuntimeException { + public OSExecuteException(String why) { + super(why); + } } diff --git a/onjava/Operation.java b/onjava/Operation.java index ca97d129b..f540bb76a 100644 --- a/onjava/Operation.java +++ b/onjava/Operation.java @@ -1,9 +1,8 @@ // onjava/Operation.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package onjava; -import java.util.*; public interface Operation { void execute(); diff --git a/onjava/Pair.java b/onjava/Pair.java index f0b4f4091..6dce28e3e 100644 --- a/onjava/Pair.java +++ b/onjava/Pair.java @@ -1,7 +1,7 @@ // onjava/Pair.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package onjava; public class Pair { @@ -11,4 +11,9 @@ 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/onjava/ProcessFiles.java b/onjava/ProcessFiles.java index 8dc5e8890..af9d5e2e8 100644 --- a/onjava/ProcessFiles.java +++ b/onjava/ProcessFiles.java @@ -1,8 +1,7 @@ // onjava/ProcessFiles.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {ValidateByHand} +// Visit http://OnJava8.com for more book information. package onjava; import java.io.*; import java.nio.file.*; @@ -46,10 +45,4 @@ public void start(String[] args) { .filter(matcher::matches) .forEach(p -> strategy.process(p.toFile())); } - // Demonstration of how to use it: - public static void main(String[] args) { - new ProcessFiles(file -> System.out.println(file), - "java").start(args); - } } -/* Output: (Execute to see) */ diff --git a/onjava/Rand.java b/onjava/Rand.java index d8f075b4f..1a589302e 100644 --- a/onjava/Rand.java +++ b/onjava/Rand.java @@ -1,7 +1,7 @@ // onjava/Rand.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Generate random values of different types package onjava; import java.util.*; @@ -9,12 +9,11 @@ import static onjava.ConvertTo.*; public interface Rand { - static final int MOD = 10_000; - public static class Boolean + int MOD = 10_000; + class Boolean implements Supplier { SplittableRandom r = new SplittableRandom(47); - @Override - public java.lang.Boolean get() { + @Override public java.lang.Boolean get() { return r.nextBoolean(); } public java.lang.Boolean get(int n) { @@ -27,35 +26,36 @@ public java.lang.Boolean[] array(int sz) { return result; } } - public static class boolean_ { + class Pboolean { public boolean[] array(int sz) { return primitive(new Boolean().array(sz)); } } - public static class Byte + class Byte implements Supplier { SplittableRandom r = new SplittableRandom(47); - @Override - public java.lang.Byte get() { + @Override public java.lang.Byte get() { return (byte)r.nextInt(MOD); } - public java.lang.Byte get(int n) { return get(); } + 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]; + java.lang.Byte[] result = + new java.lang.Byte[sz]; Arrays.setAll(result, n -> get()); return result; } } - public static class byte_ { + class Pbyte { public byte[] array(int sz) { return primitive(new Byte().array(sz)); } } - public static class Character + class Character implements Supplier { SplittableRandom r = new SplittableRandom(47); - @Override - public java.lang.Character get() { + @Override public java.lang.Character get() { return (char)r.nextInt('a', 'z' + 1); } public java.lang.Character get(int n) { @@ -68,40 +68,43 @@ public java.lang.Character[] array(int sz) { return result; } } - public static class char_ { + class Pchar { public char[] array(int sz) { return primitive(new Character().array(sz)); } } - public static class Short + class Short implements Supplier { SplittableRandom r = new SplittableRandom(47); - @Override - public java.lang.Short get() { + @Override public java.lang.Short get() { return (short)r.nextInt(MOD); } - public java.lang.Short get(int n) { return get(); } + 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]; + java.lang.Short[] result = + new java.lang.Short[sz]; Arrays.setAll(result, n -> get()); return result; } } - public static class short_ { + class Pshort { public short[] array(int sz) { return primitive(new Short().array(sz)); } } - public static class Integer + class Integer implements Supplier { SplittableRandom r = new SplittableRandom(47); - @Override - public java.lang.Integer get() { + @Override public java.lang.Integer get() { return r.nextInt(MOD); } - public java.lang.Integer get(int n) { return get(); } + public java.lang.Integer get(int n) { + return get(); + } public java.lang.Integer[] array(int sz) { - int[] primitive = new int_().array(sz); + int[] primitive = new Pint().array(sz); java.lang.Integer[] result = new java.lang.Integer[sz]; for(int i = 0; i < sz; i++) @@ -109,35 +112,37 @@ public java.lang.Integer[] array(int sz) { return result; } } - public static class int_ implements IntSupplier { + class Pint implements IntSupplier { SplittableRandom r = new SplittableRandom(47); - @Override - public int getAsInt() { return r.nextInt(MOD); } + @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(); } } - public static class Long + class Long implements Supplier { SplittableRandom r = new SplittableRandom(47); - @Override - public java.lang.Long get() { + @Override public java.lang.Long get() { return r.nextLong(MOD); } - public java.lang.Long get(int n) { return get(); } + public java.lang.Long get(int n) { + return get(); + } public java.lang.Long[] array(int sz) { - long[] primitive = new long_().array(sz); - java.lang.Long[] result = new java.lang.Long[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; } } - public static class long_ implements LongSupplier { + class Plong implements LongSupplier { SplittableRandom r = new SplittableRandom(47); - @Override - public long getAsLong() { + @Override public long getAsLong() { return r.nextLong(MOD); } public long get(int n) { return getAsLong(); } @@ -145,38 +150,43 @@ public long[] array(int sz) { return r.longs(sz, 0, MOD).toArray(); } } - public static class Float + class Float implements Supplier { SplittableRandom r = new SplittableRandom(47); - @Override - public java.lang.Float get() { + @Override public java.lang.Float get() { return (float)trim(r.nextDouble()); } - public java.lang.Float get(int n) { return get(); } + 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]; + java.lang.Float[] result = + new java.lang.Float[sz]; Arrays.setAll(result, n -> get()); return result; } } - public static class float_ { + 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; + return + ((double)Math.round(d * 1000.0)) / 100.0; } - public static class Double + class Double implements Supplier { SplittableRandom r = new SplittableRandom(47); - @Override - public java.lang.Double get() { + @Override public java.lang.Double get() { return trim(r.nextDouble()); } - public java.lang.Double get(int n) { return get(); } + public java.lang.Double get(int n) { + return get(); + } public java.lang.Double[] array(int sz) { - double[] primitive = new Rand.double_().array(sz); + double[] primitive = + new Rand.Pdouble().array(sz); java.lang.Double[] result = new java.lang.Double[sz]; for(int i = 0; i < sz; i++) @@ -184,13 +194,14 @@ public java.lang.Double[] array(int sz) { return result; } } - public static class double_ implements DoubleSupplier { + class Pdouble implements DoubleSupplier { SplittableRandom r = new SplittableRandom(47); - @Override - public double getAsDouble() { + @Override public double getAsDouble() { return trim(r.nextDouble()); } - public double get(int n) { return getAsDouble(); } + public double get(int n) { + return getAsDouble(); + } public double[] array(int sz) { double[] result = r.doubles(sz).toArray(); Arrays.setAll(result, @@ -198,22 +209,23 @@ public double[] array(int sz) { return result; } } - public static class String + class String implements Supplier { SplittableRandom r = new SplittableRandom(47); - private int strlen = 7; // Default string length + private int strlen = 7; // Default length public String() {} - public String(int str_length) { - strlen = str_length; + public String(int strLength) { + strlen = strLength; } - @Override - public java.lang.String get() { + @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 get(int n) { + return get(); + } public java.lang.String[] array(int sz) { java.lang.String[] result = new java.lang.String[sz]; diff --git a/onjava/Range.java b/onjava/Range.java index 70565c699..3003dbd52 100644 --- a/onjava/Range.java +++ b/onjava/Range.java @@ -1,34 +1,30 @@ // onjava/Range.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Array creation methods that can be used without -// qualifiers, using static imports: +// Visit http://OnJava8.com for more book information. +// Create arrays initialized with integer values. 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 a sequence [start..end) incrementing by step + // Produce sequence [start..end) incrementing by step public static int[] range(int start, int end, int step) { - int sz = (end - start)/step; + if(step == 0) + throw new + IllegalArgumentException("Step cannot be zero"); + int sz = Math.max(0, step >= 0 ? + (end + step - 1 - start) / step + : (end + step + 1 - start) / step); int[] result = new int[sz]; for(int i = 0; i < sz; i++) result[i] = start + (i * step); return result; + } // Produce a sequence [start..end) + public static int[] range(int start, int end) { + return range(start, end, 1); + } + // Produce a sequence [0..n) + public static int[] range(int n) { + return range(0, n); } } diff --git a/onjava/Repeat.java b/onjava/Repeat.java index c1c954e0a..11f4cacd8 100644 --- a/onjava/Repeat.java +++ b/onjava/Repeat.java @@ -1,7 +1,7 @@ // onjava/Repeat.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package onjava; import static java.util.stream.IntStream.*; diff --git a/onjava/RmDir.java b/onjava/RmDir.java index 1d4e7d655..fa6d1a5e9 100644 --- a/onjava/RmDir.java +++ b/onjava/RmDir.java @@ -1,29 +1,29 @@ // onjava/RmDir.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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; - } + 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/onjava/Sets.java b/onjava/Sets.java index bdd11e2fb..542f5bb30 100644 --- a/onjava/Sets.java +++ b/onjava/Sets.java @@ -1,7 +1,7 @@ // onjava/Sets.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package onjava; import java.util.*; diff --git a/onjava/Sleep.java b/onjava/Sleep.java deleted file mode 100644 index d30658ae9..000000000 --- a/onjava/Sleep.java +++ /dev/null @@ -1,17 +0,0 @@ -// onjava/Sleep.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Sleep for n seconds -package onjava; -import java.util.concurrent.*; - -public class Sleep { - public Sleep(int n) { - try { - TimeUnit.SECONDS.sleep(n); - } catch(InterruptedException e) { - throw new RuntimeException(e); - } - } -} diff --git a/onjava/Stack.java b/onjava/Stack.java index 49ae8450f..97dc454fa 100644 --- a/onjava/Stack.java +++ b/onjava/Stack.java @@ -1,21 +1,19 @@ // onjava/Stack.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Making a stack from a LinkedList +// Visit http://OnJava8.com for more book information. +// A Stack class built with an ArrayDeque package onjava; -import java.util.LinkedList; +import java.util.Deque; +import java.util.ArrayDeque; public class Stack { - private LinkedList storage = new LinkedList<>(); - public void push(T v) { storage.addFirst(v); } - public T peek() { return storage.getFirst(); } - public T pop() { return storage.removeFirst(); } - public boolean empty() { - return storage.isEmpty(); - } - @Override - public String toString() { + 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/onjava/Suppliers.java b/onjava/Suppliers.java index c04f45270..05ceafab2 100644 --- a/onjava/Suppliers.java +++ b/onjava/Suppliers.java @@ -1,18 +1,17 @@ // onjava/Suppliers.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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.*; -import java.util.function.*; public class Suppliers { // Create a collection and fill it: - public static > - C create(Supplier factory, Supplier gen, int n) { + public static > C + create(Supplier factory, Supplier gen, int n) { return Stream.generate(gen) .limit(n) .collect(factory, C::add, C::addAll); diff --git a/onjava/SwingConsole.java b/onjava/SwingConsole.java deleted file mode 100644 index a2f8158c4..000000000 --- a/onjava/SwingConsole.java +++ /dev/null @@ -1,20 +0,0 @@ -// onjava/SwingConsole.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Tool for running Swing demos from the -// console, both applets and JFrames -package onjava; -import javax.swing.*; - -public class SwingConsole { - public static void - run(final JFrame f, final int width, final int height) { - SwingUtilities.invokeLater(() -> { - f.setTitle(f.getClass().getSimpleName()); - f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - f.setSize(width, height); - f.setVisible(true); - }); - } -} diff --git a/onjava/TaskItem.java b/onjava/TaskItem.java deleted file mode 100644 index 5c9cfdcac..000000000 --- a/onjava/TaskItem.java +++ /dev/null @@ -1,16 +0,0 @@ -// onjava/TaskItem.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// A Future and the Callable that produced it -package onjava; -import java.util.concurrent.*; - -public class TaskItem> { - public final Future future; - public final C task; - public TaskItem(Future future, C task) { - this.future = future; - this.task = task; - } -} diff --git a/onjava/TaskManager.java b/onjava/TaskManager.java deleted file mode 100644 index 77c021473..000000000 --- a/onjava/TaskManager.java +++ /dev/null @@ -1,48 +0,0 @@ -// onjava/TaskManager.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Managing and executing a queue of tasks -package onjava; -import java.util.concurrent.*; -import java.util.*; - -public class TaskManager> -extends ArrayList> { - private ExecutorService exec = - Executors.newSingleThreadExecutor(); - public void add(C task) { - add(new TaskItem<>(exec.submit(task),task)); - } - public List getResults() { - Iterator> items = iterator(); - List results = new ArrayList<>(); - while(items.hasNext()) { - TaskItem item = items.next(); - if(item.future.isDone()) { - try { - results.add(item.future.get()); - } catch(InterruptedException | - ExecutionException e) { - throw new RuntimeException(e); - } - items.remove(); - } - } - return results; - } - public List purge() { - Iterator> items = iterator(); - List results = new ArrayList<>(); - while(items.hasNext()) { - TaskItem item = items.next(); - // Leave completed tasks for results reporting: - if(!item.future.isDone()) { - results.add("Cancelling " + item.task); - item.future.cancel(true); // Can interrupt - items.remove(); - } - } - return results; - } -} diff --git a/onjava/TestRange.java b/onjava/TestRange.java new file mode 100644 index 000000000..cd132d791 --- /dev/null +++ b/onjava/TestRange.java @@ -0,0 +1,29 @@ +// onjava/TestRange.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// Basic test of Range.java +import static onjava.Range.*; +import java.util.Arrays; + +public class TestRange { + private static void show(int[] rng) { + System.out.println(Arrays.toString(rng)); + } + public static void main(String[] args) { + show(range(10, 21, 3)); + show(range(21, 10, -3)); + show(range(-5, 5, -3)); + show(range(-5, 5, 3)); + show(range(10, 21)); + show(range(10)); + } +} +/* Output: +[10, 13, 16, 19] +[21, 18, 15, 12] +[] +[-5, -2, 1, 4] +[10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] +[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +*/ diff --git a/onjava/TimeIt.java b/onjava/TimeIt.java deleted file mode 100644 index e48625f3c..000000000 --- a/onjava/TimeIt.java +++ /dev/null @@ -1,17 +0,0 @@ -// onjava/TimeIt.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package onjava; -import java.util.concurrent.*; - -public interface TimeIt { - static long timeIt(Runnable test) { - long start = System.nanoTime(); - test.run(); - long delta = System.nanoTime() - start; - long millis = TimeUnit.NANOSECONDS.toMillis(delta); - System.out.println(millis); - return millis; - } -} diff --git a/onjava/TimedAbort.java b/onjava/TimedAbort.java index 69fbfd7c5..b9ebeaf89 100644 --- a/onjava/TimedAbort.java +++ b/onjava/TimedAbort.java @@ -1,19 +1,30 @@ // onjava/TimedAbort.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Terminate a program after n seconds +// Visit http://OnJava8.com for more book information. +// Terminate a program after t seconds package onjava; -import java.util.*; +import java.util.concurrent.*; public class TimedAbort { - public TimedAbort(int n) { - new Timer().schedule(new TimerTask() { - @Override - public void run() { - System.out.println("TimedAbort " + n); - System.exit(0); + 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); } - }, n * 1000); + System.out.println(msg); + System.exit(0); + }); } + public TimedAbort(double t) { + this(t, "TimedAbort " + t); + } + public void restart() { restart = true; } } diff --git a/onjava/Timer.java b/onjava/Timer.java new file mode 100644 index 000000000..44a24faed --- /dev/null +++ b/onjava/Timer.java @@ -0,0 +1,19 @@ +// onjava/Timer.java +// (c)2021 MindView 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/onjava/Tuple.java b/onjava/Tuple.java index ac6bef81f..d1d9b80cd 100644 --- a/onjava/Tuple.java +++ b/onjava/Tuple.java @@ -1,7 +1,7 @@ // onjava/Tuple.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Tuple library using type argument inference package onjava; diff --git a/onjava/Tuple2.java b/onjava/Tuple2.java index 1979dc84c..3e2874a90 100644 --- a/onjava/Tuple2.java +++ b/onjava/Tuple2.java @@ -1,16 +1,15 @@ // onjava/Tuple2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package onjava; public class Tuple2 { - public final A _1; - public final B _2; - public Tuple2(A a, B b) { _1 = a; _2 = b; } - public String rep() { return _1 + ", " + _2; } - @Override - public String toString() { + 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/onjava/Tuple3.java b/onjava/Tuple3.java index f324a56d7..117f4b668 100644 --- a/onjava/Tuple3.java +++ b/onjava/Tuple3.java @@ -1,17 +1,16 @@ // onjava/Tuple3.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package onjava; public class Tuple3 extends Tuple2 { - public final C _3; + public final C a3; public Tuple3(A a, B b, C c) { super(a, b); - _3 = c; + a3 = c; } - @Override - public String rep() { - return super.rep() + ", " + _3; + @Override public String rep() { + return super.rep() + ", " + a3; } } diff --git a/onjava/Tuple4.java b/onjava/Tuple4.java index 3b95e62e6..1a62db093 100644 --- a/onjava/Tuple4.java +++ b/onjava/Tuple4.java @@ -1,18 +1,17 @@ // onjava/Tuple4.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package onjava; public class Tuple4 extends Tuple3 { - public final D _4; + public final D a4; public Tuple4(A a, B b, C c, D d) { super(a, b, c); - _4 = d; + a4 = d; } - @Override - public String rep() { - return super.rep() + ", " + _4; + @Override public String rep() { + return super.rep() + ", " + a4; } } diff --git a/onjava/Tuple5.java b/onjava/Tuple5.java index b4dc16c53..85a3d2d06 100644 --- a/onjava/Tuple5.java +++ b/onjava/Tuple5.java @@ -1,18 +1,17 @@ // onjava/Tuple5.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package onjava; public class Tuple5 extends Tuple4 { - public final E _5; + public final E a5; public Tuple5(A a, B b, C c, D d, E e) { super(a, b, c, d); - _5 = e; + a5 = e; } - @Override - public String rep() { - return super.rep() + ", " + _5; + @Override public String rep() { + return super.rep() + ", " + a5; } } diff --git a/onjava/TypeCounter.java b/onjava/TypeCounter.java index f94a8bd49..6e89067bc 100644 --- a/onjava/TypeCounter.java +++ b/onjava/TypeCounter.java @@ -1,10 +1,11 @@ // onjava/TypeCounter.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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> { @@ -25,20 +26,16 @@ private void countClass(Class type) { put(type, quantity == null ? 1 : quantity + 1); Class superClass = type.getSuperclass(); if(superClass != null && - baseType.isAssignableFrom(superClass)) + baseType.isAssignableFrom(superClass)) { countClass(superClass); - } - @Override - public String toString() { - StringBuilder result = new StringBuilder("{"); - for(Map.Entry, Integer> pair : entrySet()) { - result.append(pair.getKey().getSimpleName()); - result.append("="); - result.append(pair.getValue()); - result.append(", "); } - result.delete(result.length() - 2, result.length()); - result.append("}"); - return result.toString(); + } + @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/onjava/atunit/AtUnit.java b/onjava/atunit/AtUnit.java index 569132fb5..976010884 100644 --- a/onjava/atunit/AtUnit.java +++ b/onjava/atunit/AtUnit.java @@ -1,8 +1,9 @@ // onjava/atunit/AtUnit.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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.*; @@ -19,7 +20,7 @@ public class AtUnit implements ProcessFiles.Strategy { public static void main(String[] args) throws Exception { ClassLoader.getSystemClassLoader() - .setDefaultAssertionStatus(true); // Enable asserts + .setDefaultAssertionStatus(true); // Enable assert new ProcessFiles(new AtUnit(), "class").start(args); if(failures == 0) System.out.println("OK (" + testsRun + " tests)"); @@ -32,8 +33,7 @@ public class AtUnit implements ProcessFiles.Strategy { System.out.println(" " + failed); } } - @Override - public void process(File cFile) { + @Override public void process(File cFile) { try { String cName = ClassNameFinder.thisClass( Files.readAllBytes(cFile.toPath())); @@ -60,13 +60,14 @@ public void process(File cFile) { if(creator == null) try { if(!Modifier.isPublic(testClass - .getDeclaredConstructor().getModifiers())) { + .getDeclaredConstructor() + .getModifiers())) { System.out.println("Error: " + testClass + - " no-arg constructor must be public"); + " zero-argument constructor must be public"); System.exit(1); } } catch(NoSuchMethodException e) { - // Synthesized no-arg constructor; OK + // Synthesized zero-argument constructor; OK } System.out.println(testClass.getName()); } @@ -111,11 +112,12 @@ void addIfTestMethod(Method m) { m.getReturnType().equals(void.class))) throw new RuntimeException("@Test method" + " must return boolean or void"); - m.setAccessible(true); // In case it's private, etc. + m.setAccessible(true); // If it's private, etc. add(m); } } - private static Method checkForCreatorMethod(Method m) { + private static + Method checkForCreatorMethod(Method m) { if(m.getAnnotation(TestObjectCreate.class) == null) return null; if(!m.getReturnType().equals(testClass)) @@ -128,7 +130,8 @@ private static Method checkForCreatorMethod(Method m) { m.setAccessible(true); return m; } - private static Method checkForCleanupMethod(Method m) { + private static + Method checkForCleanupMethod(Method m) { if(m.getAnnotation(TestObjectCleanup.class) == null) return null; if(!m.getReturnType().equals(void.class)) @@ -145,7 +148,8 @@ private static Method checkForCleanupMethod(Method m) { m.setAccessible(true); return m; } - private static Object createTestObject(Method creator) { + private static Object + createTestObject(Method creator) { if(creator != null) { try { return creator.invoke(testClass); @@ -155,13 +159,17 @@ private static Object createTestObject(Method creator) { throw new RuntimeException("Couldn't run " + "@TestObject (creator) method."); } - } else { // Use the no-arg constructor: + } else { // Use the zero-argument constructor: try { - return testClass.newInstance(); + return testClass + .getConstructor().newInstance(); } catch(InstantiationException | + NoSuchMethodException | + InvocationTargetException | IllegalAccessException e) { - throw new RuntimeException("Couldn't create a " + - "test object. Try using a @TestObject method."); + throw new RuntimeException( + "Couldn't create a test object. " + + "Try using a @TestObject method."); } } } diff --git a/onjava/atunit/ClassNameFinder.java b/onjava/atunit/ClassNameFinder.java index d4c0d7d57..315a44c5f 100644 --- a/onjava/atunit/ClassNameFinder.java +++ b/onjava/atunit/ClassNameFinder.java @@ -1,7 +1,8 @@ // onjava/atunit/ClassNameFinder.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {java onjava.atunit.ClassNameFinder} package onjava.atunit; import java.io.*; import java.nio.file.*; @@ -11,16 +12,17 @@ public class ClassNameFinder { public static String thisClass(byte[] classBytes) { Map offsetTable = new HashMap<>(); - Map classNameTable = 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 constant_pool_count = data.readShort(); - int[] constant_pool = new int[constant_pool_count]; - for(int i = 1; i < constant_pool_count; i++) { + int constantPoolCount = data.readShort(); + int[] constantPool = new int[constantPoolCount]; + for(int i = 1; i < constantPoolCount; i++) { int tag = data.read(); // int tableSize; switch(tag) { @@ -51,7 +53,7 @@ public static String thisClass(byte[] classBytes) { case 11: // INTERFACE_METHOD_REF case 12: // NAME_AND_TYPE case 18: // Invoke Dynamic - data.readInt(); // discard 4 bytes; + data.readInt(); // discard 4 bytes break; case 15: // Method Handle data.readByte(); @@ -61,16 +63,17 @@ public static String thisClass(byte[] classBytes) { data.readShort(); break; default: - throw new RuntimeException("Bad tag " + tag); + throw + new RuntimeException("Bad tag " + tag); } } - short access_flags = data.readShort(); - String access = (access_flags & 0x0001) == 0 ? + short accessFlags = data.readShort(); + String access = (accessFlags & 0x0001) == 0 ? "nonpublic:" : "public:"; - int this_class = data.readShort(); - int super_class = data.readShort(); + int thisClass = data.readShort(); + int superClass = data.readShort(); return access + classNameTable.get( - offsetTable.get(this_class)).replace('/', '.'); + offsetTable.get(thisClass)).replace('/', '.'); } catch(IOException | RuntimeException e) { throw new RuntimeException(e); } @@ -83,7 +86,6 @@ public static String thisClass(byte[] classBytes) { // Walk the entire tree: Files.walk(Paths.get(".")) .filter(matcher::matches) - //.peek(System.out::println) .map(p -> { try { return thisClass(Files.readAllBytes(p)); @@ -100,6 +102,7 @@ public static String thisClass(byte[] classBytes) { } } /* Output: +onjava.ArrayShow onjava.atunit.AtUnit$TestMethods onjava.atunit.AtUnit onjava.atunit.ClassNameFinder @@ -107,4 +110,71 @@ public static String thisClass(byte[] classBytes) { 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/onjava/atunit/Test.java b/onjava/atunit/Test.java index 4946c4c56..ff7b10b9d 100644 --- a/onjava/atunit/Test.java +++ b/onjava/atunit/Test.java @@ -1,7 +1,7 @@ // onjava/atunit/Test.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // The @Test tag package onjava.atunit; import java.lang.annotation.*; diff --git a/onjava/atunit/TestObjectCleanup.java b/onjava/atunit/TestObjectCleanup.java index 35c6b019c..c15a0e1a1 100644 --- a/onjava/atunit/TestObjectCleanup.java +++ b/onjava/atunit/TestObjectCleanup.java @@ -1,7 +1,7 @@ // onjava/atunit/TestObjectCleanup.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // The @Unit @TestObjectCleanup tag package onjava.atunit; import java.lang.annotation.*; diff --git a/onjava/atunit/TestObjectCreate.java b/onjava/atunit/TestObjectCreate.java index 8b7271b29..58cf17f9c 100644 --- a/onjava/atunit/TestObjectCreate.java +++ b/onjava/atunit/TestObjectCreate.java @@ -1,7 +1,7 @@ // onjava/atunit/TestObjectCreate.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // The @Unit @TestObjectCreate tag package onjava.atunit; import java.lang.annotation.*; diff --git a/onjava/atunit/TestProperty.java b/onjava/atunit/TestProperty.java index d13fd5a11..bbb685adb 100644 --- a/onjava/atunit/TestProperty.java +++ b/onjava/atunit/TestProperty.java @@ -1,7 +1,7 @@ // onjava/atunit/TestProperty.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // The @Unit @TestProperty tag package onjava.atunit; import java.lang.annotation.*; diff --git a/onjava/build.xml b/onjava/build.xml deleted file mode 100644 index d224e4aec..000000000 --- a/onjava/build.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/operators/AllOps.java b/operators/AllOps.java index b0afec165..d48e82af1 100644 --- a/operators/AllOps.java +++ b/operators/AllOps.java @@ -1,12 +1,12 @@ // operators/AllOps.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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: + // To accept the results of a Boolean test: void f(boolean b) {} void boolTest(boolean x, boolean y) { // Arithmetic operators: @@ -67,8 +67,8 @@ void charTest(char x, char y) { x = (char)(x - y); x++; x--; - x = (char)+y; - x = (char)-y; + x = (char) + y; + x = (char) - y; // Relational and logical: f(x > y); f(x >= y); @@ -117,8 +117,8 @@ void byteTest(byte x, byte y) { x = (byte)(x - y); x++; x--; - x = (byte)+ y; - x = (byte)- y; + x = (byte) + y; + x = (byte) - y; // Relational and logical: f(x > y); f(x >= y); @@ -167,8 +167,8 @@ void shortTest(short x, short y) { x = (short)(x - y); x++; x--; - x = (short)+y; - x = (short)-y; + x = (short) + y; + x = (short) - y; // Relational and logical: f(x > y); f(x >= y); @@ -180,7 +180,7 @@ void shortTest(short x, short y) { //- f(x && y); //- f(x || y); // Bitwise operators: - x = (short)~y; + x = (short) ~ y; x = (short)(x & y); x = (short)(x | y); x = (short)(x ^ y); diff --git a/operators/Assignment.java b/operators/Assignment.java index 9e57fbb6d..c4b9a793e 100644 --- a/operators/Assignment.java +++ b/operators/Assignment.java @@ -1,7 +1,7 @@ // operators/Assignment.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Assignment with objects is a bit tricky class Tank { diff --git a/operators/AutoInc.java b/operators/AutoInc.java index ee1ad5878..bcb090935 100644 --- a/operators/AutoInc.java +++ b/operators/AutoInc.java @@ -1,27 +1,27 @@ // operators/AutoInc.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Demonstrates the ++ and -- operators +// Visit http://OnJava8.com for more book information. +// 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); + 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 +i: 1 +++i: 2 +i++: 2 +i: 3 +--i: 2 +i--: 2 +i: 1 */ diff --git a/operators/BitManipulation.java b/operators/BitManipulation.java index 5541c9c23..80c64c93b 100644 --- a/operators/BitManipulation.java +++ b/operators/BitManipulation.java @@ -1,7 +1,7 @@ // operators/BitManipulation.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Using the bitwise operators import java.util.*; diff --git a/operators/Bool.java b/operators/Bool.java index e2b885a55..42668315b 100644 --- a/operators/Bool.java +++ b/operators/Bool.java @@ -1,7 +1,7 @@ // operators/Bool.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Relational and logical operators import java.util.*; diff --git a/operators/Casting.java b/operators/Casting.java index ed2bf7164..22b2b221c 100644 --- a/operators/Casting.java +++ b/operators/Casting.java @@ -1,7 +1,7 @@ // operators/Casting.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class Casting { public static void main(String[] args) { diff --git a/operators/CastingNumbers.java b/operators/CastingNumbers.java index 0f37c7d4d..007dc4e2c 100644 --- a/operators/CastingNumbers.java +++ b/operators/CastingNumbers.java @@ -1,7 +1,7 @@ // operators/CastingNumbers.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // What happens when you cast a float // or double to an integral value? diff --git a/operators/DoubleEquivalence.java b/operators/DoubleEquivalence.java new file mode 100644 index 000000000..5f06e25f5 --- /dev/null +++ b/operators/DoubleEquivalence.java @@ -0,0 +1,49 @@ +// operators/DoubleEquivalence.java +// (c)2021 MindView 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 DoubleEquivalence { + static void show(String desc, Double n1, Double n2) { + System.out.println(desc + ":"); + System.out.printf( + "%e==%e %b %b%n", n1, n2, n1 == n2, n1.equals(n2)); + } + @SuppressWarnings("deprecation") + public static void test(double x1, double x2) { + // x1.equals(x2) // Won't compile + System.out.printf("%e==%e %b%n", x1, x2, x1 == x2); + Double d1 = x1; + Double d2 = x2; + show("Automatic", d1, d2); + Double r1 = new Double(x1); + Double r2 = new Double(x2); + show("new Double()", r1, r2); + Double v1 = Double.valueOf(x1); + Double v2 = Double.valueOf(x2); + show("Double.valueOf()", v1, v2); + } + public static void main(String[] args) { + test(0, Double.MIN_VALUE); + System.out.println("------------------------"); + test(Double.MAX_VALUE, + Double.MAX_VALUE - Double.MIN_VALUE * 1_000_000); + } +} +/* Output: +0.000000e+00==4.900000e-324 false +Automatic: +0.000000e+00==4.900000e-324 false false +new Double(): +0.000000e+00==4.900000e-324 false false +Double.valueOf(): +0.000000e+00==4.900000e-324 false false +------------------------ +1.797693e+308==1.797693e+308 true +Automatic: +1.797693e+308==1.797693e+308 false true +new Double(): +1.797693e+308==1.797693e+308 false true +Double.valueOf(): +1.797693e+308==1.797693e+308 false true +*/ diff --git a/operators/EqualsMethod.java b/operators/EqualsMethod.java index fbdb099c6..2f281aeb5 100644 --- a/operators/EqualsMethod.java +++ b/operators/EqualsMethod.java @@ -1,15 +1,35 @@ // operators/EqualsMethod.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// Default equals() does not compare contents + +class ValA { + int i; +} + +class ValB { + int i; + // Works for this example, not a complete equals(): + public boolean equals(Object o) { + ValB rval = (ValB)o; // Cast o to be a ValB + return i == rval.i; + } +} public class EqualsMethod { public static void main(String[] args) { - Integer n1 = new Integer(47); - Integer n2 = new Integer(47); - System.out.println(n1.equals(n2)); + ValA va1 = new ValA(); + ValA va2 = new ValA(); + va1.i = va2.i = 100; + System.out.println(va1.equals(va2)); + ValB vb1 = new ValB(); + ValB vb2 = new ValB(); + vb1.i = vb2.i = 100; + System.out.println(vb1.equals(vb2)); } } /* Output: +false true */ diff --git a/operators/EqualsMethod2.java b/operators/EqualsMethod2.java deleted file mode 100644 index 2c4f81961..000000000 --- a/operators/EqualsMethod2.java +++ /dev/null @@ -1,21 +0,0 @@ -// operators/EqualsMethod2.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ 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/operators/Equivalence.java b/operators/Equivalence.java index e9fdcc701..dafc49524 100644 --- a/operators/Equivalence.java +++ b/operators/Equivalence.java @@ -1,17 +1,54 @@ // operators/Equivalence.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class Equivalence { + static void show(String desc, Integer n1, Integer n2) { + System.out.println(desc + ":"); + System.out.printf( + "%d==%d %b %b%n", n1, n2, n1 == n2, n1.equals(n2)); + } + @SuppressWarnings("deprecation") + public static void test(int value) { + Integer i1 = value; // [1] + Integer i2 = value; + show("Automatic", i1, i2); + // Old way, deprecated since Java 9: + Integer r1 = new Integer(value); // [2] + Integer r2 = new Integer(value); + show("new Integer()", r1, r2); + // Preferred since Java 9: + Integer v1 = Integer.valueOf(value); // [3] + Integer v2 = Integer.valueOf(value); + show("Integer.valueOf()", v1, v2); + // Primitives can't use equals(): + int x = value; // [4] + int y = value; + // x.equals(y); // Doesn't compile + System.out.println("Primitive int:"); + System.out.printf("%d==%d %b%n", x, y, x == y); + } public static void main(String[] args) { - Integer n1 = new Integer(47); - Integer n2 = new Integer(47); - System.out.println(n1 == n2); - System.out.println(n1 != n2); + test(127); + test(128); } } /* Output: -false -true +Automatic: +127==127 true true +new Integer(): +127==127 false true +Integer.valueOf(): +127==127 true true +Primitive int: +127==127 true +Automatic: +128==128 false true +new Integer(): +128==128 false true +Integer.valueOf(): +128==128 false true +Primitive int: +128==128 true */ diff --git a/operators/Exponents.java b/operators/Exponents.java index 4881b6f3d..8578aee51 100644 --- a/operators/Exponents.java +++ b/operators/Exponents.java @@ -1,7 +1,7 @@ // operators/Exponents.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // "e" means "10 to the power." public class Exponents { diff --git a/operators/Literals.java b/operators/Literals.java index 35947e41d..67232c222 100644 --- a/operators/Literals.java +++ b/operators/Literals.java @@ -1,7 +1,7 @@ // operators/Literals.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class Literals { public static void main(String[] args) { @@ -17,14 +17,14 @@ public static void main(String[] args) { char c = 0xffff; // max char hex value System.out.println( "c: " + Integer.toBinaryString(c)); - byte b = 0x7f; // max byte hex value 10101111; + byte b = 0x7f; // max byte hex value 0111111; 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 (but can be confusing) + long n2 = 200l; // long suffix (can be confusing) long n3 = 200; // Java 7 Binary Literals: byte blb = (byte)0b00110101; diff --git a/operators/MathOps.java b/operators/MathOps.java index a75fd84a9..125b312b8 100644 --- a/operators/MathOps.java +++ b/operators/MathOps.java @@ -1,7 +1,7 @@ // operators/MathOps.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // The mathematical operators import java.util.*; diff --git a/operators/Overflow.java b/operators/Overflow.java index 4e75edcda..68e494490 100644 --- a/operators/Overflow.java +++ b/operators/Overflow.java @@ -1,7 +1,7 @@ // operators/Overflow.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Surprise! Java lets you overflow public class Overflow { diff --git a/operators/PassObject.java b/operators/PassObject.java index f1e9564f2..698771a8d 100644 --- a/operators/PassObject.java +++ b/operators/PassObject.java @@ -1,7 +1,7 @@ // operators/PassObject.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Passing objects to methods might not be // what you're used to diff --git a/operators/Precedence.java b/operators/Precedence.java index 8d3f95bd7..e6dcc549c 100644 --- a/operators/Precedence.java +++ b/operators/Precedence.java @@ -1,13 +1,13 @@ // operators/Precedence.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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) + 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); } diff --git a/operators/RoundingNumbers.java b/operators/RoundingNumbers.java index c98d62813..e7396c113 100644 --- a/operators/RoundingNumbers.java +++ b/operators/RoundingNumbers.java @@ -1,7 +1,7 @@ // operators/RoundingNumbers.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Rounding floats and doubles public class RoundingNumbers { diff --git a/operators/ShortCircuit.java b/operators/ShortCircuit.java index 3f58f82e2..8e611d469 100644 --- a/operators/ShortCircuit.java +++ b/operators/ShortCircuit.java @@ -1,7 +1,7 @@ // operators/ShortCircuit.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Short-circuiting behavior with logical operators public class ShortCircuit { diff --git a/operators/StringOperators.java b/operators/StringOperators.java index d247f9b88..c83387f9e 100644 --- a/operators/StringOperators.java +++ b/operators/StringOperators.java @@ -1,7 +1,7 @@ // operators/StringOperators.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class StringOperators { public static void main(String[] args) { diff --git a/operators/TernaryIfElse.java b/operators/TernaryIfElse.java index 83ad41e51..51455aa74 100644 --- a/operators/TernaryIfElse.java +++ b/operators/TernaryIfElse.java @@ -1,7 +1,7 @@ // operators/TernaryIfElse.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class TernaryIfElse { static int ternary(int i) { diff --git a/operators/URShift.java b/operators/URShift.java index e2ae68ddf..7596408cd 100644 --- a/operators/URShift.java +++ b/operators/URShift.java @@ -1,7 +1,7 @@ // operators/URShift.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Test of unsigned right shift public class URShift { @@ -30,8 +30,7 @@ public static void main(String[] args) { /* Output: 11111111111111111111111111111111 1111111111111111111111 -11111111111111111111111111111111111111111111111111111111111 -11111 +1111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111 11111111111111111111111111111111 diff --git a/operators/Underscores.java b/operators/Underscores.java index 36b6625c0..fa1394893 100644 --- a/operators/Underscores.java +++ b/operators/Underscores.java @@ -1,7 +1,7 @@ // operators/Underscores.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class Underscores { public static void main(String[] args) { @@ -9,9 +9,9 @@ public static void main(String[] args) { 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); + System.out.printf("%x%n", bin); // [1] long hex = 0x7f_e9_b7_aa; - System.out.printf("%x\n", hex); + System.out.printf("%x%n", hex); } } /* Output: diff --git a/operators/build.xml b/operators/build.xml deleted file mode 100644 index f24e3023c..000000000 --- a/operators/build.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/output_duet.py b/output_duet.py deleted file mode 100644 index d7a8f3b9b..000000000 --- a/output_duet.py +++ /dev/null @@ -1,365 +0,0 @@ -# Requires Python 3.5 or greater -# (c)2016 MindView LLC: see Copyright.txt -# We make no guarantees that this code is fit for any purpose. -# Visit http://mindviewinc.com/Books/OnJava/ for more book information. -""" -ToDo: - - Right now it's ignoring the "(first x lines)" examples -""" -import sys -from pathlib import Path -import re -import textwrap -from enum import Enum, unique - -def trace(str): pass -# trace = print - -maxlinewidth = 59 -current_dir_name = Path.cwd().stem - -word_only = re.compile("[A-Za-z]+") - -def trim(block): - trimmed = "\n".join([ln.rstrip() for ln in block.splitlines()]) - return trimmed.strip() - -class Adjuster: - def adjust(self, input_text): pass - -class IgnoreDigits(Adjuster): - def adjust(self, input_text): - trace("Ignoring digits") - return trim(re.sub("-?\d", "", input_text)) - -ignore_digits = IgnoreDigits() - -class IgnoreMemoryAddresses(Adjuster): - def adjust(self, input_text): - return trim(memlocation.sub("", input_text)) - -ignore_memory_addresses = IgnoreMemoryAddresses() - -class RemoveCharacters(Adjuster): - def __init__(self, chars_to_remove): - self.chars_to_remove = chars_to_remove - def adjust(self, input_text): - for c in self.chars_to_remove: - input_text = input_text.replace(c, "") - return input_text - -class SortLines(Adjuster): - def adjust(self, input_text): - return "\n".join(sorted(input_text.splitlines())).strip() - -sort_lines = SortLines() - -class SortWords(Adjuster): - def adjust(self, input_text): - return "\n".join(sorted(input_text.split())).strip() - -sort_words = SortWords() - -class UniqueLines(Adjuster): - def adjust(self, input_text): - return "\n".join(sorted(list(set(input_text.splitlines())))) - -unique_lines = UniqueLines() - -class UniqueWords(Adjuster): - # Fairly extreme but will still reveal significant changes - def adjust(self, input_text): - return "\n".join(sorted(set(input_text.split()))) - -unique_words = UniqueWords() - -class WordsOnly(Adjuster): - # Fairly extreme but will still reveal significant changes - def adjust(self, input_text): - return "\n".join( - sorted([w for w in input_text.split() - if word_only.fullmatch(w)])) - -words_only = WordsOnly() - -class IgnoreLines(Adjuster): - def __init__(self, *lines_to_ignore): - self.lines_to_ignore = lines_to_ignore - def adjust(self, input_text): - lines = input_text.splitlines() - for ignore in sorted(list(self.lines_to_ignore), reverse=True): - ignore = ignore - 1 # Compensate for zero indexing - print("ignoring line %d: %s" % (ignore, lines[ignore])) - del lines[ignore] - return "\n".join(lines) - - -match_adjustments = { - "ToastOMatic.java" : sort_lines, - "ThreadVariations.java" : sort_lines, - "ActiveObjectDemo.java" : [sort_lines, ignore_digits], - "Interrupting.java" : sort_lines, - "SyncObject.java" : sort_lines, - "UseCaseTracker.java" : sort_lines, - "AtUnitComposition.java" : sort_lines, - "AtUnitExample1.java" : sort_lines, - "AtUnitExample2.java" : sort_lines, - "AtUnitExample3.java" : sort_lines, - "AtUnitExample5.java" : sort_lines, - "AtUnitExternalTest.java" : sort_lines, - "HashSetTest.java" : sort_lines, - "StackLStringTest.java" : sort_lines, - "WaxOMatic2.java" : sort_lines, - - "ForEach.java" : sort_words, - "PetCount4.java" : [RemoveCharacters("{}"), sort_words], - - "CachedThreadPool.java" : words_only, - "FixedThreadPool.java" : words_only, - "MoreBasicThreads.java" : words_only, - "ConstantSpecificMethod.java" : words_only, - - "BankTellerSimulation.java" : [words_only, unique_words], - - "MapComparisons.java" : ignore_digits, - "ListComparisons.java" : ignore_digits, - "NotifyVsNotifyAll.java" : ignore_digits, - "SelfManaged.java" : ignore_digits, - "SimpleMicroBenchmark.java" : ignore_digits, - "SimpleThread.java" : ignore_digits, - "SleepingTask.java" : ignore_digits, - "ExchangerDemo.java" : ignore_digits, - "Compete.java" : ignore_digits, - "MappedIO.java" : ignore_digits, - "Directories.java" : ignore_digits, - "Find.java" : ignore_digits, - "PathAnalysis.java" : ignore_digits, - "TreeWatcher.java" : ignore_digits, - "Mixins.java" : ignore_digits, - "ListPerformance.java" : ignore_digits, - "MapPerformance.java" : ignore_digits, - "SetPerformance.java" : ignore_digits, - "SynchronizationComparisons.java" : ignore_digits, - "AtomicityTest.java" : ignore_digits, - "TypesForSets.java" : ignore_digits, - "PrintableLogRecord.java" : ignore_digits, - "LockingMappedFiles.java" : ignore_digits, - - - "Conversion.java" : IgnoreLines(27, 28), - "DynamicProxyMixin.java" : IgnoreLines(2), - "PreferencesDemo.java" : IgnoreLines(5), - "AtUnitExample4.java" : IgnoreLines(6, 9), - - "SerialNumberChecker.java" : [ignore_digits, unique_lines], - "EvenSupplier.java" : [ignore_digits, unique_lines], - - "FillingLists.java" : [ ignore_memory_addresses, sort_words ], - - "SimpleDaemons.java" : [ ignore_memory_addresses, ignore_digits ], - "CaptureUncaughtException.java" : [ - ignore_memory_addresses, ignore_digits, unique_lines ], - - "CarBuilder.java" : [ ignore_digits, unique_lines ], - "CloseResource.java" : [ unique_lines ], - - "SpringDetector.java" : [ ignore_digits, sort_words ], - - "PipedIO.java" : [ unique_words ], - - "CriticalSection.java" : ignore_digits, - "ExplicitCriticalSection.java" : ignore_digits, -} - - -translate_file_name = { - "ApplyTest.java": "Apply.java", - "FillTest.java": "Fill.java", - "Fill2Test.java": "Fill2.java", - "ClassInInterface$Test.java": "ClassInInterface.java", - "TestBed$Tester.java": "TestBed.java", -} - - -memlocation = re.compile("@[0-9a-z]{5,7}") -datestamp1 = re.compile("(?:[MTWFS][a-z]{2} ){0,1}[JFMASOND][a-z]{2} \d{1,2} \d{2}:\d{2}:\d{2} [A-Z]{3} \d{4}") -datestamp2 = re.compile("[JFMASOND][a-z]{2} \d{1,2}, \d{4} \d{1,2}:\d{1,2}:\d{1,2} (:?AM|PM)") -varying = [ memlocation, datestamp1, datestamp2 ] - - -# Result of Duet.validate(): -Valid = Enum('Valid', - 'exact varying execute_to_see selected_lines fail') - - -class Duet: - """ - Holds embedded and generated output. Also original file content, and - "adjusted" output for comparison. - """ - - def __init__(self, out_filename): - - if not (out_filename.suffix == ".out" or - out_filename.suffix == ".err" or - out_filename.suffix == ".new"): - print("Error: argument to Duet() must end with '.out' or '.err' or '.new'") - print("Argument was {}".format(out_filename)) - sys.exit() - - self.java_file = None # Full contents of Java code file - self.java_slugline = None # First (marker) line of Java code file - - self.out_path = out_filename.with_suffix(".out") - self.out = None - self.generated = "" - if self.out_path.exists(): - self.out = self.out_path.read_text().strip() - trace("{} file exists".format(self.out_path)) - self.generated = self.fill_to_width(self.out) - - self.error = False - self.err_path = out_filename.with_suffix(".err") - if self.err_path.exists(): - self.error = True - self.generated += "\n___[ Error Output ]___\n" - self.generated += self.fill_to_width(self.err_path.read_text()) - trace("{} file exists".format(self.err_path)) - - self.new = None - self.new_path = out_filename.with_suffix(".new") - if self.new_path.exists(): - self.new = self.new_path.read_text().strip() - print("{} file exists".format(self.new_path)) - - self.java_path = self.calculate_java_path() - # This also fills self.java_file and self.java_slugline: - self.embedded = self.embedded_output() - - self.ignore = False - if "{IgnoreOutput}" in self.java_file: - self.ignore = True - trace("Ignoring .out for {}".format(self.java_path)) - return - - if "{ThrowsException}" in self.java_file: - self.generated = self.generated.strip() + "\n___[ Exception is Expected ]___" - trace("Exception expected for {}".format(self.java_path)) - - if "{ErrorOutputExpected}" in self.java_file: - self.generated = self.generated.strip() + "\n___[ Error Output is Expected ]___" - trace("OK: 'Error Output' expected for {}".format(self.java_path)) - - self.embedded_adjusted = self.adjust(self.embedded) - self.generated_un_adjusted = self.generated - self.generated_adjusted = None - if self.generated: - self.generated_adjusted = self.adjust(self.generated) - - def calculate_java_path(self): - - def __java_filename(out_pieces): - path_components = out_pieces.split(".", out_pieces.count(".") - 1) - # path_components[-1] = path_components[-1].replace(".out", ".java") - # path_components[-1] = path_components[-1].replace(".err", ".java") - return path_components - - _java_path = self.out_path.with_suffix(".java") - jfn = __java_filename(_java_path.parts[-1]) - # jfn = __java_filename(self.out_path.parts[-1]) - jpath = list(self.out_path.parts[:-1]) + list(jfn) - if len(jpath) > 1 and jpath[0] == jpath[1]: - del jpath[0] - if jpath[0] == current_dir_name: - del jpath[0] - if jpath[-1] in translate_file_name: - jpath[-1] = translate_file_name[jpath[-1]] - return Path(*jpath) - - - def embedded_output(self): - find_output = re.compile(r"/\* (Output:.*)\*/", re.DOTALL) # should space be \s+ ?? - with self.java_path.open() as java: - self.java_file = java.read() - self.java_slugline = self.java_file.strip().splitlines()[0] - output = find_output.search(self.java_file) - if not output: - trace("No embedded output: in {}".format(self.java_path)) - return None - lines = output.group(1).strip().splitlines() - self.output_tag = lines[0] - return ("\n".join(lines[1:])).strip() - - - @staticmethod - def fill_to_width(text): - result = "" - for line in text.splitlines(): - result += textwrap.fill(line, width=maxlinewidth) + "\n" - return result.strip() - - - def __repr__(self): - # result = "\n" + str(self.output_tag) - result = "\n" + str(self.java_path).center(60, "=") + "\n" + self.embedded - result += "\n" + str(self.out_path).center(60, "-") + "\n" + self.generated - result += "\n" + (str(self.java_path) + - "(adjusted)").center(60, "-") + "\n" + str(self.embedded_adjusted) - result += "\n" + (str(self.out_path) + - "(adjusted)").center(60, "-") + "\n" + str(self.generated_adjusted) - - difflines = [] - embedded_adjusted_lines = self.embedded_adjusted.splitlines() - generated_adjusted_lines = self.generated_adjusted.splitlines() - trace(str(self.java_path)) - trace("len embedded_adjusted %d len generated_adjusted %d" % - (len(embedded_adjusted_lines), len(generated_adjusted_lines))) - for n, line in enumerate(embedded_adjusted_lines): - try: - if not line == generated_adjusted_lines[n]: - difflines.append(">--------<") - difflines.append("embedded_adjusted: " + line) - difflines.append("generated_adjusted: " + generated_adjusted_lines[n]) - except: - continue - if difflines: - result += "\n" + "\n".join(difflines) - - return result - - - @staticmethod - def strip_varying(text): - for pat in varying: - text = pat.sub("", text) - return text - - - def adjust(self, output): - output = output.replace("\0", "NUL") - if self.java_path.name not in match_adjustments: - return output - trace("adjusting %s" % self.java_path.name) - strategy = match_adjustments[self.java_path.name] - if isinstance(strategy, Adjuster): - return strategy.adjust(output) - assert isinstance(strategy, list) - for strat in strategy: - output = strat.adjust(output) - return output - - - def validate(self): - if "(Execute to see)" in self.output_tag: - return Valid.execute_to_see - if "(None)" in self.output_tag: ### This should no longer be necessary - assert false, "(None) in output_tag " + self - if "Output: (First" in self.output_tag: ### This is temporary ### - return Valid.selected_lines - if self.generated_adjusted == self.embedded_adjusted: - return Valid.exact - if isinstance(self.generated_adjusted, str): - if (Duet.strip_varying(self.generated_adjusted) == - Duet.strip_varying(self.embedded_adjusted)): - return Valid.varying - return Valid.fail diff --git a/patterns/BoxObserver.java b/patterns/BoxObserver.java new file mode 100644 index 000000000..b48120bc1 --- /dev/null +++ b/patterns/BoxObserver.java @@ -0,0 +1,84 @@ +// patterns/BoxObserver.java +// (c)2021 MindView 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 the 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; + +@SuppressWarnings("deprecation") +class Boxes extends JFrame { + Observable notifier = new Observable() { + @Override + public void notifyObservers(Object b) { + setChanged(); + super.notifyObservers(b); + } + }; + public Boxes(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 Box(x, y, notifier)); + setSize(500, 400); + setVisible(true); + setDefaultCloseOperation(DISPOSE_ON_CLOSE); + } +} + +@SuppressWarnings("deprecation") +class Box extends JPanel implements Observer { + int x, y; // Location in grid + Color color = COLORS[ + (int)(Math.random() * COLORS.length) + ]; + 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 + }; + Box(int x, int y, Observable notifier) { + this.x = x; + this.y = y; + notifier.addObserver(this); + addMouseListener((MouseClick) + e -> notifier.notifyObservers(Box.this)); + } + @Override public void paintComponent(Graphics g) { + super.paintComponent(g); + g.setColor(color); + Dimension s = getSize(); + g.fillRect(0, 0, s.width, s.height); + } + @Override + public void update(Observable o, Object arg) { + Box clicked = (Box)arg; + if(nextTo(clicked)) { + color = clicked.color; + repaint(); + } + } + private boolean nextTo(Box b) { + return Math.abs(x - b.x) <= 1 && + Math.abs(y - b.y) <= 1; + } +} + +public class BoxObserver { + public static void main(String[] args) { + int grid = 8; + if(args.length > 0) + grid = Integer.parseInt(args[0]); + new Boxes(grid); + } +} diff --git a/patterns/CleanTheFloor.java b/patterns/CleanTheFloor.java new file mode 100644 index 000000000..8196f44bd --- /dev/null +++ b/patterns/CleanTheFloor.java @@ -0,0 +1,42 @@ +// patterns/CleanTheFloor.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// State with different compositional interface. + +class FloorCleaner { + private Attachment attachment = new Vacuum(); + public void change(Attachment newAttachment) { + attachment = newAttachment; + } + public void clean() { attachment.action(); } +} + +interface Attachment { + void action(); +} + +class Vacuum implements Attachment { + @Override public void action() { + System.out.println("Vacuuming"); + } +} + +class Mop implements Attachment { + @Override public void action() { + System.out.println("Mopping"); + } +} + +public class CleanTheFloor { + public static void main(String[] args) { + FloorCleaner floorCleaner = new FloorCleaner(); + floorCleaner.clean(); + floorCleaner.change(new Mop()); + floorCleaner.clean(); + } +} +/* Output: +Vacuuming +Mopping +*/ diff --git a/patterns/CommandPattern.java b/patterns/CommandPattern.java index 774d9d849..05bc61202 100644 --- a/patterns/CommandPattern.java +++ b/patterns/CommandPattern.java @@ -1,19 +1,26 @@ // patterns/CommandPattern.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; +class Command { + public final String msg; + public Command(String msg) { + this.msg = msg; + } +} + public class CommandPattern { + public static void show(Command cmd) { + System.out.println(cmd.msg); + } 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); + show(new Command("First Command")); + show(new Command("Second Command")); } } /* Output: -Hello World! I'm the command pattern! +First Command +Second Command */ diff --git a/patterns/Facade.java b/patterns/Facade.java index 606324a2e..e290cff43 100644 --- a/patterns/Facade.java +++ b/patterns/Facade.java @@ -1,11 +1,11 @@ // patterns/Facade.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. -class A { public A(int x) {} } -class B { public B(long x) {} } -class C { public C(double x) {} } +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 ... diff --git a/patterns/Macro.java b/patterns/Macro.java new file mode 100644 index 000000000..586b128ea --- /dev/null +++ b/patterns/Macro.java @@ -0,0 +1,25 @@ +// patterns/Macro.java +// (c)2021 MindView LLC: see Copyright.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 Macro { + public static void main(String[] args) { + List macro = new ArrayList<>( + Arrays.asList( + () -> System.out.print("Hello "), + () -> System.out.println("World! ") + )); + macro.forEach(Runnable::run); + macro.add( + () -> System.out.print("I'm the command pattern!") + ); + macro.forEach(Runnable::run); + } +} +/* Output: +Hello World! +Hello World! +I'm the command pattern! +*/ diff --git a/patterns/PaperScissorsRock.java b/patterns/PaperScissorsRock.java index 79a182fc2..478ac6755 100644 --- a/patterns/PaperScissorsRock.java +++ b/patterns/PaperScissorsRock.java @@ -1,94 +1,29 @@ // patterns/PaperScissorsRock.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Demonstration of multiple dispatching +// Visit http://OnJava8.com for more book information. +// Demonstration of multiple dispatching. import java.util.*; import java.util.function.*; import java.util.stream.*; +import enums.Outcome; +import static enums.Outcome.*; +import enums.Item; +import enums.Paper; +import enums.Scissors; +import enums.Rock; 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); - final static int sz = items.size(); - private static SplittableRandom rand = new SplittableRandom(47); + static final int SZ = items.size(); + private static SplittableRandom rand = + new SplittableRandom(47); public static Item newItem() { - return items.get(rand.nextInt(sz)).get(); + return items.get(rand.nextInt(SZ)).get(); } public static Tuple2 newPair() { return tuple(newItem(), newItem()); @@ -97,8 +32,8 @@ public static Tuple2 newPair() { class Compete { public static Outcome match(Tuple2 p) { - System.out.print(p._1 + " -> " + p._2 + " : "); - return p._1.compete(p._2); + System.out.print(p.a1 + " -> " + p.a2 + " : "); + return p.a1.compete(p.a2); } } @@ -111,24 +46,24 @@ public static void main(String[] args) { } } /* Output: -Rock -> Rock : DRAW -Paper -> Rock : WIN -Paper -> Rock : WIN -Paper -> Rock : WIN -Scissors -> Paper : WIN -Scissors -> Scissors : DRAW +Scissors -> Rock : LOSE Scissors -> Paper : WIN Rock -> Paper : LOSE -Paper -> Paper : DRAW +Rock -> Rock : DRAW Rock -> Paper : LOSE Paper -> Scissors : LOSE -Paper -> Scissors : LOSE -Rock -> Scissors : WIN Rock -> Paper : LOSE -Paper -> Rock : WIN +Scissors -> Scissors : DRAW +Scissors -> Rock : LOSE Scissors -> Paper : WIN +Scissors -> Rock : LOSE Paper -> Scissors : LOSE -Paper -> Scissors : LOSE -Paper -> Scissors : 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/patterns/ProxyDemo.java b/patterns/ProxyDemo.java index 1323a97fe..31f45aedb 100644 --- a/patterns/ProxyDemo.java +++ b/patterns/ProxyDemo.java @@ -1,8 +1,8 @@ // patterns/ProxyDemo.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Simple demonstration of the Proxy pattern +// Visit http://OnJava8.com for more book information. +// Basic demonstration of the Proxy pattern. interface ProxyBase { void f(); @@ -11,10 +11,8 @@ interface ProxyBase { } class Proxy implements ProxyBase { - private ProxyBase implementation; - public Proxy() { - implementation = new Implementation(); - } + private ProxyBase implementation = + new Implementation(); // Pass method calls to the implementation: @Override public void f() { implementation.f(); } @@ -25,13 +23,13 @@ public Proxy() { } class Implementation implements ProxyBase { - public void f() { + @Override public void f() { System.out.println("Implementation.f()"); } - public void g() { + @Override public void g() { System.out.println("Implementation.g()"); } - public void h() { + @Override public void h() { System.out.println("Implementation.h()"); } } diff --git a/patterns/Resource.java b/patterns/Resource.java new file mode 100644 index 000000000..1a8ceda50 --- /dev/null +++ b/patterns/Resource.java @@ -0,0 +1,9 @@ +// patterns/Resource.java +// (c)2021 MindView 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 Resource { + T get(); + void set(T x); +} diff --git a/patterns/ShapeFactory1.java b/patterns/ShapeFactory1.java new file mode 100644 index 000000000..a47b75b7d --- /dev/null +++ b/patterns/ShapeFactory1.java @@ -0,0 +1,39 @@ +// patterns/ShapeFactory1.java +// (c)2021 MindView 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 basic static factory method. +import java.util.*; +import java.util.stream.*; +import patterns.shapes.*; + +public class ShapeFactory1 implements FactoryMethod { + @Override 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/patterns/ShapeFactory2.java b/patterns/ShapeFactory2.java index 692e487e8..552e36306 100644 --- a/patterns/ShapeFactory2.java +++ b/patterns/ShapeFactory2.java @@ -1,90 +1,54 @@ // patterns/ShapeFactory2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Polymorphic factory methods +// Visit http://OnJava8.com for more book information. import java.util.*; -import java.util.function.*; +import java.lang.reflect.*; import java.util.stream.*; +import patterns.shapes.*; - -class BadShapeCreation extends RuntimeException { - BadShapeCreation(String msg) { - super(msg); - } -} - -interface Shape { - void draw(); - void erase(); -} - -abstract class ShapeFactory { - static Map> factories = +public class ShapeFactory2 implements FactoryMethod { + private Map factories = new HashMap<>(); - static Shape createShape(String id) - throws BadShapeCreation { - if(!factories.containsKey(id)) { - try { - Class.forName(id); // Load dynamically - } catch(ClassNotFoundException e) { - throw new BadShapeCreation(id); - } - // See if it was put in: - if(!factories.containsKey(id)) - throw new BadShapeCreation(id); + private 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); } - return factories.get(id).get(); - } -} - -class Circle implements Shape { - private Circle() {} - public void draw() { - System.out.println("Circle.draw"); } - public void erase() { - System.out.println("Circle.erase"); - } - static { - ShapeFactory.factories.put("Circle", Circle::new); - } -} - -class Square implements Shape { - private Square() {} - public void draw() { - System.out.println("Square.draw"); - } - public void erase() { - System.out.println("Square.erase"); - } - static { - ShapeFactory.factories.put("Square", Square::new); + @Override public Shape create(String id) { + try { + return (Shape)factories + .computeIfAbsent(id, ShapeFactory2::load) + .newInstance(); + } catch(Exception e) { + throw new BadShapeCreation(id); + } } -} - -public class ShapeFactory2 { public static void main(String[] args) { - List shapes = Stream.of("Circle", "Square", - "Square", "Circle", "Circle", "Square") - .map(ShapeFactory::createShape) - .collect(Collectors.toList()); - shapes.forEach(Shape::draw); - shapes.forEach(Shape::erase); + FactoryTest.test(new ShapeFactory2()); } } /* Output: -Circle.draw -Square.draw -Square.draw -Circle.draw -Circle.draw -Square.draw -Circle.erase -Square.erase -Square.erase -Circle.erase -Circle.erase -Square.erase +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/patterns/ShapeFactory3.java b/patterns/ShapeFactory3.java new file mode 100644 index 000000000..6571c5362 --- /dev/null +++ b/patterns/ShapeFactory3.java @@ -0,0 +1,53 @@ +// patterns/ShapeFactory3.java +// (c)2021 MindView 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; + } + @Override public Shape get() { + return + factories[rand.nextInt(factories.length)] + .create(); + } +} + +public class ShapeFactory3 { + public static void main(String[] args) { + RandomShapes rs = new RandomShapes( // [1] + 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/patterns/Single.java b/patterns/Single.java new file mode 100644 index 000000000..6bdb2d6e8 --- /dev/null +++ b/patterns/Single.java @@ -0,0 +1,18 @@ +// patterns/Single.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. + +@SuppressWarnings("unchecked") +public final class Single { + private static Object single; // [1] + public Single(T val) { + if(single != null) + throw new RuntimeException( + "Attempt to reassign Single<" + + val.getClass().getSimpleName() + ">" + ); + single = val; + } + public T get() { return (T)single; } +} diff --git a/patterns/SingletonPattern.java b/patterns/SingletonPattern.java index 02ff19de5..3ed313e6c 100644 --- a/patterns/SingletonPattern.java +++ b/patterns/SingletonPattern.java @@ -1,37 +1,47 @@ // patterns/SingletonPattern.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Since this isn't inherited from a Cloneable -// base class and cloneability isn't added, -// making it final prevents cloneability from -// being added through inheritance: +// Visit http://OnJava8.com for more book information. -final class Singleton { - private static Singleton s = new Singleton(47); - private int i; - private Singleton(int x) { i = x; } - public static Singleton getHandle() { - return s; +final class IntegerSingleton + implements Resource { + private static IntegerSingleton value = + new IntegerSingleton(); + private Integer i = Integer.valueOf(0); + private IntegerSingleton() { + System.out.println("IntegerSingleton()"); } - public int getValue() { return i; } - public void setValue(int x) { i = x; } + public static IntegerSingleton instance() { + return value; + } + @Override public synchronized + Integer get() { return i; } + @Override public synchronized + void set(Integer x) { i = x; } } public class SingletonPattern { + public static void show(Resource r) { + T val = r.get(); + System.out.println(val); + } + public static void put(Resource r, T val) { + r.set(val); + } public static void main(String[] args) { - Singleton s = Singleton.getHandle(); - System.out.println(s.getValue()); - Singleton s2 = Singleton.getHandle(); - s2.setValue(9); - System.out.println(s.getValue()); - try { - // Can't do this: compile-time error. - // Singleton s3 = (Singleton)s2.clone(); - } catch(Exception e) {} + System.out.println("Inside main()"); + Resource ir = + IntegerSingleton.instance(); + Resource ir2 = + IntegerSingleton.instance(); + show(ir); + put(ir2, Integer.valueOf(9)); + show(ir); } } /* Output: -47 +Inside main() +IntegerSingleton() +0 9 */ diff --git a/patterns/SingletonPattern2.java b/patterns/SingletonPattern2.java new file mode 100644 index 000000000..c02fa9f20 --- /dev/null +++ b/patterns/SingletonPattern2.java @@ -0,0 +1,16 @@ +// patterns/SingletonPattern2.java +// (c)2021 MindView 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 SingletonPattern2 { + public static void main(String[] args) { + Single pi = + new Single<>(Double.valueOf(3.14159)); + Double x = pi.get(); + System.out.println(x); + } +} +/* Output: +3.14159 +*/ diff --git a/patterns/SingletonPattern3.java b/patterns/SingletonPattern3.java new file mode 100644 index 000000000..7aee59f08 --- /dev/null +++ b/patterns/SingletonPattern3.java @@ -0,0 +1,33 @@ +// patterns/SingletonPattern3.java +// (c)2021 MindView 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 MyString { + private String s; + public MyString(String s) { + this.s = s; + } + public synchronized + void change(String s) { + this.s = s; + } + @Override public synchronized + String toString() { + return s; + } +} + +public class SingletonPattern3 { + public static void main(String[] args) { + Single x = + new Single<>(new MyString("Hello")); + System.out.println(x.get()); + x.get().change("World!"); + System.out.println(x.get()); + } +} +/* Output: +Hello +World! +*/ diff --git a/patterns/StateDemo.java b/patterns/StateDemo.java index 4a738b9e6..e96bac6ff 100644 --- a/patterns/StateDemo.java +++ b/patterns/StateDemo.java @@ -1,86 +1,67 @@ // patterns/StateDemo.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Simple demonstration of the State pattern +// Visit http://OnJava8.com for more book information. +// Basic demonstration of the State pattern. -interface StateBase { - void f(); - void g(); - void h(); - void changeImp(StateBase newImp); -} - -class State implements StateBase { - private StateBase implementation; - public State(StateBase imp) { +class State { + private State implementation; + protected State() {} + public State(State imp) { implementation = imp; } - @Override - public void changeImp(StateBase newImp) { + public void change(State newImp) { implementation = newImp; } - // Pass method calls to the implementation: - @Override + // Forward method calls to the implementation: 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() { +class Implementation1 extends State { + @Override public void f() { System.out.println("Implementation1.f()"); } - @Override - public void g() { + @Override public void g() { System.out.println("Implementation1.g()"); } - @Override - public void h() { + @Override public void h() { System.out.println("Implementation1.h()"); } - @Override - public void changeImp(StateBase newImp) {} } -class Implementation2 implements StateBase { - @Override - public void f() { +class Implementation2 extends State { + @Override public void f() { System.out.println("Implementation2.f()"); } - @Override - public void g() { + @Override public void g() { System.out.println("Implementation2.g()"); } - @Override - public void h() { + @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(); + static void test(State s) { + s.f(); + s.g(); + s.h(); } public static void main(String[] args) { - StateBase b = - new State(new Implementation1()); - test(b); - b.changeImp(new Implementation2()); - test(b); + State s = new State(new Implementation1()); + test(s); + System.out.println("Changing implementation"); + s.change(new Implementation2()); + test(s); } } /* Output: Implementation1.f() Implementation1.g() Implementation1.h() +Changing implementation Implementation2.f() Implementation2.g() Implementation2.h() diff --git a/patterns/TemplateMethod.java b/patterns/TemplateMethod.java index 4a98f4971..e9774e183 100644 --- a/patterns/TemplateMethod.java +++ b/patterns/TemplateMethod.java @@ -1,32 +1,30 @@ // patterns/TemplateMethod.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Simple demonstration of Template Method +// Visit http://OnJava8.com for more book information. +// Basic Template Method pattern. import java.util.stream.*; abstract class ApplicationFramework { - public ApplicationFramework() { + ApplicationFramework() { templateMethod(); } - abstract void customize1(); - abstract void customize2(); + abstract void customize1(int n); + abstract void customize2(int n); // "private" means automatically "final": private void templateMethod() { IntStream.range(0, 5).forEach( - n -> { customize1(); customize2(); }); + n -> { customize1(n); customize2(n); }); } } -// Create a new "application": +// Create a new application: class MyApp extends ApplicationFramework { - @Override - void customize1() { - System.out.print("Hello "); + @Override void customize1(int n) { + System.out.print("customize1 " + n); } - @Override - void customize2() { - System.out.println("World!"); + @Override void customize2(int n) { + System.out.println(" customize2 " + n); } } @@ -36,9 +34,9 @@ public static void main(String[] args) { } } /* Output: -Hello World! -Hello World! -Hello World! -Hello World! -Hello World! +customize1 0 customize2 0 +customize1 1 customize2 1 +customize1 2 customize2 2 +customize1 3 customize2 3 +customize1 4 customize2 4 */ diff --git a/patterns/TestSingle.java b/patterns/TestSingle.java new file mode 100644 index 000000000..209f06477 --- /dev/null +++ b/patterns/TestSingle.java @@ -0,0 +1,20 @@ +// patterns/TestSingle.java +// (c)2021 MindView 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 TestSingle { + public static void main(String[] args) { + Single ss = new Single<>("hello"); + System.out.println(ss.get()); + try { + Single ss2 = new Single<>("world"); + } catch(Exception e) { + System.out.println(e.getMessage()); + } + } +} +/* Output: +hello +Attempt to reassign Single +*/ diff --git a/patterns/TypeMap.java b/patterns/TypeMap.java new file mode 100644 index 000000000..db2f393a7 --- /dev/null +++ b/patterns/TypeMap.java @@ -0,0 +1,21 @@ +// patterns/TypeMap.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// Generic TypeMap works for any types. +package patterns; +import java.util.*; +import java.util.stream.*; + +public class TypeMap { + public final Map> map = + new HashMap<>(); + public void add(T o) { + Class type = o.getClass(); + map.computeIfAbsent(type, + k -> new ArrayList()).add(o); + } + public Stream> values() { + return map.values().stream(); + } +} diff --git a/patterns/absfactory/GameEnvironment.java b/patterns/abstractfactory/GameEnvironment.java similarity index 65% rename from patterns/absfactory/GameEnvironment.java rename to patterns/abstractfactory/GameEnvironment.java index f6fdf378d..51b42d553 100644 --- a/patterns/absfactory/GameEnvironment.java +++ b/patterns/abstractfactory/GameEnvironment.java @@ -1,9 +1,10 @@ -// patterns/absfactory/GameEnvironment.java -// (c)2016 MindView LLC: see Copyright.txt +// patterns/abstractfactory/GameEnvironment.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// An example of the Abstract Factory pattern -package patterns.absfactory; +// 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 { @@ -22,25 +23,23 @@ public void interactWith(Obstacle ob) { } } -class KungFuGuy implements Player { +class Fighter implements Player { @Override public void interactWith(Obstacle ob) { - System.out.print("KungFuGuy now battles a "); + System.out.print("Fighter now battles a "); ob.action(); } } class Puzzle implements Obstacle { - @Override - public void action() { + @Override public void action() { System.out.println("Puzzle"); } } -class NastyWeapon implements Obstacle { - @Override - public void action() { - System.out.println("NastyWeapon"); +class Weapon implements Obstacle { + @Override public void action() { + System.out.println("Weapon"); } } @@ -59,11 +58,11 @@ class KittiesAndPuzzles } } -class KillAndDismember +class Melee extends GameElementFactory { - KillAndDismember() { - player = KungFuGuy::new; - obstacle = NastyWeapon::new; + Melee() { + player = Fighter::new; + obstacle = Weapon::new; } } @@ -81,15 +80,15 @@ public void play() { public static void main(String[] args) { GameElementFactory kp = new KittiesAndPuzzles(), - kd = new KillAndDismember(); + ml = new Melee(); GameEnvironment g1 = new GameEnvironment(kp), - g2 = new GameEnvironment(kd); + g2 = new GameEnvironment(ml); g1.play(); g2.play(); } } /* Output: Kitty has encountered a Puzzle -KungFuGuy now battles a NastyWeapon +Fighter now battles a Weapon */ diff --git a/patterns/adapt/Adapter.java b/patterns/adapt/Adapter.java index 3ff1bc3c8..0b3a0919f 100644 --- a/patterns/adapt/Adapter.java +++ b/patterns/adapt/Adapter.java @@ -1,8 +1,9 @@ // patterns/adapt/Adapter.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Variations on the Adapter pattern +// Visit http://OnJava8.com for more book information. +// Variations on the Adapter pattern. +// {java patterns.adapt.Adapter} package patterns.adapt; class WhatIHave { @@ -16,11 +17,10 @@ interface WhatIWant { class ProxyAdapter implements WhatIWant { WhatIHave whatIHave; - public ProxyAdapter(WhatIHave wih) { + ProxyAdapter(WhatIHave wih) { whatIHave = wih; } - @Override - public void f() { + @Override public void f() { // Implement behavior using // methods in WhatIHave: whatIHave.g(); @@ -44,8 +44,7 @@ public void op(WhatIHave wih) { // Approach 3: build adapter into WhatIHave: class WhatIHave2 extends WhatIHave implements WhatIWant { - @Override - public void f() { + @Override public void f() { g(); h(); } @@ -54,8 +53,7 @@ public void f() { // Approach 4: use an inner class: class WhatIHave3 extends WhatIHave { private class InnerAdapter implements WhatIWant{ - @Override - public void f() { + @Override public void f() { g(); h(); } diff --git a/patterns/build.xml b/patterns/build.xml deleted file mode 100644 index e5a9d2dbf..000000000 --- a/patterns/build.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/patterns/chain/ChainOfResponsibility.java b/patterns/chain/ChainOfResponsibility.java index fe1b1666f..b291c3e00 100644 --- a/patterns/chain/ChainOfResponsibility.java +++ b/patterns/chain/ChainOfResponsibility.java @@ -1,69 +1,48 @@ // patterns/chain/ChainOfResponsibility.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Using the Functional interface +// Visit http://OnJava8.com for more book information. +// {java patterns.chain.ChainOfResponsibility} package patterns.chain; import java.util.*; import java.util.function.*; -class Result { - boolean success; - List line; - public Result(List data) { - success = true; - line = data; - } - public 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)); + public static Result test( + boolean success, String id, double d1, double d2) { + System.out.println(id); + if(success) // Actual test/calculation here + return new Result(Arrays.asList(d1, d2)); else // Try the next one in the chain: - return new Fail(); + return Result.fail; + } + public static Result leastSquares(List line) { + return test(false, "LeastSquares", 1.1, 2.2); } 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(); + return test(false, "Perturbation", 3.3, 4.4); } 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(); + return test(true, "Bisection", 5.5, 6.6); } - static List, Result>> algorithms = - Arrays.asList( + static List, Result>> + algorithms = Arrays.asList( FindMinima::leastSquares, FindMinima::perturbation, FindMinima::bisection ); public static Result minima(List line) { - for(Function, Result> alg : algorithms) { + for(Function, Result> alg : + algorithms) { Result result = alg.apply(line); if(result.success) return result; } - return new Fail(); + return Result.fail; } } @@ -81,8 +60,8 @@ public static void main(String[] args) { } } /* Output: -LeastSquares.algorithm -Perturbation.algorithm -Bisection.algorithm +LeastSquares +Perturbation +Bisection [5.5, 6.6] */ diff --git a/patterns/chain/Result.java b/patterns/chain/Result.java new file mode 100644 index 000000000..dc459b399 --- /dev/null +++ b/patterns/chain/Result.java @@ -0,0 +1,21 @@ +// patterns/chain/Result.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// Carries the result or indicates failure. +package patterns.chain; +import java.util.*; + +public class Result { + public final boolean success; + public final List line; + public Result(List data) { + success = true; + line = data; + } + private Result() { + success = false; + line = Collections.emptyList(); + } + public static final Result fail = new Result(); +} diff --git a/patterns/doubledispatch/Aluminum.java b/patterns/doubledispatch/Aluminum.java index 75d9e7245..9f5678b11 100644 --- a/patterns/doubledispatch/Aluminum.java +++ b/patterns/doubledispatch/Aluminum.java @@ -1,17 +1,18 @@ // patterns/doubledispatch/Aluminum.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Aluminum for double dispatching +// Visit http://OnJava8.com for more book information. +// Aluminum with double dispatching. package patterns.doubledispatch; import patterns.trash.*; import java.util.*; public class Aluminum extends patterns.trash.Aluminum - implements TypedBinMember { +implements TypedBinMember { public Aluminum(double wt) { super(wt); } @Override public boolean addToBin(List tbins) { - return tbins.stream().anyMatch(tb -> tb.add(this)); + return tbins.stream() + .anyMatch(tb -> tb.add(this)); } } diff --git a/patterns/doubledispatch/Cardboard.java b/patterns/doubledispatch/Cardboard.java index 90008eda0..390292322 100644 --- a/patterns/doubledispatch/Cardboard.java +++ b/patterns/doubledispatch/Cardboard.java @@ -1,17 +1,18 @@ // patterns/doubledispatch/Cardboard.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Cardboard for double dispatching +// Visit http://OnJava8.com for more book information. +// Cardboard with double dispatching. package patterns.doubledispatch; import patterns.trash.*; import java.util.*; public class Cardboard extends patterns.trash.Cardboard - implements TypedBinMember { +implements TypedBinMember { public Cardboard(double wt) { super(wt); } @Override public boolean addToBin(List tbins) { - return tbins.stream().anyMatch(tb -> tb.add(this)); + return tbins.stream() + .anyMatch(tb -> tb.add(this)); } } diff --git a/patterns/doubledispatch/DoubleDispatch.java b/patterns/doubledispatch/DoubleDispatch.java index dd88cf11d..d1ddfe253 100644 --- a/patterns/doubledispatch/DoubleDispatch.java +++ b/patterns/doubledispatch/DoubleDispatch.java @@ -1,94 +1,106 @@ // patterns/doubledispatch/DoubleDispatch.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Using multiple dispatching to handle more -// than one unknown type during a method call +// 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) { + public AluminumBin() { super("Aluminum"); } + @Override public boolean add(Aluminum a) { return addIt(a); } } class PaperBin extends TypedBin { - @Override - public boolean add(Paper a) { + public PaperBin() { super("Paper"); } + @Override public boolean add(Paper a) { return addIt(a); } } class GlassBin extends TypedBin { - @Override - public boolean add(Glass a) { + public GlassBin() { super("Glass"); } + @Override public boolean add(Glass a) { return addIt(a); } } class CardboardBin extends TypedBin { - @Override - public boolean add(Cardboard a) { + public CardboardBin() { super("Cardboard"); } + @Override public boolean add(Cardboard a) { return addIt(a); } } class TrashBinSet { - private List binSet = Arrays.asList( - new AluminumBin(), - new PaperBin(), - new GlassBin(), - new CardboardBin() - ); + public final 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); + throw new RuntimeException( + "sortIntoBins() 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); + TrashBinSet bins = new TrashBinSet(); // 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); + // Sum value of each bin... + bins.binSet.forEach(tb -> + TrashValue.sum(tb.bin(), tb.type)); + // ... and for the master bin: + TrashValue.sum(bin, "Trash"); } } -/* Output: (First and last 10 Lines) -Loading patterns.doubledispatch.DDGlass -Loading patterns.doubledispatch.DDPaper -Loading patterns.doubledispatch.DDAluminum -Loading patterns.doubledispatch.DDCardboard -weight of patterns.doubledispatch.DDAluminum = 89.0 -weight of patterns.doubledispatch.DDAluminum = 76.0 -weight of patterns.doubledispatch.DDAluminum = 25.0 -weight of patterns.doubledispatch.DDAluminum = 34.0 -weight of patterns.doubledispatch.DDAluminum = 27.0 -weight of patterns.doubledispatch.DDAluminum = 18.0 -________...________...________...________...________ -weight of patterns.doubledispatch.DDAluminum = 93.0 -weight of patterns.doubledispatch.DDGlass = 93.0 -weight of patterns.doubledispatch.DDPaper = 80.0 -weight of patterns.doubledispatch.DDGlass = 36.0 -weight of patterns.doubledispatch.DDGlass = 12.0 -weight of patterns.doubledispatch.DDGlass = 60.0 -weight of patterns.doubledispatch.DDPaper = 66.0 -weight of patterns.doubledispatch.DDAluminum = 36.0 -weight of patterns.doubledispatch.DDCardboard = 22.0 -Total value = 1086.0599818825722 +/* Output: +Loading patterns.doubledispatch.Cardboard +Loading patterns.doubledispatch.Paper +Loading patterns.doubledispatch.Aluminum +Loading patterns.doubledispatch.Glass +Aluminum weight: 1.80 * price: 1.67 = 3.01 +Aluminum weight: 3.40 * price: 1.67 = 5.68 +Aluminum weight: 2.70 * price: 1.67 = 4.51 +Total Aluminum value = 13.19 +Paper weight: 8.00 * price: 0.10 = 0.80 +Paper weight: 6.60 * price: 0.10 = 0.66 +Paper weight: 9.10 * price: 0.10 = 0.91 +Total Paper value = 2.37 +Glass weight: 5.40 * price: 0.23 = 1.24 +Glass weight: 4.30 * price: 0.23 = 0.99 +Glass weight: 3.60 * price: 0.23 = 0.83 +Total Glass value = 3.06 +Cardboard weight: 4.40 * price: 0.11 = 0.48 +Cardboard weight: 2.20 * price: 0.11 = 0.24 +Cardboard weight: 1.20 * price: 0.11 = 0.13 +Total Cardboard value = 0.86 +Cardboard weight: 4.40 * price: 0.11 = 0.48 +Paper weight: 8.00 * price: 0.10 = 0.80 +Aluminum weight: 1.80 * price: 1.67 = 3.01 +Glass weight: 5.40 * price: 0.23 = 1.24 +Aluminum weight: 3.40 * price: 1.67 = 5.68 +Cardboard weight: 2.20 * price: 0.11 = 0.24 +Glass weight: 4.30 * price: 0.23 = 0.99 +Cardboard weight: 1.20 * price: 0.11 = 0.13 +Paper weight: 6.60 * price: 0.10 = 0.66 +Aluminum weight: 2.70 * price: 1.67 = 4.51 +Paper weight: 9.10 * price: 0.10 = 0.91 +Glass weight: 3.60 * price: 0.23 = 0.83 +Total Trash value = 19.48 */ diff --git a/patterns/doubledispatch/Glass.java b/patterns/doubledispatch/Glass.java index 780aeb795..c0800cdf2 100644 --- a/patterns/doubledispatch/Glass.java +++ b/patterns/doubledispatch/Glass.java @@ -1,17 +1,18 @@ // patterns/doubledispatch/Glass.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Glass for double dispatching +// Visit http://OnJava8.com for more book information. +// Glass with double dispatching. package patterns.doubledispatch; import patterns.trash.*; import java.util.*; public class Glass extends patterns.trash.Glass - implements TypedBinMember { +implements TypedBinMember { public Glass(double wt) { super(wt); } @Override public boolean addToBin(List tbins) { - return tbins.stream().anyMatch(tb -> tb.add(this)); + return tbins.stream() + .anyMatch(tb -> tb.add(this)); } } diff --git a/patterns/doubledispatch/Paper.java b/patterns/doubledispatch/Paper.java index befca7561..de25cab37 100644 --- a/patterns/doubledispatch/Paper.java +++ b/patterns/doubledispatch/Paper.java @@ -1,17 +1,18 @@ // patterns/doubledispatch/Paper.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Paper for double dispatching +// Visit http://OnJava8.com for more book information. +// Paper with double dispatching. package patterns.doubledispatch; import patterns.trash.*; import java.util.*; public class Paper extends patterns.trash.Paper - implements TypedBinMember { +implements TypedBinMember { public Paper(double wt) { super(wt); } @Override public boolean addToBin(List tbins) { - return tbins.stream().anyMatch(tb -> tb.add(this)); + return tbins.stream() + .anyMatch(tb -> tb.add(this)); } } diff --git a/patterns/doubledispatch/TypedBin.java b/patterns/doubledispatch/TypedBin.java index 887e0663e..8484552c4 100644 --- a/patterns/doubledispatch/TypedBin.java +++ b/patterns/doubledispatch/TypedBin.java @@ -1,16 +1,25 @@ // patterns/doubledispatch/TypedBin.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// A List that can grab the right type +// 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 abstract class TypedBin { - List v = new ArrayList<>(); +public class TypedBin { + private List typedBin = + new ArrayList<>(); + public final String type; + public TypedBin(String type) { + this.type = type; + } + public List bin() { + // Returns a copy of typedBin: + return new ArrayList(typedBin); + } protected boolean addIt(Trash t) { - v.add(t); + typedBin.add(t); return true; } public boolean add(Aluminum a) { diff --git a/patterns/doubledispatch/TypedBinMember.java b/patterns/doubledispatch/TypedBinMember.java index a34d68068..109745b4f 100644 --- a/patterns/doubledispatch/TypedBinMember.java +++ b/patterns/doubledispatch/TypedBinMember.java @@ -1,14 +1,13 @@ // patterns/doubledispatch/TypedBinMember.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// An interface for adding the double dispatching -// method to the trash hierarchy without -// modifying the original hierarchy +// Visit http://OnJava8.com for more book information. +// Adapts the double-dispatching +// method into the trash hierarchy without +// modifying the original hierarchy. package patterns.doubledispatch; import java.util.*; -interface TypedBinMember { - // The new method: +public interface TypedBinMember { boolean addToBin(List bins); } diff --git a/patterns/dynatrash/DynaTrash.java b/patterns/dynatrash/DynaTrash.java deleted file mode 100644 index 5d3afbb59..000000000 --- a/patterns/dynatrash/DynaTrash.java +++ /dev/null @@ -1,73 +0,0 @@ -// patterns/dynatrash/DynaTrash.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ 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. -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; - public 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.Glass = 54.0 -weight of patterns.trash.Glass = 17.0 -weight of patterns.trash.Glass = 11.0 -weight of patterns.trash.Glass = 68.0 -weight of patterns.trash.Glass = 43.0 -weight of patterns.trash.Glass = 63.0 -________...________...________...________...________ -weight of patterns.trash.Aluminum = 93.0 -weight of patterns.trash.Aluminum = 36.0 -Total value = 860.0499778985977 -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 -Total value = 35.80000053346157 -*/ diff --git a/patterns/factory/ShapeFactory1.java b/patterns/factory/ShapeFactory1.java deleted file mode 100644 index 81e6844c3..000000000 --- a/patterns/factory/ShapeFactory1.java +++ /dev/null @@ -1,79 +0,0 @@ -// patterns/factory/ShapeFactory1.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// A simple static factory method -package patterns.factory; -import java.util.*; -import java.util.stream.*; - -class BadShapeCreation extends RuntimeException { - BadShapeCreation(String msg) { - super(msg); - } -} - -abstract class Shape { - public abstract void draw(); - public abstract void erase(); - static Shape factory(String type) - throws BadShapeCreation { - switch(type) { - case "Circle": return new Circle(); - case "Square": return new Square(); - default: - throw new BadShapeCreation(type); - } - } -} - -class Circle extends Shape { - Circle() {} // Friendly constructor - @Override - public void draw() { - System.out.println("Circle.draw"); - } - @Override - public void erase() { - System.out.println("Circle.erase"); - } -} - -class Square extends Shape { - Square() {} // Friendly constructor - @Override - public void draw() { - System.out.println("Square.draw"); - } - @Override - public void erase() { - System.out.println("Square.erase"); - } -} - -public class ShapeFactory1 { - public static void main(String[] args) { - List shapes = Stream.of( - "Circle", "Square", - "Square", "Circle", - "Circle", "Square") - .map(Shape::factory) - .collect(Collectors.toList()); - shapes.forEach(Shape::draw); - shapes.forEach(Shape::erase); - } -} -/* Output: -Circle.draw -Square.draw -Square.draw -Circle.draw -Circle.draw -Square.draw -Circle.erase -Square.erase -Square.erase -Circle.erase -Circle.erase -Square.erase -*/ diff --git a/patterns/observer/ObservedFlower.java b/patterns/observer/ObservedFlower.java index bc89ac39f..acfb0f656 100644 --- a/patterns/observer/ObservedFlower.java +++ b/patterns/observer/ObservedFlower.java @@ -1,77 +1,72 @@ // patterns/observer/ObservedFlower.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Demonstration of "Observer" pattern +// Visit http://OnJava8.com for more book information. +// Demonstration of the Observer pattern. +// {java patterns.observer.ObservedFlower} package patterns.observer; import java.util.*; +import java.util.function.*; +@SuppressWarnings("deprecation") class Flower { - private boolean isOpen; - private boolean alreadyOpen; - private boolean alreadyClosed; - public 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() { + private boolean isOpen = false; + private boolean alreadyOpen = false; + private boolean alreadyClosed = false; + Observable opening = new Observable() { + @Override public void notifyObservers() { if(isOpen && !alreadyOpen) { setChanged(); super.notifyObservers(); alreadyOpen = true; } } - } - class CloseNotifier extends Observable{ - @Override - public void notifyObservers() { + }; + Observable closing = new Observable() { + @Override public void notifyObservers() { if(!isOpen && !alreadyClosed) { setChanged(); super.notifyObservers(); alreadyClosed = true; } } + }; + public void open() { // Opens its petals + isOpen = true; + opening.notifyObservers(); + alreadyClosed = false; + } + public void close() { // Closes its petals + isOpen = false; + closing.notifyObservers(); + alreadyOpen = false; } } +@SuppressWarnings("deprecation") class Bee { - private String name; - public Bee(String nm) { name = nm; } + private String id; + Bee(String name) { id = name; } // Observe openings: - public Observer openObserver() { - return (ob, a) -> System.out.println( - "Bee " + name + "'s breakfast time!"); - } + public final Observer whenOpened = (ob, a) -> + System.out.println( + "Bee " + id + "'s breakfast time!"); // Observe closings: - public Observer closeObserver() { - return (ob, a) -> System.out.println( - "Bee " + name + "'s bed time!"); - } + public final Observer whenClosed = (ob, a) -> + System.out.println( + "Bee " + id + "'s bed time!"); } +@SuppressWarnings("deprecation") class Hummingbird { - private String name; - public 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!"); - } + private String id; + Hummingbird(String name) { id = name; } + public final Observer whenOpened = (ob, a) -> + System.out.println("Hummingbird " + + id + "'s breakfast time!"); + public final Observer whenClosed = (ob, a) -> + System.out.println("Hummingbird " + + id + "'s bed time!"); } public class ObservedFlower { @@ -83,39 +78,46 @@ public static void main(String[] args) { 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()); + f.opening.addObserver(ha.whenOpened); + f.opening.addObserver(hb.whenOpened); + f.opening.addObserver(ba.whenOpened); + f.opening.addObserver(bb.whenOpened); + f.closing.addObserver(ha.whenClosed); + f.closing.addObserver(hb.whenClosed); + f.closing.addObserver(ba.whenClosed); + f.closing.addObserver(bb.whenClosed); + // Hummingbird B decides to sleep in. + // Removing whenOpened stops open updates. + f.opening.deleteObserver(hb.whenOpened); // 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.open(); // No effect: it's already open. + System.out.println("---------------"); + // Bee A doesn't want to go to bed. + // Removing whenClosed stops close updates. + f.closing.deleteObserver(ba.whenClosed); f.close(); - f.close(); // It's already closed; no change + System.out.println("+++++++++++++++"); + f.close(); // No effect: it's already closed. + System.out.println("==============="); f.opening.deleteObservers(); - f.open(); - f.close(); + f.open(); // No observers to update. + System.out.println("###############"); + f.close(); // Close observers are still there. } } /* 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/patterns/recyclea/RecycleA.java b/patterns/recyclea/RecycleA.java index fb07cb412..483e700ed 100644 --- a/patterns/recyclea/RecycleA.java +++ b/patterns/recyclea/RecycleA.java @@ -1,74 +1,26 @@ // patterns/recyclea/RecycleA.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Recycling with RTTI +// Visit http://OnJava8.com for more book information. +// Recycling with reflection. +// {java patterns.recyclea.RecycleA} package patterns.recyclea; import java.util.*; import java.util.function.*; import java.util.stream.*; +import patterns.trash.*; -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 = +class SimpleFactory { + static final + List> constructors = Arrays.asList( Aluminum::new, Paper::new, Glass::new); - final static int sz = ttypes.size(); - private static SplittableRandom rand = new SplittableRandom(47); - public static Trash newTrash() { - return ttypes - .get(rand.nextInt(sz)) + static final int SIZE = constructors.size(); + private static SplittableRandom rand = + new SplittableRandom(42); + public static Trash random() { + return constructors + .get(rand.nextInt(SIZE)) .apply(rand.nextDouble()); } } @@ -76,50 +28,37 @@ public static Trash newTrash() { public class RecycleA { public static void main(String[] args) { List bin = - Stream.generate(TrashFactory::newTrash) - .limit(25) + Stream.generate(SimpleFactory::random) + .limit(10) .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); + Bins bins = new Bins(bin); + bins.show(); } } -/* Output: (First and last 11 Lines) -weight of patterns.recyclea.Aluminum = 0.11435456649761422 -weight of patterns.recyclea.Aluminum = 0.5295954256745989 -weight of patterns.recyclea.Aluminum = 0.44032876173820623 -weight of patterns.recyclea.Aluminum = 0.483968447804611 -weight of patterns.recyclea.Aluminum = 0.2724064060083268 -weight of patterns.recyclea.Aluminum = 0.7661553155473436 -weight of patterns.recyclea.Aluminum = 0.32266202529378485 -weight of patterns.recyclea.Aluminum = 0.29010681217024337 -weight of patterns.recyclea.Aluminum = 0.04867885164993724 -weight of patterns.recyclea.Aluminum = 0.6398064631177899 -Total value = 6.526465168373229 -________...________...________...________...________ -weight of patterns.recyclea.Paper = 0.7024254510631527 -weight of patterns.recyclea.Paper = 0.7775491010186331 -weight of patterns.recyclea.Paper = 0.5929413550962656 -weight of patterns.recyclea.Paper = 0.8991222558891441 -weight of patterns.recyclea.Aluminum = 0.32266202529378485 -weight of patterns.recyclea.Aluminum = 0.29010681217024337 -weight of patterns.recyclea.Glass = 0.42812712031823896 -weight of patterns.recyclea.Paper = 0.8242175461669214 -weight of patterns.recyclea.Aluminum = 0.04867885164993724 -weight of patterns.recyclea.Aluminum = 0.6398064631177899 -Total value = 7.489772197549787 +/* Output: +Aluminum weight: 0.34 * price: 1.67 = 0.57 +Aluminum weight: 0.62 * price: 1.67 = 1.03 +Aluminum weight: 0.49 * price: 1.67 = 0.82 +Aluminum weight: 0.50 * price: 1.67 = 0.83 +Total Aluminum value = 3.26 +Paper weight: 0.69 * price: 0.10 = 0.07 +Total Paper value = 0.07 +Glass weight: 0.16 * price: 0.23 = 0.04 +Glass weight: 0.87 * price: 0.23 = 0.20 +Glass weight: 0.80 * price: 0.23 = 0.18 +Glass weight: 0.52 * price: 0.23 = 0.12 +Glass weight: 0.20 * price: 0.23 = 0.05 +Total Glass value = 0.59 +Total Cardboard value = 0.00 +Glass weight: 0.16 * price: 0.23 = 0.04 +Aluminum weight: 0.34 * price: 1.67 = 0.57 +Glass weight: 0.87 * price: 0.23 = 0.20 +Glass weight: 0.80 * price: 0.23 = 0.18 +Aluminum weight: 0.62 * price: 1.67 = 1.03 +Aluminum weight: 0.49 * price: 1.67 = 0.82 +Glass weight: 0.52 * price: 0.23 = 0.12 +Glass weight: 0.20 * price: 0.23 = 0.05 +Aluminum weight: 0.50 * price: 1.67 = 0.83 +Paper weight: 0.69 * price: 0.10 = 0.07 +Total Trash value = 3.91 */ diff --git a/patterns/recycleb/RecycleB.java b/patterns/recycleb/RecycleB.java index 072e10a56..b65f1db3d 100644 --- a/patterns/recycleb/RecycleB.java +++ b/patterns/recycleb/RecycleB.java @@ -1,7 +1,8 @@ // patterns/recycleb/RecycleB.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {java patterns.recycleb.RecycleB} package patterns.recycleb; import patterns.trash.*; import java.util.*; @@ -9,47 +10,43 @@ 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); + Bins bins = new Bins(bin); + bins.show(); } } -/* Output: (First and last 10 Lines) -Loading patterns.trash.Glass +/* Output: +Loading patterns.trash.Cardboard 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 +Loading patterns.trash.Glass +Aluminum weight: 1.80 * price: 1.67 = 3.01 +Aluminum weight: 3.40 * price: 1.67 = 5.68 +Aluminum weight: 2.70 * price: 1.67 = 4.51 +Total Aluminum value = 13.19 +Paper weight: 8.00 * price: 0.10 = 0.80 +Paper weight: 6.60 * price: 0.10 = 0.66 +Paper weight: 9.10 * price: 0.10 = 0.91 +Total Paper value = 2.37 +Glass weight: 5.40 * price: 0.23 = 1.24 +Glass weight: 4.30 * price: 0.23 = 0.99 +Glass weight: 3.60 * price: 0.23 = 0.83 +Total Glass value = 3.06 +Cardboard weight: 4.40 * price: 0.11 = 0.48 +Cardboard weight: 2.20 * price: 0.11 = 0.24 +Cardboard weight: 1.20 * price: 0.11 = 0.13 +Total Cardboard value = 0.86 +Cardboard weight: 4.40 * price: 0.11 = 0.48 +Paper weight: 8.00 * price: 0.10 = 0.80 +Aluminum weight: 1.80 * price: 1.67 = 3.01 +Glass weight: 5.40 * price: 0.23 = 1.24 +Aluminum weight: 3.40 * price: 1.67 = 5.68 +Cardboard weight: 2.20 * price: 0.11 = 0.24 +Glass weight: 4.30 * price: 0.23 = 0.99 +Cardboard weight: 1.20 * price: 0.11 = 0.13 +Paper weight: 6.60 * price: 0.10 = 0.66 +Aluminum weight: 2.70 * price: 1.67 = 4.51 +Paper weight: 9.10 * price: 0.10 = 0.91 +Glass weight: 3.60 * price: 0.23 = 0.83 +Total Trash value = 19.48 */ diff --git a/patterns/recyclec/RecycleC.java b/patterns/recyclec/RecycleC.java index b3969fee3..611c30907 100644 --- a/patterns/recyclec/RecycleC.java +++ b/patterns/recyclec/RecycleC.java @@ -1,83 +1,106 @@ // patterns/recyclec/RecycleC.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Adding more objects to the recycling problem +// Visit http://OnJava8.com for more book information. +// {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; +// A List that only admits the right type: +class +TrashBin extends ArrayList { + final Class binType; + TrashBin(Class binType) { + this.binType = binType; } @SuppressWarnings("unchecked") boolean grab(Trash t) { - // Comparing class types: + // Compare class types: if(t.getClass().equals(binType)) { - add((T)t); // Downcast to this TBin's type - return true; // Object grabbed + add((T)t); // Downcast to this TrashBin type + return true; // Trash grabbed } - return false; // Object not grabbed + return false; // Trash not grabbed } } -class TbinList -extends ArrayList> { // [*1*] - boolean sort(T t) { - for(Tbin ts : this) +class TrashBinList +extends ArrayList> { // [1] + @SuppressWarnings("unchecked") + public TrashBinList(Class... types) { + for(Class type : types) + add(new TrashBin<>(type)); + } + public boolean sort(T t) { + for(TrashBin ts : this) if(ts.grab(t)) return true; - return false; // bin not found for t + return false; // TrashBin not found for t + } + public void sortBin(TrashBin bin) { // [2] + for(T trash : bin) + if(!sort(trash)) + throw new RuntimeException( + "Bin not found for " + trash); } - void sortBin(Tbin bin) { // [*2*] - for(T aBin : bin) - if(!sort(aBin)) - System.err.println("Bin not found"); + public void show() { + for(TrashBin tbin : this) { + String typeName = tbin.binType.getSimpleName(); + TrashValue.sum(tbin, typeName); + } } } public class RecycleC { - static Tbin bin = new Tbin<>(Trash.class); public static void main(String[] args) { - // Fill up the Trash bin: + TrashBin bin = + new TrashBin<>(Trash.class); 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); + @SuppressWarnings("unchecked") + TrashBinList trashBins = + new TrashBinList<>( + Aluminum.class, Paper.class, Glass.class, + // Add one item: + Cardboard.class // [3] + ); + trashBins.sortBin(bin); // [4] + trashBins.show(); + TrashValue.sum(bin, "Trash"); } } -/* Output: (First and last 10 Lines) -Loading patterns.trash.Glass +/* Output: +Loading patterns.trash.Cardboard 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 +Loading patterns.trash.Glass +Aluminum weight: 1.80 * price: 1.67 = 3.01 +Aluminum weight: 3.40 * price: 1.67 = 5.68 +Aluminum weight: 2.70 * price: 1.67 = 4.51 +Total Aluminum value = 13.19 +Paper weight: 8.00 * price: 0.10 = 0.80 +Paper weight: 6.60 * price: 0.10 = 0.66 +Paper weight: 9.10 * price: 0.10 = 0.91 +Total Paper value = 2.37 +Glass weight: 5.40 * price: 0.23 = 1.24 +Glass weight: 4.30 * price: 0.23 = 0.99 +Glass weight: 3.60 * price: 0.23 = 0.83 +Total Glass value = 3.06 +Cardboard weight: 4.40 * price: 0.11 = 0.48 +Cardboard weight: 2.20 * price: 0.11 = 0.24 +Cardboard weight: 1.20 * price: 0.11 = 0.13 +Total Cardboard value = 0.86 +Cardboard weight: 4.40 * price: 0.11 = 0.48 +Paper weight: 8.00 * price: 0.10 = 0.80 +Aluminum weight: 1.80 * price: 1.67 = 3.01 +Glass weight: 5.40 * price: 0.23 = 1.24 +Aluminum weight: 3.40 * price: 1.67 = 5.68 +Cardboard weight: 2.20 * price: 0.11 = 0.24 +Glass weight: 4.30 * price: 0.23 = 0.99 +Cardboard weight: 1.20 * price: 0.11 = 0.13 +Paper weight: 6.60 * price: 0.10 = 0.66 +Aluminum weight: 2.70 * price: 1.67 = 4.51 +Paper weight: 9.10 * price: 0.10 = 0.91 +Glass weight: 3.60 * price: 0.23 = 0.83 +Total Trash value = 19.48 */ diff --git a/patterns/shapes/BadShapeCreation.java b/patterns/shapes/BadShapeCreation.java new file mode 100644 index 000000000..52edcb692 --- /dev/null +++ b/patterns/shapes/BadShapeCreation.java @@ -0,0 +1,12 @@ +// patterns/shapes/BadShapeCreation.java +// (c)2021 MindView 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/patterns/shapes/Circle.java b/patterns/shapes/Circle.java new file mode 100644 index 000000000..3c05e664a --- /dev/null +++ b/patterns/shapes/Circle.java @@ -0,0 +1,7 @@ +// patterns/shapes/Circle.java +// (c)2021 MindView 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/patterns/shapes/FactoryMethod.java b/patterns/shapes/FactoryMethod.java new file mode 100644 index 000000000..9a4174a83 --- /dev/null +++ b/patterns/shapes/FactoryMethod.java @@ -0,0 +1,9 @@ +// patterns/shapes/FactoryMethod.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +package patterns.shapes; + +public interface FactoryMethod { + Shape create(String type); +} diff --git a/patterns/shapes/FactoryTest.java b/patterns/shapes/FactoryTest.java new file mode 100644 index 000000000..506d90360 --- /dev/null +++ b/patterns/shapes/FactoryTest.java @@ -0,0 +1,17 @@ +// patterns/shapes/FactoryTest.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +package patterns.shapes; +import java.util.stream.*; + +public class FactoryTest { + public static void test(FactoryMethod factory) { + Stream.of("Circle", "Square", "Triangle", + "Square", "Circle", "Circle", "Triangle") + .map(factory::create) + .peek(Shape::draw) + .peek(Shape::erase) + .count(); // Terminal operation + } +} diff --git a/patterns/shapes/Shape.java b/patterns/shapes/Shape.java new file mode 100644 index 000000000..38ce61440 --- /dev/null +++ b/patterns/shapes/Shape.java @@ -0,0 +1,20 @@ +// patterns/shapes/Shape.java +// (c)2021 MindView 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/patterns/shapes/Square.java b/patterns/shapes/Square.java new file mode 100644 index 000000000..91f879fa9 --- /dev/null +++ b/patterns/shapes/Square.java @@ -0,0 +1,7 @@ +// patterns/shapes/Square.java +// (c)2021 MindView 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/patterns/shapes/Triangle.java b/patterns/shapes/Triangle.java new file mode 100644 index 000000000..c54af659c --- /dev/null +++ b/patterns/shapes/Triangle.java @@ -0,0 +1,7 @@ +// patterns/shapes/Triangle.java +// (c)2021 MindView 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/patterns/state/StateMachineDemo.java b/patterns/state/StateMachineDemo.java index fc113368a..1b9630a9c 100644 --- a/patterns/state/StateMachineDemo.java +++ b/patterns/state/StateMachineDemo.java @@ -1,9 +1,12 @@ // patterns/state/StateMachineDemo.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// The StateMachine pattern and Template method +// Visit http://OnJava8.com for more book information. +// The State Machine pattern. +// {java patterns.state.StateMachineDemo} package patterns.state; +import java.util.*; +import onjava.Nap; interface State { void run(); @@ -11,10 +14,10 @@ interface State { abstract class StateMachine { protected State currentState; - abstract protected boolean changeState(); + protected abstract boolean changeState(); // Template method: protected final void runAll() { - while(changeState()) // Customizable + while(changeState()) currentState.run(); } } @@ -22,52 +25,41 @@ protected final void runAll() { // A different subclass for each state: class Wash implements State { - @Override - public void run() { + @Override public void run() { System.out.println("Washing"); - try { - Thread.sleep(500); - } catch(InterruptedException e) {} + new Nap(0.5); } } class Spin implements State { - @Override - public void run() { + @Override public void run() { System.out.println("Spinning"); - try { - Thread.sleep(500); - } catch(InterruptedException e) {} + new Nap(0.5); } } class Rinse implements State { - @Override - public void run() { + @Override public void run() { System.out.println("Rinsing"); - try { - Thread.sleep(500); - } catch(InterruptedException e) {} + 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(), - }; - public 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 + private Iterator states = + Arrays.asList( + new Wash(), new Spin(), + new Rinse(), new Spin() + ).iterator(); + Washer() { runAll(); } + @Override public boolean changeState() { + if(!states.hasNext()) return false; + // Set the surrogate reference + // to a new State object: + currentState = states.next(); + return true; } } diff --git a/patterns/strategy/StrategyPattern.java b/patterns/strategy/StrategyPattern.java index 74264f624..7e06bc1e6 100644 --- a/patterns/strategy/StrategyPattern.java +++ b/patterns/strategy/StrategyPattern.java @@ -1,20 +1,22 @@ // patterns/strategy/StrategyPattern.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 { + protected Function, List> algorithm; } -// The various strategies: +// The various strategies, each producing dummy data: class LeastSquares extends FindMinima { LeastSquares() { - // Line is a sequence of points (Dummy data): + // Line is a sequence of points: algorithm = (line) -> Arrays.asList(1.1, 2.2); } } @@ -34,8 +36,8 @@ class Bisection extends FindMinima { // The "Context" controls the strategy: class MinimaSolver { private FindMinima strategy; - public MinimaSolver(FindMinima strat) { - strategy = strat; + MinimaSolver(FindMinima strategy) { + this.strategy = strategy; } List minima(List line) { return strategy.algorithm.apply(line); @@ -53,11 +55,14 @@ public static void main(String[] args) { 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 Perturbation()); + System.out.println(solver.minima(line)); solver.changeAlgorithm(new Bisection()); System.out.println(solver.minima(line)); } } /* Output: [1.1, 2.2] +[3.3, 4.4] [5.5, 6.6] */ diff --git a/patterns/strategy/StrategyPattern2.java b/patterns/strategy/StrategyPattern2.java index fca09e50b..640b1c05d 100644 --- a/patterns/strategy/StrategyPattern2.java +++ b/patterns/strategy/StrategyPattern2.java @@ -1,13 +1,15 @@ // patterns/strategy/StrategyPattern2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 { + private Function, List> algorithm; FindMinima2() { leastSquares(); } // default // The various strategies: @@ -32,11 +34,14 @@ public static void main(String[] args) { 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.perturbation(); + System.out.println(solver.minima(line)); solver.bisection(); System.out.println(solver.minima(line)); } } /* Output: [1.1, 2.2] +[3.3, 4.4] [5.5, 6.6] */ diff --git a/patterns/trash/Aluminum.java b/patterns/trash/Aluminum.java index 17e36b269..620cd5e62 100644 --- a/patterns/trash/Aluminum.java +++ b/patterns/trash/Aluminum.java @@ -1,15 +1,16 @@ // patterns/trash/Aluminum.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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; + @Override public double price() { + return Price.ALUMINUM; + } + // Ignore for now; to be used later: + @Override public void accept(Visitor v) { + v.visit(this); } } diff --git a/patterns/trash/Bins.java b/patterns/trash/Bins.java new file mode 100644 index 000000000..304708b39 --- /dev/null +++ b/patterns/trash/Bins.java @@ -0,0 +1,35 @@ +// patterns/trash/Bins.java +// (c)2021 MindView 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; +import java.util.*; + +public class Bins { + final List bin; + final List aluminum = new ArrayList<>(); + final List paper = new ArrayList<>(); + final List glass = new ArrayList<>(); + final List cardboard = new ArrayList<>(); + public Bins(List source) { + bin = new ArrayList<>(source); // Copy + bin.forEach( t -> { + // Use reflection to discover Trash type: + if(t instanceof Aluminum) + aluminum.add((Aluminum)t); + if(t instanceof Paper) + paper.add((Paper)t); + if(t instanceof Glass) + glass.add((Glass)t); + if(t instanceof Cardboard) + cardboard.add((Cardboard)t); + }); + } + public void show() { + TrashValue.sum(aluminum, "Aluminum"); + TrashValue.sum(paper, "Paper"); + TrashValue.sum(glass, "Glass"); + TrashValue.sum(cardboard, "Cardboard"); + TrashValue.sum(bin, "Trash"); + } +} diff --git a/patterns/trash/Cardboard.java b/patterns/trash/Cardboard.java index f15ba6a3b..923f6647e 100644 --- a/patterns/trash/Cardboard.java +++ b/patterns/trash/Cardboard.java @@ -1,15 +1,16 @@ // patterns/trash/Cardboard.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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; + @Override public double price() { + return Price.CARDBOARD; + } + // Ignore for now; to be used later: + @Override public void accept(Visitor v) { + v.visit(this); } } diff --git a/patterns/trash/ClassToListOfTrashMap.java b/patterns/trash/ClassToListOfTrashMap.java new file mode 100644 index 000000000..2095cdd41 --- /dev/null +++ b/patterns/trash/ClassToListOfTrashMap.java @@ -0,0 +1,20 @@ +// patterns/trash/ClassToListOfTrashMap.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// Display a Map>. +package patterns.trash; +import java.util.*; + +public class ClassToListOfTrashMap { + public static void + show(Map> map) { + map.values().forEach( bin -> { + String typeName = "Trash"; + if(!bin.isEmpty()) + typeName = + bin.get(0).getClass().getSimpleName(); + TrashValue.sum(bin, typeName); + }); + } +} diff --git a/patterns/trash/DynaFactory.java b/patterns/trash/DynaFactory.java new file mode 100644 index 000000000..1331e9ba2 --- /dev/null +++ b/patterns/trash/DynaFactory.java @@ -0,0 +1,44 @@ +// patterns/trash/DynaFactory.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// Dynamic discovery of Trash types. +package patterns.trash; +import java.util.*; +import java.util.function.*; +import java.lang.reflect.*; + +public class DynaFactory { + private Map constructors = + new HashMap<>(); + private String packageName; + public DynaFactory(String packageName) { + this.packageName = packageName; + } + @SuppressWarnings("unchecked") + public + T create(TrashInfo info) { + try { + String typename = + "patterns." + packageName + "." + info.type; + return (T)constructors.computeIfAbsent( + typename, this::findConstructor + ).newInstance(info.data); + } catch(Exception e) { + throw new RuntimeException( + "Cannot create() Trash: " + info, e); + } + } + private + Constructor findConstructor(String typename) { + try { + System.out.println("Loading " + typename); + return Class.forName(typename) + .getConstructor(double.class); + } catch(Exception e) { + throw new RuntimeException( + "Trash(double) Constructor Not Found: " + + typename, e); + } + } +} diff --git a/patterns/trash/Fillable.java b/patterns/trash/Fillable.java index f012fe0a0..329c92bdb 100644 --- a/patterns/trash/Fillable.java +++ b/patterns/trash/Fillable.java @@ -1,8 +1,8 @@ // patterns/trash/Fillable.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Any object that can be filled with Trash +// Visit http://OnJava8.com for more book information. +// Any object that can be filled with Trash. package patterns.trash; public interface Fillable { diff --git a/patterns/trash/FillableList.java b/patterns/trash/FillableList.java index 44822abca..8a0bfa745 100644 --- a/patterns/trash/FillableList.java +++ b/patterns/trash/FillableList.java @@ -1,17 +1,18 @@ // patterns/trash/FillableList.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Adapter that makes a List Fillable +// 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; + private List list; + public FillableList(List list) { + this.list = list; + } + @Override public void addTrash(T t) { + list.add(t); } - @Override - public void addTrash(T t) { v.add(t); } } diff --git a/patterns/trash/Glass.java b/patterns/trash/Glass.java index 8b1e21ef4..df08c9963 100644 --- a/patterns/trash/Glass.java +++ b/patterns/trash/Glass.java @@ -1,15 +1,16 @@ // patterns/trash/Glass.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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; + @Override public double price() { + return Price.GLASS; + } + // Ignore for now; to be used later: + @Override public void accept(Visitor v) { + v.visit(this); } } diff --git a/patterns/trash/GroupingBy.java b/patterns/trash/GroupingBy.java new file mode 100644 index 000000000..6c8f8bc67 --- /dev/null +++ b/patterns/trash/GroupingBy.java @@ -0,0 +1,41 @@ +// patterns/trash/GroupingBy.java +// (c)2021 MindView 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.trash.GroupingBy} +package patterns.trash; +import java.util.*; +import java.util.stream.*; + +public class GroupingBy { + public static void main(String[] args) { + List bin = new ArrayList<>(); + ParseTrash.fillBin("trash", bin); + Map> m = + bin.stream().collect( + Collectors.groupingBy(Object::getClass)); + ClassToListOfTrashMap.show(m); + } +} +/* Output: +Loading patterns.trash.Cardboard +Loading patterns.trash.Paper +Loading patterns.trash.Aluminum +Loading patterns.trash.Glass +Glass weight: 5.40 * price: 0.23 = 1.24 +Glass weight: 4.30 * price: 0.23 = 0.99 +Glass weight: 3.60 * price: 0.23 = 0.83 +Total Glass value = 3.06 +Paper weight: 8.00 * price: 0.10 = 0.80 +Paper weight: 6.60 * price: 0.10 = 0.66 +Paper weight: 9.10 * price: 0.10 = 0.91 +Total Paper value = 2.37 +Cardboard weight: 4.40 * price: 0.11 = 0.48 +Cardboard weight: 2.20 * price: 0.11 = 0.24 +Cardboard weight: 1.20 * price: 0.11 = 0.13 +Total Cardboard value = 0.86 +Aluminum weight: 1.80 * price: 1.67 = 3.01 +Aluminum weight: 3.40 * price: 1.67 = 5.68 +Aluminum weight: 2.70 * price: 1.67 = 4.51 +Total Aluminum value = 13.19 +*/ diff --git a/patterns/trash/Paper.java b/patterns/trash/Paper.java index 023da2c81..5a47cea18 100644 --- a/patterns/trash/Paper.java +++ b/patterns/trash/Paper.java @@ -1,15 +1,16 @@ // patterns/trash/Paper.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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; + @Override public double price() { + return Price.PAPER; + } + // Ignore for now; to be used later: + @Override public void accept(Visitor v) { + v.visit(this); } } diff --git a/patterns/trash/ParseTrash.java b/patterns/trash/ParseTrash.java index 69cff8071..0ea5df241 100644 --- a/patterns/trash/ParseTrash.java +++ b/patterns/trash/ParseTrash.java @@ -1,9 +1,10 @@ // patterns/trash/ParseTrash.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Open a file and parse its contents into -// Trash objects, placing each into a List +// Visit http://OnJava8.com for more book information. +// Opens a file and parses its contents into +// Trash objects, placing each into a Fillable. +// {java patterns.trash.ParseTrash} package patterns.trash; import java.util.*; import java.util.stream.*; @@ -12,79 +13,56 @@ import java.nio.file.Files; public class ParseTrash { + public static String source = "Trash.dat"; public static void - fillBin(String pckg, Fillable bin) { + fillBin(String packageName, Fillable bin) { + DynaFactory factory = + new DynaFactory(packageName); try { - Files.lines(Paths.get("..", "trash", "Trash.dat")) - // Remove empty lines and comment lines: + Files.lines(Paths.get("trash", source)) + // Remove comments and empty lines: .filter(line -> line.trim().length() != 0) .filter(line -> !line.startsWith("//")) - .forEach( line -> { - String type = "patterns." + pckg + "." + - line.substring( + .forEach(line -> { + String type = 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))); + bin.addTrash(factory.create( + new TrashInfo(type, weight))); }); - } catch(IOException | - NumberFormatException | - Trash.TrashClassNotFoundException | - Trash.CannotCreateTrashException e) { + } catch(IOException | NumberFormatException e) { throw new RuntimeException(e); } } - // Special case to handle List: + // Special case to handle a List: public static void - fillBin(String pckg, List bin) { - fillBin(pckg, new FillableList<>(bin)); + fillBin(String packageName, List bin) { + fillBin(packageName, new FillableList<>(bin)); } // Basic test: public static void main(String[] args) { - List t = new ArrayList<>(); - fillBin("trash", t); - t.forEach(System.out::println); + List bin = new ArrayList<>(); + fillBin("trash", bin); + bin.forEach(System.out::println); } } /* Output: -Loading patterns.trash.Glass +Loading patterns.trash.Cardboard 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 +Loading patterns.trash.Glass +Cardboard weight: 4.40 * price: 0.11 = 0.48 +Paper weight: 8.00 * price: 0.10 = 0.80 +Aluminum weight: 1.80 * price: 1.67 = 3.01 +Glass weight: 5.40 * price: 0.23 = 1.24 +Aluminum weight: 3.40 * price: 1.67 = 5.68 +Cardboard weight: 2.20 * price: 0.11 = 0.24 +Glass weight: 4.30 * price: 0.23 = 0.99 +Cardboard weight: 1.20 * price: 0.11 = 0.13 +Paper weight: 6.60 * price: 0.10 = 0.66 +Aluminum weight: 2.70 * price: 1.67 = 4.51 +Paper weight: 9.10 * price: 0.10 = 0.91 +Glass weight: 3.60 * price: 0.23 = 0.83 */ diff --git a/patterns/trash/Price.java b/patterns/trash/Price.java new file mode 100644 index 000000000..9aa071816 --- /dev/null +++ b/patterns/trash/Price.java @@ -0,0 +1,13 @@ +// patterns/trash/Price.java +// (c)2021 MindView 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 interface Price { + double + ALUMINUM = 1.67, + PAPER = 0.10, + GLASS = 0.23, + CARDBOARD = 0.11; +} diff --git a/patterns/trash/Trash.dat b/patterns/trash/Trash.dat index 436a7a719..13bd6187a 100644 --- a/patterns/trash/Trash.dat +++ b/patterns/trash/Trash.dat @@ -1,35 +1,13 @@ // 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 +Cardboard:4.4 +Paper:8.0 +Aluminum:1.8 +Glass:5.4 +Aluminum:3.4 +Cardboard:2.2 +Glass:4.3 +Cardboard:1.2 +Paper:6.6 +Aluminum:2.7 +Paper:9.1 +Glass:3.6 diff --git a/patterns/trash/Trash.java b/patterns/trash/Trash.java index 4ecaaf1f3..9f9feca89 100644 --- a/patterns/trash/Trash.java +++ b/patterns/trash/Trash.java @@ -1,91 +1,22 @@ // patterns/trash/Trash.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Base class for Trash recycling examples +// 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); + public final double weight; + public Trash(double weight) { + this.weight = weight; } - @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); + public abstract double price(); + @Override public String toString() { + return String.format( + "%s weight: %.2f * price: %.2f = %.2f", + getClass().getSimpleName(), + weight, price(), weight * price()); } + // Ignore for now; to be used later: + public abstract void accept(Visitor v); } diff --git a/patterns/trash/TrashInfo.java b/patterns/trash/TrashInfo.java new file mode 100644 index 000000000..9adc67882 --- /dev/null +++ b/patterns/trash/TrashInfo.java @@ -0,0 +1,18 @@ +// patterns/trash/TrashInfo.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// Messenger class carrying Trash creation data. +package patterns.trash; + +public class TrashInfo { + public final String type; + public final double data; + public TrashInfo(String type, double data) { + this.type = type; + this.data = data; + } + @Override public String toString() { + return "TrashInfo(" + type + ", " + data + ")"; + } +} diff --git a/patterns/trash/TrashValue.java b/patterns/trash/TrashValue.java new file mode 100644 index 000000000..0ca9caaf0 --- /dev/null +++ b/patterns/trash/TrashValue.java @@ -0,0 +1,21 @@ +// patterns/trash/TrashValue.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// Sums the value of Trash in a bin. +package patterns.trash; +import java.util.*; + +public class TrashValue { + private static double total; + public static void + sum(List bin, String type) { + total = 0.0; + bin.forEach( t -> { + System.out.println(t); + total += t.weight * t.price(); + }); + System.out.printf( + "Total %s value = %.2f%n", type, total); + } +} diff --git a/patterns/trash/TrashVisitor.java b/patterns/trash/TrashVisitor.java new file mode 100644 index 000000000..3f8431e1b --- /dev/null +++ b/patterns/trash/TrashVisitor.java @@ -0,0 +1,104 @@ +// patterns/trash/TrashVisitor.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// Related algorithms packaged in +// each implementation of Visitor. +// {java patterns.trash.TrashVisitor} +package patterns.trash; +import java.util.*; + +class PriceVisitor extends Visitor { + public PriceVisitor() { super("price"); } + @Override public void visit(Aluminum al) { + double price = al.weight * al.price(); + show("Aluminum", price); + alTotal += price; + } + @Override public void visit(Paper p) { + double price = p.weight * p.price(); + show("Paper", price); + pTotal += price; + } + @Override public void visit(Glass g) { + double price = g.weight * g.price(); + show("Glass", price); + gTotal += price; + } + @Override public void visit(Cardboard c) { + double price = c.weight * c.price(); + show("Cardboard", price); + cTotal += price; + } +} + +class WeightVisitor extends Visitor { + public WeightVisitor() { super("weight"); } + @Override public void visit(Aluminum al) { + show("Aluminum", al.weight); + alTotal += al.weight; + } + @Override public void visit(Paper p) { + show("Paper", p.weight); + pTotal += p.weight; + } + @Override public void visit(Glass g) { + show("Glass", g.weight); + gTotal += g.weight; + } + @Override public void visit(Cardboard c) { + show("Cardboard", c.weight); + cTotal += c.weight; + } +} + +public class TrashVisitor { + public static void main(String[] args) { + List bin = new ArrayList<>(); + ParseTrash.fillBin("trash", bin); + List visitors = Arrays.asList( + new PriceVisitor(), new WeightVisitor()); + bin.forEach( + trash -> visitors.forEach(trash::accept) + ); + visitors.forEach(Visitor::total); + } +} +/* Output: +Loading patterns.trash.Cardboard +Loading patterns.trash.Paper +Loading patterns.trash.Aluminum +Loading patterns.trash.Glass +Cardboard price: 0.48 +Cardboard weight: 4.40 +Paper price: 0.80 +Paper weight: 8.00 +Aluminum price: 3.01 +Aluminum weight: 1.80 +Glass price: 1.24 +Glass weight: 5.40 +Aluminum price: 5.68 +Aluminum weight: 3.40 +Cardboard price: 0.24 +Cardboard weight: 2.20 +Glass price: 0.99 +Glass weight: 4.30 +Cardboard price: 0.13 +Cardboard weight: 1.20 +Paper price: 0.66 +Paper weight: 6.60 +Aluminum price: 4.51 +Aluminum weight: 2.70 +Paper price: 0.91 +Paper weight: 9.10 +Glass price: 0.83 +Glass weight: 3.60 +Total Aluminum price: 13.19 +Total Paper price: 2.37 +Total Glass price: 3.06 +Total Cardboard price: 0.86 +Total Aluminum weight: 7.90 +Total Paper weight: 23.70 +Total Glass weight: 13.30 +Total Cardboard weight: 7.80 +*/ diff --git a/patterns/trash/TypeMapTrash.java b/patterns/trash/TypeMapTrash.java new file mode 100644 index 000000000..bd04ab1de --- /dev/null +++ b/patterns/trash/TypeMapTrash.java @@ -0,0 +1,52 @@ +// patterns/trash/TypeMapTrash.java +// (c)2021 MindView 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 reflection to sort +// Trash into Lists. This is extensible, despite +// the use of reflection. +// {java patterns.trash.TypeMapTrash} +package patterns.trash; +import patterns.TypeMap; + +// Adapter class for ParseTrash.fillBin(): +class TypeMapAdapter implements Fillable { + private TypeMap map; + TypeMapAdapter(TypeMap map) { + this.map = map; + } + @Override + public void addTrash(Trash t) { map.add(t); } +} + +public class TypeMapTrash { + @SuppressWarnings("unchecked") + public static void main(String[] args) { + TypeMap bin = new TypeMap<>(); + ParseTrash.fillBin( + "trash", new TypeMapAdapter(bin)); + ClassToListOfTrashMap.show(bin.map); + } +} +/* Output: +Loading patterns.trash.Cardboard +Loading patterns.trash.Paper +Loading patterns.trash.Aluminum +Loading patterns.trash.Glass +Paper weight: 8.00 * price: 0.10 = 0.80 +Paper weight: 6.60 * price: 0.10 = 0.66 +Paper weight: 9.10 * price: 0.10 = 0.91 +Total Paper value = 2.37 +Glass weight: 5.40 * price: 0.23 = 1.24 +Glass weight: 4.30 * price: 0.23 = 0.99 +Glass weight: 3.60 * price: 0.23 = 0.83 +Total Glass value = 3.06 +Aluminum weight: 1.80 * price: 1.67 = 3.01 +Aluminum weight: 3.40 * price: 1.67 = 5.68 +Aluminum weight: 2.70 * price: 1.67 = 4.51 +Total Aluminum value = 13.19 +Cardboard weight: 4.40 * price: 0.11 = 0.48 +Cardboard weight: 2.20 * price: 0.11 = 0.24 +Cardboard weight: 1.20 * price: 0.11 = 0.13 +Total Cardboard value = 0.86 +*/ diff --git a/patterns/trash/Visitor.java b/patterns/trash/Visitor.java new file mode 100644 index 000000000..34f0fff83 --- /dev/null +++ b/patterns/trash/Visitor.java @@ -0,0 +1,31 @@ +// patterns/trash/Visitor.java +// (c)2021 MindView 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 class for Visitors. +package patterns.trash; + +public abstract class Visitor { + protected double alTotal; // Aluminum + protected double pTotal; // Paper + protected double gTotal; // Glass + protected double cTotal; // Cardboard + protected String descriptor; + protected Visitor(String descriptor) { + this.descriptor = descriptor; + } + protected void show(String type, double value) { + System.out.printf( + "%s %s: %.2f%n", type, descriptor, value); + } + public void total() { + show("Total Aluminum", alTotal); + show("Total Paper", pTotal); + show("Total Glass", gTotal); + show("Total Cardboard", cTotal); + } + abstract void visit(Aluminum a); + abstract void visit(Paper p); + abstract void visit(Glass g); + abstract void visit(Cardboard c); +} diff --git a/patterns/trashvisitor/Aluminum.java b/patterns/trashvisitor/Aluminum.java deleted file mode 100644 index f2444f224..000000000 --- a/patterns/trashvisitor/Aluminum.java +++ /dev/null @@ -1,16 +0,0 @@ -// patterns/trashvisitor/Aluminum.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ 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/patterns/trashvisitor/Cardboard.java b/patterns/trashvisitor/Cardboard.java deleted file mode 100644 index 815e3b957..000000000 --- a/patterns/trashvisitor/Cardboard.java +++ /dev/null @@ -1,16 +0,0 @@ -// patterns/trashvisitor/Cardboard.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ 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/patterns/trashvisitor/Glass.java b/patterns/trashvisitor/Glass.java deleted file mode 100644 index 85b77a41c..000000000 --- a/patterns/trashvisitor/Glass.java +++ /dev/null @@ -1,16 +0,0 @@ -// patterns/trashvisitor/Glass.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ 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/patterns/trashvisitor/Paper.java b/patterns/trashvisitor/Paper.java deleted file mode 100644 index 891478231..000000000 --- a/patterns/trashvisitor/Paper.java +++ /dev/null @@ -1,16 +0,0 @@ -// patterns/trashvisitor/Paper.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ 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/patterns/trashvisitor/TrashVisitor.java b/patterns/trashvisitor/TrashVisitor.java deleted file mode 100644 index 5089fbf92..000000000 --- a/patterns/trashvisitor/TrashVisitor.java +++ /dev/null @@ -1,126 +0,0 @@ -// patterns/trashvisitor/TrashVisitor.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -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/patterns/trashvisitor/Visitable.java b/patterns/trashvisitor/Visitable.java deleted file mode 100644 index b32d9b387..000000000 --- a/patterns/trashvisitor/Visitable.java +++ /dev/null @@ -1,12 +0,0 @@ -// patterns/trashvisitor/Visitable.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// An interface to add visitor functionality to the -// Trash hierarchy without modifying the base class -package patterns.trashvisitor; - -interface Visitable { - // The new method: - void accept(Visitor v); -} diff --git a/patterns/trashvisitor/Visitor.java b/patterns/trashvisitor/Visitor.java deleted file mode 100644 index 9344a8c1c..000000000 --- a/patterns/trashvisitor/Visitor.java +++ /dev/null @@ -1,14 +0,0 @@ -// patterns/trashvisitor/Visitor.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// The base interface for visitors -package patterns.trashvisitor; - -interface Visitor { - void visit(Aluminum a); - void visit(Paper p); - void visit(Glass g); - void visit(Cardboard c); - void total(); -} diff --git a/patterns/visitor/BeeAndFlowers.java b/patterns/visitor/BeeAndFlowers.java index a8a9acafd..395966190 100644 --- a/patterns/visitor/BeeAndFlowers.java +++ b/patterns/visitor/BeeAndFlowers.java @@ -1,8 +1,9 @@ // patterns/visitor/BeeAndFlowers.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Demonstration of "visitor" pattern +// Visit http://OnJava8.com for more book information. +// Demonstration of the Visitor pattern. +// {java patterns.visitor.BeeAndFlowers} package patterns.visitor; import java.util.*; import java.util.function.*; @@ -10,7 +11,7 @@ interface Visitor { void visit(Gladiolus g); - void visit(Renuculus r); + void visit(Ranunculus r); void visit(Chrysanthemum c); } @@ -24,7 +25,7 @@ class Gladiolus implements Flower { public void accept(Visitor v) { v.visit(this);} } -class Renuculus implements Flower { +class Ranunculus implements Flower { @Override public void accept(Visitor v) { v.visit(this);} } @@ -36,35 +37,28 @@ class Chrysanthemum implements Flower { // 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) { + private 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(Ranunculus r) { + s = "Ranunculus"; } - @Override - public void visit(Chrysanthemum c) { + @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) { + @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(Ranunculus r) { + System.out.println("Bee and Ranunculus"); } - @Override - public void visit(Chrysanthemum c) { + @Override public void visit(Chrysanthemum c) { System.out.println("Bee and Chrysanthemum"); } } @@ -72,11 +66,12 @@ public void visit(Chrysanthemum c) { class FlowerFactory { static List> flowers = Arrays.asList(Gladiolus::new, - Renuculus::new, Chrysanthemum::new); - final static int sz = flowers.size(); - private static SplittableRandom rand = new SplittableRandom(47); + Ranunculus::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(); + return flowers.get(rand.nextInt(SZ)).get(); } } @@ -97,24 +92,24 @@ public static void main(String[] args) { } } /* Output: +Gladiolus Chrysanthemum +Gladiolus +Ranunculus Chrysanthemum -Renuculus +Ranunculus Chrysanthemum -Renuculus Chrysanthemum -Renuculus Chrysanthemum -Gladiolus -Renuculus +Ranunculus +Bee and Gladiolus Bee and Chrysanthemum +Bee and Gladiolus +Bee and Ranunculus Bee and Chrysanthemum -Bee and Renuculus +Bee and Ranunculus Bee and Chrysanthemum -Bee and Renuculus Bee and Chrysanthemum -Bee and Renuculus Bee and Chrysanthemum -Bee and Gladiolus -Bee and Renuculus +Bee and Ranunculus */ diff --git a/patterns/visualobserver/BoxObserver.java b/patterns/visualobserver/BoxObserver.java deleted file mode 100644 index 4c2e32a99..000000000 --- a/patterns/visualobserver/BoxObserver.java +++ /dev/null @@ -1,89 +0,0 @@ -// patterns/visualobserver/BoxObserver.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Demonstration of Observer pattern using -// Java's built-in observer classes -// {TimeOut:4000} During testing -package patterns.visualobserver; -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import java.util.*; -import onjava.MouseClick; - -// You must inherit a new type of Observable: -class BoxObservable extends Observable { - @Override - public void notifyObservers(Object b) { - // Otherwise it won't propagate changes: - setChanged(); - super.notifyObservers(b); - } -} - -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) { - 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); - } -} - -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/polymorphism/CovariantReturn.java b/polymorphism/CovariantReturn.java index aaa633664..5b46602aa 100644 --- a/polymorphism/CovariantReturn.java +++ b/polymorphism/CovariantReturn.java @@ -1,16 +1,18 @@ // polymorphism/CovariantReturn.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class Grain { - @Override - public String toString() { return "Grain"; } + @Override public String toString() { + return "Grain"; + } } class Wheat extends Grain { - @Override - public String toString() { return "Wheat"; } + @Override public String toString() { + return "Wheat"; + } } class Mill { @@ -18,8 +20,9 @@ class Mill { } class WheatMill extends Mill { - @Override - Wheat process() { return new Wheat(); } + @Override Wheat process() { + return new Wheat(); + } } public class CovariantReturn { diff --git a/polymorphism/FieldAccess.java b/polymorphism/FieldAccess.java index 9bbaa27c1..e6b39229f 100644 --- a/polymorphism/FieldAccess.java +++ b/polymorphism/FieldAccess.java @@ -1,7 +1,7 @@ // polymorphism/FieldAccess.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Direct field access is determined at compile time class Super { @@ -11,8 +11,7 @@ class Super { class Sub extends Super { public int field = 1; - @Override - public int getField() { return field; } + @Override public int getField() { return field; } public int getSuperField() { return super.field; } } @@ -31,5 +30,6 @@ public static void main(String[] args) { } /* Output: sup.field = 0, sup.getField() = 1 -sub.field = 1, sub.getField() = 1, sub.getSuperField() = 0 +sub.field = 1, sub.getField() = 1, sub.getSuperField() += 0 */ diff --git a/polymorphism/Frog.java b/polymorphism/Frog.java index e29d037ab..eb0669f25 100644 --- a/polymorphism/Frog.java +++ b/polymorphism/Frog.java @@ -1,8 +1,9 @@ // polymorphism/Frog.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Cleanup and inheritance +// {java polymorphism.Frog} package polymorphism; class Characteristic { @@ -48,8 +49,7 @@ class Animal extends LivingCreature { private Description t = new Description("Animal not Vegetable"); Animal() { System.out.println("Animal()"); } - @Override - protected void dispose() { + @Override protected void dispose() { System.out.println("Animal dispose"); t.dispose(); p.dispose(); @@ -65,8 +65,7 @@ class Amphibian extends Animal { Amphibian() { System.out.println("Amphibian()"); } - @Override - protected void dispose() { + @Override protected void dispose() { System.out.println("Amphibian dispose"); t.dispose(); p.dispose(); @@ -75,11 +74,11 @@ protected void dispose() { } public class Frog extends Amphibian { - private Characteristic p = new Characteristic("Croaks"); + private Characteristic p = + new Characteristic("Croaks"); private Description t = new Description("Eats Bugs"); public Frog() { System.out.println("Frog()"); } - @Override - protected void dispose() { + @Override protected void dispose() { System.out.println("Frog dispose"); t.dispose(); p.dispose(); diff --git a/polymorphism/PolyConstructors.java b/polymorphism/PolyConstructors.java index cfc432d41..8a6d6ed5c 100644 --- a/polymorphism/PolyConstructors.java +++ b/polymorphism/PolyConstructors.java @@ -1,7 +1,7 @@ // polymorphism/PolyConstructors.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Constructors and polymorphism // don't produce what you might expect @@ -21,8 +21,7 @@ class RoundGlyph extends Glyph { System.out.println( "RoundGlyph.RoundGlyph(), radius = " + radius); } - @Override - void draw() { + @Override void draw() { System.out.println( "RoundGlyph.draw(), radius = " + radius); } diff --git a/polymorphism/PrivateOverride.java b/polymorphism/PrivateOverride.java index 167b3fc13..59aba4ed2 100644 --- a/polymorphism/PrivateOverride.java +++ b/polymorphism/PrivateOverride.java @@ -1,12 +1,15 @@ // polymorphism/PrivateOverride.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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()"); } + private void f() { + System.out.println("private f()"); + } public static void main(String[] args) { PrivateOverride po = new Derived(); po.f(); diff --git a/polymorphism/PrivateOverride2.java b/polymorphism/PrivateOverride2.java index a3d31fe08..d53d9a256 100644 --- a/polymorphism/PrivateOverride2.java +++ b/polymorphism/PrivateOverride2.java @@ -1,13 +1,15 @@ // polymorphism/PrivateOverride2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Detecting a mistaken override using @Override -// {CompileTimeError} (Won't compile) +// {WillNotCompile} package polymorphism; public class PrivateOverride2 { - private void f() { System.out.println("private f()"); } + private void f() { + System.out.println("private f()"); + } public static void main(String[] args) { PrivateOverride2 po = new Derived2(); po.f(); @@ -15,6 +17,7 @@ public static void main(String[] args) { } class Derived2 extends PrivateOverride2 { - @Override - public void f() { System.out.println("public f()"); } + @Override public void f() { + System.out.println("public f()"); + } } diff --git a/polymorphism/ReferenceCounting.java b/polymorphism/ReferenceCounting.java index 093e0198c..634cd8c6c 100644 --- a/polymorphism/ReferenceCounting.java +++ b/polymorphism/ReferenceCounting.java @@ -1,14 +1,14 @@ // polymorphism/ReferenceCounting.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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++; - public Shared() { + Shared() { System.out.println("Creating " + this); } public void addRef() { refcount++; } @@ -16,8 +16,7 @@ protected void dispose() { if(--refcount == 0) System.out.println("Disposing " + this); } - @Override - public String toString() { + @Override public String toString() { return "Shared " + id; } } @@ -26,7 +25,7 @@ class Composing { private Shared shared; private static long counter = 0; private final long id = counter++; - public Composing(Shared shared) { + Composing(Shared shared) { System.out.println("Creating " + this); this.shared = shared; this.shared.addRef(); @@ -35,8 +34,7 @@ protected void dispose() { System.out.println("disposing " + this); shared.dispose(); } - @Override - public String toString() { + @Override public String toString() { return "Composing " + id; } } diff --git a/polymorphism/RTTI.java b/polymorphism/Reflect.java similarity index 53% rename from polymorphism/RTTI.java rename to polymorphism/Reflect.java index 9532abe34..341e86f68 100644 --- a/polymorphism/RTTI.java +++ b/polymorphism/Reflect.java @@ -1,8 +1,7 @@ -// polymorphism/RTTI.java -// (c)2016 MindView LLC: see Copyright.txt +// polymorphism/Reflect.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Downcasting & Runtime type information (RTTI) +// Visit http://OnJava8.com for more book information. // {ThrowsException} class Useful { @@ -11,16 +10,14 @@ public void g() {} } class MoreUseful extends Useful { - @Override - public void f() {} - @Override - public void g() {} + @Override public void f() {} + @Override public void g() {} public void u() {} public void v() {} public void w() {} } -public class RTTI { +public class Reflect { public static void main(String[] args) { Useful[] x = { new Useful(), @@ -30,14 +27,14 @@ public static void main(String[] args) { x[1].g(); // Compile time: method not found in Useful: //- x[1].u(); - ((MoreUseful)x[1]).u(); // Downcast/RTTI + ((MoreUseful)x[1]).u(); // Downcast/Reflect ((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) -___[ Exception is Expected ]___ +Exception in thread "main" +java.lang.ClassCastException: Useful cannot be cast to +MoreUseful + at Reflect.main(Reflect.java:28) */ diff --git a/polymorphism/Sandwich.java b/polymorphism/Sandwich.java index 987fbafe0..ef39bcbae 100644 --- a/polymorphism/Sandwich.java +++ b/polymorphism/Sandwich.java @@ -1,8 +1,9 @@ // polymorphism/Sandwich.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Order of constructor calls +// {java polymorphism.Sandwich} package polymorphism; class Meal { diff --git a/polymorphism/Shapes.java b/polymorphism/Shapes.java index 2fb4dbd5a..17d82061e 100644 --- a/polymorphism/Shapes.java +++ b/polymorphism/Shapes.java @@ -1,7 +1,7 @@ // polymorphism/Shapes.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Polymorphism in Java import polymorphism.shape.*; diff --git a/polymorphism/StaticPolymorphism.java b/polymorphism/StaticPolymorphism.java index 1822d0ec7..2a7309f7e 100644 --- a/polymorphism/StaticPolymorphism.java +++ b/polymorphism/StaticPolymorphism.java @@ -1,7 +1,7 @@ // polymorphism/StaticPolymorphism.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Static methods are not polymorphic class StaticSuper { @@ -17,8 +17,7 @@ class StaticSub extends StaticSuper { public static String staticGet() { return "Derived staticGet()"; } - @Override - public String dynamicGet() { + @Override public String dynamicGet() { return "Derived dynamicGet()"; } } diff --git a/polymorphism/Transmogrify.java b/polymorphism/Transmogrify.java index 1fecf202e..4dbcdeb4b 100644 --- a/polymorphism/Transmogrify.java +++ b/polymorphism/Transmogrify.java @@ -1,7 +1,7 @@ // polymorphism/Transmogrify.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Dynamically changing the behavior of an object // via composition (the "State" design pattern) @@ -10,15 +10,13 @@ public void act() {} } class HappyActor extends Actor { - @Override - public void act() { + @Override public void act() { System.out.println("HappyActor"); } } class SadActor extends Actor { - @Override - public void act() { + @Override public void act() { System.out.println("SadActor"); } } diff --git a/polymorphism/build.xml b/polymorphism/build.xml deleted file mode 100644 index 5a425ef33..000000000 --- a/polymorphism/build.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/polymorphism/music/Instrument.java b/polymorphism/music/Instrument.java index 72bee5f6a..907b3566f 100644 --- a/polymorphism/music/Instrument.java +++ b/polymorphism/music/Instrument.java @@ -1,7 +1,7 @@ // polymorphism/music/Instrument.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package polymorphism.music; class Instrument { diff --git a/polymorphism/music/Music.java b/polymorphism/music/Music.java index fd6574ba3..fb92e0099 100644 --- a/polymorphism/music/Music.java +++ b/polymorphism/music/Music.java @@ -1,8 +1,9 @@ // polymorphism/music/Music.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Inheritance & upcasting +// {java polymorphism.music.Music} package polymorphism.music; public class Music { diff --git a/polymorphism/music/Music2.java b/polymorphism/music/Music2.java index 2f7188883..790adcf5d 100644 --- a/polymorphism/music/Music2.java +++ b/polymorphism/music/Music2.java @@ -1,20 +1,19 @@ // polymorphism/music/Music2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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) { + @Override public void play(Note n) { System.out.println("Stringed.play() " + n); } } class Brass extends Instrument { - @Override - public void play(Note n) { + @Override public void play(Note n) { System.out.println("Brass.play() " + n); } } diff --git a/polymorphism/music/Note.java b/polymorphism/music/Note.java index 72903e392..6963bc15a 100644 --- a/polymorphism/music/Note.java +++ b/polymorphism/music/Note.java @@ -1,7 +1,7 @@ // polymorphism/music/Note.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Notes to play on musical instruments package polymorphism.music; diff --git a/polymorphism/music/Wind.java b/polymorphism/music/Wind.java index 620a8f9f8..6e48f513b 100644 --- a/polymorphism/music/Wind.java +++ b/polymorphism/music/Wind.java @@ -1,15 +1,14 @@ // polymorphism/music/Wind.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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) { + @Override public void play(Note n) { System.out.println("Wind.play() " + n); } } diff --git a/polymorphism/music3/Music3.java b/polymorphism/music3/Music3.java index eb6e02906..97938dd01 100644 --- a/polymorphism/music3/Music3.java +++ b/polymorphism/music3/Music3.java @@ -1,8 +1,9 @@ // polymorphism/music3/Music3.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // An extensible program +// {java polymorphism.music3.Music3} package polymorphism.music3; import polymorphism.music.Note; @@ -17,62 +18,49 @@ void adjust() { } class Wind extends Instrument { - @Override - void play(Note n) { + @Override void play(Note n) { System.out.println("Wind.play() " + n); } - @Override - String what() { return "Wind"; } - @Override - void adjust() { + @Override String what() { return "Wind"; } + @Override void adjust() { System.out.println("Adjusting Wind"); } } class Percussion extends Instrument { - @Override - void play(Note n) { + @Override void play(Note n) { System.out.println("Percussion.play() " + n); } - @Override - String what() { return "Percussion"; } - @Override - void adjust() { + @Override String what() { return "Percussion"; } + @Override void adjust() { System.out.println("Adjusting Percussion"); } } class Stringed extends Instrument { - @Override - void play(Note n) { + @Override void play(Note n) { System.out.println("Stringed.play() " + n); } - @Override - String what() { return "Stringed"; } - @Override - void adjust() { + @Override String what() { return "Stringed"; } + @Override void adjust() { System.out.println("Adjusting Stringed"); } } class Brass extends Wind { - @Override - void play(Note n) { + @Override void play(Note n) { System.out.println("Brass.play() " + n); } - @Override - void adjust() { + @Override void adjust() { System.out.println("Adjusting Brass"); } } class Woodwind extends Wind { - @Override - void play(Note n) { + @Override void play(Note n) { System.out.println("Woodwind.play() " + n); } - @Override - String what() { return "Woodwind"; } + @Override String what() { return "Woodwind"; } } public class Music3 { diff --git a/polymorphism/shape/Circle.java b/polymorphism/shape/Circle.java index 50f392cd3..9b97edaed 100644 --- a/polymorphism/shape/Circle.java +++ b/polymorphism/shape/Circle.java @@ -1,16 +1,14 @@ // polymorphism/shape/Circle.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package polymorphism.shape; public class Circle extends Shape { - @Override - public void draw() { + @Override public void draw() { System.out.println("Circle.draw()"); } - @Override - public void erase() { + @Override public void erase() { System.out.println("Circle.erase()"); } } diff --git a/polymorphism/shape/RandomShapes.java b/polymorphism/shape/RandomShapes.java index 47d940398..03120f5ea 100644 --- a/polymorphism/shape/RandomShapes.java +++ b/polymorphism/shape/RandomShapes.java @@ -1,7 +1,7 @@ // polymorphism/shape/RandomShapes.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // A "factory" that randomly creates shapes package polymorphism.shape; import java.util.*; diff --git a/polymorphism/shape/Shape.java b/polymorphism/shape/Shape.java index bcc9333f0..d78c6dd9e 100644 --- a/polymorphism/shape/Shape.java +++ b/polymorphism/shape/Shape.java @@ -1,7 +1,7 @@ // polymorphism/shape/Shape.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package polymorphism.shape; public class Shape { diff --git a/polymorphism/shape/Square.java b/polymorphism/shape/Square.java index 35b30f4f7..fb4802b10 100644 --- a/polymorphism/shape/Square.java +++ b/polymorphism/shape/Square.java @@ -1,16 +1,14 @@ // polymorphism/shape/Square.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package polymorphism.shape; public class Square extends Shape { - @Override - public void draw() { + @Override public void draw() { System.out.println("Square.draw()"); } - @Override - public void erase() { + @Override public void erase() { System.out.println("Square.erase()"); } } diff --git a/polymorphism/shape/Triangle.java b/polymorphism/shape/Triangle.java index 077f7cac7..baebbf870 100644 --- a/polymorphism/shape/Triangle.java +++ b/polymorphism/shape/Triangle.java @@ -1,16 +1,14 @@ // polymorphism/shape/Triangle.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package polymorphism.shape; public class Triangle extends Shape { - @Override - public void draw() { + @Override public void draw() { System.out.println("Triangle.draw()"); } - @Override - public void erase() { + @Override public void erase() { System.out.println("Triangle.erase()"); } } diff --git a/preferences/PreferencesDemo.java b/preferences/PreferencesDemo.java deleted file mode 100644 index 0b05105a2..000000000 --- a/preferences/PreferencesDemo.java +++ /dev/null @@ -1,35 +0,0 @@ -// preferences/PreferencesDemo.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.prefs.*; - -public class PreferencesDemo { - public static void - main(String[] args) throws Exception { - Preferences prefs = Preferences - .userNodeForPackage(PreferencesDemo.class); - prefs.put("Location", "Oz"); - prefs.put("Footwear", "Ruby Slippers"); - prefs.putInt("Companions", 4); - prefs.putBoolean("Are there witches?", true); - int usageCount = prefs.getInt("UsageCount", 0); - usageCount++; - prefs.putInt("UsageCount", usageCount); - for(String key : prefs.keys()) - System.out.println(key + ": " - + prefs.get(key, null)); - // You must always provide a default value: - System.out.println( - "How many companions does Dorothy have? " + - prefs.getInt("Companions", 0)); - } -} -/* Output: -Location: Oz -Footwear: Ruby Slippers -Companions: 4 -Are there witches?: true -UsageCount: 33 -How many companions does Dorothy have? 4 -*/ diff --git a/preferences/build.xml b/preferences/build.xml deleted file mode 100644 index 7e888156f..000000000 --- a/preferences/build.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/references/AddingClone.java b/references/AddingClone.java index 7fb3ba179..298b78bf3 100644 --- a/references/AddingClone.java +++ b/references/AddingClone.java @@ -1,21 +1,20 @@ // references/AddingClone.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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; - public Int2(int ii) { i = ii; } + Int2(int ii) { i = ii; } public void increment() { i++; } - @Override - public String toString() { + @Override public String toString() { return Integer.toString(i); } - @Override - public Int2 clone() { + @Override public Int2 clone() { try { return (Int2)super.clone(); } catch(CloneNotSupportedException e) { @@ -27,7 +26,7 @@ public Int2 clone() { // Inheritance doesn't remove cloneability: class Int3 extends Int2 { private int j; // Automatically duplicated - public Int3(int i) { super(i); } + Int3(int i) { super(i); } } public class AddingClone { @@ -41,18 +40,18 @@ public static void main(String[] args) { // Anything inherited is also cloneable: Int3 x3 = new Int3(7); x3 = (Int3)x3.clone(); - ArrayList v = new ArrayList<>(); - for(int i = 0; i < 10; i++ ) - v.add(new Int2(i)); + 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: - for(int i = 0; i < v.size(); i++) - v2.set(i, v2.get(i).clone()); + IntStream.range(0, v.size()) + .forEach(i -> v2.set(i, v.get(i).clone())); // Increment all v2's elements: - for(Int2 i2 : v2) - i2.increment(); + v2.forEach(Int2::increment); System.out.println("v2: " + v2); // See if it changed v's elements: System.out.println("v: " + v); diff --git a/references/Alias1.java b/references/Alias1.java index a2211dc11..e3cd047b7 100644 --- a/references/Alias1.java +++ b/references/Alias1.java @@ -1,7 +1,7 @@ // references/Alias1.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Aliasing two references to one object public class Alias1 { @@ -9,11 +9,11 @@ public class Alias1 { public Alias1(int ii) { i = ii; } public static void main(String[] args) { Alias1 x = new Alias1(7); - Alias1 y = x; // Assign the reference (1) + 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) + x.i++; // [2] System.out.println("x: " + x.i); System.out.println("y: " + y.i); } diff --git a/references/Alias2.java b/references/Alias2.java index 5a0494a2e..789724697 100644 --- a/references/Alias2.java +++ b/references/Alias2.java @@ -1,7 +1,7 @@ // references/Alias2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Method calls implicitly alias their arguments public class Alias2 { diff --git a/references/CheckCloneable.java b/references/CheckCloneable.java index 4571dcfea..0293b5cef 100644 --- a/references/CheckCloneable.java +++ b/references/CheckCloneable.java @@ -1,7 +1,7 @@ // references/CheckCloneable.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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(): @@ -46,8 +46,7 @@ private BackOn duplicate(BackOn b) { // copy. A dummy copy, just to make a point: return new BackOn(); } - @Override - public Object clone() { + @Override public Object clone() { // Doesn't call NoMore.clone(): return duplicate(this); } diff --git a/references/CloneArrayList.java b/references/CloneArrayList.java index 44209e8a9..811dd419c 100644 --- a/references/CloneArrayList.java +++ b/references/CloneArrayList.java @@ -1,32 +1,32 @@ // references/CloneArrayList.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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; - public Int(int ii) { i = ii; } + Int(int ii) { i = ii; } public void increment() { i++; } - @Override - public String toString() { + @Override public String toString() { return Integer.toString(i); } } public class CloneArrayList { public static void main(String[] args) { - ArrayList v = new ArrayList<>(); - for(int i = 0; i < 10; i++) - v.add(new Int(i)); + 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: - for(Int e : v2) - e.increment(); + v2.forEach(Int::increment); // See if it changed v's elements: System.out.println("v: " + v); } diff --git a/references/Compete.java b/references/Compete.java index e673b7677..9a37c00af 100644 --- a/references/Compete.java +++ b/references/Compete.java @@ -1,8 +1,9 @@ // references/Compete.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.io.*; +import onjava.Timer; class Thing1 implements Serializable {} class Thing2 implements Serializable { @@ -10,8 +11,7 @@ class Thing2 implements Serializable { } class Thing3 implements Cloneable { - @Override - public Thing3 clone() { + @Override public Thing3 clone() { try { return (Thing3)super.clone(); } catch(CloneNotSupportedException e) { @@ -22,8 +22,7 @@ public Thing3 clone() { class Thing4 implements Cloneable { private Thing3 t3 = new Thing3(); - @Override - public Thing4 clone() { + @Override public Thing4 clone() { Thing4 t4 = null; try { t4 = (Thing4)super.clone(); @@ -46,41 +45,43 @@ public class Compete { Thing4[] b = new Thing4[SIZE]; for(int i = 0; i < SIZE; i++) b[i] = new Thing4(); - long t1 = System.currentTimeMillis(); - try(ByteArrayOutputStream buf = - new ByteArrayOutputStream(); - ObjectOutputStream oos = - new ObjectOutputStream(buf)) { + 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()))) { + 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(); } } - long t2 = System.currentTimeMillis(); System.out.println( "Duplication via serialization: " + - (t2 - t1) + " Milliseconds"); + timer.duration() + " Milliseconds"); // Now try cloning: - t1 = System.currentTimeMillis(); + timer = new Timer(); Thing4[] d = new Thing4[SIZE]; for(int i = 0; i < SIZE; i++) d[i] = b[i].clone(); - t2 = System.currentTimeMillis(); System.out.println( "Duplication via cloning: " + - (t2 - t1) + " Milliseconds"); + timer.duration() + " Milliseconds"); } } /* Output: -Duplication via serialization: 202 Milliseconds -Duplication via cloning: 17 Milliseconds +Duplication via serialization: 385 Milliseconds +Duplication via cloning: 38 Milliseconds */ diff --git a/references/CopyConstructor.java b/references/CopyConstructor.java index 3d9106206..fe16259fa 100644 --- a/references/CopyConstructor.java +++ b/references/CopyConstructor.java @@ -1,7 +1,7 @@ // references/CopyConstructor.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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.*; @@ -13,14 +13,14 @@ class FruitQualities { private int ripeness; private int smell; // etc. - // No-arg constructor: - public FruitQualities() { + // Zero-argument constructor: + FruitQualities() { // Do something meaningful... } // Other constructors: // ... // Copy constructor: - public FruitQualities(FruitQualities f) { + FruitQualities(FruitQualities f) { weight = f.weight; color = f.color; firmness = f.firmness; @@ -32,15 +32,15 @@ public FruitQualities(FruitQualities f) { class Seed { // Members... - public Seed() { /* No-arg constructor */ } - public Seed(Seed s) { /* Copy constructor */ } + Seed() { /* Zero-argument constructor */ } + Seed(Seed s) { /* Copy constructor */ } } class Fruit { private FruitQualities fq; private int seeds; private Seed[] s; - public Fruit(FruitQualities q, int seedCount) { + Fruit(FruitQualities q, int seedCount) { fq = q; seeds = seedCount; s = new Seed[seeds]; @@ -50,7 +50,7 @@ public Fruit(FruitQualities q, int seedCount) { // Other constructors: // ... // Copy constructor: - public Fruit(Fruit f) { + Fruit(Fruit f) { fq = new FruitQualities(f.fq); seeds = f.seeds; s = new Seed[seeds]; @@ -70,10 +70,10 @@ protected FruitQualities getQualities() { } class Tomato extends Fruit { - public Tomato() { + Tomato() { super(new FruitQualities(), 100); } - public Tomato(Tomato t) { // Copy-constructor + Tomato(Tomato t) { // Copy-constructor super(t); // Upcast to base copy-constructor // Other copy-construction activities... } @@ -81,22 +81,22 @@ public Tomato(Tomato t) { // Copy-constructor class ZebraQualities extends FruitQualities { private int stripedness; - // No-arg constructor: - public ZebraQualities() { + // Zero-argument constructor: + ZebraQualities() { super(); // do something meaningful... } - public ZebraQualities(ZebraQualities z) { + ZebraQualities(ZebraQualities z) { super(z); stripedness = z.stripedness; } } class GreenZebra extends Tomato { - public GreenZebra() { + GreenZebra() { addQualities(new ZebraQualities()); } - public GreenZebra(GreenZebra g) { + GreenZebra(GreenZebra g) { super(g); // Calls Tomato(Tomato) // Restore the right qualities: addQualities(new ZebraQualities()); @@ -112,12 +112,12 @@ public void evaluate() { public class CopyConstructor { public static void ripen(Tomato t) { // Use the "copy constructor": - t = new Tomato(t); // (1) + 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); // Hmmm... will this work? (2) + f = new Fruit(f); // Hmm... will this work? // [2] System.out.println("In slice, f is a " + f.getClass().getName()); } @@ -177,10 +177,12 @@ public static void main(String[] args) { /* Output: In ripen, t is a Tomato In slice, f is a Fruit -In ripen2, t is a Tomato -In slice2, f is a Tomato +java.lang.NoSuchMethodException: Tomato.(Tomato) +java.lang.NoSuchMethodException: Tomato.(Tomato) In ripen, t is a Tomato In slice, f is a Fruit -In ripen2, t is a GreenZebra -In slice2, f is a GreenZebra +java.lang.NoSuchMethodException: +GreenZebra.(GreenZebra) +java.lang.NoSuchMethodException: +GreenZebra.(GreenZebra) */ diff --git a/references/DeepCopy.java b/references/DeepCopy.java deleted file mode 100644 index 0976d6dc6..000000000 --- a/references/DeepCopy.java +++ /dev/null @@ -1,125 +0,0 @@ -// references/DeepCopy.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Cloning a composed object -// (Install libraries from junit.org) -import org.junit.Test; -import static org.junit.Assert.assertEquals; - -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); - } -} - -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); - } -} - -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; - } -} - -public class DeepCopy { - @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"); - } - public static void main(String[] args) { - org.junit.runner.JUnitCore.runClasses( - DeepCopy.class); - } -} diff --git a/references/DepthReading.java b/references/DepthReading.java new file mode 100644 index 000000000..46c14fd69 --- /dev/null +++ b/references/DepthReading.java @@ -0,0 +1,27 @@ +// references/DepthReading.java +// (c)2021 MindView 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/references/HorrorFlick.java b/references/HorrorFlick.java index b4ef52e12..e4a8656d9 100644 --- a/references/HorrorFlick.java +++ b/references/HorrorFlick.java @@ -1,16 +1,15 @@ // references/HorrorFlick.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// You can insert Cloneability at any level of inheritance +// 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() { + @Override public Scientist clone() { try { return (Scientist)super.clone(); } catch(CloneNotSupportedException e) { diff --git a/references/Immutable1.java b/references/Immutable1.java index 09680dbf5..8c2240ab5 100644 --- a/references/Immutable1.java +++ b/references/Immutable1.java @@ -1,7 +1,7 @@ // references/Immutable1.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Immutable objects are immune to aliasing public class Immutable1 { diff --git a/references/Immutable2.java b/references/Immutable2.java index 3f4ac6d76..aa23cadad 100644 --- a/references/Immutable2.java +++ b/references/Immutable2.java @@ -1,12 +1,12 @@ // references/Immutable2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // A companion class to modify immutable objects class Mutable { private int data; - public Mutable(int initVal) { + Mutable(int initVal) { data = initVal; } public Mutable add(int x) { diff --git a/references/ImmutableInteger.java b/references/ImmutableInteger.java index cf5f544e4..a42ddf1ef 100644 --- a/references/ImmutableInteger.java +++ b/references/ImmutableInteger.java @@ -1,16 +1,22 @@ // references/ImmutableInteger.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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) { - List v = new ArrayList<>(); - for(int i = 0; i < 10; i++) - v.add(new Integer(i)); + @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/references/ImmutableStrings.java b/references/ImmutableStrings.java deleted file mode 100644 index 75127afd2..000000000 --- a/references/ImmutableStrings.java +++ /dev/null @@ -1,25 +0,0 @@ -// references/ImmutableStrings.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ 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/references/LocalCopy.java b/references/LocalCopy.java new file mode 100644 index 000000000..f19f63a62 --- /dev/null +++ b/references/LocalCopy.java @@ -0,0 +1,55 @@ +// references/LocalCopy.java +// (c)2021 MindView 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(); // Local copy // [2] + 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/references/MutableInteger.java b/references/MutableInteger.java index e28e0cf54..9642777e6 100644 --- a/references/MutableInteger.java +++ b/references/MutableInteger.java @@ -1,30 +1,29 @@ // references/MutableInteger.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // A changeable wrapper class import java.util.*; +import java.util.stream.*; class IntValue { private int n; - public IntValue(int x) { n = x; } + 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() { + @Override public String toString() { return Integer.toString(n); } } public class MutableInteger { public static void main(String[] args) { - List v = new ArrayList<>(); - for(int i = 0; i < 10; i++) - v.add(new IntValue(i)); + List v = IntStream.range(0, 10) + .mapToObj(IntValue::new) + .collect(Collectors.toList()); System.out.println(v); - for(int i = 0; i < v.size(); i++) - v.get(i).increment(); + v.forEach(IntValue::increment); System.out.println(v); } } diff --git a/references/OceanReading.java b/references/OceanReading.java new file mode 100644 index 000000000..754a13b8d --- /dev/null +++ b/references/OceanReading.java @@ -0,0 +1,46 @@ +// references/OceanReading.java +// (c)2021 MindView 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/references/PassReferences.java b/references/PassReferences.java index 49348e2e9..1bd397438 100644 --- a/references/PassReferences.java +++ b/references/PassReferences.java @@ -1,7 +1,7 @@ // references/PassReferences.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class PassReferences { public static void f(PassReferences h) { diff --git a/references/SimplerMutableInteger.java b/references/SimplerMutableInteger.java index 684499657..1da86b7be 100644 --- a/references/SimplerMutableInteger.java +++ b/references/SimplerMutableInteger.java @@ -1,27 +1,27 @@ // references/SimplerMutableInteger.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // A trivial wrapper class import java.util.*; +import java.util.stream.*; class IntValue2 { public int n; - public IntValue2(int n) { this.n = n; } + IntValue2(int n) { this.n = n; } } public class SimplerMutableInteger { public static void main(String[] args) { - List v = new ArrayList<>(); - for(int i = 0; i < 10; i++) - v.add(new IntValue2(i)); - for(IntValue2 i : v) - System.out.print(i.n + " "); + List v = IntStream.range(0, 10) + .mapToObj(IntValue2::new) + .collect(Collectors.toList()); + v.forEach(iv2 -> + System.out.print(iv2.n + " ")); System.out.println(); - for(int i = 0; i < v.size(); i++) - v.get(i).n = v.get(i).n + 1; - for(IntValue2 i : v) - System.out.print(i.n + " "); + v.forEach(iv2 -> iv2.n += 1); + v.forEach(iv2 -> + System.out.print(iv2.n + " ")); } } /* Output: diff --git a/references/Snake.java b/references/Snake.java index b92c825ce..f45ec7950 100644 --- a/references/Snake.java +++ b/references/Snake.java @@ -1,7 +1,7 @@ // references/Snake.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Tests cloning to see if reference // destinations are also cloned @@ -19,15 +19,13 @@ public void increment() { if(next != null) next.increment(); } - @Override - public String toString() { + @Override public String toString() { String s = ":" + c; if(next != null) s += next.toString(); return s; } - @Override - public Snake clone() { + @Override public Snake clone() { try { return (Snake)super.clone(); } catch(CloneNotSupportedException e) { @@ -40,7 +38,8 @@ public static void main(String[] args) { Snake s2 = s.clone(); System.out.println("s2 = " + s2); s.increment(); - System.out.println("after s.increment, s2 = " + s2); + System.out.println( + "after s.increment, s2 = " + s2); } } /* Output: diff --git a/references/Stringer.java b/references/Stringer.java deleted file mode 100644 index 6b47d3a76..000000000 --- a/references/Stringer.java +++ /dev/null @@ -1,22 +0,0 @@ -// references/Stringer.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ 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/references/TemperatureReading.java b/references/TemperatureReading.java new file mode 100644 index 000000000..8f9afff6d --- /dev/null +++ b/references/TemperatureReading.java @@ -0,0 +1,31 @@ +// references/TemperatureReading.java +// (c)2021 MindView 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/references/build.xml b/references/build.xml deleted file mode 100644 index dde5d9ea6..000000000 --- a/references/build.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/references/tests/DeepCopyTest.java b/references/tests/DeepCopyTest.java new file mode 100644 index 000000000..5a7fcb6d5 --- /dev/null +++ b/references/tests/DeepCopyTest.java @@ -0,0 +1,28 @@ +// references/tests/DeepCopyTest.java +// (c)2021 MindView 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/typeinfo/AnonymousImplementation.java b/reflection/AnonymousImplementation.java similarity index 84% rename from typeinfo/AnonymousImplementation.java rename to reflection/AnonymousImplementation.java index 4c98347c0..290798bbf 100644 --- a/typeinfo/AnonymousImplementation.java +++ b/reflection/AnonymousImplementation.java @@ -1,14 +1,14 @@ -// typeinfo/AnonymousImplementation.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/AnonymousImplementation.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Anonymous inner classes can't hide from reflection -import typeinfo.interfacea.*; +import reflection.interfacea.*; class AnonymousA { public static A makeA() { return new A() { - public void f() { + @Override public void f() { System.out.println("public C.f()"); } public void g() { diff --git a/typeinfo/BoundedClassReferences.java b/reflection/BoundedClassReferences.java similarity index 65% rename from typeinfo/BoundedClassReferences.java rename to reflection/BoundedClassReferences.java index dffceaa77..6d2960591 100644 --- a/typeinfo/BoundedClassReferences.java +++ b/reflection/BoundedClassReferences.java @@ -1,7 +1,7 @@ -// typeinfo/BoundedClassReferences.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/BoundedClassReferences.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class BoundedClassReferences { public static void main(String[] args) { diff --git a/typeinfo/ClassCasts.java b/reflection/ClassCasts.java similarity index 70% rename from typeinfo/ClassCasts.java rename to reflection/ClassCasts.java index 8c1a2297f..3efd64c39 100644 --- a/typeinfo/ClassCasts.java +++ b/reflection/ClassCasts.java @@ -1,7 +1,7 @@ -// typeinfo/ClassCasts.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/ClassCasts.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class Building {} class House extends Building {} diff --git a/typeinfo/ClassInitialization.java b/reflection/ClassInitialization.java similarity index 73% rename from typeinfo/ClassInitialization.java rename to reflection/ClassInitialization.java index 0c3080ba7..21b711338 100644 --- a/typeinfo/ClassInitialization.java +++ b/reflection/ClassInitialization.java @@ -1,12 +1,12 @@ -// typeinfo/ClassInitialization.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/ClassInitialization.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; class Initable { - static final int staticFinal = 47; - static final int staticFinal2 = + static final int STATIC_FINAL = 47; + static final int STATIC_FINAL2 = ClassInitialization.rand.nextInt(1000); static { System.out.println("Initializing Initable"); @@ -34,10 +34,10 @@ public class ClassInitialization { Class initable = Initable.class; System.out.println("After creating Initable ref"); // Does not trigger initialization: - System.out.println(Initable.staticFinal); - // Does trigger initialization: - System.out.println(Initable.staticFinal2); - // Does trigger initialization: + System.out.println(Initable.STATIC_FINAL); + // Triggers initialization: + System.out.println(Initable.STATIC_FINAL2); + // Triggers initialization: System.out.println(Initable2.staticNonFinal); Class initable3 = Class.forName("Initable3"); System.out.println("After creating Initable3 ref"); diff --git a/typeinfo/DynamicSupplier.java b/reflection/DynamicSupplier.java similarity index 54% rename from typeinfo/DynamicSupplier.java rename to reflection/DynamicSupplier.java index 2ae0e5a31..910d12154 100644 --- a/typeinfo/DynamicSupplier.java +++ b/reflection/DynamicSupplier.java @@ -1,16 +1,19 @@ -// typeinfo/DynamicSupplier.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/DynamicSupplier.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.function.*; import java.util.stream.*; - -class CountedInteger { +class ID { private static long counter; private final long id = counter++; - @Override - public String toString() { return Long.toString(id); } + @Override public String toString() { + return Long.toString(id); + } + // A public default constructor is required + // to call getConstructor().newInstance(): + public ID() {} } public class DynamicSupplier implements Supplier { @@ -18,17 +21,16 @@ public class DynamicSupplier implements Supplier { public DynamicSupplier(Class type) { this.type = type; } - public T get() { + @Override public T get() { try { - return type.newInstance(); - } catch(InstantiationException | - IllegalAccessException e) { + return type.getConstructor().newInstance(); + } catch(Exception e) { throw new RuntimeException(e); } } public static void main(String[] args) { Stream.generate( - new DynamicSupplier<>(CountedInteger.class)) + new DynamicSupplier<>(ID.class)) .skip(10) .limit(5) .forEach(System.out::println); diff --git a/typeinfo/FamilyVsExactType.java b/reflection/FamilyVsExactType.java similarity index 85% rename from typeinfo/FamilyVsExactType.java rename to reflection/FamilyVsExactType.java index b73b6253b..db2bc9daf 100644 --- a/typeinfo/FamilyVsExactType.java +++ b/reflection/FamilyVsExactType.java @@ -1,9 +1,10 @@ -// typeinfo/FamilyVsExactType.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/FamilyVsExactType.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // The difference between instanceof and class -package typeinfo; +// {java reflection.FamilyVsExactType} +package reflection; class Base {} class Derived extends Base {} @@ -40,7 +41,7 @@ public static void main(String[] args) { } } /* Output: -Testing x of type class typeinfo.Base +Testing x of type class reflection.Base x instanceof Base true x instanceof Derived false Base.isInstance(x) true @@ -49,7 +50,7 @@ public static void main(String[] args) { x.getClass() == Derived.class false x.getClass().equals(Base.class)) true x.getClass().equals(Derived.class)) false -Testing x of type class typeinfo.Derived +Testing x of type class reflection.Derived x instanceof Base true x instanceof Derived true Base.isInstance(x) true diff --git a/typeinfo/GenericClassReferences.java b/reflection/GenericClassReferences.java similarity index 69% rename from typeinfo/GenericClassReferences.java rename to reflection/GenericClassReferences.java index fe01d9ada..66601f93c 100644 --- a/typeinfo/GenericClassReferences.java +++ b/reflection/GenericClassReferences.java @@ -1,14 +1,14 @@ -// typeinfo/GenericClassReferences.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/GenericClassReferences.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class GenericClassReferences { public static void main(String[] args) { Class intClass = int.class; + intClass = double.class; Class genericIntClass = int.class; genericIntClass = Integer.class; // Same thing - intClass = double.class; // genericIntClass = double.class; // Illegal } } diff --git a/typeinfo/HiddenImplementation.java b/reflection/HiddenImplementation.java similarity index 70% rename from typeinfo/HiddenImplementation.java rename to reflection/HiddenImplementation.java index 08b75a97d..1d536d309 100644 --- a/typeinfo/HiddenImplementation.java +++ b/reflection/HiddenImplementation.java @@ -1,10 +1,10 @@ -// typeinfo/HiddenImplementation.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/HiddenImplementation.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Sneaking around package hiding -import typeinfo.interfacea.*; -import typeinfo.packageaccess.*; +import reflection.interfacea.*; +import reflection.packageaccess.*; import java.lang.reflect.*; public class HiddenImplementation { @@ -20,7 +20,7 @@ public class HiddenImplementation { } */ // Oops! Reflection still allows us to call g(): callHiddenMethod(a, "g"); - // And even methods that are less accessible! + // And even less accessible methods! callHiddenMethod(a, "u"); callHiddenMethod(a, "v"); callHiddenMethod(a, "w"); @@ -28,14 +28,15 @@ public class HiddenImplementation { static void callHiddenMethod(Object a, String methodName) throws Exception { - Method g = a.getClass().getDeclaredMethod(methodName); + Method g = + a.getClass().getDeclaredMethod(methodName); g.setAccessible(true); g.invoke(a); } } /* Output: public C.f() -typeinfo.packageaccess.C +reflection.packageaccess.C public C.g() package C.u() protected C.v() diff --git a/reflection/ID2.java b/reflection/ID2.java new file mode 100644 index 000000000..6ff472af1 --- /dev/null +++ b/reflection/ID2.java @@ -0,0 +1,27 @@ +// reflection/ID2.java +// (c)2021 MindView LLC: see Copyright.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 ID2 { + private static long counter; + private final long id = counter++; + @Override public String toString() { + return Long.toString(id); + } + public static void main(String[] args) { + Stream.generate( + new DynamicSupplier<>(ID2.class)) + .skip(10) + .limit(5) + .forEach(System.out::println); + } +} +/* Output: +10 +11 +12 +13 +14 +*/ diff --git a/typeinfo/InnerImplementation.java b/reflection/InnerImplementation.java similarity index 80% rename from typeinfo/InnerImplementation.java rename to reflection/InnerImplementation.java index 4dfa5725a..248049c27 100644 --- a/typeinfo/InnerImplementation.java +++ b/reflection/InnerImplementation.java @@ -1,13 +1,13 @@ -// typeinfo/InnerImplementation.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/InnerImplementation.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Private inner classes can't hide from reflection -import typeinfo.interfacea.*; +// Visit http://OnJava8.com for more book information. +// Private inner classes can't hide from reflection. +import reflection.interfacea.*; class InnerA { private static class C implements A { - public void f() { + @Override public void f() { System.out.println("public C.f()"); } public void g() { diff --git a/typeinfo/InterfaceViolation.java b/reflection/InterfaceViolation.java similarity index 67% rename from typeinfo/InterfaceViolation.java rename to reflection/InterfaceViolation.java index 8d4c16f3d..ef8bfc954 100644 --- a/typeinfo/InterfaceViolation.java +++ b/reflection/InterfaceViolation.java @@ -1,12 +1,12 @@ -// typeinfo/InterfaceViolation.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/InterfaceViolation.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Sneaking around an interface -import typeinfo.interfacea.*; +import reflection.interfacea.*; class B implements A { - public void f() {} + @Override public void f() {} public void g() {} } diff --git a/typeinfo/ModifyingPrivateFields.java b/reflection/ModifyingPrivateFields.java similarity index 82% rename from typeinfo/ModifyingPrivateFields.java rename to reflection/ModifyingPrivateFields.java index a9bf54aa8..99b929531 100644 --- a/typeinfo/ModifyingPrivateFields.java +++ b/reflection/ModifyingPrivateFields.java @@ -1,15 +1,14 @@ -// typeinfo/ModifyingPrivateFields.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/ModifyingPrivateFields.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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() { + @Override public String toString() { return "i = " + i + ", " + s + ", " + s2; } } @@ -22,7 +21,8 @@ public class ModifyingPrivateFields { System.out.println(pf); Field f = pf.getClass().getDeclaredField("i"); f.setAccessible(true); - System.out.println("f.getInt(pf): " + f.getInt(pf)); + System.out.println( + "f.getInt(pf): " + f.getInt(pf)); f.setInt(pf, 47); System.out.println(pf); f = pf.getClass().getDeclaredField("s"); diff --git a/typeinfo/NullRobot.java b/reflection/NullRobot.java similarity index 74% rename from typeinfo/NullRobot.java rename to reflection/NullRobot.java index 2713dcfcc..c3e19659f 100644 --- a/typeinfo/NullRobot.java +++ b/reflection/NullRobot.java @@ -1,14 +1,15 @@ -// typeinfo/NullRobot.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/NullRobot.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 { +class NullRobotProxyHandler +implements InvocationHandler { private String nullName; private Robot proxied = new NRobot(); NullRobotProxyHandler(Class type) { @@ -19,13 +20,11 @@ private class NRobot implements Null, Robot { public String name() { return nullName; } @Override public String model() { return nullName; } - @Override - public List operations() { + @Override public List operations() { return Collections.emptyList(); } } - @Override - public Object + @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(proxied, args); @@ -42,8 +41,8 @@ public class NullRobot { } public static void main(String[] args) { Stream.of( - new SnowRemovalRobot("SnowBee"), - newNullRobot(SnowRemovalRobot.class) + new SnowRobot("SnowBee"), + newNullRobot(SnowRobot.class) ).forEach(Robot::test); } } @@ -57,6 +56,6 @@ public static void main(String[] args) { SnowBee can clear the roof SnowBee clearing roof [Null Robot] -Robot name: SnowRemovalRobot NullRobot -Robot model: SnowRemovalRobot NullRobot +Robot name: SnowRobot NullRobot +Robot model: SnowRobot NullRobot */ diff --git a/typeinfo/Operation.java b/reflection/Operation.java similarity index 56% rename from typeinfo/Operation.java rename to reflection/Operation.java index f6c94da72..4b749e7d1 100644 --- a/typeinfo/Operation.java +++ b/reflection/Operation.java @@ -1,14 +1,14 @@ -// typeinfo/Operation.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/Operation.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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) { + Operation(Supplier descr, Runnable cmd) { description = descr; command = cmd; } diff --git a/typeinfo/Person.java b/reflection/Person.java similarity index 77% rename from typeinfo/Person.java rename to reflection/Person.java index ec4f355da..070a2490f 100644 --- a/typeinfo/Person.java +++ b/reflection/Person.java @@ -1,7 +1,7 @@ -// typeinfo/Person.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/Person.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Using Optional with regular classes import onjava.*; import java.util.*; @@ -12,7 +12,6 @@ class Person { public final Optional address; // etc. public final boolean empty; - public Person(String first, String last, String address) { this.first = Optional.ofNullable(first); this.last = Optional.ofNullable(last); @@ -21,13 +20,12 @@ class Person { && !this.last.isPresent() && !this.address.isPresent(); } - public Person(String first, String last) { + Person(String first, String last) { this(first, last, null); } - public Person(String last) { this(null, last, null); } - public Person() { this(null, null, null); } - @Override - public String toString() { + Person(String last) { this(null, last, null); } + Person() { this(null, null, null); } + @Override public String toString() { if(empty) return ""; return (first.orElse("") + diff --git a/reflection/PetCounter.java b/reflection/PetCounter.java new file mode 100644 index 000000000..974880620 --- /dev/null +++ b/reflection/PetCounter.java @@ -0,0 +1,64 @@ +// reflection/PetCounter.java +// (c)2021 MindView 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 reflection.pets.*; +import java.util.*; + +public class PetCounter { + 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); + } + } + private Counter counter = new Counter(); + private void countPet(Pet 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"); + } + public void count(Creator creator) { + creator.stream().limit(20) + .forEach(pet -> countPet(pet)); + System.out.println(); + System.out.println(counter); + } + public static void main(String[] args) { + new PetCounter().count(new ForNamePetCreator()); + } +} +/* 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/reflection/PetCounter2.java b/reflection/PetCounter2.java new file mode 100644 index 000000000..ccac0b57f --- /dev/null +++ b/reflection/PetCounter2.java @@ -0,0 +1,18 @@ +// reflection/PetCounter2.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +import reflection.pets.*; + +public class PetCounter2 { + public static void main(String[] args) { + new PetCounter().count(new PetCreator()); + } +} +/* 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/reflection/PetCounter3.java b/reflection/PetCounter3.java new file mode 100644 index 000000000..aec88ef0b --- /dev/null +++ b/reflection/PetCounter3.java @@ -0,0 +1,53 @@ +// reflection/PetCounter3.java +// (c)2021 MindView 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 reflection.pets.*; + +public class PetCounter3 { + static class Counter extends + HashMap, Integer> { + Counter() { + super(PetCreator.ALL_TYPES.stream() + .map(type -> Pair.make(type, 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(); + new PetCreator().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 +{EgyptianMau=2, Mouse=2, Pet=20, Cymric=5, Rat=2, +Dog=6, Mutt=3, Hamster=1, Cat=9, Manx=7, Rodent=5, +Pug=3} +*/ diff --git a/typeinfo/PetCount4.java b/reflection/PetCounter4.java similarity index 51% rename from typeinfo/PetCount4.java rename to reflection/PetCounter4.java index 5f1197e82..9015e66c7 100644 --- a/typeinfo/PetCount4.java +++ b/reflection/PetCounter4.java @@ -1,14 +1,14 @@ -// typeinfo/PetCount4.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/PetCounter4.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import typeinfo.pets.*; +// Visit http://OnJava8.com for more book information. +import reflection.pets.*; import onjava.*; -public class PetCount4 { +public class PetCounter4 { public static void main(String[] args) { TypeCounter counter = new TypeCounter(Pet.class); - Pets.stream() + new PetCreator().stream() .limit(20) .peek(counter::count) .forEach(p -> System.out.print( @@ -18,8 +18,9 @@ public static void main(String[] args) { } /* Output: Rat Manx Cymric Mutt Pug Cymric Pug Manx Cymric Rat -EgyptianMau Hamster EgyptianMau Mutt Mutt Cymric Mouse Pug -Mouse Cymric -{Mutt=3, Rat=2, EgyptianMau=2, Pet=20, Mouse=2, Manx=7, -Cat=9, Rodent=5, Cymric=5, Dog=6, Pug=3, Hamster=1} +EgyptianMau Hamster EgyptianMau Mutt Mutt Cymric Mouse +Pug Mouse Cymric +{Rodent=5, Mouse=2, Hamster=1, Cymric=5, Dog=6, +EgyptianMau=2, Pet=20, Rat=2, Pug=3, Manx=7, Cat=9, +Mutt=3} */ diff --git a/typeinfo/Position.java b/reflection/Position.java similarity index 72% rename from typeinfo/Position.java rename to reflection/Position.java index 59ed027f3..ea07ca78f 100644 --- a/typeinfo/Position.java +++ b/reflection/Position.java @@ -1,7 +1,7 @@ -// typeinfo/Position.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/Position.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; class EmptyTitleException extends RuntimeException {} @@ -9,11 +9,11 @@ class EmptyTitleException extends RuntimeException {} class Position { private String title; private Person person; - public Position(String jobTitle, Person employee) { + Position(String jobTitle, Person employee) { setTitle(jobTitle); setPerson(employee); } - public Position(String jobTitle) { + Position(String jobTitle) { this(jobTitle, null); } public String getTitle() { return title; } @@ -25,12 +25,12 @@ public void setTitle(String newTitle) { public Person getPerson() { return person; } public void setPerson(Person newPerson) { // Uses empty Person if newPerson is null: - person = - Optional.ofNullable(newPerson).orElse(new Person()); + person = Optional.ofNullable(newPerson) + .orElse(new Person()); } - @Override - public String toString() { - return "Position: " + title + ", Employee: " + person; + @Override public String toString() { + return "Position: " + title + + ", Employee: " + person; } public static void main(String[] args) { System.out.println(new Position("CEO")); diff --git a/typeinfo/RegisteredFactories.java b/reflection/RegisteredFactories.java similarity index 82% rename from typeinfo/RegisteredFactories.java rename to reflection/RegisteredFactories.java index 20859977b..04267c425 100644 --- a/typeinfo/RegisteredFactories.java +++ b/reflection/RegisteredFactories.java @@ -1,15 +1,14 @@ -// typeinfo/RegisteredFactories.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/RegisteredFactories.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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() { + @Override public String toString() { return getClass().getSimpleName(); } static List> prototypes = @@ -23,7 +22,7 @@ public String toString() { new GeneratorBelt() ); private static Random rand = new Random(47); - public Part get() { + @Override public Part get() { int n = rand.nextInt(prototypes.size()); return prototypes.get(n).get(); } @@ -42,8 +41,7 @@ class AirFilter extends Filter { } class CabinAirFilter extends Filter { - @Override - public CabinAirFilter get() { + @Override public CabinAirFilter get() { return new CabinAirFilter(); } } @@ -61,15 +59,13 @@ class FanBelt extends Belt { } class GeneratorBelt extends Belt { - @Override - public GeneratorBelt get() { + @Override public GeneratorBelt get() { return new GeneratorBelt(); } } class PowerSteeringBelt extends Belt { - @Override - public PowerSteeringBelt get() { + @Override public PowerSteeringBelt get() { return new PowerSteeringBelt(); } } diff --git a/typeinfo/Robot.java b/reflection/Robot.java similarity index 74% rename from typeinfo/Robot.java rename to reflection/Robot.java index a6f57fc20..00818d378 100644 --- a/typeinfo/Robot.java +++ b/reflection/Robot.java @@ -1,7 +1,7 @@ -// typeinfo/Robot.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/Robot.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import onjava.*; import java.util.*; @@ -9,7 +9,7 @@ public interface Robot { String name(); String model(); List operations(); - public static void test(Robot r) { + static void test(Robot r) { if(r instanceof Null) System.out.println("[Null Robot]"); System.out.println("Robot name: " + r.name()); diff --git a/typeinfo/SelectingMethods.java b/reflection/SelectingMethods.java similarity index 70% rename from typeinfo/SelectingMethods.java rename to reflection/SelectingMethods.java index 6c7b4df77..9002cf356 100644 --- a/typeinfo/SelectingMethods.java +++ b/reflection/SelectingMethods.java @@ -1,17 +1,16 @@ -// typeinfo/SelectingMethods.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/SelectingMethods.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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; - public MethodSelector(Object proxied) { + MethodSelector(Object proxied) { this.proxied = proxied; } - @Override - public Object + @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(method.getName().equals("interesting")) @@ -29,16 +28,18 @@ interface SomeMethods { } 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) { + @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"); } + @Override public void boring3() { + System.out.println("boring3"); + } } class SelectingMethods { diff --git a/reflection/Shapes.java b/reflection/Shapes.java new file mode 100644 index 000000000..05d15df5c --- /dev/null +++ b/reflection/Shapes.java @@ -0,0 +1,43 @@ +// reflection/Shapes.java +// (c)2021 MindView LLC: see Copyright.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/typeinfo/ShowMethods.java b/reflection/ShowMethods.java similarity index 89% rename from typeinfo/ShowMethods.java rename to reflection/ShowMethods.java index bd99b43aa..48024cdc4 100644 --- a/typeinfo/ShowMethods.java +++ b/reflection/ShowMethods.java @@ -1,10 +1,10 @@ -// typeinfo/ShowMethods.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/ShowMethods.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 -// {Args: ShowMethods} +// {java ShowMethods ShowMethods} import java.lang.reflect.*; import java.util.regex.*; @@ -29,7 +29,8 @@ public static void main(String[] args) { if(args.length == 1) { for(Method method : methods) System.out.println( - p.matcher(method.toString()).replaceAll("")); + p.matcher( + method.toString()).replaceAll("")); for(Constructor ctor : ctors) System.out.println( p.matcher(ctor.toString()).replaceAll("")); @@ -55,11 +56,11 @@ public static void main(String[] args) { } /* 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 final void wait() throws InterruptedException public boolean equals(Object) public String toString() public native int hashCode() diff --git a/typeinfo/SimpleDynamicProxy.java b/reflection/SimpleDynamicProxy.java similarity index 79% rename from typeinfo/SimpleDynamicProxy.java rename to reflection/SimpleDynamicProxy.java index 1ced955a9..9eeb02926 100644 --- a/typeinfo/SimpleDynamicProxy.java +++ b/reflection/SimpleDynamicProxy.java @@ -1,19 +1,19 @@ -// typeinfo/SimpleDynamicProxy.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/SimpleDynamicProxy.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.lang.reflect.*; class DynamicProxyHandler implements InvocationHandler { private Object proxied; - public DynamicProxyHandler(Object proxied) { + DynamicProxyHandler(Object proxied) { this.proxied = proxied; } - @Override - public Object + @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - System.out.println("**** proxy: " + proxy.getClass() + + System.out.println( + "**** proxy: " + proxy.getClass() + ", method: " + method + ", args: " + args); if(args != null) for(Object arg : args) @@ -46,7 +46,7 @@ public static void main(String[] args) { doSomething **** proxy: class $Proxy0, method: public abstract void Interface.somethingElse(java.lang.String), args: -[Ljava.lang.Object;@1c7c054 +[Ljava.lang.Object;@1b84c92 bonobo somethingElse bonobo */ diff --git a/typeinfo/SimpleProxyDemo.java b/reflection/SimpleProxyDemo.java similarity index 71% rename from typeinfo/SimpleProxyDemo.java rename to reflection/SimpleProxyDemo.java index c6fd64f86..24f7b0166 100644 --- a/typeinfo/SimpleProxyDemo.java +++ b/reflection/SimpleProxyDemo.java @@ -1,7 +1,7 @@ -// typeinfo/SimpleProxyDemo.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/SimpleProxyDemo.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. interface Interface { void doSomething(); @@ -9,28 +9,24 @@ interface Interface { } class RealObject implements Interface { - @Override - public void doSomething() { + @Override public void doSomething() { System.out.println("doSomething"); } - @Override - public void somethingElse(String arg) { + @Override public void somethingElse(String arg) { System.out.println("somethingElse " + arg); } } class SimpleProxy implements Interface { private Interface proxied; - public SimpleProxy(Interface proxied) { + SimpleProxy(Interface proxied) { this.proxied = proxied; } - @Override - public void doSomething() { + @Override public void doSomething() { System.out.println("SimpleProxy doSomething"); proxied.doSomething(); } - @Override - public void somethingElse(String arg) { + @Override public void somethingElse(String arg) { System.out.println( "SimpleProxy somethingElse " + arg); proxied.somethingElse(arg); diff --git a/typeinfo/SnowRemovalRobot.java b/reflection/SnowRobot.java similarity index 58% rename from typeinfo/SnowRemovalRobot.java rename to reflection/SnowRobot.java index 5c49e0574..227dcb49d 100644 --- a/typeinfo/SnowRemovalRobot.java +++ b/reflection/SnowRobot.java @@ -1,31 +1,34 @@ -// typeinfo/SnowRemovalRobot.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/SnowRobot.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; -public class SnowRemovalRobot implements Robot { +public class SnowRobot implements Robot { private String name; - public SnowRemovalRobot(String name) { + public SnowRobot(String name) { this.name = name; } - @Override - public String name() { return name; } - @Override - public String model() { return "SnowBot Series 11"; } + @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")), + () -> 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"))); + () -> System.out.println( + name + " clearing roof"))); + @Override public List operations() { return ops; } public static void main(String[] args) { - Robot.test(new SnowRemovalRobot("Slusher")); + Robot.test(new SnowRobot("Slusher")); } } /* Output: diff --git a/typeinfo/Staff.java b/reflection/Staff.java similarity index 71% rename from typeinfo/Staff.java rename to reflection/Staff.java index b05d75ef0..8c3bb76e8 100644 --- a/typeinfo/Staff.java +++ b/reflection/Staff.java @@ -1,7 +1,7 @@ -// typeinfo/Staff.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/Staff.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class Staff extends ArrayList { @@ -43,19 +43,21 @@ public static void main(String[] args) { new Person("Janet", "Planner", "The Burbs")); if(staff.positionAvailable("Software Engineer")) staff.fillPosition("Software Engineer", - new Person("Bob", "Coder", "Bright Light City")); + 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: 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/typeinfo/SweetShop.java b/reflection/SweetShop.java similarity index 86% rename from typeinfo/SweetShop.java rename to reflection/SweetShop.java index 7d67210cb..d5f964f0a 100644 --- a/typeinfo/SweetShop.java +++ b/reflection/SweetShop.java @@ -1,7 +1,7 @@ -// typeinfo/SweetShop.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/SweetShop.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Examination of the way the class loader works class Cookie { diff --git a/typeinfo/WildcardClassReferences.java b/reflection/WildcardClassReferences.java similarity index 58% rename from typeinfo/WildcardClassReferences.java rename to reflection/WildcardClassReferences.java index 986c64322..d7266f732 100644 --- a/typeinfo/WildcardClassReferences.java +++ b/reflection/WildcardClassReferences.java @@ -1,7 +1,7 @@ -// typeinfo/WildcardClassReferences.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/WildcardClassReferences.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class WildcardClassReferences { public static void main(String[] args) { diff --git a/reflection/interfacea/A.java b/reflection/interfacea/A.java new file mode 100644 index 000000000..2b4c33ec9 --- /dev/null +++ b/reflection/interfacea/A.java @@ -0,0 +1,9 @@ +// reflection/interfacea/A.java +// (c)2021 MindView 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 reflection.interfacea; + +public interface A { + void f(); +} diff --git a/typeinfo/packageaccess/HiddenC.java b/reflection/packageaccess/HiddenC.java similarity index 65% rename from typeinfo/packageaccess/HiddenC.java rename to reflection/packageaccess/HiddenC.java index 086d35850..24fb20d4b 100644 --- a/typeinfo/packageaccess/HiddenC.java +++ b/reflection/packageaccess/HiddenC.java @@ -1,13 +1,12 @@ -// typeinfo/packageaccess/HiddenC.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/packageaccess/HiddenC.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package typeinfo.packageaccess; -import typeinfo.interfacea.*; +// Visit http://OnJava8.com for more book information. +package reflection.packageaccess; +import reflection.interfacea.*; class C implements A { - @Override - public void f() { + @Override public void f() { System.out.println("public C.f()"); } public void g() { diff --git a/typeinfo/pets/Cat.java b/reflection/pets/Cat.java similarity index 50% rename from typeinfo/pets/Cat.java rename to reflection/pets/Cat.java index 2bd8678e7..2ed2aba94 100644 --- a/typeinfo/pets/Cat.java +++ b/reflection/pets/Cat.java @@ -1,8 +1,8 @@ -// typeinfo/pets/Cat.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/pets/Cat.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package typeinfo.pets; +// Visit http://OnJava8.com for more book information. +package reflection.pets; public class Cat extends Pet { public Cat(String name) { super(name); } diff --git a/reflection/pets/Creator.java b/reflection/pets/Creator.java new file mode 100644 index 000000000..f5f152fe8 --- /dev/null +++ b/reflection/pets/Creator.java @@ -0,0 +1,38 @@ +// reflection/pets/Creator.java +// (c)2021 MindView 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 Pets +package reflection.pets; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; +import java.lang.reflect.InvocationTargetException; + +public abstract class Creator implements Supplier { + private Random rand = new Random(47); + // The different types of Pet to create: + public abstract List> types(); + @Override 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); + } + } + public Stream stream() { + return Stream.generate(this); + } + public Pet[] array(int size) { + return stream().limit(size).toArray(Pet[]::new); + } + public List list(int size) { + return stream().limit(size) + .collect(Collectors.toCollection(ArrayList::new)); + } +} diff --git a/typeinfo/pets/Cymric.java b/reflection/pets/Cymric.java similarity index 51% rename from typeinfo/pets/Cymric.java rename to reflection/pets/Cymric.java index c16029af7..11521fe85 100644 --- a/typeinfo/pets/Cymric.java +++ b/reflection/pets/Cymric.java @@ -1,8 +1,8 @@ -// typeinfo/pets/Cymric.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/pets/Cymric.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package typeinfo.pets; +// Visit http://OnJava8.com for more book information. +package reflection.pets; public class Cymric extends Manx { public Cymric(String name) { super(name); } diff --git a/typeinfo/pets/Dog.java b/reflection/pets/Dog.java similarity index 50% rename from typeinfo/pets/Dog.java rename to reflection/pets/Dog.java index 6f451e548..abd370ff2 100644 --- a/typeinfo/pets/Dog.java +++ b/reflection/pets/Dog.java @@ -1,8 +1,8 @@ -// typeinfo/pets/Dog.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/pets/Dog.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package typeinfo.pets; +// Visit http://OnJava8.com for more book information. +package reflection.pets; public class Dog extends Pet { public Dog(String name) { super(name); } diff --git a/typeinfo/pets/EgyptianMau.java b/reflection/pets/EgyptianMau.java similarity index 52% rename from typeinfo/pets/EgyptianMau.java rename to reflection/pets/EgyptianMau.java index 82d06f179..4e314fb63 100644 --- a/typeinfo/pets/EgyptianMau.java +++ b/reflection/pets/EgyptianMau.java @@ -1,8 +1,8 @@ -// typeinfo/pets/EgyptianMau.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/pets/EgyptianMau.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package typeinfo.pets; +// Visit http://OnJava8.com for more book information. +package reflection.pets; public class EgyptianMau extends Cat { public EgyptianMau(String name) { super(name); } diff --git a/reflection/pets/ForNamePetCreator.java b/reflection/pets/ForNamePetCreator.java new file mode 100644 index 000000000..92648db5d --- /dev/null +++ b/reflection/pets/ForNamePetCreator.java @@ -0,0 +1,36 @@ +// reflection/pets/ForNamePetCreator.java +// (c)2021 MindView 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 reflection.pets; +import java.util.*; + +public class ForNamePetCreator extends Creator { + private static List> types = + new ArrayList<>(); + // Types you want randomly created: + private static String[] typeNames = { + "reflection.pets.Mutt", + "reflection.pets.Pug", + "reflection.pets.EgyptianMau", + "reflection.pets.Manx", + "reflection.pets.Cymric", + "reflection.pets.Rat", + "reflection.pets.Mouse", + "reflection.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/typeinfo/pets/Hamster.java b/reflection/pets/Hamster.java similarity index 52% rename from typeinfo/pets/Hamster.java rename to reflection/pets/Hamster.java index b5a123dd0..fb09f3ab8 100644 --- a/typeinfo/pets/Hamster.java +++ b/reflection/pets/Hamster.java @@ -1,8 +1,8 @@ -// typeinfo/pets/Hamster.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/pets/Hamster.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package typeinfo.pets; +// Visit http://OnJava8.com for more book information. +package reflection.pets; public class Hamster extends Rodent { public Hamster(String name) { super(name); } diff --git a/typeinfo/pets/Individual.java b/reflection/pets/Individual.java similarity index 62% rename from typeinfo/pets/Individual.java rename to reflection/pets/Individual.java index 23b06a232..524fba6e4 100644 --- a/typeinfo/pets/Individual.java +++ b/reflection/pets/Individual.java @@ -1,8 +1,9 @@ -// typeinfo/pets/Individual.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/pets/Individual.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package typeinfo.pets; +// Visit http://OnJava8.com for more book information. +package reflection.pets; +import java.util.*; public class Individual implements Comparable { @@ -12,33 +13,25 @@ public Individual(String name) { this.name = name; } // 'name' is optional: public Individual() {} - @Override - public String toString() { + @Override public String toString() { return getClass().getSimpleName() + (name == null ? "" : " " + name); } public long id() { return id; } - @Override - public boolean equals(Object o) { + @Override public boolean equals(Object o) { return o instanceof Individual && - id == ((Individual)o).id; + Objects.equals(id, ((Individual)o).id); } - @Override - public int hashCode() { - int result = 17; - if(name != null) - result = 37 * result + name.hashCode(); - result = 37 * result + (int)id; - return result; + @Override public int hashCode() { + return Objects.hash(name, id); } - @Override - public int compareTo(Individual arg) { + @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; + return firstCompare; if(name != null && arg.name != null) { int secondCompare = name.compareTo(arg.name); if(secondCompare != 0) diff --git a/typeinfo/pets/Manx.java b/reflection/pets/Manx.java similarity index 50% rename from typeinfo/pets/Manx.java rename to reflection/pets/Manx.java index dace56721..a5c6bea91 100644 --- a/typeinfo/pets/Manx.java +++ b/reflection/pets/Manx.java @@ -1,8 +1,8 @@ -// typeinfo/pets/Manx.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/pets/Manx.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package typeinfo.pets; +// Visit http://OnJava8.com for more book information. +package reflection.pets; public class Manx extends Cat { public Manx(String name) { super(name); } diff --git a/typeinfo/pets/Mouse.java b/reflection/pets/Mouse.java similarity index 51% rename from typeinfo/pets/Mouse.java rename to reflection/pets/Mouse.java index 50da28d12..9ad9b290d 100644 --- a/typeinfo/pets/Mouse.java +++ b/reflection/pets/Mouse.java @@ -1,8 +1,8 @@ -// typeinfo/pets/Mouse.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/pets/Mouse.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package typeinfo.pets; +// Visit http://OnJava8.com for more book information. +package reflection.pets; public class Mouse extends Rodent { public Mouse(String name) { super(name); } diff --git a/typeinfo/pets/Mutt.java b/reflection/pets/Mutt.java similarity index 50% rename from typeinfo/pets/Mutt.java rename to reflection/pets/Mutt.java index 27fc21c45..f50ba64de 100644 --- a/typeinfo/pets/Mutt.java +++ b/reflection/pets/Mutt.java @@ -1,8 +1,8 @@ -// typeinfo/pets/Mutt.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/pets/Mutt.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package typeinfo.pets; +// Visit http://OnJava8.com for more book information. +package reflection.pets; public class Mutt extends Dog { public Mutt(String name) { super(name); } diff --git a/reflection/pets/Person.java b/reflection/pets/Person.java new file mode 100644 index 000000000..bfe61ca3b --- /dev/null +++ b/reflection/pets/Person.java @@ -0,0 +1,9 @@ +// reflection/pets/Person.java +// (c)2021 MindView 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 reflection.pets; + +public class Person extends Individual { + public Person(String name) { super(name); } +} diff --git a/typeinfo/pets/Pet.java b/reflection/pets/Pet.java similarity index 51% rename from typeinfo/pets/Pet.java rename to reflection/pets/Pet.java index fb8bd4815..a3a0cf2ed 100644 --- a/typeinfo/pets/Pet.java +++ b/reflection/pets/Pet.java @@ -1,8 +1,8 @@ -// typeinfo/pets/Pet.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/pets/Pet.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package typeinfo.pets; +// Visit http://OnJava8.com for more book information. +package reflection.pets; public class Pet extends Individual { public Pet(String name) { super(name); } diff --git a/reflection/pets/PetCreator.java b/reflection/pets/PetCreator.java new file mode 100644 index 000000000..1f01ceed3 --- /dev/null +++ b/reflection/pets/PetCreator.java @@ -0,0 +1,42 @@ +// reflection/pets/PetCreator.java +// (c)2021 MindView 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 reflection.pets.PetCreator} +package reflection.pets; +import java.util.*; + +public class PetCreator extends Creator { + // No try block needed. + 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); + List pets = new PetCreator().list(7); + System.out.println(pets); + } +} +/* Output: +[class reflection.pets.Mutt, class reflection.pets.Pug, +class reflection.pets.EgyptianMau, class +reflection.pets.Manx, class reflection.pets.Cymric, class +reflection.pets.Rat, class reflection.pets.Mouse, class +reflection.pets.Hamster] +[Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug] +*/ diff --git a/typeinfo/pets/Pug.java b/reflection/pets/Pug.java similarity index 50% rename from typeinfo/pets/Pug.java rename to reflection/pets/Pug.java index 5f249d6f3..1a150b865 100644 --- a/typeinfo/pets/Pug.java +++ b/reflection/pets/Pug.java @@ -1,8 +1,8 @@ -// typeinfo/pets/Pug.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/pets/Pug.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package typeinfo.pets; +// Visit http://OnJava8.com for more book information. +package reflection.pets; public class Pug extends Dog { public Pug(String name) { super(name); } diff --git a/typeinfo/pets/Rat.java b/reflection/pets/Rat.java similarity index 51% rename from typeinfo/pets/Rat.java rename to reflection/pets/Rat.java index 0eada2a03..cd006426d 100644 --- a/typeinfo/pets/Rat.java +++ b/reflection/pets/Rat.java @@ -1,8 +1,8 @@ -// typeinfo/pets/Rat.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/pets/Rat.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package typeinfo.pets; +// Visit http://OnJava8.com for more book information. +package reflection.pets; public class Rat extends Rodent { public Rat(String name) { super(name); } diff --git a/typeinfo/pets/Rodent.java b/reflection/pets/Rodent.java similarity index 51% rename from typeinfo/pets/Rodent.java rename to reflection/pets/Rodent.java index 075bbf224..3c9063ba3 100644 --- a/typeinfo/pets/Rodent.java +++ b/reflection/pets/Rodent.java @@ -1,8 +1,8 @@ -// typeinfo/pets/Rodent.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/pets/Rodent.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package typeinfo.pets; +// Visit http://OnJava8.com for more book information. +package reflection.pets; public class Rodent extends Pet { public Rodent(String name) { super(name); } diff --git a/reflection/toys/GenericToyTest.java b/reflection/toys/GenericToyTest.java new file mode 100644 index 000000000..3332bcd64 --- /dev/null +++ b/reflection/toys/GenericToyTest.java @@ -0,0 +1,22 @@ +// reflection/toys/GenericToyTest.java +// (c)2021 MindView 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 reflection.toys.GenericToyTest} +package reflection.toys; + +public class GenericToyTest { + public static void + main(String[] args) throws Exception { + Class ftc = FancyToy.class; + // Produces exact type: + FancyToy fancyToy = + ftc.getConstructor().newInstance(); + Class up = ftc.getSuperclass(); + // This won't compile: + // Class up2 = ftc.getSuperclass(); + // Only produces Object: + Object obj = up.getConstructor().newInstance(); + } +} diff --git a/typeinfo/toys/ToyTest.java b/reflection/toys/ToyTest.java similarity index 51% rename from typeinfo/toys/ToyTest.java rename to reflection/toys/ToyTest.java index 247577eaa..e81e64b7e 100644 --- a/typeinfo/toys/ToyTest.java +++ b/reflection/toys/ToyTest.java @@ -1,24 +1,26 @@ -// typeinfo/toys/ToyTest.java -// (c)2016 MindView LLC: see Copyright.txt +// reflection/toys/ToyTest.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Testing class Class -package typeinfo.toys; +// {java reflection.toys.ToyTest} +package reflection.toys; +import java.lang.reflect.InvocationTargetException; interface HasBatteries {} interface Waterproof {} interface Shoots {} class Toy { - // Comment out the following no-arg + // Comment out the following zero-argument // constructor to see NoSuchMethodError - Toy() {} - Toy(int i) {} + public Toy() {} + public Toy(int i) {} } class FancyToy extends Toy implements HasBatteries, Waterproof, Shoots { - FancyToy() { super(1); } + public FancyToy() { super(1); } } public class ToyTest { @@ -30,10 +32,11 @@ static void printInfo(Class cc) { 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"); + c = Class.forName("reflection.toys.FancyToy"); } catch(ClassNotFoundException e) { System.out.println("Can't find FancyToy"); System.exit(1); @@ -44,32 +47,32 @@ public static void main(String[] args) { Class up = c.getSuperclass(); Object obj = null; try { - // Requires no-arg constructor: + // Requires public zero-argument constructor: obj = up.newInstance(); - } catch(InstantiationException e) { - System.out.println("Cannot instantiate"); - System.exit(1); - } catch(IllegalAccessException e) { - System.out.println("Cannot access"); - System.exit(1); + } catch(Exception e) { + throw new + RuntimeException("Cannot instantiate"); } printInfo(obj.getClass()); } } /* Output: -Class name: typeinfo.toys.FancyToy is interface? [false] +Class name: reflection.toys.FancyToy is interface? +[false] Simple name: FancyToy -Canonical name : typeinfo.toys.FancyToy -Class name: typeinfo.toys.HasBatteries is interface? [true] +Canonical name : reflection.toys.FancyToy +Class name: reflection.toys.HasBatteries is interface? +[true] Simple name: HasBatteries -Canonical name : typeinfo.toys.HasBatteries -Class name: typeinfo.toys.Waterproof is interface? [true] +Canonical name : reflection.toys.HasBatteries +Class name: reflection.toys.Waterproof is interface? +[true] Simple name: Waterproof -Canonical name : typeinfo.toys.Waterproof -Class name: typeinfo.toys.Shoots is interface? [true] +Canonical name : reflection.toys.Waterproof +Class name: reflection.toys.Shoots is interface? [true] Simple name: Shoots -Canonical name : typeinfo.toys.Shoots -Class name: typeinfo.toys.Toy is interface? [false] +Canonical name : reflection.toys.Shoots +Class name: reflection.toys.Toy is interface? [false] Simple name: Toy -Canonical name : typeinfo.toys.Toy +Canonical name : reflection.toys.Toy */ diff --git a/remote/DisplayPerfectTime.java b/remote/DisplayPerfectTime.java deleted file mode 100644 index 060a387b5..000000000 --- a/remote/DisplayPerfectTime.java +++ /dev/null @@ -1,19 +0,0 @@ -// remote/DisplayPerfectTime.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Uses remote object PerfectTime -// {ValidateByHand} -import java.rmi.registry.*; - -public class DisplayPerfectTime { - public static void - main(String[] args) throws Exception { - Registry reg = - LocateRegistry.getRegistry("localhost"); - PerfectTime pt = - (PerfectTime)reg.lookup("PerfectTime"); - for(int i = 0; i < 10; i++) - System.out.println("Time: "+ pt.getPerfectTime()); - } -} diff --git a/remote/PerfectTime.java b/remote/PerfectTime.java deleted file mode 100644 index eb02be2cd..000000000 --- a/remote/PerfectTime.java +++ /dev/null @@ -1,10 +0,0 @@ -// remote/PerfectTime.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// The PerfectTime remote interface -import java.rmi.*; - -public interface PerfectTime extends Remote { - long getPerfectTime() throws RemoteException; -} diff --git a/remote/PerfectTimeImpl.java b/remote/PerfectTimeImpl.java deleted file mode 100644 index 8342b0c17..000000000 --- a/remote/PerfectTimeImpl.java +++ /dev/null @@ -1,12 +0,0 @@ -// remote/PerfectTimeImpl.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Implementing the PerfectTime remote object -import java.rmi.RemoteException; - -public class PerfectTimeImpl implements PerfectTime { - public long getPerfectTime() throws RemoteException { - return System.currentTimeMillis(); - } -} diff --git a/remote/PerfectTimeServer.java b/remote/PerfectTimeServer.java deleted file mode 100644 index ec07c775f..000000000 --- a/remote/PerfectTimeServer.java +++ /dev/null @@ -1,22 +0,0 @@ -// remote/PerfectTimeServer.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Server for the PerfectTime remote object -// {ValidateByHand} -import java.rmi.registry.Registry; -import java.rmi.registry.LocateRegistry; -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; - -public class PerfectTimeServer { - public static void - main(String[] args) throws RemoteException { - PerfectTimeImpl pt = new PerfectTimeImpl(); - PerfectTime stub = (PerfectTime) - UnicastRemoteObject.exportObject(pt, 0); - Registry registry = LocateRegistry.getRegistry(); - registry.rebind("PerfectTime", stub); - System.out.println("Ready to do time"); - } -} diff --git a/remote/build.xml b/remote/build.xml deleted file mode 100644 index ab6f58470..000000000 --- a/remote/build.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/remote/go.bat b/remote/go.bat deleted file mode 100644 index ac6f4c636..000000000 --- a/remote/go.bat +++ /dev/null @@ -1 +0,0 @@ -start "ptime.bat" ptime.bat diff --git a/remote/go.sh b/remote/go.sh deleted file mode 100644 index fdff7366a..000000000 --- a/remote/go.sh +++ /dev/null @@ -1 +0,0 @@ -sh ptime.sh diff --git a/remote/ptime.bat b/remote/ptime.bat deleted file mode 100644 index aee99dbfc..000000000 --- a/remote/ptime.bat +++ /dev/null @@ -1,6 +0,0 @@ -start /min "registry.bat" registry.bat 3 -start /min "server.bat" server.bat 3 -timeout /t 1 -java DisplayPerfectTime -timeout /t 3 -exit \ No newline at end of file diff --git a/remote/ptime.sh b/remote/ptime.sh deleted file mode 100644 index 937264fdc..000000000 --- a/remote/ptime.sh +++ /dev/null @@ -1,5 +0,0 @@ -sh registry.sh 3 & -sleep 1 -sh server.sh 3 & -sleep 1 -java DisplayPerfectTime diff --git a/remote/registry.bat b/remote/registry.bat deleted file mode 100644 index ddb22c41d..000000000 --- a/remote/registry.bat +++ /dev/null @@ -1,4 +0,0 @@ -start /min "rmiregistry" rmiregistry -timeout /t %1 -taskkill /im rmiregistry.exe -exit \ No newline at end of file diff --git a/remote/registry.sh b/remote/registry.sh deleted file mode 100644 index ec2ba67e1..000000000 --- a/remote/registry.sh +++ /dev/null @@ -1,3 +0,0 @@ -rmiregistry & -sleep $1 -killall rmiregistry diff --git a/remote/server.bat b/remote/server.bat deleted file mode 100644 index 119f5255f..000000000 --- a/remote/server.bat +++ /dev/null @@ -1,4 +0,0 @@ -start /min "PerfectTimeServer" java PerfectTimeServer -timeout /t %1 -taskkill /im java.exe -exit \ No newline at end of file diff --git a/remote/server.sh b/remote/server.sh deleted file mode 100644 index 1149bf92f..000000000 --- a/remote/server.sh +++ /dev/null @@ -1,3 +0,0 @@ -java PerfectTimeServer & -sleep $1 -pkill -f 'java PerfectTimeServer' \ No newline at end of file diff --git a/reuse/Bath.java b/reuse/Bath.java index 3266f8de0..f31a1490d 100644 --- a/reuse/Bath.java +++ b/reuse/Bath.java @@ -1,7 +1,7 @@ // reuse/Bath.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Constructor initialization with composition class Soap { @@ -10,8 +10,7 @@ class Soap { System.out.println("Soap()"); s = "Constructed"; } - @Override - public String toString() { return s; } + @Override public String toString() { return s; } } public class Bath { @@ -19,19 +18,18 @@ public class Bath { s1 = "Happy", s2 = "Happy", s3, s4; - private Soap castille; + private Soap castile; private int i; private float toy; public Bath() { System.out.println("Inside Bath()"); s3 = "Joy"; toy = 3.14f; - castille = new Soap(); + castile = new Soap(); } // Instance initialization: { i = 47; } - @Override - public String toString() { + @Override public String toString() { if(s4 == null) // Delayed initialization: s4 = "Joy"; return @@ -41,7 +39,7 @@ public String toString() { "s4 = " + s4 + "\n" + "i = " + i + "\n" + "toy = " + toy + "\n" + - "castille = " + castille; + "castile = " + castile; } public static void main(String[] args) { Bath b = new Bath(); @@ -57,5 +55,5 @@ Inside Bath() s4 = Joy i = 47 toy = 3.14 -castille = Constructed +castile = Constructed */ diff --git a/reuse/Beetle.java b/reuse/Beetle.java index 15dc2cebd..089f85e07 100644 --- a/reuse/Beetle.java +++ b/reuse/Beetle.java @@ -1,7 +1,7 @@ // reuse/Beetle.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // The full process of initialization class Insect { diff --git a/reuse/BlankFinal.java b/reuse/BlankFinal.java index 24e5a576a..fd96fe9b8 100644 --- a/reuse/BlankFinal.java +++ b/reuse/BlankFinal.java @@ -1,7 +1,7 @@ // reuse/BlankFinal.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // "Blank" final fields class Poppet { @@ -13,14 +13,14 @@ 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 the constructor: + // Blank finals MUST be initialized in constructor: public BlankFinal() { j = 1; // Initialize blank final - p = new Poppet(1); // Initialize blank final reference + p = new Poppet(1); // Init blank final reference } public BlankFinal(int x) { j = x; // Initialize blank final - p = new Poppet(x); // Initialize blank final reference + p = new Poppet(x); // Init blank final reference } public static void main(String[] args) { new BlankFinal(); diff --git a/reuse/CADSystem.java b/reuse/CADSystem.java index 2cd10f742..c2af7deac 100644 --- a/reuse/CADSystem.java +++ b/reuse/CADSystem.java @@ -1,8 +1,9 @@ // reuse/CADSystem.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Ensuring proper cleanup +// {java reuse.CADSystem} package reuse; class Shape { @@ -19,8 +20,7 @@ class Circle extends Shape { super(i); System.out.println("Drawing Circle"); } - @Override - void dispose() { + @Override void dispose() { System.out.println("Erasing Circle"); super.dispose(); } @@ -31,8 +31,7 @@ class Triangle extends Shape { super(i); System.out.println("Drawing Triangle"); } - @Override - void dispose() { + @Override void dispose() { System.out.println("Erasing Triangle"); super.dispose(); } @@ -47,8 +46,7 @@ class Line extends Shape { System.out.println( "Drawing Line: " + start + ", " + end); } - @Override - void dispose() { + @Override void dispose() { System.out.println( "Erasing Line: " + start + ", " + end); super.dispose(); @@ -67,8 +65,7 @@ public CADSystem(int i) { t = new Triangle(1); System.out.println("Combined constructor"); } - @Override - public void dispose() { + @Override public void dispose() { System.out.println("CADSystem.dispose()"); // The order of cleanup is the reverse // of the order of initialization: diff --git a/reuse/Car.java b/reuse/Car.java index 20e0bbe29..46021e7ad 100644 --- a/reuse/Car.java +++ b/reuse/Car.java @@ -1,7 +1,7 @@ // reuse/Car.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Composition with public objects class Engine { diff --git a/reuse/Cartoon.java b/reuse/Cartoon.java index 77a924064..4b2634570 100644 --- a/reuse/Cartoon.java +++ b/reuse/Cartoon.java @@ -1,7 +1,7 @@ // reuse/Cartoon.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Constructor calls during inheritance class Art { diff --git a/reuse/Chess.java b/reuse/Chess.java index ec3cdb755..2bd41b001 100644 --- a/reuse/Chess.java +++ b/reuse/Chess.java @@ -1,7 +1,7 @@ // reuse/Chess.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Inheritance, constructors and arguments class Game { diff --git a/reuse/DerivedSpaceShip.java b/reuse/DerivedSpaceShip.java new file mode 100644 index 000000000..5df55f543 --- /dev/null +++ b/reuse/DerivedSpaceShip.java @@ -0,0 +1,20 @@ +// reuse/DerivedSpaceShip.java +// (c)2021 MindView 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/reuse/Detergent.java b/reuse/Detergent.java index 367315bdb..2f25309d1 100644 --- a/reuse/Detergent.java +++ b/reuse/Detergent.java @@ -1,7 +1,7 @@ // reuse/Detergent.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Inheritance syntax & properties class Cleanser { @@ -10,8 +10,7 @@ class Cleanser { public void dilute() { append(" dilute()"); } public void apply() { append(" apply()"); } public void scrub() { append(" scrub()"); } - @Override - public String toString() { return s; } + @Override public String toString() { return s; } public static void main(String[] args) { Cleanser x = new Cleanser(); x.dilute(); x.apply(); x.scrub(); @@ -21,8 +20,7 @@ public static void main(String[] args) { public class Detergent extends Cleanser { // Change a method: - @Override - public void scrub() { + @Override public void scrub() { append(" Detergent.scrub()"); super.scrub(); // Call base-class version } @@ -41,7 +39,8 @@ public static void main(String[] args) { } } /* Output: -Cleanser dilute() apply() Detergent.scrub() scrub() foam() +Cleanser dilute() apply() Detergent.scrub() scrub() +foam() Testing base class: Cleanser dilute() apply() scrub() */ diff --git a/reuse/FinalArguments.java b/reuse/FinalArguments.java index b648de4dd..2c8e649d7 100644 --- a/reuse/FinalArguments.java +++ b/reuse/FinalArguments.java @@ -1,7 +1,7 @@ // reuse/FinalArguments.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Using "final" with method arguments class Gizmo { diff --git a/reuse/FinalData.java b/reuse/FinalData.java index 40a7895c7..97539e636 100644 --- a/reuse/FinalData.java +++ b/reuse/FinalData.java @@ -1,13 +1,13 @@ // reuse/FinalData.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // The effect of final on fields import java.util.*; class Value { int i; // Package access - public Value(int i) { this.i = i; } + Value(int i) { this.i = i; } } public class FinalData { @@ -27,8 +27,7 @@ public class FinalData { private static final Value VAL_3 = new Value(33); // Arrays: private final int[] a = { 1, 2, 3, 4, 5, 6 }; - @Override - public String toString() { + @Override public String toString() { return id + ": " + "i4 = " + i4 + ", INT_5 = " + INT_5; } diff --git a/reuse/FinalOverridingIllusion.java b/reuse/FinalOverridingIllusion.java index 15ef7e9ce..a74df7bef 100644 --- a/reuse/FinalOverridingIllusion.java +++ b/reuse/FinalOverridingIllusion.java @@ -1,7 +1,7 @@ // reuse/FinalOverridingIllusion.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // It only looks like you can override // a private or private final method diff --git a/reuse/Hide.java b/reuse/Hide.java index 878c0f283..e4122091b 100644 --- a/reuse/Hide.java +++ b/reuse/Hide.java @@ -1,7 +1,7 @@ // reuse/Hide.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 diff --git a/reuse/Jurassic.java b/reuse/Jurassic.java index 1b9650269..7d85e4fb7 100644 --- a/reuse/Jurassic.java +++ b/reuse/Jurassic.java @@ -1,7 +1,7 @@ // reuse/Jurassic.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Making an entire class final class SmallBrain {} diff --git a/reuse/Lisa.java b/reuse/Lisa.java index e1301d19f..68cccf0a7 100644 --- a/reuse/Lisa.java +++ b/reuse/Lisa.java @@ -1,8 +1,8 @@ // reuse/Lisa.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {CompileTimeError} (Won't compile) +// Visit http://OnJava8.com for more book information. +// {WillNotCompile} class Lisa extends Homer { @Override void doh(Milhouse m) { diff --git a/reuse/Orc.java b/reuse/Orc.java index 14376a483..c1f984208 100644 --- a/reuse/Orc.java +++ b/reuse/Orc.java @@ -1,15 +1,14 @@ // reuse/Orc.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // The protected keyword class Villain { private String name; protected void set(String nm) { name = nm; } - public Villain(String name) { this.name = name; } - @Override - public String toString() { + Villain(String name) { this.name = name; } + @Override public String toString() { return "I'm a Villain and my name is " + name; } } @@ -24,8 +23,7 @@ public void change(String name, int orcNumber) { set(name); // Available because it's protected this.orcNumber = orcNumber; } - @Override - public String toString() { + @Override public String toString() { return "Orc " + orcNumber + ": " + super.toString(); } public static void main(String[] args) { diff --git a/reuse/PlaceSetting.java b/reuse/PlaceSetting.java index 9f443976a..ec2486a80 100644 --- a/reuse/PlaceSetting.java +++ b/reuse/PlaceSetting.java @@ -1,7 +1,7 @@ // reuse/PlaceSetting.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Combining composition & inheritance class Plate { diff --git a/reuse/SpaceShip.java b/reuse/SpaceShip.java deleted file mode 100644 index 9ac426b43..000000000 --- a/reuse/SpaceShip.java +++ /dev/null @@ -1,15 +0,0 @@ -// reuse/SpaceShip.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. - -public class SpaceShip extends SpaceShipControls { - private String name; - public SpaceShip(String name) { this.name = name; } - @Override - public String toString() { return name; } - public static void main(String[] args) { - SpaceShip protector = new SpaceShip("NSEA Protector"); - protector.forward(100); - } -} diff --git a/reuse/SpaceShipControls.java b/reuse/SpaceShipControls.java index 077303226..fba9aaff5 100644 --- a/reuse/SpaceShipControls.java +++ b/reuse/SpaceShipControls.java @@ -1,7 +1,7 @@ // reuse/SpaceShipControls.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class SpaceShipControls { void up(int velocity) {} diff --git a/reuse/SpaceShipDelegation.java b/reuse/SpaceShipDelegation.java index d82f545d3..aeeca9fc2 100644 --- a/reuse/SpaceShipDelegation.java +++ b/reuse/SpaceShipDelegation.java @@ -1,7 +1,7 @@ // reuse/SpaceShipDelegation.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class SpaceShipDelegation { private String name; diff --git a/reuse/SprinklerSystem.java b/reuse/SprinklerSystem.java index d967f95ec..6cc174ff7 100644 --- a/reuse/SprinklerSystem.java +++ b/reuse/SprinklerSystem.java @@ -1,7 +1,7 @@ // reuse/SprinklerSystem.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Composition for code reuse class WaterSource { @@ -10,8 +10,7 @@ class WaterSource { System.out.println("WaterSource()"); s = "Constructed"; } - @Override - public String toString() { return s; } + @Override public String toString() { return s; } } public class SprinklerSystem { @@ -19,15 +18,14 @@ public class SprinklerSystem { private WaterSource source = new WaterSource(); private int i; private float f; - @Override - public String toString() { + @Override public String toString() { return "valve1 = " + valve1 + " " + "valve2 = " + valve2 + " " + "valve3 = " + valve3 + " " + "valve4 = " + valve4 + "\n" + "i = " + i + " " + "f = " + f + " " + - "source = " + source; // (1) + "source = " + source; // [1] } public static void main(String[] args) { SprinklerSystem sprinklers = new SprinklerSystem(); diff --git a/reuse/Wind.java b/reuse/Wind.java index 49ff6e409..ef1c79d17 100644 --- a/reuse/Wind.java +++ b/reuse/Wind.java @@ -1,7 +1,7 @@ // reuse/Wind.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Inheritance & upcasting class Instrument { diff --git a/reuse/build.xml b/reuse/build.xml deleted file mode 100644 index a915b93b2..000000000 --- a/reuse/build.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/run.bat b/run.bat deleted file mode 100644 index 83d7120c7..000000000 --- a/run.bat +++ /dev/null @@ -1,3 +0,0 @@ -python ..\tools\Validate.py -p -powershell .\runall.ps1 -python ..\tools\Validate.py -e diff --git a/serialization/APerson.java b/serialization/APerson.java index 930b5a4a3..6eb667ae9 100644 --- a/serialization/APerson.java +++ b/serialization/APerson.java @@ -1,10 +1,9 @@ // serialization/APerson.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Use the XOM library to write and read XML -// {Requires: nu.xom.Node; You must install -// the XOM library from http://www.xom.nu } +// nu.xom.Node comes from http://www.xom.nu import nu.xom.*; import java.io.*; import java.util.*; @@ -26,18 +25,20 @@ public Element getXML() { person.appendChild(lastName); return person; } - // Constructor restores a APerson from an XML Element: + // Constructor restores a APerson from XML: public APerson(Element person) { - first = - person.getFirstChildElement("first").getValue(); - last = - person.getFirstChildElement("last").getValue(); + first = person + .getFirstChildElement("first").getValue(); + last = person + .getFirstChildElement("last").getValue(); + } + @Override public String toString() { + return first + " " + last; } - @Override - public String toString() { return first + " " + last; } // Make it human-readable: public static void - format(OutputStream os, Document doc) throws Exception { + format(OutputStream os, Document doc) + throws Exception { Serializer serializer = new Serializer(os,"ISO-8859-1"); serializer.setIndent(4); diff --git a/serialization/AStoreCADState.java b/serialization/AStoreCADState.java index afcc799d6..ef496b808 100644 --- a/serialization/AStoreCADState.java +++ b/serialization/AStoreCADState.java @@ -1,113 +1,104 @@ // serialization/AStoreCADState.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 { - public static final int RED = 1, BLUE = 2, GREEN = 3; private int xPos, yPos, dimension; - private static SplittableRandom rand = new SplittableRandom(47); - private static int counter = 0; - public abstract void setColor(int newColor); - public abstract int getColor(); - public Shape(int xVal, int yVal, int dim) { + 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 abstract void setColor(Color newColor); + public abstract Color getColor(); + @Override public String toString() { + return "\n" + getClass() + " " + getColor() + + " xPos[" + xPos + "] yPos[" + yPos + + "] dim[" + dimension + "]"; } + private static Random rand = new Random(47); + private static int counter = 0; public static Shape randomFactory() { int xVal = rand.nextInt(100); int yVal = rand.nextInt(100); int dim = rand.nextInt(100); - switch(counter++ % 3) { + switch(counter++ % 2) { 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); + case 1: return new Line(xVal, yVal, dim); } } } class Circle extends Shape { - private static int color = RED; - public Circle(int xVal, int yVal, int dim) { + Circle(int xVal, int yVal, int dim) { super(xVal, yVal, dim); } - public void setColor(int newColor) { color = newColor; } - public int getColor() { return color; } -} - -class Square extends Shape { - private static int color; - public Square(int xVal, int yVal, int dim) { - super(xVal, yVal, dim); - color = RED; + private static Color color = Color.RED; + @Override public void setColor(Color newColor) { + color = newColor; } - public void setColor(int newColor) { color = newColor; } - public int getColor() { return color; } + @Override public Color getColor() { return color; } } class Line extends Shape { - private static int color = RED; + Line(int xVal, int yVal, int dim) { + super(xVal, yVal, dim); + } + private static Color color = Color.RED; + @Override public void setColor(Color newColor) { + color = newColor; + } + @Override public Color getColor() { return color; } public static void serializeStaticState(ObjectOutputStream os) - throws IOException { os.writeInt(color); } + throws IOException { + os.writeObject(color); + } public static void deserializeStaticState(ObjectInputStream os) - throws IOException { color = os.readInt(); } - public Line(int xVal, int yVal, int dim) { - super(xVal, yVal, dim); + throws IOException, ClassNotFoundException { + color = (Color)os.readObject(); } - public void setColor(int newColor) { color = newColor; } - public int getColor() { return color; } } public class AStoreCADState { - public static void - main(String[] args) throws Exception { + public static void main(String[] args) { List> shapeTypes = - new ArrayList<>(); - // Add references to the class objects: - shapeTypes.add(Circle.class); - shapeTypes.add(Square.class); - shapeTypes.add(Line.class); - List shapes = new ArrayList<>(); - // Make some shapes: - for(int i = 0; i < 10; i++) - shapes.add(Shape.randomFactory()); + Arrays.asList(Circle.class, Line.class); + List shapes = IntStream.range(0, 5) + .mapToObj(i -> Shape.randomFactory()) + .collect(Collectors.toList()); // Set all the static colors to GREEN: - for(int i = 0; i < 10; i++) - ((Shape)shapes.get(i)).setColor(Shape.GREEN); - // Save the state vector: - try(ObjectOutputStream out = - new ObjectOutputStream( - new FileOutputStream("CADState.dat"))) { + shapes.forEach(s -> s.setColor(Color.GREEN)); + // Serialize everything to CADState.dat: + 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[3] xPos[58] yPos[55] dim[93] -, class Squarecolor[3] xPos[61] yPos[61] dim[29] -, class Linecolor[3] xPos[68] yPos[0] dim[22] -, class Circlecolor[3] xPos[7] yPos[88] dim[28] -, class Squarecolor[3] xPos[51] yPos[89] dim[9] -, class Linecolor[3] xPos[78] yPos[98] dim[61] -, class Circlecolor[3] xPos[20] yPos[58] dim[16] -, class Squarecolor[3] xPos[40] yPos[11] dim[22] -, class Linecolor[3] xPos[4] yPos[83] dim[6] -, class Circlecolor[3] xPos[75] yPos[10] dim[42] -] +[ +class Circle GREEN xPos[58] yPos[55] dim[93], +class Line GREEN xPos[61] yPos[61] dim[29], +class Circle GREEN xPos[68] yPos[0] dim[22], +class Line GREEN xPos[7] yPos[88] dim[28], +class Circle GREEN xPos[51] yPos[89] dim[9]] */ diff --git a/serialization/Alien.java b/serialization/Alien.java index ce07a4050..b0ba09a4e 100644 --- a/serialization/Alien.java +++ b/serialization/Alien.java @@ -1,7 +1,7 @@ // serialization/Alien.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // A serializable class import java.io.*; public class Alien implements Serializable {} diff --git a/serialization/Blip3.java b/serialization/Blip3.java index 7e13b58b8..0e6907375 100644 --- a/serialization/Blip3.java +++ b/serialization/Blip3.java @@ -1,7 +1,7 @@ // serialization/Blip3.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Reconstructing an externalizable object import java.io.*; @@ -16,42 +16,45 @@ 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. + // s & i initialized only in non-zero-argument constructor. } - @Override - public String toString() { return s + i; } - @Override - public void writeExternal(ObjectOutput out) + @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) + @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) throws IOException, - ClassNotFoundException { + 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"))) { + 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"))) { + 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); } diff --git a/serialization/Blips.java b/serialization/Blips.java index 4e81ca34d..0ae46686f 100644 --- a/serialization/Blips.java +++ b/serialization/Blips.java @@ -1,7 +1,7 @@ // serialization/Blips.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Simple use of Externalizable & a pitfall import java.io.*; @@ -38,23 +38,29 @@ public void readExternal(ObjectInput in) } public class Blips { - public static void - main(String[] args) throws IOException, - ClassNotFoundException { + 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"))) { + 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"))) { + 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:"); diff --git a/serialization/FreezeAlien.java b/serialization/FreezeAlien.java index cb2ae0194..3ff390b88 100644 --- a/serialization/FreezeAlien.java +++ b/serialization/FreezeAlien.java @@ -1,16 +1,19 @@ // serialization/FreezeAlien.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 { - ObjectOutput out = new ObjectOutputStream( - new FileOutputStream("X.file")); - Alien quellek = new Alien(); - out.writeObject(quellek); + try( + ObjectOutputStream out = new ObjectOutputStream( + new FileOutputStream("X.file")); + ) { + Alien quellek = new Alien(); + out.writeObject(quellek); + } } } diff --git a/serialization/Logon.java b/serialization/Logon.java index 5987b7734..c8f6d9c58 100644 --- a/serialization/Logon.java +++ b/serialization/Logon.java @@ -1,11 +1,12 @@ // serialization/Logon.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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(); @@ -15,26 +16,34 @@ 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; + @Override public String toString() { + return "logon info: \n username: " + + username + "\n date: " + date + + "\n password: " + password; } - public static void - main(String[] args) throws Exception { + 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"))) { + try( + ObjectOutputStream o = + new ObjectOutputStream( + new FileOutputStream("Logon.dat")) + ) { o.writeObject(a); + } catch(IOException e) { + throw new RuntimeException(e); } - TimeUnit.SECONDS.sleep(1); // Delay + new Nap(1); // Now get them back: - try(ObjectInputStream in = new ObjectInputStream( - new FileInputStream("Logon.dat"))) { + 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); } @@ -42,11 +51,11 @@ public String toString() { /* Output: logon a = logon info: username: Hulk - date: Tue Dec 08 16:09:48 PST 2015 + date: Sun Jan 24 08:49:30 MST 2021 password: myLittlePony -Recovering object at Tue Dec 08 16:09:49 PST 2015 +Recovering object at Sun Jan 24 08:49:31 MST 2021 logon a = logon info: username: Hulk - date: Tue Dec 08 16:09:48 PST 2015 + date: Sun Jan 24 08:49:30 MST 2021 password: null */ diff --git a/serialization/MyWorld.java b/serialization/MyWorld.java index d42f4ff52..f642530fa 100644 --- a/serialization/MyWorld.java +++ b/serialization/MyWorld.java @@ -1,7 +1,7 @@ // serialization/MyWorld.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.io.*; import java.util.*; @@ -14,53 +14,64 @@ class Animal implements Serializable { name = nm; preferredHouse = h; } - @Override - public String toString() { + @Override public String toString() { return name + "[" + super.toString() + "], " + preferredHouse + "\n"; } } public class MyWorld { - public static void - main(String[] args) throws IOException, - ClassNotFoundException { + 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)); + 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)) { + 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)) { + 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()))) { + 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); + System.out.println( + "animals1: " + animals1); + System.out.println( + "animals2: " + animals2); + System.out.println( + "animals3: " + animals3); } } + } catch(IOException | ClassNotFoundException e) { + throw new RuntimeException(e); } } } @@ -69,16 +80,16 @@ public class MyWorld { , Ralph the hamster[Animal@1db9742], House@139a55 , Molly the cat[Animal@106d69c], House@139a55 ] -animals1: [Bosco the dog[Animal@10bedb4], House@103dbd3 -, Ralph the hamster[Animal@167cf4d], House@103dbd3 -, Molly the cat[Animal@a987ac], House@103dbd3 +animals1: [Bosco the dog[Animal@1ee12a7], House@10bedb4 +, Ralph the hamster[Animal@103dbd3], House@10bedb4 +, Molly the cat[Animal@167cf4d], House@10bedb4 ] -animals2: [Bosco the dog[Animal@10bedb4], House@103dbd3 -, Ralph the hamster[Animal@167cf4d], House@103dbd3 -, Molly the cat[Animal@a987ac], House@103dbd3 +animals2: [Bosco the dog[Animal@1ee12a7], House@10bedb4 +, Ralph the hamster[Animal@103dbd3], House@10bedb4 +, Molly the cat[Animal@167cf4d], House@10bedb4 ] -animals3: [Bosco the dog[Animal@a3a380], House@1453f44 -, Ralph the hamster[Animal@ad8086], House@1453f44 -, Molly the cat[Animal@be858], House@1453f44 +animals3: [Bosco the dog[Animal@a987ac], House@a3a380 +, Ralph the hamster[Animal@1453f44], House@a3a380 +, Molly the cat[Animal@ad8086], House@a3a380 ] */ diff --git a/serialization/People.java b/serialization/People.java index 5a7a7fa12..b30456669 100644 --- a/serialization/People.java +++ b/serialization/People.java @@ -1,9 +1,8 @@ // serialization/People.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {Requires: nu.xom.Node; You must install -// the XOM library from http://www.xom.nu } +// 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; diff --git a/serialization/RecoverCADState.java b/serialization/RecoverCADState.java index e23d0bca3..3c4bec35d 100644 --- a/serialization/RecoverCADState.java +++ b/serialization/RecoverCADState.java @@ -1,7 +1,7 @@ // serialization/RecoverCADState.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Restoring the state of the fictitious CAD system // {RunFirst: AStoreCADState} import java.io.*; @@ -9,30 +9,28 @@ public class RecoverCADState { @SuppressWarnings("unchecked") - public static void - main(String[] args) throws Exception { - try(ObjectInputStream in = - new ObjectInputStream( - new FileInputStream("CADState.dat"))) { + 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[1] xPos[58] yPos[55] dim[93] -, class Squarecolor[0] xPos[61] yPos[61] dim[29] -, class Linecolor[3] xPos[68] yPos[0] dim[22] -, class Circlecolor[1] xPos[7] yPos[88] dim[28] -, class Squarecolor[0] xPos[51] yPos[89] dim[9] -, class Linecolor[3] xPos[78] yPos[98] dim[61] -, class Circlecolor[1] xPos[20] yPos[58] dim[16] -, class Squarecolor[0] xPos[40] yPos[11] dim[22] -, class Linecolor[3] xPos[4] yPos[83] dim[6] -, class Circlecolor[1] xPos[75] yPos[10] dim[42] -] +[ +class Circle RED xPos[58] yPos[55] dim[93], +class Line GREEN xPos[61] yPos[61] dim[29], +class Circle RED xPos[68] yPos[0] dim[22], +class Line GREEN xPos[7] yPos[88] dim[28], +class Circle RED xPos[51] yPos[89] dim[9]] */ diff --git a/serialization/SerialCtl.java b/serialization/SerialCtl.java index 198676289..dd1d41a1f 100644 --- a/serialization/SerialCtl.java +++ b/serialization/SerialCtl.java @@ -1,7 +1,7 @@ // serialization/SerialCtl.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Controlling serialization by adding your own // writeObject() and readObject() methods import java.io.*; @@ -13,8 +13,9 @@ public SerialCtl(String aa, String bb) { a = "Not Transient: " + aa; b = "Transient: " + bb; } - @Override - public String toString() { return a + "\n" + b; } + @Override public String toString() { + return a + "\n" + b; + } private void writeObject(ObjectOutputStream stream) throws IOException { stream.defaultWriteObject(); @@ -25,20 +26,29 @@ private void readObject(ObjectInputStream stream) stream.defaultReadObject(); b = (String)stream.readObject(); } - public static void - main(String[] args) throws IOException, - ClassNotFoundException { + public static void main(String[] args) { SerialCtl sc = new SerialCtl("Test1", "Test2"); System.out.println("Before:\n" + sc); - ByteArrayOutputStream buf = - new ByteArrayOutputStream(); - ObjectOutputStream o = new ObjectOutputStream(buf); - o.writeObject(sc); - // Now get it back: - ObjectInputStream in = new ObjectInputStream( - new ByteArrayInputStream(buf.toByteArray())); - SerialCtl sc2 = (SerialCtl)in.readObject(); - System.out.println("After:\n" + sc2); + 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: diff --git a/serialization/Worm.java b/serialization/Worm.java index 0b3d949f4..7959be098 100644 --- a/serialization/Worm.java +++ b/serialization/Worm.java @@ -1,22 +1,21 @@ // serialization/Worm.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Demonstrates object serialization import java.io.*; import java.util.*; class Data implements Serializable { private int n; - public Data(int n) { this.n = n; } - @Override - public String toString() { + Data(int n) { this.n = n; } + @Override public String toString() { return Integer.toString(n); } } public class Worm implements Serializable { - private static SplittableRandom rand = new SplittableRandom(47); + private static Random rand = new Random(47); private Data[] d = { new Data(rand.nextInt(10)), new Data(rand.nextInt(10)), @@ -32,10 +31,9 @@ public Worm(int i, char x) { next = new Worm(i, (char)(x + 1)); } public Worm() { - System.out.println("No-arg constructor"); + System.out.println("Zero-argument constructor"); } - @Override - public String toString() { + @Override public String toString() { StringBuilder result = new StringBuilder(":"); result.append(c); result.append("("); @@ -51,27 +49,35 @@ public String toString() { IOException { Worm w = new Worm(6, 'a'); System.out.println("w = " + w); - try(ObjectOutputStream out = new ObjectOutputStream( - new FileOutputStream("worm.dat"))) { + 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"))) { + 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)) { + 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()))) { + 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); diff --git a/serialization/build.xml b/serialization/build.xml deleted file mode 100644 index 64b5592dd..000000000 --- a/serialization/build.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/serialization/xfiles/ThawAlien.java b/serialization/xfiles/ThawAlien.java index 0032abde5..850abd40d 100644 --- a/serialization/xfiles/ThawAlien.java +++ b/serialization/xfiles/ThawAlien.java @@ -1,8 +1,10 @@ // serialization/xfiles/ThawAlien.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Recover a serialized file +// {java serialization.xfiles.ThawAlien} +// {RunFirst: FreezeAlien} package serialization.xfiles; import java.io.*; @@ -10,7 +12,7 @@ public class ThawAlien { public static void main(String[] args) throws Exception { ObjectInputStream in = new ObjectInputStream( - new FileInputStream(new File("..", "X.file"))); + new FileInputStream(new File("X.file"))); Object mystery = in.readObject(); System.out.println(mystery.getClass()); } diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 000000000..9ab61dfbe --- /dev/null +++ b/settings.gradle @@ -0,0 +1,11 @@ +def isSubproject = { File file -> + file.isDirectory() && + !file.name.startsWith('.') && + !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/standardio/ChangeSystemOut.java b/standardio/ChangeSystemOut.java index d3943605b..e0a06bb7a 100644 --- a/standardio/ChangeSystemOut.java +++ b/standardio/ChangeSystemOut.java @@ -1,13 +1,14 @@ // standardio/ChangeSystemOut.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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); + PrintWriter out = + new PrintWriter(System.out, true); out.println("Hello, world"); } } diff --git a/standardio/Echo.java b/standardio/Echo.java index c59ac07cb..1119d6ce6 100644 --- a/standardio/Echo.java +++ b/standardio/Echo.java @@ -1,20 +1,20 @@ // standardio/Echo.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // How to read from standard input -// {TimeOutDuringTesting} import java.io.*; +import onjava.TimedAbort; public class Echo { - public static void - main(String[] args) throws IOException { - BufferedReader stdin = new BufferedReader( - new InputStreamReader(System.in)); - String s; - while((s=stdin.readLine()) != null && - s.length() != 0) - System.out.println(s); - // An empty line or Ctrl-Z terminates the program + 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/standardio/OSExecuteDemo.java b/standardio/OSExecuteDemo.java index 4801605e6..608efe81b 100644 --- a/standardio/OSExecuteDemo.java +++ b/standardio/OSExecuteDemo.java @@ -1,19 +1,16 @@ // standardio/OSExecuteDemo.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 { - public static void main(String[] args) { - OSExecute.command("javap OSExecuteDemo"); - } -} +public class OSExecuteDemo {} /* Output: Compiled from "OSExecuteDemo.java" public class OSExecuteDemo { public OSExecuteDemo(); - public static void main(java.lang.String[]); } */ diff --git a/standardio/Redirecting.java b/standardio/Redirecting.java index 5f647bc54..c89ef6303 100644 --- a/standardio/Redirecting.java +++ b/standardio/Redirecting.java @@ -1,29 +1,31 @@ // standardio/Redirecting.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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) throws IOException { + 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")))) { + 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); - BufferedReader br = new BufferedReader( - new InputStreamReader(System.in)); - String s; - while((s = br.readLine()) != null) - System.out.println(s); - out.close(); // Remember this! + new BufferedReader( + new InputStreamReader(System.in)) + .lines() + .forEach(System.out::println); + } catch(IOException e) { + throw new RuntimeException(e); + } finally { + System.setOut(console); } - System.setOut(console); } } diff --git a/standardio/build.xml b/standardio/build.xml deleted file mode 100644 index 5a06e4553..000000000 --- a/standardio/build.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/staticchecking/DogsAndRobots.cpp b/staticchecking/DogsAndRobots.cpp index eeb7f12e0..e7c1cbbc7 100644 --- a/staticchecking/DogsAndRobots.cpp +++ b/staticchecking/DogsAndRobots.cpp @@ -1,7 +1,7 @@ // staticchecking/DogsAndRobots.cpp -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. #include using namespace std; diff --git a/staticchecking/DogsAndRobots.py b/staticchecking/DogsAndRobots.py index 68663e349..df423de0b 100644 --- a/staticchecking/DogsAndRobots.py +++ b/staticchecking/DogsAndRobots.py @@ -1,7 +1,7 @@ # staticchecking/DogsAndRobots.py -# (c)2016 MindView LLC: see Copyright.txt +# (c)2021 MindView LLC: see Copyright.txt # We make no guarantees that this code is fit for any purpose. -# Visit http://mindviewinc.com/Books/OnJava/ for more book information. +# Visit http://OnJava8.com for more book information. def speak(anything): anything.talk() diff --git a/staticchecking/NoBasePetSpeak.py b/staticchecking/NoBasePetSpeak.py index 6ada61896..13590f221 100644 --- a/staticchecking/NoBasePetSpeak.py +++ b/staticchecking/NoBasePetSpeak.py @@ -1,8 +1,8 @@ # staticchecking/NoBasePetSpeak.py -# (c)2016 MindView LLC: see Copyright.txt +# (c)2021 MindView LLC: see Copyright.txt # We make no guarantees that this code is fit for any purpose. -# Visit http://mindviewinc.com/Books/OnJava/ for more book information. -# Speaking pets without base classes +# Visit http://OnJava8.com for more book information. +#- Speaking pets without base classes class Cat: def speak(self): diff --git a/staticchecking/PetSpeak.py b/staticchecking/PetSpeak.py index 36c8f2d3c..8699a6c83 100644 --- a/staticchecking/PetSpeak.py +++ b/staticchecking/PetSpeak.py @@ -1,8 +1,8 @@ # staticchecking/PetSpeak.py -# (c)2016 MindView LLC: see Copyright.txt +# (c)2021 MindView LLC: see Copyright.txt # We make no guarantees that this code is fit for any purpose. -# Visit http://mindviewinc.com/Books/OnJava/ for more book information. -# Speaking pets in Python +# Visit http://OnJava8.com for more book information. +#- Speaking pets in Python class Pet: def speak(self): pass diff --git a/staticchecking/build.xml b/staticchecking/build.xml deleted file mode 100644 index 1d8f3350f..000000000 --- a/staticchecking/build.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/staticchecking/dogsandrobots.go b/staticchecking/dogsandrobots.go index fdfe72e80..6f353bd83 100644 --- a/staticchecking/dogsandrobots.go +++ b/staticchecking/dogsandrobots.go @@ -1,7 +1,7 @@ // staticchecking/dogsandrobots.go -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package main import "fmt" diff --git a/staticchecking/dr/DogsAndRobots.java b/staticchecking/dr/DogsAndRobots.java index d44f74b90..3297a663a 100644 --- a/staticchecking/dr/DogsAndRobots.java +++ b/staticchecking/dr/DogsAndRobots.java @@ -1,20 +1,21 @@ // staticchecking/dr/DogsAndRobots.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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() { + @Override public void talk() { System.out.println("Woof!"); } public void reproduce() { } } class Robot implements Speaks { - public void talk() { + @Override public void talk() { System.out.println("Click!"); } public void oilChange() { } diff --git a/staticchecking/drc/DogAndRobotCollections.java b/staticchecking/drc/DogAndRobotCollections.java index e8cfaccc2..fdcbed71e 100644 --- a/staticchecking/drc/DogAndRobotCollections.java +++ b/staticchecking/drc/DogAndRobotCollections.java @@ -1,7 +1,8 @@ // staticchecking/drc/DogAndRobotCollections.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {java staticchecking.drc.DogAndRobotCollections} package staticchecking.drc; import java.util.*; @@ -24,10 +25,10 @@ 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 Dog()); //- dogList.add(new Robot()); // Compile-time error for(int i = 0; i < 10; i++) - robotList.add(new Robot()); + robotList.add(new Robot()); //- robotList.add(new Dog()); // Compile-time error dogList.forEach(Dog::talk); robotList.forEach(Robot::talk); diff --git a/staticchecking/latent/Latent.java b/staticchecking/latent/Latent.java index e49f5af7e..04a374fb2 100644 --- a/staticchecking/latent/Latent.java +++ b/staticchecking/latent/Latent.java @@ -1,7 +1,8 @@ // staticchecking/latent/Latent.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {java staticchecking.latent.Latent} package staticchecking.latent; import java.lang.reflect.*; @@ -21,6 +22,7 @@ public void oilChange() {} class Mime { public void walkAgainstTheWind() {} + @Override public String toString() { return "Mime"; } } diff --git a/staticchecking/petspeak.go b/staticchecking/petspeak.go index e226e8a9c..497178a4a 100644 --- a/staticchecking/petspeak.go +++ b/staticchecking/petspeak.go @@ -1,7 +1,7 @@ // staticchecking/petspeak.go -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package main import "fmt" diff --git a/staticchecking/petspeak/PetSpeak.java b/staticchecking/petspeak/PetSpeak.java index 3a3d79c65..86a3db3d7 100644 --- a/staticchecking/petspeak/PetSpeak.java +++ b/staticchecking/petspeak/PetSpeak.java @@ -1,8 +1,9 @@ // staticchecking/petspeak/PetSpeak.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Speaking pets in Java +// {java staticchecking.petspeak.PetSpeak} package staticchecking.petspeak; interface Pet { @@ -10,13 +11,13 @@ interface Pet { } class Cat implements Pet { - public void speak() { + @Override public void speak() { System.out.println("meow!"); } } class Dog implements Pet { - public void speak() { + @Override public void speak() { System.out.println("woof!"); } } diff --git a/streams/ArrayStreams.java b/streams/ArrayStreams.java index ecfcbd230..74c164606 100644 --- a/streams/ArrayStreams.java +++ b/streams/ArrayStreams.java @@ -1,13 +1,14 @@ // streams/ArrayStreams.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 }) + 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 }) diff --git a/streams/Bubble.java b/streams/Bubble.java index c0cba17c3..86c99297d 100644 --- a/streams/Bubble.java +++ b/streams/Bubble.java @@ -1,14 +1,13 @@ // streams/Bubble.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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() { + @Override public String toString() { return "Bubble(" + i + ")"; } private static int count = 0; diff --git a/streams/Bubbles.java b/streams/Bubbles.java index 89771baea..21efc8a44 100644 --- a/streams/Bubbles.java +++ b/streams/Bubbles.java @@ -1,7 +1,7 @@ // streams/Bubbles.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.stream.*; public class Bubbles { diff --git a/streams/CollectionToStream.java b/streams/CollectionToStream.java index e0453a790..7b7c69cea 100644 --- a/streams/CollectionToStream.java +++ b/streams/CollectionToStream.java @@ -1,7 +1,7 @@ // streams/CollectionToStream.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; diff --git a/streams/CreatingOptionals.java b/streams/CreatingOptionals.java index e7365b3f1..4f30cf52c 100644 --- a/streams/CreatingOptionals.java +++ b/streams/CreatingOptionals.java @@ -1,7 +1,7 @@ // streams/CreatingOptionals.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; import java.util.function.*; diff --git a/streams/Duplicator.java b/streams/Duplicator.java index e3b815bac..9e9f87eec 100644 --- a/streams/Duplicator.java +++ b/streams/Duplicator.java @@ -1,7 +1,7 @@ // streams/Duplicator.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.stream.*; public class Duplicator { diff --git a/streams/Fibonacci.java b/streams/Fibonacci.java index d71231733..0fb47d3f3 100644 --- a/streams/Fibonacci.java +++ b/streams/Fibonacci.java @@ -1,7 +1,7 @@ // streams/Fibonacci.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.stream.*; public class Fibonacci { diff --git a/streams/FileToWords.java b/streams/FileToWords.java index b4b9ed1d7..1e90d7a4b 100644 --- a/streams/FileToWords.java +++ b/streams/FileToWords.java @@ -1,7 +1,7 @@ // streams/FileToWords.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.nio.file.*; import java.util.stream.*; import java.util.regex.Pattern; diff --git a/streams/FileToWordsBuilder.java b/streams/FileToWordsBuilder.java index 89619eb46..5e830b8bb 100644 --- a/streams/FileToWordsBuilder.java +++ b/streams/FileToWordsBuilder.java @@ -1,7 +1,7 @@ // streams/FileToWordsBuilder.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.io.*; import java.nio.file.*; import java.util.stream.*; diff --git a/streams/FileToWordsRegexp.java b/streams/FileToWordsRegexp.java index 453596f75..f01c853aa 100644 --- a/streams/FileToWordsRegexp.java +++ b/streams/FileToWordsRegexp.java @@ -1,7 +1,7 @@ // streams/FileToWordsRegexp.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.io.*; import java.nio.file.*; import java.util.stream.*; @@ -16,7 +16,8 @@ public FileToWordsRegexp(String filePath) .collect(Collectors.joining(" ")); } public Stream stream() { - return Pattern.compile("[ .,?]+").splitAsStream(all); + return Pattern + .compile("[ .,?]+").splitAsStream(all); } public static void main(String[] args) throws Exception { diff --git a/streams/FileToWordsTest.java b/streams/FileToWordsTest.java index 761c1d329..7c95bebd5 100644 --- a/streams/FileToWordsTest.java +++ b/streams/FileToWordsTest.java @@ -1,7 +1,7 @@ // streams/FileToWordsTest.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.stream.*; public class FileToWordsTest { diff --git a/streams/FlatMap.java b/streams/FlatMap.java index 982e591f9..8e5fe8d69 100644 --- a/streams/FlatMap.java +++ b/streams/FlatMap.java @@ -1,7 +1,7 @@ // streams/FlatMap.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.stream.*; public class FlatMap { diff --git a/streams/ForEach.java b/streams/ForEach.java index ebc7ab7e1..a8ed8edea 100644 --- a/streams/ForEach.java +++ b/streams/ForEach.java @@ -1,28 +1,28 @@ // streams/ForEach.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; import static streams.RandInts.*; public class ForEach { - final static int sz = 14; + static final int SZ = 14; public static void main(String[] args) { - rands().limit(sz) + rands().limit(SZ) .forEach(n -> System.out.format("%d ", n)); System.out.println(); - rands().limit(sz) + rands().limit(SZ) .parallel() .forEach(n -> System.out.format("%d ", n)); System.out.println(); - rands().limit(sz) + 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 589 200 861 555 693 258 128 207 429 288 868 522 961 +551 589 861 555 288 128 429 207 693 200 258 522 868 961 258 555 693 861 961 429 868 200 522 207 288 128 551 589 */ diff --git a/streams/FunctionMap.java b/streams/FunctionMap.java index 1321a6c36..9b2fc4744 100644 --- a/streams/FunctionMap.java +++ b/streams/FunctionMap.java @@ -1,7 +1,7 @@ // streams/FunctionMap.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; import java.util.function.*; diff --git a/streams/FunctionMap2.java b/streams/FunctionMap2.java index 445b561d9..130cd7292 100644 --- a/streams/FunctionMap2.java +++ b/streams/FunctionMap2.java @@ -1,7 +1,7 @@ // streams/FunctionMap2.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Different input and output types import java.util.*; import java.util.stream.*; @@ -9,8 +9,7 @@ class Numbered { final int n; Numbered(int n) { this.n = n; } - @Override - public String toString() { + @Override public String toString() { return "Numbered(" + n + ")"; } } diff --git a/streams/FunctionMap3.java b/streams/FunctionMap3.java index 66dc6323a..6214fa327 100644 --- a/streams/FunctionMap3.java +++ b/streams/FunctionMap3.java @@ -1,7 +1,7 @@ // streams/FunctionMap3.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Producing numeric output streams import java.util.*; import java.util.stream.*; diff --git a/streams/Generator.java b/streams/Generator.java index 1ac5b12c2..f83741216 100644 --- a/streams/Generator.java +++ b/streams/Generator.java @@ -1,7 +1,7 @@ // streams/Generator.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.function.*; import java.util.stream.*; @@ -10,7 +10,7 @@ public class Generator implements Supplier { Random rand = new Random(47); char[] letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); - public String get() { + @Override public String get() { return "" + letters[rand.nextInt(letters.length)]; } public static void main(String[] args) { diff --git a/streams/ImperativeRandoms.java b/streams/ImperativeRandoms.java index 386630045..a11a072e4 100644 --- a/streams/ImperativeRandoms.java +++ b/streams/ImperativeRandoms.java @@ -1,7 +1,7 @@ // streams/ImperativeRandoms.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class ImperativeRandoms { diff --git a/streams/Informational.java b/streams/Informational.java index ff3691a25..bc33ca4d3 100644 --- a/streams/Informational.java +++ b/streams/Informational.java @@ -1,7 +1,7 @@ // streams/Informational.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.stream.*; import java.util.function.*; diff --git a/streams/LastElement.java b/streams/LastElement.java index cc0f3eb3a..74a745526 100644 --- a/streams/LastElement.java +++ b/streams/LastElement.java @@ -1,7 +1,7 @@ // streams/LastElement.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; @@ -14,7 +14,8 @@ public static void main(String[] args) { Optional lastobj = Stream.of("one", "two", "three") .reduce((n1, n2) -> n2); - System.out.println(lastobj.orElse("Nothing there!")); + System.out.println( + lastobj.orElse("Nothing there!")); } } /* Output: diff --git a/streams/Looping.java b/streams/Looping.java index 7342550c4..bfb49d031 100644 --- a/streams/Looping.java +++ b/streams/Looping.java @@ -1,7 +1,7 @@ // streams/Looping.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import static onjava.Repeat.*; public class Looping { diff --git a/streams/MapCollector.java b/streams/MapCollector.java index d8fea36ab..5ab66f715 100644 --- a/streams/MapCollector.java +++ b/streams/MapCollector.java @@ -1,21 +1,20 @@ // streams/MapCollector.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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; - public Pair(Character c, 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() { + @Override public String toString() { return "Pair(" + c + ", " + i + ")"; } } @@ -43,5 +42,6 @@ public static void main(String[] args) { } } /* Output: -{688=W, 309=C, 293=B, 761=N, 858=N, 668=G, 622=F, 751=N} +{688=W, 309=C, 293=B, 761=N, 858=N, 668=G, 622=F, +751=N} */ diff --git a/streams/Matching.java b/streams/Matching.java index c1f8b0b80..4aa6280f5 100644 --- a/streams/Matching.java +++ b/streams/Matching.java @@ -1,7 +1,7 @@ // streams/Matching.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Demonstrates short-circuiting of *Match() operations import java.util.stream.*; import java.util.function.*; diff --git a/streams/Machine2.java b/streams/MetalWork2.java similarity index 50% rename from streams/Machine2.java rename to streams/MetalWork2.java index 97c71e996..0bf74152f 100644 --- a/streams/Machine2.java +++ b/streams/MetalWork2.java @@ -1,23 +1,23 @@ -// streams/Machine2.java -// (c)2016 MindView LLC: see Copyright.txt +// streams/MetalWork2.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import onjava.Operation; -public class Machine2 { +public class MetalWork2 { public static void main(String[] args) { Arrays.stream(new Operation[] { - () -> Operation.show("Bing"), - () -> Operation.show("Crack"), + () -> Operation.show("Heat"), + () -> Operation.show("Hammer"), () -> Operation.show("Twist"), - () -> Operation.show("Pop") + () -> Operation.show("Anneal") }).forEach(Operation::execute); } } /* Output: -Bing -Crack +Heat +Hammer Twist -Pop +Anneal */ diff --git a/streams/NumericStreamInfo.java b/streams/NumericStreamInfo.java index 2636d0115..3cc6c88e3 100644 --- a/streams/NumericStreamInfo.java +++ b/streams/NumericStreamInfo.java @@ -1,7 +1,7 @@ // streams/NumericStreamInfo.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.stream.*; import static streams.RandInts.*; diff --git a/streams/OptionalBasics.java b/streams/OptionalBasics.java index f904adcab..525611d21 100644 --- a/streams/OptionalBasics.java +++ b/streams/OptionalBasics.java @@ -1,7 +1,7 @@ // streams/OptionalBasics.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; diff --git a/streams/OptionalFilter.java b/streams/OptionalFilter.java index 0c64c21b6..72e2011c0 100644 --- a/streams/OptionalFilter.java +++ b/streams/OptionalFilter.java @@ -1,7 +1,7 @@ // streams/OptionalFilter.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; import java.util.function.*; @@ -13,7 +13,8 @@ class OptionalFilter { static Stream testStream() { return Arrays.stream(elements); } - static void test(String descr, Predicate pred) { + static void + test(String descr, Predicate pred) { System.out.println(" ---( " + descr + " )---"); for(int i = 0; i <= elements.length; i++) { System.out.println( @@ -28,7 +29,8 @@ public static void main(String[] args) { test("false", str -> false); test("str != \"\"", str -> str != ""); test("str.length() == 3", str -> str.length() == 3); - test("startsWith(\"B\")", str -> str.startsWith("B")); + test("startsWith(\"B\")", + str -> str.startsWith("B")); } } /* Output: diff --git a/streams/OptionalFlatMap.java b/streams/OptionalFlatMap.java index ba0d586b4..fe5bcdddf 100644 --- a/streams/OptionalFlatMap.java +++ b/streams/OptionalFlatMap.java @@ -1,7 +1,7 @@ // streams/OptionalFlatMap.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; import java.util.function.*; @@ -24,11 +24,13 @@ static void test(String descr, } public static void main(String[] args) { - test("Add brackets", s -> Optional.of("[" + s + "]")); + test("Add brackets", + s -> Optional.of("[" + s + "]")); test("Increment", s -> { try { - return Optional.of(Integer.parseInt(s) + 1 + ""); + return Optional.of( + Integer.parseInt(s) + 1 + ""); } catch(NumberFormatException e) { return Optional.of(s); } diff --git a/streams/OptionalMap.java b/streams/OptionalMap.java index 6778033a1..50a385ed1 100644 --- a/streams/OptionalMap.java +++ b/streams/OptionalMap.java @@ -1,7 +1,7 @@ // streams/OptionalMap.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; import java.util.function.*; @@ -25,7 +25,8 @@ static Stream testStream() { public static void main(String[] args) { // If Optional is not empty, map() first extracts - // the contents which it then passes to the function: + // the contents which it then passes + // to the function: test("Add brackets", s -> "[" + s + "]"); diff --git a/streams/Optionals.java b/streams/Optionals.java index b8604dad0..c4512b4bf 100644 --- a/streams/Optionals.java +++ b/streams/Optionals.java @@ -1,7 +1,7 @@ // streams/Optionals.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; import java.util.function.*; @@ -13,17 +13,17 @@ static void basics(Optional optString) { else System.out.println("Nothing inside!"); } - static void if_present(Optional optString) { + static void ifPresent(Optional optString) { optString.ifPresent(System.out::println); } - static void or_else(Optional optString) { + static void orElse(Optional optString) { System.out.println(optString.orElse("Nada")); } - static void or_else_get(Optional optString) { + static void orElseGet(Optional optString) { System.out.println( optString.orElseGet(() -> "Generated")); } - static void or_else_throw(Optional optString) { + static void orElseThrow(Optional optString) { try { System.out.println(optString.orElseThrow( () -> new Exception("Supplied"))); @@ -31,18 +31,18 @@ static void or_else_throw(Optional optString) { System.out.println("Caught " + e); } } - static void - test(String testName, Consumer> cos) { + 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::if_present); - test("orElse", Optionals::or_else); - test("orElseGet", Optionals::or_else_get); - test("orElseThrow", Optionals::or_else_throw); + test("ifPresent", Optionals::ifPresent); + test("orElse", Optionals::orElse); + test("orElseGet", Optionals::orElseGet); + test("orElseThrow", Optionals::orElseThrow); } } /* Output: diff --git a/streams/OptionalsFromEmptyStreams.java b/streams/OptionalsFromEmptyStreams.java index e5326ed70..be206bf8d 100644 --- a/streams/OptionalsFromEmptyStreams.java +++ b/streams/OptionalsFromEmptyStreams.java @@ -1,7 +1,7 @@ // streams/OptionalsFromEmptyStreams.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; diff --git a/streams/Peeking.java b/streams/Peeking.java index 67cc56eab..75dcb3467 100644 --- a/streams/Peeking.java +++ b/streams/Peeking.java @@ -1,7 +1,7 @@ // streams/Peeking.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. class Peeking { public static void diff --git a/streams/Prime.java b/streams/Prime.java index 3920ae1a4..34e802294 100644 --- a/streams/Prime.java +++ b/streams/Prime.java @@ -1,7 +1,7 @@ // streams/Prime.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.stream.*; import static java.util.stream.LongStream.*; @@ -11,7 +11,8 @@ public static boolean isPrime(long n) { .noneMatch(i -> n % i == 0); } public LongStream numbers() { - return iterate(2, i -> i + 1).filter(Prime::isPrime); + return iterate(2, i -> i + 1) + .filter(Prime::isPrime); } public static void main(String[] args) { new Prime().numbers() diff --git a/streams/RandInts.java b/streams/RandInts.java index 68fefd1a0..8e6c2bb2d 100644 --- a/streams/RandInts.java +++ b/streams/RandInts.java @@ -1,7 +1,7 @@ // streams/RandInts.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. package streams; import java.util.*; import java.util.stream.*; diff --git a/streams/RandomGenerators.java b/streams/RandomGenerators.java index e02ec0175..286368f3f 100644 --- a/streams/RandomGenerators.java +++ b/streams/RandomGenerators.java @@ -1,16 +1,16 @@ // streams/RandomGenerators.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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("++++++++"); + stream + .limit(4) + .forEach(System.out::println); + System.out.println("++++++++"); } public static void main(String[] args) { Random rand = new Random(47); diff --git a/streams/RandomWords.java b/streams/RandomWords.java index b72cff788..6f2df4edc 100644 --- a/streams/RandomWords.java +++ b/streams/RandomWords.java @@ -1,7 +1,7 @@ // streams/RandomWords.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; import java.util.function.*; @@ -20,11 +20,10 @@ public class RandomWords implements Supplier { words.add(word.toLowerCase()); } } - public String get() { + @Override public String get() { return words.get(rand.nextInt(words.size())); } - @Override - public String toString() { + @Override public String toString() { return words.stream() .collect(Collectors.joining(" ")); } diff --git a/streams/Randoms.java b/streams/Randoms.java index e43a109d2..52e05df05 100644 --- a/streams/Randoms.java +++ b/streams/Randoms.java @@ -1,7 +1,7 @@ // streams/Randoms.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class Randoms { diff --git a/streams/Ranges.java b/streams/Ranges.java index 2719bdd16..1a4da9018 100644 --- a/streams/Ranges.java +++ b/streams/Ranges.java @@ -1,7 +1,7 @@ // streams/Ranges.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import static java.util.stream.IntStream.*; public class Ranges { diff --git a/streams/Reduce.java b/streams/Reduce.java index c5acf356f..9d513f496 100644 --- a/streams/Reduce.java +++ b/streams/Reduce.java @@ -1,22 +1,21 @@ // streams/Reduce.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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() { + @Override public String toString() { return "Frobnitz(" + size + ")"; } // Generator: static Random rand = new Random(47); - static final int bound = 100; + static final int BOUND = 100; static Frobnitz supply() { - return new Frobnitz(rand.nextInt(bound)); + return new Frobnitz(rand.nextInt(BOUND)); } } diff --git a/streams/SelectElement.java b/streams/SelectElement.java index b6d240a1a..a6b504498 100644 --- a/streams/SelectElement.java +++ b/streams/SelectElement.java @@ -1,7 +1,7 @@ // streams/SelectElement.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; import static streams.RandInts.*; diff --git a/streams/Signal.java b/streams/Signal.java index 540a1d2bc..4b14200f4 100644 --- a/streams/Signal.java +++ b/streams/Signal.java @@ -1,7 +1,7 @@ // streams/Signal.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; import java.util.function.*; @@ -10,8 +10,7 @@ public class Signal { private final String msg; public Signal(String msg) { this.msg = msg; } public String getMsg() { return msg; } - @Override - public String toString() { + @Override public String toString() { return "Signal(" + msg + ")"; } static Random rand = new Random(47); diff --git a/streams/SortedComparator.java b/streams/SortedComparator.java index 2fba575de..4d60a6486 100644 --- a/streams/SortedComparator.java +++ b/streams/SortedComparator.java @@ -1,7 +1,7 @@ // streams/SortedComparator.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class SortedComparator { diff --git a/streams/SpecialCollector.java b/streams/SpecialCollector.java index 474b09dc4..36068bf7b 100644 --- a/streams/SpecialCollector.java +++ b/streams/SpecialCollector.java @@ -1,7 +1,7 @@ // streams/SpecialCollector.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; @@ -13,9 +13,9 @@ public class SpecialCollector { .collect(ArrayList::new, ArrayList::add, ArrayList::addAll); - for(String s : words) - if(s.equals("cheese")) - System.out.println(s); + words.stream() + .filter(s -> s.equals("cheese")) + .forEach(System.out::println); } } /* Output: diff --git a/streams/StreamOf.java b/streams/StreamOf.java index 7a4e8428d..7ae3adefc 100644 --- a/streams/StreamOf.java +++ b/streams/StreamOf.java @@ -1,12 +1,13 @@ // streams/StreamOf.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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)) + Stream.of( + new Bubble(1), new Bubble(2), new Bubble(3)) .forEach(System.out::println); Stream.of("It's ", "a ", "wonderful ", "day ", "for ", "pie!") diff --git a/streams/StreamOfOptionals.java b/streams/StreamOfOptionals.java index e3aee8b71..4b0b048b0 100644 --- a/streams/StreamOfOptionals.java +++ b/streams/StreamOfOptionals.java @@ -1,7 +1,7 @@ // streams/StreamOfOptionals.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; diff --git a/streams/StreamOfRandoms.java b/streams/StreamOfRandoms.java index 377025e2e..07efa25e0 100644 --- a/streams/StreamOfRandoms.java +++ b/streams/StreamOfRandoms.java @@ -1,7 +1,7 @@ // streams/StreamOfRandoms.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; diff --git a/streams/StreamOfStreams.java b/streams/StreamOfStreams.java index 79b427c28..d282a6724 100644 --- a/streams/StreamOfStreams.java +++ b/streams/StreamOfStreams.java @@ -1,7 +1,7 @@ // streams/StreamOfStreams.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.stream.*; public class StreamOfStreams { diff --git a/streams/TreeSetOfWords.java b/streams/TreeSetOfWords.java index f2e17e2a3..93405f74e 100644 --- a/streams/TreeSetOfWords.java +++ b/streams/TreeSetOfWords.java @@ -1,7 +1,7 @@ // streams/TreeSetOfWords.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.nio.file.*; import java.util.stream.*; @@ -21,10 +21,11 @@ public class TreeSetOfWords { } } /* 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] +[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/streams/build.xml b/streams/build.xml deleted file mode 100644 index 18ac9f02e..000000000 --- a/streams/build.xml +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/strings/ArrayListDisplay.java b/strings/ArrayListDisplay.java index 6ff519e2e..586f013a2 100644 --- a/strings/ArrayListDisplay.java +++ b/strings/ArrayListDisplay.java @@ -1,7 +1,7 @@ // strings/ArrayListDisplay.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; import java.util.stream.*; import generics.coffee.*; @@ -16,6 +16,7 @@ public static void main(String[] args) { } } /* Output: -[Americano 0, Latte 1, Americano 2, Mocha 3, Mocha 4, Breve -5, Americano 6, Latte 7, Cappuccino 8, Cappuccino 9] +[Americano 0, Latte 1, Americano 2, Mocha 3, Mocha 4, +Breve 5, Americano 6, Latte 7, Cappuccino 8, Cappuccino +9] */ diff --git a/strings/BackSlashes.java b/strings/BackSlashes.java new file mode 100644 index 000000000..6363defcc --- /dev/null +++ b/strings/BackSlashes.java @@ -0,0 +1,26 @@ +// strings/BackSlashes.java +// (c)2021 MindView 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 BackSlashes { + public static void main(String[] args) { + String one = "\\"; + String two = "\\\\"; + String three = "\\\\\\"; + System.out.println(one); + System.out.println(two); + System.out.println(three); + System.out.println(one.matches("\\\\")); + System.out.println(two.matches("\\\\\\\\")); + System.out.println(three.matches("\\\\\\\\\\\\")); + } +} +/* Output: +\ +\\ +\\\ +true +true +true +*/ diff --git a/strings/BetterRead.java b/strings/BetterRead.java index 5877e9c47..02c55c397 100644 --- a/strings/BetterRead.java +++ b/strings/BetterRead.java @@ -1,7 +1,7 @@ // strings/BetterRead.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class BetterRead { @@ -17,8 +17,8 @@ public static void main(String[] args) { 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", + 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); diff --git a/strings/Concatenation.java b/strings/Concatenation.java index 751c3c0b2..33e703a85 100644 --- a/strings/Concatenation.java +++ b/strings/Concatenation.java @@ -1,7 +1,7 @@ // strings/Concatenation.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class Concatenation { public static void main(String[] args) { diff --git a/strings/Conversion.java b/strings/Conversion.java index 242fcdae0..c417c875c 100644 --- a/strings/Conversion.java +++ b/strings/Conversion.java @@ -1,7 +1,7 @@ // strings/Conversion.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.math.*; import java.util.*; @@ -11,70 +11,70 @@ public static void main(String[] args) { 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); + 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); + 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); + 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); + // 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); + // 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); + // 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: diff --git a/strings/DataPoint.java b/strings/DataPoint.java new file mode 100644 index 000000000..719e0959d --- /dev/null +++ b/strings/DataPoint.java @@ -0,0 +1,32 @@ +// strings/DataPoint.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 15 + +public class DataPoint { + private String location; + private Double temperature; + public DataPoint(String loc, Double temp) { + location = loc; + temperature = temp; + } + @Override public String toString() { + return """ + Location: %s + Temperature: %.2f + """.formatted(location, temperature); + } + public static void main(String[] args) { + var hill = new DataPoint("Hill", 45.2); + var dale = new DataPoint("Dale", 65.2); + System.out.print(hill); + System.out.print(dale); + } +} +/* Output: +Location: Hill +Temperature: 45.20 +Location: Dale +Temperature: 65.20 +*/ diff --git a/strings/DatabaseException.java b/strings/DatabaseException.java index 5e046ffa9..5a7a9bd98 100644 --- a/strings/DatabaseException.java +++ b/strings/DatabaseException.java @@ -1,11 +1,11 @@ // strings/DatabaseException.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class DatabaseException extends Exception { - public DatabaseException(int transactionID, int queryID, - String message) { + public DatabaseException(int transactionID, + int queryID, String message) { super(String.format("(t%d, q%d) %s", transactionID, queryID, message)); } diff --git a/strings/Finding.java b/strings/Finding.java index 4cd7922b8..096b080d4 100644 --- a/strings/Finding.java +++ b/strings/Finding.java @@ -1,13 +1,14 @@ // strings/Finding.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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"); + .matcher( + "Evening is full of the linnet's wings"); while(m.find()) System.out.print(m.group() + " "); System.out.println(); @@ -20,7 +21,7 @@ public static void main(String[] args) { } /* 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 +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/strings/Groups.java b/strings/Groups.java index 25668097c..b98fcddcc 100644 --- a/strings/Groups.java +++ b/strings/Groups.java @@ -1,11 +1,11 @@ // strings/Groups.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.regex.*; public class Groups { - static public final String POEM = + 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" + @@ -15,9 +15,9 @@ public class Groups { "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); + 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) + "]"); diff --git a/onjava/Hex.java b/strings/Hex.java similarity index 59% rename from onjava/Hex.java rename to strings/Hex.java index a22eaf2b1..47f05b80f 100644 --- a/onjava/Hex.java +++ b/strings/Hex.java @@ -1,7 +1,8 @@ -// onjava/Hex.java -// (c)2016 MindView LLC: see Copyright.txt +// strings/Hex.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +// {java onjava.Hex} package onjava; import java.io.*; import java.nio.file.*; @@ -25,18 +26,19 @@ public static String format(byte[] data) { if(args.length == 0) // Test by displaying this class file: System.out.println(format( - Files.readAllBytes(Paths.get("Hex.class")))); + 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 53 0A 00 05 00 22 07 -00010: 00 23 0A 00 02 00 22 08 00 24 07 00 25 0A 00 26 -00020: 00 27 0A 00 28 00 29 0A 00 02 00 2A 08 00 2B 0A -00030: 00 2C 00 2D 08 00 2E 0A 00 02 00 2F 09 00 30 00 -00040: 31 08 00 32 0A 00 33 00 34 0A 00 15 00 35 0A 00 -00050: 36 00 37 07 00 38 0A 00 12 00 39 0A 00 33 00 3A +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/strings/Immutable.java b/strings/Immutable.java index b2e263c99..365c3ebe3 100644 --- a/strings/Immutable.java +++ b/strings/Immutable.java @@ -1,7 +1,7 @@ // strings/Immutable.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class Immutable { public static String upcase(String s) { diff --git a/strings/Indentation.java b/strings/Indentation.java new file mode 100644 index 000000000..71a88365f --- /dev/null +++ b/strings/Indentation.java @@ -0,0 +1,33 @@ +// strings/Indentation.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 15 + +public class Indentation { + public static final String NONE = """ + XXX + YYY + """; // No indentation + public static final String TWO = """ + XXX + YYY + """; // Produces indent of 2 + public static final String EIGHT = """ + XXX + YYY + """; // Produces indent of 8 + public static void main(String[] args) { + System.out.print(NONE); + System.out.print(TWO); + System.out.print(EIGHT); + } +} +/* Output: +XXX +YYY + XXX + YYY + XXX + YYY +*/ diff --git a/strings/InfiniteRecursion.java b/strings/InfiniteRecursion.java index 769081720..cc523ec88 100644 --- a/strings/InfiniteRecursion.java +++ b/strings/InfiniteRecursion.java @@ -1,17 +1,17 @@ // strings/InfiniteRecursion.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Accidental recursion // {ThrowsException} -// {ValidateByHand} +// {VisuallyInspectOutput} Throws very long exception import java.util.*; import java.util.stream.*; public class InfiniteRecursion { - @Override - public String toString() { - return " InfiniteRecursion address: " + this + "\n"; + @Override public String toString() { + return + " InfiniteRecursion address: " + this + "\n"; } public static void main(String[] args) { Stream.generate(InfiniteRecursion::new) diff --git a/strings/IntegerMatch.java b/strings/IntegerMatch.java index 21c43320b..822c5d4c6 100644 --- a/strings/IntegerMatch.java +++ b/strings/IntegerMatch.java @@ -1,14 +1,18 @@ // strings/IntegerMatch.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. +import java.util.stream.*; 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+")); + String possiblyMinus = "-?\\d+"; + Stream.of( + "-1234".matches(possiblyMinus), + "5678".matches(possiblyMinus), + "+911".matches(possiblyMinus), + "+911".matches("(-|\\+)?\\d+") + ).forEach(System.out::println); } } /* Output: diff --git a/strings/JGrep.java b/strings/JGrep.java index 93a6cc419..368fd13ef 100644 --- a/strings/JGrep.java +++ b/strings/JGrep.java @@ -1,9 +1,10 @@ // strings/JGrep.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // A very simple version of the "grep" program -// {Args: WhitherStringBuilder.java 'return|for|String'} +// {java JGrep +// WhitherStringBuilder.java "return|for|String"} import java.util.regex.*; import java.nio.file.*; import java.util.stream.*; @@ -12,37 +13,38 @@ public class JGrep { public static void main(String[] args) throws Exception { if(args.length < 2) { - System.out.println("Usage: java JGrep file regex"); + 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()); - } + // Iterate through the lines of the input file: + Files.readAllLines(Paths.get(args[0])).forEach( + line -> { + m.reset(line); + while(m.find()) + System.out.println( + m.group() + ": " + m.start()); + } + ); } } /* Output: -0: String: 18 -1: String: 20 -2: String: 9 -3: String: 25 -4: String: 4 -5: for: 4 -6: String: 8 -7: return: 4 -8: String: 9 -9: String: 25 -10: String: 4 -11: String: 31 -12: for: 4 -13: String: 8 -14: return: 4 -15: String: 20 +String: 18 +String: 20 +String: 9 +String: 25 +String: 4 +for: 4 +String: 8 +return: 4 +String: 9 +String: 25 +String: 4 +String: 31 +for: 4 +String: 8 +return: 4 +String: 20 */ diff --git a/strings/ReFlags.java b/strings/ReFlags.java index 886fd9254..a407b6c97 100644 --- a/strings/ReFlags.java +++ b/strings/ReFlags.java @@ -1,7 +1,7 @@ // strings/ReFlags.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.regex.*; public class ReFlags { diff --git a/strings/ReceiptBuilder.java b/strings/ReceiptBuilder.java index bee6b5e66..e58e8bb64 100644 --- a/strings/ReceiptBuilder.java +++ b/strings/ReceiptBuilder.java @@ -1,7 +1,7 @@ // strings/ReceiptBuilder.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class ReceiptBuilder { @@ -9,25 +9,30 @@ public class ReceiptBuilder { private Formatter f = new Formatter(new StringBuilder()); public ReceiptBuilder() { - f.format("%-15s %5s %10s\n", "Item", "Qty", "Price"); - f.format("%-15s %5s %10s\n", "----", "---", "-----"); + 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); + 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", "", + 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 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); + receiptBuilder.add( + "Three Bears Porridge", 1, 14.29); System.out.println(receiptBuilder.build()); } } diff --git a/strings/Replacing.java b/strings/Replacing.java index e1bc965c9..90394c32e 100644 --- a/strings/Replacing.java +++ b/strings/Replacing.java @@ -1,7 +1,7 @@ // strings/Replacing.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class Replacing { static String s = Splitting.knights; @@ -14,7 +14,8 @@ public static void main(String[] args) { } /* 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! +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/strings/ReplacingStringTokenizer.java b/strings/ReplacingStringTokenizer.java index 13e38fa73..9c2bee8ad 100644 --- a/strings/ReplacingStringTokenizer.java +++ b/strings/ReplacingStringTokenizer.java @@ -1,17 +1,19 @@ // strings/ReplacingStringTokenizer.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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!"; + 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(" "))); + System.out.println( + Arrays.toString(input.split(" "))); Scanner scanner = new Scanner(input); while(scanner.hasNext()) System.out.print(scanner.next() + " "); diff --git a/strings/Resetting.java b/strings/Resetting.java index 7a1b1343f..67c4c8cd5 100644 --- a/strings/Resetting.java +++ b/strings/Resetting.java @@ -1,7 +1,7 @@ // strings/Resetting.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.regex.*; public class Resetting { diff --git a/strings/Rudolph.java b/strings/Rudolph.java index 15abd58ad..b90813c7d 100644 --- a/strings/Rudolph.java +++ b/strings/Rudolph.java @@ -1,7 +1,7 @@ // strings/Rudolph.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class Rudolph { public static void main(String[] args) { diff --git a/strings/ScannerDelimiter.java b/strings/ScannerDelimiter.java index 8e2969423..7ac41a4c3 100644 --- a/strings/ScannerDelimiter.java +++ b/strings/ScannerDelimiter.java @@ -1,7 +1,7 @@ // strings/ScannerDelimiter.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; public class ScannerDelimiter { diff --git a/strings/SimpleFormat.java b/strings/SimpleFormat.java index 8cbd21895..106f92572 100644 --- a/strings/SimpleFormat.java +++ b/strings/SimpleFormat.java @@ -1,7 +1,7 @@ // strings/SimpleFormat.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class SimpleFormat { public static void main(String[] args) { @@ -10,9 +10,9 @@ public static void main(String[] args) { // The old way: System.out.println("Row 1: [" + x + " " + y + "]"); // The new way: - System.out.format("Row 1: [%d %f]\n", x, y); + System.out.format("Row 1: [%d %f]%n", x, y); // or - System.out.printf("Row 1: [%d %f]\n", x, y); + System.out.printf("Row 1: [%d %f]%n", x, y); } } /* Output: diff --git a/strings/SimpleRead.java b/strings/SimpleRead.java index 1d87761f8..15533b973 100644 --- a/strings/SimpleRead.java +++ b/strings/SimpleRead.java @@ -1,27 +1,28 @@ // strings/SimpleRead.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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 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("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", + 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); diff --git a/strings/SplitDemo.java b/strings/SplitDemo.java index b8d388db2..3d5eb6719 100644 --- a/strings/SplitDemo.java +++ b/strings/SplitDemo.java @@ -1,7 +1,7 @@ // strings/SplitDemo.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.regex.*; import java.util.*; diff --git a/strings/Splitting.java b/strings/Splitting.java index 0b76d123a..f22ea1a37 100644 --- a/strings/Splitting.java +++ b/strings/Splitting.java @@ -1,14 +1,14 @@ // strings/Splitting.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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!"; + "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))); @@ -16,16 +16,17 @@ public static void split(String 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-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!] +[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/strings/StartEnd.java b/strings/StartEnd.java index faecde11e..072dde8de 100644 --- a/strings/StartEnd.java +++ b/strings/StartEnd.java @@ -1,14 +1,15 @@ // strings/StartEnd.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// 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"+ + "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 { @@ -60,7 +61,8 @@ public static void main(String[] args) { T\w+ find() 'Targathian' start = 0 end = 10 lookingAt() start = 0 end = 10 -input : signal sounds among the stars ... We'll be there. +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 ... diff --git a/strings/TestRegularExpression.java b/strings/TestRegularExpression.java index 3120424ab..d20af088f 100644 --- a/strings/TestRegularExpression.java +++ b/strings/TestRegularExpression.java @@ -1,9 +1,10 @@ // strings/TestRegularExpression.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Easily try out regular expressions -// {Args: abcabcabcdefabc "abc+" "(abc)+" "(abc){2,}" } +// Visit http://OnJava8.com for more book information. +// Simple regular expression demonstration +// {java TestRegularExpression +// abcabcabcdefabc "abc+" "(abc)+" } import java.util.regex.*; public class TestRegularExpression { @@ -40,6 +41,4 @@ public static void main(String[] args) { Regular expression: "(abc)+" Match "abcabcabc" at positions 0-8 Match "abc" at positions 12-14 -Regular expression: "(abc){2,}" -Match "abcabcabc" at positions 0-8 */ diff --git a/strings/TextBlocks.java b/strings/TextBlocks.java new file mode 100644 index 000000000..0e634001d --- /dev/null +++ b/strings/TextBlocks.java @@ -0,0 +1,37 @@ +// strings/TextBlocks.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 15 +// Poem: Antigonish by Hughes Mearns + +public class TextBlocks { + public static final String OLD = + "Yesterday, upon the stair,\n" + + "I met a man who wasn't there\n" + + "He wasn't there again today\n" + + "I wish, I wish he'd go away...\n" + + "\n" + + "When I came home last night at three\n" + + "The man was waiting there for me\n" + + "But when I looked around the hall\n" + + "I couldn't see him there at all!\n"; + + public static final String NEW = """ + Yesterday, upon the stair, + I met a man who wasn't there + He wasn't there again today + I wish, I wish he'd go away... + + When I came home last night at three + The man was waiting there for me + But when I looked around the hall + I couldn't see him there at all! + """; + public static void main(String[] args) { + System.out.println(OLD.equals(NEW)); + } +} +/* Output: +true +*/ diff --git a/strings/TheReplacements.java b/strings/TheReplacements.java index f35dc811f..cd543ab59 100644 --- a/strings/TheReplacements.java +++ b/strings/TheReplacements.java @@ -1,7 +1,7 @@ // strings/TheReplacements.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.regex.*; import java.nio.file.*; import java.util.stream.*; @@ -18,14 +18,14 @@ public class TheReplacements { String s = Files.lines( Paths.get("TheReplacements.java")) .collect(Collectors.joining("\n")); - // Match the specially commented block of text above: + // 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 one or more spaces at the beginning of each + // Replace 1+ spaces at the beginning of each // line with no spaces. Must enable MULTILINE mode: s = s.replaceAll("(?m)^ +", ""); System.out.println(s); @@ -36,7 +36,8 @@ public class TheReplacements { // Process the find information as you // perform the replacements: while(m.find()) - m.appendReplacement(sbuf, m.group().toUpperCase()); + m.appendReplacement( + sbuf, m.group().toUpperCase()); // Put in the remainder of the text: m.appendTail(sbuf); System.out.println(sbuf); diff --git a/strings/ThreatAnalyzer.java b/strings/ThreatAnalyzer.java index c32249455..28c500054 100644 --- a/strings/ThreatAnalyzer.java +++ b/strings/ThreatAnalyzer.java @@ -1,7 +1,7 @@ // strings/ThreatAnalyzer.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.regex.*; import java.util.*; @@ -23,7 +23,7 @@ public static void main(String[] args) { String ip = match.group(1); String date = match.group(2); System.out.format( - "Threat on %s from %s\n", date,ip); + "Threat on %s from %s%n", date,ip); } } } diff --git a/strings/Turtle.java b/strings/Turtle.java index c4b29ad9b..f3121b755 100644 --- a/strings/Turtle.java +++ b/strings/Turtle.java @@ -1,7 +1,7 @@ // strings/Turtle.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.io.*; import java.util.*; @@ -13,7 +13,8 @@ public Turtle(String name, Formatter f) { this.f = f; } public void move(int x, int y) { - f.format("%s The Turtle is at (%d,%d)\n", name, x, y); + f.format("%s The Turtle is at (%d,%d)%n", + name, x, y); } public static void main(String[] args) { PrintStream outAlias = System.out; diff --git a/strings/UsingStringBuilder.java b/strings/UsingStringBuilder.java index 815c2ec08..a5511ff63 100644 --- a/strings/UsingStringBuilder.java +++ b/strings/UsingStringBuilder.java @@ -1,13 +1,13 @@ // strings/UsingStringBuilder.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. import java.util.*; +import java.util.stream.*; public class UsingStringBuilder { - public static Random rand = new Random(47); - @Override - public String toString() { + 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)); @@ -17,12 +17,21 @@ public String toString() { 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) { - UsingStringBuilder usb = new UsingStringBuilder(); - System.out.println(usb); + 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] +[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/strings/WhitherStringBuilder.java b/strings/WhitherStringBuilder.java index 5c05b9884..f39d3f11f 100644 --- a/strings/WhitherStringBuilder.java +++ b/strings/WhitherStringBuilder.java @@ -1,7 +1,7 @@ // strings/WhitherStringBuilder.java -// (c)2016 MindView LLC: see Copyright.txt +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. public class WhitherStringBuilder { public String implicit(String[] fields) { diff --git a/strings/build.xml b/strings/build.xml deleted file mode 100644 index 4aec4d5bd..000000000 --- a/strings/build.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/swt/ColorBoxes.java b/swt/ColorBoxes.java deleted file mode 100644 index 543875b2c..000000000 --- a/swt/ColorBoxes.java +++ /dev/null @@ -1,83 +0,0 @@ -// swt/ColorBoxes.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// SWT translation of Swing ColorBoxes.java -import swt.util.*; -import org.eclipse.swt.*; -import org.eclipse.swt.widgets.*; -import org.eclipse.swt.events.*; -import org.eclipse.swt.graphics.*; -import org.eclipse.swt.layout.*; -import java.util.concurrent.*; -import java.util.*; -import onjava.*; - -class CBox extends Canvas implements Runnable { - class CBoxPaintListener implements PaintListener { - public void paintControl(PaintEvent e) { - Color color = new Color(e.display, cColor); - e.gc.setBackground(color); - Point size = getSize(); - e.gc.fillRectangle(0, 0, size.x, size.y); - color.dispose(); - } - } - private static SplittableRandom rand = new SplittableRandom(); - private static RGB newColor() { - return new RGB(rand.nextInt(255), - rand.nextInt(255), rand.nextInt(255)); - } - private int pause; - private RGB cColor = newColor(); - public CBox(Composite parent, int pause) { - super(parent, SWT.NONE); - this.pause = pause; - addPaintListener(new CBoxPaintListener()); - } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - cColor = newColor(); - getDisplay().asyncExec( () -> { - try { redraw(); } catch(SWTException e) {} - // SWTException is OK when the parent - // is terminated from under us. - }); - TimeUnit.MILLISECONDS.sleep(pause); - } - } catch(InterruptedException e) { - // Acceptable way to exit - } catch(SWTException e) { - // Acceptable way to exit: our parent - // was terminated from under us. - } - } -} - -public class ColorBoxes implements SWTApplication { - private int grid = 12; - private int pause = 50; - @Override - public void createContents(Composite parent) { - GridLayout gridLayout = new GridLayout(grid, true); - gridLayout.horizontalSpacing = 0; - gridLayout.verticalSpacing = 0; - parent.setLayout(gridLayout); - ExecutorService exec = new DaemonThreadPoolExecutor(); - for(int i = 0; i < (grid * grid); i++) { - final CBox cb = new CBox(parent, pause); - cb.setLayoutData(new GridData(GridData.FILL_BOTH)); - exec.execute(cb); - } - } - public static void main(String[] args) { - ColorBoxes boxes = new ColorBoxes(); - if(args.length > 0) - boxes.grid = new Integer(args[0]); - if(args.length > 1) - boxes.pause = new Integer(args[1]); - SWTConsole.run(boxes, 500, 400); - } -} diff --git a/swt/DisplayEnvironment.java b/swt/DisplayEnvironment.java deleted file mode 100644 index b2169113b..000000000 --- a/swt/DisplayEnvironment.java +++ /dev/null @@ -1,25 +0,0 @@ -// swt/DisplayEnvironment.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import swt.util.*; -import org.eclipse.swt.*; -import org.eclipse.swt.widgets.*; -import org.eclipse.swt.layout.*; -import java.util.*; - -public class -DisplayEnvironment implements SWTApplication { - @Override - public void createContents(Composite parent) { - parent.setLayout(new FillLayout()); - Text text = new Text(parent, SWT.WRAP | SWT.V_SCROLL); - for(Map.Entry entry: System.getenv().entrySet()) { - text.append(entry.getKey() + ": " + - entry.getValue() + "\n"); - } - } - public static void main(String[] args) { - SWTConsole.run(new DisplayEnvironment(), 800, 600); - } -} diff --git a/swt/DisplayProperties.java b/swt/DisplayProperties.java deleted file mode 100644 index 39548b959..000000000 --- a/swt/DisplayProperties.java +++ /dev/null @@ -1,26 +0,0 @@ -// swt/DisplayProperties.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import org.eclipse.swt.*; -import org.eclipse.swt.widgets.*; -import org.eclipse.swt.layout.*; -import java.io.*; - -public class DisplayProperties { - public static void main(String[] args) { - Display display = new Display(); - Shell shell = new Shell(display); - shell.setText("Display Properties"); - shell.setLayout(new FillLayout()); - Text text = new Text(shell, SWT.WRAP | SWT.V_SCROLL); - StringWriter props = new StringWriter(); - System.getProperties().list(new PrintWriter(props)); - text.setText(props.toString()); - shell.open(); - while(!shell.isDisposed()) - if(!display.readAndDispatch()) - display.sleep(); - display.dispose(); - } -} diff --git a/swt/HelloSWT.java b/swt/HelloSWT.java deleted file mode 100644 index a8f2f14aa..000000000 --- a/swt/HelloSWT.java +++ /dev/null @@ -1,20 +0,0 @@ -// swt/HelloSWT.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {Requires: org.eclipse.swt.widgets.Display; You must -// install the SWT library from http://www.eclipse.org } -import org.eclipse.swt.widgets.*; - -public class HelloSWT { - public static void main(String[] args) { - Display display = new Display(); - Shell shell = new Shell(display); - shell.setText("Hi there, SWT!"); // Title bar - shell.open(); - while(!shell.isDisposed()) - if(!display.readAndDispatch()) - display.sleep(); - display.dispose(); - } -} diff --git a/swt/Menus.java b/swt/Menus.java deleted file mode 100644 index 18c54b9e7..000000000 --- a/swt/Menus.java +++ /dev/null @@ -1,60 +0,0 @@ -// swt/Menus.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Fun with menus -import swt.util.*; -import org.eclipse.swt.*; -import org.eclipse.swt.widgets.*; -import java.util.*; -import java.io.IOException; -import java.nio.file.*; -import java.util.stream.*; - -public class Menus implements SWTApplication { - private static Shell shell; - @Override - public void createContents(Composite parent) { - shell = parent.getShell(); - Menu bar = new Menu(shell, SWT.BAR); - shell.setMenuBar(bar); - Set words = null; - try { - words = Files.lines(Paths.get("Menus.java")) - .flatMap(s -> Arrays.stream(s.split("\\W+"))) - .filter(s -> !s.matches("[0-9]+")) // No numbers - .map(String::trim) - .collect(Collectors.toCollection(TreeSet::new)); - } catch(IOException e) { - throw new RuntimeException(e); - } - Iterator it = words.iterator(); - MenuItem[] mItem = new MenuItem[7]; - for(int i = 0; i < mItem.length; i++) { - mItem[i] = new MenuItem(bar, SWT.CASCADE); - mItem[i].setText(it.next()); - Menu submenu = new Menu(shell, SWT.DROP_DOWN); - mItem[i].setMenu(submenu); - } - int i = 0; - while(it.hasNext()) { - addItem(bar, it, mItem[i]); - i = (i + 1) % mItem.length; - } - } - static Listener listener = new Listener() { - public void handleEvent(Event e) { - System.out.println(e.toString()); - } - }; - void - addItem(Menu bar, Iterator it, MenuItem mItem) { - MenuItem item = - new MenuItem(mItem.getMenu(),SWT.PUSH); - item.addListener(SWT.Selection, listener); - item.setText(it.next()); - } - public static void main(String[] args) { - SWTConsole.run(new Menus(), 600, 200); - } -} diff --git a/swt/ShellsAreMainWindows.java b/swt/ShellsAreMainWindows.java deleted file mode 100644 index 3d64b9f2b..000000000 --- a/swt/ShellsAreMainWindows.java +++ /dev/null @@ -1,29 +0,0 @@ -// swt/ShellsAreMainWindows.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import org.eclipse.swt.widgets.*; - -public class ShellsAreMainWindows { - static Shell[] shells = new Shell[10]; - public static void main(String[] args) { - Display display = new Display(); - for(int i = 0; i < shells.length; i++) { - shells[i] = new Shell(display); - shells[i].setText("Shell #" + i); - shells[i].open(); - } - while(!shellsDisposed()) - if(!display.readAndDispatch()) - display.sleep(); - display.dispose(); - } - static boolean shellsDisposed() { - for(Shell shell : shells) { - if(shell.isDisposed()) { - return true; - } - } - return false; - } -} diff --git a/swt/SineWave.java b/swt/SineWave.java deleted file mode 100644 index 3d644656b..000000000 --- a/swt/SineWave.java +++ /dev/null @@ -1,77 +0,0 @@ -// swt/SineWave.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// SWT translation of Swing SineWave.java -import swt.util.*; -import org.eclipse.swt.*; -import org.eclipse.swt.widgets.*; -import org.eclipse.swt.events.*; -import org.eclipse.swt.layout.*; - -class SineDraw extends Canvas { - private static final int SCALEFACTOR = 200; - private int cycles; - private int points; - private double[] sines; - private int[] pts; - public SineDraw(Composite parent, int style) { - super(parent, style); - addPaintListener(new PaintListener() { - public void paintControl(PaintEvent e) { - int maxWidth = getSize().x; - double hstep = (double)maxWidth / (double)points; - int maxHeight = getSize().y; - pts = new int[points]; - for(int i = 0; i < points; i++) - pts[i] = (int)((sines[i] * maxHeight / 2 * .95) - + (maxHeight / 2)); - e.gc.setForeground( - e.display.getSystemColor(SWT.COLOR_RED)); - for(int i = 1; i < points; i++) { - int x1 = (int)((i - 1) * hstep); - int x2 = (int)(i * hstep); - int y1 = pts[i - 1]; - int y2 = pts[i]; - e.gc.drawLine(x1, y1, x2, y2); - } - } - }); - setCycles(5); - } - public void setCycles(int newCycles) { - cycles = newCycles; - points = SCALEFACTOR * cycles * 2; - sines = new double[points]; - for(int i = 0; i < points; i++) { - double radians = (Math.PI / SCALEFACTOR) * i; - sines[i] = Math.sin(radians); - } - redraw(); - } -} - -public class SineWave implements SWTApplication { - private SineDraw sines; - private Slider slider; - @Override - public void createContents(Composite parent) { - parent.setLayout(new GridLayout(1, true)); - sines = new SineDraw(parent, SWT.NONE); - sines.setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, true)); - sines.setFocus(); - slider = new Slider(parent, SWT.HORIZONTAL); - slider.setValues(5, 1, 30, 1, 1, 1); - slider.setLayoutData( - new GridData(SWT.FILL, SWT.DEFAULT, true, false)); - slider.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent event) { - sines.setCycles(slider.getSelection()); - } - }); - } - public static void main(String[] args) { - SWTConsole.run(new SineWave(), 700, 400); - } -} diff --git a/swt/TabbedPane.java b/swt/TabbedPane.java deleted file mode 100644 index f0a411080..000000000 --- a/swt/TabbedPane.java +++ /dev/null @@ -1,152 +0,0 @@ -// swt/TabbedPane.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Placing SWT components in tabbed panes -import swt.util.*; -import org.eclipse.swt.*; -import org.eclipse.swt.widgets.*; -import org.eclipse.swt.events.*; -import org.eclipse.swt.graphics.*; -import org.eclipse.swt.layout.*; -import org.eclipse.swt.browser.*; - -public class TabbedPane implements SWTApplication { - private static TabFolder folder; - private static Shell shell; - @Override - public void createContents(Composite parent) { - shell = parent.getShell(); - parent.setLayout(new FillLayout()); - folder = new TabFolder(shell, SWT.BORDER); - labelTab(); - directoryDialogTab(); - buttonTab(); - sliderTab(); - scribbleTab(); - browserTab(); - } - public static void labelTab() { - TabItem tab = new TabItem(folder, SWT.CLOSE); - tab.setText("A Label"); // Text on the tab - tab.setToolTipText("A simple label"); - Label label = new Label(folder, SWT.CENTER); - label.setText("Label text"); - tab.setControl(label); - } - public static void directoryDialogTab() { - TabItem tab = new TabItem(folder, SWT.CLOSE); - tab.setText("Directory Dialog"); - tab.setToolTipText("Select a directory"); - final Button b = new Button(folder, SWT.PUSH); - b.setText("Select a Directory"); - b.addListener(SWT.MouseDown, new Listener() { - public void handleEvent(Event e) { - DirectoryDialog dd = new DirectoryDialog(shell); - String path = dd.open(); - if(path != null) - b.setText(path); - } - }); - tab.setControl(b); - } - public static void buttonTab() { - TabItem tab = new TabItem(folder, SWT.CLOSE); - tab.setText("Buttons"); - tab.setToolTipText("Different kinds of Buttons"); - Composite composite = new Composite(folder, SWT.NONE); - composite.setLayout(new GridLayout(4, true)); - for(int dir : new int[]{ - SWT.UP, SWT.RIGHT, SWT.LEFT, SWT.DOWN - }) { - Button b = new Button(composite, SWT.ARROW | dir); - b.addListener(SWT.MouseDown, listener); - } - newButton(composite, SWT.CHECK, "Check button"); - newButton(composite, SWT.PUSH, "Push button"); - newButton(composite, SWT.RADIO, "Radio button"); - newButton(composite, SWT.TOGGLE, "Toggle button"); - newButton(composite, SWT.FLAT, "Flat button"); - tab.setControl(composite); - } - private static Listener listener = new Listener() { - public void handleEvent(Event e) { - MessageBox m = new MessageBox(shell, SWT.OK); - m.setMessage(e.toString()); - m.open(); - } - }; - private static void newButton(Composite composite, - int type, String label) { - Button b = new Button(composite, type); - b.setText(label); - b.addListener(SWT.MouseDown, listener); - } - public static void sliderTab() { - TabItem tab = new TabItem(folder, SWT.CLOSE); - tab.setText("Sliders and Progress bars"); - tab.setToolTipText("Tied Slider to ProgressBar"); - Composite composite = new Composite(folder, SWT.NONE); - composite.setLayout(new GridLayout(2, true)); - final Slider slider = - new Slider(composite, SWT.HORIZONTAL); - final ProgressBar progress = - new ProgressBar(composite, SWT.HORIZONTAL); - slider.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent event) { - progress.setSelection(slider.getSelection()); - } - }); - tab.setControl(composite); - } - public static void scribbleTab() { - TabItem tab = new TabItem(folder, SWT.CLOSE); - tab.setText("Scribble"); - tab.setToolTipText("Simple graphics: drawing"); - final Canvas canvas = new Canvas(folder, SWT.NONE); - ScribbleMouseListener sml = - new ScribbleMouseListener(); - canvas.addMouseListener(sml); - canvas.addMouseMoveListener(sml); - tab.setControl(canvas); - } - private static class ScribbleMouseListener - extends MouseAdapter implements MouseMoveListener { - private Point p = new Point(0, 0); - public void mouseMove(MouseEvent e) { - if((e.stateMask & SWT.BUTTON1) == 0) - return; - GC gc = new GC((Canvas)e.widget); - gc.drawLine(p.x, p.y, e.x, e.y); - gc.dispose(); - updatePoint(e); - } - public void mouseDown(MouseEvent e) { - updatePoint(e); - } - private void updatePoint(MouseEvent e) { - p.x = e.x; - p.y = e.y; - } - } - public static void browserTab() { - TabItem tab = new TabItem(folder, SWT.CLOSE); - tab.setText("A Browser"); - tab.setToolTipText("A Web browser"); - Browser browser = null; - try { - browser = new Browser(folder, SWT.NONE); - } catch(SWTError e) { - Label label = new Label(folder, SWT.BORDER); - label.setText("Could not initialize browser"); - tab.setControl(label); - } - if(browser != null) { - browser.setUrl("http://www.MindviewInc.com"); - tab.setControl(browser); - } - } - public static void main(String[] args) { - SWTConsole.run(new TabbedPane(), 800, 600); - } -} diff --git a/swt/build.xml b/swt/build.xml deleted file mode 100644 index d702220d8..000000000 --- a/swt/build.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/swt/util/SWTApplication.java b/swt/util/SWTApplication.java deleted file mode 100644 index 407b258d2..000000000 --- a/swt/util/SWTApplication.java +++ /dev/null @@ -1,10 +0,0 @@ -// swt/util/SWTApplication.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package swt.util; -import org.eclipse.swt.widgets.*; - -public interface SWTApplication { - void createContents(Composite parent); -} diff --git a/swt/util/SWTConsole.java b/swt/util/SWTConsole.java deleted file mode 100644 index 396ee9a8f..000000000 --- a/swt/util/SWTConsole.java +++ /dev/null @@ -1,23 +0,0 @@ -// swt/util/SWTConsole.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package swt.util; -import org.eclipse.swt.widgets.*; - -public class SWTConsole { - public static void - run(SWTApplication swtApp, int width, int height) { - Display display = new Display(); - Shell shell = new Shell(display); - shell.setText(swtApp.getClass().getSimpleName()); - swtApp.createContents(shell); - shell.setSize(width, height); - shell.open(); - while(!shell.isDisposed()) { - if(!display.readAndDispatch()) - display.sleep(); - } - display.dispose(); - } -} diff --git a/tasks/ActiveObjectDemo.java b/tasks/ActiveObjectDemo.java deleted file mode 100644 index f39bb0dc2..000000000 --- a/tasks/ActiveObjectDemo.java +++ /dev/null @@ -1,89 +0,0 @@ -// tasks/ActiveObjectDemo.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Can only pass constants, immutables, "disconnected -// objects," or other active objects as arguments -// to asynch methods -import java.util.concurrent.*; -import java.util.*; - -public class ActiveObjectDemo { - private ExecutorService ex = - Executors.newSingleThreadExecutor(); - private SplittableRandom rand = new SplittableRandom(47); - // Insert a random delay to produce the effect - // of a calculation time: - private void pause(int factor) { - try { - TimeUnit.MILLISECONDS.sleep( - 100 + rand.nextInt(factor)); - } catch(InterruptedException e) { - System.out.println("sleep() interrupted"); - } - } - public Future - calculateInt(final int x, final int y) { - return ex.submit(() -> { - System.out.println("starting " + x + " + " + y); - pause(500); - return x + y; - }); - } - public Future - calculateFloat(final float x, final float y) { - return ex.submit(() -> { - System.out.println("starting " + x + " + " + y); - pause(2000); - return x + y; - }); - } - public void shutdown() { ex.shutdown(); } - public static void main(String[] args) { - ActiveObjectDemo d1 = new ActiveObjectDemo(); - // Prevents ConcurrentModificationException: - List> results = - new CopyOnWriteArrayList<>(); - for(float f = 0.0f; f < 1.0f; f += 0.2f) - results.add(d1.calculateFloat(f, f)); - for(int i = 0; i < 5; i++) - results.add(d1.calculateInt(i, i)); - System.out.println("All asynch calls made"); - while(results.size() > 0) { - for(Future f : results) - if(f.isDone()) { - try { - System.out.println(f.get()); - } catch(InterruptedException | - ExecutionException e) { - throw new RuntimeException(e); - } - results.remove(f); - } - } - d1.shutdown(); - } -} -/* Output: -starting 0.0 + 0.0 -All asynch calls made -0.0 -starting 0.2 + 0.2 -0.4 -starting 0.4 + 0.4 -0.8 -starting 0.6 + 0.6 -1.2 -starting 0.8 + 0.8 -1.6 -starting 0 + 0 -starting 1 + 1 -0 -2 -starting 2 + 2 -4 -starting 3 + 3 -6 -starting 4 + 4 -8 -*/ diff --git a/tasks/AtomicEvenSupplier.java b/tasks/AtomicEvenSupplier.java deleted file mode 100644 index fff3899f7..000000000 --- a/tasks/AtomicEvenSupplier.java +++ /dev/null @@ -1,20 +0,0 @@ -// tasks/AtomicEvenSupplier.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Atomic classes are occasionally useful in regular code -// {TimeOutDuringTesting} -// {IgnoreOutput} // No output validation -import java.util.concurrent.atomic.*; - -public class AtomicEvenSupplier extends IntSupplier { - private AtomicInteger currentEvenValue = - new AtomicInteger(0); - @Override - public int next() { - return currentEvenValue.addAndGet(2); - } - public static void main(String[] args) { - EvenChecker.test(new AtomicEvenSupplier()); - } -} diff --git a/tasks/AtomicIntegerTest.java b/tasks/AtomicIntegerTest.java deleted file mode 100644 index 1394399ea..000000000 --- a/tasks/AtomicIntegerTest.java +++ /dev/null @@ -1,36 +0,0 @@ -// tasks/AtomicIntegerTest.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.util.*; -import onjava.*; - -public class AtomicIntegerTest implements Runnable { - private AtomicInteger i = new AtomicInteger(0); - public int getValue() { return i.get(); } - private void evenIncrement() { i.addAndGet(2); } - @Override - public void run() { - while(true) - evenIncrement(); - } - public static void main(String[] args) { - new TimedAbort(5); // Terminate after 5 seconds - ExecutorService exec = - Executors.newCachedThreadPool(); - AtomicIntegerTest ait = new AtomicIntegerTest(); - exec.execute(ait); - while(true) { - int val = ait.getValue(); - if(val % 2 != 0) { - System.out.println(val); - System.exit(0); - } - } - } -} -/* Output: -TimedAbort 5 -*/ diff --git a/tasks/Atomicity.java b/tasks/Atomicity.java deleted file mode 100644 index 5d1ec1931..000000000 --- a/tasks/Atomicity.java +++ /dev/null @@ -1,41 +0,0 @@ -// tasks/Atomicity.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {Exec: javap -c Atomicity} - -public class Atomicity { - int i; - void f1() { i++; } - void f2() { i += 3; } -} -/* Output: -Compiled from "Atomicity.java" -public class Atomicity { - int i; - public Atomicity(); - 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/tasks/AtomicityTest.java b/tasks/AtomicityTest.java deleted file mode 100644 index 2f85d8cc4..000000000 --- a/tasks/AtomicityTest.java +++ /dev/null @@ -1,32 +0,0 @@ -// tasks/AtomicityTest.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {TimeOutDuringTesting} (on single-core machines) -import java.util.concurrent.*; - -public class AtomicityTest implements Runnable { - private int i = 0; - public int getValue() { return i; } - private synchronized void evenIncrement() { i++; i++; } - @Override - public void run() { - while(true) - evenIncrement(); - } - public static void main(String[] args) { - ExecutorService es = Executors.newCachedThreadPool(); - AtomicityTest at = new AtomicityTest(); - es.execute(at); - while(true) { - int val = at.getValue(); - if(val % 2 != 0) { - System.out.println(val); - System.exit(0); - } - } - } -} -/* Output: -73 -*/ diff --git a/tasks/BankTellerSimulation.java b/tasks/BankTellerSimulation.java deleted file mode 100644 index add65a651..000000000 --- a/tasks/BankTellerSimulation.java +++ /dev/null @@ -1,215 +0,0 @@ -// tasks/BankTellerSimulation.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Using queues and multithreading -// {Args: 5} -import java.util.concurrent.*; -import java.util.*; - -// Read-only objects don't require synchronization: -class Customer { - private final int serviceTime; - public Customer(int tm) { serviceTime = tm; } - public int getServiceTime() { return serviceTime; } - public String toString() { - return "[" + serviceTime + "]"; - } -} - -// Teach the customer line to display itself: -class CustomerLine extends ArrayBlockingQueue { - public CustomerLine(int maxLineSize) { - super(maxLineSize); - } - @Override - public String toString() { - if(this.size() == 0) - return "[Empty]"; - StringBuilder result = new StringBuilder(); - for(Customer customer : this) - result.append(customer); - return result.toString(); - } -} - -// Randomly add customers to a queue: -class CustomerSupplier implements Runnable { - private CustomerLine customers; - private static SplittableRandom rand = new SplittableRandom(47); - public CustomerSupplier(CustomerLine cq) { - customers = cq; - } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - TimeUnit.MILLISECONDS.sleep(rand.nextInt(300)); - customers.put(new Customer(rand.nextInt(1000))); - } - } catch(InterruptedException e) { - System.out.println("CustomerSupplier interrupted"); - } - System.out.println("CustomerSupplier terminating"); - } -} - -class Teller implements Runnable, Comparable { - private static int counter = 0; - private final int id = counter++; - // Customers served during this shift: - private int customersServed = 0; - private CustomerLine customers; - private boolean servingCustomerLine = true; - public Teller(CustomerLine cq) { customers = cq; } - public void run() { - try { - while(!Thread.interrupted()) { - Customer customer = customers.take(); - TimeUnit.MILLISECONDS.sleep( - customer.getServiceTime()); - synchronized(this) { - customersServed++; - while(!servingCustomerLine) - wait(); - } - } - } catch(InterruptedException e) { - System.out.println(this + "interrupted"); - } - System.out.println(this + "terminating"); - } - public synchronized void doSomethingElse() { - customersServed = 0; - servingCustomerLine = false; - } - public synchronized void serveCustomerLine() { - assert !servingCustomerLine: - "already serving: " + this; - servingCustomerLine = true; - notifyAll(); - } - public String toString() { - return "Teller " + id + " "; - } - public String shortString() { return "T" + id; } - // Used by priority queue: - public synchronized int compareTo(Teller other) { - return customersServed < other.customersServed ? -1 : - (customersServed == other.customersServed ? 0 : 1); - } -} - -class TellerManager implements Runnable { - private ExecutorService exec; - private CustomerLine customers; - private PriorityQueue workingTellers = - new PriorityQueue<>(); - private Queue tellersDoingOtherThings = - new LinkedList<>(); - private int adjustmentPeriod; - - public TellerManager(ExecutorService e, - CustomerLine customers, int adjustmentPeriod) { - exec = e; - this.customers = customers; - this.adjustmentPeriod = adjustmentPeriod; - // Start with a single teller: - Teller teller = new Teller(customers); - exec.execute(teller); - workingTellers.add(teller); - } - public void adjustTellerNumber() { - // This is actually a control system. By adjusting - // the numbers, you can reveal stability issues in - // the control mechanism. - // If line is too long, add another teller: - if(customers.size() / workingTellers.size() > 2) { - // If tellers are on break or doing - // another job, bring one back: - if(tellersDoingOtherThings.size() > 0) { - Teller teller = - tellersDoingOtherThings.remove(); - teller.serveCustomerLine(); - workingTellers.offer(teller); - return; - } - // Else create (hire) a new teller - Teller teller = new Teller(customers); - exec.execute(teller); - workingTellers.add(teller); - return; - } - // If line is short enough, remove a teller: - if(workingTellers.size() > 1 && - customers.size() / workingTellers.size() < 2) - reassignOneTeller(); - // If there is no line, we only need one teller: - if(customers.size() == 0) - while(workingTellers.size() > 1) - reassignOneTeller(); - } - // Give a teller a different job or a break: - private void reassignOneTeller() { - Teller teller = workingTellers.poll(); - teller.doSomethingElse(); - tellersDoingOtherThings.offer(teller); - } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - TimeUnit.MILLISECONDS.sleep(adjustmentPeriod); - adjustTellerNumber(); - System.out.print(customers + " { "); - for(Teller teller : workingTellers) - System.out.print(teller.shortString() + " "); - System.out.println("}"); - } - } catch(InterruptedException e) { - System.out.println(this + "interrupted"); - } - System.out.println(this + "terminating"); - } - @Override - public String toString() { return "TellerManager "; } -} - -public class BankTellerSimulation { - static final int MAX_LINE_SIZE = 50; - static final int ADJUSTMENT_PERIOD = 1000; - public static void - main(String[] args) throws Exception { - ExecutorService es = Executors.newCachedThreadPool(); - // If line is too long, customers will leave: - CustomerLine customers = - new CustomerLine(MAX_LINE_SIZE); - es.execute(new CustomerSupplier(customers)); - // Manager will add and remove tellers as necessary: - es.execute(new TellerManager( - es, customers, ADJUSTMENT_PERIOD)); - if(args.length > 0) // Optional argument - TimeUnit.SECONDS.sleep(new Integer(args[0])); - else { - System.out.println("Press 'Enter' to quit"); - System.in.read(); - } - es.shutdownNow(); - } -} -/* Output: -[200][207] { T1 T0 } -[861][258][140][322] { T1 T0 } -[575][342][804][826][896] { T1 T0 } -[896][984][810][141][12][689][992][976][368] { T2 T0 T1 } -TellerManager interrupted -CustomerSupplier interrupted -Teller 0 interrupted -Teller 2 interrupted -Teller 1 interrupted -Teller 2 terminating -Teller 0 terminating -CustomerSupplier terminating -TellerManager terminating -Teller 1 terminating -*/ diff --git a/tasks/BasicThreads.java b/tasks/BasicThreads.java deleted file mode 100644 index 49b841913..000000000 --- a/tasks/BasicThreads.java +++ /dev/null @@ -1,18 +0,0 @@ -// tasks/BasicThreads.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// The most basic use of the Thread class - -public class BasicThreads { - public static void main(String[] args) { - Thread t = new Thread(new LiftOff()); - t.start(); - System.out.println("Waiting for LiftOff"); - } -} -/* Output: -Waiting for LiftOff -#0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), -#0(1), #0(Liftoff!), -*/ diff --git a/tasks/CachedThreadPool.java b/tasks/CachedThreadPool.java deleted file mode 100644 index 715a80481..000000000 --- a/tasks/CachedThreadPool.java +++ /dev/null @@ -1,23 +0,0 @@ -// tasks/CachedThreadPool.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.concurrent.*; - -public class CachedThreadPool { - public static void main(String[] args) { - ExecutorService e = Executors.newCachedThreadPool(); - for(int i = 0; i < 5; i++) - e.execute(new LiftOff()); - e.shutdown(); - } -} -/* Output: -#0(9), #4(9), #3(9), #1(9), #2(9), #1(8), #3(8), #4(8), -#0(8), #4(7), #3(7), #1(7), #2(8), #3(6), #4(6), #0(7), -#4(5), #3(5), #1(6), #2(7), #1(5), #3(4), #4(4), #0(6), -#4(3), #3(3), #1(4), #2(6), #4(2), #0(5), #1(3), #0(4), -#4(1), #0(3), #1(2), #2(5), #3(2), #2(4), #1(1), #0(2), -#4(Liftoff!), #0(1), #1(Liftoff!), #2(3), #3(1), #2(2), -#0(Liftoff!), #2(1), #3(Liftoff!), #2(Liftoff!), -*/ diff --git a/tasks/CallableDemo.java b/tasks/CallableDemo.java deleted file mode 100644 index 6321980f0..000000000 --- a/tasks/CallableDemo.java +++ /dev/null @@ -1,50 +0,0 @@ -// tasks/CallableDemo.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.concurrent.*; -import java.util.*; - -class TaskWithResult implements Callable { - private int id; - public TaskWithResult(int id) { - this.id = id; - } - @Override - public String call() { - return "result of TaskWithResult " + id; - } -} - -public class CallableDemo { - public static void main(String[] args) { - ExecutorService es = Executors.newCachedThreadPool(); - ArrayList> results = new ArrayList<>(); - for(int i = 0; i < 10; i++) - results.add(es.submit(new TaskWithResult(i))); - for(Future fs : results) - try { - // get() blocks until completion: - System.out.println(fs.get()); - } catch(InterruptedException e) { - System.out.println(e); - return; - } catch(ExecutionException e) { - System.out.println(e); - } finally { - es.shutdown(); - } - } -} -/* Output: -result of TaskWithResult 0 -result of TaskWithResult 1 -result of TaskWithResult 2 -result of TaskWithResult 3 -result of TaskWithResult 4 -result of TaskWithResult 5 -result of TaskWithResult 6 -result of TaskWithResult 7 -result of TaskWithResult 8 -result of TaskWithResult 9 -*/ diff --git a/tasks/CarBuilder.java b/tasks/CarBuilder.java deleted file mode 100644 index 1efce05ee..000000000 --- a/tasks/CarBuilder.java +++ /dev/null @@ -1,300 +0,0 @@ -// tasks/CarBuilder.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// A complex example of tasks working together -import java.util.concurrent.*; -import java.util.*; - -class Car { - private final int id; - private boolean - engine = false, driveTrain = false, wheels = false; - public Car(int idn) { id = idn; } - // Empty Car object: - public Car() { id = -1; } - public synchronized int getId() { return id; } - public synchronized void addEngine() { engine = true; } - public synchronized void addDriveTrain() { - driveTrain = true; - } - public synchronized void addWheels() { wheels = true; } - public synchronized String toString() { - return "Car " + id + " [" + " engine: " + engine - + " driveTrain: " + driveTrain - + " wheels: " + wheels + " ]"; - } -} - -class CarQueue extends LinkedBlockingQueue {} - -class ChassisBuilder implements Runnable { - private CarQueue carQueue; - private int counter = 0; - public ChassisBuilder(CarQueue cq) { carQueue = cq; } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - TimeUnit.MILLISECONDS.sleep(500); - // Make chassis: - Car c = new Car(counter++); - System.out.println("ChassisBuilder created " + c); - // Insert into queue - carQueue.put(c); - } - } catch(InterruptedException e) { - System.out.println("Interrupted: ChassisBuilder"); - } - System.out.println("ChassisBuilder off"); - } -} - -class Assembler implements Runnable { - private CarQueue chassisQueue, finishingQueue; - private Car car; - private CyclicBarrier barrier = new CyclicBarrier(4); - private RobotPool robotPool; - public - Assembler(CarQueue cq, CarQueue fq, RobotPool rp) { - chassisQueue = cq; - finishingQueue = fq; - robotPool = rp; - } - public Car car() { return car; } - public CyclicBarrier barrier() { return barrier; } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - // Blocks until chassis is available: - car = chassisQueue.take(); - // Hire robots to perform work: - robotPool.hire(EngineRobot.class, this); - robotPool.hire(DriveTrainRobot.class, this); - robotPool.hire(WheelRobot.class, this); - barrier.await(); // Until the robots finish - // Put car into finishingQueue for further work - finishingQueue.put(car); - } - } catch(InterruptedException e) { - System.out.println( - "Exiting Assembler via interrupt"); - } catch(BrokenBarrierException e) { - // This one we want to know about - throw new RuntimeException(e); - } - System.out.println("Assembler off"); - } -} - -class Reporter implements Runnable { - private CarQueue carQueue; - public Reporter(CarQueue cq) { carQueue = cq; } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - System.out.println(carQueue.take()); - } - } catch(InterruptedException e) { - System.out.println( - "Exiting Reporter via interrupt"); - } - System.out.println("Reporter off"); - } -} - -abstract class Robot implements Runnable { - private RobotPool pool; - public Robot(RobotPool p) { pool = p; } - protected Assembler assembler; - public Robot assignAssembler(Assembler assembler) { - this.assembler = assembler; - return this; - } - private boolean engage = false; - public synchronized void engage() { - engage = true; - notifyAll(); - } - // The part of run() that's different for each robot: - abstract protected void performService(); - public void run() { - try { - powerDown(); // Wait until needed - while(!Thread.interrupted()) { - performService(); - assembler.barrier().await(); // Synchronize - // We're done with that job... - powerDown(); - } - } catch(InterruptedException e) { - System.out.println( - "Exiting " + this + " via interrupt"); - } catch(BrokenBarrierException e) { - // This one we want to know about - throw new RuntimeException(e); - } - System.out.println(this + " off"); - } - private synchronized void - powerDown() throws InterruptedException { - engage = false; - assembler = null; // Disconnect from the Assembler - // Put ourselves back in the available pool: - pool.release(this); - while(engage == false) // Power down - wait(); - } - public String toString() { - return getClass().getName(); - } -} - -class EngineRobot extends Robot { - public EngineRobot(RobotPool pool) { super(pool); } - protected void performService() { - System.out.println(this + " installing engine"); - assembler.car().addEngine(); - } -} - -class DriveTrainRobot extends Robot { - public DriveTrainRobot(RobotPool pool) { super(pool); } - protected void performService() { - System.out.println(this + " installing DriveTrain"); - assembler.car().addDriveTrain(); - } -} - -class WheelRobot extends Robot { - public WheelRobot(RobotPool pool) { super(pool); } - protected void performService() { - System.out.println(this + " installing Wheels"); - assembler.car().addWheels(); - } -} - -class RobotPool { - // Quietly prevents identical entries: - private Set pool = new HashSet<>(); - public synchronized void add(Robot r) { - pool.add(r); - notifyAll(); - } - public synchronized void - hire(Class robotType, Assembler d) - throws InterruptedException { - for(Robot r : pool) - if(r.getClass().equals(robotType)) { - pool.remove(r); - r.assignAssembler(d); - r.engage(); // Power it up to do the task - return; - } - wait(); // None available - hire(robotType, d); // Try again, recursively - } - public synchronized void release(Robot r) { add(r); } -} - -public class CarBuilder { - public static void - main(String[] args) throws Exception { - CarQueue chassisQueue = new CarQueue(), - finishingQueue = new CarQueue(); - ExecutorService es = Executors.newCachedThreadPool(); - RobotPool robotPool = new RobotPool(); - es.execute(new EngineRobot(robotPool)); - es.execute(new DriveTrainRobot(robotPool)); - es.execute(new WheelRobot(robotPool)); - es.execute(new Assembler( - chassisQueue, finishingQueue, robotPool)); - es.execute(new Reporter(finishingQueue)); - // Start everything running by producing chassis: - es.execute(new ChassisBuilder(chassisQueue)); - TimeUnit.SECONDS.sleep(7); - es.shutdownNow(); - } -} -/* Output: -ChassisBuilder created Car 0 [ engine: false driveTrain: -false wheels: false ] -WheelRobot installing Wheels -EngineRobot installing engine -DriveTrainRobot installing DriveTrain -Car 0 [ engine: true driveTrain: true wheels: true ] -ChassisBuilder created Car 1 [ engine: false driveTrain: -false wheels: false ] -EngineRobot installing engine -DriveTrainRobot installing DriveTrain -WheelRobot installing Wheels -Car 1 [ engine: true driveTrain: true wheels: true ] -ChassisBuilder created Car 2 [ engine: false driveTrain: -false wheels: false ] -EngineRobot installing engine -DriveTrainRobot installing DriveTrain -WheelRobot installing Wheels -Car 2 [ engine: true driveTrain: true wheels: true ] -ChassisBuilder created Car 3 [ engine: false driveTrain: -false wheels: false ] -DriveTrainRobot installing DriveTrain -EngineRobot installing engine -WheelRobot installing Wheels -Car 3 [ engine: true driveTrain: true wheels: true ] -ChassisBuilder created Car 4 [ engine: false driveTrain: -false wheels: false ] -EngineRobot installing engine -WheelRobot installing Wheels -DriveTrainRobot installing DriveTrain -Car 4 [ engine: true driveTrain: true wheels: true ] -ChassisBuilder created Car 5 [ engine: false driveTrain: -false wheels: false ] -DriveTrainRobot installing DriveTrain -WheelRobot installing Wheels -EngineRobot installing engine -Car 5 [ engine: true driveTrain: true wheels: true ] -ChassisBuilder created Car 6 [ engine: false driveTrain: -false wheels: false ] -EngineRobot installing engine -DriveTrainRobot installing DriveTrain -WheelRobot installing Wheels -Car 6 [ engine: true driveTrain: true wheels: true ] -ChassisBuilder created Car 7 [ engine: false driveTrain: -false wheels: false ] -EngineRobot installing engine -DriveTrainRobot installing DriveTrain -WheelRobot installing Wheels -Car 7 [ engine: true driveTrain: true wheels: true ] -ChassisBuilder created Car 8 [ engine: false driveTrain: -false wheels: false ] -EngineRobot installing engine -DriveTrainRobot installing DriveTrain -WheelRobot installing Wheels -Car 8 [ engine: true driveTrain: true wheels: true ] -ChassisBuilder created Car 9 [ engine: false driveTrain: -false wheels: false ] -DriveTrainRobot installing DriveTrain -WheelRobot installing Wheels -EngineRobot installing engine -Car 9 [ engine: true driveTrain: true wheels: true ] -ChassisBuilder created Car 10 [ engine: false driveTrain: -false wheels: false ] -DriveTrainRobot installing DriveTrain -WheelRobot installing Wheels -EngineRobot installing engine -Car 10 [ engine: true driveTrain: true wheels: true ] -Exiting Reporter via interrupt -Exiting EngineRobot via interrupt -Interrupted: ChassisBuilder -Exiting WheelRobot via interrupt -Exiting DriveTrainRobot via interrupt -Exiting Assembler via interrupt -Assembler off -DriveTrainRobot off -WheelRobot off -ChassisBuilder off -EngineRobot off -Reporter off -*/ diff --git a/tasks/Chopstick.java b/tasks/Chopstick.java deleted file mode 100644 index c27b343ae..000000000 --- a/tasks/Chopstick.java +++ /dev/null @@ -1,19 +0,0 @@ -// tasks/Chopstick.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Chopsticks for dining philosophers - -public class Chopstick { - private boolean taken = false; - public synchronized - void take() throws InterruptedException { - while(taken) - wait(); - taken = true; - } - public synchronized void drop() { - taken = false; - notifyAll(); - } -} diff --git a/tasks/CloseResource.java b/tasks/CloseResource.java deleted file mode 100644 index 9a75118d8..000000000 --- a/tasks/CloseResource.java +++ /dev/null @@ -1,45 +0,0 @@ -// tasks/CloseResource.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Interrupting a blocked task by -// closing the underlying resource -// {TimeOutDuringTesting} -import java.net.*; -import java.util.concurrent.*; -import java.io.*; - -public class CloseResource { - public static void - main(String[] args) throws Exception { - ExecutorService es = Executors.newCachedThreadPool(); - ServerSocket server = new ServerSocket(8080); - try(InputStream socketInput = - new Socket("localhost", 8080) - .getInputStream()) { - es.execute(new IOBlocked(socketInput)); - es.execute(new IOBlocked(System.in)); - TimeUnit.MILLISECONDS.sleep(100); - System.out.println("Shutting down all threads"); - es.shutdownNow(); - TimeUnit.SECONDS.sleep(1); - System.out.println( - "Closing " + socketInput.getClass().getName()); - socketInput.close(); // Releases blocked thread - } - TimeUnit.SECONDS.sleep(1); - System.out.println( - "Closing " + System.in.getClass().getName()); - System.in.close(); // Releases blocked thread - } -} -/* Output: -Waiting for read(): -Waiting for read(): -Shutting down all threads -Closing java.net.SocketInputStream -Interrupted from blocked I/O -Exiting IOBlocked.run() -Closing java.io.BufferedInputStream -Exiting IOBlocked.run() -*/ diff --git a/tasks/CountDownLatchDemo.java b/tasks/CountDownLatchDemo.java deleted file mode 100644 index 15feb8d91..000000000 --- a/tasks/CountDownLatchDemo.java +++ /dev/null @@ -1,97 +0,0 @@ -// tasks/CountDownLatchDemo.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.concurrent.*; -import java.util.*; - -// Performs some portion of a task: -class TaskPortion implements Runnable { - private static int counter = 0; - private final int id = counter++; - private static SplittableRandom rand = new SplittableRandom(47); - private final CountDownLatch latch; - TaskPortion(CountDownLatch latch) { - this.latch = latch; - } - @Override - public void run() { - try { - doWork(); - latch.countDown(); - } catch(InterruptedException ex) { - // Acceptable way to exit - } - } - public void doWork() throws InterruptedException { - TimeUnit.MILLISECONDS.sleep(rand.nextInt(2000)); - System.out.println(this + "completed"); - } - @Override - public String toString() { - return String.format("%1$-3d ", id); - } -} - -// Waits on the CountDownLatch: -class WaitingTask implements Runnable { - private static int counter = 0; - private final int id = counter++; - private final CountDownLatch latch; - WaitingTask(CountDownLatch latch) { - this.latch = latch; - } - @Override - public void run() { - try { - latch.await(); - System.out.println( - "Latch barrier passed for " + this); - } catch(InterruptedException ex) { - System.out.println(this + " interrupted"); - } - } - @Override - public String toString() { - return String.format("WaitingTask %1$-3d ", id); - } -} - -public class CountDownLatchDemo { - static final int SIZE = 100; - public static void - main(String[] args) throws Exception { - ExecutorService es = Executors.newCachedThreadPool(); - // All must share a single CountDownLatch object: - CountDownLatch latch = new CountDownLatch(SIZE); - for(int i = 0; i < 10; i++) - es.execute(new WaitingTask(latch)); - for(int i = 0; i < SIZE; i++) - es.execute(new TaskPortion(latch)); - System.out.println("Launched all tasks"); - es.shutdown(); // Quit when all tasks complete - } -} -/* Output: (First and last 10 Lines) -Launched all tasks -56 completed -99 completed -28 completed -92 completed -90 completed -8 completed -14 completed -71 completed -5 completed -________...________...________...________...________ -Latch barrier passed for WaitingTask 0 -Latch barrier passed for WaitingTask 2 -Latch barrier passed for WaitingTask 8 -Latch barrier passed for WaitingTask 9 -Latch barrier passed for WaitingTask 6 -Latch barrier passed for WaitingTask 5 -Latch barrier passed for WaitingTask 4 -Latch barrier passed for WaitingTask 3 -Latch barrier passed for WaitingTask 1 -Latch barrier passed for WaitingTask 7 -*/ diff --git a/tasks/CriticalSection.java b/tasks/CriticalSection.java deleted file mode 100644 index faaba95db..000000000 --- a/tasks/CriticalSection.java +++ /dev/null @@ -1,151 +0,0 @@ -// tasks/CriticalSection.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {TimeOutDuringTesting} -// (Behavior may have changed in Java 8) -// Synchronizing blocks instead of entire methods. Also -// demonstrates protection of a non-thread-safe class -// with a thread-safe one. -package tasks; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.util.*; - -class Pair { // Not thread-safe - private int x, y; - public Pair(int x, int y) { - this.x = x; - this.y = y; - } - public Pair() { this(0, 0); } - public int getX() { return x; } - public int getY() { return y; } - public void incrementX() { x++; } - public void incrementY() { y++; } - @Override - public String toString() { - return "x: " + x + ", y: " + y; - } - public class PairValuesNotEqualException - extends RuntimeException { - public PairValuesNotEqualException() { - super("Pair values not equal: " + Pair.this); - } - } - // Arbitrary invariant -- both variables must be equal: - public void checkState() { - if(x != y) - throw new PairValuesNotEqualException(); - } -} - -// Protect a Pair inside a thread-safe class: -abstract class PairManager { - AtomicInteger checkCounter = new AtomicInteger(0); - protected Pair p = new Pair(); - private List storage = - Collections.synchronizedList(new ArrayList<>()); - public synchronized Pair getPair() { - // Make a copy to keep the original safe: - return new Pair(p.getX(), p.getY()); - } - // Assume this is a time consuming operation - protected void store(Pair p) { - storage.add(p); - try { - TimeUnit.MILLISECONDS.sleep(50); - } catch(InterruptedException ignore) {} - } - public abstract void increment(); -} - -// Synchronize the entire method: -class PairManager1 extends PairManager { - @Override - public synchronized void increment() { - p.incrementX(); - p.incrementY(); - store(getPair()); - } -} - -// Use a critical section: -class PairManager2 extends PairManager { - @Override - public void increment() { - Pair temp; - synchronized(this) { - p.incrementX(); - p.incrementY(); - temp = getPair(); - } - store(temp); - } -} - -class PairManipulator implements Runnable { - private PairManager pm; - public PairManipulator(PairManager pm) { - this.pm = pm; - } - @Override - public void run() { - while(true) - pm.increment(); - } - @Override - public String toString() { - return "Pair: " + pm.getPair() + - " checkCounter = " + pm.checkCounter.get(); - } -} - -class PairChecker implements Runnable { - private PairManager pm; - public PairChecker(PairManager pm) { - this.pm = pm; - } - @Override - public void run() { - while(true) { - pm.checkCounter.incrementAndGet(); - pm.getPair().checkState(); - } - } -} - -public class CriticalSection { - // Test the two different approaches: - static void - testApproaches(PairManager pman1, PairManager pman2) { - ExecutorService es = Executors.newCachedThreadPool(); - PairManipulator - pm1 = new PairManipulator(pman1), - pm2 = new PairManipulator(pman2); - PairChecker - pcheck1 = new PairChecker(pman1), - pcheck2 = new PairChecker(pman2); - es.execute(pm1); - es.execute(pm2); - es.execute(pcheck1); - es.execute(pcheck2); - try { - TimeUnit.MILLISECONDS.sleep(500); - } catch(InterruptedException e) { - System.out.println("Sleep interrupted"); - } - System.out.println("pm1: " + pm1 + "\npm2: " + pm2); - System.exit(0); - } - public static void main(String[] args) { - PairManager - pman1 = new PairManager1(), - pman2 = new PairManager2(); - testApproaches(pman1, pman2); - } -} -/* Output: -pm1: Pair: x: 15, y: 15 checkCounter = 272565 -pm2: Pair: x: 16, y: 16 checkCounter = 3956974 -*/ diff --git a/tasks/DaemonFromFactory.java b/tasks/DaemonFromFactory.java deleted file mode 100644 index 210a81609..000000000 --- a/tasks/DaemonFromFactory.java +++ /dev/null @@ -1,44 +0,0 @@ -// tasks/DaemonFromFactory.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Using a Thread Factory to create daemons -import java.util.concurrent.*; -import onjava.*; - -public class DaemonFromFactory implements Runnable { - @Override - public void run() { - try { - while(true) { - TimeUnit.MILLISECONDS.sleep(100); - System.out.println( - Thread.currentThread() + " " + this); - } - } catch(InterruptedException e) { - System.out.println("Interrupted"); - } - } - public static void - main(String[] args) throws Exception { - ExecutorService exec = Executors.newCachedThreadPool( - new DaemonThreadFactory()); - for(int i = 0; i < 10; i++) - exec.execute(new DaemonFromFactory()); - System.out.println("All daemons started"); - TimeUnit.MILLISECONDS.sleep(500); // Run for a while - } -} -/* Output: (First 10 Lines) -All daemons started -Thread[Thread-2,5,main] DaemonFromFactory@1bb3d5e -Thread[Thread-8,5,main] DaemonFromFactory@12aef8a -Thread[Thread-9,5,main] DaemonFromFactory@b5ecf4 -Thread[Thread-0,5,main] DaemonFromFactory@3e3d06 -Thread[Thread-1,5,main] DaemonFromFactory@425a41 -Thread[Thread-5,5,main] DaemonFromFactory@4f61c0 -Thread[Thread-4,5,main] DaemonFromFactory@53f1ba -Thread[Thread-6,5,main] DaemonFromFactory@baf372 -Thread[Thread-3,5,main] DaemonFromFactory@1437b8f - ... -*/ diff --git a/tasks/Daemons.java b/tasks/Daemons.java deleted file mode 100644 index 2085d1f67..000000000 --- a/tasks/Daemons.java +++ /dev/null @@ -1,57 +0,0 @@ -// tasks/Daemons.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Daemon threads spawn other daemon threads -import java.util.concurrent.*; - -class Daemon implements Runnable { - private Thread[] t = new Thread[10]; - @Override - public void run() { - for(int i = 0; i < t.length; i++) { - t[i] = new Thread(new DaemonSpawn()); - t[i].start(); - System.out.print("DaemonSpawn " + i + " started, "); - } - for(int i = 0; i < t.length; i++) - System.out.print("t[" + i + "].isDaemon() = " + - t[i].isDaemon() + ", "); - while(true) - Thread.yield(); - } -} - -class DaemonSpawn implements Runnable { - @Override - public void run() { - while(true) - Thread.yield(); - } -} - -public class Daemons { - public static void - main(String[] args) throws Exception { - Thread d = new Thread(new Daemon()); - d.setDaemon(true); - d.start(); - System.out.print( - "d.isDaemon() = " + d.isDaemon() + ", "); - // Allow the daemon threads to - // finish their startup processes: - TimeUnit.SECONDS.sleep(1); - } -} -/* Output: -d.isDaemon() = true, DaemonSpawn 0 started, DaemonSpawn 1 -started, DaemonSpawn 2 started, DaemonSpawn 3 started, -DaemonSpawn 4 started, DaemonSpawn 5 started, DaemonSpawn 6 -started, DaemonSpawn 7 started, DaemonSpawn 8 started, -DaemonSpawn 9 started, t[0].isDaemon() = true, -t[1].isDaemon() = true, t[2].isDaemon() = true, -t[3].isDaemon() = true, t[4].isDaemon() = true, -t[5].isDaemon() = true, t[6].isDaemon() = true, -t[7].isDaemon() = true, t[8].isDaemon() = true, -t[9].isDaemon() = true, -*/ diff --git a/tasks/DaemonsDoRunFinally.java b/tasks/DaemonsDoRunFinally.java deleted file mode 100644 index 1abc95f1b..000000000 --- a/tasks/DaemonsDoRunFinally.java +++ /dev/null @@ -1,35 +0,0 @@ -// tasks/DaemonsDoRunFinally.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Daemon threads now run the finally clause -import java.util.concurrent.*; - -class ADaemon implements Runnable { - @Override - public void run() { - try { - System.out.println("Starting ADaemon"); - TimeUnit.SECONDS.sleep(1); - } catch(InterruptedException e) { - System.out.println( - "Exiting via InterruptedException"); - } finally { - System.out.println("ADaemon finally clause"); - } - } -} - -public class DaemonsDoRunFinally { - public static void - main(String[] args) throws Exception { - Thread t = new Thread(new ADaemon()); - t.setDaemon(true); - t.start(); - TimeUnit.SECONDS.sleep(2); - } -} -/* Output: -Starting ADaemon -ADaemon finally clause -*/ diff --git a/tasks/DeadlockingDiningPhilosophers.java b/tasks/DeadlockingDiningPhilosophers.java deleted file mode 100644 index f3882311f..000000000 --- a/tasks/DeadlockingDiningPhilosophers.java +++ /dev/null @@ -1,56 +0,0 @@ -// tasks/DeadlockingDiningPhilosophers.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Demonstrates how deadlock can be hidden in a program -// {Args: 0 5 timeout} -import java.util.concurrent.*; - -public class DeadlockingDiningPhilosophers { - public static void - main(String[] args) throws Exception { - int ponder = 5; - if(args.length > 0) - ponder = Integer.parseInt(args[0]); - int size = 5; - if(args.length > 1) - size = Integer.parseInt(args[1]); - ExecutorService es = Executors.newCachedThreadPool(); - Chopstick[] sticks = new Chopstick[size]; - for(int i = 0; i < size; i++) - sticks[i] = new Chopstick(); - for(int i = 0; i < size; i++) - es.execute(new Philosopher( - sticks[i], sticks[(i+1) % size], i, ponder)); - if(args.length == 3 && args[2].equals("timeout")) - TimeUnit.SECONDS.sleep(5); - else { - System.out.println("Press 'Enter' to quit"); - System.in.read(); - } - es.shutdownNow(); - } -} -/* Output: (First and last 10 Lines) -Philosopher 1 thinking -Philosopher 1 grabbing right -Philosopher 1 grabbing left -Philosopher 1 eating -Philosopher 1 thinking -Philosopher 3 thinking -Philosopher 4 thinking -Philosopher 2 thinking -Philosopher 1 grabbing right -Philosopher 0 thinking -________...________...________...________...________ -Philosopher 3 grabbing left -Philosopher 2 grabbing left -Philosopher 0 grabbing left -Philosopher 4 grabbing left -Philosopher 1 grabbing left -Philosopher 3 exiting via interrupt -Philosopher 4 exiting via interrupt -Philosopher 1 exiting via interrupt -Philosopher 0 exiting via interrupt -Philosopher 2 exiting via interrupt -*/ diff --git a/tasks/DelayQueueDemo.java b/tasks/DelayQueueDemo.java deleted file mode 100644 index c1397451c..000000000 --- a/tasks/DelayQueueDemo.java +++ /dev/null @@ -1,105 +0,0 @@ -// tasks/DelayQueueDemo.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.concurrent.*; -import java.util.*; -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<>(); - public 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("[%1$-4d]", delta) + - " Task " + id; - } - public String summary() { - return "(" + id + ":" + delta + ")"; - } - public static class EndSentinel extends DelayedTask { - private ExecutorService exec; - public EndSentinel(int delay, ExecutorService e) { - super(delay); - exec = e; - } - @Override - public void run() { - for(DelayedTask pt : sequence) { - System.out.print(pt.summary() + " "); - } - System.out.println(); - System.out.println(this + " Calling shutdownNow()"); - exec.shutdownNow(); - } - } -} - -class DelayedTaskConsumer implements Runnable { - private DelayQueue q; - public DelayedTaskConsumer(DelayQueue q) { - this.q = q; - } - @Override - public void run() { - try { - while(!Thread.interrupted()) - q.take().run(); // Run task with current thread - } catch(InterruptedException e) { - // Acceptable way to exit - } - System.out.println("Finished DelayedTaskConsumer"); - } -} - -public class DelayQueueDemo { - public static void main(String[] args) { - SplittableRandom rand = new SplittableRandom(47); - ExecutorService es = Executors.newCachedThreadPool(); - DelayQueue queue = - new DelayQueue<>(); - // Fill with tasks that have random delays: - for(int i = 0; i < 20; i++) - queue.put(new DelayedTask(rand.nextInt(5000))); - // Set the stopping point - queue.add(new DelayedTask.EndSentinel(5000, es)); - es.execute(new DelayedTaskConsumer(queue)); - } -} -/* Output: -[128 ] Task 11 [200 ] Task 7 [429 ] Task 5 [520 ] Task 18 -[555 ] Task 1 [961 ] Task 4 [998 ] Task 16 [1207] Task 9 -[1693] Task 2 [1809] Task 14 [1861] Task 3 [2278] Task 15 -[3288] Task 10 [3551] Task 12 [4258] Task 0 [4258] Task 19 -[4522] Task 8 [4589] Task 13 [4861] Task 17 [4868] Task 6 -(0:4258) (1:555) (2:1693) (3:1861) (4:961) (5:429) (6:4868) -(7:200) (8:4522) (9:1207) (10:3288) (11:128) (12:3551) -(13:4589) (14:1809) (15:2278) (16:998) (17:4861) (18:520) -(19:4258) (20:5000) -[5000] Task 20 Calling shutdownNow() -Finished DelayedTaskConsumer -*/ diff --git a/tasks/EvenChecker.java b/tasks/EvenChecker.java deleted file mode 100644 index 98d62fbc8..000000000 --- a/tasks/EvenChecker.java +++ /dev/null @@ -1,36 +0,0 @@ -// tasks/EvenChecker.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.concurrent.*; - -public class EvenChecker implements Runnable { - private IntSupplier generator; - private final int id; - public EvenChecker(IntSupplier g, int ident) { - generator = g; - id = ident; - } - @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 type of IntSupplier: - public static void test(IntSupplier gp, int count) { - System.out.println("Press Control-C to exit"); - ExecutorService es = Executors.newCachedThreadPool(); - for(int i = 0; i < count; i++) - es.execute(new EvenChecker(gp, i)); - es.shutdown(); - } - // Default value for count: - public static void test(IntSupplier gp) { - test(gp, 10); - } -} diff --git a/tasks/EvenSupplier.java b/tasks/EvenSupplier.java deleted file mode 100644 index 10daf9425..000000000 --- a/tasks/EvenSupplier.java +++ /dev/null @@ -1,25 +0,0 @@ -// tasks/EvenSupplier.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// When threads collide -// {TimeOutDuringTesting} (on single-core machines) - -public class EvenSupplier extends IntSupplier { - private int currentEvenValue = 0; - @Override - public int next() { - ++currentEvenValue; // Danger point here! - ++currentEvenValue; - return currentEvenValue; - } - public static void main(String[] args) { - EvenChecker.test(new EvenSupplier()); - } -} -/* Output: -Press Control-C to exit -1305 not even! -1307 not even! -1303 not even! -*/ diff --git a/tasks/ExceptionThread.java b/tasks/ExceptionThread.java deleted file mode 100644 index acd42090a..000000000 --- a/tasks/ExceptionThread.java +++ /dev/null @@ -1,18 +0,0 @@ -// tasks/ExceptionThread.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {ValidateByHand} -// {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()); - } -} diff --git a/tasks/ExchangerDemo.java b/tasks/ExchangerDemo.java deleted file mode 100644 index 358dfe1e2..000000000 --- a/tasks/ExchangerDemo.java +++ /dev/null @@ -1,85 +0,0 @@ -// tasks/ExchangerDemo.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.concurrent.*; -import java.util.*; -import java.util.function.*; -import onjava.*; - -class ExchangerProducer implements Runnable { - private Supplier generator; - private Exchanger> exchanger; - private List holder; - ExchangerProducer(Exchanger> exchg, - Supplier gen, List holder) { - exchanger = exchg; - generator = gen; - this.holder = holder; - } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - for(int i = 0; i < ExchangerDemo.size; i++) - holder.add(generator.get()); - // Exchange full for empty: - holder = exchanger.exchange(holder); - } - } catch(InterruptedException e) { - // OK to terminate this way. - } - } -} - -class ExchangerConsumer implements Runnable { - private Exchanger> exchanger; - private List holder; - private volatile T value; - ExchangerConsumer( - Exchanger> ex, List holder) { - exchanger = ex; - this.holder = holder; - } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - holder = exchanger.exchange(holder); - for(T x : holder) { - value = x; // Fetch out value - holder.remove(x); // OK for CopyOnWriteArrayList - } - } - } catch(InterruptedException e) { - // OK to terminate this way. - } - System.out.println("Final value: " + value); - } -} - -public class ExchangerDemo { - static int size = 10; - static int delay = 5; // Seconds - public static void - main(String[] args) throws Exception { - if(args.length > 0) - size = new Integer(args[0]); - if(args.length > 1) - delay = new Integer(args[1]); - ExecutorService es = Executors.newCachedThreadPool(); - Exchanger> xc = new Exchanger<>(); - List - producerList = new CopyOnWriteArrayList<>(), - consumerList = new CopyOnWriteArrayList<>(); - es.execute(new ExchangerProducer<>(xc, - BasicSupplier.create(Fat.class), producerList)); - es.execute( - new ExchangerConsumer<>(xc,consumerList)); - TimeUnit.SECONDS.sleep(delay); - es.shutdownNow(); - } -} -/* Output: -Final value: Fat id: 18859 -*/ diff --git a/tasks/ExplicitCriticalSection.java b/tasks/ExplicitCriticalSection.java deleted file mode 100644 index f60a8782a..000000000 --- a/tasks/ExplicitCriticalSection.java +++ /dev/null @@ -1,82 +0,0 @@ -// tasks/ExplicitCriticalSection.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {ThrowsException} on a multiprocessor machine -// Using explicit Lock objects to create critical sections -package tasks; -import java.util.concurrent.locks.*; - -// Synchronize the entire method: -class ExplicitPairManager1 extends PairManager { - private Lock lock = new ReentrantLock(); - @Override - public void increment() { - lock.lock(); - try { - p.incrementX(); - p.incrementY(); - store(getPair()); - } finally { - lock.unlock(); - } - } -} - -// Use a critical section: -class ExplicitPairManager2 extends PairManager { - private Lock lock = new ReentrantLock(); - @Override - public void increment() { - Pair temp; - lock.lock(); - try { - p.incrementX(); - p.incrementY(); - temp = getPair(); - } finally { - lock.unlock(); - } - store(temp); - } -} - -public class ExplicitCriticalSection { - public static void - main(String[] args) throws Exception { - PairManager - pman1 = new ExplicitPairManager1(), - pman2 = new ExplicitPairManager2(); - CriticalSection.testApproaches(pman1, pman2); - } -} -/* Output: -pm1: Pair: x: 10, y: 10 checkCounter = 2193118 -pm2: Pair: x: 10, y: 10 checkCounter = 2184256 -___[ Error Output ]___ -Exception in thread "pool-1-thread-4" Exception in thread -"pool-1-thread-3" -concurrency.Pair$PairValuesNotEqualException: Pair values -not equal: x: 2, y: 1 - at -concurrency.Pair.checkState(CriticalSection.java:36) - at -concurrency.PairChecker.run(CriticalSection.java:110) - at java.util.concurrent.ThreadPoolExecutor.runWorke -r(ThreadPoolExecutor.java:1142) - at java.util.concurrent.ThreadPoolExecutor$Worker.r -un(ThreadPoolExecutor.java:617) - at java.lang.Thread.run(Thread.java:745) -concurrency.Pair$PairValuesNotEqualException: Pair values -not equal: x: 2, y: 1 - at -concurrency.Pair.checkState(CriticalSection.java:36) - at -concurrency.PairChecker.run(CriticalSection.java:110) - at java.util.concurrent.ThreadPoolExecutor.runWorke -r(ThreadPoolExecutor.java:1142) - at java.util.concurrent.ThreadPoolExecutor$Worker.r -un(ThreadPoolExecutor.java:617) - at java.lang.Thread.run(Thread.java:745) -___[ Exception is Expected ]___ -*/ diff --git a/tasks/FastSimulation.java b/tasks/FastSimulation.java deleted file mode 100644 index e3c74b75f..000000000 --- a/tasks/FastSimulation.java +++ /dev/null @@ -1,79 +0,0 @@ -// tasks/FastSimulation.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.util.*; - -public class FastSimulation { - static final int N_ELEMENTS = 100000; - static final int N_GENES = 30; - static final int N_EVOLVERS = 50; - static final AtomicInteger[][] GRID = - new AtomicInteger[N_ELEMENTS][N_GENES]; - static SplittableRandom rand = new SplittableRandom(47); - static class Evolver implements Runnable { - @Override - public void run() { - while(!Thread.interrupted()) { - // Randomly select an element to work on: - int element = rand.nextInt(N_ELEMENTS); - for(int i = 0; i < N_GENES; i++) { - int previous = element - 1; - if(previous < 0) previous = N_ELEMENTS - 1; - int next = element + 1; - if(next >= N_ELEMENTS) next = 0; - int oldvalue = GRID[element][i].get(); - // Perform some kind of modeling calculation: - int newvalue = oldvalue + - GRID[previous][i].get() + GRID[next][i].get(); - newvalue /= 3; // Average the three values - if(!GRID[element][i] - .compareAndSet(oldvalue, newvalue)) { - // Policy here to deal with failure. Here, we - // just report it and ignore it; our model - // will eventually deal with it. - System.out.println( - "Old value changed from " + oldvalue); - } - } - } - } - } - public static void - main(String[] args) throws Exception { - ExecutorService es = Executors.newCachedThreadPool(); - for(int i = 0; i < N_ELEMENTS; i++) - for(int j = 0; j < N_GENES; j++) - GRID[i][j] = - new AtomicInteger(rand.nextInt(1000)); - for(int i = 0; i < N_EVOLVERS; i++) - es.execute(new Evolver()); - TimeUnit.SECONDS.sleep(5); - es.shutdownNow(); - } -} -/* Output: (First and last 10 Lines) -Old value changed from 542 -Old value changed from 447 -Old value changed from 446 -Old value changed from 643 -Old value changed from 419 -Old value changed from 573 -Old value changed from 668 -Old value changed from 710 -Old value changed from 800 -Old value changed from 406 -________...________...________...________...________ -Old value changed from 458 -Old value changed from 436 -Old value changed from 475 -Old value changed from 501 -Old value changed from 526 -Old value changed from 465 -Old value changed from 467 -Old value changed from 368 -Old value changed from 404 -Old value changed from 428 -*/ diff --git a/tasks/Fat.java b/tasks/Fat.java deleted file mode 100644 index 245a40db8..000000000 --- a/tasks/Fat.java +++ /dev/null @@ -1,20 +0,0 @@ -// tasks/Fat.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Objects that are expensive to create - -public class Fat { - private volatile double d; // Prevent optimization - private static int counter = 0; - private final int id = counter++; - public Fat() { - // Expensive, interruptible operation: - for(int i = 1; i < 10000; i++) { - d += (Math.PI + Math.E) / (double)i; - } - } - public void operation() { System.out.println(this); } - @Override - public String toString() { return "Fat id: " + id; } -} diff --git a/tasks/FixedDiningPhilosophers.java b/tasks/FixedDiningPhilosophers.java deleted file mode 100644 index 9ada5a78c..000000000 --- a/tasks/FixedDiningPhilosophers.java +++ /dev/null @@ -1,60 +0,0 @@ -// tasks/FixedDiningPhilosophers.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Dining philosophers without deadlock -// {Args: 5 5 timeout} -import java.util.concurrent.*; - -public class FixedDiningPhilosophers { - public static void - main(String[] args) throws Exception { - int ponder = 5; - if(args.length > 0) - ponder = Integer.parseInt(args[0]); - int size = 5; - if(args.length > 1) - size = Integer.parseInt(args[1]); - ExecutorService es = Executors.newCachedThreadPool(); - Chopstick[] sticks = new Chopstick[size]; - for(int i = 0; i < size; i++) - sticks[i] = new Chopstick(); - for(int i = 0; i < size; i++) - if(i < (size-1)) - es.execute(new Philosopher( - sticks[i], sticks[i+1], i, ponder)); - else - es.execute(new Philosopher( - sticks[0], sticks[i], i, ponder)); - if(args.length == 3 && args[2].equals("timeout")) - TimeUnit.SECONDS.sleep(5); - else { - System.out.println("Press 'Enter' to quit"); - System.in.read(); - } - es.shutdownNow(); - } -} -/* Output: (First and last 10 Lines) -Philosopher 4 thinking -Philosopher 3 thinking -Philosopher 0 thinking -Philosopher 2 thinking -Philosopher 1 thinking -Philosopher 4 grabbing right -Philosopher 1 grabbing right -Philosopher 2 grabbing right -Philosopher 2 grabbing left -Philosopher 0 grabbing right -________...________...________...________...________ -Philosopher 2 grabbing right -Philosopher 1 exiting via interrupt -Philosopher 0 exiting via interrupt -Philosopher 3 exiting via interrupt -Philosopher 4 grabbing right -Philosopher 2 grabbing left -Philosopher 4 grabbing left -Philosopher 2 exiting via interrupt -Philosopher 4 eating -Philosopher 4 exiting via interrupt -*/ diff --git a/tasks/FixedThreadPool.java b/tasks/FixedThreadPool.java deleted file mode 100644 index 358ac8024..000000000 --- a/tasks/FixedThreadPool.java +++ /dev/null @@ -1,24 +0,0 @@ -// tasks/FixedThreadPool.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.concurrent.*; - -public class FixedThreadPool { - public static void main(String[] args) { - // Constructor argument is number of threads: - ExecutorService e = Executors.newFixedThreadPool(5); - for(int i = 0; i < 5; i++) - e.execute(new LiftOff()); - e.shutdown(); - } -} -/* Output: -#3(9), #2(9), #3(8), #2(8), #1(9), #4(9), #0(9), #2(7), -#3(7), #1(8), #0(8), #4(8), #3(6), #2(6), #0(7), #1(7), -#0(6), #2(5), #4(7), #3(5), #0(5), #1(6), #0(4), #4(6), -#3(4), #2(4), #1(5), #4(5), #0(3), #2(3), #3(3), #2(2), -#0(2), #4(4), #1(4), #0(1), #2(1), #3(2), #0(Liftoff!), -#1(3), #4(3), #1(2), #3(1), #2(Liftoff!), #3(Liftoff!), -#1(1), #4(2), #1(Liftoff!), #4(1), #4(Liftoff!), -*/ diff --git a/tasks/GreenhouseScheduler.java b/tasks/GreenhouseScheduler.java deleted file mode 100644 index 35f1755ab..000000000 --- a/tasks/GreenhouseScheduler.java +++ /dev/null @@ -1,202 +0,0 @@ -// tasks/GreenhouseScheduler.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Rewriting innerclasses/GreenhouseController.java -// to use a ScheduledThreadPoolExecutor -// {Args: 5000} -import java.util.concurrent.*; -import java.util.*; - -public class GreenhouseScheduler { - private volatile boolean light = false; - private volatile boolean water = false; - private String thermostat = "Day"; - public synchronized String getThermostat() { - return thermostat; - } - public synchronized void setThermostat(String value) { - thermostat = value; - } - ScheduledThreadPoolExecutor scheduler = - new ScheduledThreadPoolExecutor(10); - public void schedule(Runnable event, long delay) { - scheduler.schedule(event,delay,TimeUnit.MILLISECONDS); - } - public void - repeat(Runnable event, long initialDelay, long period) { - scheduler.scheduleAtFixedRate( - event, initialDelay, period, TimeUnit.MILLISECONDS); - } - class LightOn implements Runnable { - @Override - public void run() { - // Put hardware control code here to - // physically turn on the light. - System.out.println("Turning on lights"); - light = true; - } - } - class LightOff implements Runnable { - @Override - public void run() { - // Put hardware control code here to - // physically turn off the light. - System.out.println("Turning off lights"); - light = false; - } - } - class WaterOn implements Runnable { - @Override - public void run() { - // Put hardware control code here. - System.out.println("Turning greenhouse water on"); - water = true; - } - } - class WaterOff implements Runnable { - @Override - public void run() { - // Put hardware control code here. - System.out.println("Turning greenhouse water off"); - water = false; - } - } - class ThermostatNight implements Runnable { - @Override - public void run() { - // Put hardware control code here. - System.out.println("Thermostat to night setting"); - setThermostat("Night"); - } - } - class ThermostatDay implements Runnable { - @Override - public void run() { - // Put hardware control code here. - System.out.println("Thermostat to day setting"); - setThermostat("Day"); - } - } - class Bell implements Runnable { - @Override - public void run() { System.out.println("Bing!"); } - } - class Terminate implements Runnable { - @Override - public void run() { - System.out.println("Terminating"); - scheduler.shutdownNow(); - // Must start a separate task to do this job, - // since the scheduler was shut down: - new Thread() { - @Override - public void run() { - for(DataPoint d : data) - System.out.println(d); - } - }.start(); - } - } - // New feature: data collection - static class DataPoint { - final Calendar time; - final double temperature; - final double humidity; - public DataPoint(Calendar d, double temp, double hum) { - time = d; - temperature = temp; - humidity = hum; - } - @Override - public String toString() { - return time.getTime() + - String.format( - " temperature: %1$.1f humidity: %2$.2f", - temperature, humidity); - } - } - private Calendar lastTime = Calendar.getInstance(); - { // Adjust date to the half hour - lastTime.set(Calendar.MINUTE, 30); - lastTime.set(Calendar.SECOND, 00); - } - private double lastTemp = 65.0f; - private int tempDirection = +1; - private double lastHumidity = 50.0f; - private int humidityDirection = +1; - private SplittableRandom rand = new SplittableRandom(47); - List data = Collections.synchronizedList( - new ArrayList<>()); - class CollectData implements Runnable { - @Override - public void run() { - System.out.println("Collecting data"); - synchronized(GreenhouseScheduler.this) { - // Pretend the interval is longer than it is: - lastTime.set(Calendar.MINUTE, - lastTime.get(Calendar.MINUTE) + 30); - // One in 5 chances of reversing the direction: - if(rand.nextInt(5) == 4) - tempDirection = -tempDirection; - // Store previous value: - lastTemp += - tempDirection * (1.0f + rand.nextDouble()); - if(rand.nextInt(5) == 4) - humidityDirection = -humidityDirection; - lastHumidity += - humidityDirection * rand.nextDouble(); - // Calendar must be cloned, otherwise all - // DataPoints hold references to same lastTime. - // For basic object like Calendar, clone() is OK. - data.add(new DataPoint((Calendar)lastTime.clone(), - lastTemp, lastHumidity)); - } - } - } - public static void main(String[] args) { - GreenhouseScheduler gh = new GreenhouseScheduler(); - gh.schedule(gh.new Terminate(), 5000); - // Former "Restart" class not necessary: - gh.repeat(gh.new Bell(), 0, 1000); - gh.repeat(gh.new ThermostatNight(), 0, 2000); - gh.repeat(gh.new LightOn(), 0, 200); - gh.repeat(gh.new LightOff(), 0, 400); - gh.repeat(gh.new WaterOn(), 0, 600); - gh.repeat(gh.new WaterOff(), 0, 800); - gh.repeat(gh.new ThermostatDay(), 0, 1400); - gh.repeat(gh.new CollectData(), 500, 500); - } -} -/* Output: (First and last 10 Lines) -Bing! -Thermostat to night setting -Turning on lights -Turning off lights -Turning greenhouse water on -Turning on lights -Turning greenhouse water off -Thermostat to day setting -Turning on lights -Turning off lights -________...________...________...________...________ -Turning on lights -Mon Jun 15 16:00:00 PDT 2015 temperature: 66.4 humidity: -50.05 -Mon Jun 15 16:30:00 PDT 2015 temperature: 68.0 humidity: -50.47 -Mon Jun 15 17:00:00 PDT 2015 temperature: 69.7 humidity: -51.42 -Mon Jun 15 17:30:00 PDT 2015 temperature: 70.8 humidity: -50.87 -Mon Jun 15 18:00:00 PDT 2015 temperature: 72.0 humidity: -50.32 -Mon Jun 15 18:30:00 PDT 2015 temperature: 73.2 humidity: -49.92 -Mon Jun 15 19:00:00 PDT 2015 temperature: 71.9 humidity: -49.81 -Mon Jun 15 19:30:00 PDT 2015 temperature: 70.1 humidity: -50.25 -Mon Jun 15 20:00:00 PDT 2015 temperature: 68.9 humidity: -51.00 -*/ diff --git a/tasks/HorseRace.java b/tasks/HorseRace.java deleted file mode 100644 index fa41aa68b..000000000 --- a/tasks/HorseRace.java +++ /dev/null @@ -1,146 +0,0 @@ -// tasks/HorseRace.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Using CyclicBarriers -import java.util.concurrent.*; -import java.util.*; - -class Horse implements Runnable { - private static int counter = 0; - private final int id = counter++; - private int strides = 0; - private static SplittableRandom rand = new SplittableRandom(47); - private static CyclicBarrier barrier; - public Horse(CyclicBarrier b) { barrier = b; } - public synchronized int getStrides() { return strides; } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - synchronized(this) { - strides += rand.nextInt(3); // Yeilds 0, 1 or 2 - } - barrier.await(); - } - } catch(InterruptedException e) { - // A legitimate way to exit - } catch(BrokenBarrierException e) { - // This one we want to know about - throw new RuntimeException(e); - } - } - @Override - public String toString() { return "Horse " + id + " "; } - public String tracks() { - StringBuilder s = new StringBuilder(); - for(int i = 0; i < getStrides(); i++) - s.append("*"); - s.append(id); - return s.toString(); - } -} - -public class HorseRace { - static final int FINISH_LINE = 75; - private List horses = new ArrayList<>(); - private ExecutorService exec = - Executors.newCachedThreadPool(); - private CyclicBarrier barrier; - public HorseRace(int nHorses, final int pause) { - barrier = new CyclicBarrier(nHorses, () -> { - StringBuilder s = new StringBuilder(); - for(int i = 0; i < FINISH_LINE; i++) - s.append("="); // The fence on the racetrack - System.out.println(s); - for(Horse horse : horses) - System.out.println(horse.tracks()); - for(Horse horse : horses) - if(horse.getStrides() >= FINISH_LINE) { - System.out.println(horse + "won!"); - exec.shutdownNow(); - return; - } - try { - TimeUnit.MILLISECONDS.sleep(pause); - } catch(InterruptedException e) { - System.out.println( - "barrier-action sleep interrupted"); - } - }); - for(int i = 0; i < nHorses; i++) { - Horse horse = new Horse(barrier); - horses.add(horse); - exec.execute(horse); - } - } - public static void main(String[] args) { - int nHorses = 7; - int pause = 200; - if(args.length > 0) { // Optional argument - int n = new Integer(args[0]); - nHorses = n > 0 ? n : nHorses; - } - if(args.length > 1) { // Optional argument - int p = new Integer(args[1]); - pause = p > -1 ? p : pause; - } - new HorseRace(nHorses, pause); - } -} -/* Output: (First and last 18 Lines) -=========================================================== -================ -*0 -**1 -*2 -**3 -**4 -*5 -**6 -=========================================================== -================ -***0 -**1 -*2 -***3 -***4 -*5 -**6 -=========================================================== -================ -*****0 -________...________...________...________...________ -*****************************************************6 -=========================================================== -================ -*********************************************************** -*0 -*********************************************************** -1 -*********************************************************** -*2 -*********************************************************** -**************3 -*********************************************************** -4 -*********************************************************** -***********5 -*******************************************************6 -=========================================================== -================ -*********************************************************** -**0 -*********************************************************** -**1 -*********************************************************** -**2 -*********************************************************** -****************3 -*********************************************************** -*4 -*********************************************************** -*************5 -********************************************************6 -Horse 3 won! -*/ diff --git a/tasks/IntSupplier.java b/tasks/IntSupplier.java deleted file mode 100644 index 4397462c6..000000000 --- a/tasks/IntSupplier.java +++ /dev/null @@ -1,12 +0,0 @@ -// tasks/IntSupplier.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. - -public abstract class IntSupplier { - private volatile boolean canceled = false; - public abstract int next(); - // Allow this to be canceled: - public void cancel() { canceled = true; } - public boolean isCanceled() { return canceled; } -} diff --git a/tasks/Interrupting.java b/tasks/Interrupting.java deleted file mode 100644 index 92dff2454..000000000 --- a/tasks/Interrupting.java +++ /dev/null @@ -1,98 +0,0 @@ -// tasks/Interrupting.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Interrupting a blocked thread -import java.util.concurrent.*; -import java.io.*; - -class SleepBlocked implements Runnable { - @Override - public void run() { - try { - TimeUnit.SECONDS.sleep(100); - } catch(InterruptedException e) { - System.out.println("InterruptedException"); - } - System.out.println("Exiting SleepBlocked.run()"); - } -} - -class IOBlocked implements Runnable { - private InputStream in; - public IOBlocked(InputStream is) { in = is; } - @Override - public void run() { - try { - System.out.println("Waiting for read():"); - in.read(); - } catch(IOException e) { - if(Thread.currentThread().isInterrupted()) { - System.out.println( - "Interrupted from blocked I/O"); - } else { - throw new RuntimeException(e); - } - } - System.out.println("Exiting IOBlocked.run()"); - } -} - -class SynchronizedBlocked implements Runnable { - public synchronized void f() { - while(true) // Never releases lock - Thread.yield(); - } - public SynchronizedBlocked() { - new Thread() { - @Override - public void run() { - f(); // Lock acquired by this thread - } - }.start(); - } - @Override - public void run() { - System.out.println("Trying to call f()"); - f(); - System.out.println( - "Exiting SynchronizedBlocked.run()"); - } -} - -public class Interrupting { - private static ExecutorService exec = - Executors.newCachedThreadPool(); - static void - test(Runnable r) throws InterruptedException { - Future f = exec.submit(r); - TimeUnit.MILLISECONDS.sleep(100); - System.out.println( - "Interrupting " + r.getClass().getName()); - f.cancel(true); // Interrupts if running - System.out.println( - "Interrupt sent to " + r.getClass().getName()); - } - public static void - main(String[] args) throws Exception { - test(new SleepBlocked()); - test(new IOBlocked(System.in)); - test(new SynchronizedBlocked()); - TimeUnit.SECONDS.sleep(3); - System.out.println("Aborting with System.exit(0)"); - System.exit(0); // ... since last 2 interrupts failed - } -} -/* Output: -Interrupting SleepBlocked -InterruptedException -Exiting SleepBlocked.run() -Interrupt sent to SleepBlocked -Waiting for read(): -Interrupting IOBlocked -Interrupt sent to IOBlocked -Trying to call f() -Interrupting SynchronizedBlocked -Interrupt sent to SynchronizedBlocked -Aborting with System.exit(0) -*/ diff --git a/tasks/Interrupting2.java b/tasks/Interrupting2.java deleted file mode 100644 index 8f7aa4bb4..000000000 --- a/tasks/Interrupting2.java +++ /dev/null @@ -1,53 +0,0 @@ -// tasks/Interrupting2.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Interrupting a task blocked with a ReentrantLock -import java.util.concurrent.*; -import java.util.concurrent.locks.*; - -class BlockedMutex { - private Lock lock = new ReentrantLock(); - public BlockedMutex() { - // Acquire it right away, to demonstrate interruption - // of a task blocked on a ReentrantLock: - lock.lock(); - } - public void f() { - try { - // This will never be available to a second task - lock.lockInterruptibly(); // Special call - System.out.println("lock acquired in f()"); - } catch(InterruptedException e) { - System.out.println( - "Interrupted from lock acquisition in f()"); - } - } -} - -class Blocked2 implements Runnable { - BlockedMutex blocked = new BlockedMutex(); - @Override - public void run() { - System.out.println("Waiting for f() in BlockedMutex"); - blocked.f(); - System.out.println("Broken out of blocked call"); - } -} - -public class Interrupting2 { - public static void - main(String[] args) throws Exception { - Thread t = new Thread(new Blocked2()); - t.start(); - TimeUnit.SECONDS.sleep(1); - System.out.println("Issuing t.interrupt()"); - t.interrupt(); - } -} -/* Output: -Waiting for f() in BlockedMutex -Issuing t.interrupt() -Interrupted from lock acquisition in f() -Broken out of blocked call -*/ diff --git a/tasks/InterruptingIdiom.java b/tasks/InterruptingIdiom.java deleted file mode 100644 index e976eba37..000000000 --- a/tasks/InterruptingIdiom.java +++ /dev/null @@ -1,84 +0,0 @@ -// tasks/InterruptingIdiom.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// General idiom for interrupting a task -// {Args: 1100} -import java.util.concurrent.*; - -class NeedsCleanup { - private final int id; - public NeedsCleanup(int ident) { - id = ident; - System.out.println("NeedsCleanup " + id); - } - public void cleanup() { - System.out.println("Cleaning up " + id); - } -} - -class Blocked3 implements Runnable { - private volatile double d = 0.0; - @Override - public void run() { - try { - while(!Thread.interrupted()) { - // point1 - NeedsCleanup n1 = new NeedsCleanup(1); - // Start try-finally immediately after definition - // of n1, to guarantee proper cleanup of n1: - try { - System.out.println("Sleeping"); - TimeUnit.SECONDS.sleep(1); - // point2 - NeedsCleanup n2 = new NeedsCleanup(2); - // Guarantee proper cleanup of n2: - try { - System.out.println("Calculating"); - // A time-consuming, non-blocking operation: - for(int i = 1; i < 2500000; i++) - d += (Math.PI + Math.E) / d; - System.out.println( - "Finished time-consuming operation"); - } finally { - n2.cleanup(); - } - } finally { - n1.cleanup(); - } - } - System.out.println("Exiting via while() test"); - } catch(InterruptedException e) { - System.out.println( - "Exiting via InterruptedException"); - } - } -} - -public class InterruptingIdiom { - public static void - main(String[] args) throws Exception { - if(args.length != 1) { - System.out.println( - "usage: java InterruptingIdiom delay-in-mS"); - System.exit(1); - } - Thread t = new Thread(new Blocked3()); - t.start(); - TimeUnit.MILLISECONDS.sleep(new Integer(args[0])); - t.interrupt(); - } -} -/* Output: -NeedsCleanup 1 -Sleeping -NeedsCleanup 2 -Calculating -Finished time-consuming operation -Cleaning up 2 -Cleaning up 1 -NeedsCleanup 1 -Sleeping -Cleaning up 1 -Exiting via InterruptedException -*/ diff --git a/tasks/Joining.java b/tasks/Joining.java deleted file mode 100644 index 685a280a3..000000000 --- a/tasks/Joining.java +++ /dev/null @@ -1,62 +0,0 @@ -// tasks/Joining.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Understanding join() - -class Sleeper extends Thread { - private int duration; - public Sleeper(String name, int sleepTime) { - super(name); - duration = sleepTime; - start(); - } - @Override - public void run() { - try { - sleep(duration); - } catch(InterruptedException e) { - System.out.println(getName() + - " was interrupted. " + - "isInterrupted(): " + isInterrupted()); - return; - } - System.out.println(getName() + " has awakened"); - } -} - -class Joiner extends Thread { - private Sleeper sleeper; - public Joiner(String name, Sleeper sleeper) { - super(name); - this.sleeper = sleeper; - start(); - } - @Override - public void run() { - try { - sleeper.join(); - } catch(InterruptedException e) { - System.out.println("Interrupted"); - } - System.out.println(getName() + " join completed"); - } -} - -public class Joining { - public static void main(String[] args) { - Sleeper - sleepy = new Sleeper("Sleepy", 1500), - grumpy = new Sleeper("Grumpy", 1500); - Joiner - dopey = new Joiner("Dopey", sleepy), - doc = new Joiner("Doc", grumpy); - grumpy.interrupt(); - } -} -/* Output: -Grumpy was interrupted. isInterrupted(): false -Doc join completed -Sleepy has awakened -Dopey join completed -*/ diff --git a/tasks/LiftOff.java b/tasks/LiftOff.java deleted file mode 100644 index 5995815d4..000000000 --- a/tasks/LiftOff.java +++ /dev/null @@ -1,26 +0,0 @@ -// tasks/LiftOff.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Demonstration of the Runnable interface - -public class LiftOff implements Runnable { - protected int countDown = 10; // Default - private static int taskCount = 0; - private final int id = taskCount++; - public LiftOff() {} - public LiftOff(int countDown) { - this.countDown = countDown; - } - public String status() { - return "#" + id + "(" + - (countDown > 0 ? countDown : "Liftoff!") + "), "; - } - @Override - public void run() { - while(countDown-- > 0) { - System.out.print(status()); - Thread.yield(); - } - } -} diff --git a/tasks/ListComparisons.java b/tasks/ListComparisons.java deleted file mode 100644 index ba8e1525d..000000000 --- a/tasks/ListComparisons.java +++ /dev/null @@ -1,90 +0,0 @@ -// tasks/ListComparisons.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {Args: 1 10 10} (Fast verification check during build) -// Rough comparison of thread-safe List performance -import java.util.concurrent.*; -import java.util.*; -import onjava.*; - -abstract class ListTest extends Tester> { - ListTest(String testId, int nReaders, int nWriters) { - super(testId, nReaders, nWriters); - } - class Reader extends TestTask { - long result = 0; - void test() { - for(long i = 0; i < testCycles; i++) - for(int n = 0; n < collectionSize; n++) - result += testCollection.get(n); - } - void putResults() { - readResult += result; - readTime += duration; - } - } - class Writer extends TestTask { - void test() { - for(long i = 0; i < testCycles; i++) - for(int n = 0; n < collectionSize; n++) - testCollection.set(n, writeData[n]); - } - void putResults() { - writeTime += duration; - } - } - void startReadersAndWriters() { - for(int i = 0; i < nReaders; i++) - exec.execute(new Reader()); - for(int i = 0; i < nWriters; i++) - exec.execute(new Writer()); - } -} - -class SynchronizedArrayListTest extends ListTest { - List collectionInitializer() { - return Collections.synchronizedList( - new ArrayList<>( - new CountingIntegerList(collectionSize))); - } - SynchronizedArrayListTest(int nReaders, int nWriters) { - super("Synched ArrayList", nReaders, nWriters); - } -} - -class CopyOnWriteArrayListTest extends ListTest { - List collectionInitializer() { - return new CopyOnWriteArrayList<>( - new CountingIntegerList(collectionSize)); - } - CopyOnWriteArrayListTest(int nReaders, int nWriters) { - super("CopyOnWriteArrayList", nReaders, nWriters); - } -} - -public class ListComparisons { - public static void main(String[] args) { - Tester.initMain(args); - new SynchronizedArrayListTest(10, 0); - new SynchronizedArrayListTest(9, 1); - new SynchronizedArrayListTest(5, 5); - new CopyOnWriteArrayListTest(10, 0); - new CopyOnWriteArrayListTest(9, 1); - new CopyOnWriteArrayListTest(5, 5); - Tester.exec.shutdown(); - } -} -/* Output: -Type Read time Write time -Synched ArrayList 10r 0w 700989 0 -Synched ArrayList 9r 1w 2531313 60622 -readTime + writeTime = 2591935 -Synched ArrayList 5r 5w 1396291 649761 -readTime + writeTime = 2046052 -CopyOnWriteArrayList 10r 0w 551005 0 -CopyOnWriteArrayList 9r 1w 161945 123521 -readTime + writeTime = 285466 -CopyOnWriteArrayList 5r 5w 549580 4230146 -readTime + writeTime = 4779726 -*/ diff --git a/tasks/MainThread.java b/tasks/MainThread.java deleted file mode 100644 index 3f424569c..000000000 --- a/tasks/MainThread.java +++ /dev/null @@ -1,15 +0,0 @@ -// tasks/MainThread.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. - -public class MainThread { - public static void main(String[] args) { - LiftOff launch = new LiftOff(); - launch.run(); - } -} -/* Output: -#0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), -#0(1), #0(Liftoff!), -*/ diff --git a/tasks/MapComparisons.java b/tasks/MapComparisons.java deleted file mode 100644 index 9a6b6a8e1..000000000 --- a/tasks/MapComparisons.java +++ /dev/null @@ -1,97 +0,0 @@ -// tasks/MapComparisons.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {Args: 1 10 10} (Fast verification check during build) -// Rough comparison of thread-safe Map performance -import java.util.concurrent.*; -import java.util.*; -import onjava.*; - -abstract class MapTest -extends Tester> { - MapTest(String testId, int nReaders, int nWriters) { - super(testId, nReaders, nWriters); - } - class Reader extends TestTask { - long result = 0; - void test() { - for(long i = 0; i < testCycles; i++) - for(int n = 0; n < collectionSize; n++) - result += testCollection.get(n); - } - void putResults() { - readResult += result; - readTime += duration; - } - } - class Writer extends TestTask { - void test() { - for(long i = 0; i < testCycles; i++) - for(int n = 0; n < collectionSize; n++) - testCollection.put(n, writeData[n]); - } - void putResults() { - writeTime += duration; - } - } - void startReadersAndWriters() { - for(int i = 0; i < nReaders; i++) - exec.execute(new Reader()); - for(int i = 0; i < nWriters; i++) - exec.execute(new Writer()); - } -} - -class SynchronizedHashMapTest extends MapTest { - Map collectionInitializer() { - return Collections.synchronizedMap( - new HashMap<>( - FilledMap.map( - new onjava.Count.Integer(), - new onjava.Count.Integer(), - collectionSize))); - } - SynchronizedHashMapTest(int nReaders, int nWriters) { - super("Synched HashMap", nReaders, nWriters); - } -} - -class ConcurrentHashMapTest extends MapTest { - Map collectionInitializer() { - return new ConcurrentHashMap<>( - FilledMap.map( - new onjava.Count.Integer(), - new onjava.Count.Integer(), - collectionSize)); - } - ConcurrentHashMapTest(int nReaders, int nWriters) { - super("ConcurrentHashMap", nReaders, nWriters); - } -} - -public class MapComparisons { - public static void main(String[] args) { - Tester.initMain(args); - new SynchronizedHashMapTest(10, 0); - new SynchronizedHashMapTest(9, 1); - new SynchronizedHashMapTest(5, 5); - new ConcurrentHashMapTest(10, 0); - new ConcurrentHashMapTest(9, 1); - new ConcurrentHashMapTest(5, 5); - Tester.exec.shutdown(); - } -} -/* Output: -Type Read time Write time -Synched HashMap 10r 0w 2825885 0 -Synched HashMap 9r 1w 3463976 74283 -readTime + writeTime = 3538259 -Synched HashMap 5r 5w 744537 633254 -readTime + writeTime = 1377791 -ConcurrentHashMap 10r 0w 437445 0 -ConcurrentHashMap 9r 1w 545597 78268 -readTime + writeTime = 623865 -ConcurrentHashMap 5r 5w 58343 232524 -readTime + writeTime = 290867 -*/ diff --git a/tasks/MoreBasicThreads.java b/tasks/MoreBasicThreads.java deleted file mode 100644 index 0e55d71ca..000000000 --- a/tasks/MoreBasicThreads.java +++ /dev/null @@ -1,23 +0,0 @@ -// tasks/MoreBasicThreads.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Adding more threads - -public class MoreBasicThreads { - public static void main(String[] args) { - for(int i = 0; i < 5; i++) - new Thread(new LiftOff()).start(); - System.out.println("Waiting for LiftOff"); - } -} -/* Output: -Waiting for LiftOff -#3(9), #2(9), #3(8), #2(8), #3(7), #2(7), #3(6), #2(6), -#3(5), #2(5), #3(4), #2(4), #3(3), #2(3), #3(2), #2(2), -#3(1), #2(1), #3(Liftoff!), #2(Liftoff!), #1(9), #0(9), -#4(9), #1(8), #4(8), #0(8), #1(7), #0(7), #4(7), #1(6), -#4(6), #0(6), #1(5), #0(5), #4(5), #1(4), #4(4), #0(4), -#1(3), #0(3), #4(3), #1(2), #4(2), #0(2), #1(1), #0(1), -#4(1), #0(Liftoff!), #4(Liftoff!), #1(Liftoff!), -*/ diff --git a/tasks/MultiLock.java b/tasks/MultiLock.java deleted file mode 100644 index beb718965..000000000 --- a/tasks/MultiLock.java +++ /dev/null @@ -1,44 +0,0 @@ -// tasks/MultiLock.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// One thread can reacquire the same lock - -public class MultiLock { - public synchronized void f1(int count) { - if(count-- > 0) { - System.out.println( - "f1() calling f2() with count " + count); - f2(count); - } - } - public synchronized void f2(int count) { - if(count-- > 0) { - System.out.println( - "f2() calling f1() with count " + count); - f1(count); - } - } - public static void - main(String[] args) throws Exception { - final MultiLock multiLock = new MultiLock(); - new Thread() { - @Override - public void run() { - multiLock.f1(10); - } - }.start(); - } -} -/* Output: -f1() calling f2() with count 9 -f2() calling f1() with count 8 -f1() calling f2() with count 7 -f2() calling f1() with count 6 -f1() calling f2() with count 5 -f2() calling f1() with count 4 -f1() calling f2() with count 3 -f2() calling f1() with count 2 -f1() calling f2() with count 1 -f2() calling f1() with count 0 -*/ diff --git a/tasks/NIOInterruption.java b/tasks/NIOInterruption.java deleted file mode 100644 index 90c7ce8fd..000000000 --- a/tasks/NIOInterruption.java +++ /dev/null @@ -1,59 +0,0 @@ -// tasks/NIOInterruption.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Interrupting a blocked NIO channel -import java.net.*; -import java.nio.*; -import java.nio.channels.*; -import java.util.concurrent.*; -import java.io.*; - -class NIOBlocked implements Runnable { - private final SocketChannel sc; - public NIOBlocked(SocketChannel sc) { this.sc = sc; } - @Override - public void run() { - try { - System.out.println("Waiting for read() in " + this); - sc.read(ByteBuffer.allocate(1)); - } catch(ClosedByInterruptException e) { - System.out.println("ClosedByInterruptException"); - } catch(AsynchronousCloseException e) { - System.out.println("AsynchronousCloseException"); - } catch(IOException e) { - throw new RuntimeException(e); - } - System.out.println( - "Exiting NIOBlocked.run() " + this); - } -} - -public class NIOInterruption { - public static void - main(String[] args) throws Exception { - ExecutorService es = Executors.newCachedThreadPool(); - InetSocketAddress isa = - new InetSocketAddress("localhost", 8080); - try(ServerSocket server = new ServerSocket(8080); - SocketChannel sc1 = SocketChannel.open(isa); - SocketChannel sc2 = SocketChannel.open(isa)) { - Future f = es.submit(new NIOBlocked(sc1)); - es.execute(new NIOBlocked(sc2)); - es.shutdown(); - TimeUnit.SECONDS.sleep(1); - // Produce an interrupt via cancel: - f.cancel(true); - TimeUnit.SECONDS.sleep(1); - // Release the block by closing the channel: - } - } -} -/* Output: -Waiting for read() in NIOBlocked@122af49 -Waiting for read() in NIOBlocked@1feeb4a -ClosedByInterruptException -Exiting NIOBlocked.run() NIOBlocked@122af49 -AsynchronousCloseException -Exiting NIOBlocked.run() NIOBlocked@1feeb4a -*/ diff --git a/tasks/NaiveExceptionHandling.java b/tasks/NaiveExceptionHandling.java deleted file mode 100644 index 919a396d1..000000000 --- a/tasks/NaiveExceptionHandling.java +++ /dev/null @@ -1,20 +0,0 @@ -// tasks/NaiveExceptionHandling.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {ValidateByHand} -// {ThrowsException} -import java.util.concurrent.*; - -public class NaiveExceptionHandling { - public static void main(String[] args) { - try { - ExecutorService exec = - Executors.newCachedThreadPool(); - exec.execute(new ExceptionThread()); - } catch(RuntimeException ue) { - // This statement will NOT execute! - System.out.println("Exception was handled!"); - } - } -} diff --git a/tasks/NotifyVsNotifyAll.java b/tasks/NotifyVsNotifyAll.java deleted file mode 100644 index 76ad54911..000000000 --- a/tasks/NotifyVsNotifyAll.java +++ /dev/null @@ -1,110 +0,0 @@ -// tasks/NotifyVsNotifyAll.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.concurrent.*; -import java.util.*; - -class Blocker { - synchronized void waitingCall() { - try { - while(!Thread.interrupted()) { - wait(); - System.out.print(Thread.currentThread() + " "); - } - } catch(InterruptedException e) { - // OK to exit this way - } - } - synchronized void prod() { notify(); } - synchronized void prodAll() { notifyAll(); } -} - -class Task implements Runnable { - static Blocker blocker = new Blocker(); - @Override - public void run() { blocker.waitingCall(); } -} - -class Task2 implements Runnable { - // A separate Blocker object: - static Blocker blocker = new Blocker(); - @Override - public void run() { blocker.waitingCall(); } -} - -public class NotifyVsNotifyAll { - public static void - main(String[] args) throws Exception { - ExecutorService es = Executors.newCachedThreadPool(); - for(int i = 0; i < 5; i++) - es.execute(new Task()); - es.execute(new Task2()); - Timer timer = new Timer(); - timer.scheduleAtFixedRate(new TimerTask() { - boolean prod = true; - @Override - public void run() { - if(prod) { - System.out.print("\nnotify() "); - Task.blocker.prod(); - prod = false; - } else { - System.out.print("\nnotifyAll() "); - Task.blocker.prodAll(); - prod = true; - } - } - }, 400, 400); // Run every .4 second - TimeUnit.SECONDS.sleep(5); // Run for a while... - timer.cancel(); - System.out.println("\nTimer canceled"); - TimeUnit.MILLISECONDS.sleep(500); - System.out.print("Task2.blocker.prodAll() "); - Task2.blocker.prodAll(); - TimeUnit.MILLISECONDS.sleep(500); - System.out.println("\nShutting down"); - es.shutdownNow(); // Interrupt all tasks - } -} -/* Output: -notify() Thread[pool-1-thread-1,5,main] -notifyAll() Thread[pool-1-thread-1,5,main] -Thread[pool-1-thread-5,5,main] -Thread[pool-1-thread-4,5,main] -Thread[pool-1-thread-3,5,main] -Thread[pool-1-thread-2,5,main] -notify() Thread[pool-1-thread-1,5,main] -notifyAll() Thread[pool-1-thread-1,5,main] -Thread[pool-1-thread-2,5,main] -Thread[pool-1-thread-3,5,main] -Thread[pool-1-thread-4,5,main] -Thread[pool-1-thread-5,5,main] -notify() Thread[pool-1-thread-1,5,main] -notifyAll() Thread[pool-1-thread-1,5,main] -Thread[pool-1-thread-5,5,main] -Thread[pool-1-thread-4,5,main] -Thread[pool-1-thread-3,5,main] -Thread[pool-1-thread-2,5,main] -notify() Thread[pool-1-thread-1,5,main] -notifyAll() Thread[pool-1-thread-1,5,main] -Thread[pool-1-thread-2,5,main] -Thread[pool-1-thread-3,5,main] -Thread[pool-1-thread-4,5,main] -Thread[pool-1-thread-5,5,main] -notify() Thread[pool-1-thread-1,5,main] -notifyAll() Thread[pool-1-thread-1,5,main] -Thread[pool-1-thread-5,5,main] -Thread[pool-1-thread-4,5,main] -Thread[pool-1-thread-3,5,main] -Thread[pool-1-thread-2,5,main] -notify() Thread[pool-1-thread-1,5,main] -notifyAll() Thread[pool-1-thread-1,5,main] -Thread[pool-1-thread-2,5,main] -Thread[pool-1-thread-3,5,main] -Thread[pool-1-thread-4,5,main] -Thread[pool-1-thread-5,5,main] -Timer canceled -Task2.blocker.prodAll() Thread[pool-1-thread-6,5,main] -Shutting down -*/ diff --git a/tasks/OrnamentalGarden.java b/tasks/OrnamentalGarden.java deleted file mode 100644 index 054acdffc..000000000 --- a/tasks/OrnamentalGarden.java +++ /dev/null @@ -1,110 +0,0 @@ -// tasks/OrnamentalGarden.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.concurrent.*; -import java.util.*; - -class Count { - private int count = 0; - private SplittableRandom rand = new SplittableRandom(47); - // Remove the synchronized keyword to see counting fail: - public synchronized int increment() { - int temp = count; - if(rand.nextBoolean()) // Yield half the time - Thread.yield(); - return (count = ++temp); - } - public synchronized int value() { return count; } -} - -class Entrance implements Runnable { - private static Count count = new Count(); - private static List entrances = - new ArrayList<>(); - private int number = 0; - // Doesn't need synchronization to read: - private final int id; - private static volatile boolean canceled = false; - // Atomic operation on a volatile field: - public static void cancel() { canceled = true; } - public Entrance(int id) { - this.id = id; - // Keep this task in a list. Also prevents - // garbage collection of dead tasks: - entrances.add(this); - } - @Override - public void run() { - while(!canceled) { - synchronized(this) { - ++number; - } - System.out.println( - this + " Total: " + count.increment()); - try { - TimeUnit.MILLISECONDS.sleep(100); - } catch(InterruptedException e) { - System.out.println("sleep interrupted"); - } - } - System.out.println("Stopping " + this); - } - public synchronized int getValue() { return number; } - @Override - public String toString() { - return "Entrance " + id + ": " + getValue(); - } - public static int getTotalCount() { - return count.value(); - } - public static int sumEntrances() { - int sum = 0; - for(Entrance entrance : entrances) - sum += entrance.getValue(); - return sum; - } -} - -public class OrnamentalGarden { - public static void - main(String[] args) throws Exception { - ExecutorService es = Executors.newCachedThreadPool(); - for(int i = 0; i < 5; i++) - es.execute(new Entrance(i)); - // Run for a while, then stop and collect the data: - TimeUnit.SECONDS.sleep(3); - Entrance.cancel(); - es.shutdown(); - if(!es.awaitTermination(250, TimeUnit.MILLISECONDS)) - System.out.println( - "Some tasks were not terminated!"); - System.out.println( - "Total: " + Entrance.getTotalCount()); - System.out.println( - "Sum of Entrances: " + Entrance.sumEntrances()); - } -} -/* Output: (First and last 10 Lines) -Entrance 0: 1 Total: 1 -Entrance 1: 1 Total: 2 -Entrance 4: 1 Total: 5 -Entrance 3: 1 Total: 3 -Entrance 2: 1 Total: 4 -Entrance 0: 2 Total: 6 -Entrance 1: 2 Total: 7 -Entrance 4: 2 Total: 8 -Entrance 2: 2 Total: 10 -Entrance 3: 2 Total: 9 -________...________...________...________...________ -Entrance 4: 30 Total: 147 -Entrance 2: 30 Total: 149 -Entrance 3: 30 Total: 150 -Stopping Entrance 0: 30 -Stopping Entrance 1: 30 -Stopping Entrance 4: 30 -Stopping Entrance 2: 30 -Stopping Entrance 3: 30 -Total: 150 -Sum of Entrances: 150 -*/ diff --git a/tasks/Philosopher.java b/tasks/Philosopher.java deleted file mode 100644 index 0b6986425..000000000 --- a/tasks/Philosopher.java +++ /dev/null @@ -1,50 +0,0 @@ -// tasks/Philosopher.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// A dining philosopher -import java.util.concurrent.*; -import java.util.*; - -public class Philosopher implements Runnable { - private Chopstick left; - private Chopstick right; - private final int id; - private final int ponderFactor; - private SplittableRandom rand = new SplittableRandom(47); - private void pause() throws InterruptedException { - if(ponderFactor == 0) return; - TimeUnit.MILLISECONDS.sleep( - rand.nextInt(ponderFactor * 250)); - } - public Philosopher(Chopstick left, Chopstick right, - int ident, int ponder) { - this.left = left; - this.right = right; - id = ident; - ponderFactor = ponder; - } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - System.out.println(this + " " + "thinking"); - pause(); - // Philosopher becomes hungry - System.out.println(this + " " + "grabbing right"); - right.take(); - System.out.println(this + " " + "grabbing left"); - left.take(); - System.out.println(this + " " + "eating"); - pause(); - right.drop(); - left.drop(); - } - } catch(InterruptedException e) { - System.out.println( - this + " " + "exiting via interrupt"); - } - } - @Override - public String toString() { return "Philosopher " + id; } -} diff --git a/tasks/PipedIO.java b/tasks/PipedIO.java deleted file mode 100644 index 34d8d67ac..000000000 --- a/tasks/PipedIO.java +++ /dev/null @@ -1,67 +0,0 @@ -// tasks/PipedIO.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Using pipes for inter-task I/O -import java.util.concurrent.*; -import java.io.*; -import java.util.*; - -class Sender implements Runnable { - private SplittableRandom rand = new SplittableRandom(47); - private PipedWriter out = new PipedWriter(); - public PipedWriter getPipedWriter() { return out; } - @Override - public void run() { - try { - while(true) - for(char c = 'A'; c <= 'z'; c++) { - out.write(c); - TimeUnit.MILLISECONDS.sleep(rand.nextInt(500)); - } - } catch(IOException e) { - System.out.println(e + " Sender write exception"); - } catch(InterruptedException e) { - System.out.println(e + " Sender sleep interrupted"); - } - } -} - -class Receiver implements Runnable { - private PipedReader in; - public Receiver(Sender sender) throws IOException { - in = new PipedReader(sender.getPipedWriter()); - } - @Override - public void run() { - try { - while(true) { - // Blocks until characters are there: - System.out.print( - "Read: " + (char)in.read() + ", "); - } - } catch(IOException e) { - System.out.println(e + " Receiver read exception"); - } - } -} - -public class PipedIO { - public static void - main(String[] args) throws Exception { - Sender sender = new Sender(); - Receiver receiver = new Receiver(sender); - ExecutorService es = Executors.newCachedThreadPool(); - es.execute(sender); - es.execute(receiver); - TimeUnit.SECONDS.sleep(4); - es.shutdownNow(); - } -} -/* Output: -Read: A, Read: B, Read: C, Read: D, Read: E, Read: F, Read: -G, Read: H, Read: I, Read: J, Read: K, Read: L, Read: M, -java.lang.InterruptedException: sleep interrupted Sender -sleep interrupted -java.io.InterruptedIOException Receiver read exception -*/ diff --git a/tasks/Pool.java b/tasks/Pool.java deleted file mode 100644 index 5ca71d15a..000000000 --- a/tasks/Pool.java +++ /dev/null @@ -1,54 +0,0 @@ -// tasks/Pool.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Using a Semaphore inside a Pool, to restrict -// the number of tasks that can use a resource -import java.util.concurrent.*; -import java.util.*; - -public class Pool { - private int size; - private List items = new ArrayList<>(); - private volatile boolean[] checkedOut; - private Semaphore available; - public Pool(Class classObject, int size) { - this.size = size; - checkedOut = new boolean[size]; - available = new Semaphore(size, true); - // Load pool with objects that can be checked out: - for(int i = 0; i < size; ++i) - try { - // Assumes a no-arg constructor: - items.add(classObject.newInstance()); - } catch(InstantiationException | - IllegalAccessException e) { - throw new RuntimeException(e); - } - } - public T checkOut() throws InterruptedException { - available.acquire(); - return getItem(); - } - public void checkIn(T x) { - if(releaseItem(x)) - available.release(); - } - private synchronized T getItem() { - for(int i = 0; i < size; ++i) - if(!checkedOut[i]) { - checkedOut[i] = true; - return items.get(i); - } - return null; // Semaphore prevents reaching here - } - private synchronized boolean releaseItem(T item) { - int index = items.indexOf(item); - if(index == -1) return false; // Not in the list - if(checkedOut[index]) { - checkedOut[index] = false; - return true; - } - return false; // Wasn't checked out - } -} diff --git a/tasks/PriorityBlockingQueueDemo.java b/tasks/PriorityBlockingQueueDemo.java deleted file mode 100644 index 00c8c764c..000000000 --- a/tasks/PriorityBlockingQueueDemo.java +++ /dev/null @@ -1,156 +0,0 @@ -// tasks/PriorityBlockingQueueDemo.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.concurrent.*; -import java.util.*; - -class PrioritizedTask implements -Runnable, Comparable { - private SplittableRandom rand = new SplittableRandom(47); - private static int counter = 0; - private final int id = counter++; - private final int priority; - protected static List sequence = - new ArrayList<>(); - public PrioritizedTask(int priority) { - this.priority = priority; - sequence.add(this); - } - @Override - public int compareTo(PrioritizedTask arg) { - return priority < arg.priority ? 1 : - (priority > arg.priority ? -1 : 0); - } - @Override - public void run() { - try { - TimeUnit.MILLISECONDS.sleep(rand.nextInt(250)); - } catch(InterruptedException e) { - // Acceptable way to exit - } - System.out.println(this); - } - @Override - public String toString() { - return String.format("[%1$-3d]", priority) + - " Task " + id; - } - public String summary() { - return "(" + id + ":" + priority + ")"; - } - public static - class EndSentinel extends PrioritizedTask { - private ExecutorService exec; - public EndSentinel(ExecutorService e) { - super(-1); // Lowest priority in this program - exec = e; - } - @Override - public void run() { - int count = 0; - for(PrioritizedTask pt : sequence) { - System.out.print(pt.summary()); - if(++count % 5 == 0) - System.out.println(); - } - System.out.println(); - System.out.println(this + " Calling shutdownNow()"); - exec.shutdownNow(); - } - } -} - -class PrioritizedTaskProducer implements Runnable { - private SplittableRandom rand = new SplittableRandom(47); - private Queue queue; - private ExecutorService exec; - public PrioritizedTaskProducer( - Queue q, ExecutorService e) { - queue = q; - exec = e; // Used for EndSentinel - } - @Override - public void run() { - // Unbounded queue; never blocks. - // Fill it up fast with random priorities: - for(int i = 0; i < 20; i++) { - queue.add(new PrioritizedTask(rand.nextInt(10))); - Thread.yield(); - } - // Trickle in highest-priority jobs: - try { - for(int i = 0; i < 10; i++) { - TimeUnit.MILLISECONDS.sleep(250); - queue.add(new PrioritizedTask(10)); - } - // Add jobs, lowest priority first: - for(int i = 0; i < 10; i++) - queue.add(new PrioritizedTask(i)); - // A sentinel to stop all the tasks: - queue.add(new PrioritizedTask.EndSentinel(exec)); - } catch(InterruptedException e) { - // Acceptable way to exit - } - System.out.println( - "Finished PrioritizedTaskProducer"); - } -} - -class PrioritizedTaskConsumer implements Runnable { - private PriorityBlockingQueue q; - public PrioritizedTaskConsumer( - PriorityBlockingQueue q) { - this.q = q; - } - @Override - public void run() { - try { - while(!Thread.interrupted()) - // Use current thread to run the task: - q.take().run(); - } catch(InterruptedException e) { - // Acceptable way to exit - } - System.out.println( - "Finished PrioritizedTaskConsumer"); - } -} - -public class PriorityBlockingQueueDemo { - public static void - main(String[] args) throws Exception { - ExecutorService es = Executors.newCachedThreadPool(); - PriorityBlockingQueue queue = - new PriorityBlockingQueue<>(); - es.execute(new PrioritizedTaskProducer(queue, es)); - es.execute(new PrioritizedTaskConsumer(queue)); - } -} -/* Output: (First and last 12 Lines) -[8 ] Task 0 -[9 ] Task 5 -[9 ] Task 13 -[9 ] Task 14 -[8 ] Task 10 -[8 ] Task 16 -[8 ] Task 19 -[8 ] Task 11 -[8 ] Task 6 -[8 ] Task 15 -[7 ] Task 9 -[5 ] Task 1 -________...________...________...________...________ -[0 ] Task 30 -(0:8)(1:5)(2:3)(3:1)(4:1) -(5:9)(6:8)(7:0)(8:2)(9:7) -(10:8)(11:8)(12:1)(13:9)(14:9) -(15:8)(16:8)(17:1)(18:0)(19:8) -(20:10)(21:10)(22:10)(23:10)(24:10) -(25:10)(26:10)(27:10)(28:10)(29:10) -(30:0)(31:1)(32:2)(33:3)(34:4) -(35:5)(36:6)(37:7)(38:8)(39:9) -(40:-1) -[-1 ] Task 40 Calling shutdownNow() -Finished PrioritizedTaskConsumer -*/ diff --git a/tasks/ReaderWriterList.java b/tasks/ReaderWriterList.java deleted file mode 100644 index d54584d07..000000000 --- a/tasks/ReaderWriterList.java +++ /dev/null @@ -1,112 +0,0 @@ -// tasks/ReaderWriterList.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.concurrent.*; -import java.util.concurrent.locks.*; -import java.util.*; - -public class ReaderWriterList { - private ArrayList lockedList; - // Make the ordering fair: - private ReentrantReadWriteLock lock = - new ReentrantReadWriteLock(true); - public ReaderWriterList(int size, T initialValue) { - lockedList = new ArrayList<>( - Collections.nCopies(size, initialValue)); - } - public T set(int index, T element) { - Lock wlock = lock.writeLock(); - wlock.lock(); - try { - return lockedList.set(index, element); - } finally { - wlock.unlock(); - } - } - public T get(int index) { - Lock rlock = lock.readLock(); - rlock.lock(); - try { - // Show that multiple readers - // can acquire the read lock: - if(lock.getReadLockCount() > 1) - System.out.println(lock.getReadLockCount()); - return lockedList.get(index); - } finally { - rlock.unlock(); - } - } - public static void - main(String[] args) throws Exception { - new ReaderWriterListTest(30, 1); - } -} - -class ReaderWriterListTest { - ExecutorService exec = Executors.newCachedThreadPool(); - private final static int SIZE = 100; - private static SplittableRandom rand = new SplittableRandom(47); - private ReaderWriterList list = - new ReaderWriterList<>(SIZE, 0); - private class Writer implements Runnable { - @Override - public void run() { - try { - for(int i = 0; i < 20; i++) { // 2 second test - list.set(i, rand.nextInt()); - TimeUnit.MILLISECONDS.sleep(100); - } - } catch(InterruptedException e) { - // Acceptable way to exit - } - System.out.println( - "Writer finished, shutting down"); - exec.shutdownNow(); - } - } - private class Reader implements Runnable { - @Override - public void run() { - try { - while(!Thread.interrupted()) { - for(int i = 0; i < SIZE; i++) { - list.get(i); - TimeUnit.MILLISECONDS.sleep(1); - } - } - } catch(InterruptedException e) { - // Acceptable way to exit - } - } - } - public ReaderWriterListTest(int readers, int writers) { - for(int i = 0; i < readers; i++) - exec.execute(new Reader()); - for(int i = 0; i < writers; i++) - exec.execute(new Writer()); - } -} -/* Output: (First and last 10 Lines) -6 -15 -14 -13 -12 -11 -10 -9 -8 -5 -________...________...________...________...________ -21 -30 -29 -28 -28 -30 -29 -28 -27 -26 -*/ diff --git a/tasks/ResponsiveUI.java b/tasks/ResponsiveUI.java deleted file mode 100644 index 732dc782e..000000000 --- a/tasks/ResponsiveUI.java +++ /dev/null @@ -1,36 +0,0 @@ -// tasks/ResponsiveUI.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// User interface responsiveness -// {TimeOutDuringTesting} - -class UnresponsiveUI { - private volatile double d = 1; - public UnresponsiveUI() throws Exception { - while(d > 0) - d += (Math.PI + Math.E) / d; - System.in.read(); // Never gets here - } -} - -public class ResponsiveUI extends Thread { - private static volatile double d = 1; - public ResponsiveUI() { - setDaemon(true); - start(); - } - @Override - public void run() { - while(true) { - d += (Math.PI + Math.E) / d; - } - } - public static void - main(String[] args) throws Exception { - //- new UnresponsiveUI(); // Must kill this process - new ResponsiveUI(); - System.in.read(); - System.out.println(d); // Shows progress - } -} diff --git a/tasks/Restaurant.java b/tasks/Restaurant.java deleted file mode 100644 index caf37d28d..000000000 --- a/tasks/Restaurant.java +++ /dev/null @@ -1,94 +0,0 @@ -// tasks/Restaurant.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// The producer-consumer approach to task cooperation -import java.util.concurrent.*; - -class Meal { - private final int orderNum; - public Meal(int orderNum) { this.orderNum = orderNum; } - @Override - public String toString() { return "Meal " + orderNum; } -} - -class WaitPerson implements Runnable { - private Restaurant restaurant; - public WaitPerson(Restaurant r) { restaurant = r; } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - synchronized(this) { - while(restaurant.meal == null) - wait(); // ... for the chef to produce a meal - } - System.out.println( - "Waitperson got " + restaurant.meal); - synchronized(restaurant.chef) { - restaurant.meal = null; - restaurant.chef.notifyAll(); // Ready for more - } - } - } catch(InterruptedException e) { - System.out.println("WaitPerson interrupted"); - } - } -} - -class Chef implements Runnable { - private Restaurant restaurant; - private int count = 0; - public Chef(Restaurant r) { restaurant = r; } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - synchronized(this) { - while(restaurant.meal != null) - wait(); // ... for the meal to be taken - } - if(++count == 10) { - System.out.println("Out of food, closing"); - restaurant.exec.shutdownNow(); - } - System.out.print("Order up! "); - synchronized(restaurant.waitPerson) { - restaurant.meal = new Meal(count); - restaurant.waitPerson.notifyAll(); - } - TimeUnit.MILLISECONDS.sleep(100); - } - } catch(InterruptedException e) { - System.out.println("Chef interrupted"); - } - } -} - -public class Restaurant { - Meal meal; - ExecutorService exec = Executors.newCachedThreadPool(); - WaitPerson waitPerson = new WaitPerson(this); - Chef chef = new Chef(this); - public Restaurant() { - exec.execute(chef); - exec.execute(waitPerson); - } - public static void main(String[] args) { - new Restaurant(); - } -} -/* Output: -Order up! Waitperson got Meal 1 -Order up! Waitperson got Meal 2 -Order up! Waitperson got Meal 3 -Order up! Waitperson got Meal 4 -Order up! Waitperson got Meal 5 -Order up! Waitperson got Meal 6 -Order up! Waitperson got Meal 7 -Order up! Waitperson got Meal 8 -Order up! Waitperson got Meal 9 -Out of food, closing -Order up! WaitPerson interrupted -Chef interrupted -*/ diff --git a/tasks/SelfManaged.java b/tasks/SelfManaged.java deleted file mode 100644 index e6f5e2468..000000000 --- a/tasks/SelfManaged.java +++ /dev/null @@ -1,37 +0,0 @@ -// tasks/SelfManaged.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// A Runnable containing its own driver Thread - -public class SelfManaged implements Runnable { - private int countDown = 5; - private Thread t = new Thread(this); - public SelfManaged() { t.start(); } - @Override - public String toString() { - return Thread.currentThread().getName() + - "(" + countDown + "), "; - } - @Override - public void run() { - while(true) { - System.out.print(this); - if(--countDown == 0) - return; - } - } - public static void main(String[] args) { - for(int i = 0; i < 5; i++) - new SelfManaged(); - } -} -/* Output: -Thread-0(5), Thread-4(5), Thread-3(5), Thread-1(5), -Thread-2(5), Thread-2(4), Thread-2(3), Thread-1(4), -Thread-3(4), Thread-4(4), Thread-0(4), Thread-4(3), -Thread-3(3), Thread-1(3), Thread-2(2), Thread-1(2), -Thread-3(2), Thread-4(2), Thread-0(3), Thread-4(1), -Thread-3(1), Thread-1(1), Thread-2(1), Thread-0(2), -Thread-0(1), -*/ diff --git a/tasks/SemaphoreDemo.java b/tasks/SemaphoreDemo.java deleted file mode 100644 index ad745e73c..000000000 --- a/tasks/SemaphoreDemo.java +++ /dev/null @@ -1,98 +0,0 @@ -// tasks/SemaphoreDemo.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Testing the Pool class -import java.util.concurrent.*; -import java.util.*; - -// A task to check a resource out of a pool: -class CheckoutTask implements Runnable { - private static int counter = 0; - private final int id = counter++; - private Pool pool; - public CheckoutTask(Pool pool) { - this.pool = pool; - } - @Override - public void run() { - try { - T item = pool.checkOut(); - System.out.println(this + "checked out " + item); - TimeUnit.SECONDS.sleep(1); - System.out.println(this +"checking in " + item); - pool.checkIn(item); - } catch(InterruptedException e) { - // Acceptable way to terminate - } - } - @Override - public String toString() { - return "CheckoutTask " + id + " "; - } -} - -public class SemaphoreDemo { - final static int SIZE = 25; - public static void - main(String[] args) throws Exception { - final Pool pool = new Pool<>(Fat.class, SIZE); - ExecutorService es = Executors.newCachedThreadPool(); - for(int i = 0; i < SIZE; i++) - es.execute(new CheckoutTask<>(pool)); - System.out.println("All CheckoutTasks created"); - List list = new ArrayList<>(); - for(int i = 0; i < SIZE; i++) { - Fat f = pool.checkOut(); - System.out.print( - i + ": main() thread checked out "); - f.operation(); - list.add(f); - } - Future blocked = es.submit(() -> { - try { - // Semaphore prevents additional checkout, - // so call is blocked: - pool.checkOut(); - } catch(InterruptedException e) { - System.out.println("checkOut() Interrupted"); - } - }); - TimeUnit.SECONDS.sleep(2); - blocked.cancel(true); // Break out of blocked call - System.out.println("Checking in objects in " + list); - for(Fat f : list) - pool.checkIn(f); - for(Fat f : list) - pool.checkIn(f); // Second checkIn ignored - es.shutdown(); - } -} -/* Output: (First and last 10 Lines) -CheckoutTask 4 checked out Fat id: 2 -CheckoutTask 22 checked out Fat id: 24 -CheckoutTask 14 checked out Fat id: 23 -CheckoutTask 21 checked out Fat id: 22 -CheckoutTask 18 checked out Fat id: 21 -CheckoutTask 17 checked out Fat id: 20 -CheckoutTask 10 checked out Fat id: 19 -CheckoutTask 13 checked out Fat id: 18 -CheckoutTask 9 checked out Fat id: 17 -CheckoutTask 6 checked out Fat id: 16 -________...________...________...________...________ -20: main() thread checked out Fat id: 5 -21: main() thread checked out Fat id: 1 -CheckoutTask 7 checking in Fat id: 3 -CheckoutTask 0 checking in Fat id: 0 -CheckoutTask 8 checking in Fat id: 4 -22: main() thread checked out Fat id: 3 -23: main() thread checked out Fat id: 0 -24: main() thread checked out Fat id: 4 -checkOut() Interrupted -Checking in objects in [Fat id: 2, Fat id: 23, Fat id: 24, -Fat id: 22, Fat id: 21, Fat id: 20, Fat id: 19, Fat id: 18, -Fat id: 17, Fat id: 16, Fat id: 15, Fat id: 14, Fat id: 13, -Fat id: 11, Fat id: 12, Fat id: 9, Fat id: 10, Fat id: 8, -Fat id: 7, Fat id: 6, Fat id: 5, Fat id: 1, Fat id: 3, Fat -id: 0, Fat id: 4] -*/ diff --git a/tasks/SerialNumberChecker.java b/tasks/SerialNumberChecker.java deleted file mode 100644 index 5c17371c8..000000000 --- a/tasks/SerialNumberChecker.java +++ /dev/null @@ -1,70 +0,0 @@ -// tasks/SerialNumberChecker.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Operations that might seem safe are not, -// when threads are present -// {Args: 4} -import java.util.concurrent.*; - -// Reuses storage so we don't run out of memory: -class CircularSet { - private int[] array; - private int len; - private int index = 0; - public CircularSet(int size) { - array = new int[size]; - len = size; - // Initialize to a value not produced - // by the SerialNumberSupplier: - for(int i = 0; i < size; i++) - array[i] = -1; - } - public synchronized void add(int i) { - array[index] = i; - // Wrap index and write over old elements: - index = ++index % len; - } - public synchronized boolean contains(int val) { - for(int i = 0; i < len; i++) - if(array[i] == val) return true; - return false; - } -} - -public class SerialNumberChecker { - private static final int SIZE = 10; - private static CircularSet serials = - new CircularSet(1000); - private static ExecutorService exec = - Executors.newCachedThreadPool(); - static class SerialChecker implements Runnable { - @Override - public void run() { - while(true) { - int serial = - SerialNumberSupplier.nextSerialNumber(); - if(serials.contains(serial)) { - System.out.println("Duplicate: " + serial); - System.exit(0); - } - serials.add(serial); - } - } - } - public static void - main(String[] args) throws Exception { - for(int i = 0; i < SIZE; i++) - exec.execute(new SerialChecker()); - // Stop after n seconds if there's an argument: - if(args.length > 0) { - TimeUnit.SECONDS.sleep(new Integer(args[0])); - System.out.println("No duplicates detected"); - System.exit(0); - } - } -} -/* Output: -Duplicate: 5453 -Duplicate: 5639 -*/ diff --git a/tasks/SerialNumberSupplier.java b/tasks/SerialNumberSupplier.java deleted file mode 100644 index a73ae120c..000000000 --- a/tasks/SerialNumberSupplier.java +++ /dev/null @@ -1,11 +0,0 @@ -// tasks/SerialNumberSupplier.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. - -public class SerialNumberSupplier { - private static volatile int serialNumber = 0; - public static int nextSerialNumber() { - return serialNumber++; // Not thread-safe - } -} diff --git a/tasks/SimpleDaemons.java b/tasks/SimpleDaemons.java deleted file mode 100644 index 6906275f6..000000000 --- a/tasks/SimpleDaemons.java +++ /dev/null @@ -1,44 +0,0 @@ -// tasks/SimpleDaemons.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Daemon threads don't prevent the program from ending -import java.util.concurrent.*; - -public class SimpleDaemons implements Runnable { - @Override - public void run() { - try { - while(true) { - TimeUnit.MILLISECONDS.sleep(100); - System.out.println( - Thread.currentThread() + " " + this); - } - } catch(InterruptedException e) { - System.out.println("sleep() interrupted"); - } - } - public static void - main(String[] args) throws Exception { - for(int i = 0; i < 10; i++) { - Thread daemon = new Thread(new SimpleDaemons()); - daemon.setDaemon(true); // Must call before start() - daemon.start(); - } - System.out.println("All daemons started"); - TimeUnit.MILLISECONDS.sleep(175); - } -} -/* Output: -All daemons started -Thread[Thread-6,5,main] SimpleDaemons@b87187 -Thread[Thread-4,5,main] SimpleDaemons@1fb28c1 -Thread[Thread-8,5,main] SimpleDaemons@8ebcf -Thread[Thread-7,5,main] SimpleDaemons@54761d -Thread[Thread-9,5,main] SimpleDaemons@156afef -Thread[Thread-0,5,main] SimpleDaemons@1320c4d -Thread[Thread-3,5,main] SimpleDaemons@4683f2 -Thread[Thread-2,5,main] SimpleDaemons@4f80f2 -Thread[Thread-5,5,main] SimpleDaemons@29c11d -Thread[Thread-1,5,main] SimpleDaemons@9df74c -*/ diff --git a/tasks/SimpleMicroBenchmark.java b/tasks/SimpleMicroBenchmark.java deleted file mode 100644 index c394494f9..000000000 --- a/tasks/SimpleMicroBenchmark.java +++ /dev/null @@ -1,52 +0,0 @@ -// tasks/SimpleMicroBenchmark.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// The dangers of microbenchmarking -import java.util.concurrent.locks.*; - -abstract class Incrementable { - protected long counter = 0; - public abstract void increment(); -} - -class SynchronizingTest extends Incrementable { - @Override - public synchronized void increment() { ++counter; } -} - -class LockingTest extends Incrementable { - private Lock lock = new ReentrantLock(); - @Override - public void increment() { - lock.lock(); - try { - ++counter; - } finally { - lock.unlock(); - } - } -} - -public class SimpleMicroBenchmark { - static long test(Incrementable incr) { - long start = System.nanoTime(); - for(long i = 0; i < 10000000L; i++) - incr.increment(); - return System.nanoTime() - start; - } - public static void main(String[] args) { - long synchTime = test(new SynchronizingTest()); - long lockTime = test(new LockingTest()); - System.out.printf( - "synchronized: %1$10d\n", synchTime); - System.out.printf("Lock: %1$10d\n", lockTime); - System.out.printf("Lock/synchronized = %1$.3f", - (double)lockTime/(double)synchTime); - } -} -/* Output: -synchronized: 243572959 -Lock: 365176719 -Lock/synchronized = 1.499 -*/ diff --git a/tasks/SimplePriorities.java b/tasks/SimplePriorities.java deleted file mode 100644 index 0bc001dc3..000000000 --- a/tasks/SimplePriorities.java +++ /dev/null @@ -1,55 +0,0 @@ -// tasks/SimplePriorities.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Shows thread priorities -import java.util.concurrent.*; - -public class SimplePriorities implements Runnable { - private int countDown = 5; - private volatile double d; // No optimization - private int priority; - public SimplePriorities(int priority) { - this.priority = priority; - } - @Override - public String toString() { - return Thread.currentThread() + ": " + countDown; - } - @Override - public void run() { - Thread.currentThread().setPriority(priority); - while(true) { - // An expensive, interruptable operation: - for(int i = 1; i < 100000; i++) { - d += (Math.PI + Math.E) / (double)i; - if(i % 1000 == 0) - Thread.yield(); - } - System.out.println(this); - if(--countDown == 0) return; - } - } - public static void main(String[] args) { - ExecutorService es = Executors.newCachedThreadPool(); - for(int i = 0; i < 5; i++) - es.execute( - new SimplePriorities(Thread.MIN_PRIORITY)); - es.execute( - new SimplePriorities(Thread.MAX_PRIORITY)); - es.shutdown(); - } -} -/* Output: (First 10 Lines) -Thread[pool-1-thread-6,10,main]: 5 -Thread[pool-1-thread-1,1,main]: 5 -Thread[pool-1-thread-4,1,main]: 5 -Thread[pool-1-thread-5,1,main]: 5 -Thread[pool-1-thread-3,1,main]: 5 -Thread[pool-1-thread-2,1,main]: 5 -Thread[pool-1-thread-3,1,main]: 4 -Thread[pool-1-thread-5,1,main]: 4 -Thread[pool-1-thread-4,1,main]: 4 -Thread[pool-1-thread-1,1,main]: 4 - ... -*/ diff --git a/tasks/SimpleThread.java b/tasks/SimpleThread.java deleted file mode 100644 index 9d1d5d3cd..000000000 --- a/tasks/SimpleThread.java +++ /dev/null @@ -1,37 +0,0 @@ -// tasks/SimpleThread.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Inheriting directly from the Thread class - -public class SimpleThread extends Thread { - private int countDown = 5; - private static int threadCount = 0; - public SimpleThread() { - // Store the thread name: - super(Integer.toString(++threadCount)); - start(); - } - @Override - public String toString() { - return "#" + getName() + "(" + countDown + "), "; - } - @Override - public void run() { - while(true) { - System.out.print(this); - if(--countDown == 0) - return; - } - } - public static void main(String[] args) { - for(int i = 0; i < 5; i++) - new SimpleThread(); - } -} -/* Output: -#4(5), #3(5), #5(5), #2(5), #2(4), #1(5), #4(4), #1(4), -#2(3), #2(2), #5(4), #3(4), #3(3), #3(2), #5(3), #5(2), -#2(1), #1(3), #4(3), #4(2), #1(2), #1(1), #5(1), #3(1), -#4(1), -*/ diff --git a/tasks/SingleThreadExecutor.java b/tasks/SingleThreadExecutor.java deleted file mode 100644 index 3a4b579bf..000000000 --- a/tasks/SingleThreadExecutor.java +++ /dev/null @@ -1,24 +0,0 @@ -// tasks/SingleThreadExecutor.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.concurrent.*; - -public class SingleThreadExecutor { - public static void main(String[] args) { - ExecutorService exec = - Executors.newSingleThreadExecutor(); - for(int i = 0; i < 5; i++) - exec.execute(new LiftOff()); - exec.shutdown(); - } -} -/* Output: -#0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), -#0(1), #0(Liftoff!), #1(9), #1(8), #1(7), #1(6), #1(5), -#1(4), #1(3), #1(2), #1(1), #1(Liftoff!), #2(9), #2(8), -#2(7), #2(6), #2(5), #2(4), #2(3), #2(2), #2(1), -#2(Liftoff!), #3(9), #3(8), #3(7), #3(6), #3(5), #3(4), -#3(3), #3(2), #3(1), #3(Liftoff!), #4(9), #4(8), #4(7), -#4(6), #4(5), #4(4), #4(3), #4(2), #4(1), #4(Liftoff!), -*/ diff --git a/tasks/SleepingTask.java b/tasks/SleepingTask.java deleted file mode 100644 index d9d983462..000000000 --- a/tasks/SleepingTask.java +++ /dev/null @@ -1,38 +0,0 @@ -// tasks/SleepingTask.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Calling sleep() to pause for a while -import java.util.concurrent.*; - -public class SleepingTask extends LiftOff { - @Override - public void run() { - try { - while(countDown-- > 0) { - System.out.print(status()); - // Old-style: - // Thread.sleep(100); - // Modern style: - TimeUnit.MILLISECONDS.sleep(100); - } - } catch(InterruptedException e) { - System.err.println("Interrupted"); - } - } - public static void main(String[] args) { - ExecutorService es = Executors.newCachedThreadPool(); - for(int i = 0; i < 5; i++) - es.execute(new SleepingTask()); - es.shutdown(); - } -} -/* Output: -#2(9), #4(9), #3(9), #0(9), #1(9), #2(8), #4(8), #3(8), -#0(8), #1(8), #4(7), #3(7), #2(7), #1(7), #0(7), #4(6), -#3(6), #2(6), #0(6), #1(6), #4(5), #2(5), #3(5), #1(5), -#0(5), #4(4), #2(4), #3(4), #1(4), #0(4), #4(3), #2(3), -#3(3), #1(3), #0(3), #4(2), #2(2), #3(2), #0(2), #1(2), -#2(1), #4(1), #3(1), #0(1), #1(1), #2(Liftoff!), -#4(Liftoff!), #3(Liftoff!), #0(Liftoff!), #1(Liftoff!), -*/ diff --git a/tasks/SyncObject.java b/tasks/SyncObject.java deleted file mode 100644 index 009fdb61b..000000000 --- a/tasks/SyncObject.java +++ /dev/null @@ -1,48 +0,0 @@ -// tasks/SyncObject.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Synchronizing on another object - -class DualSynch { - private Object syncObject = new Object(); - public synchronized void f() { - for(int i = 0; i < 5; i++) { - System.out.println("f()"); - Thread.yield(); - } - } - public void g() { - synchronized(syncObject) { - for(int i = 0; i < 5; i++) { - System.out.println("g()"); - Thread.yield(); - } - } - } -} - -public class SyncObject { - public static void main(String[] args) { - final DualSynch ds = new DualSynch(); - new Thread() { - @Override - public void run() { - ds.f(); - } - }.start(); - ds.g(); - } -} -/* Output: -f() -g() -g() -f() -g() -f() -g() -f() -f() -g() -*/ diff --git a/tasks/SynchronizationComparisons.java b/tasks/SynchronizationComparisons.java deleted file mode 100644 index 841dcc05f..000000000 --- a/tasks/SynchronizationComparisons.java +++ /dev/null @@ -1,214 +0,0 @@ -// tasks/SynchronizationComparisons.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Comparing the performance of explicit Locks -// and Atomics versus the synchronized keyword -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.util.concurrent.locks.*; -import java.util.*; - -abstract class Accumulator { - public static long cycles = 50000L; - // Number of Modifiers and Readers during each test: - private static final int N = 4; - public static ExecutorService exec = - Executors.newFixedThreadPool(N*2); - private static CyclicBarrier barrier = - new CyclicBarrier(N*2 + 1); - protected volatile int index = 0; - protected volatile long value = 0; - protected long duration = 0; - protected String id = "error"; - protected final static int SIZE = 100000; - protected static int[] preLoaded = new int[SIZE]; - static { // Load the array of random numbers: - SplittableRandom rand = new SplittableRandom(47); - for(int i = 0; i < SIZE; i++) - preLoaded[i] = rand.nextInt(); - } - public abstract void accumulate(); - public abstract long read(); - private class Modifier implements Runnable { - @Override - public void run() { - for(long i = 0; i < cycles; i++) - accumulate(); - try { - barrier.await(); - } catch(InterruptedException | - BrokenBarrierException e) { - throw new RuntimeException(e); - } - } - } - private class Reader implements Runnable { - private volatile long value; - @Override - public void run() { - for(long i = 0; i < cycles; i++) - value = read(); - try { - barrier.await(); - } catch(InterruptedException | - BrokenBarrierException e) { - throw new RuntimeException(e); - } - } - } - public void timedTest() { - long start = System.nanoTime(); - for(int i = 0; i < N; i++) { - exec.execute(new Modifier()); - exec.execute(new Reader()); - } - try { - barrier.await(); - } catch(InterruptedException | - BrokenBarrierException e) { - throw new RuntimeException(e); - } - duration = System.nanoTime() - start; - System.out.printf("%-13s: %13d\n", id, duration); - } - public void report(Accumulator acc2) { - System.out.printf( - "%-22s: %.2f\n", this.id + "/" + acc2.id, - (double)this.duration/(double)acc2.duration); - } -} - -class SynchronizedTest extends Accumulator { - { id = "synch"; } - @Override - public synchronized void accumulate() { - value += preLoaded[index++]; - if(index >= SIZE) index = 0; - } - @Override - public synchronized long read() { - return value; - } -} - -class LockTest extends Accumulator { - { id = "Lock"; } - private Lock lock = new ReentrantLock(); - @Override - public void accumulate() { - lock.lock(); - try { - value += preLoaded[index++]; - if(index >= SIZE) index = 0; - } finally { - lock.unlock(); - } - } - @Override - public long read() { - lock.lock(); - try { - return value; - } finally { - lock.unlock(); - } - } -} - -class AtomicTest extends Accumulator { - { id = "Atomic"; } - private AtomicInteger index = new AtomicInteger(0); - private AtomicLong value = new AtomicLong(0); - // Relying on more than one Atomic at a time doesn't - // work, so we still have to synchronize. But it gives - // a performance indicator: - @Override - public synchronized void accumulate() { - int i; - i = index.getAndIncrement(); - value.getAndAdd(preLoaded[i]); - if(++i >= SIZE) - index.set(0); - } - @Override - public synchronized long read() { return value.get(); } - @Override - public void report(Accumulator acc2) { - System.out.printf( - "%-22s: %.2f\n", "synch/(Atomic-synch)", - (double)acc2.duration/ - ((double)this.duration - (double)acc2.duration)); - } -} - -public class SynchronizationComparisons { - static SynchronizedTest synch = new SynchronizedTest(); - static LockTest lock = new LockTest(); - static AtomicTest atomic = new AtomicTest(); - static void test() { - System.out.println("============================"); - System.out.printf( - "%-12s : %13d\n", "Cycles", Accumulator.cycles); - synch.timedTest(); - lock.timedTest(); - atomic.timedTest(); - synch.report(lock); - atomic.report(synch); - } - public static void main(String[] args) { - int iterations = 5; // Default - if(args.length > 0) // Optionally change iterations - iterations = new Integer(args[0]); - // The first time fills the thread pool: - System.out.println("Warmup"); - synch.timedTest(); - // Now the initial test doesn't include the cost - // of starting the threads for the first time. - // Produce multiple data points: - for(int i = 0; i < iterations; i++) { - test(); - Accumulator.cycles *= 2; - } - Accumulator.exec.shutdown(); - } -} -/* Output: -Warmup -synch : 66040963 -============================ -Cycles : 50000 -synch : 66182130 -Lock : 28967506 -Atomic : 65390062 -synch/Lock : 2.28 -synch/(Atomic-synch) : -83.56 -============================ -Cycles : 100000 -synch : 131045096 -Lock : 49248746 -Atomic : 140269844 -synch/Lock : 2.66 -synch/(Atomic-synch) : 14.21 -============================ -Cycles : 200000 -synch : 256718481 -Lock : 95971018 -Atomic : 287549323 -synch/Lock : 2.67 -synch/(Atomic-synch) : 8.33 -============================ -Cycles : 400000 -synch : 513599757 -Lock : 192522353 -Atomic : 543954449 -synch/Lock : 2.67 -synch/(Atomic-synch) : 16.92 -============================ -Cycles : 800000 -synch : 1089344465 -Lock : 413671821 -Atomic : 963264943 -synch/Lock : 2.63 -synch/(Atomic-synch) : -8.64 -*/ diff --git a/tasks/TestBlockingQueues.java b/tasks/TestBlockingQueues.java deleted file mode 100644 index d47d63c27..000000000 --- a/tasks/TestBlockingQueues.java +++ /dev/null @@ -1,71 +0,0 @@ -// tasks/TestBlockingQueues.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {TimeOutDuringTesting} -import java.util.concurrent.*; -import java.io.*; - -class LiftOffRunner implements Runnable { - private BlockingQueue rockets; - public LiftOffRunner(BlockingQueue queue) { - rockets = queue; - } - public void add(LiftOff lo) { - try { - rockets.put(lo); - } catch(InterruptedException e) { - System.out.println("Interrupted during put()"); - } - } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - LiftOff rocket = rockets.take(); - rocket.run(); // Use this thread - } - } catch(InterruptedException e) { - System.out.println("Waking from take()"); - } - System.out.println("Exiting LiftOffRunner"); - } -} - -public class TestBlockingQueues { - static void getkey() { - try { - // Compensate for Windows/Linux difference in the - // length of the result produced by the Enter key: - new BufferedReader( - new InputStreamReader(System.in)).readLine(); - } catch(java.io.IOException e) { - throw new RuntimeException(e); - } - } - static void getkey(String message) { - System.out.println(message); - getkey(); - } - static void - test(String msg, BlockingQueue queue) { - System.out.println(msg); - LiftOffRunner runner = new LiftOffRunner(queue); - Thread t = new Thread(runner); - t.start(); - for(int i = 0; i < 5; i++) - runner.add(new LiftOff(5)); - getkey("Press 'Enter' (" + msg + ")"); - t.interrupt(); - System.out.println("Finished " + msg + " test"); - } - public static void main(String[] args) { - test("LinkedBlockingQueue", // Unlimited size - new LinkedBlockingQueue<>()); - test("ArrayBlockingQueue", // Fixed size - new ArrayBlockingQueue<>(3)); - test("SynchronousQueue", // Size of 1 - new SynchronousQueue<>()); - } -} -/* Output: (Execute to see) */ diff --git a/tasks/Tester.java b/tasks/Tester.java deleted file mode 100644 index 935c50e27..000000000 --- a/tasks/Tester.java +++ /dev/null @@ -1,77 +0,0 @@ -// tasks/Tester.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Performance test framework for concurrency collections -import java.util.concurrent.*; -import onjava.*; - -public abstract class Tester { - static int testReps = 10; - static int testCycles = 1000; - static int collectionSize = 1000; - abstract C collectionInitializer(); - abstract void startReadersAndWriters(); - C testCollection; - String testId; - int nReaders; - int nWriters; - volatile long readResult = 0; - volatile long readTime = 0; - volatile long writeTime = 0; - CountDownLatch endLatch; - static ExecutorService exec = - Executors.newCachedThreadPool(); - Integer[] writeData; - Tester(String testId, int nReaders, int nWriters) { - this.testId = testId + " " + - nReaders + "r " + nWriters + "w"; - this.nReaders = nReaders; - this.nWriters = nWriters; - writeData = new Rand.Integer().array(collectionSize); - for(int i = 0; i < testReps; i++) { - runTest(); - readTime = 0; - writeTime = 0; - } - } - void runTest() { - endLatch = new CountDownLatch(nReaders + nWriters); - testCollection = collectionInitializer(); - startReadersAndWriters(); - try { - endLatch.await(); - } catch(InterruptedException ex) { - System.out.println("endLatch interrupted"); - } - System.out.printf("%-27s %14d %14d\n", - testId, readTime, writeTime); - if(readTime != 0 && writeTime != 0) - System.out.printf("%-27s %14d\n", - "readTime + writeTime =", readTime + writeTime); - } - abstract class TestTask implements Runnable { - abstract void test(); - abstract void putResults(); - long duration; - public void run() { - long startTime = System.nanoTime(); - test(); - duration = System.nanoTime() - startTime; - synchronized(Tester.this) { - putResults(); - } - endLatch.countDown(); - } - } - public static void initMain(String[] args) { - if(args.length > 0) - testReps = new Integer(args[0]); - if(args.length > 1) - testCycles = new Integer(args[1]); - if(args.length > 2) - collectionSize = new Integer(args[2]); - System.out.printf("%-27s %14s %14s\n", - "Type", "Read time", "Write time"); - } -} diff --git a/tasks/ThreadLocalVariableHolder.java b/tasks/ThreadLocalVariableHolder.java deleted file mode 100644 index 6634f2bb5..000000000 --- a/tasks/ThreadLocalVariableHolder.java +++ /dev/null @@ -1,71 +0,0 @@ -// tasks/ThreadLocalVariableHolder.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Automatically giving each thread its own storage -import java.util.concurrent.*; -import java.util.*; - -class Accessor implements Runnable { - private final int id; - public Accessor(int idn) { id = idn; } - @Override - public void run() { - while(!Thread.currentThread().isInterrupted()) { - ThreadLocalVariableHolder.increment(); - System.out.println(this); - Thread.yield(); - } - } - @Override - public String toString() { - return "#" + id + ": " + - ThreadLocalVariableHolder.get(); - } -} - -public class ThreadLocalVariableHolder { - private static ThreadLocal value = - new ThreadLocal() { - private SplittableRandom rand = new SplittableRandom(47); - @Override - protected synchronized Integer initialValue() { - return rand.nextInt(10000); - } - }; - public static void increment() { - value.set(value.get() + 1); - } - public static int get() { return value.get(); } - public static void - main(String[] args) throws Exception { - ExecutorService es = Executors.newCachedThreadPool(); - for(int i = 0; i < 5; i++) - es.execute(new Accessor(i)); - TimeUnit.SECONDS.sleep(3); // Run for a while - es.shutdownNow(); // All Accessors will quit - } -} -/* Output: (First and last 10 Lines) -#2: 9259 -#1: 962 -#3: 1862 -#4: 6694 -#0: 556 -#4: 6695 -#4: 6696 -#3: 1863 -#1: 963 -#2: 9260 -________...________...________...________...________ -#3: 3791 -#2: 11096 -#4: 8402 -#4: 8403 -#2: 11097 -#3: 3792 -#0: 2637 -#1: 3032 -#4: 8404 -#2: 11098 -*/ diff --git a/tasks/ThreadVariations.java b/tasks/ThreadVariations.java deleted file mode 100644 index 3c8522076..000000000 --- a/tasks/ThreadVariations.java +++ /dev/null @@ -1,192 +0,0 @@ -// tasks/ThreadVariations.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Creating threads with inner classes -import java.util.concurrent.*; - -// Using a named inner class: -class InnerThread1 { - private int countDown = 5; - private Inner inner; - private class Inner extends Thread { - Inner(String name) { - super(name); - start(); - } - @Override - public void run() { - try { - while(true) { - System.out.println(this); - if(--countDown == 0) return; - sleep(10); - } - } catch(InterruptedException e) { - System.out.println("interrupted"); - } - } - @Override - public String toString() { - return getName() + ": " + countDown; - } - } - public InnerThread1(String name) { - inner = new Inner(name); - } -} - -// Using an anonymous inner class: -class InnerThread2 { - private int countDown = 5; - private Thread t; - public InnerThread2(String name) { - t = new Thread(name) { - @Override - public void run() { - try { - while(true) { - System.out.println(this); - if(--countDown == 0) return; - sleep(10); - } - } catch(InterruptedException e) { - System.out.println("sleep() interrupted"); - } - } - @Override - public String toString() { - return getName() + ": " + countDown; - } - }; - t.start(); - } -} - -// Using a named Runnable implementation: -class InnerRunnable1 { - private int countDown = 5; - private Inner inner; - private class Inner implements Runnable { - Thread t; - Inner(String name) { - t = new Thread(this, name); - t.start(); - } - @Override - public void run() { - try { - while(true) { - System.out.println(this); - if(--countDown == 0) return; - TimeUnit.MILLISECONDS.sleep(10); - } - } catch(InterruptedException e) { - System.out.println("sleep() interrupted"); - } - } - @Override - public String toString() { - return t.getName() + ": " + countDown; - } - } - public InnerRunnable1(String name) { - inner = new Inner(name); - } -} - -// Using an anonymous Runnable implementation: -class InnerRunnable2 { - private int countDown = 5; - private Thread t; - public InnerRunnable2(String name) { - t = new Thread(new Runnable() { - @Override - public void run() { - try { - while(true) { - System.out.println(this); - if(--countDown == 0) return; - TimeUnit.MILLISECONDS.sleep(10); - } - } catch(InterruptedException e) { - System.out.println("sleep() interrupted"); - } - } - @Override - public String toString() { - return Thread.currentThread().getName() + - ": " + countDown; - } - }, name); - t.start(); - } -} - -// A separate method to run some code as a task: -class ThreadMethod { - private int countDown = 5; - private Thread t; - private String name; - public ThreadMethod(String name) { this.name = name; } - public void runTask() { - if(t == null) { - t = new Thread(name) { - @Override - public void run() { - try { - while(true) { - System.out.println(this); - if(--countDown == 0) return; - sleep(10); - } - } catch(InterruptedException e) { - System.out.println("sleep() interrupted"); - } - } - @Override - public String toString() { - return getName() + ": " + countDown; - } - }; - t.start(); - } - } -} - -public class ThreadVariations { - public static void main(String[] args) { - new InnerThread1("InnerThread1"); - new InnerThread2("InnerThread2"); - new InnerRunnable1("InnerRunnable1"); - new InnerRunnable2("InnerRunnable2"); - new ThreadMethod("ThreadMethod").runTask(); - } -} -/* Output: -InnerThread1: 5 -InnerThread2: 5 -InnerThread1: 4 -InnerThread2: 4 -InnerThread1: 3 -InnerThread2: 3 -InnerThread1: 2 -InnerThread2: 2 -InnerRunnable1: 5 -InnerThread1: 1 -InnerThread2: 1 -InnerRunnable2: 5 -InnerRunnable1: 4 -InnerRunnable2: 4 -InnerRunnable1: 3 -InnerRunnable2: 3 -InnerRunnable1: 2 -InnerRunnable2: 2 -InnerRunnable1: 1 -InnerRunnable2: 1 -ThreadMethod: 5 -ThreadMethod: 4 -ThreadMethod: 3 -ThreadMethod: 2 -ThreadMethod: 1 -*/ diff --git a/tasks/ToastOMatic.java b/tasks/ToastOMatic.java deleted file mode 100644 index 45dfb0975..000000000 --- a/tasks/ToastOMatic.java +++ /dev/null @@ -1,212 +0,0 @@ -// tasks/ToastOMatic.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// A toaster that uses queues -import java.util.concurrent.*; -import java.util.*; - -class Toast { - public enum Status { DRY, BUTTERED, JAMMED } - private Status status = Status.DRY; - private final int id; - public Toast(int idn) { id = idn; } - public void butter() { status = Status.BUTTERED; } - public void jam() { status = Status.JAMMED; } - public Status getStatus() { return status; } - public int getId() { return id; } - @Override - public String toString() { - return "Toast " + id + ": " + status; - } -} - -class ToastQueue extends LinkedBlockingQueue {} - -class Toaster implements Runnable { - private ToastQueue toastQueue; - private int count = 0; - private SplittableRandom rand = new SplittableRandom(47); - public Toaster(ToastQueue tq) { toastQueue = tq; } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - TimeUnit.MILLISECONDS.sleep( - 100 + rand.nextInt(500)); - // Make toast - Toast t = new Toast(count++); - System.out.println(t); - // Insert into queue - toastQueue.put(t); - } - } catch(InterruptedException e) { - System.out.println("Toaster interrupted"); - } - System.out.println("Toaster off"); - } -} - -// Apply butter to toast: -class Butterer implements Runnable { - private ToastQueue dryQueue, butteredQueue; - public Butterer(ToastQueue dry, ToastQueue buttered) { - dryQueue = dry; - butteredQueue = buttered; - } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - // Blocks until next piece of toast is available: - Toast t = dryQueue.take(); - t.butter(); - System.out.println(t); - butteredQueue.put(t); - } - } catch(InterruptedException e) { - System.out.println("Butterer interrupted"); - } - System.out.println("Butterer off"); - } -} - -// Apply jam to buttered toast: -class Jammer implements Runnable { - private ToastQueue butteredQueue, finishedQueue; - public - Jammer(ToastQueue buttered, ToastQueue finished) { - butteredQueue = buttered; - finishedQueue = finished; - } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - // Blocks until next piece of toast is available: - Toast t = butteredQueue.take(); - t.jam(); - System.out.println(t); - finishedQueue.put(t); - } - } catch(InterruptedException e) { - System.out.println("Jammer interrupted"); - } - System.out.println("Jammer off"); - } -} - -// Consume the toast: -class Eater implements Runnable { - private ToastQueue finishedQueue; - private int counter = 0; - public Eater(ToastQueue finished) { - finishedQueue = finished; - } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - // Blocks until next piece of toast is available: - Toast t = finishedQueue.take(); - // Verify that the toast is coming in order, - // and that all pieces are getting jammed: - if(t.getId() != counter++ || - t.getStatus() != Toast.Status.JAMMED) { - System.out.println(">>>> Error: " + t); - System.exit(1); - } else - System.out.println("Chomp! " + t); - } - } catch(InterruptedException e) { - System.out.println("Eater interrupted"); - } - System.out.println("Eater off"); - } -} - -public class ToastOMatic { - public static void - main(String[] args) throws Exception { - ToastQueue dryQueue = new ToastQueue(), - butteredQueue = new ToastQueue(), - finishedQueue = new ToastQueue(); - ExecutorService es = Executors.newCachedThreadPool(); - es.execute(new Toaster(dryQueue)); - es.execute(new Butterer(dryQueue, butteredQueue)); - es.execute(new Jammer(butteredQueue, finishedQueue)); - es.execute(new Eater(finishedQueue)); - TimeUnit.SECONDS.sleep(5); - es.shutdownNow(); - } -} -/* Output: -Toast 0: DRY -Toast 0: BUTTERED -Toast 0: JAMMED -Chomp! Toast 0: JAMMED -Toast 1: DRY -Toast 1: BUTTERED -Toast 1: JAMMED -Chomp! Toast 1: JAMMED -Toast 2: DRY -Toast 2: BUTTERED -Toast 2: JAMMED -Chomp! Toast 2: JAMMED -Toast 3: DRY -Toast 3: BUTTERED -Toast 3: JAMMED -Chomp! Toast 3: JAMMED -Toast 4: DRY -Toast 4: BUTTERED -Toast 4: JAMMED -Chomp! Toast 4: JAMMED -Toast 5: DRY -Toast 5: BUTTERED -Toast 5: JAMMED -Chomp! Toast 5: JAMMED -Toast 6: DRY -Toast 6: BUTTERED -Toast 6: JAMMED -Chomp! Toast 6: JAMMED -Toast 7: DRY -Toast 7: BUTTERED -Toast 7: JAMMED -Chomp! Toast 7: JAMMED -Toast 8: DRY -Toast 8: BUTTERED -Toast 8: JAMMED -Chomp! Toast 8: JAMMED -Toast 9: DRY -Toast 9: BUTTERED -Toast 9: JAMMED -Chomp! Toast 9: JAMMED -Toast 10: DRY -Toast 10: BUTTERED -Toast 10: JAMMED -Chomp! Toast 10: JAMMED -Toast 11: DRY -Toast 11: BUTTERED -Toast 11: JAMMED -Chomp! Toast 11: JAMMED -Toast 12: DRY -Toast 12: BUTTERED -Toast 12: JAMMED -Chomp! Toast 12: JAMMED -Toast 13: DRY -Toast 13: BUTTERED -Toast 13: JAMMED -Chomp! Toast 13: JAMMED -Toast 14: DRY -Toast 14: BUTTERED -Toast 14: JAMMED -Chomp! Toast 14: JAMMED -Jammer interrupted -Jammer off -Butterer interrupted -Butterer off -Toaster interrupted -Eater interrupted -Toaster off -Eater off -*/ diff --git a/tasks/build.xml b/tasks/build.xml deleted file mode 100644 index d321f0733..000000000 --- a/tasks/build.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tasks/restaurant2/RestaurantWithQueues.java b/tasks/restaurant2/RestaurantWithQueues.java deleted file mode 100644 index c58972ba7..000000000 --- a/tasks/restaurant2/RestaurantWithQueues.java +++ /dev/null @@ -1,230 +0,0 @@ -// tasks/restaurant2/RestaurantWithQueues.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// {Args: 5} -package tasks.restaurant2; -import enums.menu.*; -import java.util.concurrent.*; -import java.util.*; - -// This is given to the waiter, who gives it to the chef: -class Order { // (A data-transfer object) - private static int counter = 0; - private final int id = counter++; - private final Customer customer; - private final WaitPerson waitPerson; - private final Food food; - public Order(Customer cust, WaitPerson wp, Food f) { - customer = cust; - waitPerson = wp; - food = f; - } - public Food item() { return food; } - public Customer getCustomer() { return customer; } - public WaitPerson getWaitPerson() { return waitPerson; } - @Override - public String toString() { - return "Order: " + id + " item: " + food + - " for: " + customer + - " served by: " + waitPerson; - } -} - -// This is what comes back from the chef: -class Plate { - private final Order order; - private final Food food; - public Plate(Order ord, Food f) { - order = ord; - food = f; - } - public Order getOrder() { return order; } - public Food getFood() { return food; } - @Override - public String toString() { return food.toString(); } -} - -class Customer implements Runnable { - private static int counter = 0; - private final int id = counter++; - private final WaitPerson waitPerson; - // Only one course at a time can be received: - private SynchronousQueue placeSetting = - new SynchronousQueue<>(); - public Customer(WaitPerson w) { waitPerson = w; } - public void - deliver(Plate p) throws InterruptedException { - // Only blocks if customer is still - // eating the previous course: - placeSetting.put(p); - } - @Override - public void run() { - for(Course course : Course.values()) { - Food food = course.randomSelection(); - try { - waitPerson.placeOrder(this, food); - // Blocks until course is delivered: - System.out.println( - this + "eating " + placeSetting.take()); - } catch(InterruptedException e) { - System.out.println(this + "waiting for " + - course + " interrupted"); - break; - } - } - System.out.println(this + "finished meal, leaving"); - } - @Override - public String toString() { - return "Customer " + id + " "; - } -} - -class WaitPerson implements Runnable { - private static int counter = 0; - private final int id = counter++; - private final Restaurant restaurant; - BlockingQueue filledOrders = - new LinkedBlockingQueue<>(); - public WaitPerson(Restaurant rest) { - restaurant = rest; - } - public void placeOrder(Customer cust, Food food) { - try { - // Shouldn't actually block because this is - // a LinkedBlockingQueue with no size limit: - restaurant.orders.put(new Order(cust, this, food)); - } catch(InterruptedException e) { - System.out.println( - this + " placeOrder interrupted"); - } - } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - // Blocks until a course is ready - Plate plate = filledOrders.take(); - System.out.println(this + "received " + plate + - " delivering to " + - plate.getOrder().getCustomer()); - plate.getOrder().getCustomer().deliver(plate); - } - } catch(InterruptedException e) { - System.out.println(this + " interrupted"); - } - System.out.println(this + " off duty"); - } - @Override - public String toString() { - return "WaitPerson " + id + " "; - } -} - -class Chef implements Runnable { - private static int counter = 0; - private final int id = counter++; - private final Restaurant restaurant; - private static SplittableRandom rand = new SplittableRandom(47); - public Chef(Restaurant rest) { restaurant = rest; } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - // Blocks until an order appears: - Order order = restaurant.orders.take(); - Food requestedItem = order.item(); - // Time to prepare order: - TimeUnit.MILLISECONDS.sleep(rand.nextInt(500)); - Plate plate = new Plate(order, requestedItem); - order.getWaitPerson().filledOrders.put(plate); - } - } catch(InterruptedException e) { - System.out.println(this + " interrupted"); - } - System.out.println(this + " off duty"); - } - @Override - public String toString() { return "Chef " + id + " "; } -} - -class Restaurant implements Runnable { - private List waitPersons = - new ArrayList<>(); - private List chefs = new ArrayList<>(); - private ExecutorService exec; - private static SplittableRandom rand = new SplittableRandom(47); - BlockingQueue - orders = new LinkedBlockingQueue<>(); - public Restaurant(ExecutorService e, int nWaitPersons, - int nChefs) { - exec = e; - for(int i = 0; i < nWaitPersons; i++) { - WaitPerson waitPerson = new WaitPerson(this); - waitPersons.add(waitPerson); - exec.execute(waitPerson); - } - for(int i = 0; i < nChefs; i++) { - Chef chef = new Chef(this); - chefs.add(chef); - exec.execute(chef); - } - } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - // A new customer arrives; assign a WaitPerson: - WaitPerson wp = waitPersons.get( - rand.nextInt(waitPersons.size())); - Customer c = new Customer(wp); - exec.execute(c); - TimeUnit.MILLISECONDS.sleep(100); - } - } catch(InterruptedException e) { - System.out.println("Restaurant interrupted"); - } - System.out.println("Restaurant closing"); - } -} - -public class RestaurantWithQueues { - public static void - main(String[] args) throws Exception { - ExecutorService es = Executors.newCachedThreadPool(); - Restaurant restaurant = new Restaurant(es, 5, 2); - es.execute(restaurant); - if(args.length > 0) // Optional argument - TimeUnit.SECONDS.sleep(new Integer(args[0])); - else { - System.out.println("Press 'Enter' to quit"); - System.in.read(); - } - es.shutdownNow(); - } -} -/* Output: (First and last 10 Lines) -WaitPerson 0 received SPRING_ROLLS delivering to Customer 1 -Customer 1 eating SPRING_ROLLS -WaitPerson 3 received SPRING_ROLLS delivering to Customer 0 -Customer 0 eating SPRING_ROLLS -WaitPerson 3 received SOUP delivering to Customer 2 -Customer 2 eating SOUP -WaitPerson 0 received VINDALOO delivering to Customer 1 -Customer 1 eating VINDALOO -WaitPerson 1 received SOUP delivering to Customer 3 -Customer 3 eating SOUP -________...________...________...________...________ -WaitPerson 3 off duty -Customer 6 finished meal, leaving -WaitPerson 4 off duty -Customer 42 finished meal, leaving -Customer 7 finished meal, leaving -Customer 28 finished meal, leaving -Customer 9 finished meal, leaving -Customer 15 finished meal, leaving -Customer 21 finished meal, leaving -Customer 0 finished meal, leaving -*/ diff --git a/tasks/waxomatic/WaxOMatic.java b/tasks/waxomatic/WaxOMatic.java deleted file mode 100644 index 42d15c7e0..000000000 --- a/tasks/waxomatic/WaxOMatic.java +++ /dev/null @@ -1,88 +0,0 @@ -// tasks/waxomatic/WaxOMatic.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Basic task cooperation -package tasks.waxomatic; -import java.util.concurrent.*; - -class Car { - private boolean waxOn = false; - public synchronized void waxed() { - waxOn = true; // Ready to buff - notifyAll(); - } - public synchronized void buffed() { - waxOn = false; // Ready for another coat of wax - notifyAll(); - } - public synchronized void waitForWaxing() - throws InterruptedException { - while(waxOn == false) - wait(); - } - public synchronized void waitForBuffing() - throws InterruptedException { - while(waxOn == true) - wait(); - } -} - -class WaxOn implements Runnable { - private Car car; - public WaxOn(Car c) { car = c; } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - System.out.print("Wax On! "); - TimeUnit.MILLISECONDS.sleep(200); - car.waxed(); - car.waitForBuffing(); - } - } catch(InterruptedException e) { - System.out.println("Exiting via interrupt"); - } - System.out.println("Ending Wax On task"); - } -} - -class WaxOff implements Runnable { - private Car car; - public WaxOff(Car c) { car = c; } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - car.waitForWaxing(); - System.out.print("Wax Off! "); - TimeUnit.MILLISECONDS.sleep(200); - car.buffed(); - } - } catch(InterruptedException e) { - System.out.println("Exiting via interrupt"); - } - System.out.println("Ending Wax Off task"); - } -} - -public class WaxOMatic { - public static void - main(String[] args) throws Exception { - Car car = new Car(); - ExecutorService es = Executors.newCachedThreadPool(); - es.execute(new WaxOff(car)); - es.execute(new WaxOn(car)); - TimeUnit.SECONDS.sleep(5); // Run for a while... - es.shutdownNow(); // Interrupt all tasks - } -} -/* Output: -Wax On! Wax Off! Wax On! Wax Off! Wax On! Wax Off! Wax On! -Wax Off! Wax On! Wax Off! Wax On! Wax Off! Wax On! Wax Off! -Wax On! Wax Off! Wax On! Wax Off! Wax On! Wax Off! Wax On! -Wax Off! Wax On! Wax Off! Wax On! Exiting via interrupt -Ending Wax On task -Exiting via interrupt -Ending Wax Off task -*/ diff --git a/tasks/waxomatic2/WaxOMatic2.java b/tasks/waxomatic2/WaxOMatic2.java deleted file mode 100644 index 2c9ed53bd..000000000 --- a/tasks/waxomatic2/WaxOMatic2.java +++ /dev/null @@ -1,111 +0,0 @@ -// tasks/waxomatic2/WaxOMatic2.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Using Lock and Condition objects -package tasks.waxomatic2; -import java.util.concurrent.*; -import java.util.concurrent.locks.*; - -class Car { - private Lock lock = new ReentrantLock(); - private Condition condition = lock.newCondition(); - private boolean waxOn = false; - public void waxed() { - lock.lock(); - try { - waxOn = true; // Ready to buff - condition.signalAll(); - } finally { - lock.unlock(); - } - } - public void buffed() { - lock.lock(); - try { - waxOn = false; // Ready for another coat of wax - condition.signalAll(); - } finally { - lock.unlock(); - } - } - public void - waitForWaxing() throws InterruptedException { - lock.lock(); - try { - while(waxOn == false) - condition.await(); - } finally { - lock.unlock(); - } - } - public void - waitForBuffing() throws InterruptedException{ - lock.lock(); - try { - while(waxOn == true) - condition.await(); - } finally { - lock.unlock(); - } - } -} - -class WaxOn implements Runnable { - private Car car; - public WaxOn(Car c) { car = c; } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - System.out.print("Wax On! "); - TimeUnit.MILLISECONDS.sleep(200); - car.waxed(); - car.waitForBuffing(); - } - } catch(InterruptedException e) { - System.out.println("Exiting via interrupt"); - } - System.out.println("Ending Wax On task"); - } -} - -class WaxOff implements Runnable { - private Car car; - public WaxOff(Car c) { car = c; } - @Override - public void run() { - try { - while(!Thread.interrupted()) { - car.waitForWaxing(); - System.out.print("Wax Off! "); - TimeUnit.MILLISECONDS.sleep(200); - car.buffed(); - } - } catch(InterruptedException e) { - System.out.println("Exiting via interrupt"); - } - System.out.println("Ending Wax Off task"); - } -} - -public class WaxOMatic2 { - public static void - main(String[] args) throws Exception { - Car car = new Car(); - ExecutorService es = Executors.newCachedThreadPool(); - es.execute(new WaxOff(car)); - es.execute(new WaxOn(car)); - TimeUnit.SECONDS.sleep(5); - es.shutdownNow(); - } -} -/* Output: -Wax On! Wax Off! Wax On! Wax Off! Wax On! Wax Off! Wax On! -Wax Off! Wax On! Wax Off! Wax On! Wax Off! Wax On! Wax Off! -Wax On! Wax Off! Wax On! Wax Off! Wax On! Wax Off! Wax On! -Wax Off! Wax On! Wax Off! Wax On! Exiting via interrupt -Exiting via interrupt -Ending Wax On task -Ending Wax Off task -*/ diff --git a/typeinfo/PetCount.java b/typeinfo/PetCount.java deleted file mode 100644 index 475cdc8f3..000000000 --- a/typeinfo/PetCount.java +++ /dev/null @@ -1,65 +0,0 @@ -// typeinfo/PetCount.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ 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/typeinfo/PetCount2.java b/typeinfo/PetCount2.java deleted file mode 100644 index fa1e7a11b..000000000 --- a/typeinfo/PetCount2.java +++ /dev/null @@ -1,18 +0,0 @@ -// typeinfo/PetCount2.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ 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/typeinfo/PetCount3.java b/typeinfo/PetCount3.java deleted file mode 100644 index 7fcaa0da7..000000000 --- a/typeinfo/PetCount3.java +++ /dev/null @@ -1,54 +0,0 @@ -// typeinfo/PetCount3.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Using isInstance() -import typeinfo.pets.*; -import java.util.*; -import onjava.*; - -public class PetCount3 { - static class Counter - extends LinkedHashMap, Integer> { - public Counter() { - super(FilledMap.map(LiteralPetCreator.allTypes, 0)); - } - public void count(Pet pet) { - // Class.isInstance() eliminates instanceofs: - for(Map.Entry, Integer> - pair : entrySet()) - if(pair.getKey().isInstance(pet)) - put(pair.getKey(), pair.getValue() + 1); - } - @Override - public String toString() { - StringBuilder result = new StringBuilder("{"); - for(Map.Entry, Integer> - pair : entrySet()) { - result.append(pair.getKey().getSimpleName()); - result.append("="); - result.append(pair.getValue()); - result.append(", "); - } - result.delete(result.length() - 2, result.length()); - result.append("}"); - return result.toString(); - } - } - 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 -{Pet=20, Dog=6, Cat=9, Rodent=5, Mutt=3, Pug=3, -EgyptianMau=2, Manx=7, Cymric=5, Rat=2, Mouse=2, Hamster=1} -*/ diff --git a/typeinfo/Shapes.java b/typeinfo/Shapes.java deleted file mode 100644 index 1d43e4393..000000000 --- a/typeinfo/Shapes.java +++ /dev/null @@ -1,38 +0,0 @@ -// typeinfo/Shapes.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import java.util.stream.*; - -abstract class Shape { - void draw() { System.out.println(this + ".draw()"); } - @Override - abstract public 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/typeinfo/build.xml b/typeinfo/build.xml deleted file mode 100644 index 9d52770e2..000000000 --- a/typeinfo/build.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/typeinfo/interfacea/A.java b/typeinfo/interfacea/A.java deleted file mode 100644 index 0086dfaa2..000000000 --- a/typeinfo/interfacea/A.java +++ /dev/null @@ -1,9 +0,0 @@ -// typeinfo/interfacea/A.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package typeinfo.interfacea; - -public interface A { - void f(); -} diff --git a/typeinfo/pets/ForNameCreator.java b/typeinfo/pets/ForNameCreator.java deleted file mode 100644 index 3799f62c9..000000000 --- a/typeinfo/pets/ForNameCreator.java +++ /dev/null @@ -1,37 +0,0 @@ -// typeinfo/pets/ForNameCreator.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package typeinfo.pets; -import java.util.*; - -public class ForNameCreator extends PetCreator { - private static List> types = - new ArrayList<>(); - // Types that 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/typeinfo/pets/LiteralPetCreator.java b/typeinfo/pets/LiteralPetCreator.java deleted file mode 100644 index ffdafe74f..000000000 --- a/typeinfo/pets/LiteralPetCreator.java +++ /dev/null @@ -1,36 +0,0 @@ -// typeinfo/pets/LiteralPetCreator.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Using class literals -package typeinfo.pets; -import java.util.*; - -public class LiteralPetCreator extends PetCreator { - // No try block needed. - @SuppressWarnings("unchecked") - public static - final List> allTypes = - 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 = - allTypes.subList(allTypes.indexOf(Mutt.class), - allTypes.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/typeinfo/pets/Person.java b/typeinfo/pets/Person.java deleted file mode 100644 index bf8005a22..000000000 --- a/typeinfo/pets/Person.java +++ /dev/null @@ -1,9 +0,0 @@ -// typeinfo/pets/Person.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -package typeinfo.pets; - -public class Person extends Individual { - public Person(String name) { super(name); } -} diff --git a/typeinfo/pets/PetCreator.java b/typeinfo/pets/PetCreator.java deleted file mode 100644 index 973f24170..000000000 --- a/typeinfo/pets/PetCreator.java +++ /dev/null @@ -1,24 +0,0 @@ -// typeinfo/pets/PetCreator.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Creates random sequences of Pets -package typeinfo.pets; -import java.util.*; -import java.util.function.*; - -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).newInstance(); - } catch(InstantiationException | - IllegalAccessException e) { - throw new RuntimeException(e); - } - } -} diff --git a/typeinfo/pets/Pets.java b/typeinfo/pets/Pets.java deleted file mode 100644 index 5d84b42fe..000000000 --- a/typeinfo/pets/Pets.java +++ /dev/null @@ -1,30 +0,0 @@ -// typeinfo/pets/Pets.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ 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/typeinfo/toys/GenericToyTest.java b/typeinfo/toys/GenericToyTest.java deleted file mode 100644 index 73492fa55..000000000 --- a/typeinfo/toys/GenericToyTest.java +++ /dev/null @@ -1,20 +0,0 @@ -// typeinfo/toys/GenericToyTest.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Testing class Class -package typeinfo.toys; - -public class GenericToyTest { - 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/ui/BorderLayout1.java b/ui/BorderLayout1.java deleted file mode 100644 index 6236f4e9e..000000000 --- a/ui/BorderLayout1.java +++ /dev/null @@ -1,21 +0,0 @@ -// ui/BorderLayout1.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Demonstrates BorderLayout -import javax.swing.*; -import java.awt.*; -import static onjava.SwingConsole.*; - -public class BorderLayout1 extends JFrame { - public BorderLayout1() { - add(BorderLayout.NORTH, new JButton("North")); - add(BorderLayout.SOUTH, new JButton("South")); - add(BorderLayout.EAST, new JButton("East")); - add(BorderLayout.WEST, new JButton("West")); - add(BorderLayout.CENTER, new JButton("Center")); - } - public static void main(String[] args) { - run(new BorderLayout1(), 300, 250); - } -} diff --git a/ui/Borders.java b/ui/Borders.java deleted file mode 100644 index 55bf25c3e..000000000 --- a/ui/Borders.java +++ /dev/null @@ -1,40 +0,0 @@ -// ui/Borders.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Different Swing borders -import javax.swing.*; -import javax.swing.border.*; -import java.awt.*; -import static onjava.SwingConsole.*; - -public class Borders extends JFrame { - static JPanel showBorder(Border b) { - JPanel jp = new JPanel(); - jp.setLayout(new BorderLayout()); - String nm = b.getClass().toString(); - nm = nm.substring(nm.lastIndexOf('.') + 1); - jp.add(new JLabel(nm, JLabel.CENTER), - BorderLayout.CENTER); - jp.setBorder(b); - return jp; - } - public Borders() { - setLayout(new GridLayout(2,4)); - add(showBorder(new TitledBorder("Title"))); - add(showBorder(new EtchedBorder())); - add(showBorder(new LineBorder(Color.BLUE))); - add(showBorder( - new MatteBorder(5,5,30,30,Color.GREEN))); - add(showBorder( - new BevelBorder(BevelBorder.RAISED))); - add(showBorder( - new SoftBevelBorder(BevelBorder.LOWERED))); - add(showBorder(new CompoundBorder( - new EtchedBorder(), - new LineBorder(Color.RED)))); - } - public static void main(String[] args) { - run(new Borders(), 500, 300); - } -} diff --git a/ui/Button1.java b/ui/Button1.java deleted file mode 100644 index 7f49c9fee..000000000 --- a/ui/Button1.java +++ /dev/null @@ -1,22 +0,0 @@ -// ui/Button1.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Putting buttons on a Swing application -import javax.swing.*; -import java.awt.*; -import static onjava.SwingConsole.*; - -public class Button1 extends JFrame { - private JButton - b1 = new JButton("Button 1"), - b2 = new JButton("Button 2"); - public Button1() { - setLayout(new FlowLayout()); - add(b1); - add(b2); - } - public static void main(String[] args) { - run(new Button1(), 200, 100); - } -} diff --git a/ui/Button2.java b/ui/Button2.java deleted file mode 100644 index 2762bf375..000000000 --- a/ui/Button2.java +++ /dev/null @@ -1,35 +0,0 @@ -// ui/Button2.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Responding to button presses -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import static onjava.SwingConsole.*; - -public class Button2 extends JFrame { - private JButton - b1 = new JButton("Button 1"), - b2 = new JButton("Button 2"); - private JTextField txt = new JTextField(10); - class ButtonListener implements ActionListener { - @Override - public void actionPerformed(ActionEvent e) { - String name = ((JButton)e.getSource()).getText(); - txt.setText(name); - } - } - private ButtonListener bl = new ButtonListener(); - public Button2() { - b1.addActionListener(bl); - b2.addActionListener(bl); - setLayout(new FlowLayout()); - add(b1); - add(b2); - add(txt); - } - public static void main(String[] args) { - run(new Button2(), 200, 150); - } -} diff --git a/ui/Button2b.java b/ui/Button2b.java deleted file mode 100644 index ebb09dc30..000000000 --- a/ui/Button2b.java +++ /dev/null @@ -1,31 +0,0 @@ -// ui/Button2b.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Using anonymous inner classes -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import static onjava.SwingConsole.*; - -public class Button2b extends JFrame { - private JButton - b1 = new JButton("Button 1"), - b2 = new JButton("Button 2"); - private JTextField txt = new JTextField(10); - private ActionListener bl = e -> { - String name1 = ((JButton)e.getSource()).getText(); - txt.setText(name1); - }; - public Button2b() { - b1.addActionListener(bl); - b2.addActionListener(bl); - setLayout(new FlowLayout()); - add(b1); - add(b2); - add(txt); - } - public static void main(String[] args) { - run(new Button2b(), 200, 150); - } -} diff --git a/ui/ButtonGroups.java b/ui/ButtonGroups.java deleted file mode 100644 index 6c9acb088..000000000 --- a/ui/ButtonGroups.java +++ /dev/null @@ -1,56 +0,0 @@ -// ui/ButtonGroups.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Uses reflection to create groups -// of different types of AbstractButton -import javax.swing.*; -import javax.swing.border.*; -import java.awt.*; -import java.lang.reflect.*; -import static onjava.SwingConsole.*; - -public class ButtonGroups extends JFrame { - private static String[] ids = { - "June", "Ward", "Beaver", "Wally", "Eddie", "Lumpy" - }; - static JPanel makeBPanel( - Class kind, String[] ids) { - ButtonGroup bg = new ButtonGroup(); - JPanel jp = new JPanel(); - String title = kind.getName(); - title = title.substring(title.lastIndexOf('.') + 1); - jp.setBorder(new TitledBorder(title)); - for(String id : ids) { - AbstractButton ab = new JButton("failed"); - try { - // Get the dynamic constructor method - // that takes a String argument: - Constructor ctor = - kind.getConstructor(String.class); - // Create a new object: - ab = (AbstractButton)ctor.newInstance(id); - } catch(NoSuchMethodException | - SecurityException | - InstantiationException | - IllegalAccessException | - IllegalArgumentException | - InvocationTargetException ex) { - System.err.println("can't create " + kind); - } - bg.add(ab); - jp.add(ab); - } - return jp; - } - public ButtonGroups() { - setLayout(new FlowLayout()); - add(makeBPanel(JButton.class, ids)); - add(makeBPanel(JToggleButton.class, ids)); - add(makeBPanel(JCheckBox.class, ids)); - add(makeBPanel(JRadioButton.class, ids)); - } - public static void main(String[] args) { - run(new ButtonGroups(), 500, 350); - } -} diff --git a/ui/Buttons.java b/ui/Buttons.java deleted file mode 100644 index 7a0ca1939..000000000 --- a/ui/Buttons.java +++ /dev/null @@ -1,36 +0,0 @@ -// ui/Buttons.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Various Swing buttons -import javax.swing.*; -import javax.swing.border.*; -import javax.swing.plaf.basic.*; -import java.awt.*; -import static onjava.SwingConsole.*; - -public class Buttons extends JFrame { - private JButton jb = new JButton("JButton"); - private BasicArrowButton - up = new BasicArrowButton(BasicArrowButton.NORTH), - down = new BasicArrowButton(BasicArrowButton.SOUTH), - right = new BasicArrowButton(BasicArrowButton.EAST), - left = new BasicArrowButton(BasicArrowButton.WEST); - public Buttons() { - setLayout(new FlowLayout()); - add(jb); - add(new JToggleButton("JToggleButton")); - add(new JCheckBox("JCheckBox")); - add(new JRadioButton("JRadioButton")); - JPanel jp = new JPanel(); - jp.setBorder(new TitledBorder("Directions")); - jp.add(up); - jp.add(down); - jp.add(left); - jp.add(right); - add(jp); - } - public static void main(String[] args) { - run(new Buttons(), 350, 200); - } -} diff --git a/ui/CheckBoxes.java b/ui/CheckBoxes.java deleted file mode 100644 index 1aa99a843..000000000 --- a/ui/CheckBoxes.java +++ /dev/null @@ -1,35 +0,0 @@ -// ui/CheckBoxes.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Using JCheckBoxes -import javax.swing.*; -import java.awt.*; -import static onjava.SwingConsole.*; - -public class CheckBoxes extends JFrame { - private JTextArea t = new JTextArea(6, 15); - private JCheckBox - cb1 = new JCheckBox("Check Box 1"), - cb2 = new JCheckBox("Check Box 2"), - cb3 = new JCheckBox("Check Box 3"); - public CheckBoxes() { - cb1.addActionListener(e -> trace("1", cb1)); - cb2.addActionListener(e -> trace("2", cb2)); - cb3.addActionListener(e -> trace("3", cb3)); - setLayout(new FlowLayout()); - add(new JScrollPane(t)); - add(cb1); - add(cb2); - add(cb3); - } - private void trace(String b, JCheckBox cb) { - if(cb.isSelected()) - t.append("Box " + b + " Set\n"); - else - t.append("Box " + b + " Cleared\n"); - } - public static void main(String[] args) { - run(new CheckBoxes(), 200, 300); - } -} diff --git a/ui/ColorBoxes.java b/ui/ColorBoxes.java deleted file mode 100644 index 403be7989..000000000 --- a/ui/ColorBoxes.java +++ /dev/null @@ -1,57 +0,0 @@ -// ui/ColorBoxes.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// A visual demonstration of threading -import javax.swing.*; -import java.awt.*; -import java.util.concurrent.*; -import java.util.*; -import static onjava.SwingConsole.*; - -class CBox extends JPanel implements Runnable { - private int pause; - private static SplittableRandom rand = new SplittableRandom(); - private Color color = new Color(0); - public void paintComponent(Graphics g) { - g.setColor(color); - Dimension s = getSize(); - g.fillRect(0, 0, s.width, s.height); - } - public CBox(int pause) { this.pause = pause; } - public void run() { - try { - while(!Thread.interrupted()) { - color = new Color(rand.nextInt(0x1000000)); - repaint(); // Asynchronously request a paint() - TimeUnit.MILLISECONDS.sleep(pause); - } - } catch(InterruptedException e) { - // Acceptable way to exit - } - } -} - -public class ColorBoxes extends JFrame { - private int grid = 12; - private int pause = 50; - private static ExecutorService exec = - Executors.newCachedThreadPool(); - public void setUp() { - setLayout(new GridLayout(grid, grid)); - for(int i = 0; i < grid * grid; i++) { - CBox cb = new CBox(pause); - add(cb); - exec.execute(cb); - } - } - public static void main(String[] args) { - ColorBoxes boxes = new ColorBoxes(); - if(args.length > 0) - boxes.grid = new Integer(args[0]); - if(args.length > 1) - boxes.pause = new Integer(args[1]); - boxes.setUp(); - run(boxes, 500, 400); - } -} diff --git a/ui/ComboBoxes.java b/ui/ComboBoxes.java deleted file mode 100644 index aa2475c5d..000000000 --- a/ui/ComboBoxes.java +++ /dev/null @@ -1,38 +0,0 @@ -// ui/ComboBoxes.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Using drop-down lists -import javax.swing.*; -import java.awt.*; -import static onjava.SwingConsole.*; - -public class ComboBoxes extends JFrame { - private String[] description = { - "Ebullient", "Obtuse", "Recalcitrant", "Brilliant", - "Somnescent", "Timorous", "Florid", "Putrescent" - }; - private JTextField t = new JTextField(15); - private JComboBox c = new JComboBox<>(); - private JButton b = new JButton("Add items"); - private int count = 0; - public ComboBoxes() { - for(int i = 0; i < 4; i++) - c.addItem(description[count++]); - t.setEditable(false); - b.addActionListener(e -> { - if(count < description.length) - c.addItem(description[count++]); - }); - c.addActionListener(e -> t.setText("index: " + - c.getSelectedIndex() + " " + - ((JComboBox)e.getSource()).getSelectedItem())); - setLayout(new FlowLayout()); - add(t); - add(c); - add(b); - } - public static void main(String[] args) { - run(new ComboBoxes(), 200, 175); - } -} diff --git a/ui/Dialogs.java b/ui/Dialogs.java deleted file mode 100644 index ae1fb96b2..000000000 --- a/ui/Dialogs.java +++ /dev/null @@ -1,33 +0,0 @@ -// ui/Dialogs.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Creating and using Dialog Boxes -import javax.swing.*; -import java.awt.*; -import static onjava.SwingConsole.*; - -class MyDialog extends JDialog { - public MyDialog(JFrame parent) { - super(parent, "My dialog", true); - setLayout(new FlowLayout()); - add(new JLabel("Here is my dialog")); - JButton ok = new JButton("OK"); - ok.addActionListener(e -> - dispose()); // Closes the dialog - add(ok); - setSize(150,125); - } -} - -public class Dialogs extends JFrame { - private JButton b1 = new JButton("Dialog Box"); - private MyDialog dlg = new MyDialog(null); - public Dialogs() { - b1.addActionListener(e -> dlg.setVisible(true)); - add(b1); - } - public static void main(String[] args) { - run(new Dialogs(), 125, 75); - } -} diff --git a/ui/Face0.gif b/ui/Face0.gif deleted file mode 100644 index 9850c6d37..000000000 Binary files a/ui/Face0.gif and /dev/null differ diff --git a/ui/Face1.gif b/ui/Face1.gif deleted file mode 100644 index 691fe54a2..000000000 Binary files a/ui/Face1.gif and /dev/null differ diff --git a/ui/Face2.gif b/ui/Face2.gif deleted file mode 100644 index 9b325c511..000000000 Binary files a/ui/Face2.gif and /dev/null differ diff --git a/ui/Face3.gif b/ui/Face3.gif deleted file mode 100644 index 2bbac492e..000000000 Binary files a/ui/Face3.gif and /dev/null differ diff --git a/ui/Face4.gif b/ui/Face4.gif deleted file mode 100644 index 8d4605e04..000000000 Binary files a/ui/Face4.gif and /dev/null differ diff --git a/ui/Faces.java b/ui/Faces.java deleted file mode 100644 index 834dae892..000000000 --- a/ui/Faces.java +++ /dev/null @@ -1,55 +0,0 @@ -// ui/Faces.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Icon behavior in JButtons -import javax.swing.*; -import java.awt.*; -import static onjava.SwingConsole.*; - -public class Faces extends JFrame { - private static Icon[] faces; - private JButton jb, jb2 = new JButton("Disable"); - private boolean mad = false; - public Faces() { - faces = new Icon[]{ - new ImageIcon(getClass().getResource("Face0.gif")), - new ImageIcon(getClass().getResource("Face1.gif")), - new ImageIcon(getClass().getResource("Face2.gif")), - new ImageIcon(getClass().getResource("Face3.gif")), - new ImageIcon(getClass().getResource("Face4.gif")), - }; - jb = new JButton("JButton", faces[3]); - setLayout(new FlowLayout()); - jb.addActionListener(e -> { - if(mad) { - jb.setIcon(faces[3]); - mad = false; - } else { - jb.setIcon(faces[0]); - mad = true; - } - jb.setVerticalAlignment(JButton.TOP); - jb.setHorizontalAlignment(JButton.LEFT); - }); - jb.setRolloverEnabled(true); - jb.setRolloverIcon(faces[1]); - jb.setPressedIcon(faces[2]); - jb.setDisabledIcon(faces[4]); - jb.setToolTipText("Yow!"); - add(jb); - jb2.addActionListener(e -> { - if(jb.isEnabled()) { - jb.setEnabled(false); - jb2.setText("Enable"); - } else { - jb.setEnabled(true); - jb2.setText("Disable"); - } - }); - add(jb2); - } - public static void main(String[] args) { - run(new Faces(), 250, 125); - } -} diff --git a/ui/FileChooserTest.java b/ui/FileChooserTest.java deleted file mode 100644 index 240b3ebf0..000000000 --- a/ui/FileChooserTest.java +++ /dev/null @@ -1,60 +0,0 @@ -// ui/FileChooserTest.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Demonstration of File dialog boxes -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import static onjava.SwingConsole.*; - -public class FileChooserTest extends JFrame { - private JTextField - fileName = new JTextField(), - dir = new JTextField(); - private JButton - open = new JButton("Open"), - save = new JButton("Save"); - public FileChooserTest() { - JPanel p = new JPanel(); - open.addActionListener(event -> { - JFileChooser c = new JFileChooser(); - // Demonstrate "Open" dialog: - int rVal = c.showOpenDialog(FileChooserTest.this); - if(rVal == JFileChooser.APPROVE_OPTION) { - fileName.setText(c.getSelectedFile().getName()); - dir.setText(c.getCurrentDirectory().toString()); - } - if(rVal == JFileChooser.CANCEL_OPTION) { - fileName.setText("You pressed cancel"); - dir.setText(""); - } - }); - p.add(open); - save.addActionListener(event -> { - JFileChooser c = new JFileChooser(); - // Demonstrate "Save" dialog: - int rVal = c.showSaveDialog(FileChooserTest.this); - if(rVal == JFileChooser.APPROVE_OPTION) { - fileName.setText(c.getSelectedFile().getName()); - dir.setText(c.getCurrentDirectory().toString()); - } - if(rVal == JFileChooser.CANCEL_OPTION) { - fileName.setText("You pressed cancel"); - dir.setText(""); - } - }); - p.add(save); - add(p, BorderLayout.SOUTH); - dir.setEditable(false); - fileName.setEditable(false); - p = new JPanel(); - p.setLayout(new GridLayout(2,1)); - p.add(fileName); - p.add(dir); - add(p, BorderLayout.NORTH); - } - public static void main(String[] args) { - run(new FileChooserTest(), 250, 150); - } -} diff --git a/ui/FlowLayout1.java b/ui/FlowLayout1.java deleted file mode 100644 index 5d707aee9..000000000 --- a/ui/FlowLayout1.java +++ /dev/null @@ -1,19 +0,0 @@ -// ui/FlowLayout1.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Demonstrates FlowLayout -import javax.swing.*; -import java.awt.*; -import static onjava.SwingConsole.*; - -public class FlowLayout1 extends JFrame { - public FlowLayout1() { - setLayout(new FlowLayout()); - for(int i = 0; i < 20; i++) - add(new JButton("Button " + i)); - } - public static void main(String[] args) { - run(new FlowLayout1(), 300, 300); - } -} diff --git a/ui/GridLayout1.java b/ui/GridLayout1.java deleted file mode 100644 index 0ff08ddcf..000000000 --- a/ui/GridLayout1.java +++ /dev/null @@ -1,19 +0,0 @@ -// ui/GridLayout1.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Demonstrates GridLayout -import javax.swing.*; -import java.awt.*; -import static onjava.SwingConsole.*; - -public class GridLayout1 extends JFrame { - public GridLayout1() { - setLayout(new GridLayout(7,3)); - for(int i = 0; i < 20; i++) - add(new JButton("Button " + i)); - } - public static void main(String[] args) { - run(new GridLayout1(), 300, 300); - } -} diff --git a/ui/HTMLButton.java b/ui/HTMLButton.java deleted file mode 100644 index 9581439f4..000000000 --- a/ui/HTMLButton.java +++ /dev/null @@ -1,27 +0,0 @@ -// ui/HTMLButton.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Putting HTML text on Swing components -import javax.swing.*; -import java.awt.*; -import static onjava.SwingConsole.*; - -public class HTMLButton extends JFrame { - private JButton b = new JButton( - "" + - "
Hello!
Press me now!"); - public HTMLButton() { - b.addActionListener(e -> { - add(new JLabel("" + - "Kapow!")); - // Force a re-layout to include the new label: - validate(); - }); - setLayout(new FlowLayout()); - add(b); - } - public static void main(String[] args) { - run(new HTMLButton(), 200, 500); - } -} diff --git a/ui/HelloLabel.java b/ui/HelloLabel.java deleted file mode 100644 index 76115ea9a..000000000 --- a/ui/HelloLabel.java +++ /dev/null @@ -1,20 +0,0 @@ -// ui/HelloLabel.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import javax.swing.*; -import java.util.concurrent.*; - -public class HelloLabel { - public static void - main(String[] args) throws Exception { - JFrame frame = new JFrame("Hello Swing"); - JLabel label = new JLabel("A Label"); - frame.add(label); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setSize(300, 100); - frame.setVisible(true); - TimeUnit.SECONDS.sleep(1); - label.setText("Hey! This is Different!"); - } -} diff --git a/ui/HelloSwing.java b/ui/HelloSwing.java deleted file mode 100644 index b3971346e..000000000 --- a/ui/HelloSwing.java +++ /dev/null @@ -1,14 +0,0 @@ -// ui/HelloSwing.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import javax.swing.*; - -public class HelloSwing { - public static void main(String[] args) { - JFrame frame = new JFrame("Hello Swing"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setSize(300, 100); - frame.setVisible(true); - } -} diff --git a/ui/InterruptableLongRunningCallable.java b/ui/InterruptableLongRunningCallable.java deleted file mode 100644 index 95dc5ce5e..000000000 --- a/ui/InterruptableLongRunningCallable.java +++ /dev/null @@ -1,54 +0,0 @@ -// ui/InterruptableLongRunningCallable.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Using Callables for long-running tasks -import javax.swing.*; -import java.awt.*; -import java.util.concurrent.*; -import onjava.*; -import static onjava.SwingConsole.*; - -class CallableTask extends Task -implements Callable { - @Override - public String call() { - run(); - return "Return value of " + this; - } -} - -public class -InterruptableLongRunningCallable extends JFrame { - private JButton - b1 = new JButton("Start Long Running Task"), - b2 = new JButton("End Long Running Task"), - b3 = new JButton("Get results"); - private TaskManager manager = - new TaskManager<>(); - public InterruptableLongRunningCallable() { - b1.addActionListener(e -> { - CallableTask task = new CallableTask(); - manager.add(task); - System.out.println(task + " added to the queue"); - }); - b2.addActionListener(e -> { - for(String result : manager.purge()) - System.out.println(result); - }); - b3.addActionListener(e -> { - // Sample call to a Task method: - for(TaskItem tt : manager) - tt.task.id(); // No cast required - for(String result : manager.getResults()) - System.out.println(result); - }); - setLayout(new FlowLayout()); - add(b1); - add(b2); - add(b3); - } - public static void main(String[] args) { - run(new InterruptableLongRunningCallable(), 200, 150); - } -} diff --git a/ui/InterruptableLongRunningTask.java b/ui/InterruptableLongRunningTask.java deleted file mode 100644 index a40dc783d..000000000 --- a/ui/InterruptableLongRunningTask.java +++ /dev/null @@ -1,52 +0,0 @@ -// ui/InterruptableLongRunningTask.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Long-running tasks in threads -import javax.swing.*; -import java.awt.*; -import java.util.concurrent.*; -import static onjava.SwingConsole.*; - -class Task implements Runnable { - private static int counter = 0; - private final int id = counter++; - @Override - public void run() { - System.out.println(this + " started"); - try { - TimeUnit.SECONDS.sleep(3); - } catch(InterruptedException e) { - System.out.println(this + " interrupted"); - return; - } - System.out.println(this + " completed"); - } - @Override - public String toString() { return "Task " + id; } - public long id() { return id; } -}; - -public class InterruptableLongRunningTask extends JFrame { - private JButton - b1 = new JButton("Start Long Running Task"), - b2 = new JButton("End Long Running Task"); - ExecutorService executor = - Executors.newSingleThreadExecutor(); - public InterruptableLongRunningTask() { - b1.addActionListener(e -> { - Task task = new Task(); - executor.execute(task); - System.out.println(task + " added to the queue"); - }); - b2.addActionListener(e -> { - executor.shutdownNow(); // Heavy-handed - }); - setLayout(new FlowLayout()); - add(b1); - add(b2); - } - public static void main(String[] args) { - run(new InterruptableLongRunningTask(), 200, 150); - } -} diff --git a/ui/List.java b/ui/List.java deleted file mode 100644 index 51e4e16ee..000000000 --- a/ui/List.java +++ /dev/null @@ -1,61 +0,0 @@ -// ui/List.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import javax.swing.*; -import javax.swing.border.*; -import javax.swing.event.*; -import java.awt.*; -import java.awt.event.*; -import static onjava.SwingConsole.*; - -public class List extends JFrame { - private String[] flavors = { - "Chocolate", "Strawberry", "Vanilla Fudge Swirl", - "Mint Chip", "Mocha Almond Fudge", "Rum Raisin", - "Praline Cream", "Mud Pie" - }; - private int count = 0; - private DefaultListModel lItems = - new DefaultListModel<>(); - private JList lst = new JList<>(lItems); - private JTextArea t = - new JTextArea(flavors.length, 20); - private JButton b = new JButton("Add Item"); - private ActionListener bl = e -> { - if(count < flavors.length) { - lItems.add(0, flavors[count++]); - } else { - // Disable, since there are no more - // flavors left to be added to the List - b.setEnabled(false); - } - }; - private ListSelectionListener ll = e -> { - if(e.getValueIsAdjusting()) return; - t.setText(""); - for(Object item : lst.getSelectedValuesList()) - t.append(item + "\n"); - }; - public List() { - t.setEditable(false); - setLayout(new FlowLayout()); - // Create Borders for components: - Border brd = BorderFactory.createMatteBorder( - 1, 1, 2, 2, Color.BLACK); - lst.setBorder(brd); - t.setBorder(brd); - // Add the first four items to the List - for(int i = 0; i < 4; i++) - lItems.addElement(flavors[count++]); - add(t); - add(lst); - add(b); - // Register event listeners - lst.addListSelectionListener(ll); - b.addActionListener(bl); - } - public static void main(String[] args) { - run(new List(), 250, 375); - } -} diff --git a/ui/LongRunningTask.java b/ui/LongRunningTask.java deleted file mode 100644 index 4cbc3e141..000000000 --- a/ui/LongRunningTask.java +++ /dev/null @@ -1,36 +0,0 @@ -// ui/LongRunningTask.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// A badly designed program -import javax.swing.*; -import java.awt.*; -import java.util.concurrent.*; -import static onjava.SwingConsole.*; - -public class LongRunningTask extends JFrame { - private JButton - b1 = new JButton("Start Long Running Task"), - b2 = new JButton("End Long Running Task"); - public LongRunningTask() { - b1.addActionListener(e -> { - try { - TimeUnit.SECONDS.sleep(3); - } catch(InterruptedException ex) { - System.out.println("Task interrupted"); - return; - } - System.out.println("Task completed"); - }); - b2.addActionListener(e -> { - // Interrupt yourself? - Thread.currentThread().interrupt(); - }); - setLayout(new FlowLayout()); - add(b1); - add(b2); - } - public static void main(String[] args) { - run(new LongRunningTask(), 200, 150); - } -} diff --git a/ui/LookAndFeel.java b/ui/LookAndFeel.java deleted file mode 100644 index b49f5e641..000000000 --- a/ui/LookAndFeel.java +++ /dev/null @@ -1,90 +0,0 @@ -// ui/LookAndFeel.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Selecting different looks & feels -// {Args: motif} -import javax.swing.*; -import java.awt.*; -import java.util.*; -import static onjava.SwingConsole.*; - -public class LookAndFeel extends JFrame { - private String[] choices = - "Eeny Meeny Minnie Mickey Moe Larry Curly" - .split(" "); - private Component[] samples = { - new JButton("JButton"), - new JTextField("JTextField"), - new JLabel("JLabel"), - new JCheckBox("JCheckBox"), - new JRadioButton("Radio"), - new JComboBox<>(choices), - new JList<>(choices), - }; - private static - Map optionMap = new HashMap<>(); - private static String options = ""; - public LookAndFeel() { - super("Look And Feel"); - setLayout(new FlowLayout()); - for(Component component : samples) - add(component); - } - public static void initOptions() { - if(optionMap.isEmpty()) { - UIManager.LookAndFeelInfo[] lafi = - UIManager.getInstalledLookAndFeels(); - for(UIManager.LookAndFeelInfo lf : lafi) { - String classname = lf.getClassName(); - String[] parts = classname.split("\\."); - String option = parts[parts.length - 2]; - optionMap.put(option, classname); - } - for(String option : optionMap.keySet()) - options += option + " | "; - options = - options.substring(0, options.length() - 3); - options = "cross | system | " + options; - } - } - private static void usageError() { - System.out.println( - "Usage:LookAndFeel [ " + options + " ]"); - System.exit(1); - } - public static void main(String[] args) { - initOptions(); - if(args.length == 0) usageError(); - try { - switch(args[0]) { - case "cross": - UIManager.setLookAndFeel(UIManager. - getCrossPlatformLookAndFeelClassName()); - break; - case "system": - UIManager.setLookAndFeel(UIManager. - getSystemLookAndFeelClassName()); - break; - case "motif": - UIManager.setLookAndFeel("com.sun.java."+ - "swing.plaf.motif.MotifLookAndFeel"); - break; - default: - if(optionMap.containsKey(args[0])) - UIManager.setLookAndFeel( - optionMap.get(args[0])); - else - usageError(); - } - } catch(ClassNotFoundException | - InstantiationException | - IllegalAccessException | - UnsupportedLookAndFeelException e) { - usageError(); - } - // Note the look & feel must be set before - // any components are created. - run(new LookAndFeel(), 300, 300); - } -} diff --git a/ui/Menus.java b/ui/Menus.java deleted file mode 100644 index a8328d4bb..000000000 --- a/ui/Menus.java +++ /dev/null @@ -1,163 +0,0 @@ -// ui/Menus.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Submenus, check box menu items, swapping menus, -// mnemonics (shortcuts) and action commands -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import static onjava.SwingConsole.*; - -public class Menus extends JFrame { - private String[] flavors = { - "Chocolate", "Strawberry", "Vanilla Fudge Swirl", - "Mint Chip", "Mocha Almond Fudge", "Rum Raisin", - "Praline Cream", "Mud Pie" - }; - private JTextField t = new JTextField("No flavor", 30); - private JMenuBar mb1 = new JMenuBar(); - private JMenu - f = new JMenu("File"), - m = new JMenu("Flavors"), - s = new JMenu("Safety"); - // Alternative approach: - private JCheckBoxMenuItem[] safety = { - new JCheckBoxMenuItem("Guard"), - new JCheckBoxMenuItem("Hide") - }; - private JMenuItem[] file = { new JMenuItem("Open") }; - // A second menu bar to swap to: - private JMenuBar mb2 = new JMenuBar(); - private JMenu fooBar = new JMenu("fooBar"); - private JMenuItem[] other = { - // Adding a menu shortcut (mnemonic) is very - // simple, but only JMenuItems can have them - // in their constructors: - new JMenuItem("Foo", KeyEvent.VK_F), - new JMenuItem("Bar", KeyEvent.VK_A), - // No shortcut: - new JMenuItem("Baz"), - }; - private JButton b = new JButton("Swap Menus"); - class BL implements ActionListener { - @Override - public void actionPerformed(ActionEvent e) { - JMenuBar m = getJMenuBar(); - setJMenuBar(m == mb1 ? mb2 : mb1); - validate(); // Refresh the frame - } - } - class ML implements ActionListener { - @Override - public void actionPerformed(ActionEvent e) { - JMenuItem target = (JMenuItem)e.getSource(); - String actionCommand = target.getActionCommand(); - if(actionCommand.equals("Open")) { - String s = t.getText(); - boolean chosen = false; - for(String flavor : flavors) - if(s.equals(flavor)) - chosen = true; - if(!chosen) - t.setText("Choose a flavor first!"); - else - t.setText("Opening " + s + ". Mmm, mm!"); - } - } - } - class FL implements ActionListener { - @Override - public void actionPerformed(ActionEvent e) { - JMenuItem target = (JMenuItem)e.getSource(); - t.setText(target.getText()); - } - } - // Alternatively, you can create a different - // class for each different MenuItem. Then you - // don't have to figure out which one it is: - class FooL implements ActionListener { - @Override - public void actionPerformed(ActionEvent e) { - t.setText("Foo selected"); - } - } - class BarL implements ActionListener { - @Override - public void actionPerformed(ActionEvent e) { - t.setText("Bar selected"); - } - } - class BazL implements ActionListener { - @Override - public void actionPerformed(ActionEvent e) { - t.setText("Baz selected"); - } - } - class CMIL implements ItemListener { - @Override - public void itemStateChanged(ItemEvent e) { - JCheckBoxMenuItem target = - (JCheckBoxMenuItem)e.getSource(); - String actionCommand = target.getActionCommand(); - switch (actionCommand) { - case "Guard": - t.setText("Guard the Ice Cream! " + - "Guarding is " + target.getState()); - break; - case "Hide": - t.setText("Hide the Ice Cream! " + - "Is it hidden? " + target.getState()); - break; - } - } - } - public Menus() { - ML ml = new ML(); - CMIL cmil = new CMIL(); - safety[0].setActionCommand("Guard"); - safety[0].setMnemonic(KeyEvent.VK_G); - safety[0].addItemListener(cmil); - safety[1].setActionCommand("Hide"); - safety[1].setMnemonic(KeyEvent.VK_H); - safety[1].addItemListener(cmil); - other[0].addActionListener(new FooL()); - other[1].addActionListener(new BarL()); - other[2].addActionListener(new BazL()); - FL fl = new FL(); - int n = 0; - for(String flavor : flavors) { - JMenuItem mi = new JMenuItem(flavor); - mi.addActionListener(fl); - m.add(mi); - // Add separators at intervals: - if((n++ + 1) % 3 == 0) - m.addSeparator(); - } - for(JCheckBoxMenuItem sfty : safety) - s.add(sfty); - s.setMnemonic(KeyEvent.VK_A); - f.add(s); - f.setMnemonic(KeyEvent.VK_F); - for(JMenuItem file1 : file) { - file1.addActionListener(ml); - f.add(file1); - } - mb1.add(f); - mb1.add(m); - setJMenuBar(mb1); - t.setEditable(false); - add(t, BorderLayout.CENTER); - // Set up the system for swapping menus: - b.addActionListener(new BL()); - b.setMnemonic(KeyEvent.VK_S); - add(b, BorderLayout.NORTH); - for(JMenuItem oth : other) - fooBar.add(oth); - fooBar.setMnemonic(KeyEvent.VK_B); - mb2.add(fooBar); - } - public static void main(String[] args) { - run(new Menus(), 300, 200); - } -} diff --git a/ui/MessageBoxes.java b/ui/MessageBoxes.java deleted file mode 100644 index bd2fab08e..000000000 --- a/ui/MessageBoxes.java +++ /dev/null @@ -1,72 +0,0 @@ -// ui/MessageBoxes.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Demonstrates JOptionPane -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import static onjava.SwingConsole.*; - -public class MessageBoxes extends JFrame { - private JButton[] b = { - new JButton("Alert"), new JButton("Yes/No"), - new JButton("Color"), new JButton("Input"), - new JButton("3 Vals") - }; - private JTextField txt = new JTextField(15); - private ActionListener al = e -> { - String id = ((JButton)e.getSource()).getText(); - switch (id) { - case "Alert": - JOptionPane.showMessageDialog(null, - "There's a bug on you!", "Hey!", - JOptionPane.ERROR_MESSAGE); - break; - case "Yes/No": - JOptionPane.showConfirmDialog(null, - "or no", "choose yes", - JOptionPane.YES_NO_OPTION); - break; - case "Color": - Object[] options = { "Red", "Green" }; - int sel = JOptionPane.showOptionDialog( - null, "Choose a Color!", "Warning", - JOptionPane.DEFAULT_OPTION, - JOptionPane.WARNING_MESSAGE, null, - options, options[0]); - if(sel != JOptionPane.CLOSED_OPTION) - txt.setText("Color Selected: " + options[sel]); - break; - case "Input": { - String val = JOptionPane.showInputDialog( - "How many fingers do you see?"); - txt.setText(val); - break; - } - case "3 Vals": { - Object[] selections = { - "First", "Second", "Third" - }; - Object val = JOptionPane.showInputDialog( - null, "Choose one", "Input", - JOptionPane.INFORMATION_MESSAGE, - null, selections, selections[0]); - if(val != null) - txt.setText(val.toString()); - break; - } - } - }; - public MessageBoxes() { - setLayout(new FlowLayout()); - for(JButton b1 : b) { - b1.addActionListener(al); - add(b1); - } - add(txt); - } - public static void main(String[] args) { - run(new MessageBoxes(), 200, 200); - } -} diff --git a/ui/MonitoredLongRunningCallable.java b/ui/MonitoredLongRunningCallable.java deleted file mode 100644 index adbf6bad4..000000000 --- a/ui/MonitoredLongRunningCallable.java +++ /dev/null @@ -1,81 +0,0 @@ -// ui/MonitoredLongRunningCallable.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Displaying task progress with ProgressMonitors -// {IgnoreOutput} -import javax.swing.*; -import java.awt.*; -import java.util.concurrent.*; -import onjava.*; -import static onjava.SwingConsole.*; - -class MonitoredCallable implements Callable { - private static int counter = 0; - private final int id = counter++; - private final ProgressMonitor monitor; - private final static int MAX = 8; - public MonitoredCallable(ProgressMonitor monitor) { - this.monitor = monitor; - monitor.setNote(toString()); - monitor.setMaximum(MAX - 1); - monitor.setMillisToPopup(500); - } - @Override - public String call() { - System.out.println(this + " started"); - try { - for(int i = 0; i < MAX; i++) { - TimeUnit.MILLISECONDS.sleep(500); - if(monitor.isCanceled()) - Thread.currentThread().interrupt(); - final int progress = i; - SwingUtilities.invokeLater(() -> - monitor.setProgress(progress)); - } - } catch(InterruptedException e) { - monitor.close(); - System.out.println(this + " interrupted"); - return "Result: " + this + " interrupted"; - } - System.out.println(this + " completed"); - return "Result: " + this + " completed"; - } - @Override - public String toString() { return "Task " + id; } -}; - -public class MonitoredLongRunningCallable extends JFrame { - private JButton - b1 = new JButton("Start Long Running Task"), - b2 = new JButton("End Long Running Task"), - b3 = new JButton("Get results"); - private TaskManager manager = - new TaskManager<>(); - public MonitoredLongRunningCallable() { - b1.addActionListener(e -> { - MonitoredCallable task = new MonitoredCallable( - new ProgressMonitor( - MonitoredLongRunningCallable.this, - "Long-Running Task", "", 0, 0) - ); - manager.add(task); - System.out.println(task + " added to the queue"); - }); - b2.addActionListener(e -> { - for(String result : manager.purge()) - System.out.println(result); - }); - b3.addActionListener(e -> { - for(String result : manager.getResults()) - System.out.println(result); - }); - setLayout(new FlowLayout()); - add(b1); - add(b2); - add(b3); - } - public static void main(String[] args) { - run(new MonitoredLongRunningCallable(), 200, 500); - } -} diff --git a/ui/Popup.java b/ui/Popup.java deleted file mode 100644 index 67469e363..000000000 --- a/ui/Popup.java +++ /dev/null @@ -1,53 +0,0 @@ -// ui/Popup.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Creating popup menus with Swing -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import static onjava.SwingConsole.*; - -public class Popup extends JFrame { - private JPopupMenu popup = new JPopupMenu(); - private JTextField t = new JTextField(10); - public Popup() { - setLayout(new FlowLayout()); - add(t); - ActionListener al = e -> - t.setText(((JMenuItem)e.getSource()).getText()); - JMenuItem m = new JMenuItem("Hither"); - m.addActionListener(al); - popup.add(m); - m = new JMenuItem("Yon"); - m.addActionListener(al); - popup.add(m); - m = new JMenuItem("Afar"); - m.addActionListener(al); - popup.add(m); - popup.addSeparator(); - m = new JMenuItem("Stay Here"); - m.addActionListener(al); - popup.add(m); - PopupListener pl = new PopupListener(); - addMouseListener(pl); - t.addMouseListener(pl); - } - class PopupListener extends MouseAdapter { - @Override - public void mousePressed(MouseEvent e) { - maybeShowPopup(e); - } - @Override - public void mouseReleased(MouseEvent e) { - maybeShowPopup(e); - } - private void maybeShowPopup(MouseEvent e) { - if(e.isPopupTrigger()) - popup.show(e.getComponent(), e.getX(), e.getY()); - } - } - public static void main(String[] args) { - run(new Popup(), 300, 200); - } -} diff --git a/ui/Progress.java b/ui/Progress.java deleted file mode 100644 index a1e4b99c5..000000000 --- a/ui/Progress.java +++ /dev/null @@ -1,35 +0,0 @@ -// ui/Progress.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Using sliders, progress bars and progress monitors -import javax.swing.*; -import javax.swing.border.*; -import java.awt.*; -import static onjava.SwingConsole.*; - -public class Progress extends JFrame { - private JProgressBar pb = new JProgressBar(); - private ProgressMonitor pm = new ProgressMonitor( - this, "Monitoring Progress", "Test", 0, 100); - private JSlider sb = - new JSlider(JSlider.HORIZONTAL, 0, 100, 60); - public Progress() { - setLayout(new GridLayout(2,1)); - add(pb); - pm.setProgress(0); - pm.setMillisToPopup(1000); - sb.setValue(0); - sb.setPaintTicks(true); - sb.setMajorTickSpacing(20); - sb.setMinorTickSpacing(5); - sb.setBorder(new TitledBorder("Slide Me")); - pb.setModel(sb.getModel()); // Share model - add(sb); - sb.addChangeListener(e -> - pm.setProgress(sb.getValue())); - } - public static void main(String[] args) { - run(new Progress(), 300, 200); - } -} diff --git a/ui/RadioButtons.java b/ui/RadioButtons.java deleted file mode 100644 index 180e0d5b8..000000000 --- a/ui/RadioButtons.java +++ /dev/null @@ -1,36 +0,0 @@ -// ui/RadioButtons.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Using JRadioButtons -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import static onjava.SwingConsole.*; - -public class RadioButtons extends JFrame { - private JTextField t = new JTextField(15); - private ButtonGroup g = new ButtonGroup(); - private JRadioButton - rb1 = new JRadioButton("one", false), - rb2 = new JRadioButton("two", false), - rb3 = new JRadioButton("three", false); - private ActionListener al = e -> - t.setText("Radio button " + - ((JRadioButton)e.getSource()).getText()); - public RadioButtons() { - rb1.addActionListener(al); - rb2.addActionListener(al); - rb3.addActionListener(al); - g.add(rb1); g.add(rb2); g.add(rb3); - t.setEditable(false); - setLayout(new FlowLayout()); - add(t); - add(rb1); - add(rb2); - add(rb3); - } - public static void main(String[] args) { - run(new RadioButtons(), 200, 125); - } -} diff --git a/ui/ShowAddListeners.java b/ui/ShowAddListeners.java deleted file mode 100644 index e8b8b47d8..000000000 --- a/ui/ShowAddListeners.java +++ /dev/null @@ -1,63 +0,0 @@ -// ui/ShowAddListeners.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Display the "addXXXListener" methods of any Swing class -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import java.lang.reflect.*; -import java.util.regex.*; -import static onjava.SwingConsole.*; - -public class ShowAddListeners extends JFrame { - private JTextField name = new JTextField(25); - private JTextArea results = new JTextArea(40, 65); - private static Pattern addListener = - Pattern.compile("(add\\w+?Listener\\(.*?\\))"); - private static Pattern qualifier = - Pattern.compile("\\w+\\."); - class NameL implements ActionListener { - @Override - public void actionPerformed(ActionEvent e) { - String nm = name.getText().trim(); - if(nm.length() == 0) { - results.setText("No match"); - return; - } - Class kind; - try { - kind = Class.forName("javax.swing." + nm); - } catch(ClassNotFoundException ex) { - results.setText("No match"); - return; - } - Method[] methods = kind.getMethods(); - results.setText(""); - for(Method m : methods) { - Matcher matcher = - addListener.matcher(m.toString()); - if(matcher.find()) - results.append(qualifier.matcher( - matcher.group(1)).replaceAll("") + "\n"); - } - } - } - public ShowAddListeners() { - NameL nameListener = new NameL(); - name.addActionListener(nameListener); - JPanel top = new JPanel(); - top.add(new JLabel( - "Swing class name (press Enter):")); - top.add(name); - add(BorderLayout.NORTH, top); - add(new JScrollPane(results)); - // Initial data and test: - name.setText("JTextArea"); - nameListener.actionPerformed( - new ActionEvent("", 0, "")); - } - public static void main(String[] args) { - run(new ShowAddListeners(), 500, 400); - } -} diff --git a/ui/SimpleMenus.java b/ui/SimpleMenus.java deleted file mode 100644 index b9667e4a8..000000000 --- a/ui/SimpleMenus.java +++ /dev/null @@ -1,40 +0,0 @@ -// ui/SimpleMenus.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import static onjava.SwingConsole.*; - -public class SimpleMenus extends JFrame { - private JTextField t = new JTextField(15); - private ActionListener al = e -> - t.setText(((JMenuItem)e.getSource()).getText()); - private JMenu[] menus = { - new JMenu("Winken"), new JMenu("Blinken"), - new JMenu("Nod") - }; - private JMenuItem[] items = { - new JMenuItem("Fee"), new JMenuItem("Fi"), - new JMenuItem("Fo"), new JMenuItem("Zip"), - new JMenuItem("Zap"), new JMenuItem("Zot"), - new JMenuItem("Olly"), new JMenuItem("Oxen"), - new JMenuItem("Free") - }; - public SimpleMenus() { - for(int i = 0; i < items.length; i++) { - items[i].addActionListener(al); - menus[i % 3].add(items[i]); - } - JMenuBar mb = new JMenuBar(); - for(JMenu jm : menus) - mb.add(jm); - setJMenuBar(mb); - setLayout(new FlowLayout()); - add(t); - } - public static void main(String[] args) { - run(new SimpleMenus(), 200, 150); - } -} diff --git a/ui/SineWave.java b/ui/SineWave.java deleted file mode 100644 index 6f1915f16..000000000 --- a/ui/SineWave.java +++ /dev/null @@ -1,60 +0,0 @@ -// ui/SineWave.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Drawing with Swing, using a JSlider -import javax.swing.*; -import javax.swing.event.*; -import java.awt.*; -import static onjava.SwingConsole.*; - -class SineDraw extends JPanel { - private static final int SCALEFACTOR = 200; - private int cycles; - private int points; - private double[] sines; - private int[] pts; - public SineDraw() { setCycles(5); } - public void paintComponent(Graphics g) { - super.paintComponent(g); - int maxWidth = getWidth(); - double hstep = (double)maxWidth / (double)points; - int maxHeight = getHeight(); - pts = new int[points]; - for(int i = 0; i < points; i++) - pts[i] = - (int)(sines[i] * maxHeight/2 * .95 + maxHeight/2); - g.setColor(Color.RED); - for(int i = 1; i < points; i++) { - int x1 = (int)((i - 1) * hstep); - int x2 = (int)(i * hstep); - int y1 = pts[i-1]; - int y2 = pts[i]; - g.drawLine(x1, y1, x2, y2); - } - } - public void setCycles(int newCycles) { - cycles = newCycles; - points = SCALEFACTOR * cycles * 2; - sines = new double[points]; - for(int i = 0; i < points; i++) { - double radians = (Math.PI / SCALEFACTOR) * i; - sines[i] = Math.sin(radians); - } - repaint(); - } -} - -public class SineWave extends JFrame { - private SineDraw sines = new SineDraw(); - private JSlider adjustCycles = new JSlider(1, 30, 5); - public SineWave() { - add(sines); - adjustCycles.addChangeListener(e -> sines.setCycles( - ((JSlider)e.getSource()).getValue())); - add(BorderLayout.SOUTH, adjustCycles); - } - public static void main(String[] args) { - run(new SineWave(), 700, 400); - } -} diff --git a/ui/SubmitLabelManipulationTask.java b/ui/SubmitLabelManipulationTask.java deleted file mode 100644 index 1616387bc..000000000 --- a/ui/SubmitLabelManipulationTask.java +++ /dev/null @@ -1,21 +0,0 @@ -// ui/SubmitLabelManipulationTask.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import javax.swing.*; -import java.util.concurrent.*; - -public class SubmitLabelManipulationTask { - public static void - main(String[] args) throws Exception { - JFrame frame = new JFrame("Hello Swing"); - final JLabel label = new JLabel("A Label"); - frame.add(label); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setSize(300, 100); - frame.setVisible(true); - TimeUnit.SECONDS.sleep(1); - SwingUtilities.invokeLater(() -> - label.setText("Hey! This is Different!")); - } -} diff --git a/ui/SubmitSwingProgram.java b/ui/SubmitSwingProgram.java deleted file mode 100644 index fe029cf02..000000000 --- a/ui/SubmitSwingProgram.java +++ /dev/null @@ -1,27 +0,0 @@ -// ui/SubmitSwingProgram.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -import javax.swing.*; -import java.util.concurrent.*; - -public class SubmitSwingProgram extends JFrame { - JLabel label; - public SubmitSwingProgram() { - super("Hello Swing"); - label = new JLabel("A Label"); - add(label); - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - setSize(300, 100); - setVisible(true); - } - static SubmitSwingProgram ssp; - public static void - main(String[] args) throws Exception { - SwingUtilities.invokeLater(() -> - ssp = new SubmitSwingProgram()); - TimeUnit.SECONDS.sleep(1); - SwingUtilities.invokeLater(() -> - ssp.label.setText("Hey! This is Different!")); - } -} diff --git a/ui/TabbedPane1.java b/ui/TabbedPane1.java deleted file mode 100644 index 0d529dec9..000000000 --- a/ui/TabbedPane1.java +++ /dev/null @@ -1,32 +0,0 @@ -// ui/TabbedPane1.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Demonstrates the Tabbed Pane -import javax.swing.*; -import java.awt.*; -import static onjava.SwingConsole.*; - -public class TabbedPane1 extends JFrame { - private String[] flavors = { - "Chocolate", "Strawberry", "Vanilla Fudge Swirl", - "Mint Chip", "Mocha Almond Fudge", "Rum Raisin", - "Praline Cream", "Mud Pie" - }; - private JTabbedPane tabs = new JTabbedPane(); - private JTextField txt = new JTextField(20); - public TabbedPane1() { - int i = 0; - for(String flavor : flavors) - tabs.addTab(flavors[i], - new JButton("Tabbed pane " + i++)); - tabs.addChangeListener(e -> - txt.setText("Tab selected: " + - tabs.getSelectedIndex())); - add(BorderLayout.SOUTH, txt); - add(tabs); - } - public static void main(String[] args) { - run(new TabbedPane1(), 400, 250); - } -} diff --git a/ui/TextArea.java b/ui/TextArea.java deleted file mode 100644 index ab8d8dfb1..000000000 --- a/ui/TextArea.java +++ /dev/null @@ -1,34 +0,0 @@ -// ui/TextArea.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Using the JTextArea control -import javax.swing.*; -import java.awt.*; -import java.util.*; -import onjava.*; -import static onjava.SwingConsole.*; - -public class TextArea extends JFrame { - private JButton - b = new JButton("Add Data"), - c = new JButton("Clear Data"); - private JTextArea t = new JTextArea(20, 40); - private Map m = new HashMap<>(); - public TextArea() { - // Use up all the data: - m.putAll(Countries.capitals()); - b.addActionListener(e -> { - for(Map.Entry me : m.entrySet()) - t.append(me.getKey() + ": "+ me.getValue()+"\n"); - }); - c.addActionListener(e -> t.setText("")); - setLayout(new FlowLayout()); - add(new JScrollPane(t)); - add(b); - add(c); - } - public static void main(String[] args) { - run(new TextArea(), 475, 425); - } -} diff --git a/ui/TextFields.java b/ui/TextFields.java deleted file mode 100644 index eba0abe81..000000000 --- a/ui/TextFields.java +++ /dev/null @@ -1,92 +0,0 @@ -// ui/TextFields.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Text fields and Java events -import javax.swing.*; -import javax.swing.event.*; -import javax.swing.text.*; -import java.awt.*; -import java.awt.event.*; -import static onjava.SwingConsole.*; - -public class TextFields extends JFrame { - private JButton - b1 = new JButton("Get Text"), - b2 = new JButton("Set Text"); - private JTextField - t1 = new JTextField(30), - t2 = new JTextField(30), - t3 = new JTextField(30); - private String s = ""; - private UpperCaseDocument ucd = new UpperCaseDocument(); - public TextFields() { - t1.setDocument(ucd); - ucd.addDocumentListener(new T1()); - b1.addActionListener(new B1()); - b2.addActionListener(new B2()); - t1.addActionListener(new T1A()); - setLayout(new FlowLayout()); - add(b1); - add(b2); - add(t1); - add(t2); - add(t3); - } - class T1 implements DocumentListener { - @Override - public void changedUpdate(DocumentEvent e) {} - @Override - public void insertUpdate(DocumentEvent e) { - t2.setText(t1.getText()); - t3.setText("Text: "+ t1.getText()); - } - @Override - public void removeUpdate(DocumentEvent e) { - t2.setText(t1.getText()); - } - } - class T1A implements ActionListener { - private int count = 0; - @Override - public void actionPerformed(ActionEvent e) { - t3.setText("t1 Action Event " + count++); - } - } - class B1 implements ActionListener { - @Override - public void actionPerformed(ActionEvent e) { - if(t1.getSelectedText() == null) - s = t1.getText(); - else - s = t1.getSelectedText(); - t1.setEditable(true); - } - } - class B2 implements ActionListener { - @Override - public void actionPerformed(ActionEvent e) { - ucd.setUpperCase(false); - t1.setText("Inserted by Button 2: " + s); - ucd.setUpperCase(true); - t1.setEditable(false); - } - } - public static void main(String[] args) { - run(new TextFields(), 375, 200); - } -} - -class UpperCaseDocument extends PlainDocument { - private boolean upperCase = true; - public void setUpperCase(boolean flag) { - upperCase = flag; - } - @Override - public void insertString( - int offset, String str, AttributeSet attSet) - throws BadLocationException { - if(upperCase) str = str.toUpperCase(); - super.insertString(offset, str, attSet); - } -} diff --git a/ui/TextPane.java b/ui/TextPane.java deleted file mode 100644 index 046dd7ace..000000000 --- a/ui/TextPane.java +++ /dev/null @@ -1,28 +0,0 @@ -// ui/TextPane.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// The JTextPane control is a little editor -import javax.swing.*; -import java.awt.*; -import java.util.function.*; -import onjava.*; -import static onjava.SwingConsole.*; - -public class TextPane extends JFrame { - private JButton b = new JButton("Add Text"); - private JTextPane tp = new JTextPane(); - private static Supplier sg = - new Rand.String(7); - public TextPane() { - b.addActionListener(e -> { - for(int i = 1; i < 10; i++) - tp.setText(tp.getText() + sg.get() + "\n"); - }); - add(new JScrollPane(tp)); - add(BorderLayout.SOUTH, b); - } - public static void main(String[] args) { - run(new TextPane(), 475, 425); - } -} diff --git a/ui/TicTacToe.java b/ui/TicTacToe.java deleted file mode 100644 index d7ada215f..000000000 --- a/ui/TicTacToe.java +++ /dev/null @@ -1,83 +0,0 @@ -// ui/TicTacToe.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Dialog boxes and creating your own components -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import static onjava.SwingConsole.*; - -public class TicTacToe extends JFrame { - private JTextField - rows = new JTextField("3"), - cols = new JTextField("3"); - private enum State { BLANK, XX, OO } - static class ToeDialog extends JDialog { - private State turn = State.XX; // Start with x's turn - ToeDialog(int cellsWide, int cellsHigh) { - setTitle("The game itself"); - setLayout(new GridLayout(cellsWide, cellsHigh)); - for(int i = 0; i < cellsWide * cellsHigh; i++) - add(new ToeButton()); - setSize(cellsWide * 50, cellsHigh * 50); - setDefaultCloseOperation(DISPOSE_ON_CLOSE); - } - class ToeButton extends JPanel { - private State state = State.BLANK; - public ToeButton() { addMouseListener(new ML()); } - @Override - public void paintComponent(Graphics g) { - super.paintComponent(g); - int - x1 = 0, y1 = 0, - x2 = getSize().width - 1, - y2 = getSize().height - 1; - g.drawRect(x1, y1, x2, y2); - x1 = x2/4; - y1 = y2/4; - int wide = x2/2, high = y2/2; - if(state == State.XX) { - g.drawLine(x1, y1, x1 + wide, y1 + high); - g.drawLine(x1, y1 + high, x1 + wide, y1); - } - if(state == State.OO) - g.drawOval(x1, y1, x1 + wide/2, y1 + high/2); - } - class ML extends MouseAdapter { - @Override - public void mousePressed(MouseEvent e) { - if(state == State.BLANK) { - state = turn; - turn = - (turn == State.XX ? State.OO : State.XX); - } - else - state = - (state == State.XX ? State.OO : State.XX); - repaint(); - } - } - } - } - public TicTacToe() { - JPanel p = new JPanel(); - p.setLayout(new GridLayout(2,2)); - p.add(new JLabel("Rows", JLabel.CENTER)); - p.add(rows); - p.add(new JLabel("Columns", JLabel.CENTER)); - p.add(cols); - add(p, BorderLayout.NORTH); - JButton b = new JButton("go"); - b.addActionListener(e -> { - JDialog d = new ToeDialog( - new Integer(rows.getText()), - new Integer(cols.getText())); - d.setVisible(true); - }); - add(b, BorderLayout.SOUTH); - } - public static void main(String[] args) { - run(new TicTacToe(), 200, 200); - } -} diff --git a/ui/TrackEvent.java b/ui/TrackEvent.java deleted file mode 100644 index 1192955c0..000000000 --- a/ui/TrackEvent.java +++ /dev/null @@ -1,108 +0,0 @@ -// ui/TrackEvent.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Show events as they happen -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import java.util.*; -import static onjava.SwingConsole.*; - -public class TrackEvent extends JFrame { - private HashMap h = - new HashMap<>(); - private String[] event = { - "focusGained", "focusLost", "keyPressed", - "keyReleased", "keyTyped", "mouseClicked", - "mouseEntered", "mouseExited", "mousePressed", - "mouseReleased", "mouseDragged", "mouseMoved" - }; - private MyButton - b1 = new MyButton(Color.BLUE, "test1"), - b2 = new MyButton(Color.RED, "test2"); - class MyButton extends JButton { - void report(String field, String msg) { - h.get(field).setText(msg); - } - FocusListener fl = new FocusListener() { - @Override - public void focusGained(FocusEvent e) { - report("focusGained", e.paramString()); - } - @Override - public void focusLost(FocusEvent e) { - report("focusLost", e.paramString()); - } - }; - KeyListener kl = new KeyListener() { - @Override - public void keyPressed(KeyEvent e) { - report("keyPressed", e.paramString()); - } - @Override - public void keyReleased(KeyEvent e) { - report("keyReleased", e.paramString()); - } - @Override - public void keyTyped(KeyEvent e) { - report("keyTyped", e.paramString()); - } - }; - MouseListener ml = new MouseListener() { - @Override - public void mouseClicked(MouseEvent e) { - report("mouseClicked", e.paramString()); - } - @Override - public void mouseEntered(MouseEvent e) { - report("mouseEntered", e.paramString()); - } - @Override - public void mouseExited(MouseEvent e) { - report("mouseExited", e.paramString()); - } - @Override - public void mousePressed(MouseEvent e) { - report("mousePressed", e.paramString()); - } - @Override - public void mouseReleased(MouseEvent e) { - report("mouseReleased", e.paramString()); - } - }; - MouseMotionListener mml = new MouseMotionListener() { - @Override - public void mouseDragged(MouseEvent e) { - report("mouseDragged", e.paramString()); - } - @Override - public void mouseMoved(MouseEvent e) { - report("mouseMoved", e.paramString()); - } - }; - public MyButton(Color color, String label) { - super(label); - setBackground(color); - addFocusListener(fl); - addKeyListener(kl); - addMouseListener(ml); - addMouseMotionListener(mml); - } - } - public TrackEvent() { - setLayout(new GridLayout(event.length + 1, 2)); - for(String evt : event) { - JTextField t = new JTextField(); - t.setEditable(false); - add(new JLabel(evt, JLabel.RIGHT)); - add(t); - h.put(evt, t); - } - add(b1); - add(b2); - } - public static void main(String[] args) { - run(new TrackEvent(), 700, 500); - } -} diff --git a/ui/build.xml b/ui/build.xml deleted file mode 100644 index f48dfdb29..000000000 --- a/ui/build.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/unittesting/JUnitDemo.java b/unittesting/JUnitDemo.java deleted file mode 100644 index 8ad0a8466..000000000 --- a/unittesting/JUnitDemo.java +++ /dev/null @@ -1,109 +0,0 @@ -// unittesting/JUnitDemo.java -// (c)2016 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. -// Simple use of JUnit to test ArrayList -// (Install libraries from junit.org) -import java.util.*; -import org.junit.Test; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static java.lang.System.out; - -// So we can see the list objects being created, -// and keep track of when they are cleaned up: -class CountedList extends ArrayList { - private static int counter = 0; - private int id = counter++; - public CountedList() { - out.println("CountedList #" + id); - } - public int getId() { return id; } -} - -public class JUnitDemo { - private CountedList list = new CountedList(); - // You can use the constructor instead of setUp(): - public JUnitDemo() { - for(int i = 0; i < 3; i++) - list.add("" + i); - } - // Thus, setUp() is optional, but is run right - // before the test: - protected void setUp() { - out.println("Set up for " + list.getId()); - } - // tearDown() is also optional, and is called after - // each test. setUp() and tearDown() can be either - // protected or public: - public void tearDown() { - out.println("Tearing down " + list.getId()); - } - // All tests are marked with the @Test annotation: - @Test - public void insert() { - 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() { - 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 reduce code duplication. As long - // as it isn't annotated with @Test, it will not - // be automatically executed by JUnit. - private - void compare(ArrayList lst, String[] strs) { - String[] array = (String[])lst.toArray(); - assertTrue("Arrays not the same length", - array.length == strs.length); - for(int i = 0; i < array.length; i++) - assertEquals(strs[i], array[i]); - } - @Test - public void order() { - out.println("Running testOrder()"); - compare(list, new String[] { "0", "1", "2" }); - } - @Test - public void remove() { - 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() { - 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" }); - } - public static void main(String[] args) { - // Invoke JUnit on the class: - org.junit.runner.JUnitCore.runClasses( - JUnitDemo.class); - } -} -/* Output: -CountedList #0 -Running testAddAll() -CountedList #1 -Running testInsert() -CountedList #2 -Running testRemove() -CountedList #3 -Running testOrder() -CountedList #4 -Running testReplace() -*/ diff --git a/unittesting/build.xml b/unittesting/build.xml deleted file mode 100644 index 7fd331247..000000000 --- a/unittesting/build.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/assertions/Assert1.java b/validating/Assert1.java similarity index 54% rename from assertions/Assert1.java rename to validating/Assert1.java index 96ef9f4a6..53dbfda30 100644 --- a/assertions/Assert1.java +++ b/validating/Assert1.java @@ -1,9 +1,10 @@ -// assertions/Assert1.java -// (c)2016 MindView LLC: see Copyright.txt +// validating/Assert1.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Non-informative style of assert -// {JVMArgs: -ea} // Must run with -ea +// Must run using -ea flag: +// {java -ea Assert1} // {ThrowsException} public class Assert1 { @@ -14,6 +15,5 @@ public static void main(String[] args) { /* Output: ___[ Error Output ]___ Exception in thread "main" java.lang.AssertionError - at Assert1.main(Assert1.java:8) -___[ Exception is Expected ]___ + at Assert1.main(Assert1.java:9) */ diff --git a/validating/Assert2.java b/validating/Assert2.java new file mode 100644 index 000000000..cdc9f89dd --- /dev/null +++ b/validating/Assert2.java @@ -0,0 +1,20 @@ +// validating/Assert2.java +// (c)2021 MindView 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/validating/BadMicroBenchmark.java b/validating/BadMicroBenchmark.java new file mode 100644 index 000000000..5e1ddbd7c --- /dev/null +++ b/validating/BadMicroBenchmark.java @@ -0,0 +1,28 @@ +// validating/BadMicroBenchmark.java +// (c)2021 MindView 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: +Insufficient memory +*/ diff --git a/validating/BadMicroBenchmark2.java b/validating/BadMicroBenchmark2.java new file mode 100644 index 000000000..aab204bfb --- /dev/null +++ b/validating/BadMicroBenchmark2.java @@ -0,0 +1,35 @@ +// validating/BadMicroBenchmark2.java +// (c)2021 MindView 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: 1008 +setAll: 294 +parallelSetAll: 78 +setAll: 88 +*/ diff --git a/validating/CircularQueue.java b/validating/CircularQueue.java new file mode 100644 index 000000000..b42509cf9 --- /dev/null +++ b/validating/CircularQueue.java @@ -0,0 +1,91 @@ +// validating/CircularQueue.java +// (c)2021 MindView 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/validating/CircularQueueException.java b/validating/CircularQueueException.java new file mode 100644 index 000000000..c30710df0 --- /dev/null +++ b/validating/CircularQueueException.java @@ -0,0 +1,12 @@ +// validating/CircularQueueException.java +// (c)2021 MindView 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/validating/CountedList.java b/validating/CountedList.java new file mode 100644 index 000000000..30de1acc5 --- /dev/null +++ b/validating/CountedList.java @@ -0,0 +1,16 @@ +// validating/CountedList.java +// (c)2021 MindView 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/validating/GuavaAssertions.java b/validating/GuavaAssertions.java new file mode 100644 index 000000000..85c724f6f --- /dev/null +++ b/validating/GuavaAssertions.java @@ -0,0 +1,49 @@ +// validating/GuavaAssertions.java +// (c)2021 MindView 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/validating/GuavaPreconditions.java b/validating/GuavaPreconditions.java new file mode 100644 index 000000000..f8f9c702a --- /dev/null +++ b/validating/GuavaPreconditions.java @@ -0,0 +1,125 @@ +// validating/GuavaPreconditions.java +// (c)2021 MindView 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/validating/Inverter1.java b/validating/Inverter1.java new file mode 100644 index 000000000..78ec38dc1 --- /dev/null +++ b/validating/Inverter1.java @@ -0,0 +1,10 @@ +// validating/Inverter1.java +// (c)2021 MindView 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 { + @Override + public String invert(String str) { return str; } +} diff --git a/validating/Inverter2.java b/validating/Inverter2.java new file mode 100644 index 000000000..5ea22f6fd --- /dev/null +++ b/validating/Inverter2.java @@ -0,0 +1,19 @@ +// validating/Inverter2.java +// (c)2021 MindView 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 { + @Override 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/validating/Inverter3.java b/validating/Inverter3.java new file mode 100644 index 000000000..eecf815e3 --- /dev/null +++ b/validating/Inverter3.java @@ -0,0 +1,21 @@ +// validating/Inverter3.java +// (c)2021 MindView 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 { + @Override 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/validating/Inverter4.java b/validating/Inverter4.java new file mode 100644 index 000000000..4bb15f12f --- /dev/null +++ b/validating/Inverter4.java @@ -0,0 +1,26 @@ +// validating/Inverter4.java +// (c)2021 MindView 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"; + @Override 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/assertions/LoaderAssertions.java b/validating/LoaderAssertions.java similarity index 69% rename from assertions/LoaderAssertions.java rename to validating/LoaderAssertions.java index 27914ed70..aa150ad7e 100644 --- a/assertions/LoaderAssertions.java +++ b/validating/LoaderAssertions.java @@ -1,7 +1,7 @@ -// assertions/LoaderAssertions.java -// (c)2016 MindView LLC: see Copyright.txt +// validating/LoaderAssertions.java +// (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. -// Visit http://mindviewinc.com/Books/OnJava/ for more book information. +// Visit http://OnJava8.com for more book information. // Using the class loader to enable assertions // {ThrowsException} @@ -23,6 +23,6 @@ public void go() { Exception in thread "main" java.lang.AssertionError: Loaded.go() at Loaded.go(LoaderAssertions.java:15) - at LoaderAssertions.main(LoaderAssertions.java:9) -___[ Exception is Expected ]___ + at +LoaderAssertions.main(LoaderAssertions.java:9) */ diff --git a/validating/NonNullConstruction.java b/validating/NonNullConstruction.java new file mode 100644 index 000000000..4caa3de54 --- /dev/null +++ b/validating/NonNullConstruction.java @@ -0,0 +1,18 @@ +// validating/NonNullConstruction.java +// (c)2021 MindView LLC: 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/validating/SLF4JLevels.java b/validating/SLF4JLevels.java new file mode 100644 index 000000000..d56821a52 --- /dev/null +++ b/validating/SLF4JLevels.java @@ -0,0 +1,29 @@ +// validating/SLF4JLevels.java +// (c)2021 MindView LLC: 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: +2021-01-24T08:49:37.658 +[main] TRACE SLF4JLevels - Hello +2021-01-24T08:49:37.661 +[main] DEBUG SLF4JLevels - Logging +2021-01-24T08:49:37.661 +[main] INFO SLF4JLevels - Using +2021-01-24T08:49:37.661 +[main] WARN SLF4JLevels - the SLF4J +2021-01-24T08:49:37.661 +[main] ERROR SLF4JLevels - Facade +*/ diff --git a/validating/SLF4JLogging.java b/validating/SLF4JLogging.java new file mode 100644 index 000000000..f8eeb696c --- /dev/null +++ b/validating/SLF4JLogging.java @@ -0,0 +1,17 @@ +// validating/SLF4JLogging.java +// (c)2021 MindView LLC: 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: +2021-01-24T08:49:38.496 +[main] INFO SLF4JLogging - hello logging +*/ diff --git a/validating/SimpleDebugging.java b/validating/SimpleDebugging.java new file mode 100644 index 000000000..609e8e7d5 --- /dev/null +++ b/validating/SimpleDebugging.java @@ -0,0 +1,25 @@ +// validating/SimpleDebugging.java +// (c)2021 MindView 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(); + } +} diff --git a/validating/StringInverter.java b/validating/StringInverter.java new file mode 100644 index 000000000..542788935 --- /dev/null +++ b/validating/StringInverter.java @@ -0,0 +1,9 @@ +// validating/StringInverter.java +// (c)2021 MindView 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/validating/jmh/JMH1.java b/validating/jmh/JMH1.java new file mode 100644 index 000000000..63657c3fa --- /dev/null +++ b/validating/jmh/JMH1.java @@ -0,0 +1,31 @@ +// validating/jmh/JMH1.java +// (c)2021 MindView 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/validating/jmh/JMH2.java b/validating/jmh/JMH2.java new file mode 100644 index 000000000..5010b00ed --- /dev/null +++ b/validating/jmh/JMH2.java @@ -0,0 +1,44 @@ +// validating/jmh/JMH2.java +// (c)2021 MindView 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/validating/jmh/JMH3.java b/validating/jmh/JMH3.java new file mode 100644 index 000000000..7bf22de11 --- /dev/null +++ b/validating/jmh/JMH3.java @@ -0,0 +1,48 @@ +// validating/jmh/JMH3.java +// (c)2021 MindView 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/validating/logback.xml b/validating/logback.xml new file mode 100644 index 000000000..0a774e446 --- /dev/null +++ b/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/validating/tests/CircularQueueTest.java b/validating/tests/CircularQueueTest.java new file mode 100644 index 000000000..920b459be --- /dev/null +++ b/validating/tests/CircularQueueTest.java @@ -0,0 +1,150 @@ +// validating/tests/CircularQueueTest.java +// (c)2021 MindView 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/validating/tests/CountedListTest.java b/validating/tests/CountedListTest.java new file mode 100644 index 000000000..74a29b376 --- /dev/null +++ b/validating/tests/CountedListTest.java @@ -0,0 +1,101 @@ +// validating/tests/CountedListTest.java +// (c)2021 MindView 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/validating/tests/DynamicStringInverterTests.java b/validating/tests/DynamicStringInverterTests.java new file mode 100644 index 000000000..338b65fb0 --- /dev/null +++ b/validating/tests/DynamicStringInverterTests.java @@ -0,0 +1,122 @@ +// validating/tests/DynamicStringInverterTests.java +// (c)2021 MindView 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/validating/tests/StringInverterTests.java b/validating/tests/StringInverterTests.java new file mode 100644 index 000000000..01ada920e --- /dev/null +++ b/validating/tests/StringInverterTests.java @@ -0,0 +1,65 @@ +// validating/tests/StringInverterTests.java +// (c)2021 MindView 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); + } +} diff --git a/verify_output.py b/verify_output.py deleted file mode 100644 index 1a04a0276..000000000 --- a/verify_output.py +++ /dev/null @@ -1,74 +0,0 @@ -# Requires Python 3.5 or greater -# (c)2016 MindView LLC: see Copyright.txt -# We make no guarantees that this code is fit for any purpose. -# Visit http://mindviewinc.com/Books/OnJava/ for more book information. -""" -ToDo: - - Validate errors -""" -from pathlib import Path -from output_duet import Duet, Valid -import os -import collections -import pprint -import itertools - -def trace(*str): pass -# trace = print - -def clean(): - for p in (Path(f) for f in [ - "update_output.bat", - "edit_errors.bat", - "strategies.txt", - "validate_successes.txt", - "validate_failures.txt", - ]): - if p.exists(): - p.unlink() - - -if __name__ == '__main__': - clean() - jfiles = sorted([java.name for java in Path(".").glob("**/*.java")]) - duplicates = sorted([x for x, y in collections.Counter(jfiles).items() if y > 1]) - if duplicates: - print("Duplicates:") - pprint.pprint(duplicates) - - count = 0 - for output in itertools.chain(Path(".").glob("**/*.out"), Path(".").glob("**/*.err")): - duet = Duet(output) - # if duet.error: - # os.system("subl {}".format(duet.java_path)) - trace("duet.ignore:", duet.ignore, duet.java_path ) - if duet.ignore: - continue - v = duet.validate() - if v is Valid.fail: - with Path("validate_failures.txt").open('a') as vf: - print(duet, file = vf) - with Path("strategies.txt").open('a') as st: - print(' "' + duet.java_path.name + '" : IgnoreSortedLines(),', file = st) - with Path("update_output.bat").open('a') as uo: - print('call no ' + str(duet.out_path.with_suffix(".new")), file = uo) - with Path("edit_errors.bat").open('a') as eo: - print('subl ' + str(duet.java_path), file = eo) - if duet.error: - duet.out_path.with_suffix(".new").write_text(duet.generated_un_adjusted) - os.system('subl ' + str(duet.out_path.with_suffix(".new"))) - else: - with Path("validate_successes.txt").open('a') as vs: - print("{:<20}".format(v) + "{}".format(duet.java_path), file = vs) - count += 1 - print("\n" + " Verified files = {} ".format(count).center(60, "*")) - - if Path("validate_failures.txt").exists(): - os.system("subl " - "update_output.bat " - "edit_errors.bat " - "strategies.txt " - "validate_successes.txt " - "validate_failures.txt") - else: - print("\n" + " No Output Errors ".center(60, "="))