Java Coding Problems: Improve your Java Programming skills by solving real-world coding challenges
()
About this ebook
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
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
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.
Anghel Leonard
Anghel Leonard is a Chief Technology Strategist and independent consultant with 20+ years of experience in the Java ecosystem. In daily work, he is focused on architecting and developing Java distributed applications that empower robust architectures, clean code, and high-performance. Also passionate about coaching, mentoring and technical leadership. He is the author of several books, videos and dozens of articles related to Java technologies.
Read more from Anghel Leonard
Mastering JavaServer Faces 2.2 Rating: 0 out of 5 stars0 ratingsJSF 2.0 Cookbook: LITE Rating: 0 out of 5 stars0 ratingsJBoss Tools 3 Developers Guide Rating: 0 out of 5 stars0 ratings
Related to Java Coding Problems
Related ebooks
Learn Java 12 Programming: A step-by-step guide to learning essential concepts in Java SE 10, 11, and 12 Rating: 0 out of 5 stars0 ratingsJava 9 Programming By Example Rating: 4 out of 5 stars4/5Grokking the Java Interview Rating: 0 out of 5 stars0 ratingsJava Core Interview Questions and Answers. Tech interviewer’s notes Rating: 1 out of 5 stars1/5Learn Java: A Crash Course Guide to Learn Java in 1 Week Rating: 3 out of 5 stars3/5Java Multithreading Interview Questions And Answers Rating: 0 out of 5 stars0 ratingsCore Java Professional: For First Time Learner's. Rating: 0 out of 5 stars0 ratingsJava 8 Programmer II Study Guide: Exam 1Z0-809 Rating: 4 out of 5 stars4/5JAVA for Beginner's Crash Course: Java for Beginners Guide to Program Java, jQuery, & Java Programming Rating: 4 out of 5 stars4/5OCP Oracle Certified Professional Java SE 11 Developer Practice Tests: Exam 1Z0-819 and Upgrade Exam 1Z0-817 Rating: 5 out of 5 stars5/5Seriously Good Software: Code that works, survives, and wins Rating: 5 out of 5 stars5/5Mastering Unit Testing Using Mockito and JUnit Rating: 0 out of 5 stars0 ratingsIntroduction to JVM Languages Rating: 0 out of 5 stars0 ratingsCore Java Programming Rating: 4 out of 5 stars4/5Testing with JUnit Rating: 0 out of 5 stars0 ratingsJava All-in-One For Dummies Rating: 0 out of 5 stars0 ratingsJava: A Beginner's Guide, Seventh Edition Rating: 3 out of 5 stars3/5CORE JAVA Interview Questions You'll Most Likely Be Asked Rating: 4 out of 5 stars4/5OCP Oracle Certified Professional Java SE 11 Programmer I Study Guide: Exam 1Z0-815 Rating: 5 out of 5 stars5/5Java and Java EE Interview Preparations Rating: 0 out of 5 stars0 ratingsCore Java: Made Simple: A popular language for Android smart phone application, favoured for edge device and Rating: 0 out of 5 stars0 ratingsOCP: Oracle Certified Professional Java SE 8 Programmer II Study Guide: Exam 1Z0-809 Rating: 5 out of 5 stars5/5Professional Java EE Design Patterns Rating: 0 out of 5 stars0 ratings100+ Solutions in Java: A Hands-On Introduction to Programming in Java (English Edition) Rating: 0 out of 5 stars0 ratingsJavaScript Unlocked Rating: 5 out of 5 stars5/5Java Programming Rating: 0 out of 5 stars0 ratingsEveryday Data Structures Rating: 0 out of 5 stars0 ratings.NET Design Patterns Rating: 3 out of 5 stars3/5
Programming For You
Coding All-in-One For Dummies Rating: 4 out of 5 stars4/5Learn to Code. Get a Job. The Ultimate Guide to Learning and Getting Hired as a Developer. Rating: 5 out of 5 stars5/5Python Programming : How to Code Python Fast In Just 24 Hours With 7 Simple Steps Rating: 4 out of 5 stars4/5Python: Learn Python in 24 Hours Rating: 4 out of 5 stars4/5SQL QuickStart Guide: The Simplified Beginner's Guide to Managing, Analyzing, and Manipulating Data With SQL Rating: 4 out of 5 stars4/5Excel 101: A Beginner's & Intermediate's Guide for Mastering the Quintessence of Microsoft Excel (2010-2019 & 365) in no time! Rating: 0 out of 5 stars0 ratingsSQL All-in-One For Dummies Rating: 3 out of 5 stars3/5Excel : The Ultimate Comprehensive Step-By-Step Guide to the Basics of Excel Programming: 1 Rating: 5 out of 5 stars5/5Coding All-in-One For Dummies Rating: 0 out of 5 stars0 ratingsHTML in 30 Pages Rating: 5 out of 5 stars5/5Linux: Learn in 24 Hours Rating: 5 out of 5 stars5/5Python Machine Learning By Example Rating: 4 out of 5 stars4/5Python: For Beginners A Crash Course Guide To Learn Python in 1 Week Rating: 4 out of 5 stars4/5Learn SQL in 24 Hours Rating: 5 out of 5 stars5/5Python Data Structures and Algorithms Rating: 5 out of 5 stars5/5Coding with JavaScript For Dummies Rating: 0 out of 5 stars0 ratingsLearn PowerShell in a Month of Lunches, Fourth Edition: Covers Windows, Linux, and macOS Rating: 5 out of 5 stars5/5A Slackers Guide to Coding with Python: Ultimate Beginners Guide to Learning Python Quick Rating: 0 out of 5 stars0 ratingsJavaScript All-in-One For Dummies Rating: 5 out of 5 stars5/5
Reviews for Java Coding Problems
0 ratings0 reviews
Book preview
Java Coding Problems - Anghel Leonard
Java Coding Problems
Improve your Java Programming skills by solving
real-world coding challenges
Anghel Leonard
BIRMINGHAM - MUMBAI
Java Coding Problems
Copyright © 2019 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
Commissioning Editor: Richa Tripathi
Acquisition Editor: Alok Dhuri
Content Development Editor: Zeeyan Pinheiro
Senior Editor: Afshaan Khan
Technical Editor: Pradeep Sahu
Copy Editor: Safis Editing
Project Coordinator: Prajakta Naik
Proofreader: Safis Editing
Indexer: Manju Arasan
Production Designer: Aparna Bhagat
First published: September 2019
Production reference: 1200919
Published by Packt Publishing Ltd.
Livery Place
35 Livery Street
Birmingham
B3 2PB, UK.
ISBN 978-1-78980-141-5
www.packt.com
Packt.com
Subscribe to our online digital library for full access to over 7,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website.
Why subscribe?
Spend less time learning and more time coding with practical eBooks and Videos from over 4,000 industry professionals
Improve your learning with Skill Plans built especially for you
Get a free eBook or video every month
Fully searchable for easy access to vital information
Copy and paste, print, and bookmark content
Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.packt.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at customercare@packtpub.com for more details.
At www.packt.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks.
Contributors
About the author
Anghel Leonard is a Chief Technology Strategist with more than 20 years of experience in the Java ecosystem. In his daily work, he is focused on architecting and developing Java distributed applications that empower robust architectures, clean code, and high performance. He is also passionate about coaching, mentoring, and technical leadership.
He is the author of several books, videos, and dozens of articles related to Java technologies.
About the reviewers
Cristian Stancalau has an MSc and BSc in computer science and engineering from Babes-Bolyai University, where he has contributed as an assistant lecturer since 2018. Currently, he works as chief software architect, focused on enterprise code review at DevFactory.
Previously, he co-founded and lead a video technology start-up as technical director. Cristian has proven mentoring and teaching expertise in both the commercial and academic sectors, advising on Java technologies and product architecture.
I would like to thank Anghel Leonard for the honor of entrusting me to perform the technical review for Java Coding Problems. Reading it was a real pleasure for me and I am sure it will also be for his readers.
Vishnu Govindrao Kulkarni is an enthusiastic freelancer solutions provider (with Fortune Consulting). He has a wide range of experience in various domains, with 8 years of experience working with full-stack Java, Java Spring, Spring Boot, the Hibernate REST API, and Oracle. He has also had the opportunity to work with several organizations to build enterprise solutions using Java and Java frameworks. Today, he continues to design and develop solutions while closely working with clients to help them derive value from these solutions.
Previously, he worked as the technical reviewer for the book Java Fundamentals for Packt Publishing.
Packt is searching for authors like you
If you're interested in becoming an author for Packt, please visit authors.packtpub.com and apply today. We have worked with thousands of developers and tech professionals, just like you, to help them share their insight with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea.
Table of Contents
Title Page
Copyright and Credits
Java Coding Problems
About Packt
Why subscribe?
Contributors
About the author
About the reviewers
Packt is searching for authors like you
Preface
Who this book is for
What this book covers
To get the most out of this book
Download the example code files
Download the color images
Code in action
Conventions used
Get in touch
Reviews
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
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
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
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
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
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
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
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
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<A> supplier();
Accumulating elements – BiConsumer<A, T> accumulator();
Applying the final transformation – Function<A, R> finisher();
Parallelizing the collector – BinaryOperator<A> combiner();
Returning the final result – Function<A, R> finisher();
Characteristics – Set<Characteristics> 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
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
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
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<T> 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
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
Leave a review - let other readers know what you think
Preface
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.
Who this book is for
Java Coding Problems is especially useful for beginners and intermediate Java developers. However, the problems looked at here are encountered in the daily work of any Java developer.
The required technical background is quite thin. Mainly, you should be a Java fan and have good skills and intuition in following a piece of Java code.
What this book covers
Chapter 1, Strings, Numbers, and Math, includes 39 problems that involve strings, numbers, and mathematical operations. The chapter starts with a bunch of classical problems for strings such as counting duplicates, reversing a string, and removing white spaces. The chapter continues with problems dedicated to numbers and mathematical operations such as summing two large numbers, operation overflow, comparing two unsigned numbers, computing the floor of a division and a modulus, and much more. Each problem is passed through several solutions, including Java 8 functional style. Moreover, the chapter covers problems that futures added in JDK 9, 10, 11, and 12.
Chapter 2, Objects, Immutability, and Switch Expressions, includes 18 problems that involve objects, immutability, and switch expressions. The chapter starts with several problems about dealing with null references. It continues with problems regarding checking indexes, equals() and hashCode(), and immutability (for example, writing immutable classes and passing/returning mutable objects from immutable classes). The last part of the chapter deals with cloning objects and JDK 12 switch expressions.
Chapter 3, Working with Date and Time, includes 20 problems that involve date and time. These problems are meant to cover a wide range of topics (converting, formatting, adding, subtracting, defining periods/durations, computing, and so on) via Date, Calendar, LocalDate, LocalTime, LocalDateTime, ZoneDateTime, OffsetDateTime, OffsetTime, Instant, and so on. By the end of this chapter, you will have no problems shaping date and time to conform to your application's needs.
Chapter 4, Type Inference, includes 21 problems that involve JEP 286, Java Local Variable Type Inference (LVTI), or the var type. These problems have been carefully crafted to reveal the best practices and common mistakes involved in using var. By the end of this chapter, you will have everything you need to know about var to push it in production.
Chapter 5, Arrays, Collections, and Data Structures, includes 30 problems that involve arrays, collections, and several data structures. The aim is to provide solutions to a category of problems encountered in a wide range of applications, such as sorting, finding, comparing, ordering, reversing, filling, merging, copying, replacing, and so on. The provided solutions are implemented in Java 8-12 and they can be used as the base for solving other related problems as well. By the end of this chapter, you will have a solid base of knowledge that's useful for solving a lot of problems that involve arrays, collections, and data structures.
Chapter 6, Java I/O Paths, Files, Buffers, Scanning, and Formatting, includes 20 problems that involve Java I/O for files. From manipulating, walking, and watching paths to streaming files and efficient ways for reading/writing text and binary files, we will cover problems that are a must in the arsenal of any Java developer. With the skills gained from this chapter, you will be able to tackle most of the common problems that involve Java I/O files.
Chapter 7, Java Reflection Classes, Interfaces, Constructors, Methods, and Fields, includes 17 problems that involve the Java Reflection API. From classical topics, such as inspecting and instantiating Java artifacts (for example, modules, packages, classes, interfaces, super-classes, constructors, methods, annotations, arrays, and so on), to synthetic and bridge constructs or nest-based access control (JDK 11), this chapter provides solid coverage of the Java Reflection API.
Chapter 8, Functional Style Programming – Fundamentals and Design Patterns, includes 11 problems that involve Java functional programming. The chapter starts with a problem designed to acquaint you completely with functional interfaces. It continues with a suite of design patterns from GoF interpreted in Java functional style.
Chapter 9, Functional Style Programming – Deep Dive, includes 22 problems that involve Java functional programming. Here, we focus on several problems that involve classical operations encountered in streams (for example, filters, and maps), and we discuss infinite streams, null-safe streams, and default methods. A comprehensive list of problems covers grouping, partitioning, and collectors, including the JDK 12 teeing() collector and the matter of writing a custom collector. In addition, takeWhile(), dropWhile(), composing functions, predicates and comparators, testing and debugging lambdas, and other cool topics are discussed as well.
Chapter 10, Concurrency – Thread Pools, Callables, and Synchronizers, includes 14 problems that involve Java concurrency. This chapter starts with several fundamental problems about the thread life cycle and object-/class-level locking. It continues with a bunch of problems about thread pools in Java, including JDK 8 work-stealing thread pools. Afterward, we have problems dedicated to Callable and Future. Next, we dedicate several problems to Java synchronizers (for example, barrier, semaphore, and exchanger). By the end of this chapter, you should be familiar with the main coordinates of Java concurrency and be ready to continue with a set of advanced problems.
Chapter 11, Concurrency – Deep Dive, includes 13 problems that involve Java concurrency. This chapter covers problems about fork/join frameworks, CompletableFuture, ReentrantLock, ReentrantReadWriteLock, StampedLock, atomic variables, task cancelation, interruptible methods, thread-local locks, and deadlocks. Completing this chapter will guarantee the achievement of the considerable amount of concurrency knowledge needed by any Java developer.
Chapter 12, Optional, includes 24 problems meant to draw several rules for working with Optional. The problems and solutions presented in this section are based on the Brian Goetz' (Java's language architect) definition—Optional is intended to provide a limited mechanism for library method return types where there needed to be a clear way to represent no result, and using null for such was overwhelmingly likely to cause errors. But where there are rules, there are exceptions as well. Therefore, do not conclude that the rules (or practices) presented here should be followed (or avoided) at all costs. Like always, the solution depends on the problem.
Chapter 13, HTTP Client and WebSocket APIs, includes 20 problems meant to cover the HTTP Client and WebSocket APIs. Remember HttpUrlConnection? Well, JDK 11 comes with the HTTP Client API as a reinvention of HttpUrlConnection. The HTTP Client API is easy to use and supports HTTP/2 (default) and HTTP/1.1. For backward compatibility, the HTTP Client API will automatically downgrade from HTTP/2 to HTTP 1.1 when the server doesn't support HTTP/2. Moreover, the HTTP Client API supports synchronous and asynchronous programming models and relies on streams to transfer data (reactive streams). It also supports the WebSocket protocol used in real-time web applications to provide client-server communication with low message overhead.
To get the most out of this book
You should have fundamental knowledge about the Java language. You should install the following:
An IDE (recommended, but not a must, is Apache NetBeans 11.x: https://netbeans.apache.org/)
JDK 12 and Maven 3.3.x
Additional third-party libraries will need to be installed at the right moment (nothing special)
Download the example code files
You can download the example code files for this book from your account at www.packt.com. If you purchased this book elsewhere, you can visit www.packtpub.com/support and register to have the files emailed directly to you.
You can download the code files by following these steps:
Log in or register at www.packt.com.
Select the Support tab.
Click on Code Downloads.
Enter the name of the book in the Search box and follow the onscreen instructions.
Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:
WinRAR/7-Zip for Windows
Zipeg/iZip/UnRarX for Mac
7-Zip/PeaZip for Linux
The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Java-Coding-Problems. In case there's an update to the code, it will be updated on the existing GitHub repository.
We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
Download the color images
We also provide a PDF file that has color images of the screenshots/diagrams used in this book. You can download it here: https://static.packt-cdn.com/downloads/9781789801415_ColorImages.pdf.
Code in action
To see the code being executed please visit the following link: http://bit.ly/2kSgFKf.
Conventions used
There are a number of text conventions used throughout this book.
CodeInText: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: If the current character exists in the Map instance, then simply increase its occurrences by 1 with (character, occurrences+1).
A block of code is set as follows:
public Map
Map
// or use for(char ch: str.toCharArray()) { ... }
for (int i = 0; i
char ch = str.charAt(i);
result.compute(ch, (k, v) -> (v == null) ? 1 : ++v);
}
return result;
}
When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:
for (int i = 0; i < str.length(); i++) {
int cp = str.codePointAt(i);
String ch = String.valueOf(Character.toChars(cp));
if(Character.charCount(cp) == 2) { // 2 means a surrogate pair
i++;
}
}
Any command-line input or output is written as follows:
$ mkdir css
$ cd css
Bold: Indicates a new term, an important word, or words that you see onscreen. For example, words in menus or dialog boxes appear in the text like this. Here is an example: "In Java, the logical AND operator is represented as &&, the logical OR operator is represented as ||, and the logical XOR operator is represented as ^."
Warnings or important notes appear like this.
Tips and tricks appear like this.
Get in touch
Feedback from our readers is always welcome.
General feedback: If you have questions about any aspect of this book, mention the book title in the subject of your message and email us at customercare@packtpub.com.
Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packtpub.com/support/errata, selecting your book, clicking on the Errata Submission Form link, and entering the details.
Piracy: If you come across any illegal copies of our works in any form on the Internet, we would be grateful if you would provide us with the location address or website name. Please contact us at copyright@packt.com with a link to the material.
If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.
Reviews
Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at Packt can understand what you think about our products, and our authors can see your feedback on their book. Thank you!
For more information about Packt, please visit packt.com.
Strings, Numbers, and Math
This chapter includes 39 problems that involve strings, numbers, and mathematical operations. We will start by looking at a bunch of classical problems for strings such as counting duplicates, reversing a string, and removing white spaces. Then, we will look at problems dedicated to numbers and mathematical operations such as summing two large numbers and operation overflow, comparing two unsigned numbers, and computing the floor of a division and modulus. Each problem is passed through several solutions, including Java 8's functional style. Moreover, we will be covering problems that concern JDK 9, 10, 11, and 12.
By the end of this chapter, you will know how to use a bunch of techniques so that you can manipulate strings and apply, adapt, and adjust them to many other problems. You will also know how to solve mathematical corner cases that may lead to weird and unpredictable results.
Problems
Use the following problems to test your string manipulation and mathematical corner case programming prowess. I strongly encourage you to give each problem a try before you turn to the solutions and download the example programs:
Counting duplicate characters: Write a program that counts duplicate characters from a given string.
Finding the first non-repeated character: Write a program that returns the first non-repeated character from a given string.
Reversing letters and words: Write a program that reverses the letters of each word and a program that reverses the letters of each word and the words themselves.
Checking whether a string contains only digits: Write a program that checks whether the given string contains only digits.
Counting vowels and consonants: Write a program that counts the number of vowels and consonants in a given string. Do this for the English language, which has five vowels (a, e, i, o, and u).
Counting occurrences of a certain character: Write a program that counts the occurrences of a certain character in a given string.
Converting String into int, long, float, or double: Write a program that converts the given String object (representing a number) into int, long, float, or double.
Removing white spaces from a string: Write a program that removes all white spaces from the given string.
Joining multiple strings with a delimiter: Write a program that joins the given strings by the given delimiter.
Generating all permutations: Write a program that generates all of the permutations of a given string.
Checking whether a string is a palindrome: Write a program that determines whether the given string is a palindrome or not.
Removing duplicate characters: Write a program that removes the duplicate characters from the given string.
Removing given characters: Write a program that removes the given character from the given string.
Finding the character with the most appearances: Write a program that finds the character with the most appearances in the given string.
Sorting an array of strings by length: Write a program that sorts by the length of the given array of strings.
Checking that a string contains a substring: Write a program that checks whether the given string contains the given substring.
Counting substring occurrences a string: Write a program that counts the occurrences of a given string in another given string.
Checking whether two strings are anagrams: Write a program that checks whether two strings are anagrams. Consider that an anagram of a string is a permutation of this string by ignoring capitalization and white spaces.
Declaring multiline strings (text blocks): Write a program that declares multiline strings or text blocks.
Concatenating the same string n times: Write a program that concatenates the same string a given number of times.
Removing leading and trailing spaces: Write a program that removes the leading and trailing spaces of the given string.
Finding the longest common prefix: Write a program that finds the longest common prefix of given strings.
Applying indentation: Write several snippets of code to apply indentation to the given text.
Transforming strings: Write several snippets of code to transform a string into another string.
Computing the minimum and maximum of two numbers: Write a program that returns the minimum and maximum of two numbers.
Summing two large int/long numbers and operation overflow: Write a program that sums two large int/long numbers and throws an arithmetic exception in the case of an operation overflow.
String as an unsigned number in the radix: Write a program that parses the given string into an unsigned number (int or long) in the given radix.
Converting into a number by an unsigned conversion: Write a program that converts a given int number into long by an unsigned conversion.
Comparing two unsigned numbers: Write a program that compares the given two numbers as unsigned.
Division and modulo of unsigned values: Write a program that computes the division and modulo of the given unsigned value.
double/float is a finite floating-point value: Write a program that determines whether the given double/float value is a finite floating-point value.
Applying logical AND/OR/XOR to two boolean expressions: Write a program that applies the logical AND/OR/XOR to two boolean expressions.
ConvertingBigInteger into a primitive type: Write a program that extracts the primitive type value from the given BigInteger.
Converting long into int: Write a program that converts long into int.
Computing the floor of a division and modulus: Write a program that computes the floor division and the floor modulus of the given dividend (x) and divisor (y).
Next floating-point value: Write a program that returns the next floating-point adjacent to the given float/double value in the direction of positive and negative infinity.
Multiplying two large int/long values and operation overflow: Write a program that multiplies two large int/long values and throws an arithmetic exception in the case of operation overflow.
Fused Multiply Add (FMA): Write a program that takes three float/double values (a, b, c) and computes a * b + c in an efficient way.
Compact number formatting: Write a program that formats the number 1,000,000 to 1M (US locale) and to 1 mln (Italian locale). In addition, parse 1M and 1 mln from a string into a number.
Solutions
The following sections describe solutions to the preceding problems. Remember that there usually isn't a single correct way to solve a particular problem. Also, remember that the explanations shown here only include the most interesting and important details needed to solve the problems. You can download the example solutions to see additional details and experiment with the programs from https://github.com/PacktPublishing/Java-Coding-Problems.
1. Counting duplicate characters
The solution to counting the characters in a string (including special characters such as #, $, and %) implies taking each character and comparing them with the rest. During the comparison, the counting state is maintained via a numeric counter that's increased by one each time the current character is found.
There are two solutions to this problem.
The first solution iterates the string characters and uses Map to store the characters as keys and the number of occurrences as values. If the current character was never added to Map, then add it as (character, 1). If the current character exists in Map, then simply increase its occurrences by 1, for example, (character, occurrences+1). This is shown in the following code:
public Map
Map
// or use for(char ch: str.toCharArray()) { ... }
for (int i = 0; i
char ch = str.charAt(i);
result.compute(ch, (k, v) -> (v == null) ? 1 : ++v);
}
return result;
}
Another solution relies on Java 8's stream feature. This solution has three steps. The first two steps are meant to transform the given string into Stream
Call the String.chars() method on the original string. This will return IntStream. This IntStream contains an integer representation of the characters from the given string.
Transform IntStream into a stream of characters via the mapToObj() method (convert the integer representation into the human-friendly character form).
Finally, group the characters (Collectors.groupingBy()) and count them (Collectors.counting()).
The following snippet of code glues these three steps into a single method:
public Map
Map
.mapToObj(c -> (char) c)
.collect(Collectors.groupingBy(c -> c, Collectors.counting()));
return result;
}
What about Unicode characters?
We are pretty familiar with ASCII characters. We have unprintable control codes between 0-31, printable characters between 32-127, and extended ASCII codes between 128-255. But what about Unicode characters? Consider this section for each problem that requires that we manipulate Unicode characters.
So, in a nutshell, early Unicode versions contained characters with values less than 65,535 (0xFFFF). Java represents these characters using the 16-bit char data type. Calling charAt(i) works as expected as long as i doesn't exceed 65,535. But over time, Unicode has added more characters and the maximum value has reached 1,114,111 (0x10FFFF). These characters don't fit into 16 bits, and so 32-bit values (known as code points) were considered for the UTF-32 encoding scheme.
Unfortunately, Java doesn't support UTF-32! Nevertheless, Unicode has come up with a solution for still using 16 bits to represent these characters. This solution implies the following:
16-bit high surrogates: 1,024 values (U+D800 to U+DBFF)
16-bit low surrogates: 1,024 values (U+DC00 to U+DFFF)
Now, a high surrogate followed by a low surrogate defines what is known as a surrogate pair. Surrogate pairs are used to represent values between 65,536 (0x10000) and 1,114,111 (0x10FFFF). So, certain characters, known as Unicode supplementary characters, are represented as Unicode surrogate pairs (a one-character (symbol) fits in the space of a pair of characters) that are merged into a single code point. Java takes advantage of this representation and exposes it via a suite of methods such as codePointAt(), codePoints(), codePointCount(), and offsetByCodePoints() (take a look at the Java documentation for details). Calling codePointAt() instead of charAt(), codePoints() instead of chars(), and so on helps us to write solutions that cover ASCII and Unicode characters as well.
For example, the well-known two hearts symbol is a Unicode surrogate pair that can be represented as a char[] containing two values: \uD83D and \uDC95. The code point of this symbol is 128149. To obtain a String object from this code point, call String str = String.valueOf(Character.toChars(128149)). Counting the code points in str can be done by calling str.codePointCount(0, str.length()), which returns 1 even if the str length is 2. Calling str.codePointAt(0) returns 128149 and calling str.codePointAt(1) returns 56469. Calling Character.toChars(128149) returns 2 since two characters are needed to represent this code point being a Unicode surrogate pair. For ASCII and Unicode 16- bit characters, it will return 1.
So, if we try to rewrite the first solution (that iterates the string characters and uses Map to store the characters as keys and the number of occurrences as values) to support ASCII and Unicode (including surrogate pairs), we obtain the following code:
public static Map
countDuplicateCharacters(String str) {
Map
for (int i = 0; i < str.length(); i++) {
int cp = str.codePointAt(i);
String ch = String.valueOf(Character.toChars(cp));
if(Character.charCount(cp) == 2) { // 2 means a surrogate pair
i++;
}
result.compute(ch, (k, v) -> (v == null) ? 1 : ++v);
}
return result;
}
The highlighted code can be written as follows, as well:
String ch = String.valueOf(Character.toChars(str.codePointAt(i)));
if (i < str.length() - 1 && str.codePointCount(i, i + 2) == 1) {
i++;
}
Finally, trying to rewrite the Java 8 functional style solution to cover Unicode surrogate pairs can be done as follows:
public static Map
Map
.mapToObj(c -> String.valueOf(Character.toChars(c)))
.collect(Collectors.groupingBy(c -> c, Collectors.counting()));
return result;
}
For third-party library support, please consider Guava: Multiset
Some of the following problems will provide solutions that cover ASCII, 16-bit Unicode, and Unicode surrogate pairs as well. They have been chosen arbitrarily, and so, by relying on these solutions, you can easily write solutions for problems that don't provide such a solution.
2. Finding the first non-repeated character
There are different solutions to finding the first non-repeated character in a string. Mainly, the problem can be solved in a single traversal of the string or in more complete/partial traversals.
In the single traversal approach, we populate an array that's meant to store the indexes of all of the characters that appear exactly once in the string. With this array, simply return the smallest index containing a non-repeated character:
private static final int EXTENDED_ASCII_CODES = 256;
...
public char firstNonRepeatedCharacter(String str) {
int[] flags = new int[EXTENDED_ASCII_CODES];
for (int i = 0; i < flags.length; i++) {
flags[i] = -1;
}
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (flags[ch] == -1) {
flags[ch] = i;
} else {
flags[ch] = -2;
}
}
int position = Integer.MAX_VALUE;
for (int i = 0; i < EXTENDED_ASCII_CODES; i++) {
if (flags[i] >= 0) {
position = Math.min(position, flags[i]);
}
}
return position == Integer.MAX_VALUE ?
Character.MIN_VALUE : str.charAt(position);
}
This solution assumes that every character from the string is part of the extended ASCII table (256 codes). Having codes greater than 256 requires us to increase the size of the array accordingly (http://www.alansofficespace.com/unicode/unicd99.htm). The solution will work as long as the array size is not extended beyond the largest value of the char type, which is Character.MAX_VALUE, that is, 65,535. On the other hand, Character.MAX_CODE_POINT returns the maximum value of a Unicode code point, 1,114,111. To cover this range, we need another implementation based on codePointAt() and codePoints().
Thanks to the single traversal approach, this is pretty fast. Another solution consists of looping the string for each character and counting the number of occurrences. Every second occurrence (duplicate) simply breaks the loop, jumps to the next character, and repeats the algorithm. If the end of the string is reached, then it returns the current character as the first non-repeatable character. This solution is available in the code bundled with this book.
Another solution that's presented here relies on LinkedHashMap. This Java map is an insertion-order map (it maintains the order in which the keys were inserted into the map) and is very convenient for this solution. LinkedHashMap is populated with characters as keys and the number of occurrences as values. Once LinkedHashMap is complete, it will return the first key that has a value equal to 1. Thanks to the insertion-order feature, this is the first non-repeatable character in the string:
public char firstNonRepeatedCharacter(String str) {
Map
// or use for(char ch: str.toCharArray()) { ... }
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
chars.compute(ch, (k, v) -> (v == null) ? 1 : ++v);
}
for (Map.Entry
if (entry.getValue() == 1) {
return entry.getKey();
}
}
return Character.MIN_VALUE;
}
In the code bundled with this book, the aforementioned solution has been written in Java 8 functional style. Moreover, the functional style solution for supporting ASCII, 16-bit Unicode, and Unicode surrogate pairs is as follows:
public static String firstNonRepeatedCharacter(String str) {
Map
.mapToObj(cp -> cp)
.collect(Collectors.groupingBy(Function.identity(),
LinkedHashMap::new, Collectors.counting()));
int cp = chs.entrySet().stream()
.filter(e -> e.getValue()