Cover
Title Page
Copyright and Credits
About Packt
Contributors
Table of Contents
Preface
Chapter 1: Strings, Numbers, and Math
Problems
Solutions
1. Counting duplicate characters
What about Unicode characters?
2. Finding the first non-repeated character
3. Reversing letters and words
4. Checking whether a string contains only digits
5. Counting vowels and consonants
6. Counting the occurrences of a certain character
7. Converting a string into an int, long, float, or double
8. Removing white spaces from a string
9. Joining multiple strings with a delimiter
10. Generating all permutations
11. Checking whether a string is a palindrome
12. Removing duplicate characters
13. Removing a given character
14. Finding the character with the most appearances
15. Sorting an array of strings by length
16. Checking that a string contains a substring
17. Counting substring occurrences in a string
18. Checking whether two strings are anagrams
19. Declaring multiline strings (text blocks)
20. Concatenating the same string n times
21. Removing leading and trailing spaces
22. Finding the longest common prefix
23. Applying indentation
24. Transforming strings
25. Computing the minimum and maximum of two numbers
26. Summing two large int/long values and operation overflow
27. String as an unsigned number in the radix
28. Converting into a number by an unsigned conversion
29. Comparing two unsigned numbers
30. Division and modulo of unsigned values
31. double/float is a finite floating-point value
32. Applying logical AND/OR/XOR to two boolean expressions
33. Converting BigInteger into a primitive type
34. Converting long into int
35. Computing the floor of a division and modulus
36. Next floating-point value
37. Multiplying two large int/long values and operation overflow
38. Fused Multiply Add
39. Compact number formatting
Formatting
Parsing
Summary
Chapter 2: Objects, Immutability, and Switch Expressions
Problems
Solutions
40. Checking null references in functional style and imperative code
41. Checking null references and throwing customized NullPointerException
42. Checking null references and throwing the specified exception
43. Checking null references and returning non-null default references
44. Checking the index in the range from 0 to length
45. Checking the subrange in the range from 0 to length
46. equals() and hashCode()
47. Immutable objects in a nutshell
48. Immutable string
Pros of string immutability
String constant pool or cached pool
Security
Thread safety
Hash code caching
Class loading
Cons of string immutability
String cannot be extended
Sensitive data in memory for a long time
OutOfMemoryError
Is String completely immutable?
49. Writing an immutable class
50. Passing/returning mutable objects to/from an immutable class
51. Writing an immutable class via the Builder pattern
52. Avoiding bad data in immutable objects
53. Cloning objects
Manual cloning
Cloning via clone()
Cloning via a constructor
Cloning via the Cloning library
Cloning via serialization
Cloning via JSON
54. Overriding toString()
55. Switch expressions
56. Multiple case labels
57. Statement blocks
Summary
Chapter 3: Working with Date and Time
Problems
Solutions
58. Converting a string to date and time
Before JDK 8
Starting with JDK 8
59. Formatting date and time
60. Getting the current date/time without time/date
61. LocalDateTime from LocalDate and LocalTime
62. Machine time via an Instant class
Converting String to Instant
Adding or subtracting time to/from Instant
Comparing Instant objects
Converting between Instant and LocalDateTime, ZonedDateTime, and OffsetDateTime
63. Defining a period of time using date-based values and a duration of time using time-based values
Period of time using date-based values
Duration of time using time-based values
64. Getting date and time units
65. Adding and subtracting to/from date-time
Working with Date
Working with LocalDateTime
66. Getting all time zones with UTC and GMT
Before JDK 8
Starting with JDK 8
67. Getting local date-time in all available time zones
Before JDK 8
Starting with JDK 8
68. Displaying date-time information about a flight
69. Converting a Unix timestamp to date-time
70. Finding the first/last day of the month
71. Defining/extracting zone offsets
Before JDK 8
Starting with JDK 8
72. Converting between Date and Temporal
Date – Instant
Date – LocalDate
Date – DateLocalTime
Date – ZonedDateTime
Date – OffsetDateTime
Date – LocalTime
Date – OffsetTime
73. Iterating a range of dates
Before JDK 8
Starting with JDK 8
Starting with JDK 9
74. Calculating age
Before JDK 8
Starting with JDK 8
75. Start and end of a day
76. Difference between two dates
Before JDK 8
Starting with JDK 8
77. Implementing a chess clock
Summary
Chapter 4: Type Inference
Problems
Solutions
78. Simple var example
79. Using var with primitive types
80. Using var and implicit type casting to sustain the code's maintainability
81. Explicit downcast or better avoid var
82. Avoid using var if the called names don't contain enough type information for humans
83. Combining LVTI and programming to the interface technique
84. Combining LVTI and the diamond operator
85. Assigning an array to var
86. Using LVTI in compound declarations
87. LVTI and variable scope
88. LVTI and the ternary operator
89. LVTI and for loops
90. LVTI and streams
91. Using LVTI to break up nested/large chains of expressions
92. LVTI and the method return and argument types
93. LVTI and anonymous classes
94. LVTI can be final and effectively final
95. LVTI and lambdas
96. LVTI and null initializers, instance variables, and catch blocks variables
Try-with-resource
97. LVTI and generic types, T
98. LVTI, wildcards, covariants, and contravariants
LVTI and wildcards
LVTI and covariants/contravariants
Summary
Chapter 5: Arrays, Collections, and Data Structures
Problems
Solutions
99. Sorting an array
JDK built-in solutions
Other sorting algorithms
Bubble sort
Insertion sort
Counting sort
Heap sort
100. Finding an element in an array
Check only for the presence
Check only for the first index
101. Checking whether two arrays are equal or mismatches
Checking whether two arrays are equal
Checking whether two arrays contain a mismatch
102. Comparing two arrays lexicographically
103. Creating a Stream from an array
104. Minimum, maximum, and average of an array
Computing maximum and minimum
Computing average
105. Reversing an array
106. Filling and setting an array
107. Next Greater Element
108. Changing array size
109. Creating unmodifiable/immutable collections
Problem 1 (Collections.unmodifiableList())
Problem 2 (Arrays.asList())
Problem 3 (Collections.unmodifiableList() and static block)
Problem 4 (List.of())
Problem 5 (immutable)
110. Mapping a default value
111. Computing whether absent/present in a map
Example 1 (computeIfPresent())
Example 2 (computeIfAbsent())
Example 3 (compute())
Example 4 (merge())
Example 5 (putIfAbsent())
112. Removal from a Map
113. Replacing entries from a Map
114. Comparing two maps
115. Sorting a Map
Sorting by key via TreeMap and natural ordering
Sorting by key and value via Stream and Comparator
Sorting by key and value via List
116. Copying HashMap
117. Merging two maps
118. Removing all elements of a collection that match a predicate
Removing via an iterator
Removing via Collection.removeIf()
Removing via Stream
Separating elements via Collectors.partitioningBy()
119. Converting a collection into an array
120. Filtering a Collection by a List
121. Replacing elements of a List
122. Thread-safe collections, stacks, and queues
Concurrent collections
Thread-safe lists
Thread-safe set
Thread-safe map
Thread-safe queue backed by an array
Thread-safe queue based on linked nodes
Thread-safe priority queue
Thread-safe delay queue
Thread-safe transfer queue
Thread-safe synchronous queue
Thread-safe stack
Synchronized collections
Concurrent versus synchronized collections
123. Breadth-first search
124. Trie
Inserting in a Trie
Finding in a Trie
Deleting from a Trie
125. Tuple
126. Union Find
Implementing the find operation
Implementing the union operation
127. Fenwick Tree or Binary Indexed Tree
128. Bloom filter
Summary
Chapter 6: Java I/O Paths, Files, Buffers, Scanning, and Formatting
Problems
Solutions
129. Creating file paths
Creating a path relative to the file store root
Creating a path relative to the current folder
Creating an absolute path
Creating a path using shortcuts
130. Converting file paths
131. Joining file paths
132. Constructing a path between two locations
133. Comparing file paths
Path.equals()
Paths representing the same file/folder
Lexicographical comparison
Partial comparing
134. Walking paths
Trivial traversal of a folder
Searching for a file by name
Deleting a folder
Copying a folder
JDK 8, Files.walk()
135. Watching paths
Watching a folder for changes
136. Streaming a file's content
137. Searching for files/folders in a file tree
138. Reading/writing text files efficiently
Reading text files in memory
Writing text files
139. Reading/writing binary files efficiently
Reading binary files into memory
Writing binary files
140. Searching in big files
Solution based on BufferedReader
Solution based on Files.readAllLines()
Solution based on Files.lines()
Solution based on Scanner
Solution based on MappedByteBuffer
141. Reading a JSON/CSV file as an object
Read/write a JSON file as an object
Using JSON-B
Using Jackson
Using Gson
Reading a CSV file as an object
142. Working with temporary files/folders
Creating a temporary folder/file
Deleting a temporary folder/file via shutdown-hook
Deleting a temporary folder/file via deleteOnExit()
Deleting a temporary file via DELETE_ON_CLOSE
143. Filtering files
Filtering via Files.newDirectoryStream()
Filtering via FilenameFilter
Filtering via FileFilter
144. Discovering mismatches between two files
145. Circular byte buffer
146. Tokenizing files
147. Writing formatted output directly to a file
148. Working with Scanner
Scanner versus BufferedReader
Summary
Chapter 7: Java Reflection Classes, Interfaces, Constructors, Methods, and Fields
Problems
Solutions
149. Inspecting packages
Getting the classes of a package
Inspecting packages inside modules
150. Inspecting classes
Get the name of the Pair class via an instance
Getting the Pair class modifiers
Getting the Pair class implemented interfaces
Getting the Pair class constructors
Getting the Pair class fields
Getting the Pair class methods
Getting the Pair class module
Getting the Pair class superclass
Getting the name of a certain type
Getting a string that describes the class
Getting the type descriptor string for a class
Getting the component type of an array
Getting a class for an array type whose component type is described by Pair
151. Instantiating via a reflected constructor
Instantiating a class via a private constructor
Instantiating a class from a JAR
Useful snippets of code
152. Getting the annotation of a receiver type
153. Getting synthetic and bridge constructs
154. Checking the variable number of arguments
155. Checking default methods
156. Nest-based access control via reflection
Access via the Reflection API
157. Reflection for getters and setters
Fetching getters and setters
Generating getters and setters
158. Reflecting annotations
Inspecting package annotations
Inspecting class annotations
Inspecting methods annotations
Inspecting annotations of the thrown exceptions
Inspecting annotations of the return type
Inspecting annotations of the method's parameters
Inspecting annotations of fields
Inspecting annotations of the superclass
Inspecting annotations of interfaces
Get annotations by type
Get a declared annotation
159. Invoking an instance method
160. Getting static methods
161. Getting generic types of method, fields, and exceptions
Generics of methods
Generics of fields
Generics of a superclass
Generics of interfaces
Generics of exceptions
162. Getting public and private fields
163. Working with arrays
164. Inspecting modules
165. Dynamic proxies
Implementing a dynamic proxy
Summary
Chapter 8: Functional Style Programming - Fundamentals and Design Patterns
Problems
Solutions
166. Writing functional interfaces
Day 1 (filtering melons by their type)
Day 2 (filtering melons of a certain weight)
Day 3 (filtering melons by type and weight)
Day 4 (pushing the behavior as a parameter)
Day 5 (implementing another 100 filters)
Day 6 (anonymous classes can be written as lambdas)
Day 7 (abstracting the List type)
167. Lambdas in a nutshell
168. Implementing the Execute Around pattern
169. Implementing the Factory pattern
170. Implementing the Strategy pattern
171. Implementing the Template Method pattern
172. Implementing the Observer pattern
173. Implementing the Loan pattern
174. Implementing the Decorator pattern
175. Implementing the Cascaded Builder pattern
176. Implementing the Command pattern
Summary
Chapter 9: Functional Style Programming - a Deep Dive
Problems
Solutions
177. Testing high-order functions
Testing a method that takes a lambda as a parameter
Testing a method that returns a functional interface
178. Testing methods that use lambdas
179. Debugging lambdas
180. Filtering the non-zero elements of a stream
181. Infinite streams, takeWhile(), and dropWhile()
Infinite sequential ordered stream
Unlimited stream of pseudorandom values
Infinite sequential unordered stream
Take while a predicate returns true
Drop while a predicate returns true
182. Mapping the elements of a stream
Using Stream.map()
Using Stream.flatMap()
183. Finding elements in a stream
findAny
findFirst
184. Matching elements in a stream
185. Sum, max, and min in a stream
The sum(), min(), and max() terminal operations
Reducing
186. Collecting the result of a stream
187. Joining the results of a stream
188. Summarization collectors
Summing
Averaging
Counting
Maximum and minimum
Getting all
189. Grouping
Single-level grouping
Multilevel grouping
190. Partitioning
191. Filtering, flattening, and mapping collectors
filtering()
mapping()
flatMapping()
192. Teeing
193. Writing a custom collector
The supplier – Supplier
supplier();
Accumulating elements – BiConsumer accumulator();
Applying the final transformation – Function finisher();
Parallelizing the collector – BinaryOperator combiner();
Returning the final result – Function finisher();
Characteristics – Set characteristics();
Testing time
Custom collecting via collect()
194. Method reference
Method reference to a static method
Method reference to an instance method
Method reference to a constructor
195. Parallel processing of streams
Spliterators
Writing a custom Spliterator
196. Null-safe streams
197. Composing functions, predicates, and comparators
Composing predicates
Composing comparators
Composing functions
198. Default methods
Summary
Chapter 10: Concurrency - Thread Pools, Callables, and Synchronizers
Problems
Solutions
199. Thread life cycle states
The NEW state
The RUNNABLE state
The BLOCKED state
The WAITING state
The TIMED_WAITING state
The TERMINATED state
200. Object- versus class-level locking
Locking at the object level
Lock at the class level
Good to know
201. Thread pools in Java
Executor
ExecutorService
ScheduledExecutorService
Thread pools via Executors
202. Thread pool with a single thread
Producer waits for the consumer to be available
Producer doesn't wait for the consumer to be available
203. Thread pool with a fixed number of threads
204. Cached and scheduled thread pools
205. Work-stealing thread pool
A large number of small tasks
A small number of time-consuming tasks
206. Callable and Future
Canceling a Future
207. Invoking multiple Callable tasks
208. Latches
209. Barrier
210. Exchanger
211. Semaphores
212. Phasers
Summary
Chapter 11: Concurrency - Deep Dive
Problems
Solutions
213. Interruptible methods
214. Fork/join framework
Computing the sum via RecursiveTask
Computing Fibonacci via RecursiveAction
Using CountedCompleter
215. Fork/join framework and compareAndSetForkJoinTaskTag()
216. CompletableFuture
Running asynchronous task and return void
Running an asynchronous task and returning a result
Running an asynchronous task and returning a result via an explicit thread pool
Attaching a callback that processes the result of an asynchronous task and returns a result
Attaching a callback that processes the result of an asynchronous task and returns void
Attaching a callback that runs after an asynchronous task and returns void
Handling exceptions of an asynchronous task via exceptionally()
JDK 12 exceptionallyCompose()
Handling exceptions of an asynchronous task via handle()
Explicitly complete a CompletableFuture
217. Combining multiple CompletableFuture instances
Combining via thenCompose()
Combining via thenCombine()
Combining via allOf()
Combining via anyOf()
218. Optimizing busy waiting
219. Task Cancellation
220. ThreadLocal
Per-thread instances
Per-thread context
221. Atomic variables
Adders and accumulators
222. ReentrantLock
223. ReentrantReadWriteLock
224. StampedLock
225. Deadlock (dining philosophers)
Summary
Chapter 12: Optional
Problems
Solutions
226. Initializing Optional
227. Optional.get() and missing value
228. Returning an already-constructed default value
229. Returning a non-existent default value
230. Throwing NoSuchElementException
231. Optional and null references
232. Consuming a present Optional class
233. Returning a present Optional class or another one
234. Chaining lambdas via orElseFoo()
235. Do not use Optional just for getting a value
236. Do not use Optional for fields
237. Do not use Optional in constructor args
238. Do not use Optional in setter args
239. Do not use Optional in method args
240. Do not use Optional to return empty or null collections or arrays
241. Avoiding Optional in collections
242. Confusing of() with ofNullable()
243. Optional versus OptionalInt
244. Asserting equality of Optionals
245. Transforming values via Map() and flatMap()
246. Filter values via Optional.filter()
247. Chaining the Optional and Stream APIs
248. Optional and identity-sensitive operations
249. Returning a boolean if the Optional class is empty
Summary
Chapter 13: The HTTP Client and WebSocket APIs
Problems
Solutions
250. HTTP/2
251. Triggering an asynchronous GET request
Query parameter builder
252. Setting a proxy
253. Setting/getting headers
Setting request headers
Getting request/response headers
254. Specifying the HTTP method
255. Setting a request body
Creating a body from a string
Creating a body from InputStream
Creating a body from a byte array
Creating a body from a file
256. Setting connection authentication
257. Setting a timeout
258. Setting the redirect policy
259. Sending sync and async requests
Sending a request synchronously
Sending a request asynchronously
Sending multiple requests concurrently
260. Handling cookies
261. Getting response information
262. Handling response body types
Handling a response body as a string
Handling a response body as a file
Handling a response body as a byte array
Handling a response body as an input stream
Handling a response body as a stream of strings
263. Getting, updating, and saving a JSON
JSON response to User
Updated User to JSON request
New User to JSON request
264. Compression
265. Handling form data
266. Downloading a resource
267. Uploading with multipart
268. HTTP/2 server push
269. WebSocket
Summary
Other Books You May Enjoy
Index