Preface
Who This Book Is For
What’s in This Book?
What’s Not in This Book
Organization of This Book
Java Books
Conventions Used in This Book
Using Code Examples
O’Reilly Online Learning
Comments and Questions
Acknowledgments
1. Getting Started: Compiling and Running Java
1.0. Introduction
1.1. Hello, World: Compiling and Running Java with the Standard JDK
1.2. Hello, World of Classless Main 21P
1.3. Downloading and Using the Code Examples
1.4. Compiling, Running, and Testing with an IDE
1.5. Exploring Java with JShell 11
1.6. Using CLASSPATH Effectively
1.7. Documenting Classes with Javadoc
1.8. Beyond Javadoc: Annotations/Metadata
1.9. Packaging and Running JAR Files
1.10. Creating a JAR That Supports Multiple Versions of Java
1.11. Packaging Web Tier Components into a WAR File
1.12. Compiling and Running Java: GraalVM for Better Performance
1.13. Getting Information About the Environment, OS, and Runtime
2. Software Development, Testing, and Maintenance
2.0. Introduction
2.1. Designing Applications: Packages, Modules
2.2. Using the Java Modules System
2.3. Using JPMS to Create a Module
2.4. Automating Compilation, Testing, and Deployment with Apache Maven
2.5. Automating Compilation, Testing, and Deployment with Gradle
2.6. Automating Dependency Management with Maven and Gradle
2.7. Dealing with Deprecation Warnings
2.8. Batch Refactoring for Warnings and Migrations
2.9. Maintaining Code Correctness with Unit Testing: JUnit
2.10. Isolating the Test Target with Mock Objects and Mockito
2.11. Logging: Network or Local
2.12. Setting Up SLF4J
2.13. Network Logging with Log4j
2.14. Network Logging with java.util.logging
2.15. Maintaining Your Code with Continuous Integration
2.16. Performance Timing
2.17. Creating a Custom JDK Distribution with jlink
2.18. Creating Platform-Specific Installers with jpackage
3. Strings and Things
3.0. Introduction
3.1. Taking Strings Apart with Substrings, Tokenizing, and Trimming Methods
3.2. String Formatting with Formatter and printf()
3.3. Building Strings with StringBuilder
3.4. Processing a String One Character at a Time
3.5. Aligning, Indenting, and Unindenting Strings
3.6. Converting Between Unicode Characters and Strings
3.7. Reversing a String by Word or by Character
3.8. Expanding and Compressing Tabs
3.9. Controlling Case
3.10. Adding Nonprintable Characters into a String
3.11. Creating a Message to the World with I18N Resources
3.12. Using a Particular Locale
3.13. Creating a Resource Bundle
3.14. Program: A Simple Text Formatter
4. String Matching with Regular Expressions
4.0. Introduction
4.1. Regular Expression Syntax
4.2. Checking If a String Matches a Regex
4.3. Grouping: Specifying Parts of the Regex
4.4. Finding the Matching Text
4.5. Replacing the Matched Text
4.6. Printing All Occurrences of a Pattern
4.7. Controlling Case in Regular Expressions
4.8. Matching Accented, or Composite, Characters
4.9. Matching Newlines in Text
4.10. Program: Full Grep
5. Numbers
5.0. Introduction
5.1. Checking Whether a String Is a Valid Number
5.2. Converting Numbers to Objects and Vice Versa
5.3. Taking a Fraction of an Integer Without Using Floating Point
5.4. Working with Floating-Point Numbers
5.5. Formatting Numbers
5.6. Converting Among Binary, Octal, Decimal, and Hexadecimal
5.7. Operating on a Range of Integers
5.8. Formatting with Correct Plurals
5.9. Generating Random Numbers
5.10. Multiplying Matrices
5.11. Optimizing Large Arithmetic Operations with Vector Operations 22C
5.12. Using Complex Numbers
5.13. Handling Very Large Numbers
5.14. Program: TempConverter
6. Dates and Times
6.0. Introduction
6.1. Finding Today’s Date
6.2. Formatting Dates and Times
6.3. Converting Among Dates/Times and Epoch Seconds
6.4. Parsing Strings into Dates
6.5. Difference Between Two Dates
6.6. Adding to or Subtracting from a Date
6.7. Calculating Recurring Events
6.8. Computing Dates Involving Time Zones
6.9. Interfacing with Legacy Date and Calendar Classes
7. Structuring Data with Java
7.0. Introduction
7.1. Using Arrays for Data Structuring
7.2. Resizing an Array
7.3. Simplifying Array Handling with the Arrays Class
7.4. The Collections Framework
7.5. Lists: Like an Array, but More Dynamic
7.6. Using Generic Types in Your Own Class: Stack Demo
7.7. How Shall I Iterate Thee? Let Me Enumerate the Ways
7.8. Avoiding Duplicate Values with a Set
7.9. Mapping with Hashtable and HashMap
7.10. Storing Strings in Properties and Preferences
7.11. Sorting a Collection
7.12. Finding an Object in a Collection
7.13. Converting Between Collections and Arrays
7.14. Making Your Own Data Structures Iterable
7.15. Multidimensional Structures
8. Object-Oriented Techniques
8.0. Introduction
8.1. Object Methods: Formatting Objects with toString(), Comparing with Equals
8.2. Constructor Simplification: Statements Before super(…) 22P
8.3. Using Inner Classes
8.4. Simplifying Data Objects with Records (or Lombok)
8.5. Providing Callbacks via Interfaces
8.6. Polymorphism/Abstract Methods
8.7. Improving Interfaces with Default, Static, and Private Methods
8.8. Using Typesafe Enumerations
8.9. Using Type Pattern Matching
8.10. Avoiding NPEs with “Optional”
8.11. Controlling Subclassing with Sealed Types 17
8.12. Enforcing the Singleton Pattern
8.13. Roll Your Own Exceptions
8.14. Using Dependency Injection
8.15. Combining Java Features for Data-Oriented Programming
9. Functional Programming Techniques: Functional Interfaces, Streams, and Parallel Collections
9.0. Introduction
9.1. Using Lambdas/Closures Instead of Inner Classes
9.2. Using Predefined Lambda Interfaces or Rolling Your Own
9.3. Simplifying Processing with Streams
9.4. Simplifying Streams with Collectors
9.5. Simplifying Streams with Stream Gatherers 22P
9.6. Simplifying Streams with Your Own Stream Gatherer 22P
9.7. Improving Throughput with Parallel Streams and Collections
9.8. Using Existing Code as Functional with Method References
9.9. Java Mixins: Mixing in Methods
9.10. Functional Programming with Flow and Reactive Streams
10. Input and Output: Reading, Writing, and Directory Tricks
10.0. Introduction
10.1. Discovering Filesystem Paths
10.2. Getting and Setting File and Directory Information: Files and Path
10.3. Creating and Deleting Files or Directories
10.4. Changing a File’s Name or Other Attributes
10.5. About InputStreams/OutputStreams and Readers/Writers
10.6. Reading and Writing Files
10.7. Scanning Input with StreamTokenizer, Scanner, Parsers
10.8. Reading from the Standard Input or from the Console/Controlling Terminal
10.9. Copying a File
10.10. Reassigning the Standard Streams
10.11. Duplicating a Stream as It Is Written
10.12. Reading/Writing a Different Character Set
10.13. Those Pesky End-of-Line Characters
10.14. Beware Platform-Dependent File Code
10.15. Reading and Writing JAR or ZIP Archives
10.16. Reading Files in a Filesystem-Neutral Way with getResource() and getResourceAsStream()
10.17. Creating a Transient/Temporary File
10.18. Getting the Directory Roots
10.19. Using the File Watcher Service to Get Notified About File Changes
10.20. Walking a File Tree (like Find)
11. Threaded Java
11.0. Introduction
11.1. Running Code in a Different Thread
11.2. Using Virtual Threads for Better Performance
11.3. Rendezvous and Timeouts
11.4. Synchronizing Threads with the synchronized Keyword
11.5. Simplifying Synchronization with Locks
11.6. Locking with One Writer, Many Readers
11.7. Sharing Data Among Threads—ThreadLocal and ScopedValue: Structuring Concurrency
11.8. Simplifying Producer/Consumer with the Queue Interface
11.9. Optimizing Parallel Processing with Fork/Join
11.10. Scheduling Tasks: Future Times, Background Saving in an Editor
12. Data Science and R
12.0. Introduction
12.1. Using Data in Apache Spark
12.2. Using R Interactively
12.3. Comparing/Choosing an R Implementation
12.4. Using R from Within a Java App: Renjin
12.5. Using Java from Within an R Session
12.6. Using R in a Web App
13. Machine Learning/Artificial Intelligence
13.0. Introduction
13.1. Some Major AI Software
13.2. Using ChatGPT Directly
13.3. Using ChatGPT via LangChain4j
13.4. Making an AI Service with LangChain4j
13.5. Conversing with Shadows
13.6. Generating Images with LangChain4j
13.7. Mixed Media Prompts: Inferences from Images with LangChain4j
13.8. Running AI Locally with ollama
14. Network Clients
14.0. Introduction
14.1. HTTP/REST Web Client—Modern API 11
14.2. Contacting a Socket Server
14.3. Finding and Reporting Network Addresses
14.4. Handling Network Errors
14.5. Reading and Writing Textual Data
14.6. Reading and Writing Binary or Serialized Data
14.7. Postcards of the Internet: Using UDP Datagrams
14.8. URI, URL, or URN?
14.9. Program: Sockets-Based Chat Client
15. Server-Side Java
15.0. Introduction
15.1. Opening a Server Socket for Business
15.2. Finding Network Interfaces
15.3. Returning a Response (String or Binary)
15.4. Handling Multiple Clients
15.5. Serving the HTTP Protocol
15.6. Securing a Web Server with TLS (formerly SSL) and JSSE
15.7. Creating a REST Service/Microservice with JAX-RS
15.8. Unix Domain Sockets—Even on Windows! 16
16. Processing JSON Data
16.0. Introduction
16.1. Generating JSON Directly
16.2. Parsing and Writing JSON with Jackson
16.3. Parsing and Writing JSON with org.json
16.4. Parsing and Writing JSON with JSON-B
16.5. Finding JSON Elements with JSON Pointer
17. Reflection, or “A Class Named Class”
17.0. Introduction
17.1. Loading and Instantiating a Class Dynamically
17.2. Printing Class Information
17.3. Getting a Class Descriptor
17.4. Finding and Using Methods and Fields
17.5. Invoking Class Members via MethodHandles
17.6. Listing Classes in a Package
17.7. Accessing Nested Members of Same Class
17.8. Accessing Private Methods and Fields via Reflection
17.9. Constructing a Class from Scratch with a ClassLoader
17.10. Constructing a Class from Scratch with JavaCompiler
17.11. Constructing or Modifying Class Files with the Class-File API 22P
17.12. Using and Defining Annotations
17.13. Finding Plug-In-Like Classes via Annotations
17.14. A Timing Program
17.15. Program: CrossRef
18. Using Java with Other Languages
18.0. Introduction
18.1. Running an External Program from Java
18.2. Running a Program and Capturing Its Output
18.3. Calling Other Languages via javax.script
18.4. Mixing Languages with GraalVM 21
18.5. Calling Between Java and Native Code with the Foreign Function and Memory API 22
18.6. Calling Other Languages via Native Code (JNI)
18.7. Calling Java from Native Code with JNI
Afterword
Java Then and Now
Introduction: Always in Motion the Java Is
What Was New in Java 16 16
What Was New in Java 17 LTS 17
What Was New in Java 18 18
What Was New in Java 19 19
What Was New in Java 20 20
What Was New in Java 21 LTS 21
What Was New in Java 22 22
What’s New in Java 23 23
What’s New in Java 24 24
Looking Ahead
Index
About the Author
As Java continues to evolve, this cookbook continues to grow in tandem with hundreds of hands-on recipes across a broad range of Java topics. Author Ian Darwin gets developers up to speed right away with useful techniques for everything from string handling and functional programming to network communication and AI.
If you're familiar with any release of Java, this book will bolster your knowledge of the language and its many recent changes, including how to apply them in your day-to-day development. Each recipe includes self-contained code solutions that you can freely use, along with a discussion of how and why they work.
Downloadable from GitHub, all code examples compile successfully. This updated edition covers changes up to Java 23 and most of Java 24.
Learn how to apply many new and old Java APIs
Use the new language features in recent Java versions
Understand the code you're maintaining
Develop code using standard APIs and good practices
Explore the brave new world of current Java development