Download Full (Ebook) Java Coding Problems, 2nd Edition: Become an expert Java programmer by solving over 200 brand-new, modern, real-world problems by Anghel Leonard PDF All Chapters
Download Full (Ebook) Java Coding Problems, 2nd Edition: Become an expert Java programmer by solving over 200 brand-new, modern, real-world problems by Anghel Leonard PDF All Chapters
com
DOWLOAD EBOOK
ebooknice.com
ebooknice.com
ebooknice.com
(Ebook) SAT II Success MATH 1C and 2C 2002 (Peterson's SAT
II Success) by Peterson's ISBN 9780768906677, 0768906679
https://ebooknice.com/product/sat-ii-success-
math-1c-and-2c-2002-peterson-s-sat-ii-success-1722018
ebooknice.com
https://ebooknice.com/product/pro-java-7-nio-2-36180254
ebooknice.com
ebooknice.com
ebooknice.com
ebooknice.com
Java Coding Problems
Second Edition
Anghel Leonard
BIRMINGHAM—MUMBAI
Java Coding Problems
Second Edition
Grosvenor House
11 St Paul’s Square
Birmingham
B3 1RB, UK.
ISBN 978-1-83763-394-4
www.packt.com
Contributors
He is the author of several books and videos and dozens of articles related
to Java technologies.
About the reviewers
George Adams is a senior software engineer at Microsoft and the Java
Champion and steering committee chair at Eclipse Adoptium. He was a co-
founder of AdoptOpenJDK in 2016 and, since then, has led its community
outreach efforts. He was instrumental in moving the project to the Eclipse
Foundation. George also contributes to both the Homebrew project and the
Node.js Foundation, where he is a core collaborator and plays an active role
in several of the workgroups.
https://discord.gg/8mgytp5DGQ
Contents
Preface
Who this book is for
What this book covers
To get the most out of this book
Get in touch
1. Text Blocks, Locales, Numbers, and Math
Problems
1. Creating a multiline SQL, JSON, and HTML string
Before JDK 8
Starting with JDK 8
Introducing text blocks (JDK 13/15)
Hooking text blocks syntax
2. Exemplifying the usage of text block delimiters
3. Working with indentation in text blocks
Shifting the closing delimiter and/or the content
Using indentation methods
4. Removing incidental white spaces in text blocks
5. Using text blocks just for readability
6. Escaping quotes and line terminators in text blocks
7. Translating escape sequences programmatically
8. Formatting text blocks with variables/expressions
9. Adding comments in text blocks
10. Mixing ordinary string literals with text blocks
11. Mixing regular expression with text blocks
12. Checking if two text blocks are isomorphic
13. Concatenating strings versus StringBuilder
JDK 8
JDK 11
14. Converting int to String
15. Introducing string templates
What’s a string template?
The STR template processor
The FMT template processor
The RAW template processor
16. Writing a custom template processor
17. Creating a Locale
18. Customizing localized date-time formats
19. Restoring Always-Strict Floating-Point semantics
20. Computing mathematical absolute value for int/long and
result overflow
21. Computing the quotient of the arguments and result overflow
22. Computing the largest/smallest value that is less/greater than
or equal to the algebraic quotient
23. Getting integral and fractional parts from a double
24. Testing if a double number is an integer
25. Hooking Java (un)signed integers in a nutshell
26. Returning the flooring/ceiling modulus
27. Collecting all prime factors of a given number
28. Computing the square root of a number using the Babylonian
method
29. Rounding a float number to specified decimals
30. Clamping a value between min and max
31. Multiply two integers without using loops, multiplication,
bitwise, division, and operators
32. Using TAU
What is TAU?
33. Selecting a pseudo-random number generator
Choosing an algorithm by name
Choosing an algorithm by property
34. Filling a long array with pseudo-random numbers
35. Creating a stream of pseudo-random generators
36. Getting a legacy pseudo-random generator from new ones of
JDK 17
37. Using pseudo-random generators in a thread-safe fashion
(multithreaded environments)
Summary
2. Objects, Immutability, Switch Expressions, and Pattern Matching
Problems
38. Explain and exemplifying UTF-8, UTF-16, and UTF-32
Introducing ASCII encoding scheme (or single-byte
encoding)
Introducing multi-byte encoding
Unicode
Java and Unicode
JDK 18 defaults the charset to UTF-8
39. Checking a sub-range in the range from 0 to length
40. Returning an identity string
41. Hooking unnamed classes and instance main methods
42. Adding code snippets in Java API documentation
Adding attributes
Using markup comments and regions
Highlighting
Linking
Modifying the code’s text
Using external snippets
Regions in external snippets
43. Invoking default methods from Proxy instances
JDK 8
JDK 9+, pre-JDK 16
JDK 16+
44. Converting between bytes and hex-encoded strings
JDK 17+
45. Exemplify the initialization-on-demand holder design pattern
Static vs. non-static blocks
Nested classes
Tackling the initialization-on-demand holder design pattern
JDK 16+
46. Adding nested classes in anonymous classes
JDK 16+
47. Exemplify erasure vs. overloading
Erasure in a nutshell
Erasure of generic types
Erasure and bridge methods
Type erasure and heap pollution
Polymorphic overloading in a nutshell
Erasure vs. overloading
48. Xlinting default constructors
49. Working with the receiver parameter
50. Implementing an immutable stack
51. Revealing a common mistake with Strings
52. Using the enhanced NullPointerException
WARNING 1! NPE when calling an instance method via a
null object
WARNING 2! NPE when accessing (or modifying) the field
of a null object
WARNING 3! NPE when null is passed in the method
argument
WARNING 4! NPE when accessing the index value of a null
array/collection
WARNING 5! NPE when accessing a field via a getter
53. Using yield in switch expressions
54. Tackling the case null clause in switch
55. Taking on the hard way to discover equals()
56. Hooking instanceof in a nutshell
57. Introducing pattern matching
The scope of binding variables in pattern matching
Guarded patterns
Type coverage
Current status of pattern matching
58. Introducing type pattern matching for instanceof
59. Handling the scope of a binding variable in type patterns for
instanceof
60. Rewriting equals() via type patterns for instanceof
61. Tackling type patterns for instanceof and generics
62. Tackling type patterns for instanceof and streams
63. Introducing type pattern matching for switch
64. Adding guarded pattern labels in switch
65. Dealing with pattern label dominance in switch
66. Dealing with completeness (type coverage) in pattern labels
for switch
67. Understanding the unconditional patterns and nulls in switch
expressions
Summary
3. Working with Date and Time
Problems
68. Defining a day period
Before JDK 16
JDK 16+
69. Converting between Date and YearMonth
70. Converting between int and YearMonth
71. Converting week/year to Date
72. Checking for a leap year
73. Calculating the quarter of a given date
74. Getting the first and last day of a quarter
75. Extracting the months from a given quarter
76. Computing pregnancy due date
77. Implementing a stopwatch
78. Extracting the count of milliseconds since midnight
79. Splitting a date-time range into equal intervals
80. Explaining the difference between Clock.systemUTC() and
Clock.systemDefaultZone()
81. Displaying the names of the days of the week
82. Getting the first and last day of the year
83. Getting the first and last day of the week
84. Calculating the middle of the month
85. Getting the number of quarters between two dates
86. Converting Calendar to LocalDateTime
87. Getting the number of weeks between two dates
Summary
4. Records and Record Patterns
Problems
88. Declaring a Java record
89. Introducing the canonical and compact constructors for
records
Handling validation
Reassigning components
Defensive copies of the given components
90. Adding more artifacts in a record
91. Iterating what we cannot have in a record
A record cannot extend another class
A record cannot be extended
A record cannot be enriched with instance fields
A record cannot have private canonical constructors
A record cannot have setters
92. Defining multiple constructors in a record
93. Implementing interfaces in records
94. Understanding record serialization
How serialization/deserialization works
Serializing/deserializing gacContainer (a typical Java class)
Deserializing a malicious stream
Serializing/deserializing gacContainerR (a Java record)
Deserializing a malicious stream
Refactoring legacy serialization
95. Invoking the canonical constructor via reflection
96. Using records in streams
97. Introducing record patterns for instanceof
Nested records and record patterns
98. Introducing record patterns for switch
99. Tackling guarded record patterns
100. Using generic records in record patterns
Type argument inference
Type argument inference and nested records
101. Handling nulls in nested record patterns
102. Simplifying expressions via record patterns
103. Hooking unnamed patterns and variables
Unnamed patterns
Unnamed variables
In a catch block
In a for loop
In an assignment that ignores the result
In try-with-resources
In lambda expressions
104. Tackling records in Spring Boot
Using records in controllers
Using records with templates
Using records for configuration
Record and dependency injection
105. Tackling records in JPA
DTO via record constructor
DTO via record and JPA constructor expression
DTO via record and result transformer
DTO via record and JdbcTemplate
Team up Java records and @Embeddable
106. Tackling records in jOOQ
Summary
5. Arrays, Collections, and Data Structures
Problems
107. Introducing parallel computations with arrays
108. Covering the Vector API’s structure and terminology
The vector element type
The vector shape
The vector species
Vector lanes
Vector operations
Creating vectors
Creating vectors of zeros
Creating vectors of the same primitive value
Creating vectors from Java arrays
Creating vectors from memory segments
109. Summing two arrays via the Vector API
110. Summing two arrays unrolled via the Vector API
111. Benchmarking the Vector API
112. Applying the Vector API to compute FMA
113. Multiplying matrices via the Vector API
114. Hooking the image negative filter with the Vector API
115. Dissecting factory methods for collections
Factory methods for maps
Factory methods for lists
Factory methods for sets
116. Getting a list from a stream
117. Handling map capacity
118. Tackling Sequenced Collections
Applying the Sequenced Collections API to lists
Applying the Sequenced Collections API to ArrayList
and LinkedList
Applying the Sequenced Collections API to sets
Applying the Sequenced Collections API to HashSet
Applying the Sequenced Collections API to
LinkedHashSet
Applying the Sequenced Collections API to TreeSet
Applying the Sequenced Collections API to maps
Applying the Sequenced Collections API to
LinkedHashMap
Applying the Sequenced Collections API to SortedMap
(TreeMap)
119. Introducing the Rope data structure
Implementing indexAt(Node node, int index)
Implementing concat(Node node1, Node node2)
Implementing insert(Node node, int index, String str)
Implementing delete(Node node, int start, int end)
Implementing split(Node node, int index)
120. Introducing the Skip List data structure
Implementing contains(Integer data)
Implementing insert(Integer data)
Implementing delete(Integer data)
121. Introducing the K-D Tree data structure
Inserting into a K-D Tree
Finding the nearest neighbor
122. Introducing the Zipper data structure
123. Introducing the Binomial Heap data structure
Implementing insert(int key)
Implementing findMin()
Implementing extractMin()
Implementing decreaseKey(int key, int newKey)
Implementing delete(int key)
Implementing unionHeap(BinomialHeap heap)
124. Introducing the Fibonacci Heap data structure
125. Introducing the Pairing Heap data structure
126. Introducing the Huffman Coding data structure
Encoding the string
Decoding the string
127. Introducing the Splay Tree data structure
128. Introducing the Interval Tree data structure
Implementing insert(Interval interval)
129. Introducing the Unrolled Linked List data structure
130. Implementing join algorithms
Nested Loop Join
Hash Join
Sort Merge Join
Summary
6. Java I/O: Context-Specific Deserialization Filters
Problems
131. Serializing objects to byte arrays
132. Serializing objects to strings
133. Serializing objects to XML
134. Introducing JDK 9 deserialization filters
Pattern-based filters
Applying a pattern-based filter per application
Applying a pattern-based filter to all applications in a
process
ObjectInputFilter-based filters
135. Implementing a custom pattern-based ObjectInputFilter
136. Implementing a custom class ObjectInputFilter
137. Implementing a custom method ObjectInputFilter
138. Implementing a custom lambda ObjectInputFilter
139. Avoiding StackOverflowError at deserialization
140. Avoiding DoS attacks at deserialization
141. Introducing JDK 17 easy filter creation
142. Tackling context-specific deserialization filters
Applying a Filter Factory per application
Applying a Filter Factory to all applications in a process
Applying a Filter Factory via ObjectInputFilter.Config
Implementing a Filter Factory
143. Monitoring deserialization via JFR
Summary
7. Foreign (Function) Memory API
Problems
144. Introducing Java Native Interface (JNI)
Generating the header (.h) file
Implementing the modern_challenge_Main.cpp
Compiling the C source code
Generating the native shared library
Finally, run the code
145. Introducing Java Native Access (JNA)
Implementing the .cpp and .h files
Compiling the C source code
Generating the native shared library
Finally, run the code
146. Introducing Java Native Runtime (JNR)
147. Motivating and introducing Project Panama
148. Introducing Panama’s architecture and terminology
149. Introducing Arena and MemorySegment
Introducing memory layouts (ValueLayout)
Allocating memory segments of value layouts
Setting/getting the content of a memory segment
Working with Java strings
150. Allocating arrays into memory segments
151. Understanding addresses (pointers)
152. Introducing the sequence layout
Introducing PathElement
Introducing VarHandle
Putting PathElement and VarHandle together
Working with nested sequence layouts
153. Shaping C-like structs into memory segments
Introducing StructLayout
154. Shaping C-like unions into memory segments
Introducing UnionLayout
155. Introducing PaddingLayout
Hooking size, alignment, stride, and padding
Hooking size
Hooking alignment
Hooking stride
Hooking padding
Adding implicit extra space (implicit padding) to validate
alignment
Adding explicit extra space (explicit padding) to validate
alignment
156. Copying and slicing memory segments
Copying a segment
Copying a part of the segment into another segment (1)
Copying a segment into an on-heap array
Copying an on-heap array into a segment
Copying a part of the segment into another segment (2)
Slicing a segment
Using asOverlappingSlice()
Using segmentOffset()
157. Tackling the slicing allocator
158. Introducing the slice handle
159. Introducing layout flattening
160. Introducing layout reshaping
161. Introducing the layout spreader
162. Introducing the memory segment view VarHandle
163. Streaming memory segments
164. Tackling mapped memory segments
165. Introducing the Foreign Linker API
166. Calling the sumTwoInt() foreign function
167. Calling the modf() foreign function
168. Calling the strcat() foreign function
169. Calling the bsearch() foreign function
170. Introducing Jextract
171. Generating native binding for modf()
Summary
8. Sealed and Hidden Classes
Problems
172. Creating an electrical panel (hierarchy of classes)
173. Closing the electrical panel before JDK 17
Applying the final modifier
Defining package-private constructors
Declaring classes/interfaces as non-public
Throwing everything in a module
Conclusion
174. Introducing JDK 17 sealed classes
175. Introducing the permits clause
Working with sealed classes in separate sources (same
package)
Working with sealed classes in separate packages
176. Closing the electrical panel after JDK 17
177. Combining sealed classes and records
178. Hooking sealed classes and instanceof
179. Hooking sealed classes in switch
180. Reinterpreting the Visitor pattern via sealed classes and type
pattern matching for switch
181. Getting info about sealed classes (using reflection)
182. Listing the top three benefits of sealed classes
183. Briefly introducing hidden classes
184. Creating a hidden class
Summary
9. Functional Style Programming – Extending APIs
Problems
185. Working with mapMulti()
186. Streaming custom code to map
187. Exemplifying a method reference vs. a lamda
Scenario 1: Calling printReset()
Scenario 2: Calling static printNoReset()
Conclusion
188. Hooking lambda laziness via Supplier/Consumer
189. Refactoring code to add lambda laziness
Fixing in imperative fashion
Fixing in functional fashion
190. Writing a Function<String, T> for parsing data
191. Composing predicates in a Stream’s filters
192. Filtering nested collections with Streams
193. Using BiPredicate
194. Building a dynamic predicate for a custom model
195. Building a dynamic predicate from a custom map of
conditions
196. Logging in predicates
197. Extending Stream with containsAll() and containsAny()
Exposing containsAll/Any() via a custom interface
Exposing containsAll/Any() via an extension of Stream
198. Extending Stream with removeAll() and retainAll()
Exposing removeAll()/retainAll() via a custom interface
Exposing removeAll/retainAll() via an extension of Stream
199. Introducing stream comparators
Sorting via natural order
Reversing the natural order
Sorting and nulls
Writing custom comparators
200. Sorting a map
201. Filtering a map
202. Creating a custom collector via Collector.of()
Writing a custom collector that collects into a TreeSet
Writing a custom collector that collects into a
LinkedHashSet
Writing a custom collector that excludes elements of another
collector
Writing a custom collector that collects elements by type
Writing a custom collector for SplayTree
203. Throwing checked exceptions from lambdas
204. Implementing distinctBy() for the Stream API
205. Writing a custom collector that takes/skips a given number
of elements
206. Implementing a Function that takes five (or any other
arbitrary number of) arguments
207. Implementing a Consumer that takes five (or any other
arbitrary number of) arguments
208. Partially applying a Function
Summary
10. Concurrency – Virtual Threads and Structured Concurrency
Problems
209. Explaining concurrency vs. parallelism
210. Introducing structured concurrency
211. Introducing virtual threads
What’s the problem with platform (OS) threads?
What are virtual threads?
Creating a virtual thread
How many virtual threads we can start
Backward compatibility
Avoiding fake conclusions (potentially myths)
212. Using the ExecutorService for virtual threads
213. Explaining how virtual threads work
Capturing virtual threads
Pinning virtual threads
214. Hooking virtual threads and sync code
215. Exemplifying thread context switching
Example 1
Example 2
Example 3
216. Introducing the ExecutorService invoke all/any for virtual
threads – part 1
Working with invokeAll()
Working with invokeAny()
217. Introducing the ExecutorService invoke all/any for virtual
threads – part 2
218. Hooking task state
219. Combining newVirtualThreadPerTaskExecutor() and streams
220. Introducing a scope object (StructuredTaskScope)
ExecutorService vs. StructuredTaskScope
221. Introducing ShutdownOnSuccess
222. Introducing ShutdownOnFailure
223. Combining StructuredTaskScope and streams
224. Observing and monitoring virtual threads
Using JFR
Using Java Management Extensions (JMX)
Running 10,000 tasks via the cached thread pool executor
Running 10,000 tasks via the fixed thread pool executor
Running 10,000 tasks via the virtual thread per task executor
Summary
11. Concurrency ‒ Virtual Threads and Structured Concurrency: Diving
Deeper
Problems
225. Tackling continuations
Introducing continuations
Continuations and virtual threads
226. Tracing virtual thread states and transitions
NEW
STARTED
RUNNING
PARKING
PARKED/PINNED
YIELDING
RUNNABLE
TERMINATED
227. Extending StructuredTaskScope
228. Assembling StructuredTaskScope
229. Assembling StructuredTaskScope instances with timeout
230. Hooking ThreadLocal and virtual threads
231. Hooking ScopedValue and virtual threads
Thread-local variables’ shortcomings
Introducing scoped values
232. Using ScopedValue and executor services
233. Chaining and rebinding scoped values
Changing scoped values
Rebinding scoped values
234. Using ScopedValue and StructuredTaskScope
235. Using Semaphore instead of Executor
236. Avoiding pinning via locking
237. Solving the producer-consumer problem via virtual threads
238. Solving the producer-consumer problem via virtual threads
(fixed via Semaphore)
239. Solving the producer-consumer problem via virtual threads
(increase/decrease consumers)
240. Implementing an HTTP web server on top of virtual threads
241. Hooking CompletableFuture and virtual threads
242. Signaling virtual threads via wait() and notify()
Summary
12. Garbage Collectors and Dynamic CDS Archives
Problems
243. Hooking the garbage collector goal
244. Handling the garbage collector stages
245. Covering some garbage collector terminology
Epoch
Single and multiple passes
Serial and parallel
Stop-the-World (STW) and concurrent
Live set
Allocation rate
NUMA
Region-based
Generational garbage collection
246. Tracing the generational GC process
247. Choosing the correct garbage collector
248. Categorizing garbage collectors
Serial garbage collector
Parallel garbage collector
Garbage-First (G1) collector
Z Garbage Collector (ZGC)
Shenandoah Garbage Collector
Concurrent Mark Sweep (CMS) collector (deprecated)
249. Introducing G1
Design principles
250. Tackling G1 throughput improvements
Delaying the start of the Old generation
Focusing on easy pickings
Improving NUMA-aware memory allocation
Parallelized full-heap collections
Other improvements
251. Tackling G1 latency improvements
Merge parallel phases into a larger one
Reduction of metadata
Better work balancing
Better parallelization
Better reference scanning
Other improvements
252. Tackling G1 footprint improvements
Maintain only the needed metadata
Release memory
253. Introducing ZGC
ZGC is concurrent
ZGC and colored pointers
ZGC and load barriers
ZGC is region-based
254. Monitoring garbage collectors
255. Logging garbage collectors
256. Tuning garbage collectors
How to tune
Tuning the serial garbage collector
Tunning the parallel garbage collector
Tuning the G1 garbage collector
Tuning Z Garbage Collector
Tuning Metaspace (Metadata space)
257. Introducing Application Class Data Sharing (AppCDS, or
Java’s Startup Booster)
Tackling a JDK class data archive
JDK 10/JDK 11
JDK 12+
Tackling application class data archive
Before JDK 13
JDK 13+
JDK 19+
Summary
13. Socket API and Simple Web Server
Problems
258. Introducing socket basics
259. Introducing TCP server/client applications
Blocking vs. non-blocking mechanisms
260. Introducing the Java Socket API
Introducing NetworkChannel
Tackling socket options
261. Writing a blocking TCP server/client application
Writing a single-thread blocking TCP echo server
Creating a new server socket channel
Configuring the blocking mechanism
Setting server socket channel options
Binding the server socket channel
Accepting connections
Transmitting data over a connection
Closing the channel
Putting it all together into the echo server
Writing a single-thread blocking TCP client
Creating a new (client) socket channel
Configuring the blocking mechanism
Setting client socket channel options
Connecting the client socket channel
Transmitting data over a connection
Closing the channel
Putting it all together into the client
Testing the blocking echo application
262. Writing a non-blocking TCP server/client application
Using the SelectionKey class
Using the Selector methods
Writing the non-blocking server
Writing the non-blocking client
Testing the non-blocking echo application
263. Writing UDP server/client applications
Writing a single-thread blocking UDP echo server
Creating a server datagram-oriented socket channel
Setting datagram-oriented socket channel options
Binding the server datagram-oriented socket channel
Transmitting data packets
Closing the channel
Putting it all together into the client
Writing a connectionless UDP client
Testing the UDP connectionless echo application
Writing a connected UDP client
264. Introducing multicasting
A brief overview of MembershipKey
265. Exploring network interfaces
266. Writing a UDP multicast server/client application
Writing a UDP multicast server
Writing a UDP multicast client
Blocking/unblocking datagrams
Testing the multicasting server/client application
267. Adding KEM to a TCP server/client application
Generating a public-private keypair by the receiver
Transmitting the public key to the sender
Generating the common secret key by the sender
Sending the encapsulation message to the receiver
Using the secret key to encrypt/decrypt messages
268. Reimplementing the legacy Socket API
269. Quick overview of SWS
Key abstractions of SWS
270. Exploring the SWS command-line tool
Starting SWS from the command line
Configuring SWS from the command line
Stopping SWS from the command line
271. Introducing the com.sun.net.httpserver API
Using a custom HttpHandler
Using a custom filter
Using a custom executor
272. Adapting request/exchange
273. Complementing a conditional HttpHandler with another
handler
274. Implementing SWS for an in-memory file system
275. Implementing SWS for a zip file system
276. Implementing SWS for a Java runtime directory
Summary
Other Books You May Enjoy
Index
Preface
The super-fast evolution of the JDK between versions 12 and 21 means two
things: first, Java now has a host of powerful new features that you can
adopt to solve a variety of modern-day problems; second, the learning curve
of modern Java is becoming very steep.
This book enables you to take an objective approach to solving common
problems by explaining the correct practices and decisions you need to
make with respect to complexity, performance, readability, and more.
Java Coding Problems, Second Edition, will help you complete your daily
tasks and meet deadlines, all while becoming a more proficient and self-
sufficient Java developer. You can count on the 270+ (all brand-new for this
edition) problems in this book to cover the most common and fundamental
areas of interest: strings, numbers, arrays, collections, the Foreign Function
and Memory API, data structures, date and time, pattern matching,
sealed/hidden classes, functional programming, virtual threads, Structured
Concurrency, Garbage Collectors, Dynamic CDS Archives, the Socket API,
and Simple Web Server.
Put your skills on steroids with problems that have been carefully crafted to
highlight and teach the core knowledge needed for daily work. In other
words (no matter if your task is simple, middling, or complex), having this
knowledge in 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 you’ll have the confidence to develop and choose the
right solutions to all your Java problems.
While this book is entirely stand-alone, and you do not need anything else
to get the most out of it, many of the topics covered in this book are also
explored in Java Coding Problems, First Edition. If you haven’t already
read it, and you wish to get even more practice in, then consider picking
that book up for a completely different set of Java problems.
Who this book is for
Java Coding Problems, Second Edition, is especially useful for late-
beginner-to-intermediate Java developers looking to level-up their
knowledge by solving real-world problems. However, the problems looked
at within these pages will be encountered in the daily work of any Java
developer, from beginner all the way to advanced practitioner.
Edinburgh Observer.
The people are not satisfied with the imperfect disclosures that
have taken place, and the trivial atonement that is to be made to
outraged humanity, by the death of only one of the atrocious gang.
There is a cry for blood—more blood—throughout the land; and
coming, as it does, from the bulk of the nation, it will require no little
discrimination and firmness, on the part of the Public Prosecutor, to
see his way clearly, and to keep it when he has found it. A more
difficult situation than his, at the present time, we cannot well
imagine. Even the activity of the press, in reiterating the calls for
further inquiry and for more victims, at the very moment when he is
known to be indefatigably employed in prosecuting the one and
searching for the other, has greatly contributed to render his duties
more harassing and ungracious. Under a sincere, and, despite what
others say, we conceive a just impression, that all the monsters
might escape the gallows, as one of them has actually done, by a
verdict of “not proven,” he permitted two of them to purchase their
worthless lives by bearing testimony against their associates. That
the Hares obtained this immunity as being the lesser criminals in his
estimation, we do not believe. The fact of the particular murder,
which led to the whole discoveries, having been perpetrated under
Burke’s roof, naturally pointed out him and his guilty partner as the
more immediate objects of legal vengeance. It is evident, that
throughout the whole business, the Lord Advocate has been
actuated by the most honourable anxiety to investigate the affair to
the uttermost; and had he not, at the very outset of the trial, been
urged into a concession to the legal scruples of the counsel opposed
to him, whose eloquence most assuredly reft one wretch from the
clutch of the hangman, not merely one, but three acts of the horrid
drama would have been publicly revealed. It is stated, that since the
trial, his Lordship and his assistants have been unremitting in their
inquiries. He has attended almost every precognition, and surveyed
in person the foul abodes which the murderers inhabited, and even
the dwellings of their victims. But he refuses to violate the public
faith, of which, in this instance he is the custodier, by yielding up the
tools he has been forced to employ, to that punishment which they
have so abundantly merited, yet from which the nation stands
pledged they are redeemed. God forbid that we should advocate the
indemnity of these monsters on any ground, save the sanctity of
such a pledge. We question greatly, whether Hare and his partner,
cast upon the world with ignominy and crime branded on their
foreheads, are not more condignly punished, than the wretched man
whose days are numbered, and whose doom, it is certainly not
uncharitable to predict, will yet overtake them. In the case of
Weare’s murder, Probert, one of the accessaries, was admitted to a
like immunity. When his foul breath had consigned one of his
associates to the gallows, he was allowed to go forth into the world
a free man; but, like Cain, he found himself an outcast, and, in the
course of a few months, was again arraigned as a felon, convicted,
and executed.
Though we dissent from the summary mode of procedure which
many people recommend, and conceive that it would be a perilous
innovation on the prerogative of the Public Prosecutor to say, that in
this instance, his pledge of immunity shall be disregarded, unless
some new charge can be substantiated, we view the detestation so
unaffectedly expressed by the public towards the whole gang, as
consolatory to humanity. Had criminals, with hands so deeply dyed
in blood, found even one commiserator or advocate beyond the
walls of the Court of Justice—had any man ventured to whisper that
the crimes which they have perpetrated are not worthy of death—
nay, had not the whole nation lifted up its voice, and declared, that
even death itself was but a miserable atonement for crimes so
monstrous, we should have regarded it as a national disgrace. It is
to be hoped, however, that this laudable spirit will not degenerate
into tumultuary violence. The authorities, we are satisfied, will not
relax their efforts to develope the whole of these sanguinary
atrocities; and, if the correspondence which is at present carrying on
between the Lord Advocate and the teachers of anatomy should, in
conjunction with other investigations in progress, lead to the
inculpation, in the remotest way, of any individual, we are satisfied
that nothing will shield the culprit from the vengeance of the law, be
his rank or previous respectability what it may. As yet only one
individual of that body has been in any way implicated in these
horrible transactions; and we know that a feeling is prevalent that he
has been treated with greater delicacy than he deserves; but the
culpability of one man must not be received as condemnatory
evidence against a whole tribe. An earnest desire is entertained by
the teachers of anatomy that the fullest investigation should take
place; and if criminal laxity in the receipt of subjects can be traced to
any particular quarter, an ample exposition will follow. This
exposition they are entitled to demand; for the reputation of the
whole fraternity is perilled by the revolting suspicions which the
crimes of their caterers have engendered.
WILLIAM BURKE.
Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.
ebooknice.com