Table of Contents
Preface xiii
1 Getting Started: Compiling and Running Java 1
1.0 Introduction 1
1.1 Compiling and Running Java: Standard JDK 2
1.2 Compiling and Running Java: GraalVM for Better Performance 3
1.3 Compiling, Running, and Testing with an IDE 5
1.4 Exploring Java with JShell 11
1.5 Using CLASSPATH Effectively 13
1.6 Downloading and Using the Code Examples 15
1.7 Automating Dependencies, Compilation, Testing, and Deployment with Apache Maven 23
1.8 Automating Dependencies, Compilation, Testing, and Deployment with Gradle 27
1.9 Dealing with Deprecation Warnings 29
1.10 Maintaining Code Correctness with Unit Testing: JUnit 31
1.11 Maintaining Your Code with Continuous Integration 34
1.12 Getting Readable Stack Traces 38
1.13 Finding More Java Source Code 39
1.14 Finding Runnable Java Libraries 40
2 Interacting with the Environment 43
2.0 Introduction 43
2.1 Getting Environment Variables 43
2.2 Getting Information from System Properties 44
2.3 Dealing with Code That Depends on the Java Version or the Operating System 46
2.4 Using Extensions or Other Packaged APIs 51
2.5 Using the Java Modules System 52
3 Strings and Things 57
3.0 Introduction 57
3.1 Taking Strings Apart with Substrings or Tokenizing 60
3.2 Putting Strings Together with StringBuilder 65
3.3 Processing a String One Character at a Time 67
3.4 Aligning, Indenting, and Unindenting Strings 69
3.5 Converting Between Unicode Characters and Strings 73
3.6 Reversing a String by Word or by Character 75
3.7 Expanding and Compressing Tabs 76
3.8 Controlling Case 81
3.9 Entering Nonprintable Characters 82
3.10 Trimming Blanks from the End of a String 83
3.11 Creating a Message with I18N Resources 85
3.12 Using a Particular Locale 88
3.13 Creating a Resource Bundle 89
3.14 Program: A Simple Text Formatter 90
3.15 Program: Soundex Name Comparisons 92
4 Pattern Matching with Regular Expressions 97
4.0 Introduction 97
4.1 Regular Expression Syntax 99
4.2 Using Regexes in Java: Test for a Pattern 106
4.3 Finding the Matching Text 109
4.4 Replacing the Matched Text 112
4.5 Printing All Occurrences of a Pattern 115
4.6 Printing Lines Containing a Pattern 118
4.7 Controlling Case in Regular Expressions 119
4.8 Matching Accented, or Composite, Characters 120
4.9 Matching Newlines in Text 121
4.10 Program: Apache Logfile Parsing 123
4.11 Program: Full Grep 125
5 Numbers 131
5.0 Introduction 131
5.1 Checking Whether a String Is a Valid Number 134
5.2 Converting Numbers to Objects and Vice Versa 135
5.3 Taking a Fraction of an Integer Without Using Floating Point 136
5.4 Working with Floating-Point Numbers 137
5.5 Formatting Numbers 142
5.6 Converting Among Binary, Octal, Decimal, and Hexadecimal 146
5.7 Operating on a Series of Integers 147
5.8 Formatting with Correct Plurals 149
5.9 Generating Random Numbers 151
5.10 Multiplying Matrices 153
5.11 Using Complex Numbers 155
5.12 Handling Very Large Numbers 158
5.13 Program: TempConverter 160
5.14 Program: Number Palindromes 162
6 Dates and Times 167
6.0 Introduction 167
6.1 Finding Today's Date 170
6.2 Formatting Dates and Times 172
6.3 Converting Among Dates/Times, YMDHMS, and Epoch Seconds 174
6.4 Parsing Strings into Dates 175
6.5 Difference Between Two Dates 176
6.6 Adding to or Subtracting from a Date 177
6.7 Handling Recurring Events 178
6.8 Computing Dates Involving Time Zones 181
6.9 Interfacing with Legacy Date and Calendar Classes 182
7 Structuring Data with Java 185
7.0 Introduction 185
7.1 Using Arrays for Data Structuring 186
7.2 Resizing an Array 188
7.3 The Collections Framework 189
7.4 Like an Array, but More Dynamic 190
7.5 Using Generic Types in Your Own Class 194
7.6 How Shall I Iterate Thee? Let Me Enumerate the Ways 197
7.7 Eschewing Duplicates with a Set 201
7.8 Structuring Data in a Linked List 202
7.9 Mapping with Hashtable and HashMap 207
7.10 Storing Strings in Properties and Preferences 209
7.11 Sorting a Collection 213
7.12 Avoiding the Urge to Sort 218
7.13 Finding an Object in a Collection 220
7.14 Converting a Collection to an Array 222
7.15 Making Your Data Iterable 223
7.16 Using a Stack of Objects 226
7.17 Multidimensional Structures 229
7.18 Simplifying Data Objects with Lombok or Record 231
7.19 Program: Timing Comparisons 233
8 Object-Oriented Techniques 237
8.0 Introduction 237
8.1 Object Methods: Formatting Objects with toString(), Comparing with Equals 240
8.2 Using Inner Classes 247
8.3 Providing Callbacks via Interfaces 249
8.4 Polymorphism/Abstract Methods 253
8.5 Using Typesafe Enumerations 255
8.6 Avoiding NPEs with Optional 259
8.7 Enforcing the Singleton Pattern 261
8.8 Roll Your Own Exceptions 263
8.9 Using Dependency Injection 265
8.10 Program: Plotter 268
9 Functional Programming Techniques: Functional Interfaces, Streams, and Parallel Collections 273
9.0 Introduction 273
9.1 Using Lambdas/Closures Instead of Inner Classes 276
9.2 Using Lambda Predefined Interfaces Instead of Your Own 281
9.3 Simplifying Processing with Streams 283
9.4 Simplifying Streams with Collectors 284
9.5 Improving Throughput with Parallel Streams and Collections 288
9.6 Using Existing Code as Functional with Method References 289
9.7 Java Mixins: Mixing in Methods 293
10 Input and Output: Reading, Writing, and Directory Tricks 297
10.0 Introduction 297
10.1 About InputStrearns/Outputstreams and Readers/Writers 299
10.2 Reading a Text File 301
10.3 Reading from the Standard Input or from the Console/Controlling Terminal 304
10.4 Printing with Formatter and printf 308
10.5 Scanning Input with StreamTokenizer 312
10.6 Scanning Input with the Scanner Class 316
10.7 Scanning Input with Grammatical Structure 319
10.8 Copying a File 324
10.9 Reassigning the Standard Streams 325
10.10 Duplicating a Stream as It Is Written; Reassigning Standard Streams 326
10.11 Reading/Writing a Different Character Set 329
10.12 Those Pesky End-of-Line Characters 330
10.13 Beware Platform-Dependent File Code 330
10.14 Reading/Writing Binary Data 331
10.15 Reading and Writing JAR or ZIP Archives 332
10.16 Finding Files in a Filesystem-Neutral Way with getResource() and getResourceAsStream() 336
10.17 Getting File Information: Files and Path 338
10.18 Creating a New File or Directory 345
10.19 Changing a File's Name or Other Attributes 346
10.20 Deleting a File 349
10.21 Creating a Transient/Temporary File 351
10.22 Listing a Directory 354
10.23 Getting the Directory Roots 355
10.24 Using the FileWatcher Service to Get Notified About File Changes 356
10.25 Program: Save User Data to Disk 358
10.26 Program: Find-Walking a File Tree 362
11 Data Science and R 367
11.1 Machine Learning with Java 368
11.2 Using Data In Apache Spark 369
11.3 Using R Interactively 372
11.4 Comparing/Choosing an R Implementation 374
11.5 Using R from Within a Java App: Renjin 375
11.6 Using Java from Within an R Session 377
11.7 Using FastR, the GraalVM Implementation of R 379
11.8 Using R in a Web App 380
12 Network Clients 383
12.0 Introduction 383
12.1 HTTP/REST Web Client 386
12.2 Contacting a Socket Server 388
12.3 Finding and Reporting Network Addresses 389
12.4 Handling Network Errors 391
12.5 Reading and Writing Textual Data 392
12.6 Reading and Writing Binary or Serialized Data 394
12.7 UDP Datagrams 397
12.8 URI, URL, or URN? 400
12.9 Program: TFTP UDP Client 402
12.10 Program: Sockets-Based Chat Client 406
12.11 Program: Simple HTTP Link Checker 410
13 Server-Side Java 413
13.0 Introduction 413
13.1 Opening a Server Socket for Business 414
13.2 Finding Network Interfaces 417
13.3 Returning a Response (String or Binary) 418
13.4 Returning Object Information Across a Network Connection 422
13.5 Handling Multiple Clients 423
13.6 Serving the HTTP Protocol 428
13.7 Securing a Web Server with SSL and JSSE 430
13.8 Creating a REST Service with JAX-RS 433
13.9 Network Logging 436
13.10 Setting Up SLF4J 437
13.11 Network Logging with Log4j 439
13.12 Network Logging with java.util.logging 444
14 Processing JSON Data 449
14.0 Introduction 449
14.1 Generating JSON Directly 451
14.2 Parsing and Writing JSON with Jackson 452
14.3 Parsing and Writing JSON with org.json 453
14.4 Parsing and Writing JSON with JSON-B 455
14.5 Finding JSON Elements with JSON Pointer 457
15 Packages and Packaging 461
15.0 Introduction 461
15.1 Creating a Package 462
15.2 Documenting Classes with Javadoc 464
15.3 Beyond Javadoc: Annotations/Metadata 468
15.4 Preparing a Class as a JavaBean 469
15.5 Archiving with JAR 473
15.6 Running a Program from a JAR 475
15.7 Packaging Web Tier Components into a WAR File 477
15.8 Creating a Smaller Distribution with jlink 478
15.9 Using JPMS to Create a Module 479
16 Threaded Java 483
16.0 Introduction 483
16.1 Running Code in a Different Thread 485
16.2 Displaying a Moving Image with Animation 489
16.3 Stopping a Thread 494
16.4 Rendezvous and Timeouts 497
16.5 Synchronizing Threads with the synchronized Keyword 498
16.6 Simplifying Synchronization with Locks 504
16.7 Simplifying Producer/Consumer with the Queue Interface 508
16.8 Optimizing Parallel Processing with Fork/Join 511
16.9 Scheduling Tasks: Future Times, Background Saving in an Editor 514
17 Reflection, or "A Class Named Class" 519
17.0 Introduction 519
17.1 Getting a Class Descriptor 520
17.2 Finding and Using Methods and Fields 521
17.3 Accessing Private Methods and Fields via Reflection 525
17.4 Loading and Instantiating a Class Dynamically 526
17.5 Constructing a Class from Scratch with a ClassLoader 529
17.6 Constructing a Class from Scratch with JavaCompiler 530
17.7 Performance Timing 533
17.8 Printing Class Information 538
17.9 Listing Classes in a Package 539
17.10 Using and Defining Annotations 542
17.11 Finding Plug-In-Like Classes via Annotations 547
17.12 Program: CrossRef 550
18 Using Java with Other Languages 555
18.0 Introduction 555
18.1 Running an External Program from Java 556
18.2 Running a Program and Capturing Its Output 560
18.3 Calling Other Languages via javax.script 564
18.4 Mixing Languages with GraalVM 566
18.5 Marrying Java and Perl 567
18.6 Calling Other Languages via Native Code 571
18.7 Calling Java from Native Code 576
Afterword dlxxix
A Java Then and Now 581
Index 591