Java Coding Problems

Book description

Develop your coding skills by exploring Java concepts and techniques such as Strings, Objects and Types, Data Structures and Algorithms, Concurrency, and Functional programming

Key Features

  • Solve Java programming challenges and get interview-ready by using the power of modern Java 11
  • Test your Java skills using language features, algorithms, data structures, and design patterns
  • Explore areas such as web development, mobile development, and GUI programming

Book Description

The super-fast evolution of the JDK between versions 8 and 12 has increased the learning curve of modern Java, therefore has increased the time needed for placing developers in the Plateau of Productivity. Its new features and concepts can be adopted to solve a variety of modern-day problems. This book enables you to adopt an objective approach to common problems by explaining the correct practices and decisions with respect to complexity, performance, readability, and more.

Java Coding Problems will help you complete your daily tasks and meet deadlines. You can count on the 300+ applications containing 1,000+ examples in this book to cover the common and fundamental areas of interest: strings, numbers, arrays, collections, data structures, date and time, immutability, type inference, Optional, Java I/O, Java Reflection, functional programming, concurrency and the HTTP Client API. Put your skills on steroids with problems that have been carefully crafted to highlight and cover the core knowledge that is accessed in daily work. In other words (no matter if your task is easy, medium or complex) having this knowledge under your tool belt is a must, not an option.

By the end of this book, you will have gained a strong understanding of Java concepts and have the confidence to develop and choose the right solutions to your problems.

What you will learn

  • Adopt the latest JDK 11 and JDK 12 features in your applications
  • Solve cutting-edge problems relating to collections and data structures
  • Get to grips with functional-style programming using lambdas
  • Perform asynchronous communication and parallel data processing
  • Solve strings and number problems using the latest Java APIs
  • Become familiar with different aspects of object immutability in Java
  • Implement the correct practices and clean code techniques

Who this book is for

If you are a Java developer who wants to level-up by solving real-world problems, then this book is for you. Working knowledge of Java is required to get the most out of this book.

Table of contents

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

Product information

  • Title: Java Coding Problems
  • Author(s): Anghel Leonard
  • Release date: September 2019
  • Publisher(s): Packt Publishing
  • ISBN: 9781789801415